From 4f6d31b0eb493ba223c07c851bd8580b074cd0b7 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Fri, 9 Apr 2021 21:00:37 -0700 Subject: [PATCH] Generate documents for commit f6c02e629d95e6164d330244ce449b752493064b --- docs/annotated.html | 745 +- docs/classes.html | 196 +- ...ia_1_1mp4_1_1HandlerReference-members.html | 17 +- ..._1_1media_1_1RsaRequestSigner-members.html | 17 +- .../muxer__listener__factory_8cc_source.html | 173 +- docs/d0/d06/mpd__flags_8cc_source.html | 90 +- ...odec__configuration__record_8h_source.html | 73 +- ...ka_1_1media_1_1HttpKeyFetcher-members.html | 19 +- ...oder__configuration__record_8h_source.html | 71 +- docs/d0/d0e/muxer__options_8h_source.html | 74 +- ...media_1_1mp2t_1_1TsSectionPmt-members.html | 17 +- ...edia_1_1WidevinePsshGenerator-members.html | 17 +- .../structshaka_1_1media_1_1VPxFrameInfo.html | 17 +- ...tshaka_1_1media_1_1StreamData-members.html | 17 +- docs/d0/d1a/text__sample_8h_source.html | 157 +- ...H265ByteToUnitStreamConverter-members.html | 17 +- ..._1_1media_1_1mp4_1_1VTTCueBox-members.html | 17 +- ...haka_1_1media_1_1mp2t_1_1TsSectionPat.html | 37 +- .../structshaka_1_1media_1_1MuxerOptions.html | 17 +- docs/d0/d2b/representation_8h_source.html | 212 +- .../d0/d30/mock__mpd__notifier_8h_source.html | 88 +- docs/d0/d32/mp2t__common_8h_source.html | 47 +- .../d33/classshaka_1_1MockRepresentation.html | 33 +- docs/d0/d35/es__descriptor_8cc_source.html | 284 +- ...1_1EncryptedStreamAttributes_1_1OneOf.html | 31 +- docs/d0/d39/video__util_8cc_source.html | 87 +- ...s__notify__muxer__listener_8cc_source.html | 362 +- docs/d0/d3a/webm__constants_8h_source.html | 262 +- ...mp4_1_1ProtectionSystemSpecificHeader.html | 25 +- docs/d0/d42/aes__cryptor_8h_source.html | 151 +- ...idevine__encryption__flags_8cc_source.html | 199 +- .../d43/structshaka_1_1Mp4OutputParams.html | 17 +- docs/d0/d46/fourccs_8h_source.html | 204 +- ...shaka_1_1media_1_1SegmentInfo-members.html | 17 +- ...nfo__dump__muxer__listener_8cc_source.html | 184 +- ...ia_1_1mp4_1_1MediaInformation-members.html | 38 +- .../structshaka_1_1media_1_1StreamData.html | 17 +- ...haka_1_1media_1_1AudioTimestampHelper.html | 17 +- .../d4e/libcrypto__threading_8cc_source.html | 71 +- ...a_1_1media_1_1mp2t_1_1TsMuxer-members.html | 19 +- ...oder__configuration__record_8h_source.html | 71 +- docs/d0/d59/classshaka_1_1media_1_1Job.html | 21 +- docs/d0/d59/classshaka_1_1media_1_1Job.png | Bin 527 -> 560 bytes ...dia_1_1MpdNotifyMuxerListener-members.html | 17 +- .../ad__cue__generator__flags_8cc_source.html | 38 +- ...shaka_1_1media_1_1mp2t_1_1EsParserDvb.html | 133 + ...sshaka_1_1media_1_1mp2t_1_1EsParserDvb.png | Bin 0 -> 820 bytes ...a_1_1media_1_1mp4_1_1VideoSampleEntry.html | 25 +- docs/d0/d73/webvtt__muxer_8h_source.html | 123 + ...haka_1_1media_1_1TextFragment-members.html | 93 + ...haka_1_1media_1_1mp4_1_1SampleToGroup.html | 25 +- docs/d0/d7d/decryptor__source_8h_source.html | 70 +- ...a_1_1media_1_1AesCbcEncryptor-members.html | 17 +- ...media_1_1ProtectionSystemSpecificInfo.html | 19 +- .../structshaka_1_1media_1_1mp4_1_1Movie.html | 25 +- ...sshaka_1_1media_1_1SubsampleGenerator.html | 23 +- ...ka_1_1media_1_1AACAudioSpecificConfig.html | 123 +- ...shaka_1_1media_1_1CommonPsshGenerator.html | 21 +- ...aka_1_1media_1_1RequestSigner-members.html | 17 +- ...uctshaka_1_1xml_1_1XmlDeleter-members.html | 26 +- .../d0/da6/stream__descriptor_8cc_source.html | 319 +- ...1_1media_1_1PackedAudioWriter-members.html | 19 +- docs/d0/da8/structshaka_1_1HlsParams.html | 43 +- ...edia_1_1mp4_1_1SingleSegmentSegmenter.html | 27 +- docs/d0/dab/subtitle__composer_8h_source.html | 159 + ...1_1media_1_1EncryptionHandler-members.html | 19 +- docs/d0/dae/file__util_8h_source.html | 34 +- docs/d0/db4/structshaka_1_1RawKeyParams.html | 25 +- ...1_1media_1_1mp2t_1_1Ac3Header-members.html | 17 +- docs/d0/dbc/bit__writer_8h_source.html | 79 +- docs/d0/dbc/webvtt__parser_8h_source.html | 93 +- ...webm_1_1MultiSegmentSegmenter-members.html | 17 +- ...tructshaka_1_1RawKeyParams_1_1KeyInfo.html | 22 +- .../structshaka_1_1media_1_1SegmentInfo.html | 17 +- ...edia_1_1mp4_1_1VTTEmptyCueBox-members.html | 17 +- ..._1xml_1_1AdaptationSetXmlNode-members.html | 55 +- .../classshaka_1_1media_1_1RsaPrivateKey.html | 19 +- ...aka_1_1media_1_1mp4_1_1CueSettingsBox.html | 25 +- .../dd6/webm__crypto__helpers_8cc_source.html | 135 +- ...lassshaka_1_1media_1_1AesCtrEncryptor.html | 25 +- ...edia_1_1DecoderSpecificInfoDescriptor.html | 23 +- ...classshaka_1_1media_1_1SyncPointQueue.html | 19 +- .../dee/segmenter__test__base_8h_source.html | 154 +- ...1_1media_1_1ttml_1_1TtmlToMp4Handler.html} | 64 +- ...a_1_1media_1_1ttml_1_1TtmlToMp4Handler.png | Bin 0 -> 795 bytes docs/d0/df3/packager__util_8cc_source.html | 201 +- ...haka_1_1hls_1_1MasterPlaylist-members.html | 21 +- ...ia_1_1mp4_1_1AudioSampleEntry-members.html | 54 +- ...media_1_1MuxerListener_1_1MediaRanges.html | 17 +- ...shaka_1_1AdCueGeneratorParams-members.html | 17 +- .../d07/structshaka_1_1Cuepoint-members.html | 17 +- .../d0a/classshaka_1_1media_1_1MkvWriter.html | 27 +- .../d0a/classshaka_1_1media_1_1MkvWriter.png | Bin 592 -> 652 bytes .../d0a/structshaka_1_1media_1_1H264Sps.html | 20 +- ...der__configuration__record_8cc_source.html | 186 +- ...media_1_1mp2t_1_1EsParserH264-members.html | 42 +- docs/d1/d12/range_8h_source.html | 46 +- docs/d1/d13/status_8h_source.html | 166 +- ...a_1_1WidevineDecryptionParams-members.html | 17 +- ...classshaka_1_1media_1_1MockAesCryptor.html | 25 +- ...single__segment__segmenter_8cc_source.html | 212 +- docs/d1/d1d/muxer__flags_8cc_source.html | 74 +- docs/d1/d1e/hls__notifier_8h_source.html | 109 +- .../d1f/classshaka_1_1media_1_1KeySource.html | 82 +- ...1media_1_1mp4_1_1DecodingTimeIterator.html | 17 +- ...media_1_1MediaHandlerTestBase-members.html | 17 +- docs/d1/d27/key__fetcher_8h_source.html | 58 +- ..._1media_1_1mp2t_1_1AdtsHeader-members.html | 17 +- docs/d1/d2a/decryptor__source_8cc_source.html | 182 +- docs/d1/d2b/file__util_8cc_source.html | 76 +- ...media_1_1mp4_1_1DataReference-members.html | 17 +- .../structshaka_1_1media_1_1mp4_1_1Box.html | 86 +- .../structshaka_1_1media_1_1mp4_1_1Box.png | Bin 20518 -> 21090 bytes ...haka_1_1media_1_1mp2t_1_1TsSectionPes.html | 37 +- docs/d1/d31/classshaka_1_1xml_1_1XmlNode.html | 243 +- ...tructshaka_1_1media_1_1SubsampleEntry.html | 17 +- .../d35/classshaka_1_1hls_1_1Tag-members.html | 17 +- docs/d1/d37/es__parser__h264_8h_source.html | 83 +- .../d3b/mpd__generator__flags_8h_source.html | 37 +- ...shaka_1_1media_1_1mp4_1_1MovieExtends.html | 25 +- .../d40/classshaka_1_1MpdWriter-members.html | 17 +- .../structshaka_1_1media_1_1Scte35Event.html | 17 +- ..._1hls_1_1MediaPlaylistFactory-members.html | 17 +- .../decoding__time__iterator_8cc_source.html | 103 +- ...1media_1_1CachingMediaHandler-members.html | 19 +- .../d1/d48/text__track__config_8h_source.html | 69 +- .../d4e/classshaka_1_1media_1_1TextMuxer.html | 219 + .../d4e/classshaka_1_1media_1_1TextMuxer.png | Bin 0 -> 1968 bytes ...a_1_1media_1_1OffsetByteQueue-members.html | 17 +- .../d4f/structshaka_1_1DecryptionParams.html | 21 +- ...aka_1_1media_1_1EncryptionKey-members.html | 22 +- ..._1media_1_1mp4_1_1TrackFragmentHeader.html | 57 +- docs/d1/d70/vp8__parser_8cc_source.html | 224 +- docs/d1/d72/language__utils_8cc_source.html | 162 +- ...media_1_1PackedAudioSegmenter-members.html | 17 +- .../d74/mp2t__media__parser_8cc_source.html | 493 +- ..._1media_1_1H265VideoSliceHeaderParser.html | 25 +- ...shaka_1_1media_1_1Scte35Event-members.html | 17 +- .../d7d/webm__video__client_8cc_source.html | 298 +- docs/d1/d7e/classshaka_1_1hls_1_1Tag.html | 17 +- ...shaka_1_1media_1_1BlockReader-members.html | 23 +- ...ia_1_1H265ReferencePictureSet-members.html | 17 +- ..._1_1media_1_1WebMParserClient-members.html | 17 +- ...1media_1_1AV1CodecConfigurationRecord.html | 17 +- ...dia_1_1SingleThreadJobManager-members.html | 94 + .../classshaka_1_1hls_1_1MasterPlaylist.html | 51 +- .../d8e/webm__audio__client_8cc_source.html | 145 +- docs/d1/d8f/retired__flags_8h_source.html | 38 +- ...aka_1_1media_1_1H26xBitReader-members.html | 17 +- ...a_1_1WidevineEncryptionParams-members.html | 17 +- ...ssshaka_1_1media_1_1ByteQueue-members.html | 17 +- docs/d1/d9d/tracks__builder_8h_source.html | 140 +- ..._1_1mp4_1_1CodecConfiguration-members.html | 17 +- ...assshaka_1_1media_1_1mp4_1_1BoxBuffer.html | 34 +- ...ia_1_1wvm_1_1DemuxStreamIdMediaSample.html | 17 +- ...1NalUnitToByteStreamConverter-members.html | 17 +- ..._1media_1_1VPCodecConfigurationRecord.html | 35 +- ...lassshaka_1_1media_1_1Demuxer-members.html | 19 +- ...a_1_1media_1_1mp4_1_1VideoMediaHeader.html | 25 +- ...oder__configuration__record_8h_source.html | 120 +- ...shaka_1_1media_1_1mp2t_1_1AudioHeader.html | 48 +- ...sshaka_1_1media_1_1mp2t_1_1AudioHeader.png | Bin 1077 -> 1403 bytes ..._1media_1_1PlayReadyKeySource-members.html | 28 +- docs/d1/dc2/h26x__bit__reader_8h_source.html | 122 +- docs/d1/dc7/classshaka_1_1HttpFile.html | 442 + docs/d1/dc7/classshaka_1_1HttpFile.png | Bin 0 -> 486 bytes ...dec__configuration__record_8cc_source.html | 119 +- .../dd5/classshaka_1_1media_1_1Cluster.html | 17 +- ...dia_1_1mp4_1_1DataInformation-members.html | 17 +- ...tructshaka_1_1PackagingParams-members.html | 24 +- ..._1_1media_1_1EncryptionConfig-members.html | 17 +- ...a_1_1media_1_1VideoStreamInfo-members.html | 17 +- ...position__offset__iterator_8cc_source.html | 94 +- ...sshaka_1_1media_1_1KeyFetcher-members.html | 17 +- ...sshaka_1_1xml_1_1AdaptationSetXmlNode.html | 127 +- ...rencePictureListModifications-members.html | 17 +- ..._1_1media_1_1ProgressListener-members.html | 17 +- ...assshaka_1_1media_1_1mp4_1_1BoxReader.html | 31 +- ...tshaka_1_1media_1_1mp4_1_1SampleTable.html | 25 +- docs/d1/df0/aes__encryptor_8h_source.html | 130 +- docs/d1/df3/structshaka_1_1MpdOptions.html | 17 +- docs/d1/df5/nalu__reader_8cc_source.html | 518 +- ...ia_1_1mp4_1_1VideoMediaHeader-members.html | 17 +- docs/d2/d02/timestamp_8h_source.html | 43 +- ...assshaka_1_1media_1_1SeekHead-members.html | 17 +- ...ka_1_1media_1_1mp4_1_1NullMediaHeader.html | 162 + ...aka_1_1media_1_1mp4_1_1NullMediaHeader.png | Bin 0 -> 1107 bytes .../d0f/classshaka_1_1MpdBuilder-members.html | 19 +- ...aka_1_1media_1_1wvm_1_1PrevSampleData.html | 17 +- ...aka_1_1media_1_1MuxerListener-members.html | 17 +- docs/d2/d17/ts__section__pat_8cc_source.html | 143 +- .../d2/d1f/structshaka_1_1ChunkingParams.html | 17 +- docs/d2/d20/classshaka_1_1Status.html | 17 +- .../d2/d23/threaded__io__file_8cc_source.html | 249 +- ...classshaka_1_1media_1_1PsshBoxBuilder.html | 19 +- docs/d2/d24/packager__util_8h_source.html | 61 +- ...sshaka_1_1media_1_1LineReader-members.html | 23 +- .../aes__encryptor__factory_8cc_source.html | 109 +- .../d2/d2a/classshaka_1_1IoCache-members.html | 17 +- docs/d2/d30/tracks__builder_8cc_source.html | 415 +- ...ideo__slice__header__parser_8h_source.html | 111 +- ...1_1media_1_1WidevineKeySource-members.html | 26 +- .../classshaka_1_1media_1_1Job-members.html | 17 +- docs/d2/d3b/manifest__flags_8cc_source.html | 54 +- docs/d2/d3c/muxer__factory_8cc_source.html | 128 +- ...1_1mp4_1_1TrackFragmentHeader-members.html | 17 +- .../webvtt__to__mp4__handler_8h_source.html | 81 +- ...rogram__map__table__writer_8cc_source.html | 387 +- ...o__byte__stream__converter_8cc_source.html | 449 +- docs/d2/d4d/file_8h_source.html | 171 +- .../d4f/structshaka_1_1Element-members.html | 17 +- ...classshaka_1_1MockMpdNotifier-members.html | 58 +- docs/d2/d57/master__playlist_8h_source.html | 69 +- ...ructshaka_1_1media_1_1H264SliceHeader.html | 33 +- ...ssshaka_1_1media_1_1KeySource-members.html | 22 +- ...assshaka_1_1SimpleMpdNotifier-members.html | 44 +- ...a_1_1H264ModificationOfPicNum-members.html | 17 +- .../d62/simple__mpd__notifier_8h_source.html | 121 +- ...haka_1_1media_1_1mp4_1_1Movie-members.html | 17 +- ...sshaka_1_1media_1_1AesCryptor-members.html | 17 +- ...ctshaka_1_1media_1_1mp4_1_1SchemeInfo.html | 25 +- ...edia_1_1CombinedMuxerListener-members.html | 21 +- ...ka_1_1media_1_1JobManager_1_1JobEntry.html | 97 + .../d7b/simple__mpd__notifier_8cc_source.html | 247 +- .../d7b/structshaka_1_1StreamDescriptor.html | 72 +- ...ac__audio__specific__config_8h_source.html | 160 +- ...haka_1_1media_1_1mp4_1_1CuePayloadBox.html | 25 +- ...shaka_1_1BufferCallbackParams-members.html | 17 +- ...ls__notify__muxer__listener_8h_source.html | 130 +- ...media_1_1mp4_1_1CuePayloadBox-members.html | 17 +- docs/d2/d92/box__reader_8h_source.html | 188 +- ...ssshaka_1_1media_1_1mp2t_1_1PesPacket.html | 17 +- .../structshaka_1_1FileCloser-members.html | 17 +- ..._1_1media_1_1TrickPlayHandler-members.html | 19 +- docs/d2/da6/threaded__io__file_8h_source.html | 107 +- docs/d2/da8/mp4_2segmenter_8cc_source.html | 396 +- ...haka_1_1media_1_1BufferWriter-members.html | 17 +- ...assshaka_1_1MockAdaptationSet-members.html | 73 +- docs/d2/dae/webm__muxer_8cc_source.html | 176 +- docs/d2/db1/master__playlist_8cc_source.html | 553 +- ...media_1_1mp4_1_1SampleToGroup-members.html | 17 +- ...a_1_1media_1_1mp4_1_1FileType-members.html | 17 +- ...edia_1_1mp4_1_1CueSourceIDBox-members.html | 17 +- ...lassshaka_1_1media_1_1SegmentTestBase.html | 29 +- ...classshaka_1_1media_1_1SegmentTestBase.png | Bin 627 -> 703 bytes ...shaka_1_1media_1_1TextChunker-members.html | 19 +- docs/d2/dbc/av1__parser_8cc_source.html | 1896 ++- docs/d2/dbf/status__macros_8h_source.html | 43 +- ...haka_1_1media_1_1mp4_1_1Track-members.html | 17 +- ...media__handler__test__base_8cc_source.html | 397 +- .../structshaka_1_1MpdOptions-members.html | 17 +- ...program__map__table__writer_8h_source.html | 129 +- ...a_1_1media_1_1mp4_1_1EditList-members.html | 17 +- docs/d2/dcd/tag_8h_source.html | 83 +- ...structshaka_1_1WidevineSigner-members.html | 17 +- ...edia_1_1webm_1_1MultiSegmentSegmenter.html | 29 +- docs/d2/dd6/mkv__writer_8h_source.html | 91 +- .../structshaka_1_1RawKeyParams-members.html | 17 +- ...a_1_1media_1_1ChunkingHandler-members.html | 19 +- ...lassshaka_1_1media_1_1WebMMediaParser.html | 55 +- docs/d2/ddc/hls__audio__util_8h_source.html | 44 +- docs/d2/de1/dvb__image_8h_source.html | 194 + docs/d2/de1/webvtt__timestamp_8h_source.html | 78 - ...haka_1_1media_1_1mp2t_1_1TsSectionPmt.html | 45 +- docs/d2/de6/packager__main_8cc_source.html | 625 +- ...ka_1_1media_1_1TextStreamInfo-members.html | 55 +- ...shaka_1_1media_1_1mp4_1_1Edit-members.html | 17 +- docs/d2/de9/media__handler_8cc_source.html | 161 +- .../de9/mock__muxer__listener_8h_source.html | 122 +- docs/d2/deb/es__parser_8h_source.html | 74 +- ...media_1_1mp2t_1_1TsSectionPes-members.html | 17 +- .../pes__packet__generator_8cc_source.html | 204 +- docs/d2/def/webvtt__muxer_8cc_source.html | 145 + ..._1media_1_1mp4_1_1AC4Specific-members.html | 94 + ...a_1_1SegmentTestBase_1_1ClusterParser.html | 21 +- ...ssshaka_1_1media_1_1MkvWriter-members.html | 17 +- docs/d2/dfd/adts__header_8h_source.html | 98 +- ...dia_1_1OnNewSegmentParameters-members.html | 17 +- ..._1_1media_1_1mp4_1_1BoxReader-members.html | 48 +- docs/d3/d07/mpd__params_8h_source.html | 92 +- ..._1_1mp4_1_1SyncSampleIterator-members.html | 17 +- .../classshaka_1_1media_1_1MediaParser.html | 100 +- .../classshaka_1_1media_1_1MediaParser.png | Bin 1696 -> 1981 bytes ...sshaka_1_1media_1_1mp2t_1_1AdtsHeader.html | 21 +- ..._1media_1_1LibcryptoThreading-members.html | 17 +- ...1media_1_1mp4_1_1FlacSpecific-members.html | 17 +- ...media_1_1mp2t_1_1TsSectionPat-members.html | 17 +- docs/d3/d19/io__cache_8h_source.html | 99 +- .../classshaka_1_1media_1_1Replicator.html | 27 +- ...aka_1_1media_1_1FakeInputMediaHandler.html | 67 +- ...deo__slice__header__parser_8cc_source.html | 173 +- docs/d3/d48/packager_8cc_source.html | 1125 +- ...sshaka_1_1media_1_1LibcryptoThreading.html | 17 +- .../classshaka_1_1media_1_1JobManager.html | 58 +- .../d53/classshaka_1_1media_1_1JobManager.png | Bin 0 -> 863 bytes .../structshaka_1_1media_1_1TextFragment.html | 133 + docs/d3/d56/decrypt__config_8cc_source.html | 69 +- docs/d3/d5f/sync__point__queue_8h_source.html | 90 +- .../d3/d62/continuity__counter_8h_source.html | 55 +- docs/d3/d62/rcheck_8h_source.html | 37 +- ...1media_1_1mp4_1_1DataEntryUrl-members.html | 17 +- ...lassshaka_1_1media_1_1WebMVideoClient.html | 25 +- ...structshaka_1_1MpdParams_1_1UtcTiming.html | 17 +- .../ad__cue__generator__params_8h_source.html | 55 +- ...lassshaka_1_1media_1_1mp2t_1_1TsMuxer.html | 27 +- docs/d3/d73/classshaka_1_1File.html | 92 +- docs/d3/d73/classshaka_1_1File.png | Bin 1523 -> 1705 bytes ...ssshaka_1_1media_1_1webm_1_1WebMMuxer.html | 29 +- .../classshaka_1_1media_1_1AesEncryptor.html | 25 +- ...a_1_1mp4_1_1ChunkInfoIterator-members.html | 17 +- docs/d3/d76/muxer__flags_8h_source.html | 43 +- ...dia_1_1mp4_1_1TextSampleEntry-members.html | 23 +- docs/d3/d7a/ttml__muxer_8h_source.html | 120 + ...haka_1_1media_1_1RsaPublicKey-members.html | 17 +- ...lassshaka_1_1media_1_1WebMAudioClient.html | 25 +- ...tshaka_1_1media_1_1TextRegion-members.html | 88 + docs/d3/d80/muxer__util_8h_source.html | 51 +- ...haka_1_1media_1_1mp4_1_1SampleToChunk.html | 25 +- .../d87/trick__play__handler_8cc_source.html | 216 +- .../d3/d8d/webm__audio__client_8h_source.html | 77 +- docs/d3/d90/ec3__audio__util_8cc_source.html | 308 +- .../classshaka_1_1media_1_1H264Parser.html | 27 +- docs/d3/d93/media__handler_8h_source.html | 296 +- ...lassshaka_1_1hls_1_1MockMediaPlaylist.html | 61 +- ...1_1media_1_1MediaHandlerGraphTestBase.html | 29 +- ..._1_1media_1_1MediaHandlerGraphTestBase.png | Bin 1113 -> 1199 bytes .../d9c/encryption__handler_8cc_source.html | 441 +- docs/d3/da0/ec3__audio__util_8h_source.html | 52 +- ...dia_1_1webm_1_1SingleSegmentSegmenter.html | 23 +- ...ctshaka_1_1media_1_1mp4_1_1SchemeType.html | 25 +- ...aka_1_1MpdParams_1_1UtcTiming-members.html | 17 +- .../structshaka_1_1media_1_1mp4_1_1ID3v2.html | 25 +- ..._1_1media_1_1WebMWebVTTParser-members.html | 17 +- .../structshaka_1_1media_1_1mp4_1_1Track.html | 25 +- docs/d3/db6/webm__parser_8cc_source.html | 1022 +- docs/d3/dbc/seek__head_8cc_source.html | 135 +- docs/d3/dbe/demuxer_8cc_source.html | 458 +- ...ructshaka_1_1media_1_1mp4_1_1EditList.html | 25 +- ...ructshaka_1_1DecryptionParams-members.html | 17 +- ...a_1_1media_1_1mp2t_1_1Mp2tMediaParser.html | 57 +- docs/d3/dd0/classshaka_1_1MpdNotifier.html | 67 +- ...tshaka_1_1media_1_1mp4_1_1SegmentType.html | 25 +- docs/d3/dd7/id3__tag_8h_source.html | 80 +- ...ka_1_1media_1_1PlayReadyPsshGenerator.html | 31 +- docs/d3/de2/structshaka_1_1FileCloser.html | 17 +- docs/d3/de4/seek__head_8h_source.html | 85 +- docs/d3/de6/job__manager_8h_source.html | 133 +- ..._1_1media_1_1mp4_1_1BoxBuffer-members.html | 50 +- ...mp4_1_1SampleGroupDescription-members.html | 17 +- .../deb/packed__audio__writer_8cc_source.html | 185 +- docs/d3/df1/box__reader_8cc_source.html | 193 +- ...haka_1_1media_1_1CueEventInfo-members.html | 17 +- ...1media_1_1CueAlignmentHandler-members.html | 19 +- ...ssshaka_1_1media_1_1AesPatternCryptor.html | 29 +- ...2multi__segment__segmenter_8cc_source.html | 200 +- ...shaka_1_1media_1_1AesEncryptorFactory.html | 17 +- ...edia_1_1mp4_1_1MP4MediaParser-members.html | 28 +- .../d0b/classshaka_1_1media_1_1TextTrack.html | 17 +- docs/d4/d0c/text__readers_8h_source.html | 93 +- .../d4/d15/gflags__hex__bytes_8cc_source.html | 44 +- ...haka_1_1media_1_1mp4_1_1EditListEntry.html | 19 +- docs/d4/d1e/webvtt__utils_8h_source.html | 119 + ...lassshaka_1_1media_1_1AesCbcEncryptor.html | 25 +- ...ia_1_1mp4_1_1ChunkLargeOffset-members.html | 17 +- ..._1_1media_1_1SegmentEventInfo-members.html | 17 +- ...haka_1_1media_1_1mp4_1_1ID3v2-members.html | 17 +- ...1media_1_1mp4_1_1WebVTTSourceLabelBox.html | 25 +- docs/d4/d37/io__cache_8cc_source.html | 184 +- ...ructshaka_1_1media_1_1H264Sps-members.html | 68 +- .../sample__aes__ec3__cryptor_8h_source.html | 68 +- ...lassshaka_1_1media_1_1ChunkingHandler.html | 27 +- ...pleAuxiliaryInformationOffset-members.html | 17 +- ...haka_1_1media_1_1H264WeightingFactors.html | 19 +- docs/d4/d51/ttml__muxer_8cc_source.html | 125 + ...1media_1_1mp2t_1_1Mpeg1Header-members.html | 96 + .../classshaka_1_1media_1_1Nalu-members.html | 17 +- ...assshaka_1_1media_1_1WebMWebVTTParser.html | 17 +- ...aka_1_1media_1_1DecryptConfig-members.html | 17 +- .../structshaka_1_1media_1_1TextRegion.html | 163 + .../ad__cue__generator__flags_8h_source.html | 33 +- ...1_1media_1_1ttml_1_1TtmlMuxer-members.html | 120 + .../structshaka_1_1SegmentInfo-members.html | 17 +- docs/d4/d87/nalu__reader_8h_source.html | 256 +- docs/d4/d87/text__sample_8cc_source.html | 59 +- ...dia_1_1HEVCDecoderConfigurationRecord.html | 21 +- ...ssshaka_1_1BandwidthEstimator-members.html | 17 +- ...tshaka_1_1media_1_1mp4_1_1EC3Specific.html | 25 +- ...haka_1_1media_1_1MediaHandlerTestBase.html | 23 +- ...shaka_1_1media_1_1MediaHandlerTestBase.png | Bin 1124 -> 1208 bytes ...ctshaka_1_1media_1_1TextFragmentStyle.html | 100 + ...sshaka_1_1media_1_1PlayReadyKeySource.html | 137 +- .../da7/segmenter__test__base_8cc_source.html | 254 +- .../d4/da9/subtitle__composer_8cc_source.html | 333 + ...a_1_1media_1_1mp4_1_1SampleEncryption.html | 29 +- ...a_1_1mp4_1_1CompactSampleSize-members.html | 17 +- docs/d4/db2/cluster__builder_8h_source.html | 112 +- .../db4/classshaka_1_1MpdNotifierFactory.html | 17 +- ...tshaka_1_1media_1_1mp4_1_1MediaHeader.html | 25 +- docs/d4/dcb/classshaka_1_1UdpFile.html | 31 +- docs/d4/dd3/bit__reader_8h_source.html | 130 +- ...ka_1_1media_1_1mp4_1_1FullBox-members.html | 17 +- docs/d4/dd6/raw__key__source_8cc_source.html | 190 +- docs/d4/dde/webvtt__util_8h_source.html | 53 +- ...haka_1_1media_1_1mp4_1_1DataReference.html | 25 +- ...assshaka_1_1media_1_1ProgressListener.html | 17 +- ...VodMediaInfoDumpMuxerListener-members.html | 17 +- docs/d4/dec/hls__flags_8h_source.html | 37 +- docs/d4/df5/request__signer_8cc_source.html | 105 +- ...shaka_1_1media_1_1mp4_1_1SegmentIndex.html | 25 +- .../structshaka_1_1media_1_1RgbaColor.html | 113 + ...tshaka_1_1media_1_1mp4_1_1AC3Specific.html | 25 +- .../dfd/structshaka_1_1media_1_1H265Sps.html | 17 +- .../dff/webm__media__parser_8cc_source.html | 304 +- .../common__pssh__generator_8h_source.html | 63 +- ...ructshaka_1_1media_1_1mp4_1_1FileType.html | 25 +- ...aka_1_1media_1_1mp4_1_1OriginalFormat.html | 25 +- ...ructshaka_1_1media_1_1mp4_1_1CueIDBox.html | 25 +- ..._1_1EncryptedStreamAttributes-members.html | 17 +- ...ka_1_1media_1_1WebMInfoParser-members.html | 17 +- ..._1_1mp4_1_1ElementaryStreamDescriptor.html | 25 +- .../classshaka_1_1media_1_1ESDescriptor.html | 26 +- .../producer__consumer__queue_8h_source.html | 315 +- .../d1a/classshaka_1_1Packager-members.html | 17 +- docs/d5/d1a/ts__section_8h_source.html | 64 +- ...playready__pssh__generator_8cc_source.html | 228 +- ...ia_1_1mp4_1_1TrackRunIterator-members.html | 17 +- docs/d5/d27/key__fetcher_8cc_source.html | 35 +- docs/d5/d28/webvtt__utils_8cc_source.html | 391 + docs/d5/d2a/proto__json__util_8cc_source.html | 61 +- ...aka_1_1media_1_1ProducerConsumerQueue.html | 17 +- ...haka_1_1media_1_1mp4_1_1Media-members.html | 17 +- .../classshaka_1_1media_1_1TextChunker.html | 27 +- ...2single__segment__segmenter_8h_source.html | 100 +- ...media_1_1mp2t_1_1TsSectionPsi-members.html | 17 +- .../d4b/packed__audio__writer_8h_source.html | 94 +- docs/d5/d4d/box_8cc_source.html | 124 +- .../packed__audio__segmenter_8cc_source.html | 196 +- docs/d5/d52/ts__section__pes_8h_source.html | 92 +- ...ampleAuxiliaryInformationSize-members.html | 17 +- ...esentationStateChangeListener-members.html | 17 +- ...a_1_1media_1_1DecoderConfigDescriptor.html | 27 +- ...ssshaka_1_1MockRepresentation-members.html | 19 +- docs/d5/d5a/webvtt__timestamp_8cc_source.html | 78 - docs/d5/d5b/dvb__sub__parser_8cc_source.html | 562 + .../d5c/continuity__counter_8cc_source.html | 46 +- ...haka_1_1media_1_1mp2t_1_1EsParserH265.html | 42 +- docs/d5/d63/network__util_8cc_source.html | 51 +- ...media_1_1NalUnitToByteStreamConverter.html | 21 +- ...aka_1_1media_1_1WidevinePsshGenerator.html | 21 +- ...1media_1_1AesEncryptorFactory-members.html | 17 +- docs/d5/d6f/vlog__flags_8cc_source.html | 45 +- ...der__configuration__record_8cc_source.html | 158 +- .../d5/d76/classshaka_1_1hls_1_1HlsEntry.html | 25 +- docs/d5/d7b/box__definitions_8h_source.html | 1064 +- ...a_1_1media_1_1mp4_1_1MediaInformation.html | 28 +- .../d89/widevine__key__source_8cc_source.html | 560 +- ..._1_1media_1_1mp4_1_1CompositionOffset.html | 19 +- ...1media_1_1SampleAesEc3Cryptor-members.html | 17 +- .../d8f/webm__cluster__parser_8cc_source.html | 701 +- ...media_1_1mp4_1_1EditListEntry-members.html | 17 +- docs/d5/d98/encryptor_8cc_source.html | 134 +- ...odec__configuration__record_8h_source.html | 259 +- ...H265ReferencePictureListModifications.html | 17 +- docs/d5/da4/aes__encryptor_8cc_source.html | 234 +- ...a_1_1media_1_1H265ReferencePictureSet.html | 17 +- .../classshaka_1_1media_1_1StreamInfo.html | 31 +- docs/d5/db8/text__muxer_8cc_source.html | 172 + ...haka_1_1media_1_1mp2t_1_1EsParserH264.html | 42 +- docs/d5/dba/ts__packet_8cc_source.html | 236 +- ..._1media_1_1TextSubStreamInfo-members.html} | 26 +- .../dc1/webm__webvtt__parser_8cc_source.html | 102 +- ...media_1_1mp4_1_1TrackFragment-members.html | 17 +- ...4_1_1SampleAuxiliaryInformationOffset.html | 25 +- ...raw__key__encryption__flags_8h_source.html | 51 +- docs/d5/dcf/rsa__key_8h_source.html | 99 +- ...tshaka_1_1media_1_1TextNumber-members.html | 84 + docs/d5/dda/ts__section__psi_8h_source.html | 84 +- ...vtt__text__output__handler_8cc_source.html | 81 - ...ctshaka_1_1media_1_1RgbaColor-members.html | 87 + docs/d5/de0/bit__reader_8cc_source.html | 140 +- ..._1media_1_1mp2t_1_1PesPacketGenerator.html | 25 +- ...ListenerFactory_1_1StreamData-members.html | 29 +- .../de3/structshaka_1_1PackagingParams.html | 36 +- docs/d5/de9/replicator_8cc_source.html | 62 +- ...assshaka_1_1media_1_1WebMParserClient.html | 31 +- ...der__configuration__record_8cc_source.html | 55 +- ...mp4_1_1WebVTTConfigurationBox-members.html | 17 +- docs/d5/def/ts__section__pmt_8h_source.html | 67 +- docs/d5/df2/media__playlist_8cc_source.html | 824 +- .../common__pssh__generator_8cc_source.html | 65 +- ...ka_1_1media_1_1HlsNotifyMuxerListener.html | 37 +- ...shaka_1_1media_1_1MediaParser-members.html | 26 +- docs/d5/dfc/file_8cc_source.html | 491 +- docs/d5/dfe/classshaka_1_1File-members.html | 17 +- ...ady__key__encryption__flags_8h_source.html | 47 +- ...a_1_1media_1_1AesCbcDecryptor-members.html | 17 +- .../d09/aes__pattern__cryptor_8h_source.html | 84 +- .../d6/d16/text__stream__info_8cc_source.html | 79 +- docs/d6/d17/es__parser__h264_8cc_source.html | 210 +- ..._1AV1CodecConfigurationRecord-members.html | 17 +- ...tshaka_1_1media_1_1mp4_1_1MovieHeader.html | 25 +- .../ts__packet__writer__util_8cc_source.html | 184 +- ..._1media_1_1DvbImageColorSpace-members.html | 90 + ...1_1media_1_1VideoStreamInfoParameters.html | 17 +- ...ka_1_1media_1_1WebVttTextOutputHandler.png | Bin 826 -> 0 bytes docs/d6/d2c/ts__stream__type_8h_source.html | 73 +- .../d2e/mpd__notifier__util_8cc_source.html | 87 +- ...ssshaka_1_1media_1_1TextTrack-members.html | 17 +- .../webm__content__encodings_8cc_source.html | 49 +- .../combined__muxer__listener_8cc_source.html | 125 +- .../d3b/chunk__info__iterator_8cc_source.html | 106 +- .../d3e/pssh__generator__util_8h_source.html | 43 +- .../structshaka_1_1media_1_1CueEventInfo.html | 17 +- docs/d6/d47/hls__params_8h_source.html | 76 +- ...ssshaka_1_1media_1_1PackedAudioWriter.html | 29 +- ...ssshaka_1_1media_1_1EncryptionHandler.html | 31 +- ...2multi__segment__segmenter_8cc_source.html | 135 +- docs/d6/d55/aes__cryptor_8cc_source.html | 164 +- ...edia_1_1AVCDecoderConfigurationRecord.html | 34 +- ...ion__system__specific__info_8h_source.html | 101 +- docs/d6/d5b/classshaka_1_1Status-members.html | 17 +- ...1_1VPCodecConfigurationRecord-members.html | 17 +- docs/d6/d62/structshaka_1_1TestParams.html | 17 +- ...ka_1_1RawKeyParams_1_1KeyInfo-members.html | 22 +- ...haka_1_1media_1_1RawKeySource-members.html | 26 +- docs/d6/d6c/h26x__bit__reader_8cc_source.html | 205 +- docs/d6/d6e/ts__section__pes_8cc_source.html | 337 +- docs/d6/d71/scoped__xml__ptr_8h_source.html | 65 +- .../d74/classshaka_1_1UdpOptions-members.html | 17 +- ...1media_1_1mp4_1_1VTTAdditionalTextBox.html | 25 +- .../d7b/webm__tracks__parser_8h_source.html | 141 +- ..._1media_1_1mp4_1_1AC3Specific-members.html | 17 +- ...ti__codec__muxer__listener_8cc_source.html | 126 + .../d86/bandwidth__estimator_8cc_source.html | 138 +- docs/d6/d8a/vp9__parser_8cc_source.html | 632 +- ..._1_1RepresentationBaseXmlNode-members.html | 51 +- ..._1_1ttml_1_1TtmlToMp4Handler-members.html} | 36 +- docs/d6/d9b/h264__parser_8h_source.html | 377 +- docs/d6/d9f/hls__flags_8cc_source.html | 51 +- .../webvtt__to__mp4__handler_8cc_source.html | 287 +- docs/d6/da0/ts__section__pat_8h_source.html | 67 +- ...tshaka_1_1media_1_1mp4_1_1AC4Specific.html | 160 + ...ctshaka_1_1media_1_1mp4_1_1AC4Specific.png | Bin 0 -> 742 bytes docs/d6/da3/mpd__builder_8h_source.html | 144 +- ...AVCDecoderConfigurationRecord-members.html | 64 +- ...iceHeader_1_1LongTermPicsInfo-members.html | 17 +- .../da9/classshaka_1_1media_1_1BitReader.html | 49 +- ...uctshaka_1_1media_1_1mp4_1_1VTTCueBox.html | 25 +- .../widevine__pssh__generator_8cc_source.html | 76 +- ...lassshaka_1_1media_1_1VideoStreamInfo.html | 23 +- ..._1_1VideoStreamInfoParameters-members.html | 17 +- .../classshaka_1_1media_1_1FileReader.html | 166 - .../d6/dbe/mp4__output__params_8h_source.html | 44 +- ...classshaka_1_1hls_1_1HlsEntry-members.html | 17 +- ...sParserH26x_1_1VideoSliceInfo-members.html | 17 +- ...media_1_1mp2t_1_1EsParserH26x-members.html | 38 +- docs/d6/dc8/mkv__writer_8cc_source.html | 129 +- ...media_1_1mp4_1_1SampleEncryptionEntry.html | 27 +- ...ssshaka_1_1media_1_1VP9Parser-members.html | 17 +- ...ia_1_1mp4_1_1SegmentReference-members.html | 17 +- ...tructshaka_1_1media_1_1H264SEIMessage.html | 22 +- ...DecoderSpecificInfoDescriptor-members.html | 17 +- ...tructshaka_1_1Mp4OutputParams-members.html | 17 +- ...assshaka_1_1media_1_1WebVttFileBuffer.html | 23 +- ...1_1media_1_1H265VuiParameters-members.html | 17 +- ...shaka_1_1media_1_1mp4_1_1KeyFrameInfo.html | 17 +- ...1_1media_1_1mp4_1_1CueTimeBox-members.html | 17 +- ...haka_1_1media_1_1VPxFrameInfo-members.html | 17 +- docs/d6/de8/local__file_8cc_source.html | 246 +- docs/d6/de8/network__util_8h_source.html | 39 +- docs/d6/de9/ts__segmenter_8cc_source.html | 277 +- docs/d6/ded/ts__packet_8h_source.html | 100 +- .../sync__sample__iterator_8cc_source.html | 73 +- ...ructshaka_1_1StreamDescriptor-members.html | 40 +- ...1media_1_1mp2t_1_1AudioHeader-members.html | 17 +- docs/d6/dff/classshaka_1_1media_1_1Nalu.html | 131 +- ...haka_1_1media_1_1MuxerFactory-members.html | 18 +- ...edia_1_1mp4_1_1SampleGroupDescription.html | 25 +- ...a_1_1media_1_1mp4_1_1SoundMediaHeader.html | 25 +- ...xer__listener__test__helper_8h_source.html | 131 +- docs/d7/d12/media__parser_8h_source.html | 92 +- docs/d7/d15/mpd__notifier_8h_source.html | 115 +- ...ia_1_1mp4_1_1VideoSampleEntry-members.html | 17 +- docs/d7/d1d/text__chunker_8h_source.html | 89 +- .../d1e/subsample__generator_8cc_source.html | 420 +- docs/d7/d20/period_8h_source.html | 179 +- .../d21/classshaka_1_1MockPeriod-members.html | 22 +- .../d22/libcrypto__threading_8h_source.html | 48 +- ...1_1media_1_1mp4_1_1SyncSampleIterator.html | 17 +- ...ructshaka_1_1media_1_1H265Sps-members.html | 17 +- ...p4_1_1CompositionTimeToSample-members.html | 17 +- docs/d7/d2a/manifest__flags_8h_source.html | 38 +- ...assshaka_1_1media_1_1SubtitleComposer.html | 126 + ...uctshaka_1_1media_1_1EncryptionConfig.html | 17 +- ...a_1_1media_1_1ContentEncoding-members.html | 21 +- ...ctshaka_1_1media_1_1AV1Parser_1_1Tile.html | 17 +- ...on__system__specific__info_8cc_source.html | 184 +- ...ctshaka_1_1media_1_1mp4_1_1SampleSize.html | 25 +- ...ia_1_1mp4_1_1SampleEncryption-members.html | 17 +- ...ka_1_1media_1_1WebMListParser-members.html | 17 +- ...1media_1_1CommonPsshGenerator-members.html | 17 +- ...sshaka_1_1media_1_1WebVttToMp4Handler.html | 27 +- ...H26xByteToUnitStreamConverter-members.html | 17 +- ...lassshaka_1_1media_1_1DecryptorSource.html | 23 +- ...ka_1_1media_1_1SyncPointQueue-members.html | 17 +- ...lassshaka_1_1hls_1_1SimpleHlsNotifier.html | 40 +- .../d6c/structshaka_1_1HlsParams-members.html | 23 +- .../classshaka_1_1media_1_1MediaSample.html | 29 +- ...onParams_1_1EncryptedStreamAttributes.html | 29 +- ...ka_1_1media_1_1MockAesCryptor-members.html | 17 +- docs/d7/d75/callback__file_8h_source.html | 82 +- ..._1media_1_1mp4_1_1MediaHeader-members.html | 17 +- ...ka_1_1media_1_1H264SEIMessage-members.html | 28 +- docs/d7/d79/chunking__handler_8h_source.html | 106 +- docs/d7/d7c/vlog__flags_8h_source.html | 34 +- .../d7/d87/video__stream__info_8h_source.html | 158 +- docs/d7/d91/text__padder_8h_source.html | 65 +- ...shaka_1_1media_1_1CachingMediaHandler.html | 29 +- docs/d7/d94/representation_8cc_source.html | 612 +- ..._1H265SliceHeader_1_1LongTermPicsInfo.html | 17 +- docs/d7/d9d/progress__listener_8h_source.html | 58 +- ...ia_1_1JobManager_1_1JobEntry-members.html} | 28 +- .../da4/track__run__iterator_8h_source.html | 153 +- .../dad/simple__hls__notifier_8cc_source.html | 577 +- ...uctshaka_1_1media_1_1mp4_1_1MediaData.html | 25 +- docs/d7/db0/mpd__writer_8h_source.html | 112 +- ...media_1_1mp4_1_1SampleToChunk-members.html | 17 +- docs/d7/dbd/classshaka_1_1LocalFile.html | 31 +- ...ka_1_1media_1_1mp4_1_1TextSampleEntry.html | 31 +- docs/d7/dc6/byte__queue_8h_source.html | 80 +- ...ka_1_1media_1_1CcStreamFilter-members.html | 107 + .../d7/dd0/mpd__notifier__util_8h_source.html | 60 +- docs/d7/dd4/request__signer_8h_source.html | 113 +- docs/d7/dd5/ac4__audio__util_8h_source.html | 114 + ...aka_1_1media_1_1mp4_1_1MP4MediaParser.html | 59 +- docs/d7/dd6/key__source_8cc_source.html | 39 +- .../dda/classshaka_1_1media_1_1ByteQueue.html | 25 +- ...assshaka_1_1media_1_1RsaRequestSigner.html | 31 +- .../d7/dde/cc__stream__filter_8cc_source.html | 135 + ...1ProtectionSystemSpecificInfo-members.html | 17 +- ...classshaka_1_1media_1_1HttpKeyFetcher.html | 128 +- ...1_1media_1_1mp4_1_1SampleToGroupEntry.html | 23 +- ...to__unit__stream__converter_8h_source.html | 73 +- docs/d7/dee/mpd__generator_8cc_source.html | 176 +- .../d7/def/mp4__media__parser_8cc_source.html | 978 +- docs/d7/df9/byte__queue_8cc_source.html | 110 +- ...1_1media_1_1TextFragmentStyle-members.html | 84 + docs/d8/d02/classshaka_1_1MockPeriod.html | 27 +- ...edia_1_1ttml_1_1TtmlGenerator-members.html | 88 + ...edia_1_1H264ByteToUnitStreamConverter.html | 31 +- ...1_1media_1_1WebMClusterParser-members.html | 19 +- ..._1_1media_1_1mp2t_1_1TsWriter-members.html | 23 +- ..._1media_1_1mp4_1_1MovieHeader-members.html | 17 +- ...ia_1_1MultiCodecMuxerListener-members.html | 103 + ...bvtt__text__output__handler_8h_source.html | 86 - docs/d8/d0d/media__sample_8cc_source.html | 159 +- .../protection__system__flags_8h_source.html | 35 +- ...shaka_1_1media_1_1mp4_1_1DecodingTime.html | 19 +- ...ssshaka_1_1media_1_1BitReader-members.html | 32 +- .../d14/classshaka_1_1media_1_1VP8Parser.html | 21 +- docs/d8/d16/http__file_8cc_source.html | 424 + ...haka_1_1media_1_1MuxerOptions-members.html | 17 +- .../d19/bandwidth__estimator_8h_source.html | 80 +- docs/d8/d1c/crypto__flags_8cc_source.html | 78 +- ...edia_1_1mp4_1_1WebVTTConfigurationBox.html | 25 +- ...ka_1_1media_1_1SubsampleEntry-members.html | 17 +- docs/d8/d28/es__parser__h265_8h_source.html | 86 +- ..._content__encodings__client_8h_source.html | 71 +- ...ructshaka_1_1WidevineDecryptionParams.html | 19 +- docs/d8/d4a/mpeg1__header_8h_source.html | 141 + docs/d8/d4d/aes__decryptor_8h_source.html | 81 +- ...sshaka_1_1media_1_1TextSample-members.html | 37 +- docs/d8/d51/text__readers_8cc_source.html | 139 +- docs/d8/d53/crypto__flags_8h_source.html | 40 +- ...edia_1_1webvtt_1_1WebVttMuxer-members.html | 120 + ...a_1_1media_1_1mp4_1_1AudioSampleEntry.html | 28 +- docs/d8/d61/ac3__audio__util_8cc_source.html | 71 +- .../d8/d66/classshaka_1_1UdpFile-members.html | 17 +- ...ka_1_1media_1_1ClusterBuilder-members.html | 17 +- ...ka_1_1media_1_1mp4_1_1DataInformation.html | 25 +- docs/d8/d6f/origin__handler_8h_source.html | 69 +- ...a_1_1media_1_1mp4_1_1Metadata-members.html | 17 +- docs/d8/d72/adaptation__set_8h_source.html | 269 +- .../classshaka_1_1media_1_1TracksBuilder.html | 17 +- .../d81/classshaka_1_1LocalFile-members.html | 17 +- ...assshaka_1_1media_1_1WebMTracksParser.html | 21 +- ...1media_1_1mp4_1_1MovieExtends-members.html | 17 +- docs/d8/d8e/classshaka_1_1AdaptationSet.html | 137 +- ...a_1_1media_1_1AesCtrEncryptor-members.html | 17 +- ..._1_1media_1_1AesRequestSigner-members.html | 17 +- ...media_1_1H264DecRefPicMarking-members.html | 17 +- ...1_1mp4_1_1SubtitleMediaHeader-members.html | 17 +- docs/d8/d94/pes__packet_8h_source.html | 106 +- .../structshaka_1_1media_1_1TextNumber.html} | 54 +- ..._1mp4_1_1VTTAdditionalTextBox-members.html | 17 +- docs/d8/d9a/fragmenter_8cc_source.html | 360 +- .../d9c/webm__tracks__parser_8cc_source.html | 383 +- docs/d8/d9f/udp__file_8h_source.html | 95 +- ...a_1_1media_1_1DecryptorSource-members.html | 17 +- ...1_1media_1_1mp4_1_1SampleSize-members.html | 17 +- ...sshaka_1_1media_1_1NaluReader-members.html | 17 +- .../classshaka_1_1media_1_1DvbSubParser.html | 111 + docs/d8/daa/stream__info_8h_source.html | 176 +- docs/d8/daf/namespaceshaka.html | 367 +- ...sshaka_1_1media_1_1DvbImageColorSpace.html | 120 + ...media_1_1mp4_1_1MultiSegmentSegmenter.html | 23 +- ...1_1WebMContentEncodingsClient-members.html | 17 +- .../classshaka_1_1media_1_1PsshGenerator.html | 23 +- ...sshaka_1_1media_1_1Replicator-members.html | 19 +- ...p2t_1_1EsParserH26x_1_1VideoSliceInfo.html | 17 +- ...ctshaka_1_1media_1_1mp4_1_1CueTimeBox.html | 25 +- docs/d8/dca/ts__writer_8h_source.html | 88 +- docs/d8/dcb/dvb__image_8cc_source.html | 354 + ...1media_1_1mp4_1_1DecodingTime-members.html | 17 +- ...1media_1_1mp4_1_1TrackExtends-members.html | 17 +- ..._1_1media_1_1WebVttFileBuffer-members.html | 19 +- ...ssshaka_1_1media_1_1TextMuxer-members.html | 118 + ...1_1media_1_1mp2t_1_1ContinuityCounter.html | 17 +- ...1mp4_1_1CencSampleEncryptionInfoEntry.html | 19 +- docs/d8/de1/classshaka_1_1Period.html | 71 +- .../de1/classshaka_1_1SimpleMpdNotifier.html | 33 +- .../de6/webm__crypto__helpers_8h_source.html | 44 +- ..._1_1media_1_1mp2t_1_1EsParser-members.html | 32 +- docs/d8/deb/retired__flags_8cc_source.html | 136 +- .../ttml__to__mp4__handler_8cc_source.html | 205 + ...media_1_1AudioTimestampHelper-members.html | 17 +- ...ssshaka_1_1media_1_1VPxParser-members.html | 17 +- ...single__segment__segmenter_8cc_source.html | 161 +- ...a_1_1media_1_1SegmentTestBase-members.html | 17 +- .../classshaka_1_1media_1_1TextPadder.html | 27 +- ...to__byte__stream__converter_8h_source.html | 91 +- ...media_1_1OnMediaEndParameters-members.html | 17 +- ...2single__segment__segmenter_8h_source.html | 77 +- docs/d9/d08/mock__mpd__builder_8h_source.html | 142 +- ...dia_1_1HlsNotifyMuxerListener-members.html | 17 +- .../classshaka_1_1media_1_1RsaPublicKey.html | 19 +- docs/d9/d12/chunking__handler_8cc_source.html | 194 +- .../classshaka_1_1media_1_1BufferReader.html | 29 +- .../protection__system__flags_8cc_source.html | 35 +- ...haka_1_1media_1_1mp4_1_1MovieFragment.html | 25 +- ...haka_1_1media_1_1AesEncryptor-members.html | 17 +- ...assshaka_1_1media_1_1mp4_1_1Segmenter.html | 23 +- ...lassshaka_1_1media_1_1DvbImageBuilder.html | 171 + .../packed__audio__segmenter_8h_source.html | 123 +- docs/d9/d2f/http__file_8h_source.html | 172 + ...aka_1_1media_1_1TracksBuilder-members.html | 17 +- .../webm__content__encodings_8h_source.html | 110 +- ...aka_1_1media_1_1mp4_1_1VTTEmptyCueBox.html | 25 +- ...aka_1_1media_1_1mp4_1_1CueSourceIDBox.html | 25 +- .../classshaka_1_1media_1_1WebVttParser.html | 253 +- .../classshaka_1_1media_1_1WebVttParser.png | Bin 1061 -> 717 bytes ...a_1_1media_1_1MultiCodecMuxerListener.html | 207 + ...ka_1_1media_1_1MultiCodecMuxerListener.png | Bin 0 -> 1236 bytes ...structshaka_1_1media_1_1KeyFrameEvent.html | 17 +- ..._1_1media_1_1mp4_1_1ChunkInfoIterator.html | 17 +- ...ka_1_1media_1_1SingleThreadJobManager.html | 143 + ...aka_1_1media_1_1SingleThreadJobManager.png | Bin 0 -> 855 bytes ...1MuxerListener_1_1MediaRanges-members.html | 17 +- ...haka_1_1media_1_1PackedAudioSegmenter.html | 17 +- ...ctshaka_1_1media_1_1H265VuiParameters.html | 17 +- ...aka_1_1media_1_1CombinedMuxerListener.html | 116 +- ...haka_1_1media_1_1CombinedMuxerListener.png | Bin 825 -> 1246 bytes ...a_1_1media_1_1H264SliceHeader-members.html | 100 +- docs/d9/d76/ts__muxer_8cc_source.html | 94 +- ...ka_1_1media_1_1BaseDescriptor-members.html | 17 +- ...aka_1_1media_1_1ClosureThread-members.html | 17 +- docs/d9/d86/limits_8h_source.html | 70 +- ..._1media_1_1WebMContentEncodingsClient.html | 21 +- ...assshaka_1_1media_1_1AesRequestSigner.html | 31 +- docs/d9/d90/text__track_8h_source.html | 64 +- ...sshaka_1_1hls_1_1MediaPlaylistFactory.html | 19 +- .../sample__aes__ec3__cryptor_8cc_source.html | 145 +- ...shaka_1_1media_1_1SampleAesEc3Cryptor.html | 25 +- docs/d9/da4/stream__descriptor_8h_source.html | 43 +- ...ka_1_1media_1_1MpdNotifyMuxerListener.html | 47 +- ..._1_1media_1_1mp4_1_1Segmenter-members.html | 17 +- .../structshaka_1_1BufferCallbackParams.html | 21 +- docs/d9/dae/text__muxer_8h_source.html | 128 + ..._1_1CompositionOffsetIterator-members.html | 17 +- ...ntent__protection__element_8cc_source.html | 33 +- docs/d9/db9/muxer_8cc_source.html | 166 +- ...haka_1_1media_1_1BufferReader-members.html | 34 +- ...1mp4_1_1SampleEncryptionEntry-members.html | 17 +- ...ssshaka_1_1media_1_1BitWriter-members.html | 17 +- docs/d9/dc8/webm__constants_8cc_source.html | 35 +- .../dca/ttml__to__mp4__handler_8h_source.html | 126 + .../d9/dcc/webm__video__client_8h_source.html | 102 +- ...ructshaka_1_1WidevineEncryptionParams.html | 19 +- docs/d9/dda/ac3__header_8cc_source.html | 216 +- .../d9/de0/structshaka_1_1media_1_1Range.html | 17 +- .../de2/mock__media__playlist_8cc_source.html | 40 +- .../muxer__listener__internal_8cc_source.html | 335 +- .../deb/classshaka_1_1hls_1_1HlsNotifier.html | 23 +- ...c__audio__specific__config_8cc_source.html | 420 +- ...p4_1_1TrackFragmentDecodeTime-members.html | 17 +- ...lassshaka_1_1media_1_1OffsetByteQueue.html | 17 +- docs/d9/dfc/hls__audio__util_8cc_source.html | 103 +- docs/d9/dfe/classshaka_1_1UdpOptions.html | 19 +- ..._1_1media_1_1H264ModificationOfPicNum.html | 19 +- ...classshaka_1_1media_1_1Id3Tag-members.html | 17 +- .../d04/audio__stream__info_8cc_source.html | 182 +- ...shaka_1_1hls_1_1MediaPlaylist-members.html | 31 +- ...assshaka_1_1media_1_1mp2t_1_1EsParser.html | 51 +- ...lassshaka_1_1media_1_1mp2t_1_1EsParser.png | Bin 1900 -> 2196 bytes ...1_1AudioProgramMapTableWriter-members.html | 17 +- ...ructshaka_1_1media_1_1mp4_1_1Language.html | 19 +- ...ssshaka_1_1media_1_1mp2t_1_1TsSection.html | 37 +- docs/da/d1d/udp__options_8cc_source.html | 168 +- ...haka_1_1media_1_1mp2t_1_1EsParserH26x.html | 42 +- docs/da/d23/ts__muxer_8h_source.html | 76 +- docs/da/d24/h265__parser_8h_source.html | 401 +- .../classshaka_1_1media_1_1MuxerFactory.html | 24 +- docs/da/d2a/text__stream__info_8h_source.html | 117 +- .../d2c/classshaka_1_1BandwidthEstimator.html | 17 +- ...1_1media_1_1webm_1_1WebMMuxer-members.html | 19 +- ...aka_1_1media_1_1webvtt_1_1WebVttMuxer.html | 226 + ...haka_1_1media_1_1webvtt_1_1WebVttMuxer.png | Bin 0 -> 1440 bytes ...ia_1_1mp4_1_1PixelAspectRatio-members.html | 17 +- ..._2multi__segment__segmenter_8h_source.html | 80 +- ...ructshaka_1_1ContentProtectionElement.html | 17 +- docs/da/d4a/media__playlist_8h_source.html | 266 +- ...lassshaka_1_1media_1_1AudioStreamInfo.html | 31 +- ...1_1media_1_1mp4_1_1MovieExtendsHeader.html | 25 +- ...media_1_1MuxerListenerFactory-members.html | 17 +- docs/da/d53/es__parser__h265_8cc_source.html | 209 +- .../d55/simple__hls__notifier_8h_source.html | 133 +- ..._1_1media_1_1mp4_1_1CompactSampleSize.html | 25 +- .../d5c/widevine__key__source_8h_source.html | 171 +- ...1_1H264VideoSliceHeaderParser-members.html | 17 +- ...mp4_1_1SingleSegmentSegmenter-members.html | 17 +- ...1_1mp2t_1_1VideoProgramMapTableWriter.html | 27 +- ...edia_1_1mp4_1_1AudioRollRecoveryEntry.html | 19 +- ...1_1media_1_1AV1Parser_1_1Tile-members.html | 17 +- ...1media_1_1mp2t_1_1TsSegmenter-members.html | 19 +- docs/da/d88/mp4__muxer_8cc_source.html | 741 +- ...a_1_1media_1_1WebMMediaParser-members.html | 30 +- docs/da/d8e/container__names_8cc_source.html | 1798 ++- docs/da/d93/origin__handler_8cc_source.html | 39 +- .../d93/structshaka_1_1media_1_1CueEvent.html | 17 +- ...a_1_1mp4_1_1CompositionOffset-members.html | 17 +- ..._1media_1_1mp4_1_1EC3Specific-members.html | 17 +- ...ssshaka_1_1MpdNotifierFactory-members.html | 17 +- ...1_1media_1_1MockMuxerListener-members.html | 17 +- ...assshaka_1_1media_1_1mp2t_1_1TsPacket.html | 17 +- ...shaka_1_1media_1_1CueAlignmentHandler.html | 29 +- .../classshaka_1_1Representation-members.html | 19 +- .../db3/webvtt__file__buffer_8cc_source.html | 109 +- ...dia_1_1DOVIDecoderConfigurationRecord.html | 17 +- ...a_1_1media_1_1mp4_1_1HandlerReference.html | 25 +- ...ssshaka_1_1media_1_1AV1Parser-members.html | 17 +- docs/da/dc3/status_8cc_source.html | 124 +- ...tshaka_1_1media_1_1mp4_1_1TrackHeader.html | 31 +- ...aka_1_1media_1_1OriginHandler-members.html | 19 +- docs/da/dcb/es__descriptor_8h_source.html | 220 +- .../playready__key__source_8cc_source.html | 247 +- .../structshaka_1_1media_1_1mp4_1_1Edit.html | 25 +- docs/da/dd0/webm__info__parser_8h_source.html | 70 +- docs/da/dd1/fragmenter_8h_source.html | 152 +- ..._1_1media_1_1mp2t_1_1TsPacket-members.html | 17 +- ...H264ByteToUnitStreamConverter-members.html | 17 +- ...ia_1_1mp2t_1_1Mp2tMediaParser-members.html | 28 +- ...media_1_1H264SEIRecoveryPoint-members.html | 17 +- ...ssshaka_1_1media_1_1WidevineKeySource.html | 141 +- ...a_1_1mp4_1_1SampleDescription-members.html | 17 +- .../da/de2/mock__mpd__builder_8cc_source.html | 54 +- ...ssshaka_1_1media_1_1WebMClusterParser.html | 35 +- ...1_1media_1_1mp4_1_1SchemeType-members.html | 17 +- ...a_1_1media_1_1AudioStreamInfo-members.html | 17 +- ...1media_1_1mp4_1_1ProtectionSchemeInfo.html | 25 +- ..._1media_1_1H264VideoSliceHeaderParser.html | 23 +- docs/da/df4/aes__decryptor_8cc_source.html | 193 +- ..._1_1media_1_1mp4_1_1SampleDescription.html | 25 +- ...1_1media_1_1AesPatternCryptor-members.html | 17 +- ...sshaka_1_1media_1_1JobManager-members.html | 29 +- .../classshaka_1_1media_1_1MediaHandler.html | 56 +- .../classshaka_1_1media_1_1MediaHandler.png | Bin 7562 -> 8028 bytes docs/db/d04/webvtt__parser_8cc_source.html | 526 +- ...ructshaka_1_1media_1_1H265SliceHeader.html | 17 +- ...1_1media_1_1mp4_1_1CodecConfiguration.html | 25 +- ...a_1_1media_1_1DvbImageBuilder-members.html | 91 + ...sshaka_1_1media_1_1H265Parser-members.html | 17 +- ...media_1_1H264WeightingFactors-members.html | 17 +- docs/db/d19/ttml__generator_8cc_source.html | 319 + .../d1b/classshaka_1_1MemoryFile-members.html | 17 +- .../classshaka_1_1media_1_1TextSample.html | 52 +- ..._1media_1_1mp4_1_1SubtitleMediaHeader.html | 25 +- ...1_1VideoProgramMapTableWriter-members.html | 17 +- ...lassshaka_1_1media_1_1mp4_1_1MP4Muxer.html | 29 +- ...ssshaka_1_1media_1_1ttml_1_1TtmlMuxer.html | 219 + ...assshaka_1_1media_1_1ttml_1_1TtmlMuxer.png | Bin 0 -> 1336 bytes ...to__unit__stream__converter_8h_source.html | 96 +- .../d31/track__run__iterator_8cc_source.html | 840 +- ...1media_1_1mp2t_1_1EsParserDvb-members.html | 92 + ...1_1mp2t_1_1PesPacketGenerator-members.html | 17 +- ...dia_1_1VideoSliceHeaderParser-members.html | 17 +- ...pd__notify__muxer__listener_8h_source.html | 138 +- .../structshaka_1_1media_1_1EventInfo.html | 17 +- .../d4b/classshaka_1_1MockAdaptationSet.html | 47 +- ...a_1_1mp4_1_1CompositionOffsetIterator.html | 17 +- .../db/d51/mp2t__media__parser_8h_source.html | 143 +- ..._single__segment__segmenter_8h_source.html | 78 +- .../media__handler__test__base_8h_source.html | 441 +- ...classshaka_1_1media_1_1CcStreamFilter.html | 254 + .../classshaka_1_1media_1_1CcStreamFilter.png | Bin 0 -> 725 bytes .../d5a/classshaka_1_1media_1_1VP9Parser.html | 21 +- docs/db/d60/mpd__options_8h_source.html | 55 +- ..._1media_1_1mp4_1_1SegmentType-members.html | 17 +- docs/db/d66/udp__file_8cc_source.html | 340 +- .../d6b/structshaka_1_1MpdParams-members.html | 29 +- docs/db/d71/http__key__fetcher_8h_source.html | 83 +- ...EVCDecoderConfigurationRecord-members.html | 17 +- ...TwoPassSingleSegmentSegmenter-members.html | 17 +- ..._1_1mp2t_1_1ContinuityCounter-members.html | 17 +- docs/db/d79/chunking__params_8h_source.html | 51 +- docs/db/d7e/muxer__options_8cc_source.html | 35 +- ...dia_1_1AACAudioSpecificConfig-members.html | 17 +- .../classshaka_1_1media_1_1NaluReader.html | 23 +- docs/db/d8f/mp4__muxer_8h_source.html | 123 +- ...classshaka_1_1media_1_1ClusterBuilder.html | 17 +- ...ssshaka_1_1media_1_1mp4_1_1Fragmenter.html | 17 +- ...a_1_1media_1_1mp4_1_1ChunkLargeOffset.html | 25 +- docs/db/d96/wvm__media__parser_8h_source.html | 300 +- docs/db/da6/memory__file_8h_source.html | 93 +- ...classshaka_1_1media_1_1TextStreamInfo.html | 83 +- .../cue__alignment__handler_8cc_source.html | 358 +- ...classshaka_1_1media_1_1WebMInfoParser.html | 21 +- ...ia_1_1mp4_1_1SoundMediaHeader-members.html | 17 +- ...CencSampleEncryptionInfoEntry-members.html | 17 +- ...haka_1_1media_1_1TextSettings-members.html | 88 + docs/db/db8/ac4__audio__util_8cc_source.html | 607 + ...haka_1_1media_1_1OnMediaEndParameters.html | 17 +- ...ka_1_1media_1_1mp4_1_1TrackEncryption.html | 25 +- docs/db/db9/text__chunker_8cc_source.html | 152 +- .../dc7/classshaka_1_1media_1_1AV1Parser.html | 17 +- .../dcb/classshaka_1_1media_1_1VPxParser.html | 25 +- docs/db/dcd/classshaka_1_1MpdWriter.html | 17 +- ..._1media_1_1mp4_1_1DTSSpecific-members.html | 17 +- docs/db/dd0/classshaka_1_1Packager.html | 27 +- .../classshaka_1_1media_1_1RawKeySource.html | 65 +- ...edia_1_1VodMediaInfoDumpMuxerListener.html | 37 +- docs/db/dd0/ttml__generator_8h_source.html | 142 + .../dd2/chunk__info__iterator_8h_source.html | 101 +- .../dd9/sync__sample__iterator_8h_source.html | 74 +- docs/db/dde/h265__parser_8cc_source.html | 1176 +- docs/db/de1/mock__aes__cryptor_8h_source.html | 62 +- .../classshaka_1_1media_1_1LineReader.html | 75 +- ...assshaka_1_1media_1_1TrickPlayHandler.html | 27 +- .../audio__timestamp__helper_8cc_source.html | 94 +- docs/db/dee/pes__packet_8cc_source.html | 37 +- ...a_1_1media_1_1H265SliceHeader-members.html | 17 +- ...lassshaka_1_1media_1_1Cluster-members.html | 17 +- docs/db/df6/muxer_8h_source.html | 150 +- ...edia_1_1H265ByteToUnitStreamConverter.html | 25 +- .../df8/pssh__generator__util_8cc_source.html | 49 +- docs/db/dfb/mpd__utils_8cc_source.html | 515 +- ...d__notify__muxer__listener_8cc_source.html | 296 +- ..._1_1media_1_1mp4_1_1ChunkInfo-members.html | 17 +- .../dff/webvtt__file__buffer_8h_source.html | 73 +- ...edia_1_1mp2t_1_1ProgramMapTableWriter.html | 25 +- ...sshaka_1_1media_1_1StreamInfo-members.html | 17 +- ...aw__key__encryption__flags_8cc_source.html | 138 +- ...haka_1_1media_1_1ESDescriptor-members.html | 22 +- .../d16/classshaka_1_1media_1_1SeekHead.html | 17 +- docs/dc/d17/status__test__util_8h_source.html | 38 +- ...aka_1_1media_1_1wvm_1_1WvmMediaParser.html | 55 +- ..._1mp4_1_1ProtectionSchemeInfo-members.html | 17 +- docs/dc/d19/box_8h_source.html | 126 +- ...1_1mp2t_1_1AudioProgramMapTableWriter.html | 27 +- docs/dc/d1c/replicator_8h_source.html | 51 +- ...haka_1_1media_1_1WebVttParser-members.html | 51 +- ...ssshaka_1_1media_1_1mp2t_1_1Ac3Header.html | 21 +- ...ructshaka_1_1EncryptionParams-members.html | 41 +- .../d3c/webm__cluster__parser_8h_source.html | 247 +- docs/dc/d3f/key__source_8h_source.html | 100 +- ...ssshaka_1_1hls_1_1HlsNotifier-members.html | 17 +- .../classshaka_1_1xml_1_1XmlNode-members.html | 44 +- .../classshaka_1_1media_1_1BufferWriter.html | 17 +- docs/dc/d48/pssh__generator_8h_source.html | 83 +- ...rotectionSystemSpecificHeader-members.html | 17 +- ..._1media_1_1mp4_1_1TrackHeader-members.html | 17 +- ...o__unit__stream__converter_8cc_source.html | 181 +- .../decoding__time__iterator_8h_source.html | 84 +- .../dc/d52/sync__point__queue_8cc_source.html | 156 +- docs/dc/d53/webm_2segmenter_8cc_source.html | 498 +- ...haka_1_1media_1_1H264DecRefPicMarking.html | 19 +- docs/dc/d56/audio__header_8h_source.html | 99 +- .../dc/d58/webm__media__parser_8h_source.html | 118 +- .../dc/d5c/classshaka_1_1MockMpdNotifier.html | 23 +- docs/dc/d65/dvb__sub__parser_8h_source.html | 170 + ...edia_1_1mp4_1_1CueSettingsBox-members.html | 17 +- ...1_1media_1_1webm_1_1Segmenter-members.html | 17 +- ...1_1media_1_1mp2t_1_1TsSection-members.html | 17 +- ...ssshaka_1_1media_1_1MockMuxerListener.html | 35 +- .../d76/classshaka_1_1media_1_1BitWriter.html | 17 +- ...ka_1_1media_1_1PsshBoxBuilder-members.html | 17 +- docs/dc/d7b/closure__thread_8cc_source.html | 51 +- docs/dc/d7b/h264__parser_8cc_source.html | 1179 +- ...1_1ElementaryStreamDescriptor-members.html | 17 +- ...aka_1_1media_1_1mp2t_1_1EsParserAudio.html | 42 +- ..._1media_1_1mp4_1_1MovieFragmentHeader.html | 25 +- ...structshaka_1_1media_1_1Range-members.html | 17 +- .../da0/structshaka_1_1EncryptionParams.html | 92 +- ...tshaka_1_1media_1_1mp4_1_1DTSSpecific.html | 25 +- docs/dc/da1/classshaka_1_1MpdBuilder.html | 43 +- .../buffer__callback__params_8h_source.html | 49 +- docs/dc/da3/es__parser__audio_8h_source.html | 113 +- .../muxer__listener__factory_8h_source.html | 99 +- ...lassshaka_1_1media_1_1ContentEncoding.html | 53 +- docs/dc/dbf/box__buffer_8h_source.html | 261 +- ...1xml_1_1RepresentationXmlNode-members.html | 59 +- ...edia_1_1mp2t_1_1EsParserAudio-members.html | 36 +- ...classshaka_1_1media_1_1WebMListParser.html | 17 +- ...uctshaka_1_1media_1_1CueEvent-members.html | 17 +- docs/dc/dd9/rsa__key_8cc_source.html | 274 +- .../structshaka_1_1media_1_1mp4_1_1Media.html | 25 +- docs/dc/de1/structshaka_1_1SegmentInfo.html | 17 +- ...1_1media_1_1mp4_1_1Fragmenter-members.html | 17 +- ...to__unit__stream__converter_8h_source.html | 73 +- docs/dc/dec/ts__section__pmt_8cc_source.html | 156 +- .../classshaka_1_1media_1_1ClosureThread.html | 21 +- .../classshaka_1_1media_1_1ClosureThread.png | Bin 670 -> 697 bytes .../structshaka_1_1TestParams-members.html | 17 +- ...ebm_1_1SingleSegmentSegmenter-members.html | 17 +- ...ia_1_1mp4_1_1TrackFragmentRun-members.html | 17 +- docs/dc/df8/closure__thread_8h_source.html | 60 +- ...uctshaka_1_1media_1_1SegmentEventInfo.html | 17 +- docs/dd/d05/encryption__config_8h_source.html | 50 +- ...tshaka_1_1media_1_1mp4_1_1ChunkOffset.html | 25 +- docs/dd/d0c/classshaka_1_1ThreadedIoFile.html | 31 +- docs/dd/d10/muxer__factory_8h_source.html | 85 +- docs/dd/d11/mpd__builder_8cc_source.html | 492 +- docs/dd/d12/mpd__writer_8cc_source.html | 123 +- ...mp4_1_1SampleAuxiliaryInformationSize.html | 25 +- docs/dd/d14/job__manager_8cc_source.html | 137 +- .../d17/classshaka_1_1media_1_1Demuxer.html | 43 +- docs/dd/d18/av1__parser_8h_source.html | 304 +- .../d19/video__stream__info_8cc_source.html | 131 +- .../classshaka_1_1hls_1_1MediaPlaylist.html | 176 +- .../cue__alignment__handler_8h_source.html | 112 +- .../dd/d30/wvm__media__parser_8cc_source.html | 1225 +- docs/dd/d3a/gflags__hex__bytes_8h_source.html | 69 +- docs/dd/d3b/mp4_2segmenter_8h_source.html | 184 +- docs/dd/d3e/callback__file_8cc_source.html | 115 +- ...ctshaka_1_1media_1_1mp4_1_1SyncSample.html | 25 +- docs/dd/d40/classshaka_1_1CallbackFile.html | 27 +- docs/dd/d42/encryptor_8h_source.html | 50 +- docs/dd/d46/webm__parser_8h_source.html | 158 +- ..._1media_1_1SLConfigDescriptor-members.html | 17 +- docs/dd/d4b/event__info_8h_source.html | 83 +- ...media_1_1mp4_1_1MovieFragment-members.html | 17 +- docs/dd/d4e/classshaka_1_1Period-members.html | 22 +- ...a_1_1hls_1_1SimpleHlsNotifier-members.html | 17 +- ..._1_1PlayReadyEncryptionParams-members.html | 17 +- ...der__configuration__record_8cc_source.html | 64 +- ...m_1_1DemuxStreamIdMediaSample-members.html | 17 +- ...widevine__encryption__flags_8h_source.html | 59 +- docs/dd/d58/bit__writer_8cc_source.html | 67 +- docs/dd/d58/crypto__params_8h_source.html | 268 +- ...media_1_1mp2t_1_1EsParserH265-members.html | 42 +- ...1_1media_1_1mp4_1_1SchemeInfo-members.html | 17 +- .../structshaka_1_1media_1_1TextSettings.html | 195 + docs/dd/d60/raw__key__source_8h_source.html | 88 +- ...1_1media_1_1mp4_1_1SyncSample-members.html | 17 +- docs/dd/d65/vp8__parser_8h_source.html | 69 +- ...o__unit__stream__converter_8cc_source.html | 175 +- ...1_1H265VideoSliceHeaderParser-members.html | 17 +- ...a_1_1media_1_1mp4_1_1PixelAspectRatio.html | 25 +- ..._1_1MediaHandlerGraphTestBase-members.html | 17 +- ...shaka_1_1media_1_1mp2t_1_1Mpeg1Header.html | 501 + ...sshaka_1_1media_1_1mp2t_1_1Mpeg1Header.png | Bin 0 -> 821 bytes ...OVIDecoderConfigurationRecord-members.html | 17 +- .../classshaka_1_1media_1_1MuxerListener.html | 56 +- .../classshaka_1_1media_1_1MuxerListener.png | Bin 2370 -> 3272 bytes docs/dd/d80/media__sample_8h_source.html | 203 +- docs/dd/d87/memory__file_8cc_source.html | 226 +- .../d88/pes__packet__generator_8h_source.html | 107 +- docs/dd/d8c/file__test__util_8h_source.html | 64 +- ...1media_1_1mp4_1_1SegmentIndex-members.html | 17 +- .../classshaka_1_1ThreadedIoFile-members.html | 17 +- .../ts__packet__writer__util_8h_source.html | 56 +- .../audio__timestamp__helper_8h_source.html | 97 +- ...a_1_1media_1_1mp4_1_1SegmentReference.html | 35 +- .../classshaka_1_1MpdNotifier-members.html | 38 +- .../da4/structshaka_1_1xml_1_1XmlDeleter.html | 20 +- ...webm_1_1TwoPassSingleSegmentSegmenter.html | 23 +- ...info__dump__muxer__listener_8h_source.html | 123 +- docs/dd/dab/webm__muxer_8h_source.html | 76 +- ..._1mp4_1_1WebVTTSourceLabelBox-members.html | 17 +- ...a_1_1media_1_1WebMAudioClient-members.html | 17 +- ..._1media_1_1mp4_1_1SampleTable-members.html | 17 +- docs/dd/db5/packager_8h_source.html | 219 +- ...a_1_1xml_1_1RepresentationBaseXmlNode.html | 129 +- docs/dd/dbc/buffer__reader_8cc_source.html | 142 +- .../dd/dbc/encryption__handler_8h_source.html | 131 +- ...structshaka_1_1media_1_1EncryptionKey.html | 24 +- ...dia_1_1mp4_1_1TrackEncryption-members.html | 17 +- .../dbf/webm__webvtt__parser_8h_source.html | 75 +- ...tructshaka_1_1media_1_1mp4_1_1FullBox.html | 66 +- ...structshaka_1_1media_1_1mp4_1_1FullBox.png | Bin 25666 -> 26301 bytes ...edia_1_1ProducerConsumerQueue-members.html | 17 +- ...ssshaka_1_1media_1_1webm_1_1Segmenter.html | 27 +- ...haka_1_1media_1_1DvbSubParser-members.html | 88 + ...edia_1_1mp4_1_1OriginalFormat-members.html | 17 +- docs/dd/dd2/buffer__writer_8h_source.html | 97 +- docs/dd/dd3/buffer__writer_8cc_source.html | 127 +- ...a_1_1media_1_1WebMVideoClient-members.html | 17 +- .../dd8/mock__muxer__listener_8cc_source.html | 66 +- ...tshaka_1_1media_1_1mp4_1_1Box-members.html | 17 +- ...ctshaka_1_1media_1_1TextSubStreamInfo.html | 97 + .../ddc/trick__play__handler_8h_source.html | 100 +- docs/dd/de1/period_8cc_source.html | 398 +- ...ka_1_1media_1_1VideoSliceHeaderParser.html | 21 +- ...ructshaka_1_1media_1_1H265Pps-members.html | 17 +- docs/dd/de7/xml__node_8h_source.html | 227 +- ...haka_1_1media_1_1MediaHandler-members.html | 19 +- ...structshaka_1_1ChunkingParams-members.html | 17 +- docs/dd/dee/box__definitions_8cc_source.html | 3219 ++++- ..._2multi__segment__segmenter_8h_source.html | 88 +- ...aka_1_1media_1_1PsshGenerator-members.html | 17 +- ...a_1_1media_1_1mp4_1_1TrackFragmentRun.html | 39 +- ...ructshaka_1_1media_1_1mp4_1_1Metadata.html | 25 +- ...dia_1_1PlayReadyPsshGenerator-members.html | 19 +- .../structshaka_1_1AdCueGeneratorParams.html | 17 +- ..._1_1media_1_1SubtitleComposer-members.html | 93 + docs/de/d00/ac3__header_8h_source.html | 99 +- docs/de/d03/text__padder_8cc_source.html | 88 +- ..._1media_1_1SubsampleGenerator-members.html | 17 +- .../widevine__pssh__generator_8h_source.html | 67 +- docs/de/d0f/local__file_8h_source.html | 92 +- docs/de/d12/container__names_8h_source.html | 89 +- docs/de/d13/ts__writer_8cc_source.html | 233 +- ...a_1_1media_1_1TextTrackConfig-members.html | 17 +- docs/de/d17/cluster__builder_8cc_source.html | 276 +- ...edia_1_1wvm_1_1WvmMediaParser-members.html | 30 +- ...1media_1_1mp4_1_1KeyFrameInfo-members.html | 17 +- ...single__segment__segmenter_8cc_source.html | 274 +- .../d22/aes__pattern__cryptor_8cc_source.html | 131 +- .../de/d26/classshaka_1_1media_1_1Id3Tag.html | 19 +- docs/de/d27/es__parser__audio_8cc_source.html | 291 +- docs/de/d29/es__parser__dvb_8cc_source.html | 219 + ...shaka_1_1media_1_1mp4_1_1TrackExtends.html | 25 +- ..._1_1media_1_1WebMTracksParser-members.html | 17 +- .../d33/structshaka_1_1media_1_1H265Pps.html | 17 +- .../de/d34/offset__byte__queue_8h_source.html | 78 +- docs/de/d39/id3__tag_8cc_source.html | 130 +- ...o__unit__stream__converter_8cc_source.html | 141 +- docs/de/d3c/macros_8h_source.html | 73 +- docs/de/d3e/buffer__reader_8h_source.html | 101 +- ...sshaka_1_1media_1_1H264Parser-members.html | 17 +- ...1_1media_1_1mp2t_1_1PesPacket-members.html | 17 +- .../classshaka_1_1media_1_1DecryptConfig.html | 17 +- .../muxer__listener__internal_8h_source.html | 71 +- docs/de/d52/classshaka_1_1Representation.html | 49 +- ...edia_1_1FakeInputMediaHandler-members.html | 39 +- ...shaka_1_1media_1_1mp4_1_1FlacSpecific.html | 25 +- ...a_1_1media_1_1mp4_1_1Language-members.html | 17 +- docs/de/d5b/adts__header_8cc_source.html | 177 +- docs/de/d5c/mpd__flags_8h_source.html | 46 +- ...mp2t_1_1ProgramMapTableWriter-members.html | 17 +- ...assshaka_1_1media_1_1mp2t_1_1TsWriter.html | 115 +- ...ingle__thread__job__manager_8h_source.html | 114 + .../d6c/mock__media__playlist_8h_source.html | 114 +- ..._1_1mp4_1_1SampleToGroupEntry-members.html | 17 +- ...dia_1_1MockOutputMediaHandler-members.html | 19 +- docs/de/d6e/language__utils_8h_source.html | 47 +- .../de/d70/http__key__fetcher_8cc_source.html | 110 +- docs/de/d75/mpeg1__header_8cc_source.html | 339 + docs/de/d76/proto__json__util_8h_source.html | 49 +- ...content__encodings__client_8cc_source.html | 289 +- docs/de/d7b/mp4__media__parser_8h_source.html | 145 +- ...haka_1_1media_1_1mp2t_1_1TsSectionPsi.html | 37 +- ...ptedStreamAttributes_1_1OneOf-members.html | 17 +- ...ox__definitions__comparison_8h_source.html | 530 +- .../classshaka_1_1media_1_1OriginHandler.html | 30 +- .../classshaka_1_1media_1_1OriginHandler.png | Bin 1449 -> 1032 bytes ...edia_1_1wvm_1_1PrevSampleData-members.html | 17 +- docs/de/d88/tag_8cc_source.html | 90 +- ...1_1mp4_1_1MovieFragmentHeader-members.html | 17 +- ...ssshaka_1_1media_1_1VP8Parser-members.html | 17 +- .../aes__encryptor__factory_8h_source.html | 61 +- docs/de/da9/structshaka_1_1Element.html | 17 +- docs/de/dab/es__parser__h26x_8cc_source.html | 372 +- docs/de/dad/classshaka_1_1MemoryFile.html | 29 +- docs/de/dad/validate__flag_8cc_source.html | 46 +- ...ka_1_1media_1_1MockOutputMediaHandler.html | 29 +- ...lassshaka_1_1media_1_1TextTrackConfig.html | 17 +- .../classshaka_1_1media_1_1H26xBitReader.html | 17 +- ...1_1MuxerListenerFactory_1_1StreamData.html | 23 +- ...haka_1_1media_1_1MuxerListenerFactory.html | 21 +- ...dia_1_1mp4_1_1NullMediaHeader-members.html | 97 + docs/de/dbf/udp__options_8h_source.html | 76 +- docs/de/dc1/demuxer_8h_source.html | 175 +- docs/de/dc2/adaptation__set_8cc_source.html | 674 +- .../classshaka_1_1media_1_1H265Parser.html | 25 +- ..._1mp4_1_1DecodingTimeToSample-members.html | 17 +- docs/de/dcb/ts__segmenter_8h_source.html | 137 +- docs/de/dcc/key__frame__info_8h_source.html | 47 +- .../dcc/mock__mpd__notifier_8cc_source.html | 28 +- docs/de/dcf/file__closer_8h_source.html | 55 +- .../protection__system__ids_8h_source.html | 63 +- ...ontent__protection__element_8h_source.html | 73 +- ...er__listener__test__helper_8cc_source.html | 126 +- ...lti__codec__muxer__listener_8h_source.html | 116 + .../classshaka_1_1media_1_1Muxer-members.html | 19 +- ...shaka_1_1media_1_1mp2t_1_1TsSegmenter.html | 35 +- ..._1_1media_1_1mp4_1_1MediaData-members.html | 17 +- ..._1media_1_1DecoderConfigurationRecord.html | 25 +- ...a_1_1media_1_1mp4_1_1MP4Muxer-members.html | 19 +- .../de4/structshaka_1_1media_1_1H264Pps.html | 22 +- ...edia_1_1H26xByteToUnitStreamConverter.html | 25 +- docs/de/deb/structshaka_1_1Cuepoint.html | 17 +- ...1media_1_1mp4_1_1DecodingTimeToSample.html | 25 +- .../combined__muxer__listener_8h_source.html | 112 +- ...a_1_1media_1_1mp4_1_1TrackRunIterator.html | 17 +- docs/de/dfa/muxer__listener_8h_source.html | 133 +- ...shaka_1_1media_1_1mp4_1_1OpusSpecific.html | 25 +- docs/de/dfd/stream__info_8cc_source.html | 96 +- .../d00/playready__key__source_8h_source.html | 95 +- ...dec__configuration__record_8cc_source.html | 449 +- .../classshaka_1_1media_1_1BlockReader.html | 75 +- .../playready__pssh__generator_8h_source.html | 71 +- .../d1a/offset__byte__queue_8cc_source.html | 87 +- ...shaka_1_1media_1_1MediaSample-members.html | 17 +- ...mposition__offset__iterator_8h_source.html | 84 +- docs/df/d1d/ac3__audio__util_8h_source.html | 43 +- ...mentTestBase_1_1ClusterParser-members.html | 28 +- .../df/d22/structshaka_1_1WidevineSigner.html | 39 +- docs/df/d22/validate__flag_8h_source.html | 71 +- ..._1mp4_1_1DecodingTimeIterator-members.html | 17 +- docs/df/d2b/pssh__generator_8cc_source.html | 98 +- ...lassshaka_1_1media_1_1AesCbcDecryptor.html | 27 +- docs/df/d31/muxer__util_8cc_source.html | 186 +- .../df/d32/audio__stream__info_8h_source.html | 102 +- .../classshaka_1_1AdaptationSet-members.html | 57 +- ...sshaka_1_1media_1_1SLConfigDescriptor.html | 23 +- ...uctshaka_1_1media_1_1mp4_1_1ChunkInfo.html | 19 +- ..._1_1mp4_1_1MovieExtendsHeader-members.html | 17 +- .../classshaka_1_1media_1_1RequestSigner.html | 25 +- docs/df/d46/classshaka_1_1media_1_1Muxer.html | 44 +- docs/df/d46/classshaka_1_1media_1_1Muxer.png | Bin 2254 -> 3521 bytes ...ia_1_1DecoderConfigDescriptor-members.html | 17 +- ...uctshaka_1_1PlayReadyEncryptionParams.html | 21 +- docs/df/d4e/classshaka_1_1IoCache.html | 17 +- ...aka_1_1media_1_1RsaPrivateKey-members.html | 17 +- .../classshaka_1_1CallbackFile-members.html | 17 +- docs/df/d60/classshaka_1_1MockMpdBuilder.html | 29 +- ...aka_1_1media_1_1KeyFrameEvent-members.html | 17 +- ...mp4_1_1AudioRollRecoveryEntry-members.html | 17 +- .../classshaka_1_1media_1_1KeyFetcher.html | 21 +- .../classshaka_1_1MockMpdBuilder-members.html | 19 +- ...1media_1_1mp4_1_1OpusSpecific-members.html | 17 +- ...ka_1_1media_1_1OnNewSegmentParameters.html | 17 +- ...dia_1_1mp4_1_1CompositionTimeToSample.html | 25 +- ...haka_1_1media_1_1mp4_1_1TrackFragment.html | 25 +- .../df/d7d/webm__info__parser_8cc_source.html | 133 +- ...1_1DecoderConfigurationRecord-members.html | 17 +- ...sshaka_1_1media_1_1TextPadder-members.html | 19 +- .../classshaka_1_1media_1_1AesCryptor.html | 31 +- ...aka_1_1media_1_1ttml_1_1TtmlGenerator.html | 111 + ...shaka_1_1media_1_1mp4_1_1DataEntryUrl.html | 25 +- docs/df/d8a/vp9__parser_8h_source.html | 69 +- docs/df/d8a/vpx__parser_8h_source.html | 80 +- ...1mp4_1_1MultiSegmentSegmenter-members.html | 17 +- docs/df/d8d/es__parser__h26x_8h_source.html | 169 +- ..._1_1RepresentationStateChangeListener.html | 19 +- docs/df/d96/xml__node_8cc_source.html | 653 +- ...dia_1_1mp4_1_1TrackFragmentDecodeTime.html | 25 +- ...shaka_1_1xml_1_1RepresentationXmlNode.html | 143 +- docs/df/d9e/es__parser__dvb_8h_source.html | 139 + ..._1media_1_1mp4_1_1ChunkOffset-members.html | 17 +- docs/df/da1/cc__stream__filter_8h_source.html | 120 + ...a_1_1media_1_1mp4_1_1CueIDBox-members.html | 17 +- ...ctshaka_1_1media_1_1EventInfo-members.html | 17 +- docs/df/dad/decrypt__config_8h_source.html | 108 +- ...classshaka_1_1media_1_1BaseDescriptor.html | 27 +- ..._1media_1_1WebVttToMp4Handler-members.html | 19 +- ...oder__configuration__record_8h_source.html | 96 +- ...a_1_1hls_1_1MockMediaPlaylist-members.html | 78 +- docs/df/dd2/mpd__utils_8h_source.html | 102 +- ...ructshaka_1_1media_1_1H264Pps-members.html | 48 +- ...ngle__thread__job__manager_8cc_source.html | 113 + docs/df/ddc/structshaka_1_1MpdParams.html | 69 +- docs/df/ddc/webm_2segmenter_8h_source.html | 206 +- docs/df/dde/ts__section__psi_8cc_source.html | 157 +- ...haka_1_1media_1_1H264SEIRecoveryPoint.html | 19 +- .../de3/text__track__config_8cc_source.html | 51 +- docs/df/de9/segment__info_8h_source.html | 44 +- .../dee/classshaka_1_1HttpFile-members.html | 111 + ...a_1_1ContentProtectionElement-members.html | 17 +- .../df8/subsample__generator_8h_source.html | 117 +- docs/df/dfa/video__util_8h_source.html | 45 +- ...dy__key__encryption__flags_8cc_source.html | 64 +- .../dir_121b61e6efa4d9009f3d31a3be5e474d.html | 78 + .../dir_1338cd99faf71b6cb1609e99e3340e45.html | 17 +- .../dir_35c1fdffcdd4ade6d7f948073ab165de.html | 17 +- .../dir_375ba2cfd8fd5b05c50b92d996b9d386.html | 17 +- .../dir_3f8eec2fc361645de4b1ec14c19fffc7.html | 17 +- .../dir_48fdaa95ed78e499807eaa909d50b2cd.html | 17 +- .../dir_51897ee7df8868b4f901d3ff10922ac3.html | 17 +- .../dir_51a7c7233efd277e3898c7f3689e7b5b.html | 78 + .../dir_588b87f799233a7c3afc1168633bb252.html | 17 +- .../dir_64597db6ac7a9160e951a4226a03f10e.html | 17 +- .../dir_65bafb41b3669ba481c8da543a696a08.html | 17 +- .../dir_6fe4b0529cd3ec97045d3314254a0cce.html | 17 +- .../dir_7053349436b45d276056de3c928a6fc6.html | 17 +- .../dir_7fa7c3de4a91b9652697b9f1c2d38e70.html | 17 +- .../dir_83c56f445d5c796bd14e4ebf939c29ad.html | 17 +- .../dir_880f0837661bea0e588ff6a42c226fba.html | 17 +- .../dir_933242dc2ed3ec7a82c146e98110781e.html | 17 +- .../dir_aa847bee70cdde822696c7e33a504139.html | 17 +- .../dir_ae142483ff91a68c468a97c037f98d4d.html | 17 +- .../dir_b23f8e22c8c095d1c8c0cb8f88104a00.html | 17 +- .../dir_b7f276137d53b05d7f6b34219adc0a31.html | 17 +- .../dir_b885194e7131202a9b4650a8967e838c.html | 17 +- .../dir_b8a35a7f00287a46b0da66a108ec1239.html | 17 +- .../dir_bf7f1d16febc509cca62cff27fb88644.html | 17 +- .../dir_c41da90e13af52a77978e497cf9cac63.html | 17 +- .../dir_c727d19e3a8f99ea2539fb71bdb2ad10.html | 17 +- .../dir_d258fb6e36cbaad69b44b6c9489b2bbb.html | 17 +- .../dir_e329e4913ca1adf6e112c00fbb0d634f.html | 17 +- .../dir_e3bda0bde998a4d5063328245b9909be.html | 17 +- .../dir_f74090996960c752a82246b98a23aa62.html | 17 +- .../dir_f99dae54fe7170f791f339b952d5067a.html | 17 +- .../dir_ffb529e2a1792bf603304ea6ff9bf092.html | 17 +- docs/doxygen.css | 461 +- docs/doxygen.png | Bin 3779 -> 0 bytes docs/doxygen.svg | 26 + docs/dynsections.js | 30 +- docs/files.html | 655 +- docs/functions.html | 49 +- docs/functions_b.html | 19 +- docs/functions_c.html | 36 +- docs/functions_d.html | 25 +- docs/functions_e.html | 19 +- docs/functions_enum.html | 20 +- docs/functions_eval.html | 17 +- docs/functions_f.html | 28 +- docs/functions_func.html | 48 +- docs/functions_func_b.html | 21 +- docs/functions_func_c.html | 26 +- docs/functions_func_d.html | 20 +- docs/functions_func_e.html | 19 +- docs/functions_func_f.html | 28 +- docs/functions_func_g.html | 51 +- docs/functions_func_h.html | 21 +- docs/functions_func_i.html | 37 +- docs/functions_func_l.html | 20 +- docs/functions_func_m.html | 25 +- docs/functions_func_n.html | 22 +- docs/functions_func_o.html | 22 +- docs/functions_func_p.html | 33 +- docs/functions_func_r.html | 26 +- docs/functions_func_s.html | 54 +- docs/functions_func_t.html | 25 +- docs/functions_func_u.html | 20 +- docs/functions_func_v.html | 17 +- docs/functions_func_w.html | 27 +- docs/functions_func_x.html | 19 +- ...s_func_0x7e.html => functions_func_~.html} | 19 +- docs/functions_g.html | 53 +- docs/functions_h.html | 30 +- docs/functions_i.html | 39 +- docs/functions_k.html | 23 +- docs/functions_l.html | 23 +- docs/functions_m.html | 28 +- docs/functions_n.html | 29 +- docs/functions_o.html | 22 +- docs/functions_p.html | 44 +- docs/functions_r.html | 30 +- docs/functions_rela.html | 17 +- docs/functions_s.html | 61 +- docs/functions_t.html | 28 +- docs/functions_type.html | 24 +- docs/functions_u.html | 20 +- docs/functions_v.html | 17 +- docs/functions_vars.html | 90 +- docs/functions_w.html | 37 +- docs/functions_x.html | 19 +- .../{functions_0x7e.html => functions_~.html} | 19 +- docs/hierarchy.html | 645 +- docs/index.html | 17 +- docs/jquery.js | 94 +- docs/menu.js | 29 +- docs/menudata.js | 28 +- docs/namespacemembers.html | 20 +- docs/namespacemembers_enum.html | 20 +- docs/namespacemembers_func.html | 17 +- docs/namespaces.html | 418 +- docs/search/all_0.html | 25 +- docs/search/all_0.js | 149 +- docs/search/all_1.html | 25 +- docs/search/all_1.js | 52 +- docs/search/all_10.html | 25 +- docs/search/all_10.js | 69 +- docs/search/all_11.html | 25 +- docs/search/all_11.js | 243 +- docs/search/all_12.html | 25 +- docs/search/all_12.js | 114 +- docs/search/all_13.html | 25 +- docs/search/all_13.js | 19 +- docs/search/all_14.html | 25 +- docs/search/all_14.js | 48 +- docs/search/all_15.html | 25 +- docs/search/all_15.js | 87 +- docs/search/all_16.html | 25 +- docs/search/all_16.js | 4 +- docs/search/all_17.html | 25 +- docs/search/all_17.js | 4 +- docs/search/all_2.html | 25 +- docs/search/all_2.js | 158 +- docs/search/all_3.html | 25 +- docs/search/all_3.js | 86 +- docs/search/all_4.html | 25 +- docs/search/all_4.js | 53 +- docs/search/all_5.html | 25 +- docs/search/all_5.js | 41 +- docs/search/all_6.html | 25 +- docs/search/all_6.js | 123 +- docs/search/all_7.html | 25 +- docs/search/all_7.js | 95 +- docs/search/all_8.html | 25 +- docs/search/all_8.js | 74 +- docs/search/all_9.html | 25 +- docs/search/all_9.js | 5 +- docs/search/all_a.html | 25 +- docs/search/all_a.js | 45 +- docs/search/all_b.html | 25 +- docs/search/all_b.js | 21 +- docs/search/all_c.html | 25 +- docs/search/all_c.js | 129 +- docs/search/all_d.html | 25 +- docs/search/all_d.js | 41 +- docs/search/all_e.html | 25 +- docs/search/all_e.js | 58 +- docs/search/all_f.html | 25 +- docs/search/all_f.js | 123 +- docs/search/classes_0.html | 25 +- docs/search/classes_0.js | 49 +- docs/search/classes_1.html | 25 +- docs/search/classes_1.js | 24 +- docs/search/classes_10.html | 25 +- docs/search/classes_10.js | 78 +- docs/search/classes_11.html | 25 +- docs/search/classes_11.js | 74 +- docs/search/classes_12.html | 25 +- docs/search/classes_12.js | 6 +- docs/search/classes_13.html | 25 +- docs/search/classes_13.js | 32 +- docs/search/classes_14.html | 25 +- docs/search/classes_14.js | 46 +- docs/search/classes_15.html | 25 +- docs/search/classes_15.js | 4 +- docs/search/classes_2.html | 25 +- docs/search/classes_2.js | 65 +- docs/search/classes_3.html | 25 +- docs/search/classes_3.js | 35 +- docs/search/classes_4.html | 25 +- docs/search/classes_4.js | 37 +- docs/search/classes_5.html | 25 +- docs/search/classes_5.js | 15 +- docs/search/classes_6.html | 25 +- docs/search/classes_6.js | 59 +- docs/search/classes_7.html | 25 +- docs/search/classes_7.js | 6 +- docs/search/classes_8.html | 25 +- docs/search/classes_8.js | 5 +- docs/search/classes_9.html | 25 +- docs/search/classes_9.js | 10 +- docs/search/classes_a.html | 25 +- docs/search/classes_a.js | 10 +- docs/search/classes_b.html | 25 +- docs/search/classes_b.js | 98 +- docs/search/classes_c.html | 25 +- docs/search/classes_c.js | 7 +- docs/search/classes_d.html | 25 +- docs/search/classes_d.js | 14 +- docs/search/classes_e.html | 25 +- docs/search/classes_e.js | 41 +- docs/search/classes_f.html | 25 +- docs/search/classes_f.js | 25 +- docs/search/close.png | Bin 273 -> 0 bytes docs/search/close.svg | 31 + docs/search/enums_0.html | 25 +- docs/search/enums_0.js | 2 +- docs/search/enums_1.html | 25 +- docs/search/enums_1.js | 2 +- docs/search/enums_2.html | 25 +- docs/search/enums_2.js | 4 +- docs/search/enumvalues_0.html | 25 +- docs/search/enumvalues_0.js | 9 +- docs/search/functions_0.html | 25 +- docs/search/functions_0.js | 109 +- docs/search/functions_1.html | 25 +- docs/search/functions_1.js | 30 +- docs/search/functions_10.html | 25 +- docs/search/functions_10.js | 37 +- docs/search/functions_11.html | 25 +- docs/search/functions_11.js | 15 +- docs/search/functions_12.html | 25 +- docs/search/functions_12.js | 16 +- docs/search/functions_13.html | 25 +- docs/search/functions_13.js | 45 +- docs/search/functions_14.html | 25 +- docs/search/functions_14.js | 2 +- docs/search/functions_15.html | 25 +- docs/search/functions_15.js | 4 +- docs/search/functions_2.html | 25 +- docs/search/functions_2.js | 83 +- docs/search/functions_3.html | 25 +- docs/search/functions_3.js | 44 +- docs/search/functions_4.html | 25 +- docs/search/functions_4.js | 12 +- docs/search/functions_5.html | 25 +- docs/search/functions_5.js | 28 +- docs/search/functions_6.html | 25 +- docs/search/functions_6.js | 115 +- docs/search/functions_7.html | 25 +- docs/search/functions_7.js | 32 +- docs/search/functions_8.html | 25 +- docs/search/functions_8.js | 53 +- docs/search/functions_9.html | 25 +- docs/search/functions_9.js | 13 +- docs/search/functions_a.html | 25 +- docs/search/functions_a.js | 28 +- docs/search/functions_b.html | 25 +- docs/search/functions_b.js | 34 +- docs/search/functions_c.html | 25 +- docs/search/functions_c.js | 36 +- docs/search/functions_d.html | 25 +- docs/search/functions_d.js | 78 +- docs/search/functions_e.html | 25 +- docs/search/functions_e.js | 42 +- docs/search/functions_f.html | 25 +- docs/search/functions_f.js | 142 +- docs/search/mag_sel.png | Bin 563 -> 0 bytes docs/search/mag_sel.svg | 74 + docs/search/namespaces_0.html | 25 +- docs/search/namespaces_0.js | 2 +- docs/search/nomatches.html | 5 +- docs/search/related_0.html | 25 +- docs/search/related_0.js | 2 +- docs/search/search.css | 106 +- docs/search/search.js | 45 +- docs/search/search_l.png | Bin 604 -> 567 bytes docs/search/search_r.png | Bin 612 -> 553 bytes docs/search/typedefs_0.html | 25 +- docs/search/typedefs_0.js | 2 +- docs/search/typedefs_1.html | 25 +- docs/search/typedefs_1.js | 3 +- docs/search/variables_0.html | 25 +- docs/search/variables_0.js | 5 +- docs/search/variables_1.html | 25 +- docs/search/variables_1.js | 8 +- docs/search/variables_10.html | 25 +- docs/search/variables_10.js | 2 +- docs/search/variables_11.html | 25 +- docs/search/variables_11.js | 5 +- docs/search/variables_2.html | 25 +- docs/search/variables_2.js | 18 +- docs/search/variables_3.html | 25 +- docs/search/variables_3.js | 15 +- docs/search/variables_4.html | 25 +- docs/search/variables_4.js | 4 +- docs/search/variables_5.html | 25 +- docs/search/variables_5.js | 8 +- docs/search/variables_6.html | 25 +- docs/search/variables_6.js | 14 +- docs/search/variables_7.html | 25 +- docs/search/variables_7.js | 16 +- docs/search/variables_8.html | 25 +- docs/search/variables_8.js | 24 +- docs/search/variables_9.html | 25 +- docs/search/variables_9.js | 3 +- docs/search/variables_a.html | 25 +- docs/search/variables_a.js | 15 +- docs/search/variables_b.html | 25 +- docs/search/variables_b.js | 8 +- docs/search/variables_c.html | 25 +- docs/search/variables_c.js | 14 +- docs/search/variables_d.html | 25 +- docs/search/variables_d.js | 4 +- docs/search/variables_e.html | 25 +- docs/search/variables_e.js | 31 +- docs/search/variables_f.html | 25 +- docs/search/variables_f.js | 11 +- docs/tabs.css | 2 +- html/.buildinfo | 2 +- ...af1c119c853656e59490991f24816ae8064016.png | Bin 13383 -> 13336 bytes ...6b26625ec04fed330621f00c3a39700f74259e.png | Bin 51771 -> 45010 bytes ...d86a2355342a0020a62fc7db969063daa9597c.png | Bin 6426 -> 6297 bytes ...83f8f1c2843c664b6cd4bc1f27820dfd89c860.png | Bin 80436 -> 79948 bytes ...88f7ab1eb3f4d70c57feb299c189351a097db9.png | Bin 11305 -> 12311 bytes ...88f7ab1eb3f4d70c57feb299c189351a097db9.png | Bin 0 -> 12311 bytes html/_sources/build_instructions.md.txt | 39 +- html/_sources/options/dash_options.rst.txt | 10 + .../general_encryption_options.rst.txt | 31 +- html/_sources/options/hls_options.rst.txt | 29 + .../options/mp4_output_options.rst.txt | 8 +- .../raw_key_encryption_options.rst.txt | 6 +- .../options/stream_descriptors.rst.txt | 10 + html/_sources/tutorials/dash.rst.txt | 2 +- .../tutorials/dash_hls_example.rst.txt | 18 + html/_sources/tutorials/http_upload.rst.txt | 227 + html/_sources/tutorials/raw_key.rst.txt | 23 +- html/_sources/tutorials/text.rst.txt | 47 + html/_sources/tutorials/tutorials.rst.txt | 2 + html/_static/basic.css | 144 +- html/_static/doctools.js | 10 +- html/_static/documentation_options.js | 1 + html/_static/graphviz.css | 2 +- html/_static/jquery-3.4.1.js | 10598 --------------- html/_static/jquery.js | 10872 +++++++++++++++- html/_static/language_data.js | 2 +- html/_static/pygments.css | 7 +- html/_static/searchtools.js | 36 +- html/_static/sphinxdoc.css | 11 +- html/_static/underscore-1.3.1.js | 999 -- html/_static/underscore.js | 1723 ++- html/build_instructions.html | 193 +- html/design.html | 103 +- html/docker_instructions.html | 97 +- html/documentation.html | 213 +- html/genindex.html | 196 +- html/index.html | 129 +- html/library.html | 106 +- html/library_details.html | 1878 +-- html/objects.inv | Bin 6627 -> 6996 bytes html/options/ads_options.html | 67 +- html/options/chunking_options.html | 67 +- html/options/dash_options.html | 80 +- html/options/dash_stream_descriptors.html | 67 +- html/options/drm_stream_descriptors.html | 67 +- html/options/general_encryption_options.html | 118 +- html/options/hls_options.html | 91 +- html/options/hls_stream_descriptors.html | 67 +- html/options/mp4_output_options.html | 74 +- .../options/playready_encryption_options.html | 67 +- html/options/raw_key_encryption_options.html | 72 +- html/options/segment_template_formatting.html | 67 +- html/options/stream_descriptors.html | 93 +- .../transport_stream_output_options.html | 67 +- html/options/udp_file_options.html | 67 +- html/options/widevine_encryption_options.html | 67 +- html/search.html | 46 +- html/searchindex.js | 2 +- html/tutorials/ads.html | 111 +- html/tutorials/basic_usage.html | 99 +- html/tutorials/dash.html | 137 +- html/tutorials/dash_hls_example.html | 80 +- html/tutorials/drm.html | 131 +- html/tutorials/encoding.html | 99 +- html/tutorials/ffmpeg_piping.html | 113 +- html/tutorials/hls.html | 150 +- html/tutorials/http_upload.html | 332 + html/tutorials/live.html | 105 +- html/tutorials/playready.html | 126 +- html/tutorials/raw_key.html | 170 +- html/tutorials/text.html | 166 + html/tutorials/tutorials.html | 92 +- html/tutorials/widevine.html | 130 +- 1660 files changed, 122512 insertions(+), 35928 deletions(-) create mode 100644 docs/d0/d6c/classshaka_1_1media_1_1mp2t_1_1EsParserDvb.html create mode 100644 docs/d0/d6c/classshaka_1_1media_1_1mp2t_1_1EsParserDvb.png create mode 100644 docs/d0/d73/webvtt__muxer_8h_source.html create mode 100644 docs/d0/d7b/structshaka_1_1media_1_1TextFragment-members.html create mode 100644 docs/d0/dab/subtitle__composer_8h_source.html rename docs/{d6/d2a/classshaka_1_1media_1_1WebVttTextOutputHandler.html => d0/df2/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler.html} (85%) create mode 100644 docs/d0/df2/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler.png create mode 100644 docs/d1/d4e/classshaka_1_1media_1_1TextMuxer.html create mode 100644 docs/d1/d4e/classshaka_1_1media_1_1TextMuxer.png create mode 100644 docs/d1/d84/classshaka_1_1media_1_1SingleThreadJobManager-members.html create mode 100644 docs/d1/dc7/classshaka_1_1HttpFile.html create mode 100644 docs/d1/dc7/classshaka_1_1HttpFile.png create mode 100644 docs/d2/d0e/structshaka_1_1media_1_1mp4_1_1NullMediaHeader.html create mode 100644 docs/d2/d0e/structshaka_1_1media_1_1mp4_1_1NullMediaHeader.png create mode 100644 docs/d2/d76/structshaka_1_1media_1_1JobManager_1_1JobEntry.html create mode 100644 docs/d2/de1/dvb__image_8h_source.html delete mode 100644 docs/d2/de1/webvtt__timestamp_8h_source.html create mode 100644 docs/d2/def/webvtt__muxer_8cc_source.html create mode 100644 docs/d2/df7/structshaka_1_1media_1_1mp4_1_1AC4Specific-members.html create mode 100644 docs/d3/d53/classshaka_1_1media_1_1JobManager.png create mode 100644 docs/d3/d54/structshaka_1_1media_1_1TextFragment.html create mode 100644 docs/d3/d7a/ttml__muxer_8h_source.html create mode 100644 docs/d3/d7d/structshaka_1_1media_1_1TextRegion-members.html create mode 100644 docs/d4/d1e/webvtt__utils_8h_source.html create mode 100644 docs/d4/d51/ttml__muxer_8cc_source.html create mode 100644 docs/d4/d56/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header-members.html create mode 100644 docs/d4/d60/structshaka_1_1media_1_1TextRegion.html create mode 100644 docs/d4/d6b/classshaka_1_1media_1_1ttml_1_1TtmlMuxer-members.html create mode 100644 docs/d4/d9f/structshaka_1_1media_1_1TextFragmentStyle.html create mode 100644 docs/d4/da9/subtitle__composer_8cc_source.html create mode 100644 docs/d4/dfa/structshaka_1_1media_1_1RgbaColor.html create mode 100644 docs/d5/d28/webvtt__utils_8cc_source.html delete mode 100644 docs/d5/d5a/webvtt__timestamp_8cc_source.html create mode 100644 docs/d5/d5b/dvb__sub__parser_8cc_source.html create mode 100644 docs/d5/db8/text__muxer_8cc_source.html rename docs/d5/{d78/classshaka_1_1media_1_1FileReader-members.html => dc0/structshaka_1_1media_1_1TextSubStreamInfo-members.html} (65%) create mode 100644 docs/d5/dd2/structshaka_1_1media_1_1TextNumber-members.html delete mode 100644 docs/d5/ddb/webvtt__text__output__handler_8cc_source.html create mode 100644 docs/d5/ddf/structshaka_1_1media_1_1RgbaColor-members.html create mode 100644 docs/d6/d22/classshaka_1_1media_1_1DvbImageColorSpace-members.html delete mode 100644 docs/d6/d2a/classshaka_1_1media_1_1WebVttTextOutputHandler.png create mode 100644 docs/d6/d84/multi__codec__muxer__listener_8cc_source.html rename docs/{de/da9/classshaka_1_1media_1_1WebVttTextOutputHandler-members.html => d6/d97/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler-members.html} (71%) create mode 100644 docs/d6/da2/structshaka_1_1media_1_1mp4_1_1AC4Specific.html create mode 100644 docs/d6/da2/structshaka_1_1media_1_1mp4_1_1AC4Specific.png delete mode 100644 docs/d6/db8/classshaka_1_1media_1_1FileReader.html create mode 100644 docs/d7/d30/classshaka_1_1media_1_1SubtitleComposer.html rename docs/{d3/de7/classshaka_1_1media_1_1PeekingReader-members.html => d7/d9e/structshaka_1_1media_1_1JobManager_1_1JobEntry-members.html} (58%) create mode 100644 docs/d7/dcf/classshaka_1_1media_1_1CcStreamFilter-members.html create mode 100644 docs/d7/dd5/ac4__audio__util_8h_source.html create mode 100644 docs/d7/dde/cc__stream__filter_8cc_source.html create mode 100644 docs/d8/d00/structshaka_1_1media_1_1TextFragmentStyle-members.html create mode 100644 docs/d8/d04/classshaka_1_1media_1_1ttml_1_1TtmlGenerator-members.html create mode 100644 docs/d8/d0c/classshaka_1_1media_1_1MultiCodecMuxerListener-members.html delete mode 100644 docs/d8/d0c/webvtt__text__output__handler_8h_source.html create mode 100644 docs/d8/d16/http__file_8cc_source.html create mode 100644 docs/d8/d4a/mpeg1__header_8h_source.html create mode 100644 docs/d8/d54/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer-members.html rename docs/d8/{dc6/classshaka_1_1media_1_1PeekingReader.html => d99/structshaka_1_1media_1_1TextNumber.html} (54%) create mode 100644 docs/d8/da9/classshaka_1_1media_1_1DvbSubParser.html create mode 100644 docs/d8/db4/classshaka_1_1media_1_1DvbImageColorSpace.html create mode 100644 docs/d8/dcb/dvb__image_8cc_source.html create mode 100644 docs/d8/dd3/classshaka_1_1media_1_1TextMuxer-members.html create mode 100644 docs/d8/dec/ttml__to__mp4__handler_8cc_source.html create mode 100644 docs/d9/d28/classshaka_1_1media_1_1DvbImageBuilder.html create mode 100644 docs/d9/d2f/http__file_8h_source.html create mode 100644 docs/d9/d44/classshaka_1_1media_1_1MultiCodecMuxerListener.html create mode 100644 docs/d9/d44/classshaka_1_1media_1_1MultiCodecMuxerListener.png create mode 100644 docs/d9/d65/classshaka_1_1media_1_1SingleThreadJobManager.html create mode 100644 docs/d9/d65/classshaka_1_1media_1_1SingleThreadJobManager.png create mode 100644 docs/d9/dae/text__muxer_8h_source.html create mode 100644 docs/d9/dca/ttml__to__mp4__handler_8h_source.html create mode 100644 docs/da/d33/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer.html create mode 100644 docs/da/d33/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer.png create mode 100644 docs/db/d13/classshaka_1_1media_1_1DvbImageBuilder-members.html create mode 100644 docs/db/d19/ttml__generator_8cc_source.html create mode 100644 docs/db/d30/classshaka_1_1media_1_1ttml_1_1TtmlMuxer.html create mode 100644 docs/db/d30/classshaka_1_1media_1_1ttml_1_1TtmlMuxer.png create mode 100644 docs/db/d32/classshaka_1_1media_1_1mp2t_1_1EsParserDvb-members.html create mode 100644 docs/db/d5a/classshaka_1_1media_1_1CcStreamFilter.html create mode 100644 docs/db/d5a/classshaka_1_1media_1_1CcStreamFilter.png create mode 100644 docs/db/db6/structshaka_1_1media_1_1TextSettings-members.html create mode 100644 docs/db/db8/ac4__audio__util_8cc_source.html create mode 100644 docs/db/dd0/ttml__generator_8h_source.html create mode 100644 docs/dc/d65/dvb__sub__parser_8h_source.html create mode 100644 docs/dd/d5e/structshaka_1_1media_1_1TextSettings.html create mode 100644 docs/dd/d79/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header.html create mode 100644 docs/dd/d79/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header.png create mode 100644 docs/dd/dc7/classshaka_1_1media_1_1DvbSubParser-members.html create mode 100644 docs/dd/ddb/structshaka_1_1media_1_1TextSubStreamInfo.html create mode 100644 docs/dd/dff/classshaka_1_1media_1_1SubtitleComposer-members.html create mode 100644 docs/de/d29/es__parser__dvb_8cc_source.html create mode 100644 docs/de/d69/single__thread__job__manager_8h_source.html create mode 100644 docs/de/d75/mpeg1__header_8cc_source.html create mode 100644 docs/de/dbd/structshaka_1_1media_1_1mp4_1_1NullMediaHeader-members.html create mode 100644 docs/de/ddc/multi__codec__muxer__listener_8h_source.html create mode 100644 docs/df/d87/classshaka_1_1media_1_1ttml_1_1TtmlGenerator.html create mode 100644 docs/df/d9e/es__parser__dvb_8h_source.html create mode 100644 docs/df/da1/cc__stream__filter_8h_source.html create mode 100644 docs/df/dda/single__thread__job__manager_8cc_source.html create mode 100644 docs/df/dee/classshaka_1_1HttpFile-members.html create mode 100644 docs/dir_121b61e6efa4d9009f3d31a3be5e474d.html create mode 100644 docs/dir_51a7c7233efd277e3898c7f3689e7b5b.html delete mode 100644 docs/doxygen.png create mode 100644 docs/doxygen.svg rename docs/{functions_func_0x7e.html => functions_func_~.html} (79%) rename docs/{functions_0x7e.html => functions_~.html} (80%) delete mode 100644 docs/search/close.png create mode 100644 docs/search/close.svg delete mode 100644 docs/search/mag_sel.png create mode 100644 docs/search/mag_sel.svg create mode 100644 html/_plantuml/d3/d388f7ab1eb3f4d70c57feb299c189351a097db9.png create mode 100644 html/_sources/tutorials/http_upload.rst.txt create mode 100644 html/_sources/tutorials/text.rst.txt delete mode 100644 html/_static/jquery-3.4.1.js delete mode 100644 html/_static/underscore-1.3.1.js create mode 100644 html/tutorials/http_upload.html create mode 100644 html/tutorials/text.html diff --git a/docs/annotated.html b/docs/annotated.html index e83c67deba..033832cebd 100644 --- a/docs/annotated.html +++ b/docs/annotated.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class List @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -66,12 +69,12 @@ $(function() {
[detail level 12345]
- - - + + + - - + + @@ -79,371 +82,393 @@ $(function() { - - - - + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + +
 NshakaAll the methods that are virtual are virtual for mocking
 Nhls
 Nmedia
 Nxml
 CAdaptationSet
 CAdCueGeneratorParamsCuepoint generator related parameters
 CBandwidthEstimator
 CBufferCallbackParamsBuffer callback params
 CCallbackFile
 CChunkingParamsChunking (segmentation) related parameters
 CContentProtectionElement
 CCuepoint
 CDecryptionParamsDecryption parameters
 CElement
 CEncryptionParamsEncryption parameters
 CFileDefine an abstract file interface
 CFileCloser
 CHlsParamsHLS related parameters
 CIoCacheDeclaration of class which implements a thread-safe circular buffer
 CLocalFileImplement LocalFile which deals with local storage
 CMemoryFile
 CMockAdaptationSet
 CMockMpdBuilder
 CMockMpdNotifier
 CMockPeriod
 CMockRepresentation
 CCallbackFile
 CFileDefine an abstract file interface
 CFileCloser
 CHttpFile
 CIoCacheDeclaration of class which implements a thread-safe circular buffer
 CLocalFileImplement LocalFile which deals with local storage
 CMemoryFile
 CBufferCallbackParamsBuffer callback params
 CThreadedIoFileDeclaration of class which implements a thread-safe circular buffer
 CUdpFileImplements UdpFile, which receives UDP unicast and multicast streams
 CUdpOptionsOptions parsed from UDP url string of the form: udp://ip:port[?options]
 CHlsParamsHLS related parameters
 CCuepoint
 CAdCueGeneratorParamsCuepoint generator related parameters
 CChunkingParamsChunking (segmentation) related parameters
 CWidevineSignerSigner credential for Widevine license server
 CWidevineEncryptionParamsWidevine encryption parameters
 CPlayReadyEncryptionParams
 CRawKeyParamsRaw key encryption/decryption parameters, i.e. with key parameters provided
 CEncryptionParamsEncryption parameters
 CWidevineDecryptionParamsWidevine decryption parameters
 CDecryptionParamsDecryption parameters
 CMp4OutputParamsMP4 (ISO-BMFF) output related parameters
 CMpdBuilderThis class generates DASH MPDs (Media Presentation Descriptions)
 CMpdNotifier
 CMpdNotifierFactory
 CMpdOptionsDefines Mpd Options
 CMpdParamsDASH MPD related parameters
 CMpdWriter
 CPackager
 CPackagingParamsPackaging parameters
 CPeriod
 CPlayReadyEncryptionParams
 CRawKeyParamsRaw key encryption/decryption parameters, i.e. with key parameters provided
 CRepresentation
 CRepresentationStateChangeListener
 CSegmentInfo
 CSimpleMpdNotifier
 CStatus
 CStreamDescriptorDefines a single input/output stream
 CTestParamsParameters used for testing
 CThreadedIoFileDeclaration of class which implements a thread-safe circular buffer
 CUdpFileImplements UdpFile, which receives UDP unicast and multicast streams
 CUdpOptionsOptions parsed from UDP url string of the form: udp://ip:port[?options]
 CWidevineDecryptionParamsWidevine decryption parameters
 CWidevineEncryptionParamsWidevine encryption parameters
 CWidevineSignerSigner credential for Widevine license server
 CAdaptationSet
 CBandwidthEstimator
 CElement
 CContentProtectionElement
 CMockMpdBuilder
 CMockPeriod
 CMockAdaptationSet
 CMockRepresentation
 CMockMpdNotifier
 CMpdBuilderThis class generates DASH MPDs (Media Presentation Descriptions)
 CMpdNotifier
 CMpdOptionsDefines Mpd Options
 CPeriod
 CRepresentationStateChangeListener
 CRepresentation
 CSegmentInfo
 CSimpleMpdNotifier
 CMpdParamsDASH MPD related parameters
 CMpdNotifierFactory
 CMpdWriter
 CTestParamsParameters used for testing
 CPackagingParamsPackaging parameters
 CStreamDescriptorDefines a single input/output stream
 CPackager
 CStatus
diff --git a/docs/classes.html b/docs/classes.html index ce24dcad2e..aa950657e7 100644 --- a/docs/classes.html +++ b/docs/classes.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Index @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -62,122 +65,79 @@ $(function() {
Class Index
-
a | b | c | d | e | f | h | i | j | k | l | m | n | o | p | r | s | t | u | v | w | x
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  a  
-
DecodingTime (shaka::media::mp4)   KeyFrameEvent (shaka::media)   PeekingReader (shaka::media)   TextSampleEntry (shaka::media::mp4)   
DecodingTimeIterator (shaka::media::mp4)   KeyFrameInfo (shaka::media::mp4)   Period (shaka)   TextStreamInfo (shaka::media)   
AACAudioSpecificConfig (shaka::media)   DecodingTimeToSample (shaka::media::mp4)   RawKeyParams::KeyInfo (shaka)   PesPacket (shaka::media::mp2t)   TextTrack (shaka::media)   
Ac3Header (shaka::media::mp2t)   DecryptConfig (shaka::media)   KeySource (shaka::media)   PesPacketGenerator (shaka::media::mp2t)   TextTrackConfig (shaka::media)   
AC3Specific (shaka::media::mp4)   DecryptionParams (shaka)   
  l  
-
PixelAspectRatio (shaka::media::mp4)   ThreadedIoFile (shaka)   
AdaptationSet (shaka)   DecryptorSource (shaka::media)   PlayReadyEncryptionParams (shaka)   AV1Parser::Tile (shaka::media)   
AdaptationSetXmlNode (shaka::xml)   Demuxer (shaka::media)   Language (shaka::media::mp4)   PlayReadyKeySource (shaka::media)   Track (shaka::media::mp4)   
AdCueGeneratorParams (shaka)   DemuxStreamIdMediaSample (shaka::media::wvm)   LibcryptoThreading (shaka::media)   PlayReadyPsshGenerator (shaka::media)   TrackEncryption (shaka::media::mp4)   
AdtsHeader (shaka::media::mp2t)   DOVIDecoderConfigurationRecord (shaka::media)   LineReader (shaka::media)   PrevSampleData (shaka::media::wvm)   TrackExtends (shaka::media::mp4)   
AesCbcDecryptor (shaka::media)   DTSSpecific (shaka::media::mp4)   LocalFile (shaka)   ProducerConsumerQueue (shaka::media)   TrackFragment (shaka::media::mp4)   
AesCbcEncryptor (shaka::media)   
  e  
-
H265SliceHeader::LongTermPicsInfo (shaka::media)   ProgramMapTableWriter (shaka::media::mp2t)   TrackFragmentDecodeTime (shaka::media::mp4)   
AesCryptor (shaka::media)   
  m  
-
ProgressListener (shaka::media)   TrackFragmentHeader (shaka::media::mp4)   
AesCtrEncryptor (shaka::media)   EC3Specific (shaka::media::mp4)   ProtectionSchemeInfo (shaka::media::mp4)   TrackFragmentRun (shaka::media::mp4)   
AesEncryptor (shaka::media)   Edit (shaka::media::mp4)   MasterPlaylist (shaka::hls)   ProtectionSystemSpecificHeader (shaka::media::mp4)   TrackHeader (shaka::media::mp4)   
AesEncryptorFactory (shaka::media)   EditList (shaka::media::mp4)   Media (shaka::media::mp4)   ProtectionSystemSpecificInfo (shaka::media)   TrackRunIterator (shaka::media::mp4)   
AesPatternCryptor (shaka::media)   EditListEntry (shaka::media::mp4)   MediaData (shaka::media::mp4)   PsshBoxBuilder (shaka::media)   TracksBuilder (shaka::media)   
AesRequestSigner (shaka::media)   Element (shaka)   MediaHandler (shaka::media)   PsshGenerator (shaka::media)   TrickPlayHandler (shaka::media)   
AudioHeader (shaka::media::mp2t)   ElementaryStreamDescriptor (shaka::media::mp4)   MediaHandlerGraphTestBase (shaka::media)   
  r  
-
TsMuxer (shaka::media::mp2t)   
AudioProgramMapTableWriter (shaka::media::mp2t)   EncryptionParams::EncryptedStreamAttributes (shaka)   MediaHandlerTestBase (shaka::media)   TsPacket (shaka::media::mp2t)   
AudioRollRecoveryEntry (shaka::media::mp4)   EncryptionConfig (shaka::media)   MediaHeader (shaka::media::mp4)   Range (shaka::media)   TsSection (shaka::media::mp2t)   
AudioSampleEntry (shaka::media::mp4)   EncryptionHandler (shaka::media)   MediaInformation (shaka::media::mp4)   RawKeyParams (shaka)   TsSectionPat (shaka::media::mp2t)   
AudioStreamInfo (shaka::media)   EncryptionKey (shaka::media)   MediaParser (shaka::media)   RawKeySource (shaka::media)   TsSectionPes (shaka::media::mp2t)   
AudioTimestampHelper (shaka::media)   EncryptionParams (shaka)   MediaPlaylist (shaka::hls)   Replicator (shaka::media)   TsSectionPmt (shaka::media::mp2t)   
AV1CodecConfigurationRecord (shaka::media)   ESDescriptor (shaka::media)   MediaPlaylistFactory (shaka::hls)   Representation (shaka)   TsSectionPsi (shaka::media::mp2t)   
AV1Parser (shaka::media)   EsParser (shaka::media::mp2t)   MuxerListener::MediaRanges (shaka::media)   RepresentationBaseXmlNode (shaka::xml)   TsSegmenter (shaka::media::mp2t)   
AVCDecoderConfigurationRecord (shaka::media)   EsParserAudio (shaka::media::mp2t)   MediaSample (shaka::media)   RepresentationStateChangeListener (shaka)   TsWriter (shaka::media::mp2t)   
  b  
-
EsParserH264 (shaka::media::mp2t)   MemoryFile (shaka)   RepresentationXmlNode (shaka::xml)   TwoPassSingleSegmentSegmenter (shaka::media::webm)   
EsParserH265 (shaka::media::mp2t)   Metadata (shaka::media::mp4)   RequestSigner (shaka::media)   
  u  
-
BandwidthEstimator (shaka)   EsParserH26x (shaka::media::mp2t)   MkvWriter (shaka::media)   RsaPrivateKey (shaka::media)   
BaseDescriptor (shaka::media)   EventInfo (shaka::media)   MockAdaptationSet (shaka)   RsaPublicKey (shaka::media)   UdpFile (shaka)   
BitReader (shaka::media)   
  f  
-
MockAesCryptor (shaka::media)   RsaRequestSigner (shaka::media)   UdpOptions (shaka)   
BitWriter (shaka::media)   MockMediaPlaylist (shaka::hls)   
  s  
-
MpdParams::UtcTiming (shaka)   
BlockReader (shaka::media)   FakeInputMediaHandler (shaka::media)   MockMpdBuilder (shaka)   
  v  
-
Box (shaka::media::mp4)   File (shaka)   MockMpdNotifier (shaka)   SampleAesEc3Cryptor (shaka::media)   
BoxBuffer (shaka::media::mp4)   FileCloser (shaka)   MockMuxerListener (shaka::media)   SampleAuxiliaryInformationOffset (shaka::media::mp4)   VideoMediaHeader (shaka::media::mp4)   
BoxReader (shaka::media::mp4)   FileReader (shaka::media)   MockOutputMediaHandler (shaka::media)   SampleAuxiliaryInformationSize (shaka::media::mp4)   VideoProgramMapTableWriter (shaka::media::mp2t)   
BufferCallbackParams (shaka)   FileType (shaka::media::mp4)   MockPeriod (shaka)   SampleDescription (shaka::media::mp4)   VideoSampleEntry (shaka::media::mp4)   
BufferReader (shaka::media)   FlacSpecific (shaka::media::mp4)   MockRepresentation (shaka)   SampleEncryption (shaka::media::mp4)   VideoSliceHeaderParser (shaka::media)   
BufferWriter (shaka::media)   Fragmenter (shaka::media::mp4)   Movie (shaka::media::mp4)   SampleEncryptionEntry (shaka::media::mp4)   EsParserH26x::VideoSliceInfo (shaka::media::mp2t)   
ByteQueue (shaka::media)   FullBox (shaka::media::mp4)   MovieExtends (shaka::media::mp4)   SampleGroupDescription (shaka::media::mp4)   VideoStreamInfo (shaka::media)   
  c  
-
  h  
-
MovieExtendsHeader (shaka::media::mp4)   SampleSize (shaka::media::mp4)   VideoStreamInfoParameters (shaka::media)   
MovieFragment (shaka::media::mp4)   SampleTable (shaka::media::mp4)   VodMediaInfoDumpMuxerListener (shaka::media)   
CachingMediaHandler (shaka::media)   H264ByteToUnitStreamConverter (shaka::media)   MovieFragmentHeader (shaka::media::mp4)   SampleToChunk (shaka::media::mp4)   VP8Parser (shaka::media)   
CallbackFile (shaka)   H264DecRefPicMarking (shaka::media)   MovieHeader (shaka::media::mp4)   SampleToGroup (shaka::media::mp4)   VP9Parser (shaka::media)   
CencSampleEncryptionInfoEntry (shaka::media::mp4)   H264ModificationOfPicNum (shaka::media)   Mp2tMediaParser (shaka::media::mp2t)   SampleToGroupEntry (shaka::media::mp4)   VPCodecConfigurationRecord (shaka::media)   
ChunkInfo (shaka::media::mp4)   H264Parser (shaka::media)   MP4MediaParser (shaka::media::mp4)   SchemeInfo (shaka::media::mp4)   VPxFrameInfo (shaka::media)   
ChunkInfoIterator (shaka::media::mp4)   H264Pps (shaka::media)   MP4Muxer (shaka::media::mp4)   SchemeType (shaka::media::mp4)   VPxParser (shaka::media)   
ChunkingHandler (shaka::media)   H264SEIMessage (shaka::media)   Mp4OutputParams (shaka)   Scte35Event (shaka::media)   VTTAdditionalTextBox (shaka::media::mp4)   
ChunkingParams (shaka)   H264SEIRecoveryPoint (shaka::media)   MpdBuilder (shaka)   SeekHead (shaka::media)   VTTCueBox (shaka::media::mp4)   
ChunkLargeOffset (shaka::media::mp4)   H264SliceHeader (shaka::media)   MpdNotifier (shaka)   Segmenter (shaka::media::mp4)   VTTEmptyCueBox (shaka::media::mp4)   
ChunkOffset (shaka::media::mp4)   H264Sps (shaka::media)   MpdNotifierFactory (shaka)   Segmenter (shaka::media::webm)   
  w  
-
ClosureThread (shaka::media)   H264VideoSliceHeaderParser (shaka::media)   MpdNotifyMuxerListener (shaka::media)   SegmentEventInfo (shaka::media)   
Cluster (shaka::media)   H264WeightingFactors (shaka::media)   MpdOptions (shaka)   SegmentIndex (shaka::media::mp4)   WebMAudioClient (shaka::media)   
ClusterBuilder (shaka::media)   H265ByteToUnitStreamConverter (shaka::media)   MpdParams (shaka)   SegmentInfo (shaka::media)   WebMClusterParser (shaka::media)   
SegmentTestBase::ClusterParser (shaka::media)   H265Parser (shaka::media)   MpdWriter (shaka)   SegmentInfo (shaka)   WebMContentEncodingsClient (shaka::media)   
CodecConfiguration (shaka::media::mp4)   H265Pps (shaka::media)   MultiSegmentSegmenter (shaka::media::mp4)   SegmentReference (shaka::media::mp4)   WebMInfoParser (shaka::media)   
CombinedMuxerListener (shaka::media)   H265ReferencePictureListModifications (shaka::media)   MultiSegmentSegmenter (shaka::media::webm)   SegmentTestBase (shaka::media)   WebMListParser (shaka::media)   
CommonPsshGenerator (shaka::media)   H265ReferencePictureSet (shaka::media)   Muxer (shaka::media)   SegmentType (shaka::media::mp4)   WebMMediaParser (shaka::media)   
CompactSampleSize (shaka::media::mp4)   H265SliceHeader (shaka::media)   MuxerFactory (shaka::media)   SimpleHlsNotifier (shaka::hls)   WebMMuxer (shaka::media::webm)   
CompositionOffset (shaka::media::mp4)   H265Sps (shaka::media)   MuxerListener (shaka::media)   SimpleMpdNotifier (shaka)   WebMParserClient (shaka::media)   
CompositionOffsetIterator (shaka::media::mp4)   H265VideoSliceHeaderParser (shaka::media)   MuxerListenerFactory (shaka::media)   SingleSegmentSegmenter (shaka::media::mp4)   WebMTracksParser (shaka::media)   
CompositionTimeToSample (shaka::media::mp4)   H265VuiParameters (shaka::media)   MuxerOptions (shaka::media)   SingleSegmentSegmenter (shaka::media::webm)   WebMVideoClient (shaka::media)   
ContentEncoding (shaka::media)   H26xBitReader (shaka::media)   
  n  
-
SLConfigDescriptor (shaka::media)   WebMWebVTTParser (shaka::media)   
ContentProtectionElement (shaka)   H26xByteToUnitStreamConverter (shaka::media)   SoundMediaHeader (shaka::media::mp4)   WebVTTConfigurationBox (shaka::media::mp4)   
ContinuityCounter (shaka::media::mp2t)   HandlerReference (shaka::media::mp4)   Nalu (shaka::media)   Status (shaka)   WebVttFileBuffer (shaka::media)   
CueAlignmentHandler (shaka::media)   HEVCDecoderConfigurationRecord (shaka::media)   NalUnitToByteStreamConverter (shaka::media)   MuxerListenerFactory::StreamData (shaka::media)   WebVttParser (shaka::media)   
CueEvent (shaka::media)   HlsEntry (shaka::hls)   NaluReader (shaka::media)   StreamData (shaka::media)   WebVTTSourceLabelBox (shaka::media::mp4)   
CueEventInfo (shaka::media)   HlsNotifier (shaka::hls)   
  o  
-
StreamDescriptor (shaka)   WebVttTextOutputHandler (shaka::media)   
CueIDBox (shaka::media::mp4)   HlsNotifyMuxerListener (shaka::media)   StreamInfo (shaka::media)   WebVttToMp4Handler (shaka::media)   
CuePayloadBox (shaka::media::mp4)   HlsParams (shaka)   OffsetByteQueue (shaka::media)   SubsampleEntry (shaka::media)   WidevineDecryptionParams (shaka)   
Cuepoint (shaka)   HttpKeyFetcher (shaka::media)   EncryptionParams::EncryptedStreamAttributes::OneOf (shaka)   SubsampleGenerator (shaka::media)   WidevineEncryptionParams (shaka)   
CueSettingsBox (shaka::media::mp4)   
  i  
-
OnMediaEndParameters (shaka::media)   SubtitleMediaHeader (shaka::media::mp4)   WidevineKeySource (shaka::media)   
CueSourceIDBox (shaka::media::mp4)   OnNewSegmentParameters (shaka::media)   SyncPointQueue (shaka::media)   WidevinePsshGenerator (shaka::media)   
CueTimeBox (shaka::media::mp4)   Id3Tag (shaka::media)   OpusSpecific (shaka::media::mp4)   SyncSample (shaka::media::mp4)   WidevineSigner (shaka)   
  d  
-
ID3v2 (shaka::media::mp4)   OriginalFormat (shaka::media::mp4)   SyncSampleIterator (shaka::media::mp4)   WvmMediaParser (shaka::media::wvm)   
IoCache (shaka)   OriginHandler (shaka::media)   
  t  
-
  x  
-
DataEntryUrl (shaka::media::mp4)   
  j  
-
  p  
-
DataInformation (shaka::media::mp4)   Tag (shaka::hls)   XmlDeleter (shaka::xml)   
DataReference (shaka::media::mp4)   Job (shaka::media)   Packager (shaka)   TestParams (shaka)   XmlNode (shaka::xml)   
DecoderConfigDescriptor (shaka::media)   JobManager (shaka::media)   PackagingParams (shaka)   TextChunker (shaka::media)   
DecoderConfigurationRecord (shaka::media)   
  k  
-
PackedAudioSegmenter (shaka::media)   TextPadder (shaka::media)   
DecoderSpecificInfoDescriptor (shaka::media)   PackedAudioWriter (shaka::media)   TextSample (shaka::media)   
KeyFetcher (shaka::media)   
-
a | b | c | d | e | f | h | i | j | k | l | m | n | o | p | r | s | t | u | v | w | x
+
A | B | C | D | E | F | H | I | J | K | L | M | N | O | P | R | S | T | U | V | W | X
+
+
+
A
+
AACAudioSpecificConfig (shaka::media)
Ac3Header (shaka::media::mp2t)
AC3Specific (shaka::media::mp4)
AC4Specific (shaka::media::mp4)
AdaptationSet (shaka)
AdaptationSetXmlNode (shaka::xml)
AdCueGeneratorParams (shaka)
AdtsHeader (shaka::media::mp2t)
AesCbcDecryptor (shaka::media)
AesCbcEncryptor (shaka::media)
AesCryptor (shaka::media)
AesCtrEncryptor (shaka::media)
AesEncryptor (shaka::media)
AesEncryptorFactory (shaka::media)
AesPatternCryptor (shaka::media)
AesRequestSigner (shaka::media)
AudioHeader (shaka::media::mp2t)
AudioProgramMapTableWriter (shaka::media::mp2t)
AudioRollRecoveryEntry (shaka::media::mp4)
AudioSampleEntry (shaka::media::mp4)
AudioStreamInfo (shaka::media)
AudioTimestampHelper (shaka::media)
AV1CodecConfigurationRecord (shaka::media)
AV1Parser (shaka::media)
AVCDecoderConfigurationRecord (shaka::media)
+
+
B
+
BandwidthEstimator (shaka)
BaseDescriptor (shaka::media)
BitReader (shaka::media)
BitWriter (shaka::media)
BlockReader (shaka::media)
Box (shaka::media::mp4)
BoxBuffer (shaka::media::mp4)
BoxReader (shaka::media::mp4)
BufferCallbackParams (shaka)
BufferReader (shaka::media)
BufferWriter (shaka::media)
ByteQueue (shaka::media)
+
+
C
+
CachingMediaHandler (shaka::media)
CallbackFile (shaka)
CcStreamFilter (shaka::media)
CencSampleEncryptionInfoEntry (shaka::media::mp4)
ChunkInfo (shaka::media::mp4)
ChunkInfoIterator (shaka::media::mp4)
ChunkingHandler (shaka::media)
ChunkingParams (shaka)
ChunkLargeOffset (shaka::media::mp4)
ChunkOffset (shaka::media::mp4)
ClosureThread (shaka::media)
Cluster (shaka::media)
ClusterBuilder (shaka::media)
SegmentTestBase::ClusterParser (shaka::media)
CodecConfiguration (shaka::media::mp4)
CombinedMuxerListener (shaka::media)
CommonPsshGenerator (shaka::media)
CompactSampleSize (shaka::media::mp4)
CompositionOffset (shaka::media::mp4)
CompositionOffsetIterator (shaka::media::mp4)
CompositionTimeToSample (shaka::media::mp4)
ContentEncoding (shaka::media)
ContentProtectionElement (shaka)
ContinuityCounter (shaka::media::mp2t)
CueAlignmentHandler (shaka::media)
CueEvent (shaka::media)
CueEventInfo (shaka::media)
CueIDBox (shaka::media::mp4)
CuePayloadBox (shaka::media::mp4)
Cuepoint (shaka)
CueSettingsBox (shaka::media::mp4)
CueSourceIDBox (shaka::media::mp4)
CueTimeBox (shaka::media::mp4)
+
+
D
+
DataEntryUrl (shaka::media::mp4)
DataInformation (shaka::media::mp4)
DataReference (shaka::media::mp4)
DecoderConfigDescriptor (shaka::media)
DecoderConfigurationRecord (shaka::media)
DecoderSpecificInfoDescriptor (shaka::media)
DecodingTime (shaka::media::mp4)
DecodingTimeIterator (shaka::media::mp4)
DecodingTimeToSample (shaka::media::mp4)
DecryptConfig (shaka::media)
DecryptionParams (shaka)
DecryptorSource (shaka::media)
Demuxer (shaka::media)
DemuxStreamIdMediaSample (shaka::media::wvm)
DOVIDecoderConfigurationRecord (shaka::media)
DTSSpecific (shaka::media::mp4)
DvbImageBuilder (shaka::media)
DvbImageColorSpace (shaka::media)
DvbSubParser (shaka::media)
+
+
E
+
EC3Specific (shaka::media::mp4)
Edit (shaka::media::mp4)
EditList (shaka::media::mp4)
EditListEntry (shaka::media::mp4)
Element (shaka)
ElementaryStreamDescriptor (shaka::media::mp4)
EncryptionParams::EncryptedStreamAttributes (shaka)
EncryptionConfig (shaka::media)
EncryptionHandler (shaka::media)
EncryptionKey (shaka::media)
EncryptionParams (shaka)
ESDescriptor (shaka::media)
EsParser (shaka::media::mp2t)
EsParserAudio (shaka::media::mp2t)
EsParserDvb (shaka::media::mp2t)
EsParserH264 (shaka::media::mp2t)
EsParserH265 (shaka::media::mp2t)
EsParserH26x (shaka::media::mp2t)
EventInfo (shaka::media)
+
+
F
+
FakeInputMediaHandler (shaka::media)
File (shaka)
FileCloser (shaka)
FileType (shaka::media::mp4)
FlacSpecific (shaka::media::mp4)
Fragmenter (shaka::media::mp4)
FullBox (shaka::media::mp4)
+
+
H
+
H264ByteToUnitStreamConverter (shaka::media)
H264DecRefPicMarking (shaka::media)
H264ModificationOfPicNum (shaka::media)
H264Parser (shaka::media)
H264Pps (shaka::media)
H264SEIMessage (shaka::media)
H264SEIRecoveryPoint (shaka::media)
H264SliceHeader (shaka::media)
H264Sps (shaka::media)
H264VideoSliceHeaderParser (shaka::media)
H264WeightingFactors (shaka::media)
H265ByteToUnitStreamConverter (shaka::media)
H265Parser (shaka::media)
H265Pps (shaka::media)
H265ReferencePictureListModifications (shaka::media)
H265ReferencePictureSet (shaka::media)
H265SliceHeader (shaka::media)
H265Sps (shaka::media)
H265VideoSliceHeaderParser (shaka::media)
H265VuiParameters (shaka::media)
H26xBitReader (shaka::media)
H26xByteToUnitStreamConverter (shaka::media)
HandlerReference (shaka::media::mp4)
HEVCDecoderConfigurationRecord (shaka::media)
HlsEntry (shaka::hls)
HlsNotifier (shaka::hls)
HlsNotifyMuxerListener (shaka::media)
HlsParams (shaka)
HttpFile (shaka)
HttpKeyFetcher (shaka::media)
+
+
I
+
Id3Tag (shaka::media)
ID3v2 (shaka::media::mp4)
IoCache (shaka)
+
+
J
+
Job (shaka::media)
JobManager::JobEntry (shaka::media)
JobManager (shaka::media)
+
+
K
+
KeyFetcher (shaka::media)
KeyFrameEvent (shaka::media)
KeyFrameInfo (shaka::media::mp4)
RawKeyParams::KeyInfo (shaka)
KeySource (shaka::media)
+
+
L
+
Language (shaka::media::mp4)
LibcryptoThreading (shaka::media)
LineReader (shaka::media)
LocalFile (shaka)
H265SliceHeader::LongTermPicsInfo (shaka::media)
+
+
M
+
MasterPlaylist (shaka::hls)
Media (shaka::media::mp4)
MediaData (shaka::media::mp4)
MediaHandler (shaka::media)
MediaHandlerGraphTestBase (shaka::media)
MediaHandlerTestBase (shaka::media)
MediaHeader (shaka::media::mp4)
MediaInformation (shaka::media::mp4)
MediaParser (shaka::media)
MediaPlaylist (shaka::hls)
MediaPlaylistFactory (shaka::hls)
MuxerListener::MediaRanges (shaka::media)
MediaSample (shaka::media)
MemoryFile (shaka)
Metadata (shaka::media::mp4)
MkvWriter (shaka::media)
MockAdaptationSet (shaka)
MockAesCryptor (shaka::media)
MockMediaPlaylist (shaka::hls)
MockMpdBuilder (shaka)
MockMpdNotifier (shaka)
MockMuxerListener (shaka::media)
MockOutputMediaHandler (shaka::media)
MockPeriod (shaka)
MockRepresentation (shaka)
Movie (shaka::media::mp4)
MovieExtends (shaka::media::mp4)
MovieExtendsHeader (shaka::media::mp4)
MovieFragment (shaka::media::mp4)
MovieFragmentHeader (shaka::media::mp4)
MovieHeader (shaka::media::mp4)
Mp2tMediaParser (shaka::media::mp2t)
MP4MediaParser (shaka::media::mp4)
MP4Muxer (shaka::media::mp4)
Mp4OutputParams (shaka)
MpdBuilder (shaka)
MpdNotifier (shaka)
MpdNotifierFactory (shaka)
MpdNotifyMuxerListener (shaka::media)
MpdOptions (shaka)
MpdParams (shaka)
MpdWriter (shaka)
Mpeg1Header (shaka::media::mp2t)
MultiCodecMuxerListener (shaka::media)
MultiSegmentSegmenter (shaka::media::mp4)
MultiSegmentSegmenter (shaka::media::webm)
Muxer (shaka::media)
MuxerFactory (shaka::media)
MuxerListener (shaka::media)
MuxerListenerFactory (shaka::media)
MuxerOptions (shaka::media)
+
+
N
+
Nalu (shaka::media)
NalUnitToByteStreamConverter (shaka::media)
NaluReader (shaka::media)
NullMediaHeader (shaka::media::mp4)
+
+
O
+
OffsetByteQueue (shaka::media)
EncryptionParams::EncryptedStreamAttributes::OneOf (shaka)
OnMediaEndParameters (shaka::media)
OnNewSegmentParameters (shaka::media)
OpusSpecific (shaka::media::mp4)
OriginalFormat (shaka::media::mp4)
OriginHandler (shaka::media)
+
+
P
+
Packager (shaka)
PackagingParams (shaka)
PackedAudioSegmenter (shaka::media)
PackedAudioWriter (shaka::media)
Period (shaka)
PesPacket (shaka::media::mp2t)
PesPacketGenerator (shaka::media::mp2t)
PixelAspectRatio (shaka::media::mp4)
PlayReadyEncryptionParams (shaka)
PlayReadyKeySource (shaka::media)
PlayReadyPsshGenerator (shaka::media)
PrevSampleData (shaka::media::wvm)
ProducerConsumerQueue (shaka::media)
ProgramMapTableWriter (shaka::media::mp2t)
ProgressListener (shaka::media)
ProtectionSchemeInfo (shaka::media::mp4)
ProtectionSystemSpecificHeader (shaka::media::mp4)
ProtectionSystemSpecificInfo (shaka::media)
PsshBoxBuilder (shaka::media)
PsshGenerator (shaka::media)
+
+
R
+
Range (shaka::media)
RawKeyParams (shaka)
RawKeySource (shaka::media)
Replicator (shaka::media)
Representation (shaka)
RepresentationBaseXmlNode (shaka::xml)
RepresentationStateChangeListener (shaka)
RepresentationXmlNode (shaka::xml)
RequestSigner (shaka::media)
RgbaColor (shaka::media)
RsaPrivateKey (shaka::media)
RsaPublicKey (shaka::media)
RsaRequestSigner (shaka::media)
+
+
S
+
SampleAesEc3Cryptor (shaka::media)
SampleAuxiliaryInformationOffset (shaka::media::mp4)
SampleAuxiliaryInformationSize (shaka::media::mp4)
SampleDescription (shaka::media::mp4)
SampleEncryption (shaka::media::mp4)
SampleEncryptionEntry (shaka::media::mp4)
SampleGroupDescription (shaka::media::mp4)
SampleSize (shaka::media::mp4)
SampleTable (shaka::media::mp4)
SampleToChunk (shaka::media::mp4)
SampleToGroup (shaka::media::mp4)
SampleToGroupEntry (shaka::media::mp4)
SchemeInfo (shaka::media::mp4)
SchemeType (shaka::media::mp4)
Scte35Event (shaka::media)
SeekHead (shaka::media)
Segmenter (shaka::media::mp4)
Segmenter (shaka::media::webm)
SegmentEventInfo (shaka::media)
SegmentIndex (shaka::media::mp4)
SegmentInfo (shaka::media)
SegmentInfo (shaka)
SegmentReference (shaka::media::mp4)
SegmentTestBase (shaka::media)
SegmentType (shaka::media::mp4)
SimpleHlsNotifier (shaka::hls)
SimpleMpdNotifier (shaka)
SingleSegmentSegmenter (shaka::media::mp4)
SingleSegmentSegmenter (shaka::media::webm)
SingleThreadJobManager (shaka::media)
SLConfigDescriptor (shaka::media)
SoundMediaHeader (shaka::media::mp4)
Status (shaka)
MuxerListenerFactory::StreamData (shaka::media)
StreamData (shaka::media)
StreamDescriptor (shaka)
StreamInfo (shaka::media)
SubsampleEntry (shaka::media)
SubsampleGenerator (shaka::media)
SubtitleComposer (shaka::media)
SubtitleMediaHeader (shaka::media::mp4)
SyncPointQueue (shaka::media)
SyncSample (shaka::media::mp4)
SyncSampleIterator (shaka::media::mp4)
+
+
T
+
Tag (shaka::hls)
TestParams (shaka)
TextChunker (shaka::media)
TextFragment (shaka::media)
TextFragmentStyle (shaka::media)
TextMuxer (shaka::media)
TextNumber (shaka::media)
TextPadder (shaka::media)
TextRegion (shaka::media)
TextSample (shaka::media)
TextSampleEntry (shaka::media::mp4)
TextSettings (shaka::media)
TextStreamInfo (shaka::media)
TextSubStreamInfo (shaka::media)
TextTrack (shaka::media)
TextTrackConfig (shaka::media)
ThreadedIoFile (shaka)
AV1Parser::Tile (shaka::media)
Track (shaka::media::mp4)
TrackEncryption (shaka::media::mp4)
TrackExtends (shaka::media::mp4)
TrackFragment (shaka::media::mp4)
TrackFragmentDecodeTime (shaka::media::mp4)
TrackFragmentHeader (shaka::media::mp4)
TrackFragmentRun (shaka::media::mp4)
TrackHeader (shaka::media::mp4)
TrackRunIterator (shaka::media::mp4)
TracksBuilder (shaka::media)
TrickPlayHandler (shaka::media)
TsMuxer (shaka::media::mp2t)
TsPacket (shaka::media::mp2t)
TsSection (shaka::media::mp2t)
TsSectionPat (shaka::media::mp2t)
TsSectionPes (shaka::media::mp2t)
TsSectionPmt (shaka::media::mp2t)
TsSectionPsi (shaka::media::mp2t)
TsSegmenter (shaka::media::mp2t)
TsWriter (shaka::media::mp2t)
TtmlGenerator (shaka::media::ttml)
TtmlMuxer (shaka::media::ttml)
TtmlToMp4Handler (shaka::media::ttml)
TwoPassSingleSegmentSegmenter (shaka::media::webm)
+
+
U
+
UdpFile (shaka)
UdpOptions (shaka)
MpdParams::UtcTiming (shaka)
+
+
V
+
VideoMediaHeader (shaka::media::mp4)
VideoProgramMapTableWriter (shaka::media::mp2t)
VideoSampleEntry (shaka::media::mp4)
VideoSliceHeaderParser (shaka::media)
EsParserH26x::VideoSliceInfo (shaka::media::mp2t)
VideoStreamInfo (shaka::media)
VideoStreamInfoParameters (shaka::media)
VodMediaInfoDumpMuxerListener (shaka::media)
VP8Parser (shaka::media)
VP9Parser (shaka::media)
VPCodecConfigurationRecord (shaka::media)
VPxFrameInfo (shaka::media)
VPxParser (shaka::media)
VTTAdditionalTextBox (shaka::media::mp4)
VTTCueBox (shaka::media::mp4)
VTTEmptyCueBox (shaka::media::mp4)
+
+
W
+
WebMAudioClient (shaka::media)
WebMClusterParser (shaka::media)
WebMContentEncodingsClient (shaka::media)
WebMInfoParser (shaka::media)
WebMListParser (shaka::media)
WebMMediaParser (shaka::media)
WebMMuxer (shaka::media::webm)
WebMParserClient (shaka::media)
WebMTracksParser (shaka::media)
WebMVideoClient (shaka::media)
WebMWebVTTParser (shaka::media)
WebVTTConfigurationBox (shaka::media::mp4)
WebVttFileBuffer (shaka::media)
WebVttMuxer (shaka::media::webvtt)
WebVttParser (shaka::media)
WebVTTSourceLabelBox (shaka::media::mp4)
WebVttToMp4Handler (shaka::media)
WidevineDecryptionParams (shaka)
WidevineEncryptionParams (shaka)
WidevineKeySource (shaka::media)
WidevinePsshGenerator (shaka::media)
WidevineSigner (shaka)
WvmMediaParser (shaka::media::wvm)
+
+
X
+
XmlDeleter (shaka::xml)
XmlNode (shaka::xml)
+
diff --git a/docs/d0/d00/structshaka_1_1media_1_1mp4_1_1HandlerReference-members.html b/docs/d0/d00/structshaka_1_1media_1_1mp4_1_1HandlerReference-members.html index 60e0156eaf..cbd5479de2 100644 --- a/docs/d0/d00/structshaka_1_1media_1_1mp4_1_1HandlerReference-members.html +++ b/docs/d0/d00/structshaka_1_1media_1_1mp4_1_1HandlerReference-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d0/d04/classshaka_1_1media_1_1RsaRequestSigner-members.html b/docs/d0/d04/classshaka_1_1media_1_1RsaRequestSigner-members.html index 8f3e0a0f59..6aa19353fe 100644 --- a/docs/d0/d04/classshaka_1_1media_1_1RsaRequestSigner-members.html +++ b/docs/d0/d04/classshaka_1_1media_1_1RsaRequestSigner-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d0/d05/muxer__listener__factory_8cc_source.html b/docs/d0/d05/muxer__listener__factory_8cc_source.html index 1044f6a5a4..9d1dfaa416 100644 --- a/docs/d0/d05/muxer__listener__factory_8cc_source.html +++ b/docs/d0/d05/muxer__listener__factory_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/muxer_listener_factory.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
muxer_listener_factory.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/event/muxer_listener_factory.h"
8 
9 #include "packager/base/memory/ptr_util.h"
10 #include "packager/base/strings/stringprintf.h"
11 #include "packager/hls/base/hls_notifier.h"
12 #include "packager/media/event/combined_muxer_listener.h"
13 #include "packager/media/event/hls_notify_muxer_listener.h"
14 #include "packager/media/event/mpd_notify_muxer_listener.h"
15 #include "packager/media/event/muxer_listener.h"
16 #include "packager/media/event/vod_media_info_dump_muxer_listener.h"
17 #include "packager/mpd/base/mpd_notifier.h"
18 
19 namespace shaka {
20 namespace media {
21 namespace {
22 const char kMediaInfoSuffix[] = ".media_info";
23 
24 std::unique_ptr<MuxerListener> CreateMediaInfoDumpListenerInternal(
25  const std::string& output) {
26  DCHECK(!output.empty());
27 
28  std::unique_ptr<MuxerListener> listener(
29  new VodMediaInfoDumpMuxerListener(output + kMediaInfoSuffix));
30  return listener;
31 }
32 
33 std::unique_ptr<MuxerListener> CreateMpdListenerInternal(
34  const MuxerListenerFactory::StreamData& stream,
35  MpdNotifier* notifier) {
36  DCHECK(notifier);
37 
38  auto listener = base::MakeUnique<MpdNotifyMuxerListener>(notifier);
39  listener->set_accessibilities(stream.dash_accessiblities);
40  listener->set_roles(stream.dash_roles);
41  return listener;
42 }
43 
44 std::list<std::unique_ptr<MuxerListener>> CreateHlsListenersInternal(
45  const MuxerListenerFactory::StreamData& stream,
46  int stream_index,
47  hls::HlsNotifier* notifier) {
48  DCHECK(notifier);
49  DCHECK_GE(stream_index, 0);
50 
51  std::string name = stream.hls_name;
52  std::string playlist_name = stream.hls_playlist_name;
53 
54  const std::string& group_id = stream.hls_group_id;
55  const std::string& iframe_playlist_name = stream.hls_iframe_playlist_name;
56  const std::vector<std::string>& characteristics = stream.hls_characteristics;
57 
58  if (name.empty()) {
59  name = base::StringPrintf("stream_%d", stream_index);
60  }
61 
62  if (playlist_name.empty()) {
63  playlist_name = base::StringPrintf("stream_%d.m3u8", stream_index);
64  }
65 
66  const bool kIFramesOnly = true;
67  std::list<std::unique_ptr<MuxerListener>> listeners;
68  listeners.emplace_back(new HlsNotifyMuxerListener(
69  playlist_name, !kIFramesOnly, name, group_id, characteristics, notifier));
70  if (!iframe_playlist_name.empty()) {
71  listeners.emplace_back(new HlsNotifyMuxerListener(
72  iframe_playlist_name, kIFramesOnly, name, group_id,
73  std::vector<std::string>(), notifier));
74  }
75  return listeners;
76 }
77 } // namespace
78 
80  MpdNotifier* mpd_notifier,
81  hls::HlsNotifier* hls_notifier)
82  : output_media_info_(output_media_info),
83  mpd_notifier_(mpd_notifier),
84  hls_notifier_(hls_notifier) {}
85 
86 std::unique_ptr<MuxerListener> MuxerListenerFactory::CreateListener(
87  const StreamData& stream) {
88  const int stream_index = stream_index_++;
89 
90  std::unique_ptr<CombinedMuxerListener> combined_listener(
92 
93  if (output_media_info_) {
94  combined_listener->AddListener(
95  CreateMediaInfoDumpListenerInternal(stream.media_info_output));
96  }
97  if (mpd_notifier_) {
98  combined_listener->AddListener(
99  CreateMpdListenerInternal(stream, mpd_notifier_));
100  }
101  if (hls_notifier_) {
102  for (auto& listener :
103  CreateHlsListenersInternal(stream, stream_index, hls_notifier_)) {
104  combined_listener->AddListener(std::move(listener));
105  }
106  }
107 
108  return std::move(combined_listener);
109 }
110 
111 std::unique_ptr<MuxerListener> MuxerListenerFactory::CreateHlsListener(
112  const StreamData& stream) {
113  if (!hls_notifier_) {
114  return nullptr;
115  }
116 
117  const int stream_index = stream_index_++;
118  return std::move(
119  CreateHlsListenersInternal(stream, stream_index, hls_notifier_).front());
120 }
121 
122 } // namespace media
123 } // namespace shaka
All the methods that are virtual are virtual for mocking.
- -
std::unique_ptr< MuxerListener > CreateListener(const StreamData &stream)
Create a listener for a stream.
- -
std::unique_ptr< MuxerListener > CreateHlsListener(const StreamData &stream)
- -
MuxerListenerFactory(bool output_media_info, MpdNotifier *mpd_notifier, hls::HlsNotifier *hls_notifier)
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/event/muxer_listener_factory.h"
+
8 
+
9 #include <list>
+
10 
+
11 #include "packager/base/memory/ptr_util.h"
+
12 #include "packager/base/strings/stringprintf.h"
+
13 #include "packager/hls/base/hls_notifier.h"
+
14 #include "packager/media/event/combined_muxer_listener.h"
+
15 #include "packager/media/event/hls_notify_muxer_listener.h"
+
16 #include "packager/media/event/mpd_notify_muxer_listener.h"
+
17 #include "packager/media/event/multi_codec_muxer_listener.h"
+
18 #include "packager/media/event/muxer_listener.h"
+
19 #include "packager/media/event/vod_media_info_dump_muxer_listener.h"
+
20 #include "packager/mpd/base/mpd_notifier.h"
+
21 
+
22 namespace shaka {
+
23 namespace media {
+
24 namespace {
+
25 const char kMediaInfoSuffix[] = ".media_info";
+
26 
+
27 std::unique_ptr<MuxerListener> CreateMediaInfoDumpListenerInternal(
+
28  const std::string& output) {
+
29  DCHECK(!output.empty());
+
30 
+
31  std::unique_ptr<MuxerListener> listener(
+
32  new VodMediaInfoDumpMuxerListener(output + kMediaInfoSuffix));
+
33  return listener;
+
34 }
+
35 
+
36 std::unique_ptr<MuxerListener> CreateMpdListenerInternal(
+
37  const MuxerListenerFactory::StreamData& stream,
+
38  MpdNotifier* notifier) {
+
39  DCHECK(notifier);
+
40 
+
41  auto listener = base::MakeUnique<MpdNotifyMuxerListener>(notifier);
+
42  listener->set_accessibilities(stream.dash_accessiblities);
+
43  listener->set_roles(stream.dash_roles);
+
44  return listener;
+
45 }
+
46 
+
47 std::list<std::unique_ptr<MuxerListener>> CreateHlsListenersInternal(
+
48  const MuxerListenerFactory::StreamData& stream,
+
49  int stream_index,
+
50  hls::HlsNotifier* notifier) {
+
51  DCHECK(notifier);
+
52  DCHECK_GE(stream_index, 0);
+
53 
+
54  std::string name = stream.hls_name;
+
55  std::string playlist_name = stream.hls_playlist_name;
+
56 
+
57  const std::string& group_id = stream.hls_group_id;
+
58  const std::string& iframe_playlist_name = stream.hls_iframe_playlist_name;
+
59  const std::vector<std::string>& characteristics = stream.hls_characteristics;
+
60 
+
61  if (name.empty()) {
+
62  name = base::StringPrintf("stream_%d", stream_index);
+
63  }
+
64 
+
65  if (playlist_name.empty()) {
+
66  playlist_name = base::StringPrintf("stream_%d.m3u8", stream_index);
+
67  }
+
68 
+
69  const bool kIFramesOnly = true;
+
70  std::list<std::unique_ptr<MuxerListener>> listeners;
+
71  listeners.emplace_back(new HlsNotifyMuxerListener(
+
72  playlist_name, !kIFramesOnly, name, group_id, characteristics, notifier));
+
73  if (!iframe_playlist_name.empty()) {
+
74  listeners.emplace_back(new HlsNotifyMuxerListener(
+
75  iframe_playlist_name, kIFramesOnly, name, group_id,
+
76  std::vector<std::string>(), notifier));
+
77  }
+
78  return listeners;
+
79 }
+
80 } // namespace
+
81 
+ +
83  MpdNotifier* mpd_notifier,
+
84  hls::HlsNotifier* hls_notifier)
+
85  : output_media_info_(output_media_info),
+
86  mpd_notifier_(mpd_notifier),
+
87  hls_notifier_(hls_notifier) {}
+
88 
+
89 std::unique_ptr<MuxerListener> MuxerListenerFactory::CreateListener(
+
90  const StreamData& stream) {
+
91  const int stream_index = stream_index_++;
+
92 
+
93  // Use a MultiCodecMuxerListener to handle possible DolbyVision profile 8
+
94  // stream which can be signalled as two different codecs.
+
95  std::unique_ptr<MultiCodecMuxerListener> multi_codec_listener(
+ +
97  // Creates two child MuxerListeners. Both are used if the stream is a
+
98  // multi-codec stream (e.g. DolbyVision proifile 8); otherwise the second
+
99  // child is ignored. Right now the only use case is DolbyVision profile 8
+
100  // which contains two codecs.
+
101  for (int i = 0; i < 2; i++) {
+
102  std::unique_ptr<CombinedMuxerListener> combined_listener(
+ +
104  if (output_media_info_) {
+
105  combined_listener->AddListener(
+
106  CreateMediaInfoDumpListenerInternal(stream.media_info_output));
+
107  }
+
108 
+
109  if (mpd_notifier_ && !stream.hls_only) {
+
110  combined_listener->AddListener(
+
111  CreateMpdListenerInternal(stream, mpd_notifier_));
+
112  }
+
113 
+
114  if (hls_notifier_ && !stream.dash_only) {
+
115  for (auto& listener :
+
116  CreateHlsListenersInternal(stream, stream_index, hls_notifier_)) {
+
117  combined_listener->AddListener(std::move(listener));
+
118  }
+
119  }
+
120 
+
121  multi_codec_listener->AddListener(std::move(combined_listener));
+
122  }
+
123 
+
124  return std::move(multi_codec_listener);
+
125 }
+
126 
+
127 std::unique_ptr<MuxerListener> MuxerListenerFactory::CreateHlsListener(
+
128  const StreamData& stream) {
+
129  if (!hls_notifier_) {
+
130  return nullptr;
+
131  }
+
132 
+
133  const int stream_index = stream_index_++;
+
134  return std::move(
+
135  CreateHlsListenersInternal(stream, stream_index, hls_notifier_).front());
+
136 }
+
137 
+
138 } // namespace media
+
139 } // namespace shaka
+ + + + +
std::unique_ptr< MuxerListener > CreateHlsListener(const StreamData &stream)
+
std::unique_ptr< MuxerListener > CreateListener(const StreamData &stream)
Create a listener for a stream.
+
MuxerListenerFactory(bool output_media_info, MpdNotifier *mpd_notifier, hls::HlsNotifier *hls_notifier)
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d0/d06/mpd__flags_8cc_source.html b/docs/d0/d06/mpd__flags_8cc_source.html index d9dff9d2d5..5df4e20094 100644 --- a/docs/d0/d06/mpd__flags_8cc_source.html +++ b/docs/d0/d06/mpd__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/mpd_flags.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mpd_flags.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines Mpd flags.
8 
9 #include "packager/app/mpd_flags.h"
10 
11 DEFINE_bool(generate_static_live_mpd,
12  false,
13  "Set to true to generate static mpd. If segment_template is "
14  "specified in stream descriptors, shaka-packager generates dynamic "
15  "mpd by default; if this flag is enabled, shaka-packager generates "
16  "static mpd instead. Note that if segment_template is not "
17  "specified, shaka-packager always generates static mpd regardless "
18  "of the value of this flag.");
19 // TODO(rkuroiwa, kqyang): Remove the 'Exclusive' statements once
20 // --output_media_info can work together with --mpd_output.
21 DEFINE_bool(output_media_info,
22  false,
23  "Create a human readable format of MediaInfo. The output file name "
24  "will be the name specified by output flag, suffixed with "
25  "'.media_info'. Exclusive with --mpd_output.");
26 DEFINE_string(mpd_output, "",
27  "MPD output file name. Exclusive with --output_media_info.");
28 DEFINE_string(base_urls,
29  "",
30  "Comma separated BaseURLs for the MPD. The values will be added "
31  "as <BaseURL> element(s) immediately under the <MPD> element.");
32 DEFINE_double(min_buffer_time,
33  2.0,
34  "Specifies, in seconds, a common duration used in the definition "
35  "of the MPD Representation data rate.");
36 DEFINE_double(minimum_update_period,
37  5.0,
38  "Indicates to the player how often to refresh the media "
39  "presentation description in seconds. This value is used for "
40  "dynamic MPD only.");
41 DEFINE_double(suggested_presentation_delay,
42  0.0,
43  "Specifies a delay, in seconds, to be added to the media "
44  "presentation time. This value is used for dynamic MPD only.");
45 DEFINE_string(utc_timings,
46  "",
47  "Comma separated UTCTiming schemeIdUri and value pairs for the "
48  "MPD. This value is used for dynamic MPD only.");
49 DEFINE_bool(generate_dash_if_iop_compliant_mpd,
50  true,
51  "Try to generate DASH-IF IOP compliant MPD. This is best effort "
52  "and does not guarantee compliance.");
53 DEFINE_bool(
54  allow_approximate_segment_timeline,
55  false,
56  "For live profile only. "
57  "If enabled, segments with close duration (i.e. with difference less than "
58  "one sample) are considered to have the same duration. This enables MPD "
59  "generator to generate less SegmentTimeline entries. If all segments are "
60  "of the same duration except the last one, we will do further optimization "
61  "to use SegmentTemplate@duration instead and omit SegmentTimeline "
62  "completely."
63  "Ignored if $Time$ is used in segment template, since $Time$ requires "
64  "accurate Segment Timeline.");
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines Mpd flags.
+
8 
+
9 #include "packager/app/mpd_flags.h"
+
10 
+
11 DEFINE_bool(generate_static_live_mpd,
+
12  false,
+
13  "Set to true to generate static mpd. If segment_template is "
+
14  "specified in stream descriptors, shaka-packager generates dynamic "
+
15  "mpd by default; if this flag is enabled, shaka-packager generates "
+
16  "static mpd instead. Note that if segment_template is not "
+
17  "specified, shaka-packager always generates static mpd regardless "
+
18  "of the value of this flag.");
+
19 DEFINE_bool(output_media_info,
+
20  false,
+
21  "Create a human readable format of MediaInfo. The output file name "
+
22  "will be the name specified by output flag, suffixed with "
+
23  "'.media_info'.");
+
24 DEFINE_string(mpd_output, "", "MPD output file name.");
+
25 DEFINE_string(base_urls,
+
26  "",
+
27  "Comma separated BaseURLs for the MPD. The values will be added "
+
28  "as <BaseURL> element(s) immediately under the <MPD> element.");
+
29 DEFINE_double(min_buffer_time,
+
30  2.0,
+
31  "Specifies, in seconds, a common duration used in the definition "
+
32  "of the MPD Representation data rate.");
+
33 DEFINE_double(minimum_update_period,
+
34  5.0,
+
35  "Indicates to the player how often to refresh the media "
+
36  "presentation description in seconds. This value is used for "
+
37  "dynamic MPD only.");
+
38 DEFINE_double(suggested_presentation_delay,
+
39  0.0,
+
40  "Specifies a delay, in seconds, to be added to the media "
+
41  "presentation time. This value is used for dynamic MPD only.");
+
42 DEFINE_string(utc_timings,
+
43  "",
+
44  "Comma separated UTCTiming schemeIdUri and value pairs for the "
+
45  "MPD. This value is used for dynamic MPD only.");
+
46 DEFINE_bool(generate_dash_if_iop_compliant_mpd,
+
47  true,
+
48  "Try to generate DASH-IF IOP compliant MPD. This is best effort "
+
49  "and does not guarantee compliance.");
+
50 DEFINE_bool(
+
51  allow_approximate_segment_timeline,
+
52  false,
+
53  "For live profile only. "
+
54  "If enabled, segments with close duration (i.e. with difference less than "
+
55  "one sample) are considered to have the same duration. This enables MPD "
+
56  "generator to generate less SegmentTimeline entries. If all segments are "
+
57  "of the same duration except the last one, we will do further optimization "
+
58  "to use SegmentTemplate@duration instead and omit SegmentTimeline "
+
59  "completely."
+
60  "Ignored if $Time$ is used in segment template, since $Time$ requires "
+
61  "accurate Segment Timeline.");
+
62 DEFINE_bool(allow_codec_switching,
+
63  false,
+
64  "If enabled, allow adaptive switching between different codecs, "
+
65  "if they have the same language, media type (audio, video etc) and "
+
66  "container type.");
+
67 DEFINE_bool(include_mspr_pro_for_playready,
+
68  true,
+
69  "If enabled, PlayReady Object <mspr:pro> will be inserted into "
+
70  "<ContentProtection ...> element alongside with <cenc:pssh> "
+
71  "when using PlayReady protection system.");
+
diff --git a/docs/d0/d07/av1__codec__configuration__record_8h_source.html b/docs/d0/d07/av1__codec__configuration__record_8h_source.html index dec88f2a34..d5ee8cfea2 100644 --- a/docs/d0/d07/av1__codec__configuration__record_8h_source.html +++ b/docs/d0/d07/av1__codec__configuration__record_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/av1_codec_configuration_record.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
av1_codec_configuration_record.h
-
1 // Copyright 2018 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CODECS_AV1_CODEC_CONFIGURATION_RECORD_H_
8 #define PACKAGER_MEDIA_CODECS_AV1_CODEC_CONFIGURATION_RECORD_H_
9 
10 #include <stdint.h>
11 #include <string>
12 #include <vector>
13 
14 namespace shaka {
15 namespace media {
16 
19  public:
22 
25  bool Parse(const std::vector<uint8_t>& data) {
26  return Parse(data.data(), data.size());
27  }
28 
31  bool Parse(const uint8_t* data, size_t data_size);
32 
34  std::string GetCodecString() const;
35 
36  private:
37  int profile_ = 0;
38  int level_ = 0;
39  int tier_ = 0;
40  int bit_depth_ = 0;
41  int mono_chrome_ = 0;
42  int chroma_subsampling_x_ = 0;
43  int chroma_subsampling_y_ = 0;
44  int chroma_sample_position_ = 0;
45 
46  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
47  // generated copy constructor and assignment operator. Since the internal data
48  // is small, the performance impact is minimal.
49 };
50 
51 } // namespace media
52 } // namespace shaka
53 
54 #endif // PACKAGER_MEDIA_CODECS_AV1_CODEC_CONFIGURATION_RECORD_H_
All the methods that are virtual are virtual for mocking.
- -
bool Parse(const std::vector< uint8_t > &data)
-
Class for parsing AV1 codec configuration record.
+
1 // Copyright 2018 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_AV1_CODEC_CONFIGURATION_RECORD_H_
+
8 #define PACKAGER_MEDIA_CODECS_AV1_CODEC_CONFIGURATION_RECORD_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 
+ +
19  public:
+ + +
22 
+
25  bool Parse(const std::vector<uint8_t>& data) {
+
26  return Parse(data.data(), data.size());
+
27  }
+
28 
+
31  bool Parse(const uint8_t* data, size_t data_size);
+
32 
+
34  std::string GetCodecString() const;
+
35 
+
36  private:
+
37  int profile_ = 0;
+
38  int level_ = 0;
+
39  int tier_ = 0;
+
40  int bit_depth_ = 0;
+
41  int mono_chrome_ = 0;
+
42  int chroma_subsampling_x_ = 0;
+
43  int chroma_subsampling_y_ = 0;
+
44  int chroma_sample_position_ = 0;
+
45 
+
46  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
+
47  // generated copy constructor and assignment operator. Since the internal data
+
48  // is small, the performance impact is minimal.
+
49 };
+
50 
+
51 } // namespace media
+
52 } // namespace shaka
+
53 
+
54 #endif // PACKAGER_MEDIA_CODECS_AV1_CODEC_CONFIGURATION_RECORD_H_
+
Class for parsing AV1 codec configuration record.
+ +
bool Parse(const std::vector< uint8_t > &data)
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d0e/classshaka_1_1media_1_1HttpKeyFetcher-members.html b/docs/d0/d0e/classshaka_1_1media_1_1HttpKeyFetcher-members.html index 8f070d9234..a84725d0b4 100644 --- a/docs/d0/d0e/classshaka_1_1media_1_1HttpKeyFetcher-members.html +++ b/docs/d0/d0e/classshaka_1_1media_1_1HttpKeyFetcher-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
HttpKeyFetcher(uint32_t timeout_in_seconds)shaka::media::HttpKeyFetcher KeyFetcher() (defined in shaka::media::KeyFetcher)shaka::media::KeyFetcher Post(const std::string &url, const std::string &data, std::string *response)shaka::media::HttpKeyFetchervirtual - SetCaFile(const std::string &ca_file)shaka::media::HttpKeyFetcherinline - SetClientCertInfo(const std::string &cert_file, const std::string &private_key_file, const std::string &private_key_password)shaka::media::HttpKeyFetcherinline ~HttpKeyFetcher() override (defined in shaka::media::HttpKeyFetcher)shaka::media::HttpKeyFetcher ~KeyFetcher() (defined in shaka::media::KeyFetcher)shaka::media::KeyFetchervirtual
diff --git a/docs/d0/d0e/hevc__decoder__configuration__record_8h_source.html b/docs/d0/d0e/hevc__decoder__configuration__record_8h_source.html index 48e6747047..c67304eb36 100644 --- a/docs/d0/d0e/hevc__decoder__configuration__record_8h_source.html +++ b/docs/d0/d0e/hevc__decoder__configuration__record_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/hevc_decoder_configuration_record.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
hevc_decoder_configuration_record.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CODECS_HEVC_DECODER_CONFIGURATION_RECORD_H_
8 #define PACKAGER_MEDIA_CODECS_HEVC_DECODER_CONFIGURATION_RECORD_H_
9 
10 #include <stdint.h>
11 #include <string>
12 #include <vector>
13 
14 #include "packager/base/macros.h"
15 #include "packager/media/base/fourccs.h"
16 #include "packager/media/base/video_stream_info.h"
17 #include "packager/media/codecs/decoder_configuration_record.h"
18 
19 namespace shaka {
20 namespace media {
21 
24  public:
27 
29  std::string GetCodecString(FourCC codec_fourcc) const;
30 
31  private:
32  bool ParseInternal() override;
33 
34  uint8_t version_ = 0;
35  uint8_t general_profile_space_ = 0;
36  bool general_tier_flag_ = false;
37  uint8_t general_profile_idc_ = 0;
38  uint32_t general_profile_compatibility_flags_ = 0;
39  std::vector<uint8_t> general_constraint_indicator_flags_;
40  uint8_t general_level_idc_ = 0;
41 
42  DISALLOW_COPY_AND_ASSIGN(HEVCDecoderConfigurationRecord);
43 };
44 
45 } // namespace media
46 } // namespace shaka
47 
48 #endif // PACKAGER_MEDIA_CODECS_HEVC_DECODER_CONFIGURATION_RECORD_H_
-
All the methods that are virtual are virtual for mocking.
- -
Class for parsing HEVC decoder configuration record.
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_HEVC_DECODER_CONFIGURATION_RECORD_H_
+
8 #define PACKAGER_MEDIA_CODECS_HEVC_DECODER_CONFIGURATION_RECORD_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/base/macros.h"
+
15 #include "packager/media/base/fourccs.h"
+
16 #include "packager/media/base/video_stream_info.h"
+
17 #include "packager/media/codecs/decoder_configuration_record.h"
+
18 
+
19 namespace shaka {
+
20 namespace media {
+
21 
+ +
24  public:
+ + +
27 
+
29  std::string GetCodecString(FourCC codec_fourcc) const;
+
30 
+
31  private:
+
32  bool ParseInternal() override;
+
33 
+
34  uint8_t version_ = 0;
+
35  uint8_t general_profile_space_ = 0;
+
36  bool general_tier_flag_ = false;
+
37  uint8_t general_profile_idc_ = 0;
+
38  uint32_t general_profile_compatibility_flags_ = 0;
+
39  std::vector<uint8_t> general_constraint_indicator_flags_;
+
40  uint8_t general_level_idc_ = 0;
+
41 
+
42  DISALLOW_COPY_AND_ASSIGN(HEVCDecoderConfigurationRecord);
+
43 };
+
44 
+
45 } // namespace media
+
46 } // namespace shaka
+
47 
+
48 #endif // PACKAGER_MEDIA_CODECS_HEVC_DECODER_CONFIGURATION_RECORD_H_
+ +
Class for parsing HEVC decoder configuration record.
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d0e/muxer__options_8h_source.html b/docs/d0/d0e/muxer__options_8h_source.html index bc7e2e288a..0734ed989e 100644 --- a/docs/d0/d0e/muxer__options_8h_source.html +++ b/docs/d0/d0e/muxer__options_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/muxer_options.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
muxer_options.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_MUXER_OPTIONS_H_
8 #define PACKAGER_MEDIA_BASE_MUXER_OPTIONS_H_
9 
10 #include <stdint.h>
11 
12 #include <string>
13 
14 #include "packager/media/public/mp4_output_params.h"
15 
16 namespace shaka {
17 namespace media {
18 
20 struct MuxerOptions {
21  MuxerOptions();
22  ~MuxerOptions();
23 
26 
27  // A positive value, in milliseconds, by which output timestamps are offset to
28  // compensate for negative timestamps in the input.
29  uint32_t transport_stream_timestamp_offset_ms = 0;
30 
34  std::string output_file_name;
35 
40  std::string segment_template;
41 
43  std::string temp_dir;
44 
47  uint32_t bandwidth = 0;
48 };
49 
50 } // namespace media
51 } // namespace shaka
52 
53 #endif // PACKAGER_MEDIA_BASE_MUXER_OPTIONS_H_
-
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
-
MP4 (ISO-BMFF) output related parameters.
-
Mp4OutputParams mp4_params
MP4 (ISO-BMFF) specific parameters.
Definition: muxer_options.h:25
-
std::string temp_dir
Specify temporary directory for intermediate files.
Definition: muxer_options.h:43
- - +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_MUXER_OPTIONS_H_
+
8 #define PACKAGER_MEDIA_BASE_MUXER_OPTIONS_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <string>
+
13 
+
14 #include "packager/media/public/mp4_output_params.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+
20 struct MuxerOptions {
+
21  MuxerOptions();
+
22  ~MuxerOptions();
+
23 
+ +
26 
+
27  // A positive value, in milliseconds, by which output timestamps are offset to
+
28  // compensate for negative timestamps in the input.
+
29  uint32_t transport_stream_timestamp_offset_ms = 0;
+
30 
+
34  std::string output_file_name;
+
35 
+
40  std::string segment_template;
+
41 
+
43  std::string temp_dir;
+
44 
+
47  uint32_t bandwidth = 0;
+
48 };
+
49 
+
50 } // namespace media
+
51 } // namespace shaka
+
52 
+
53 #endif // PACKAGER_MEDIA_BASE_MUXER_OPTIONS_H_
+
All the methods that are virtual are virtual for mocking.
+
MP4 (ISO-BMFF) output related parameters.
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+ +
std::string temp_dir
Specify temporary directory for intermediate files.
Definition: muxer_options.h:43
+ +
Mp4OutputParams mp4_params
MP4 (ISO-BMFF) specific parameters.
Definition: muxer_options.h:25
+
diff --git a/docs/d0/d0f/classshaka_1_1media_1_1mp2t_1_1TsSectionPmt-members.html b/docs/d0/d0f/classshaka_1_1media_1_1mp2t_1_1TsSectionPmt-members.html index 56fc367d78..b7f0ceb5ca 100644 --- a/docs/d0/d0f/classshaka_1_1media_1_1mp2t_1_1TsSectionPmt-members.html +++ b/docs/d0/d0f/classshaka_1_1media_1_1mp2t_1_1TsSectionPmt-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/d10/classshaka_1_1media_1_1WidevinePsshGenerator-members.html b/docs/d0/d10/classshaka_1_1media_1_1WidevinePsshGenerator-members.html index aadfbb10da..2391f116b6 100644 --- a/docs/d0/d10/classshaka_1_1media_1_1WidevinePsshGenerator-members.html +++ b/docs/d0/d10/classshaka_1_1media_1_1WidevinePsshGenerator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d0/d11/structshaka_1_1media_1_1VPxFrameInfo.html b/docs/d0/d11/structshaka_1_1media_1_1VPxFrameInfo.html index d66ec9cc29..1ac078ba8e 100644 --- a/docs/d0/d11/structshaka_1_1media_1_1VPxFrameInfo.html +++ b/docs/d0/d11/structshaka_1_1media_1_1VPxFrameInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::VPxFrameInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
height diff --git a/docs/d0/d17/structshaka_1_1media_1_1StreamData-members.html b/docs/d0/d17/structshaka_1_1media_1_1StreamData-members.html index 0434a60bbf..a68da37d10 100644 --- a/docs/d0/d17/structshaka_1_1media_1_1StreamData-members.html +++ b/docs/d0/d17/structshaka_1_1media_1_1StreamData-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/d1a/text__sample_8h_source.html b/docs/d0/d1a/text__sample_8h_source.html index b185af0187..2c877ceb12 100644 --- a/docs/d0/d1a/text__sample_8h_source.html +++ b/docs/d0/d1a/text__sample_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/text_sample.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
text_sample.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_TEXT_SAMPLE_H_
8 #define PACKAGER_MEDIA_BASE_TEXT_SAMPLE_H_
9 
10 #include <stdint.h>
11 
12 #include <string>
13 
14 namespace shaka {
15 namespace media {
16 
17 class TextSample {
18  public:
19  TextSample() = default;
20 
21  const std::string& id() const { return id_; }
22  int64_t start_time() const { return start_time_; }
23  int64_t duration() const { return duration_; }
24  const std::string& settings() const { return settings_; }
25  const std::string& payload() const { return payload_; }
26  int64_t EndTime() const;
27 
28  void set_id(const std::string& id) { id_ = id; }
29  void SetTime(int64_t start_time, int64_t end_time);
30  void AppendStyle(const std::string& style);
31  void AppendPayload(const std::string& payload);
32 
33  private:
34  // Allow the compiler generated copy constructor and assignment operator
35  // intentionally. Since the text data is typically small, the performance
36  // impact is minimal.
37 
38  std::string id_;
39  int64_t start_time_ = 0;
40  int64_t duration_ = 0;
41  std::string settings_;
42  std::string payload_;
43 };
44 
45 } // namespace media
46 } // namespace shaka
47 
48 #endif // PACKAGER_MEDIA_BASE_TEXT_SAMPLE_H_
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_TEXT_SAMPLE_H_
+
8 #define PACKAGER_MEDIA_BASE_TEXT_SAMPLE_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <string>
+
13 #include <vector>
+
14 
+
15 #include "packager/base/optional.h"
+
16 
+
17 namespace shaka {
+
18 namespace media {
+
19 
+
20 enum class TextUnitType {
+
22  kPixels,
+
24  kLines,
+
26  kPercent,
+
27 };
+
28 
+
29 enum class WritingDirection {
+
30  kHorizontal,
+
31  kVerticalGrowingLeft,
+
32  kVerticalGrowingRight,
+
33 };
+
34 
+
35 enum class TextAlignment {
+
37  kStart,
+
39  kCenter,
+
41  kEnd,
+
43  kLeft,
+
45  kRight,
+
46 };
+
47 
+
48 struct TextNumber {
+
49  TextNumber(float value, TextUnitType type) : value(value), type(type) {}
+
50 
+
51  float value;
+
52  TextUnitType type;
+
53 };
+
54 
+
55 struct TextSettings {
+
58  base::Optional<TextNumber> line;
+
61  base::Optional<TextNumber> position;
+
65  base::Optional<TextNumber> width;
+
69  base::Optional<TextNumber> height;
+
70 
+
72  std::string region;
+
73 
+
76  WritingDirection writing_direction = WritingDirection::kHorizontal;
+
78  TextAlignment text_alignment = TextAlignment::kCenter;
+
79 };
+
80 
+ +
82  base::Optional<bool> underline;
+
83  base::Optional<bool> bold;
+
84  base::Optional<bool> italic;
+
85 };
+
86 
+
89 struct TextFragment {
+
90  TextFragment() {}
+
91  TextFragment(const TextFragmentStyle& style,
+
92  const std::vector<TextFragment>& sub_fragments)
+
93  : style(style), sub_fragments(sub_fragments) {}
+
94  TextFragment(const TextFragmentStyle& style, const char* body)
+
95  : style(style), body(body) {}
+
96  TextFragment(const TextFragmentStyle& style, const std::string& body)
+
97  : style(style), body(body) {}
+
98  TextFragment(const TextFragmentStyle& style,
+
99  const std::vector<uint8_t>& image)
+
100  : style(style), image(image) {}
+
101  TextFragment(const TextFragmentStyle& style, bool newline)
+
102  : style(style), newline(newline) {}
+
103 
+
104  TextFragmentStyle style;
+
105 
+
106  std::vector<TextFragment> sub_fragments;
+
107  std::string body;
+
109  std::vector<uint8_t> image;
+
110  bool newline = false;
+
111 
+
112  bool is_empty() const;
+
113 };
+
114 
+
115 class TextSample {
+
116  public:
+
117  TextSample(const std::string& id,
+
118  int64_t start_time,
+
119  int64_t end_time,
+
120  const TextSettings& settings,
+
121  const TextFragment& body);
+
122 
+
123  const std::string& id() const { return id_; }
+
124  int64_t start_time() const { return start_time_; }
+
125  int64_t duration() const { return duration_; }
+
126  const TextSettings& settings() const { return settings_; }
+
127  const TextFragment& body() const { return body_; }
+
128  int64_t EndTime() const;
+
129 
+
130  int32_t sub_stream_index() const { return sub_stream_index_; }
+
131  void set_sub_stream_index(int32_t idx) { sub_stream_index_ = idx; }
+
132 
+
133  private:
+
134  // Allow the compiler generated copy constructor and assignment operator
+
135  // intentionally. Since the text data is typically small, the performance
+
136  // impact is minimal.
+
137 
+
138  const std::string id_;
+
139  const int64_t start_time_ = 0;
+
140  const int64_t duration_ = 0;
+
141  const TextSettings settings_;
+
142  const TextFragment body_;
+
143  int32_t sub_stream_index_ = -1;
+
144 };
+
145 
+
146 } // namespace media
+
147 } // namespace shaka
+
148 
+
149 #endif // PACKAGER_MEDIA_BASE_TEXT_SAMPLE_H_
+ +
All the methods that are virtual are virtual for mocking.
+ + +
std::vector< uint8_t > image
PNG image data.
Definition: text_sample.h:109
+ + +
base::Optional< TextNumber > line
Definition: text_sample.h:58
+
TextAlignment text_alignment
How to align the text within the cue box.
Definition: text_sample.h:78
+
std::string region
The region to draw the cue in.
Definition: text_sample.h:72
+
base::Optional< TextNumber > position
Definition: text_sample.h:61
+
base::Optional< TextNumber > height
Definition: text_sample.h:69
+
WritingDirection writing_direction
Definition: text_sample.h:76
+
base::Optional< TextNumber > width
Definition: text_sample.h:65
diff --git a/docs/d0/d1e/classshaka_1_1media_1_1H265ByteToUnitStreamConverter-members.html b/docs/d0/d1e/classshaka_1_1media_1_1H265ByteToUnitStreamConverter-members.html index 20655549c0..ff98639c69 100644 --- a/docs/d0/d1e/classshaka_1_1media_1_1H265ByteToUnitStreamConverter-members.html +++ b/docs/d0/d1e/classshaka_1_1media_1_1H265ByteToUnitStreamConverter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/d1f/structshaka_1_1media_1_1mp4_1_1VTTCueBox-members.html b/docs/d0/d1f/structshaka_1_1media_1_1mp4_1_1VTTCueBox-members.html index a42163126b..7b3a029250 100644 --- a/docs/d0/d1f/structshaka_1_1media_1_1mp4_1_1VTTCueBox-members.html +++ b/docs/d0/d1f/structshaka_1_1media_1_1mp4_1_1VTTCueBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d0/d26/classshaka_1_1media_1_1mp2t_1_1TsSectionPat.html b/docs/d0/d26/classshaka_1_1media_1_1mp2t_1_1TsSectionPat.html index 985390b52e..9e0a9c7841 100644 --- a/docs/d0/d26/classshaka_1_1media_1_1mp2t_1_1TsSectionPat.html +++ b/docs/d0/d26/classshaka_1_1media_1_1mp2t_1_1TsSectionPat.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::TsSectionPat Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp2t::TsSectionPsi shaka::media::mp2t::TsSection - -
+ + @@ -88,11 +91,11 @@ typedef base::Callback< void(int, int)>  @@ -113,9 +116,9 @@ void  - - + + @@ -130,9 +133,7 @@ void 

Public Types

 
- Public Types inherited from shaka::media::mp2t::TsSection
enum  SpecialPid {
-  kPidPat = 0x0, -kPidCat = 0x1, -kPidTsdt = 0x2, -kPidNullPacket = 0x1fff, -
+  kPidPat = 0x0 +, kPidCat = 0x1 +, kPidTsdt = 0x2 +, kPidNullPacket = 0x1fff +,
  kPidMax = 0x1fff
}
ResetPsiSection (
bool Parse (bool payload_unit_start_indicator, const uint8_t *buf, int size) override
 
-void Flush () override
 
+bool Flush () override
 
void Reset () override
 
Reset () override diff --git a/docs/d0/d27/structshaka_1_1media_1_1MuxerOptions.html b/docs/d0/d27/structshaka_1_1media_1_1MuxerOptions.html index 2a0f271aa8..b2097b8566 100644 --- a/docs/d0/d27/structshaka_1_1media_1_1MuxerOptions.html +++ b/docs/d0/d27/structshaka_1_1media_1_1MuxerOptions.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MuxerOptions Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/d2b/representation_8h_source.html b/docs/d0/d2b/representation_8h_source.html index 87643962a2..8df0c2e209 100644 --- a/docs/d0/d2b/representation_8h_source.html +++ b/docs/d0/d2b/representation_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/representation.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
representation.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
8 
9 #ifndef PACKAGER_MPD_BASE_REPRESENTATION_H_
10 #define PACKAGER_MPD_BASE_REPRESENTATION_H_
11 
12 #include "packager/mpd/base/bandwidth_estimator.h"
13 #include "packager/mpd/base/media_info.pb.h"
14 #include "packager/mpd/base/segment_info.h"
15 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
16 
17 #include <stdint.h>
18 
19 #include <list>
20 #include <memory>
21 
22 namespace shaka {
23 
24 struct ContentProtectionElement;
25 struct MpdOptions;
26 
27 namespace xml {
28 class XmlNode;
29 class RepresentationXmlNode;
30 } // namespace xml
31 
33  public:
36 
41  virtual void OnNewSegmentForRepresentation(int64_t start_time,
42  int64_t duration) = 0;
43 
48  virtual void OnSetFrameRateForRepresentation(uint32_t frame_duration,
49  uint32_t timescale) = 0;
50 };
51 
55  public:
56  enum SuppressFlag {
57  kSuppressWidth = 1,
58  kSuppressHeight = 2,
59  kSuppressFrameRate = 4,
60  };
61 
62  virtual ~Representation();
63 
67  bool Init();
68 
79  virtual void AddContentProtectionElement(
80  const ContentProtectionElement& element);
81 
93  virtual void UpdateContentProtectionPssh(const std::string& drm_uuid,
94  const std::string& pssh);
95 
104  virtual void AddNewSegment(int64_t start_time,
105  int64_t duration,
106  uint64_t size);
107 
113  virtual void SetSampleDuration(uint32_t sample_duration);
114 
116  virtual const MediaInfo& GetMediaInfo() const;
117 
119  xml::scoped_xml_ptr<xmlNode> GetXml();
120 
129  void SuppressOnce(SuppressFlag flag);
130 
132  void SetPresentationTimeOffset(double presentation_time_offset);
133 
142  bool GetStartAndEndTimestamps(double* start_timestamp_seconds,
143  double* end_timestamp_seconds) const;
144 
146  uint32_t id() const { return id_; }
147 
148  void set_media_info(const MediaInfo& media_info) { media_info_ = media_info; }
149 
150  protected:
160  const MediaInfo& media_info,
161  const MpdOptions& mpd_options,
162  uint32_t representation_id,
163  std::unique_ptr<RepresentationStateChangeListener> state_change_listener);
164 
169  const Representation& representation,
170  std::unique_ptr<RepresentationStateChangeListener> state_change_listener);
171 
172  private:
173  Representation(const Representation&) = delete;
174  Representation& operator=(const Representation&) = delete;
175 
176  friend class AdaptationSet;
177  friend class RepresentationTest;
178 
179  // Returns true if |media_info_| has required fields to generate a valid
180  // Representation. Otherwise returns false.
181  bool HasRequiredMediaInfoFields() const;
182 
183  // Add a SegmentInfo. This function may insert an adjusted SegmentInfo if
184  // |allow_approximate_segment_timeline_| is set.
185  void AddSegmentInfo(int64_t start_time, int64_t duration);
186 
187  // Check if two timestamps are approximately equal if
188  // |allow_approximate_segment_timeline_| is set; Otherwise check whether the
189  // two times match.
190  bool ApproximiatelyEqual(int64_t time1, int64_t time2) const;
191 
192  // Return adjusted duration if |allow_aproximate_segment_timeline_or_duration|
193  // is set; otherwise duration is returned without adjustment.
194  int64_t AdjustDuration(int64_t duration) const;
195 
196  // Remove elements from |segment_infos_| for dynamic live profile. Increments
197  // |start_number_| by the number of segments removed.
198  void SlideWindow();
199 
200  // Remove the first segment in |segment_info|.
201  void RemoveOldSegment(SegmentInfo* segment_info);
202 
203  // Note: Because 'mimeType' is a required field for a valid MPD, these return
204  // strings.
205  std::string GetVideoMimeType() const;
206  std::string GetAudioMimeType() const;
207  std::string GetTextMimeType() const;
208 
209  // Get Representation as string. For debugging.
210  std::string RepresentationAsString() const;
211 
212  // Init() checks that only one of VideoInfo, AudioInfo, or TextInfo is set. So
213  // any logic using this can assume only one set.
214  MediaInfo media_info_;
215  std::list<ContentProtectionElement> content_protection_elements_;
216 
217  int64_t current_buffer_depth_ = 0;
218  // TODO(kqyang): Address sliding window issue with multiple periods.
219  std::list<SegmentInfo> segment_infos_;
220  // A list to hold the file names of the segments to be removed temporarily.
221  // Once a file is actually removed, it is removed from the list.
222  std::list<std::string> segments_to_be_removed_;
223 
224  const uint32_t id_;
225  std::string mime_type_;
226  std::string codecs_;
227  BandwidthEstimator bandwidth_estimator_;
228  const MpdOptions& mpd_options_;
229 
230  // startNumber attribute for SegmentTemplate.
231  // Starts from 1.
232  uint32_t start_number_ = 1;
233 
234  // If this is not null, then Representation is responsible for calling the
235  // right methods at right timings.
236  std::unique_ptr<RepresentationStateChangeListener> state_change_listener_;
237 
238  // Bit vector for tracking witch attributes should not be output.
239  int output_suppression_flags_ = 0;
240 
241  // When set to true, allows segments to have slightly different durations (up
242  // to one sample).
243  const bool allow_approximate_segment_timeline_ = false;
244  // Segments with duration difference less than one frame duration are
245  // considered to have the same duration.
246  uint32_t frame_duration_ = 0;
247 };
248 
249 } // namespace shaka
250 
251 #endif // PACKAGER_MPD_BASE_REPRESENTATION_H_
-
uint32_t id() const
-
All the methods that are virtual are virtual for mocking.
- - - - -
Defines Mpd Options.
Definition: mpd_options.h:25
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
8 
+
9 #ifndef PACKAGER_MPD_BASE_REPRESENTATION_H_
+
10 #define PACKAGER_MPD_BASE_REPRESENTATION_H_
+
11 
+
12 #include <stdint.h>
+
13 
+
14 #include <list>
+
15 #include <memory>
+
16 
+
17 #include "packager/base/optional.h"
+
18 #include "packager/mpd/base/bandwidth_estimator.h"
+
19 #include "packager/mpd/base/media_info.pb.h"
+
20 #include "packager/mpd/base/segment_info.h"
+
21 #include "packager/mpd/base/xml/xml_node.h"
+
22 
+
23 namespace shaka {
+
24 
+
25 struct ContentProtectionElement;
+
26 struct MpdOptions;
+
27 
+ +
29  public:
+ + +
32 
+
37  virtual void OnNewSegmentForRepresentation(int64_t start_time,
+
38  int64_t duration) = 0;
+
39 
+
44  virtual void OnSetFrameRateForRepresentation(uint32_t frame_duration,
+
45  uint32_t timescale) = 0;
+
46 };
+
47 
+ +
51  public:
+
52  enum SuppressFlag {
+
53  kSuppressWidth = 1,
+
54  kSuppressHeight = 2,
+
55  kSuppressFrameRate = 4,
+
56  };
+
57 
+
58  virtual ~Representation();
+
59 
+
63  bool Init();
+
64 
+
75  virtual void AddContentProtectionElement(
+
76  const ContentProtectionElement& element);
+
77 
+
89  virtual void UpdateContentProtectionPssh(const std::string& drm_uuid,
+
90  const std::string& pssh);
+
91 
+
100  virtual void AddNewSegment(int64_t start_time,
+
101  int64_t duration,
+
102  uint64_t size);
+
103 
+
109  virtual void SetSampleDuration(uint32_t sample_duration);
+
110 
+
112  virtual const MediaInfo& GetMediaInfo() const;
+
113 
+
115  base::Optional<xml::XmlNode> GetXml();
+
116 
+
125  void SuppressOnce(SuppressFlag flag);
+
126 
+
128  void SetPresentationTimeOffset(double presentation_time_offset);
+
129 
+
138  bool GetStartAndEndTimestamps(double* start_timestamp_seconds,
+
139  double* end_timestamp_seconds) const;
+
140 
+
142  uint32_t id() const { return id_; }
+
143 
+
144  void set_media_info(const MediaInfo& media_info) { media_info_ = media_info; }
+
145 
+
146  protected:
+ +
156  const MediaInfo& media_info,
+
157  const MpdOptions& mpd_options,
+
158  uint32_t representation_id,
+
159  std::unique_ptr<RepresentationStateChangeListener> state_change_listener);
+
160 
+ +
165  const Representation& representation,
+
166  std::unique_ptr<RepresentationStateChangeListener> state_change_listener);
+
167 
+
168  private:
+
169  Representation(const Representation&) = delete;
+
170  Representation& operator=(const Representation&) = delete;
+
171 
+
172  friend class AdaptationSet;
+
173  friend class RepresentationTest;
+
174 
+
175  // Returns true if |media_info_| has required fields to generate a valid
+
176  // Representation. Otherwise returns false.
+
177  bool HasRequiredMediaInfoFields() const;
+
178 
+
179  // Add a SegmentInfo. This function may insert an adjusted SegmentInfo if
+
180  // |allow_approximate_segment_timeline_| is set.
+
181  void AddSegmentInfo(int64_t start_time, int64_t duration);
+
182 
+
183  // Check if two timestamps are approximately equal if
+
184  // |allow_approximate_segment_timeline_| is set; Otherwise check whether the
+
185  // two times match.
+
186  bool ApproximiatelyEqual(int64_t time1, int64_t time2) const;
+
187 
+
188  // Return adjusted duration if |allow_aproximate_segment_timeline_or_duration|
+
189  // is set; otherwise duration is returned without adjustment.
+
190  int64_t AdjustDuration(int64_t duration) const;
+
191 
+
192  // Remove elements from |segment_infos_| for dynamic live profile. Increments
+
193  // |start_number_| by the number of segments removed.
+
194  void SlideWindow();
+
195 
+
196  // Remove the first segment in |segment_info|.
+
197  void RemoveOldSegment(SegmentInfo* segment_info);
+
198 
+
199  // Note: Because 'mimeType' is a required field for a valid MPD, these return
+
200  // strings.
+
201  std::string GetVideoMimeType() const;
+
202  std::string GetAudioMimeType() const;
+
203  std::string GetTextMimeType() const;
+
204 
+
205  // Get Representation as string. For debugging.
+
206  std::string RepresentationAsString() const;
+
207 
+
208  // Init() checks that only one of VideoInfo, AudioInfo, or TextInfo is set. So
+
209  // any logic using this can assume only one set.
+
210  MediaInfo media_info_;
+
211  std::list<ContentProtectionElement> content_protection_elements_;
+
212 
+
213  int64_t current_buffer_depth_ = 0;
+
214  // TODO(kqyang): Address sliding window issue with multiple periods.
+
215  std::list<SegmentInfo> segment_infos_;
+
216  // A list to hold the file names of the segments to be removed temporarily.
+
217  // Once a file is actually removed, it is removed from the list.
+
218  std::list<std::string> segments_to_be_removed_;
+
219 
+
220  const uint32_t id_;
+
221  std::string mime_type_;
+
222  std::string codecs_;
+
223  BandwidthEstimator bandwidth_estimator_;
+
224  const MpdOptions& mpd_options_;
+
225 
+
226  // startNumber attribute for SegmentTemplate.
+
227  // Starts from 1.
+
228  uint32_t start_number_ = 1;
+
229 
+
230  // If this is not null, then Representation is responsible for calling the
+
231  // right methods at right timings.
+
232  std::unique_ptr<RepresentationStateChangeListener> state_change_listener_;
+
233 
+
234  // Bit vector for tracking witch attributes should not be output.
+
235  int output_suppression_flags_ = 0;
+
236 
+
237  // When set to true, allows segments to have slightly different durations (up
+
238  // to one sample).
+
239  const bool allow_approximate_segment_timeline_ = false;
+
240  // Segments with duration difference less than one frame duration are
+
241  // considered to have the same duration.
+
242  uint32_t frame_duration_ = 0;
+
243 };
+
244 
+
245 } // namespace shaka
+
246 
+
247 #endif // PACKAGER_MPD_BASE_REPRESENTATION_H_
+ +
virtual void OnSetFrameRateForRepresentation(uint32_t frame_duration, uint32_t timescale)=0
+
virtual void OnNewSegmentForRepresentation(int64_t start_time, int64_t duration)=0
+ +
virtual void SetSampleDuration(uint32_t sample_duration)
+
virtual void AddContentProtectionElement(const ContentProtectionElement &element)
+
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
+
void SuppressOnce(SuppressFlag flag)
+
virtual const MediaInfo & GetMediaInfo() const
+
bool GetStartAndEndTimestamps(double *start_timestamp_seconds, double *end_timestamp_seconds) const
+
Representation(const MediaInfo &media_info, const MpdOptions &mpd_options, uint32_t representation_id, std::unique_ptr< RepresentationStateChangeListener > state_change_listener)
+
uint32_t id() const
+
void SetPresentationTimeOffset(double presentation_time_offset)
Set @presentationTimeOffset in SegmentBase / SegmentTemplate.
+
base::Optional< xml::XmlNode > GetXml()
+ +
virtual void AddNewSegment(int64_t start_time, int64_t duration, uint64_t size)
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d0/d30/mock__mpd__notifier_8h_source.html b/docs/d0/d30/mock__mpd__notifier_8h_source.html index 4495057a56..cde984e111 100644 --- a/docs/d0/d30/mock__mpd__notifier_8h_source.html +++ b/docs/d0/d30/mock__mpd__notifier_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mock_mpd_notifier.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mock_mpd_notifier.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef MPD_BASE_MOCK_MPD_NOTIFIER_H_
8 #define MPD_BASE_MOCK_MPD_NOTIFIER_H_
9 
10 #include "packager/mpd/base/mpd_notifier.h"
11 
12 #include <gmock/gmock.h>
13 
14 #include "packager/mpd/base/content_protection_element.h"
15 #include "packager/mpd/base/media_info.pb.h"
16 
17 namespace shaka {
18 
19 class MockMpdNotifier : public MpdNotifier {
20  public:
21  explicit MockMpdNotifier(const MpdOptions& mpd_options);
22  virtual ~MockMpdNotifier();
23 
24  MOCK_METHOD0(Init, bool());
25  MOCK_METHOD2(NotifyNewContainer,
26  bool(const MediaInfo& media_info, uint32_t* container_id));
27  MOCK_METHOD2(NotifySampleDuration,
28  bool(uint32_t container_id, uint32_t sample_duration));
29  MOCK_METHOD4(NotifyNewSegment,
30  bool(uint32_t container_id,
31  uint64_t start_time,
32  uint64_t duration,
33  uint64_t size));
34  MOCK_METHOD2(NotifyCueEvent, bool(uint32_t container_id, uint64_t timestamp));
35  MOCK_METHOD4(NotifyEncryptionUpdate,
36  bool(uint32_t container_id,
37  const std::string& drm_uuid,
38  const std::vector<uint8_t>& new_key_id,
39  const std::vector<uint8_t>& new_pssh));
40  MOCK_METHOD2(NotifyMediaInfoUpdate,
41  bool(uint32_t container_id, const MediaInfo& media_info));
42  MOCK_METHOD0(Flush, bool());
43 };
44 
45 } // namespace shaka
46 
47 #endif // MPD_BASE_MOCK_MPD_NOTIFIER_H_
virtual bool Flush()=0
-
virtual bool Init()=0
-
virtual bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0
- -
virtual bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0
-
All the methods that are virtual are virtual for mocking.
-
virtual bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0
-
virtual bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0
-
virtual bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0
- -
virtual bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0
-
Defines Mpd Options.
Definition: mpd_options.h:25
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef MPD_BASE_MOCK_MPD_NOTIFIER_H_
+
8 #define MPD_BASE_MOCK_MPD_NOTIFIER_H_
+
9 
+
10 #include "packager/mpd/base/mpd_notifier.h"
+
11 
+
12 #include <gmock/gmock.h>
+
13 
+
14 #include "packager/mpd/base/content_protection_element.h"
+
15 #include "packager/mpd/base/media_info.pb.h"
+
16 
+
17 namespace shaka {
+
18 
+
19 class MockMpdNotifier : public MpdNotifier {
+
20  public:
+
21  explicit MockMpdNotifier(const MpdOptions& mpd_options);
+
22  virtual ~MockMpdNotifier();
+
23 
+
24  MOCK_METHOD0(Init, bool());
+
25  MOCK_METHOD2(NotifyNewContainer,
+
26  bool(const MediaInfo& media_info, uint32_t* container_id));
+
27  MOCK_METHOD2(NotifySampleDuration,
+
28  bool(uint32_t container_id, uint32_t sample_duration));
+
29  MOCK_METHOD4(NotifyNewSegment,
+
30  bool(uint32_t container_id,
+
31  uint64_t start_time,
+
32  uint64_t duration,
+
33  uint64_t size));
+
34  MOCK_METHOD2(NotifyCueEvent, bool(uint32_t container_id, uint64_t timestamp));
+
35  MOCK_METHOD4(NotifyEncryptionUpdate,
+
36  bool(uint32_t container_id,
+
37  const std::string& drm_uuid,
+
38  const std::vector<uint8_t>& new_key_id,
+
39  const std::vector<uint8_t>& new_pssh));
+
40  MOCK_METHOD2(NotifyMediaInfoUpdate,
+
41  bool(uint32_t container_id, const MediaInfo& media_info));
+
42  MOCK_METHOD0(Flush, bool());
+
43 };
+
44 
+
45 } // namespace shaka
+
46 
+
47 #endif // MPD_BASE_MOCK_MPD_NOTIFIER_H_
+ + +
virtual bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0
+
virtual bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0
+
virtual bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0
+
virtual bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0
+
virtual bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0
+
virtual bool Init()=0
+
virtual bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0
+
virtual bool Flush()=0
+
All the methods that are virtual are virtual for mocking.
+
Defines Mpd Options.
Definition: mpd_options.h:25
diff --git a/docs/d0/d32/mp2t__common_8h_source.html b/docs/d0/d32/mp2t__common_8h_source.html index 0a50eced8d..6caea03e90 100644 --- a/docs/d0/d32/mp2t__common_8h_source.html +++ b/docs/d0/d32/mp2t__common_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/mp2t_common.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mp2t_common.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_MP2T_COMMON_H_
6 #define PACKAGER_MEDIA_FORMATS_MP2T_MP2T_COMMON_H_
7 
8 #define LOG_LEVEL_TS 5
9 #define LOG_LEVEL_PES 4
10 #define LOG_LEVEL_ES 3
11 
12 #define RCHECK(x) \
13  do { \
14  if (!(x)) { \
15  DLOG(WARNING) << "Failure while parsing Mpeg2TS: " << #x; \
16  return false; \
17  } \
18  } while (0)
19 
20 #endif
21 
22 namespace shaka {
23 namespace media {
24 
25 const uint32_t kMpeg2Timescale = 90000;
26 
27 } // namespace media
28 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_MP2T_COMMON_H_
+
6 #define PACKAGER_MEDIA_FORMATS_MP2T_MP2T_COMMON_H_
+
7 
+
8 #define LOG_LEVEL_TS 5
+
9 #define LOG_LEVEL_PES 4
+
10 #define LOG_LEVEL_ES 3
+
11 
+
12 #define RCHECK(x) \
+
13  do { \
+
14  if (!(x)) { \
+
15  DLOG(WARNING) << "Failure while parsing Mpeg2TS: " << #x; \
+
16  return false; \
+
17  } \
+
18  } while (0)
+
19 
+
20 #endif
+
21 
+
22 namespace shaka {
+
23 namespace media {
+
24 
+
25 const uint32_t kMpeg2Timescale = 90000;
+
26 
+
27 } // namespace media
+
28 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d33/classshaka_1_1MockRepresentation.html b/docs/d0/d33/classshaka_1_1MockRepresentation.html index a91159b25f..7615c53647 100644 --- a/docs/d0/d33/classshaka_1_1MockRepresentation.html +++ b/docs/d0/d33/classshaka_1_1MockRepresentation.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MockRepresentation Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::Representation - -
+ + @@ -112,13 +115,13 @@ Public Member Functions - - + + - + @@ -131,9 +134,9 @@ void  - @@ -152,9 +155,7 @@ Additional Inherited Members diff --git a/docs/d0/d35/es__descriptor_8cc_source.html b/docs/d0/d35/es__descriptor_8cc_source.html index de16f9458f..afcd3085b3 100644 --- a/docs/d0/d35/es__descriptor_8cc_source.html +++ b/docs/d0/d35/es__descriptor_8cc_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/codecs/es_descriptor.cc Source File @@ -29,18 +29,21 @@

Public Member Functions

 
virtual const MediaInfo & GetMediaInfo () const
 
xml::scoped_xml_ptr< xmlNode > GetXml ()
 
base::Optional< xml::XmlNodeGetXml ()
 
void SuppressOnce (SuppressFlag flag)
 
void SetPresentationTimeOffset (double presentation_time_offset)
 Set in SegmentBase / SegmentTemplate.
 Set @presentationTimeOffset in SegmentBase / SegmentTemplate.
 
bool GetStartAndEndTimestamps (double *start_timestamp_seconds, double *end_timestamp_seconds) const
 
set_media_info (c

Additional Inherited Members

- Public Types inherited from shaka::Representation
enum  SuppressFlag { kSuppressWidth = 1, -kSuppressHeight = 2, -kSuppressFrameRate = 4 +
enum  SuppressFlag { kSuppressWidth = 1 +, kSuppressHeight = 2 +, kSuppressFrameRate = 4 }
 
- Protected Member Functions inherited from shaka::Representation
- + +/* @license-end */
es_descriptor.cc
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/codecs/es_descriptor.h"
6 
7 #include "packager/media/base/bit_reader.h"
8 #include "packager/media/base/buffer_writer.h"
9 #include "packager/media/base/rcheck.h"
10 
11 namespace shaka {
12 namespace media {
13 namespace {
14 
15 // ISO/IEC 14496-1:2004 Section 7.2.6.6 Table 6: StreamType values.
16 enum StreamType {
17  kForbiddenStreamType = 0x00,
18  kObjectDescriptorStreamType = 0x01,
19  kClockReferenceStreamType = 0x02,
20  kSceneDescriptionStreamType = 0x03,
21  kVisualStreamType = 0x04,
22  kAudioStreamType = 0x05,
23  kMPEG7StreamType = 0x06,
24  kIPMPStreamType = 0x07,
25  kObjectContentInfoStreamType = 0x08,
26  kMPEGJStreamType = 0x09,
27  kInteractionStream = 0x0A,
28  kIPMPToolStreamType = 0x0B,
29 };
30 
31 // ISO/IEC 14496-1:2004 Section 7.3.2.3 Table 12: ISO SL Config Descriptor.
32 enum SLPredefinedTags {
33  kSLPredefinedNull = 0x01,
34  kSLPredefinedMP4 = 0x02,
35 };
36 
37 // The elementary stream size is specific by up to 4 bytes.
38 // The MSB of a byte indicates if there are more bytes for the size.
39 bool ReadDescriptorSize(BitReader* reader, size_t* size) {
40  uint8_t msb;
41  uint8_t byte;
42 
43  *size = 0;
44 
45  for (size_t i = 0; i < 4; ++i) {
46  RCHECK(reader->ReadBits(1, &msb));
47  RCHECK(reader->ReadBits(7, &byte));
48  *size = (*size << 7) + byte;
49 
50  if (msb == 0)
51  break;
52  }
53 
54  return true;
55 }
56 
57 void WriteDescriptorSize(size_t size, BufferWriter* writer) {
58  std::vector<uint8_t> size_bytes;
59  while (size > 0) {
60  uint8_t byte = (size & 0x7F);
61  size >>= 7;
62  if (!size_bytes.empty())
63  byte |= 0x80;
64  size_bytes.push_back(byte);
65  }
66  for (auto iter = size_bytes.rbegin(); iter != size_bytes.rend(); iter++)
67  writer->AppendInt(*iter);
68 }
69 
70 size_t CountDescriptorSize(size_t size) {
71  size_t num_bytes = 0;
72  while (size > 0) {
73  num_bytes++;
74  size >>= 7;
75  }
76  return num_bytes;
77 }
78 
79 } // namespace
80 
81 bool BaseDescriptor::Parse(const std::vector<uint8_t>& data) {
82  BitReader reader(data.data(), data.size());
83  return Read(&reader);
84 }
85 
87  uint8_t tag;
88  RCHECK(reader->ReadBits(8, &tag));
89  if (tag != static_cast<uint8_t>(tag_)) {
90  LOG(ERROR) << "Expecting tag " << static_cast<int>(tag_) << ", but seeing "
91  << static_cast<int>(tag);
92  return false;
93  }
94  RCHECK(ReadDescriptorSize(reader, &data_size_));
95  return ReadData(reader);
96 }
97 
99  // Compute and update descriptor size.
100  size_t size = ComputeSize();
101  size_t buffer_size_before_write = writer->Size();
102 
103  WriteInternal(writer);
104 
105  DCHECK_EQ(size, writer->Size() - buffer_size_before_write);
106 }
107 
109  data_size_ = ComputeDataSize();
110  return 1 + CountDescriptorSize(data_size_) + data_size_;
111 }
112 
114  writer->AppendInt(static_cast<uint8_t>(tag_));
115  WriteDescriptorSize(data_size_, writer);
116 }
117 
118 bool DecoderSpecificInfoDescriptor::ReadData(BitReader* reader) {
119  data_.resize(data_size());
120  for (uint8_t& data_entry : data_)
121  RCHECK(reader->ReadBits(8, &data_entry));
122  return true;
123 }
124 
125 void DecoderSpecificInfoDescriptor::WriteInternal(BufferWriter* writer) {
126  WriteHeader(writer);
127  writer->AppendVector(data_);
128 }
129 
130 size_t DecoderSpecificInfoDescriptor::ComputeDataSize() {
131  return data_.size();
132 }
133 
134 bool DecoderConfigDescriptor::ReadData(BitReader* reader) {
135  const size_t start_pos = reader->bit_position();
136  RCHECK(reader->ReadBits(8, &object_type_));
137 
138  int stream_type;
139  RCHECK(reader->ReadBits(6, &stream_type));
140  if (stream_type != kAudioStreamType) {
141  LOG(ERROR) << "Seeing non audio stream type " << stream_type;
142  return false;
143  }
144 
145  RCHECK(reader->SkipBits(2)); // Skip |upStream| and |reserved|.
146  RCHECK(reader->ReadBits(24, &buffer_size_db_));
147  RCHECK(reader->ReadBits(32, &max_bitrate_));
148  RCHECK(reader->ReadBits(32, &avg_bitrate_));
149  const size_t fields_bits = reader->bit_position() - start_pos;
150 
151  const size_t kBitsInByte = 8;
152  const bool has_child_tags = data_size() * kBitsInByte > fields_bits;
153  decoder_specific_info_descriptor_ = DecoderSpecificInfoDescriptor();
154  if (has_child_tags)
155  RCHECK(decoder_specific_info_descriptor_.Read(reader));
156 
157  return true;
158 }
159 
160 void DecoderConfigDescriptor::WriteInternal(BufferWriter* writer) {
161  WriteHeader(writer);
162 
163  writer->AppendInt(static_cast<uint8_t>(object_type_));
164  // 6 bit stream type. The last bit is reserved with 1.
165  const uint8_t stream_type = (kAudioStreamType << 2) | 1;
166  writer->AppendInt(stream_type);
167  writer->AppendNBytes(buffer_size_db_, 3);
168  writer->AppendInt(max_bitrate_);
169  writer->AppendInt(avg_bitrate_);
170  decoder_specific_info_descriptor_.Write(writer);
171 }
172 
173 size_t DecoderConfigDescriptor::ComputeDataSize() {
174  // object_type (1 byte), stream_type (1 byte), decoding_buffer_size (3 bytes),
175  // max_bitrate (4 bytes), avg_bitrate (4 bytes).
176  const size_t data_size_without_children = 1 + 1 + 3 + 4 + 4;
177  return data_size_without_children +
178  decoder_specific_info_descriptor_.ComputeSize();
179 }
180 
181 bool SLConfigDescriptor::ReadData(BitReader* reader) {
182  return true;
183 }
184 
185 void SLConfigDescriptor::WriteInternal(BufferWriter* writer) {
186  WriteHeader(writer);
187  writer->AppendInt(static_cast<uint8_t>(kSLPredefinedMP4));
188 }
189 
190 size_t SLConfigDescriptor::ComputeDataSize() {
191  return 1;
192 }
193 
194 bool ESDescriptor::ReadData(BitReader* reader) {
195  bool stream_dependency_flag;
196  bool url_flag;
197  bool ocr_stream_flag;
198  RCHECK(reader->ReadBits(16, &esid_));
199  RCHECK(reader->ReadBits(1, &stream_dependency_flag));
200  RCHECK(reader->ReadBits(1, &url_flag));
201  RCHECK(!url_flag); // We don't support url flag
202  RCHECK(reader->ReadBits(1, &ocr_stream_flag));
203  RCHECK(reader->SkipBits(5)); // streamPriority
204 
205  if (stream_dependency_flag)
206  RCHECK(reader->SkipBits(16)); // dependsOn_ES_ID
207  if (ocr_stream_flag)
208  RCHECK(reader->SkipBits(16)); // OCR_ES_Id
209 
210  return decoder_config_descriptor_.Read(reader);
211  // Skip the parsing of |sl_config_descriptor_| intentionally as we do not care
212  // about the data.
213 }
214 
215 void ESDescriptor::WriteInternal(BufferWriter* writer) {
216  WriteHeader(writer);
217 
218  writer->AppendInt(esid_);
219  const uint8_t kNoEsFlags = 0;
220  writer->AppendInt(kNoEsFlags);
221 
222  decoder_config_descriptor_.Write(writer);
223  sl_config_descriptor_.Write(writer);
224 }
225 
226 size_t ESDescriptor::ComputeDataSize() {
227  // esid (2 bytes), es_flags (1 byte).
228  const size_t data_size_without_children = 2 + 1;
229  return data_size_without_children + decoder_config_descriptor_.ComputeSize() +
230  sl_config_descriptor_.ComputeSize();
231 }
232 
233 } // namespace media
234 } // namespace shaka
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:35
-
A class to read bit streams.
Definition: bit_reader.h:17
-
bool Read(BitReader *reader)
- -
All the methods that are virtual are virtual for mocking.
- -
void WriteHeader(BufferWriter *writer)
Write descriptor header.
-
size_t bit_position() const
Definition: bit_reader.h:94
- -
void AppendNBytes(uint64_t v, size_t num_bytes)
-
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
-
void Write(BufferWriter *writer)
- - -
bool Parse(const std::vector< uint8_t > &data)
+
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/codecs/es_descriptor.h"
+
6 
+
7 #include "packager/media/base/bit_reader.h"
+
8 #include "packager/media/base/buffer_writer.h"
+
9 #include "packager/media/base/rcheck.h"
+
10 
+
11 namespace shaka {
+
12 namespace media {
+
13 namespace {
+
14 
+
15 // ISO/IEC 14496-1:2004 Section 7.2.6.6 Table 6: StreamType values.
+
16 enum StreamType {
+
17  kForbiddenStreamType = 0x00,
+
18  kObjectDescriptorStreamType = 0x01,
+
19  kClockReferenceStreamType = 0x02,
+
20  kSceneDescriptionStreamType = 0x03,
+
21  kVisualStreamType = 0x04,
+
22  kAudioStreamType = 0x05,
+
23  kMPEG7StreamType = 0x06,
+
24  kIPMPStreamType = 0x07,
+
25  kObjectContentInfoStreamType = 0x08,
+
26  kMPEGJStreamType = 0x09,
+
27  kInteractionStream = 0x0A,
+
28  kIPMPToolStreamType = 0x0B,
+
29 };
+
30 
+
31 // ISO/IEC 14496-1:2004 Section 7.3.2.3 Table 12: ISO SL Config Descriptor.
+
32 enum SLPredefinedTags {
+
33  kSLPredefinedNull = 0x01,
+
34  kSLPredefinedMP4 = 0x02,
+
35 };
+
36 
+
37 // The elementary stream size is specific by up to 4 bytes.
+
38 // The MSB of a byte indicates if there are more bytes for the size.
+
39 bool ReadDescriptorSize(BitReader* reader, size_t* size) {
+
40  uint8_t msb;
+
41  uint8_t byte;
+
42 
+
43  *size = 0;
+
44 
+
45  for (size_t i = 0; i < 4; ++i) {
+
46  RCHECK(reader->ReadBits(1, &msb));
+
47  RCHECK(reader->ReadBits(7, &byte));
+
48  *size = (*size << 7) + byte;
+
49 
+
50  if (msb == 0)
+
51  break;
+
52  }
+
53 
+
54  return true;
+
55 }
+
56 
+
57 void WriteDescriptorSize(size_t size, BufferWriter* writer) {
+
58  std::vector<uint8_t> size_bytes;
+
59  while (size > 0) {
+
60  uint8_t byte = (size & 0x7F);
+
61  size >>= 7;
+
62  if (!size_bytes.empty())
+
63  byte |= 0x80;
+
64  size_bytes.push_back(byte);
+
65  }
+
66  for (auto iter = size_bytes.rbegin(); iter != size_bytes.rend(); iter++)
+
67  writer->AppendInt(*iter);
+
68 }
+
69 
+
70 size_t CountDescriptorSize(size_t size) {
+
71  size_t num_bytes = 0;
+
72  while (size > 0) {
+
73  num_bytes++;
+
74  size >>= 7;
+
75  }
+
76  return num_bytes;
+
77 }
+
78 
+
79 } // namespace
+
80 
+
81 bool BaseDescriptor::Parse(const std::vector<uint8_t>& data) {
+
82  BitReader reader(data.data(), data.size());
+
83  return Read(&reader);
+
84 }
+
85 
+ +
87  uint8_t tag;
+
88  RCHECK(reader->ReadBits(8, &tag));
+
89  if (tag != static_cast<uint8_t>(tag_)) {
+
90  LOG(ERROR) << "Expecting tag " << static_cast<int>(tag_) << ", but seeing "
+
91  << static_cast<int>(tag);
+
92  return false;
+
93  }
+
94  RCHECK(ReadDescriptorSize(reader, &data_size_));
+
95  return ReadData(reader);
+
96 }
+
97 
+ +
99  // Compute and update descriptor size.
+
100  size_t size = ComputeSize();
+
101  size_t buffer_size_before_write = writer->Size();
+
102 
+
103  WriteInternal(writer);
+
104 
+
105  DCHECK_EQ(size, writer->Size() - buffer_size_before_write);
+
106 }
+
107 
+ +
109  data_size_ = ComputeDataSize();
+
110  return 1 + CountDescriptorSize(data_size_) + data_size_;
+
111 }
+
112 
+ +
114  writer->AppendInt(static_cast<uint8_t>(tag_));
+
115  WriteDescriptorSize(data_size_, writer);
+
116 }
+
117 
+
118 bool DecoderSpecificInfoDescriptor::ReadData(BitReader* reader) {
+
119  data_.resize(data_size());
+
120  for (uint8_t& data_entry : data_)
+
121  RCHECK(reader->ReadBits(8, &data_entry));
+
122  return true;
+
123 }
+
124 
+
125 void DecoderSpecificInfoDescriptor::WriteInternal(BufferWriter* writer) {
+
126  WriteHeader(writer);
+
127  writer->AppendVector(data_);
+
128 }
+
129 
+
130 size_t DecoderSpecificInfoDescriptor::ComputeDataSize() {
+
131  return data_.size();
+
132 }
+
133 
+
134 bool DecoderConfigDescriptor::ReadData(BitReader* reader) {
+
135  const size_t start_pos = reader->bit_position();
+
136  RCHECK(reader->ReadBits(8, &object_type_));
+
137 
+
138  int stream_type;
+
139  RCHECK(reader->ReadBits(6, &stream_type));
+
140  if (stream_type != kAudioStreamType) {
+
141  LOG(ERROR) << "Seeing non audio stream type " << stream_type;
+
142  return false;
+
143  }
+
144 
+
145  RCHECK(reader->SkipBits(2)); // Skip |upStream| and |reserved|.
+
146  RCHECK(reader->ReadBits(24, &buffer_size_db_));
+
147  RCHECK(reader->ReadBits(32, &max_bitrate_));
+
148  RCHECK(reader->ReadBits(32, &avg_bitrate_));
+
149  const size_t fields_bits = reader->bit_position() - start_pos;
+
150 
+
151  const size_t kBitsInByte = 8;
+
152  const bool has_child_tags = data_size() * kBitsInByte > fields_bits;
+
153  decoder_specific_info_descriptor_ = DecoderSpecificInfoDescriptor();
+
154  if (has_child_tags)
+
155  RCHECK(decoder_specific_info_descriptor_.Read(reader));
+
156 
+
157  return true;
+
158 }
+
159 
+
160 void DecoderConfigDescriptor::WriteInternal(BufferWriter* writer) {
+
161  WriteHeader(writer);
+
162 
+
163  writer->AppendInt(static_cast<uint8_t>(object_type_));
+
164  // 6 bit stream type. The last bit is reserved with 1.
+
165  const uint8_t stream_type = (kAudioStreamType << 2) | 1;
+
166  writer->AppendInt(stream_type);
+
167  writer->AppendNBytes(buffer_size_db_, 3);
+
168  writer->AppendInt(max_bitrate_);
+
169  writer->AppendInt(avg_bitrate_);
+
170 
+
171  if (!decoder_specific_info_descriptor_.data().empty())
+
172  decoder_specific_info_descriptor_.Write(writer);
+
173 }
+
174 
+
175 size_t DecoderConfigDescriptor::ComputeDataSize() {
+
176  // object_type (1 byte), stream_type (1 byte), decoding_buffer_size (3 bytes),
+
177  // max_bitrate (4 bytes), avg_bitrate (4 bytes).
+
178  const size_t data_size_without_children = 1 + 1 + 3 + 4 + 4;
+
179  if (decoder_specific_info_descriptor_.data().empty())
+
180  return data_size_without_children;
+
181  return data_size_without_children +
+
182  decoder_specific_info_descriptor_.ComputeSize();
+
183 }
+
184 
+
185 bool SLConfigDescriptor::ReadData(BitReader* reader) {
+
186  return true;
+
187 }
+
188 
+
189 void SLConfigDescriptor::WriteInternal(BufferWriter* writer) {
+
190  WriteHeader(writer);
+
191  writer->AppendInt(static_cast<uint8_t>(kSLPredefinedMP4));
+
192 }
+
193 
+
194 size_t SLConfigDescriptor::ComputeDataSize() {
+
195  return 1;
+
196 }
+
197 
+
198 bool ESDescriptor::ReadData(BitReader* reader) {
+
199  bool stream_dependency_flag;
+
200  bool url_flag;
+
201  bool ocr_stream_flag;
+
202  RCHECK(reader->ReadBits(16, &esid_));
+
203  RCHECK(reader->ReadBits(1, &stream_dependency_flag));
+
204  RCHECK(reader->ReadBits(1, &url_flag));
+
205  RCHECK(!url_flag); // We don't support url flag
+
206  RCHECK(reader->ReadBits(1, &ocr_stream_flag));
+
207  RCHECK(reader->SkipBits(5)); // streamPriority
+
208 
+
209  if (stream_dependency_flag)
+
210  RCHECK(reader->SkipBits(16)); // dependsOn_ES_ID
+
211  if (ocr_stream_flag)
+
212  RCHECK(reader->SkipBits(16)); // OCR_ES_Id
+
213 
+
214  return decoder_config_descriptor_.Read(reader);
+
215  // Skip the parsing of |sl_config_descriptor_| intentionally as we do not care
+
216  // about the data.
+
217 }
+
218 
+
219 void ESDescriptor::WriteInternal(BufferWriter* writer) {
+
220  WriteHeader(writer);
+
221 
+
222  // According to ISO/IEC 14496-14:2018 Section 4.1.2,
+
223  // ES_ID is set to 0 when stored
+
224  const uint16_t kEsid = 0;
+
225  writer->AppendInt(kEsid);
+
226  const uint8_t kNoEsFlags = 0;
+
227  writer->AppendInt(kNoEsFlags);
+
228 
+
229  decoder_config_descriptor_.Write(writer);
+
230  sl_config_descriptor_.Write(writer);
+
231 }
+
232 
+
233 size_t ESDescriptor::ComputeDataSize() {
+
234  // esid (2 bytes), es_flags (1 byte).
+
235  const size_t data_size_without_children = 2 + 1;
+
236  return data_size_without_children + decoder_config_descriptor_.ComputeSize() +
+
237  sl_config_descriptor_.ComputeSize();
+
238 }
+
239 
+
240 } // namespace media
+
241 } // namespace shaka
+ +
bool Parse(const std::vector< uint8_t > &data)
+
void WriteHeader(BufferWriter *writer)
Write descriptor header.
+
bool Read(BitReader *reader)
+
void Write(BufferWriter *writer)
+ +
A class to read bit streams.
Definition: bit_reader.h:17
+
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:35
+ + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d37/unionshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes_1_1OneOf.html b/docs/d0/d37/unionshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes_1_1OneOf.html index 03afab023d..17c124e332 100644 --- a/docs/d0/d37/unionshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes_1_1OneOf.html +++ b/docs/d0/d37/unionshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes_1_1OneOf.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::EncryptionParams::EncryptedStreamAttributes::OneOf Union Reference @@ -29,18 +29,21 @@
- + +/* @license-end */

Public Attributes

- + struct {    int   width = 0 @@ -86,28 +89,26 @@ struct {    int   bit_depth = 0   -} video -  - +} video +  + struct {    int   number_of_channels = 0   -} audio -  +} audio

Detailed Description

-

Definition at line 153 of file crypto_params.h.

+

Definition at line 195 of file crypto_params.h.


The documentation for this union was generated from the following file:
diff --git a/docs/d0/d39/video__util_8cc_source.html b/docs/d0/d39/video__util_8cc_source.html index 5cc28d9287..13c711834b 100644 --- a/docs/d0/d39/video__util_8cc_source.html +++ b/docs/d0/d39/video__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/video_util.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
video_util.cc
-
1 // Copyright 2019 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/video_util.h"
8 
9 #include <limits>
10 
11 namespace {
12 
13 uint64_t CalculateGCD(uint64_t a, uint64_t b) {
14  while (b != 0) {
15  uint64_t temp = a;
16  a = b;
17  b = temp % b;
18  }
19  return a;
20 }
21 
22 void ReducePixelWidthHeight(uint64_t* pixel_width, uint64_t* pixel_height) {
23  if (*pixel_width == 0 || *pixel_height == 0)
24  return;
25  const uint64_t kMaxUint32 = std::numeric_limits<uint32_t>::max();
26  while (true) {
27  uint64_t gcd = CalculateGCD(*pixel_width, *pixel_height);
28  *pixel_width /= gcd;
29  *pixel_height /= gcd;
30  // Both width and height needs to be 32 bit or less.
31  if (*pixel_width <= kMaxUint32 && *pixel_height <= kMaxUint32)
32  break;
33  *pixel_width >>= 1;
34  *pixel_height >>= 1;
35  }
36 }
37 
38 } // namespace
39 
40 namespace shaka {
41 namespace media {
42 
43 void DerivePixelWidthHeight(uint32_t frame_width,
44  uint32_t frame_height,
45  uint32_t display_width,
46  uint32_t display_height,
47  uint32_t* pixel_width,
48  uint32_t* pixel_height) {
49  // DAR = PAR * FAR => PAR = DAR / FAR.
50  // Thus:
51  // pixel_width display_width frame_width
52  // ----------- = ------------- / -----------
53  // pixel_height display_height frame_height
54  // So:
55  // pixel_width display_width x frame_height
56  // ----------- = ------------------------------
57  // pixel_height display_height x frame_width
58  uint64_t pixel_width_unreduced =
59  static_cast<uint64_t>(display_width) * frame_height;
60  uint64_t pixel_height_unreduced =
61  static_cast<uint64_t>(display_height) * frame_width;
62  ReducePixelWidthHeight(&pixel_width_unreduced, &pixel_height_unreduced);
63  *pixel_width = pixel_width_unreduced;
64  *pixel_height = pixel_height_unreduced;
65 }
66 
67 } // namespace media
68 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2019 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/video_util.h"
+
8 
+
9 #include <limits>
+
10 
+
11 namespace {
+
12 
+
13 uint64_t CalculateGCD(uint64_t a, uint64_t b) {
+
14  while (b != 0) {
+
15  uint64_t temp = a;
+
16  a = b;
+
17  b = temp % b;
+
18  }
+
19  return a;
+
20 }
+
21 
+
22 void ReducePixelWidthHeight(uint64_t* pixel_width, uint64_t* pixel_height) {
+
23  if (*pixel_width == 0 || *pixel_height == 0)
+
24  return;
+
25  const uint64_t kMaxUint32 = std::numeric_limits<uint32_t>::max();
+
26  while (true) {
+
27  uint64_t gcd = CalculateGCD(*pixel_width, *pixel_height);
+
28  *pixel_width /= gcd;
+
29  *pixel_height /= gcd;
+
30  // Both width and height needs to be 32 bit or less.
+
31  if (*pixel_width <= kMaxUint32 && *pixel_height <= kMaxUint32)
+
32  break;
+
33  *pixel_width >>= 1;
+
34  *pixel_height >>= 1;
+
35  }
+
36 }
+
37 
+
38 } // namespace
+
39 
+
40 namespace shaka {
+
41 namespace media {
+
42 
+
43 void DerivePixelWidthHeight(uint32_t frame_width,
+
44  uint32_t frame_height,
+
45  uint32_t display_width,
+
46  uint32_t display_height,
+
47  uint32_t* pixel_width,
+
48  uint32_t* pixel_height) {
+
49  // DAR = PAR * FAR => PAR = DAR / FAR.
+
50  // Thus:
+
51  // pixel_width display_width frame_width
+
52  // ----------- = ------------- / -----------
+
53  // pixel_height display_height frame_height
+
54  // So:
+
55  // pixel_width display_width x frame_height
+
56  // ----------- = ------------------------------
+
57  // pixel_height display_height x frame_width
+
58  uint64_t pixel_width_unreduced =
+
59  static_cast<uint64_t>(display_width) * frame_height;
+
60  uint64_t pixel_height_unreduced =
+
61  static_cast<uint64_t>(display_height) * frame_width;
+
62  ReducePixelWidthHeight(&pixel_width_unreduced, &pixel_height_unreduced);
+
63  *pixel_width = pixel_width_unreduced;
+
64  *pixel_height = pixel_height_unreduced;
+
65 }
+
66 
+
67 } // namespace media
+
68 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d3a/hls__notify__muxer__listener_8cc_source.html b/docs/d0/d3a/hls__notify__muxer__listener_8cc_source.html index 911065cf9b..2980b09f81 100644 --- a/docs/d0/d3a/hls__notify__muxer__listener_8cc_source.html +++ b/docs/d0/d3a/hls__notify__muxer__listener_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/hls_notify_muxer_listener.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
hls_notify_muxer_listener.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/event/hls_notify_muxer_listener.h"
8 
9 #include <memory>
10 #include "packager/base/logging.h"
11 #include "packager/hls/base/hls_notifier.h"
12 #include "packager/media/base/muxer_options.h"
13 #include "packager/media/base/protection_system_specific_info.h"
14 #include "packager/media/event/muxer_listener_internal.h"
15 
16 namespace shaka {
17 namespace media {
18 
20  const std::string& playlist_name,
21  bool iframes_only,
22  const std::string& ext_x_media_name,
23  const std::string& ext_x_media_group_id,
24  const std::vector<std::string>& characteristics,
25  hls::HlsNotifier* hls_notifier)
26  : playlist_name_(playlist_name),
27  iframes_only_(iframes_only),
28  ext_x_media_name_(ext_x_media_name),
29  ext_x_media_group_id_(ext_x_media_group_id),
30  characteristics_(characteristics),
31  hls_notifier_(hls_notifier) {
32  DCHECK(hls_notifier);
33 }
34 
35 HlsNotifyMuxerListener::~HlsNotifyMuxerListener() {}
36 
37 // These methods work together to notify that the media is encrypted.
38 // If OnEncryptionInfoReady() is called before the media has been started, then
39 // the information is stored and handled when OnEncryptionStart() is called.
40 // If OnEncryptionStart() is called before the media has been started then
41 // OnMediaStart() is responsible for notifying that the segments are encrypted
42 // right away i.e. call OnEncryptionStart().
44  bool is_initial_encryption_info,
45  FourCC protection_scheme,
46  const std::vector<uint8_t>& key_id,
47  const std::vector<uint8_t>& iv,
48  const std::vector<ProtectionSystemSpecificInfo>& key_system_infos) {
49  if (!stream_id_) {
50  next_key_id_ = key_id;
51  next_iv_ = iv;
52  next_key_system_infos_ = key_system_infos;
53  protection_scheme_ = protection_scheme;
54  return;
55  }
56  for (const ProtectionSystemSpecificInfo& info : key_system_infos) {
57  const bool result = hls_notifier_->NotifyEncryptionUpdate(
58  stream_id_.value(), key_id, info.system_id, iv, info.psshs);
59  LOG_IF(WARNING, !result) << "Failed to add encryption info.";
60  }
61 }
62 
64  if (!stream_id_) {
65  must_notify_encryption_start_ = true;
66  return;
67  }
68  if (next_key_id_.empty()) {
69  DCHECK(next_iv_.empty());
70  DCHECK(next_key_system_infos_.empty());
71  return;
72  }
73 
74  for (const ProtectionSystemSpecificInfo& info : next_key_system_infos_) {
75  const bool result = hls_notifier_->NotifyEncryptionUpdate(
76  stream_id_.value(), next_key_id_, info.system_id, next_iv_, info.psshs);
77  LOG_IF(WARNING, !result) << "Failed to add encryption info";
78  }
79  next_key_id_.clear();
80  next_iv_.clear();
81  next_key_system_infos_.clear();
82  must_notify_encryption_start_ = false;
83 }
84 
86  const StreamInfo& stream_info,
87  uint32_t time_scale,
88  ContainerType container_type) {
89  std::unique_ptr<MediaInfo> media_info(new MediaInfo);
90  if (!internal::GenerateMediaInfo(muxer_options, stream_info, time_scale,
91  container_type, media_info.get())) {
92  LOG(ERROR) << "Failed to generate MediaInfo from input.";
93  return;
94  }
95  if (!characteristics_.empty()) {
96  for (const std::string& characteristic : characteristics_)
97  media_info->add_hls_characteristics(characteristic);
98  }
99  if (protection_scheme_ != FOURCC_NULL) {
100  internal::SetContentProtectionFields(protection_scheme_, next_key_id_,
101  next_key_system_infos_,
102  media_info.get());
103  }
104 
105  // The content may be splitted into multiple files, but their MediaInfo
106  // should be compatible.
107  if (media_info_ &&
108  !internal::IsMediaInfoCompatible(*media_info, *media_info_)) {
109  LOG(WARNING) << "Incompatible MediaInfo " << media_info->ShortDebugString()
110  << " vs " << media_info_->ShortDebugString()
111  << ". The result manifest may not be playable.";
112  }
113  media_info_ = std::move(media_info);
114 
115  if (!media_info_->has_segment_template()) {
116  return;
117  }
118 
119  if (!NotifyNewStream())
120  return;
121  DCHECK(stream_id_);
122 
123  if (must_notify_encryption_start_) {
125  }
126 }
127 
128 void HlsNotifyMuxerListener::OnSampleDurationReady(uint32_t sample_duration) {
129  if (stream_id_) {
130  // This happens in live mode.
131  hls_notifier_->NotifySampleDuration(stream_id_.value(), sample_duration);
132  return;
133  }
134 
135  if (!media_info_) {
136  LOG(WARNING) << "Got sample duration " << sample_duration
137  << " but no media was specified.";
138  return;
139  }
140  if (!media_info_->has_video_info()) {
141  // If non video, don't worry about it (at the moment).
142  return;
143  }
144 
145  media_info_->mutable_video_info()->set_frame_duration(sample_duration);
146 }
147 
149  float duration_seconds) {
150  DCHECK(media_info_);
151  // TODO(kqyang): Should we just Flush here to avoid calling Flush explicitly?
152  // Don't flush the notifier here. Flushing here would write all the playlists
153  // before all Media Playlists are read. Which could cause problems
154  // setting the correct EXT-X-TARGETDURATION.
155  if (media_info_->has_segment_template()) {
156  return;
157  }
158  if (media_ranges.init_range) {
159  shaka::Range* init_range = media_info_->mutable_init_range();
160  init_range->set_begin(media_ranges.init_range.value().start);
161  init_range->set_end(media_ranges.init_range.value().end);
162  }
163  if (media_ranges.index_range) {
164  shaka::Range* index_range = media_info_->mutable_index_range();
165  index_range->set_begin(media_ranges.index_range.value().start);
166  index_range->set_end(media_ranges.index_range.value().end);
167  }
168 
169  if (!stream_id_) {
170  if (!NotifyNewStream())
171  return;
172  DCHECK(stream_id_);
173  } else {
174  // HLS is not interested in MediaInfo update.
175  }
176 
177  // TODO(rkuroiwa); Keep track of which (sub)segments are encrypted so that the
178  // notification is sent right before the enecrypted (sub)segments.
179  if (must_notify_encryption_start_) {
181  }
182 
183  if (!media_ranges.subsegment_ranges.empty()) {
184  const std::vector<Range>& subsegment_ranges =
185  media_ranges.subsegment_ranges;
186  const size_t num_subsegments = subsegment_ranges.size();
187  size_t subsegment_index = 0;
188  for (const auto& event_info : event_info_) {
189  switch (event_info.type) {
190  case EventInfoType::kSegment:
191  if (subsegment_index < num_subsegments) {
192  const Range& range = subsegment_ranges[subsegment_index];
193  hls_notifier_->NotifyNewSegment(
194  stream_id_.value(), media_info_->media_file_name(),
195  event_info.segment_info.start_time,
196  event_info.segment_info.duration, range.start,
197  range.end + 1 - range.start);
198  }
199  ++subsegment_index;
200  break;
201  case EventInfoType::kKeyFrame:
202  if (subsegment_index < num_subsegments) {
203  const uint64_t segment_start_offset =
204  subsegment_ranges[subsegment_index].start;
205  hls_notifier_->NotifyKeyFrame(
206  stream_id_.value(), event_info.key_frame.timestamp,
207  segment_start_offset +
208  event_info.key_frame.start_offset_in_segment,
209  event_info.key_frame.size);
210  }
211  break;
212  case EventInfoType::kCue:
213  hls_notifier_->NotifyCueEvent(stream_id_.value(),
214  event_info.cue_event_info.timestamp);
215  break;
216  }
217  }
218  if (subsegment_index != num_subsegments) {
219  LOG(WARNING) << "Number of subsegment ranges (" << num_subsegments
220  << ") does not match the number of subsegments notified to "
221  "OnNewSegment() ("
222  << event_info_.size() << ").";
223  }
224  }
225  event_info_.clear();
226 }
227 
228 void HlsNotifyMuxerListener::OnNewSegment(const std::string& file_name,
229  int64_t start_time,
230  int64_t duration,
231  uint64_t segment_file_size) {
232  if (!media_info_->has_segment_template()) {
233  EventInfo event_info;
234  event_info.type = EventInfoType::kSegment;
235  event_info.segment_info = {start_time, duration, segment_file_size};
236  event_info_.push_back(event_info);
237  } else {
238  // For multisegment, it always starts from the beginning of the file.
239  const size_t kStartingByteOffset = 0u;
240  const bool result = hls_notifier_->NotifyNewSegment(
241  stream_id_.value(), file_name, start_time, duration,
242  kStartingByteOffset, segment_file_size);
243  LOG_IF(WARNING, !result) << "Failed to add new segment.";
244  }
245 }
246 
247 void HlsNotifyMuxerListener::OnKeyFrame(int64_t timestamp,
248  uint64_t start_byte_offset,
249  uint64_t size) {
250  if (!iframes_only_)
251  return;
252  if (!media_info_->has_segment_template()) {
253  EventInfo event_info;
254  event_info.type = EventInfoType::kKeyFrame;
255  event_info.key_frame = {timestamp, start_byte_offset, size};
256  event_info_.push_back(event_info);
257  } else {
258  const bool result = hls_notifier_->NotifyKeyFrame(
259  stream_id_.value(), timestamp, start_byte_offset, size);
260  LOG_IF(WARNING, !result) << "Failed to add new segment.";
261  }
262 }
263 
264 void HlsNotifyMuxerListener::OnCueEvent(int64_t timestamp,
265  const std::string& cue_data) {
266  // Not using |cue_data| at this moment.
267  if (!media_info_->has_segment_template()) {
268  EventInfo event_info;
269  event_info.type = EventInfoType::kCue;
270  event_info.cue_event_info = {timestamp};
271  event_info_.push_back(event_info);
272  } else {
273  hls_notifier_->NotifyCueEvent(stream_id_.value(), timestamp);
274  }
275 }
276 
277 bool HlsNotifyMuxerListener::NotifyNewStream() {
278  DCHECK(media_info_);
279 
280  uint32_t stream_id;
281  const bool result = hls_notifier_->NotifyNewStream(
282  *media_info_, playlist_name_, ext_x_media_name_, ext_x_media_group_id_,
283  &stream_id);
284  if (!result) {
285  LOG(WARNING) << "Failed to notify new stream for VOD.";
286  return false;
287  }
288  stream_id_ = stream_id;
289  return true;
290 }
291 
292 } // namespace media
293 } // namespace shaka
void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
-
base::Optional< Range > init_range
Range of the initialization section of a segment.
-
Abstract class holds stream information.
Definition: stream_info.h:62
-
virtual bool NotifySampleDuration(uint32_t stream_id, uint32_t sample_duration)=0
-
void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
-
base::Optional< Range > index_range
Range of the index section of a segment.
- - -
void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
-
virtual bool NotifyKeyFrame(uint32_t stream_id, uint64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
-
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
- - -
virtual bool NotifyNewSegment(uint32_t stream_id, const std::string &segment_name, uint64_t start_time, uint64_t duration, uint64_t start_byte_offset, uint64_t size)=0
-
virtual bool NotifyNewStream(const MediaInfo &media_info, const std::string &playlist_name, const std::string &stream_name, const std::string &group_id, uint32_t *stream_id)=0
- -
void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
-
HlsNotifyMuxerListener(const std::string &playlist_name, bool iframes_only, const std::string &ext_x_media_name, const std::string &ext_x_media_group_id, const std::vector< std::string > &characteristics, hls::HlsNotifier *hls_notifier)
-
void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
-
void OnSampleDurationReady(uint32_t sample_duration) override
- -
void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
-
virtual bool NotifyEncryptionUpdate(uint32_t stream_id, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &system_id, const std::vector< uint8_t > &iv, const std::vector< uint8_t > &protection_system_specific_data)=0
-
virtual bool NotifyCueEvent(uint32_t stream_id, uint64_t timestamp)=0
- +
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/event/hls_notify_muxer_listener.h"
+
8 
+
9 #include <memory>
+
10 #include "packager/base/logging.h"
+
11 #include "packager/hls/base/hls_notifier.h"
+
12 #include "packager/media/base/muxer_options.h"
+
13 #include "packager/media/base/protection_system_specific_info.h"
+
14 #include "packager/media/event/muxer_listener_internal.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+ +
20  const std::string& playlist_name,
+
21  bool iframes_only,
+
22  const std::string& ext_x_media_name,
+
23  const std::string& ext_x_media_group_id,
+
24  const std::vector<std::string>& characteristics,
+
25  hls::HlsNotifier* hls_notifier)
+
26  : playlist_name_(playlist_name),
+
27  iframes_only_(iframes_only),
+
28  ext_x_media_name_(ext_x_media_name),
+
29  ext_x_media_group_id_(ext_x_media_group_id),
+
30  characteristics_(characteristics),
+
31  hls_notifier_(hls_notifier) {
+
32  DCHECK(hls_notifier);
+
33 }
+
34 
+
35 HlsNotifyMuxerListener::~HlsNotifyMuxerListener() {}
+
36 
+
37 // These methods work together to notify that the media is encrypted.
+
38 // If OnEncryptionInfoReady() is called before the media has been started, then
+
39 // the information is stored and handled when OnEncryptionStart() is called.
+
40 // If OnEncryptionStart() is called before the media has been started then
+
41 // OnMediaStart() is responsible for notifying that the segments are encrypted
+
42 // right away i.e. call OnEncryptionStart().
+ +
44  bool is_initial_encryption_info,
+
45  FourCC protection_scheme,
+
46  const std::vector<uint8_t>& key_id,
+
47  const std::vector<uint8_t>& iv,
+
48  const std::vector<ProtectionSystemSpecificInfo>& key_system_infos) {
+
49  if (!stream_id_) {
+
50  next_key_id_ = key_id;
+
51  next_iv_ = iv;
+
52  next_key_system_infos_ = key_system_infos;
+
53  protection_scheme_ = protection_scheme;
+
54  return;
+
55  }
+
56  for (const ProtectionSystemSpecificInfo& info : key_system_infos) {
+
57  const bool result = hls_notifier_->NotifyEncryptionUpdate(
+
58  stream_id_.value(), key_id, info.system_id, iv, info.psshs);
+
59  LOG_IF(WARNING, !result) << "Failed to add encryption info.";
+
60  }
+
61 }
+
62 
+ +
64  if (!stream_id_) {
+
65  must_notify_encryption_start_ = true;
+
66  return;
+
67  }
+
68  if (next_key_id_.empty()) {
+
69  DCHECK(next_iv_.empty());
+
70  DCHECK(next_key_system_infos_.empty());
+
71  return;
+
72  }
+
73 
+
74  for (const ProtectionSystemSpecificInfo& info : next_key_system_infos_) {
+
75  const bool result = hls_notifier_->NotifyEncryptionUpdate(
+
76  stream_id_.value(), next_key_id_, info.system_id, next_iv_, info.psshs);
+
77  LOG_IF(WARNING, !result) << "Failed to add encryption info";
+
78  }
+
79  next_key_id_.clear();
+
80  next_iv_.clear();
+
81  next_key_system_infos_.clear();
+
82  must_notify_encryption_start_ = false;
+
83 }
+
84 
+ +
86  const StreamInfo& stream_info,
+
87  uint32_t time_scale,
+
88  ContainerType container_type) {
+
89  std::unique_ptr<MediaInfo> media_info(new MediaInfo);
+
90  if (!internal::GenerateMediaInfo(muxer_options, stream_info, time_scale,
+
91  container_type, media_info.get())) {
+
92  LOG(ERROR) << "Failed to generate MediaInfo from input.";
+
93  return;
+
94  }
+
95  if (!characteristics_.empty()) {
+
96  for (const std::string& characteristic : characteristics_)
+
97  media_info->add_hls_characteristics(characteristic);
+
98  }
+
99  if (protection_scheme_ != FOURCC_NULL) {
+
100  internal::SetContentProtectionFields(protection_scheme_, next_key_id_,
+
101  next_key_system_infos_,
+
102  media_info.get());
+
103  }
+
104 
+
105  // The content may be splitted into multiple files, but their MediaInfo
+
106  // should be compatible.
+
107  if (media_info_ &&
+
108  !internal::IsMediaInfoCompatible(*media_info, *media_info_)) {
+
109  LOG(WARNING) << "Incompatible MediaInfo " << media_info->ShortDebugString()
+
110  << " vs " << media_info_->ShortDebugString()
+
111  << ". The result manifest may not be playable.";
+
112  }
+
113  media_info_ = std::move(media_info);
+
114 
+
115  if (!media_info_->has_segment_template()) {
+
116  return;
+
117  }
+
118 
+
119  if (!NotifyNewStream())
+
120  return;
+
121  DCHECK(stream_id_);
+
122 
+
123  if (must_notify_encryption_start_) {
+ +
125  }
+
126 }
+
127 
+
128 void HlsNotifyMuxerListener::OnSampleDurationReady(uint32_t sample_duration) {
+
129  if (stream_id_) {
+
130  // This happens in live mode.
+
131  hls_notifier_->NotifySampleDuration(stream_id_.value(), sample_duration);
+
132  return;
+
133  }
+
134 
+
135  if (!media_info_) {
+
136  LOG(WARNING) << "Got sample duration " << sample_duration
+
137  << " but no media was specified.";
+
138  return;
+
139  }
+
140  if (!media_info_->has_video_info()) {
+
141  // If non video, don't worry about it (at the moment).
+
142  return;
+
143  }
+
144 
+
145  media_info_->mutable_video_info()->set_frame_duration(sample_duration);
+
146 }
+
147 
+ +
149  float duration_seconds) {
+
150  DCHECK(media_info_);
+
151  // TODO(kqyang): Should we just Flush here to avoid calling Flush explicitly?
+
152  // Don't flush the notifier here. Flushing here would write all the playlists
+
153  // before all Media Playlists are read. Which could cause problems
+
154  // setting the correct EXT-X-TARGETDURATION.
+
155  if (media_info_->has_segment_template()) {
+
156  return;
+
157  }
+
158  if (media_ranges.init_range) {
+
159  shaka::Range* init_range = media_info_->mutable_init_range();
+
160  init_range->set_begin(media_ranges.init_range.value().start);
+
161  init_range->set_end(media_ranges.init_range.value().end);
+
162  }
+
163  if (media_ranges.index_range) {
+
164  shaka::Range* index_range = media_info_->mutable_index_range();
+
165  index_range->set_begin(media_ranges.index_range.value().start);
+
166  index_range->set_end(media_ranges.index_range.value().end);
+
167  }
+
168 
+
169  if (!stream_id_) {
+
170  if (!NotifyNewStream())
+
171  return;
+
172  DCHECK(stream_id_);
+
173  } else {
+
174  // HLS is not interested in MediaInfo update.
+
175  }
+
176 
+
177  // TODO(rkuroiwa); Keep track of which (sub)segments are encrypted so that the
+
178  // notification is sent right before the enecrypted (sub)segments.
+
179  if (must_notify_encryption_start_) {
+ +
181  }
+
182 
+
183  if (!media_ranges.subsegment_ranges.empty()) {
+
184  const std::vector<Range>& subsegment_ranges =
+
185  media_ranges.subsegment_ranges;
+
186  const size_t num_subsegments = subsegment_ranges.size();
+
187  size_t subsegment_index = 0;
+
188  for (const auto& event_info : event_info_) {
+
189  switch (event_info.type) {
+
190  case EventInfoType::kSegment:
+
191  if (subsegment_index < num_subsegments) {
+
192  const Range& range = subsegment_ranges[subsegment_index];
+
193  hls_notifier_->NotifyNewSegment(
+
194  stream_id_.value(), media_info_->media_file_name(),
+
195  event_info.segment_info.start_time,
+
196  event_info.segment_info.duration, range.start,
+
197  range.end + 1 - range.start);
+
198  }
+
199  ++subsegment_index;
+
200  break;
+
201  case EventInfoType::kKeyFrame:
+
202  if (subsegment_index < num_subsegments) {
+
203  const uint64_t segment_start_offset =
+
204  subsegment_ranges[subsegment_index].start;
+
205  hls_notifier_->NotifyKeyFrame(
+
206  stream_id_.value(), event_info.key_frame.timestamp,
+
207  segment_start_offset +
+
208  event_info.key_frame.start_offset_in_segment,
+
209  event_info.key_frame.size);
+
210  }
+
211  break;
+
212  case EventInfoType::kCue:
+
213  hls_notifier_->NotifyCueEvent(stream_id_.value(),
+
214  event_info.cue_event_info.timestamp);
+
215  break;
+
216  }
+
217  }
+
218  if (subsegment_index != num_subsegments) {
+
219  LOG(WARNING) << "Number of subsegment ranges (" << num_subsegments
+
220  << ") does not match the number of subsegments notified to "
+
221  "OnNewSegment() ("
+
222  << event_info_.size() << ").";
+
223  }
+
224  }
+
225  event_info_.clear();
+
226 }
+
227 
+
228 void HlsNotifyMuxerListener::OnNewSegment(const std::string& file_name,
+
229  int64_t start_time,
+
230  int64_t duration,
+
231  uint64_t segment_file_size) {
+
232  if (!media_info_->has_segment_template()) {
+
233  EventInfo event_info;
+
234  event_info.type = EventInfoType::kSegment;
+
235  event_info.segment_info = {start_time, duration, segment_file_size};
+
236  event_info_.push_back(event_info);
+
237  } else {
+
238  // For multisegment, it always starts from the beginning of the file.
+
239  const size_t kStartingByteOffset = 0u;
+
240  const bool result = hls_notifier_->NotifyNewSegment(
+
241  stream_id_.value(), file_name, start_time, duration,
+
242  kStartingByteOffset, segment_file_size);
+
243  LOG_IF(WARNING, !result) << "Failed to add new segment.";
+
244  }
+
245 }
+
246 
+
247 void HlsNotifyMuxerListener::OnKeyFrame(int64_t timestamp,
+
248  uint64_t start_byte_offset,
+
249  uint64_t size) {
+
250  if (!iframes_only_)
+
251  return;
+
252  if (!media_info_->has_segment_template()) {
+
253  EventInfo event_info;
+
254  event_info.type = EventInfoType::kKeyFrame;
+
255  event_info.key_frame = {timestamp, start_byte_offset, size};
+
256  event_info_.push_back(event_info);
+
257  } else {
+
258  const bool result = hls_notifier_->NotifyKeyFrame(
+
259  stream_id_.value(), timestamp, start_byte_offset, size);
+
260  LOG_IF(WARNING, !result) << "Failed to add new segment.";
+
261  }
+
262 }
+
263 
+
264 void HlsNotifyMuxerListener::OnCueEvent(int64_t timestamp,
+
265  const std::string& cue_data) {
+
266  // Not using |cue_data| at this moment.
+
267  if (!media_info_->has_segment_template()) {
+
268  EventInfo event_info;
+
269  event_info.type = EventInfoType::kCue;
+
270  event_info.cue_event_info = {timestamp};
+
271  event_info_.push_back(event_info);
+
272  } else {
+
273  hls_notifier_->NotifyCueEvent(stream_id_.value(), timestamp);
+
274  }
+
275 }
+
276 
+
277 bool HlsNotifyMuxerListener::NotifyNewStream() {
+
278  DCHECK(media_info_);
+
279 
+
280  uint32_t stream_id;
+
281  const bool result = hls_notifier_->NotifyNewStream(
+
282  *media_info_, playlist_name_, ext_x_media_name_, ext_x_media_group_id_,
+
283  &stream_id);
+
284  if (!result) {
+
285  LOG(WARNING) << "Failed to notify new stream for VOD.";
+
286  return false;
+
287  }
+
288  stream_id_ = stream_id;
+
289  return true;
+
290 }
+
291 
+
292 } // namespace media
+
293 } // namespace shaka
+ +
virtual bool NotifyCueEvent(uint32_t stream_id, uint64_t timestamp)=0
+
virtual bool NotifyNewStream(const MediaInfo &media_info, const std::string &playlist_name, const std::string &stream_name, const std::string &group_id, uint32_t *stream_id)=0
+
virtual bool NotifyEncryptionUpdate(uint32_t stream_id, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &system_id, const std::vector< uint8_t > &iv, const std::vector< uint8_t > &protection_system_specific_data)=0
+
virtual bool NotifySampleDuration(uint32_t stream_id, uint32_t sample_duration)=0
+
virtual bool NotifyKeyFrame(uint32_t stream_id, uint64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
+
virtual bool NotifyNewSegment(uint32_t stream_id, const std::string &segment_name, uint64_t start_time, uint64_t duration, uint64_t start_byte_offset, uint64_t size)=0
+ +
void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
+
void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
+
void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
+
void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
+
void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
+
void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
+
HlsNotifyMuxerListener(const std::string &playlist_name, bool iframes_only, const std::string &ext_x_media_name, const std::string &ext_x_media_group_id, const std::vector< std::string > &characteristics, hls::HlsNotifier *hls_notifier)
+
void OnSampleDurationReady(uint32_t sample_duration) override
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
All the methods that are virtual are virtual for mocking.
+ + +
base::Optional< Range > init_range
Range of the initialization section of a segment.
+ +
base::Optional< Range > index_range
Range of the index section of a segment.
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+ +
diff --git a/docs/d0/d3a/webm__constants_8h_source.html b/docs/d0/d3a/webm__constants_8h_source.html index 00e52b4f1e..819676cc12 100644 --- a/docs/d0/d3a/webm__constants_8h_source.html +++ b/docs/d0/d3a/webm__constants_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_constants.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
webm_constants.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONSTANTS_H_
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONSTANTS_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 namespace shaka {
12 namespace media {
13 
17 const int kWebMIdAESSettingsCipherMode = 0x47E8;
18 const int kWebMIdAlphaMode = 0x53C0;
19 const int kWebMIdAspectRatioType = 0x54B3;
20 const int kWebMIdAttachedFile = 0x61A7;
21 const int kWebMIdAttachmentLink = 0x7446;
22 const int kWebMIdAttachments = 0x1941A469;
23 const int kWebMIdAudio = 0xE1;
24 const int kWebMIdBitDepth = 0x6264;
25 const int kWebMIdBlock = 0xA1;
26 const int kWebMIdBlockAddID = 0xEE;
27 const int kWebMIdBlockAdditions = 0x75A1;
28 const int kWebMIdBlockAdditional = 0xA5;
29 const int kWebMIdBlockDuration = 0x9B;
30 const int kWebMIdBlockGroup = 0xA0;
31 const int kWebMIdBlockMore = 0xA6;
32 const int kWebMIdChannels = 0x9F;
33 const int kWebMIdChapCountry = 0x437E;
34 const int kWebMIdChapLanguage = 0x437C;
35 const int kWebMIdChapProcess = 0x6944;
36 const int kWebMIdChapProcessCodecID = 0x6955;
37 const int kWebMIdChapProcessCommand = 0x6911;
38 const int kWebMIdChapProcessData = 0x6933;
39 const int kWebMIdChapProcessPrivate = 0x450D;
40 const int kWebMIdChapProcessTime = 0x6922;
41 const int kWebMIdChapString = 0x85;
42 const int kWebMIdChapterAtom = 0xB6;
43 const int kWebMIdChapterDisplay = 0x80;
44 const int kWebMIdChapterFlagEnabled = 0x4598;
45 const int kWebMIdChapterFlagHidden = 0x98;
46 const int kWebMIdChapterPhysicalEquiv = 0x63C3;
47 const int kWebMIdChapters = 0x1043A770;
48 const int kWebMIdChapterSegmentEditionUID = 0x6EBC;
49 const int kWebMIdChapterSegmentUID = 0x6E67;
50 const int kWebMIdChapterTimeEnd = 0x92;
51 const int kWebMIdChapterTimeStart = 0x91;
52 const int kWebMIdChapterTrack = 0x8F;
53 const int kWebMIdChapterTrackNumber = 0x89;
54 const int kWebMIdChapterTranslate = 0x6924;
55 const int kWebMIdChapterTranslateCodec = 0x69BF;
56 const int kWebMIdChapterTranslateEditionUID = 0x69FC;
57 const int kWebMIdChapterTranslateID = 0x69A5;
58 const int kWebMIdChapterUID = 0x73C4;
59 const int kWebMIdCluster = 0x1F43B675;
60 const int kWebMIdCodecDecodeAll = 0xAA;
61 const int kWebMIdCodecDelay = 0x56AA;
62 const int kWebMIdCodecID = 0x86;
63 const int kWebMIdCodecName = 0x258688;
64 const int kWebMIdCodecPrivate = 0x63A2;
65 const int kWebMIdCodecState = 0xA4;
66 const int kWebMIdColor = 0x55B0;
67 const int kWebMIdColorMatrixCoefficients = 0x55B1;
68 const int kWebMIdColorBitsPerChannel = 0x55B2;
69 const int kWebMIdColorChromaSubsamplingHorz = 0x55B3;
70 const int kWebMIdColorChromaSubsamplingVert = 0x55B4;
71 const int kWebMIdColorCbSamplingHorz = 0x55B5;
72 const int kWebMIdColorCbSamplingVert = 0x55B6;
73 const int kWebMIdColorChromaSitingHorz = 0x55B7;
74 const int kWebMIdColorChromaSitingVert = 0x55B8;
75 const int kWebMIdColorRange = 0x55B9;
76 const int kWebMIdColorTransferCharacteristics = 0x55BA;
77 const int kWebMIdColorPrimaries = 0x55BB;
78 const int kWebMIdColorMaxCLL = 0x55BC;
79 const int kWebMIdColorMaxFALL = 0x55BD;
80 const int kWebMIdColorMasteringMetadata = 0x55D0;
81 const int kWebMIdColorSpace = 0x2EB524;
82 const int kWebMIdContentCompAlgo = 0x4254;
83 const int kWebMIdContentCompression = 0x5034;
84 const int kWebMIdContentCompSettings = 0x4255;
85 const int kWebMIdContentEncAESSettings = 0x47E7;
86 const int kWebMIdContentEncAlgo = 0x47E1;
87 const int kWebMIdContentEncKeyID = 0x47E2;
88 const int kWebMIdContentEncoding = 0x6240;
89 const int kWebMIdContentEncodingOrder = 0x5031;
90 const int kWebMIdContentEncodings = 0x6D80;
91 const int kWebMIdContentEncodingScope = 0x5032;
92 const int kWebMIdContentEncodingType = 0x5033;
93 const int kWebMIdContentEncryption = 0x5035;
94 const int kWebMIdContentSigAlgo = 0x47E5;
95 const int kWebMIdContentSigHashAlgo = 0x47E6;
96 const int kWebMIdContentSigKeyID = 0x47E4;
97 const int kWebMIdContentSignature = 0x47E3;
98 const int kWebMIdCRC32 = 0xBF;
99 const int kWebMIdCueBlockNumber = 0x5378;
100 const int kWebMIdCueClusterPosition = 0xF1;
101 const int kWebMIdCueCodecState = 0xEA;
102 const int kWebMIdCuePoint = 0xBB;
103 const int kWebMIdCueReference = 0xDB;
104 const int kWebMIdCueRefTime = 0x96;
105 const int kWebMIdCues = 0x1C53BB6B;
106 const int kWebMIdCueTime = 0xB3;
107 const int kWebMIdCueTrack = 0xF7;
108 const int kWebMIdCueTrackPositions = 0xB7;
109 const int kWebMIdDateUTC = 0x4461;
110 const int kWebMIdDefaultDuration = 0x23E383;
111 const int kWebMIdDiscardPadding = 0x75A2;
112 const int kWebMIdDisplayHeight = 0x54BA;
113 const int kWebMIdDisplayUnit = 0x54B2;
114 const int kWebMIdDisplayWidth = 0x54B0;
115 const int kWebMIdDocType = 0x4282;
116 const int kWebMIdDocTypeReadVersion = 0x4285;
117 const int kWebMIdDocTypeVersion = 0x4287;
118 const int kWebMIdDuration = 0x4489;
119 const int kWebMIdEBMLHeader = 0x1A45DFA3;
120 const int kWebMIdEBMLMaxIDLength = 0x42F2;
121 const int kWebMIdEBMLMaxSizeLength = 0x42F3;
122 const int kWebMIdEBMLReadVersion = 0x42F7;
123 const int kWebMIdEBMLVersion = 0x4286;
124 const int kWebMIdEditionEntry = 0x45B9;
125 const int kWebMIdEditionFlagDefault = 0x45DB;
126 const int kWebMIdEditionFlagHidden = 0x45BD;
127 const int kWebMIdEditionFlagOrdered = 0x45DD;
128 const int kWebMIdEditionUID = 0x45BC;
129 const int kWebMIdFileData = 0x465C;
130 const int kWebMIdFileDescription = 0x467E;
131 const int kWebMIdFileMimeType = 0x4660;
132 const int kWebMIdFileName = 0x466E;
133 const int kWebMIdFileUID = 0x46AE;
134 const int kWebMIdFlagDefault = 0x88;
135 const int kWebMIdFlagEnabled = 0xB9;
136 const int kWebMIdFlagForced = 0x55AA;
137 const int kWebMIdFlagInterlaced = 0x9A;
138 const int kWebMIdFlagLacing = 0x9C;
139 const int kWebMIdFrameRate = 0x2383E3;
140 const int kWebMIdInfo = 0x1549A966;
141 const int kWebMIdJoinBlocks = 0xE9;
142 const int kWebMIdLaceNumber = 0xCC;
143 const int kWebMIdLanguage = 0x22B59C;
144 const int kWebMIdMaxBlockAdditionId = 0x55EE;
145 const int kWebMIdMaxCache = 0x6DF8;
146 const int kWebMIdMinCache = 0x6DE7;
147 const int kWebMIdMuxingApp = 0x4D80;
148 const int kWebMIdName = 0x536E;
149 const int kWebMIdNextFilename = 0x3E83BB;
150 const int kWebMIdNextUID = 0x3EB923;
151 const int kWebMIdOutputSamplingFrequency = 0x78B5;
152 const int kWebMIdPixelCropBottom = 0x54AA;
153 const int kWebMIdPixelCropLeft = 0x54CC;
154 const int kWebMIdPixelCropRight = 0x54DD;
155 const int kWebMIdPixelCropTop = 0x54BB;
156 const int kWebMIdPixelHeight = 0xBA;
157 const int kWebMIdPixelWidth = 0xB0;
158 const int kWebMIdPosition = 0xA7;
159 const int kWebMIdPrevFilename = 0x3C83AB;
160 const int kWebMIdPrevSize = 0xAB;
161 const int kWebMIdPrevUID = 0x3CB923;
162 const int kWebMIdReferenceBlock = 0xFB;
163 const int kWebMIdReferencePriority = 0xFA;
164 const int kWebMIdSamplingFrequency = 0xB5;
165 const int kWebMIdSeek = 0x4DBB;
166 const int kWebMIdSeekHead = 0x114D9B74;
167 const int kWebMIdSeekID = 0x53AB;
168 const int kWebMIdSeekPosition = 0x53AC;
169 const int kWebMIdSeekPreRoll = 0x56BB;
170 const int kWebMIdSegment = 0x18538067;
171 const int kWebMIdSegmentFamily = 0x4444;
172 const int kWebMIdSegmentFilename = 0x7384;
173 const int kWebMIdSegmentUID = 0x73A4;
174 const int kWebMIdSilentTrackNumber = 0x58D7;
175 const int kWebMIdSilentTracks = 0x5854;
176 const int kWebMIdSimpleBlock = 0xA3;
177 const int kWebMIdSimpleTag = 0x67C8;
178 const int kWebMIdSlices = 0x8E;
179 const int kWebMIdStereoMode = 0x53B8;
180 const int kWebMIdTag = 0x7373;
181 const int kWebMIdTagAttachmentUID = 0x63C6;
182 const int kWebMIdTagBinary = 0x4485;
183 const int kWebMIdTagChapterUID = 0x63C4;
184 const int kWebMIdTagDefault = 0x4484;
185 const int kWebMIdTagEditionUID = 0x63C9;
186 const int kWebMIdTagLanguage = 0x447A;
187 const int kWebMIdTagName = 0x45A3;
188 const int kWebMIdTags = 0x1254C367;
189 const int kWebMIdTagString = 0x4487;
190 const int kWebMIdTagTrackUID = 0x63C5;
191 const int kWebMIdTargets = 0x63C0;
192 const int kWebMIdTargetType = 0x63CA;
193 const int kWebMIdTargetTypeValue = 0x68CA;
194 const int kWebMIdTimecode = 0xE7;
195 const int kWebMIdTimecodeScale = 0x2AD7B1;
196 const int kWebMIdTimeSlice = 0xE8;
197 const int kWebMIdTitle = 0x7BA9;
198 const int kWebMIdTrackCombinePlanes = 0xE3;
199 const int kWebMIdTrackEntry = 0xAE;
200 const int kWebMIdTrackJoinUID = 0xED;
201 const int kWebMIdTrackNumber = 0xD7;
202 const int kWebMIdTrackOperation = 0xE2;
203 const int kWebMIdTrackOverlay = 0x6FAB;
204 const int kWebMIdTrackPlane = 0xE4;
205 const int kWebMIdTrackPlaneType = 0xE6;
206 const int kWebMIdTrackPlaneUID = 0xE5;
207 const int kWebMIdTracks = 0x1654AE6B;
208 const int kWebMIdTrackTimecodeScale = 0x23314F;
209 const int kWebMIdTrackTranslate = 0x6624;
210 const int kWebMIdTrackTranslateCodec = 0x66BF;
211 const int kWebMIdTrackTranslateEditionUID = 0x66FC;
212 const int kWebMIdTrackTranslateTrackID = 0x66A5;
213 const int kWebMIdTrackType = 0x83;
214 const int kWebMIdTrackUID = 0x73C5;
215 const int kWebMIdVideo = 0xE0;
216 const int kWebMIdVoid = 0xEC;
217 const int kWebMIdWritingApp = 0x5741;
218 
219 const int64_t kWebMReservedId = 0x1FFFFFFF;
220 const int64_t kWebMUnknownSize = 0x00FFFFFFFFFFFFFFLL;
221 
222 const uint8_t kWebMFlagKeyframe = 0x80;
223 
226 const size_t kWebMIvSize = 8;
227 const size_t kWebMSignalByteSize = 1;
228 const uint8_t kWebMEncryptedSignal = 0x01;
229 const uint8_t kWebMPartitionedSignal = 0x02;
230 const size_t kWebMNumPartitionsSize = 1;
231 const size_t kWebMPartitionOffsetSize = sizeof(uint32_t);
232 const uint8_t kWebMMaxSubsamples = 127;
233 
236 
237 const int kWebMTrackTypeVideo = 1;
238 const int kWebMTrackTypeAudio = 2;
239 const int kWebMTrackTypeSubtitlesOrCaptions = 0x11;
240 const int kWebMTrackTypeDescriptionsOrMetadata = 0x21;
241 
242 extern const char kWebMCodecSubtitles[];
243 extern const char kWebMCodecCaptions[];
244 extern const char kWebMCodecDescriptions[];
245 extern const char kWebMCodecMetadata[];
246 
247 } // namespace media
248 } // namespace shaka
249 
250 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONSTANTS_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONSTANTS_H_
+
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONSTANTS_H_
+
7 
+
8 #include <stddef.h>
+
9 #include <stdint.h>
+
10 
+
11 namespace shaka {
+
12 namespace media {
+
13 
+
17 const int kWebMIdAESSettingsCipherMode = 0x47E8;
+
18 const int kWebMIdAlphaMode = 0x53C0;
+
19 const int kWebMIdAspectRatioType = 0x54B3;
+
20 const int kWebMIdAttachedFile = 0x61A7;
+
21 const int kWebMIdAttachmentLink = 0x7446;
+
22 const int kWebMIdAttachments = 0x1941A469;
+
23 const int kWebMIdAudio = 0xE1;
+
24 const int kWebMIdBitDepth = 0x6264;
+
25 const int kWebMIdBlock = 0xA1;
+
26 const int kWebMIdBlockAddID = 0xEE;
+
27 const int kWebMIdBlockAdditions = 0x75A1;
+
28 const int kWebMIdBlockAdditional = 0xA5;
+
29 const int kWebMIdBlockDuration = 0x9B;
+
30 const int kWebMIdBlockGroup = 0xA0;
+
31 const int kWebMIdBlockMore = 0xA6;
+
32 const int kWebMIdChannels = 0x9F;
+
33 const int kWebMIdChapCountry = 0x437E;
+
34 const int kWebMIdChapLanguage = 0x437C;
+
35 const int kWebMIdChapProcess = 0x6944;
+
36 const int kWebMIdChapProcessCodecID = 0x6955;
+
37 const int kWebMIdChapProcessCommand = 0x6911;
+
38 const int kWebMIdChapProcessData = 0x6933;
+
39 const int kWebMIdChapProcessPrivate = 0x450D;
+
40 const int kWebMIdChapProcessTime = 0x6922;
+
41 const int kWebMIdChapString = 0x85;
+
42 const int kWebMIdChapterAtom = 0xB6;
+
43 const int kWebMIdChapterDisplay = 0x80;
+
44 const int kWebMIdChapterFlagEnabled = 0x4598;
+
45 const int kWebMIdChapterFlagHidden = 0x98;
+
46 const int kWebMIdChapterPhysicalEquiv = 0x63C3;
+
47 const int kWebMIdChapters = 0x1043A770;
+
48 const int kWebMIdChapterSegmentEditionUID = 0x6EBC;
+
49 const int kWebMIdChapterSegmentUID = 0x6E67;
+
50 const int kWebMIdChapterTimeEnd = 0x92;
+
51 const int kWebMIdChapterTimeStart = 0x91;
+
52 const int kWebMIdChapterTrack = 0x8F;
+
53 const int kWebMIdChapterTrackNumber = 0x89;
+
54 const int kWebMIdChapterTranslate = 0x6924;
+
55 const int kWebMIdChapterTranslateCodec = 0x69BF;
+
56 const int kWebMIdChapterTranslateEditionUID = 0x69FC;
+
57 const int kWebMIdChapterTranslateID = 0x69A5;
+
58 const int kWebMIdChapterUID = 0x73C4;
+
59 const int kWebMIdCluster = 0x1F43B675;
+
60 const int kWebMIdCodecDecodeAll = 0xAA;
+
61 const int kWebMIdCodecDelay = 0x56AA;
+
62 const int kWebMIdCodecID = 0x86;
+
63 const int kWebMIdCodecName = 0x258688;
+
64 const int kWebMIdCodecPrivate = 0x63A2;
+
65 const int kWebMIdCodecState = 0xA4;
+
66 const int kWebMIdColor = 0x55B0;
+
67 const int kWebMIdColorMatrixCoefficients = 0x55B1;
+
68 const int kWebMIdColorBitsPerChannel = 0x55B2;
+
69 const int kWebMIdColorChromaSubsamplingHorz = 0x55B3;
+
70 const int kWebMIdColorChromaSubsamplingVert = 0x55B4;
+
71 const int kWebMIdColorCbSamplingHorz = 0x55B5;
+
72 const int kWebMIdColorCbSamplingVert = 0x55B6;
+
73 const int kWebMIdColorChromaSitingHorz = 0x55B7;
+
74 const int kWebMIdColorChromaSitingVert = 0x55B8;
+
75 const int kWebMIdColorRange = 0x55B9;
+
76 const int kWebMIdColorTransferCharacteristics = 0x55BA;
+
77 const int kWebMIdColorPrimaries = 0x55BB;
+
78 const int kWebMIdColorMaxCLL = 0x55BC;
+
79 const int kWebMIdColorMaxFALL = 0x55BD;
+
80 const int kWebMIdColorMasteringMetadata = 0x55D0;
+
81 const int kWebMIdColorSpace = 0x2EB524;
+
82 const int kWebMIdContentCompAlgo = 0x4254;
+
83 const int kWebMIdContentCompression = 0x5034;
+
84 const int kWebMIdContentCompSettings = 0x4255;
+
85 const int kWebMIdContentEncAESSettings = 0x47E7;
+
86 const int kWebMIdContentEncAlgo = 0x47E1;
+
87 const int kWebMIdContentEncKeyID = 0x47E2;
+
88 const int kWebMIdContentEncoding = 0x6240;
+
89 const int kWebMIdContentEncodingOrder = 0x5031;
+
90 const int kWebMIdContentEncodings = 0x6D80;
+
91 const int kWebMIdContentEncodingScope = 0x5032;
+
92 const int kWebMIdContentEncodingType = 0x5033;
+
93 const int kWebMIdContentEncryption = 0x5035;
+
94 const int kWebMIdContentSigAlgo = 0x47E5;
+
95 const int kWebMIdContentSigHashAlgo = 0x47E6;
+
96 const int kWebMIdContentSigKeyID = 0x47E4;
+
97 const int kWebMIdContentSignature = 0x47E3;
+
98 const int kWebMIdCRC32 = 0xBF;
+
99 const int kWebMIdCueBlockNumber = 0x5378;
+
100 const int kWebMIdCueClusterPosition = 0xF1;
+
101 const int kWebMIdCueCodecState = 0xEA;
+
102 const int kWebMIdCuePoint = 0xBB;
+
103 const int kWebMIdCueReference = 0xDB;
+
104 const int kWebMIdCueRefTime = 0x96;
+
105 const int kWebMIdCues = 0x1C53BB6B;
+
106 const int kWebMIdCueTime = 0xB3;
+
107 const int kWebMIdCueTrack = 0xF7;
+
108 const int kWebMIdCueTrackPositions = 0xB7;
+
109 const int kWebMIdDateUTC = 0x4461;
+
110 const int kWebMIdDefaultDuration = 0x23E383;
+
111 const int kWebMIdDiscardPadding = 0x75A2;
+
112 const int kWebMIdDisplayHeight = 0x54BA;
+
113 const int kWebMIdDisplayUnit = 0x54B2;
+
114 const int kWebMIdDisplayWidth = 0x54B0;
+
115 const int kWebMIdDocType = 0x4282;
+
116 const int kWebMIdDocTypeReadVersion = 0x4285;
+
117 const int kWebMIdDocTypeVersion = 0x4287;
+
118 const int kWebMIdDuration = 0x4489;
+
119 const int kWebMIdEBMLHeader = 0x1A45DFA3;
+
120 const int kWebMIdEBMLMaxIDLength = 0x42F2;
+
121 const int kWebMIdEBMLMaxSizeLength = 0x42F3;
+
122 const int kWebMIdEBMLReadVersion = 0x42F7;
+
123 const int kWebMIdEBMLVersion = 0x4286;
+
124 const int kWebMIdEditionEntry = 0x45B9;
+
125 const int kWebMIdEditionFlagDefault = 0x45DB;
+
126 const int kWebMIdEditionFlagHidden = 0x45BD;
+
127 const int kWebMIdEditionFlagOrdered = 0x45DD;
+
128 const int kWebMIdEditionUID = 0x45BC;
+
129 const int kWebMIdFileData = 0x465C;
+
130 const int kWebMIdFileDescription = 0x467E;
+
131 const int kWebMIdFileMimeType = 0x4660;
+
132 const int kWebMIdFileName = 0x466E;
+
133 const int kWebMIdFileUID = 0x46AE;
+
134 const int kWebMIdFlagDefault = 0x88;
+
135 const int kWebMIdFlagEnabled = 0xB9;
+
136 const int kWebMIdFlagForced = 0x55AA;
+
137 const int kWebMIdFlagInterlaced = 0x9A;
+
138 const int kWebMIdFlagLacing = 0x9C;
+
139 const int kWebMIdFrameRate = 0x2383E3;
+
140 const int kWebMIdInfo = 0x1549A966;
+
141 const int kWebMIdJoinBlocks = 0xE9;
+
142 const int kWebMIdLaceNumber = 0xCC;
+
143 const int kWebMIdLanguage = 0x22B59C;
+
144 const int kWebMIdMaxBlockAdditionId = 0x55EE;
+
145 const int kWebMIdMaxCache = 0x6DF8;
+
146 const int kWebMIdMinCache = 0x6DE7;
+
147 const int kWebMIdMuxingApp = 0x4D80;
+
148 const int kWebMIdName = 0x536E;
+
149 const int kWebMIdNextFilename = 0x3E83BB;
+
150 const int kWebMIdNextUID = 0x3EB923;
+
151 const int kWebMIdOutputSamplingFrequency = 0x78B5;
+
152 const int kWebMIdPixelCropBottom = 0x54AA;
+
153 const int kWebMIdPixelCropLeft = 0x54CC;
+
154 const int kWebMIdPixelCropRight = 0x54DD;
+
155 const int kWebMIdPixelCropTop = 0x54BB;
+
156 const int kWebMIdPixelHeight = 0xBA;
+
157 const int kWebMIdPixelWidth = 0xB0;
+
158 const int kWebMIdPosition = 0xA7;
+
159 const int kWebMIdPrevFilename = 0x3C83AB;
+
160 const int kWebMIdPrevSize = 0xAB;
+
161 const int kWebMIdPrevUID = 0x3CB923;
+
162 const int kWebMIdReferenceBlock = 0xFB;
+
163 const int kWebMIdReferencePriority = 0xFA;
+
164 const int kWebMIdSamplingFrequency = 0xB5;
+
165 const int kWebMIdSeek = 0x4DBB;
+
166 const int kWebMIdSeekHead = 0x114D9B74;
+
167 const int kWebMIdSeekID = 0x53AB;
+
168 const int kWebMIdSeekPosition = 0x53AC;
+
169 const int kWebMIdSeekPreRoll = 0x56BB;
+
170 const int kWebMIdSegment = 0x18538067;
+
171 const int kWebMIdSegmentFamily = 0x4444;
+
172 const int kWebMIdSegmentFilename = 0x7384;
+
173 const int kWebMIdSegmentUID = 0x73A4;
+
174 const int kWebMIdSilentTrackNumber = 0x58D7;
+
175 const int kWebMIdSilentTracks = 0x5854;
+
176 const int kWebMIdSimpleBlock = 0xA3;
+
177 const int kWebMIdSimpleTag = 0x67C8;
+
178 const int kWebMIdSlices = 0x8E;
+
179 const int kWebMIdStereoMode = 0x53B8;
+
180 const int kWebMIdTag = 0x7373;
+
181 const int kWebMIdTagAttachmentUID = 0x63C6;
+
182 const int kWebMIdTagBinary = 0x4485;
+
183 const int kWebMIdTagChapterUID = 0x63C4;
+
184 const int kWebMIdTagDefault = 0x4484;
+
185 const int kWebMIdTagEditionUID = 0x63C9;
+
186 const int kWebMIdTagLanguage = 0x447A;
+
187 const int kWebMIdTagName = 0x45A3;
+
188 const int kWebMIdTags = 0x1254C367;
+
189 const int kWebMIdTagString = 0x4487;
+
190 const int kWebMIdTagTrackUID = 0x63C5;
+
191 const int kWebMIdTargets = 0x63C0;
+
192 const int kWebMIdTargetType = 0x63CA;
+
193 const int kWebMIdTargetTypeValue = 0x68CA;
+
194 const int kWebMIdTimecode = 0xE7;
+
195 const int kWebMIdTimecodeScale = 0x2AD7B1;
+
196 const int kWebMIdTimeSlice = 0xE8;
+
197 const int kWebMIdTitle = 0x7BA9;
+
198 const int kWebMIdTrackCombinePlanes = 0xE3;
+
199 const int kWebMIdTrackEntry = 0xAE;
+
200 const int kWebMIdTrackJoinUID = 0xED;
+
201 const int kWebMIdTrackNumber = 0xD7;
+
202 const int kWebMIdTrackOperation = 0xE2;
+
203 const int kWebMIdTrackOverlay = 0x6FAB;
+
204 const int kWebMIdTrackPlane = 0xE4;
+
205 const int kWebMIdTrackPlaneType = 0xE6;
+
206 const int kWebMIdTrackPlaneUID = 0xE5;
+
207 const int kWebMIdTracks = 0x1654AE6B;
+
208 const int kWebMIdTrackTimecodeScale = 0x23314F;
+
209 const int kWebMIdTrackTranslate = 0x6624;
+
210 const int kWebMIdTrackTranslateCodec = 0x66BF;
+
211 const int kWebMIdTrackTranslateEditionUID = 0x66FC;
+
212 const int kWebMIdTrackTranslateTrackID = 0x66A5;
+
213 const int kWebMIdTrackType = 0x83;
+
214 const int kWebMIdTrackUID = 0x73C5;
+
215 const int kWebMIdVideo = 0xE0;
+
216 const int kWebMIdVoid = 0xEC;
+
217 const int kWebMIdWritingApp = 0x5741;
+
218 
+
219 const int64_t kWebMReservedId = 0x1FFFFFFF;
+
220 const int64_t kWebMUnknownSize = 0x00FFFFFFFFFFFFFFLL;
+
221 
+
222 const uint8_t kWebMFlagKeyframe = 0x80;
+
223 
+
226 const size_t kWebMIvSize = 8;
+
227 const size_t kWebMSignalByteSize = 1;
+
228 const uint8_t kWebMEncryptedSignal = 0x01;
+
229 const uint8_t kWebMPartitionedSignal = 0x02;
+
230 const size_t kWebMNumPartitionsSize = 1;
+
231 const size_t kWebMPartitionOffsetSize = sizeof(uint32_t);
+
232 const uint8_t kWebMMaxSubsamples = 127;
+
233 
+
236 
+
237 const int kWebMTrackTypeVideo = 1;
+
238 const int kWebMTrackTypeAudio = 2;
+
239 const int kWebMTrackTypeSubtitlesOrCaptions = 0x11;
+
240 const int kWebMTrackTypeDescriptionsOrMetadata = 0x21;
+
241 
+
242 extern const char kWebMCodecSubtitles[];
+
243 extern const char kWebMCodecCaptions[];
+
244 extern const char kWebMCodecDescriptions[];
+
245 extern const char kWebMCodecMetadata[];
+
246 
+
247 } // namespace media
+
248 } // namespace shaka
+
249 
+
250 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONSTANTS_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d3c/structshaka_1_1media_1_1mp4_1_1ProtectionSystemSpecificHeader.html b/docs/d0/d3c/structshaka_1_1media_1_1mp4_1_1ProtectionSystemSpecificHeader.html index f47d4c4aad..a97e6cd7dc 100644 --- a/docs/d0/d3c/structshaka_1_1media_1_1mp4_1_1ProtectionSystemSpecificHeader.html +++ b/docs/d0/d3c/structshaka_1_1media_1_1mp4_1_1ProtectionSystemSpecificHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::ProtectionSystemSpecificHeader Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -121,7 +124,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 58 of file box_definitions.h.

+

Definition at line 59 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -149,7 +152,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 164 of file box_definitions.cc.

+

Definition at line 176 of file box_definitions.cc.

@@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/d0/d42/aes__cryptor_8h_source.html b/docs/d0/d42/aes__cryptor_8h_source.html index 6c26ee9a86..405dcafc5d 100644 --- a/docs/d0/d42/aes__cryptor_8h_source.html +++ b/docs/d0/d42/aes__cryptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/aes_cryptor.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
aes_cryptor.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_AES_CRYPTOR_H_
8 #define PACKAGER_MEDIA_BASE_AES_CRYPTOR_H_
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "packager/base/macros.h"
15 #include "packager/media/base/fourccs.h"
16 
17 struct aes_key_st;
18 typedef struct aes_key_st AES_KEY;
19 
20 namespace shaka {
21 namespace media {
22 
23 // AES cryptor interface. Inherited by various AES encryptor and decryptor
24 // implementations.
25 class AesCryptor {
26  public:
27  enum ConstantIvFlag {
28  kUseConstantIv,
29  kDontUseConstantIv,
30  };
31 
38  explicit AesCryptor(ConstantIvFlag constant_iv_flag);
39  virtual ~AesCryptor();
40 
43  virtual bool InitializeWithIv(const std::vector<uint8_t>& key,
44  const std::vector<uint8_t>& iv) = 0;
45 
51  bool Crypt(const std::vector<uint8_t>& text,
52  std::vector<uint8_t>* crypt_text);
53  bool Crypt(const std::string& text, std::string* crypt_text);
55  bool Crypt(const uint8_t* text, size_t text_size, uint8_t* crypt_text) {
56  size_t crypt_text_size = text_size;
57  return Crypt(text, text_size, crypt_text, &crypt_text_size);
58  }
59  bool Crypt(const uint8_t* text,
60  size_t text_size,
61  uint8_t* crypt_text,
62  size_t* crypt_text_size) {
63  if (constant_iv_flag_ == kUseConstantIv)
64  SetIvInternal();
65  else
66  num_crypt_bytes_ += text_size;
67  return CryptInternal(text, text_size, crypt_text, crypt_text_size);
68  }
70 
74  bool SetIv(const std::vector<uint8_t>& iv);
75 
79  void UpdateIv();
80 
82  const std::vector<uint8_t>& iv() const { return iv_; }
83 
85  bool use_constant_iv() const { return constant_iv_flag_ == kUseConstantIv; }
86 
91  static bool GenerateRandomIv(FourCC protection_scheme,
92  std::vector<uint8_t>* iv);
93 
94  protected:
95  const AES_KEY* aes_key() const { return aes_key_.get(); }
96  AES_KEY* mutable_aes_key() { return aes_key_.get(); }
97 
98  private:
99  // Internal implementation of crypt function.
100  // |text| points to the input text.
101  // |text_size| is the size of input text.
102  // |crypt_text| points to the output encrypted or decrypted text, depends on
103  // whether it is an encryption or decryption. |text| and |crypt_text| can
104  // point to the same address for in place encryption/decryption.
105  // |crypt_text_size| contains the size of |crypt_text| and it will be updated
106  // to contain the actual encrypted/decrypted size for |crypt_text| on success.
107  // Return false if the input |crypt_text_size| is not large enough to hold the
108  // output |crypt_text| or if there is any error in encryption/decryption.
109  virtual bool CryptInternal(const uint8_t* text,
110  size_t text_size,
111  uint8_t* crypt_text,
112  size_t* crypt_text_size) = 0;
113 
114  // Internal implementation of SetIv, which setup internal iv.
115  virtual void SetIvInternal() = 0;
116 
117  // |size| specifies the input text size.
118  // Return the number of padding bytes needed.
119  // Note: No paddings should be needed except for pkcs5-cbc encryptor.
120  virtual size_t NumPaddingBytes(size_t size) const;
121 
122  // Openssl AES_KEY.
123  std::unique_ptr<AES_KEY> aes_key_;
124 
125  // Indicates whether a constant iv is used. Internal iv will be reset to
126  // |iv_| before calling Crypt if that is the case.
127  const ConstantIvFlag constant_iv_flag_;
128  // Initialization vector from by SetIv or InitializeWithIv, with size 8 or 16
129  // bytes.
130  std::vector<uint8_t> iv_;
131  // Tracks number of crypt bytes. It is used to calculate how many blocks
132  // should iv advance in UpdateIv(). It will be reset to 0 after iv is updated.
133  size_t num_crypt_bytes_;
134 
135  DISALLOW_COPY_AND_ASSIGN(AesCryptor);
136 };
137 
138 } // namespace media
139 } // namespace shaka
140 
141 #endif // PACKAGER_MEDIA_BASE_AES_CRYPTOR_H_
- -
AesCryptor(ConstantIvFlag constant_iv_flag)
Definition: aes_cryptor.cc:32
-
All the methods that are virtual are virtual for mocking.
-
virtual bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv)=0
-
bool Crypt(const uint8_t *text, size_t text_size, uint8_t *crypt_text)
Definition: aes_cryptor.h:55
-
static bool GenerateRandomIv(FourCC protection_scheme, std::vector< uint8_t > *iv)
Definition: aes_cryptor.cc:110
-
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
-
bool SetIv(const std::vector< uint8_t > &iv)
Definition: aes_cryptor.cc:70
-
bool use_constant_iv() const
Definition: aes_cryptor.h:85
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_AES_CRYPTOR_H_
+
8 #define PACKAGER_MEDIA_BASE_AES_CRYPTOR_H_
+
9 
+
10 #include <memory>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/base/macros.h"
+
15 #include "packager/media/base/fourccs.h"
+
16 
+
17 struct aes_key_st;
+
18 typedef struct aes_key_st AES_KEY;
+
19 
+
20 namespace shaka {
+
21 namespace media {
+
22 
+
23 // AES cryptor interface. Inherited by various AES encryptor and decryptor
+
24 // implementations.
+
25 class AesCryptor {
+
26  public:
+
27  enum ConstantIvFlag {
+
28  kUseConstantIv,
+
29  kDontUseConstantIv,
+
30  };
+
31 
+
38  explicit AesCryptor(ConstantIvFlag constant_iv_flag);
+
39  virtual ~AesCryptor();
+
40 
+
43  virtual bool InitializeWithIv(const std::vector<uint8_t>& key,
+
44  const std::vector<uint8_t>& iv) = 0;
+
45 
+
51  bool Crypt(const std::vector<uint8_t>& text,
+
52  std::vector<uint8_t>* crypt_text);
+
53  bool Crypt(const std::string& text, std::string* crypt_text);
+
55  bool Crypt(const uint8_t* text, size_t text_size, uint8_t* crypt_text) {
+
56  size_t crypt_text_size = text_size;
+
57  return Crypt(text, text_size, crypt_text, &crypt_text_size);
+
58  }
+
59  bool Crypt(const uint8_t* text,
+
60  size_t text_size,
+
61  uint8_t* crypt_text,
+
62  size_t* crypt_text_size) {
+
63  if (constant_iv_flag_ == kUseConstantIv)
+
64  SetIvInternal();
+
65  else
+
66  num_crypt_bytes_ += text_size;
+
67  return CryptInternal(text, text_size, crypt_text, crypt_text_size);
+
68  }
+
70 
+
74  bool SetIv(const std::vector<uint8_t>& iv);
+
75 
+
79  void UpdateIv();
+
80 
+
82  const std::vector<uint8_t>& iv() const { return iv_; }
+
83 
+
85  bool use_constant_iv() const { return constant_iv_flag_ == kUseConstantIv; }
+
86 
+
91  static bool GenerateRandomIv(FourCC protection_scheme,
+
92  std::vector<uint8_t>* iv);
+
93 
+
94  protected:
+
95  const AES_KEY* aes_key() const { return aes_key_.get(); }
+
96  AES_KEY* mutable_aes_key() { return aes_key_.get(); }
+
97 
+
98  private:
+
99  // Internal implementation of crypt function.
+
100  // |text| points to the input text.
+
101  // |text_size| is the size of input text.
+
102  // |crypt_text| points to the output encrypted or decrypted text, depends on
+
103  // whether it is an encryption or decryption. |text| and |crypt_text| can
+
104  // point to the same address for in place encryption/decryption.
+
105  // |crypt_text_size| contains the size of |crypt_text| and it will be updated
+
106  // to contain the actual encrypted/decrypted size for |crypt_text| on success.
+
107  // Return false if the input |crypt_text_size| is not large enough to hold the
+
108  // output |crypt_text| or if there is any error in encryption/decryption.
+
109  virtual bool CryptInternal(const uint8_t* text,
+
110  size_t text_size,
+
111  uint8_t* crypt_text,
+
112  size_t* crypt_text_size) = 0;
+
113 
+
114  // Internal implementation of SetIv, which setup internal iv.
+
115  virtual void SetIvInternal() = 0;
+
116 
+
117  // |size| specifies the input text size.
+
118  // Return the number of padding bytes needed.
+
119  // Note: No paddings should be needed except for pkcs5-cbc encryptor.
+
120  virtual size_t NumPaddingBytes(size_t size) const;
+
121 
+
122  // Openssl AES_KEY.
+
123  std::unique_ptr<AES_KEY> aes_key_;
+
124 
+
125  // Indicates whether a constant iv is used. Internal iv will be reset to
+
126  // |iv_| before calling Crypt if that is the case.
+
127  const ConstantIvFlag constant_iv_flag_;
+
128  // Initialization vector from by SetIv or InitializeWithIv, with size 8 or 16
+
129  // bytes.
+
130  std::vector<uint8_t> iv_;
+
131  // Tracks number of crypt bytes. It is used to calculate how many blocks
+
132  // should iv advance in UpdateIv(). It will be reset to 0 after iv is updated.
+
133  size_t num_crypt_bytes_;
+
134 
+
135  DISALLOW_COPY_AND_ASSIGN(AesCryptor);
+
136 };
+
137 
+
138 } // namespace media
+
139 } // namespace shaka
+
140 
+
141 #endif // PACKAGER_MEDIA_BASE_AES_CRYPTOR_H_
+ +
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
+
static bool GenerateRandomIv(FourCC protection_scheme, std::vector< uint8_t > *iv)
Definition: aes_cryptor.cc:110
+
virtual bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv)=0
+
AesCryptor(ConstantIvFlag constant_iv_flag)
Definition: aes_cryptor.cc:32
+
bool SetIv(const std::vector< uint8_t > &iv)
Definition: aes_cryptor.cc:70
+ +
bool use_constant_iv() const
Definition: aes_cryptor.h:85
+
bool Crypt(const uint8_t *text, size_t text_size, uint8_t *crypt_text)
Definition: aes_cryptor.h:55
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d42/widevine__encryption__flags_8cc_source.html b/docs/d0/d42/widevine__encryption__flags_8cc_source.html index db22f1c190..2fea300dad 100644 --- a/docs/d0/d42/widevine__encryption__flags_8cc_source.html +++ b/docs/d0/d42/widevine__encryption__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/widevine_encryption_flags.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
widevine_encryption_flags.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines command line flags for widevine_encryption.
8 
9 #include "packager/app/widevine_encryption_flags.h"
10 
11 #include "packager/app/validate_flag.h"
12 #include "packager/base/logging.h"
13 #include "packager/base/strings/string_piece.h"
14 #include "packager/base/strings/string_util.h"
15 
16 DEFINE_bool(enable_widevine_encryption,
17  false,
18  "Enable encryption with Widevine key server. User should provide "
19  "either AES signing key (--aes_signing_key, --aes_signing_iv) or "
20  "RSA signing key (--rsa_signing_key_path).");
21 DEFINE_bool(enable_widevine_decryption,
22  false,
23  "Enable decryption with Widevine license server/proxy. User should "
24  "provide either AES signing key (--aes_signing_key, "
25  "--aes_signing_iv) or RSA signing key (--rsa_signing_key_path).");
26 DEFINE_string(key_server_url, "", "Key server url. Required for encryption and "
27  "decryption");
28 DEFINE_hex_bytes(content_id, "", "Content Id (hex).");
29 DEFINE_string(policy,
30  "",
31  "The name of a stored policy, which specifies DRM content "
32  "rights.");
33 DEFINE_int32(max_sd_pixels,
34  768 * 576,
35  "The video track is considered SD if its max pixels per frame is "
36  "no higher than max_sd_pixels. Default: 442368 (768 x 576).");
37 DEFINE_int32(max_hd_pixels,
38  1920 * 1080,
39  "The video track is considered HD if its max pixels per frame is "
40  "higher than max_sd_pixels, but no higher than max_hd_pixels. "
41  "Default: 2073600 (1920 x 1080).");
42 DEFINE_int32(max_uhd1_pixels,
43  4096 * 2160,
44  "The video track is considered UHD1 if its max pixels per frame "
45  "is higher than max_hd_pixels, but no higher than max_uhd1_pixels."
46  " Otherwise it is UHD2. Default: 8847360 (4096 x 2160).");
47 DEFINE_string(signer, "", "The name of the signer.");
48 DEFINE_hex_bytes(aes_signing_key,
49  "",
50  "AES signing key in hex string. --aes_signing_iv is required. "
51  "Exclusive with --rsa_signing_key_path.");
52 DEFINE_hex_bytes(aes_signing_iv, "", "AES signing iv in hex string.");
53 DEFINE_string(rsa_signing_key_path,
54  "",
55  "Stores PKCS#1 RSA private key for request signing. Exclusive "
56  "with --aes_signing_key.");
57 DEFINE_int32(crypto_period_duration,
58  0,
59  "Crypto period duration in seconds. If it is non-zero, key "
60  "rotation is enabled.");
61 DEFINE_hex_bytes(group_id, "", "Identifier for a group of licenses (hex).");
62 DEFINE_bool(enable_entitlement_license,
63  false,
64  "Enable entitlement license when using Widevine key server.");
65 
66 namespace shaka {
67 namespace {
68 const bool kOptional = true;
69 } // namespace
70 
72  bool success = true;
73 
74  const bool widevine_crypto =
75  FLAGS_enable_widevine_encryption || FLAGS_enable_widevine_decryption;
76  const char widevine_crypto_label[] =
77  "--enable_widevine_encryption/decryption";
78  // key_server_url and signer (optional) are associated with
79  // enable_widevine_encryption and enable_widevine_descryption.
80  if (!ValidateFlag("key_server_url",
81  FLAGS_key_server_url,
82  widevine_crypto,
83  !kOptional,
84  widevine_crypto_label)) {
85  success = false;
86  }
87  if (!ValidateFlag("signer",
88  FLAGS_signer,
89  widevine_crypto,
90  kOptional,
91  widevine_crypto_label)) {
92  success = false;
93  }
94  if (widevine_crypto && FLAGS_signer.empty() &&
95  base::StartsWith(base::StringPiece(FLAGS_key_server_url), "http",
96  base::CompareCase::INSENSITIVE_ASCII)) {
97  LOG(WARNING) << "--signer is likely required with "
98  "--enable_widevine_encryption/decryption.";
99  }
100 
101  const char widevine_encryption_label[] = "--enable_widevine_encryption";
102  // content_id and policy (optional) are associated with
103  // enable_widevine_encryption.
104  if (!ValidateFlag("content_id",
105  FLAGS_content_id_bytes,
106  FLAGS_enable_widevine_encryption,
107  !kOptional,
108  widevine_encryption_label)) {
109  success = false;
110  }
111  if (!ValidateFlag("policy",
112  FLAGS_policy,
113  FLAGS_enable_widevine_encryption,
114  kOptional,
115  widevine_encryption_label)) {
116  success = false;
117  }
118 
119  if (FLAGS_max_sd_pixels <= 0) {
120  PrintError("--max_sd_pixels must be positive.");
121  success = false;
122  }
123  if (FLAGS_max_hd_pixels <= 0) {
124  PrintError("--max_hd_pixels must be positive.");
125  success = false;
126  }
127  if (FLAGS_max_uhd1_pixels <= 0) {
128  PrintError("--max_uhd1_pixels must be positive.");
129  success = false;
130  }
131  if (FLAGS_max_hd_pixels <= FLAGS_max_sd_pixels) {
132  PrintError("--max_hd_pixels must be greater than --max_sd_pixels.");
133  success = false;
134  }
135  if (FLAGS_max_uhd1_pixels <= FLAGS_max_hd_pixels) {
136  PrintError("--max_uhd1_pixels must be greater than --max_hd_pixels.");
137  success = false;
138  }
139 
140  const bool aes = !FLAGS_aes_signing_key_bytes.empty() ||
141  !FLAGS_aes_signing_iv_bytes.empty();
142  if (aes && (FLAGS_aes_signing_key_bytes.empty() ||
143  FLAGS_aes_signing_iv_bytes.empty())) {
144  PrintError("--aes_signing_key/iv is required if using aes signing.");
145  success = false;
146  }
147 
148  const bool rsa = !FLAGS_rsa_signing_key_path.empty();
149 
150  if (FLAGS_signer.empty() && (aes || rsa)) {
151  PrintError("--signer is required if using aes/rsa signing.");
152  success = false;
153  }
154  if (!FLAGS_signer.empty() && !aes && !rsa) {
155  PrintError(
156  "--aes_signing_key/iv or --rsa_signing_key_path is required with "
157  "--signer.");
158  success = false;
159  }
160  if (aes && rsa) {
161  PrintError(
162  "Only one of --aes_signing_key/iv and --rsa_signing_key_path should be "
163  "specified.");
164  success = false;
165  }
166 
167  if (FLAGS_crypto_period_duration < 0) {
168  PrintError("--crypto_period_duration should not be negative.");
169  success = false;
170  }
171  return success;
172 }
173 
174 } // namespace shaka
void PrintError(const std::string &error_message)
-
bool ValidateFlag(const char *flag_name, const FlagType &flag_value, bool condition, bool optional, const char *label)
Definition: validate_flag.h:37
-
bool ValidateWidevineCryptoFlags()
-
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines command line flags for widevine_encryption.
+
8 
+
9 #include "packager/app/widevine_encryption_flags.h"
+
10 
+
11 #include "packager/app/validate_flag.h"
+
12 #include "packager/base/logging.h"
+
13 #include "packager/base/strings/string_piece.h"
+
14 #include "packager/base/strings/string_util.h"
+
15 
+
16 DEFINE_bool(enable_widevine_encryption,
+
17  false,
+
18  "Enable encryption with Widevine key server. User should provide "
+
19  "either AES signing key (--aes_signing_key, --aes_signing_iv) or "
+
20  "RSA signing key (--rsa_signing_key_path).");
+
21 DEFINE_bool(enable_widevine_decryption,
+
22  false,
+
23  "Enable decryption with Widevine license server/proxy. User should "
+
24  "provide either AES signing key (--aes_signing_key, "
+
25  "--aes_signing_iv) or RSA signing key (--rsa_signing_key_path).");
+
26 DEFINE_string(key_server_url, "", "Key server url. Required for encryption and "
+
27  "decryption");
+
28 DEFINE_hex_bytes(content_id, "", "Content Id (hex).");
+
29 DEFINE_string(policy,
+
30  "",
+
31  "The name of a stored policy, which specifies DRM content "
+
32  "rights.");
+
33 DEFINE_int32(max_sd_pixels,
+
34  768 * 576,
+
35  "The video track is considered SD if its max pixels per frame is "
+
36  "no higher than max_sd_pixels. Default: 442368 (768 x 576).");
+
37 DEFINE_int32(max_hd_pixels,
+
38  1920 * 1080,
+
39  "The video track is considered HD if its max pixels per frame is "
+
40  "higher than max_sd_pixels, but no higher than max_hd_pixels. "
+
41  "Default: 2073600 (1920 x 1080).");
+
42 DEFINE_int32(max_uhd1_pixels,
+
43  4096 * 2160,
+
44  "The video track is considered UHD1 if its max pixels per frame "
+
45  "is higher than max_hd_pixels, but no higher than max_uhd1_pixels."
+
46  " Otherwise it is UHD2. Default: 8847360 (4096 x 2160).");
+
47 DEFINE_string(signer, "", "The name of the signer.");
+
48 DEFINE_hex_bytes(aes_signing_key,
+
49  "",
+
50  "AES signing key in hex string. --aes_signing_iv is required. "
+
51  "Exclusive with --rsa_signing_key_path.");
+
52 DEFINE_hex_bytes(aes_signing_iv, "", "AES signing iv in hex string.");
+
53 DEFINE_string(rsa_signing_key_path,
+
54  "",
+
55  "Stores PKCS#1 RSA private key for request signing. Exclusive "
+
56  "with --aes_signing_key.");
+
57 DEFINE_int32(crypto_period_duration,
+
58  0,
+
59  "Crypto period duration in seconds. If it is non-zero, key "
+
60  "rotation is enabled.");
+
61 DEFINE_hex_bytes(group_id, "", "Identifier for a group of licenses (hex).");
+
62 DEFINE_bool(enable_entitlement_license,
+
63  false,
+
64  "Enable entitlement license when using Widevine key server.");
+
65 
+
66 namespace shaka {
+
67 namespace {
+
68 const bool kOptional = true;
+
69 } // namespace
+
70 
+ +
72  bool success = true;
+
73 
+
74  const bool widevine_crypto =
+
75  FLAGS_enable_widevine_encryption || FLAGS_enable_widevine_decryption;
+
76  const char widevine_crypto_label[] =
+
77  "--enable_widevine_encryption/decryption";
+
78  // key_server_url and signer (optional) are associated with
+
79  // enable_widevine_encryption and enable_widevine_descryption.
+
80  if (!ValidateFlag("key_server_url",
+
81  FLAGS_key_server_url,
+
82  widevine_crypto,
+
83  !kOptional,
+
84  widevine_crypto_label)) {
+
85  success = false;
+
86  }
+
87  if (!ValidateFlag("signer",
+
88  FLAGS_signer,
+
89  widevine_crypto,
+
90  kOptional,
+
91  widevine_crypto_label)) {
+
92  success = false;
+
93  }
+
94  if (widevine_crypto && FLAGS_signer.empty() &&
+
95  base::StartsWith(base::StringPiece(FLAGS_key_server_url), "http",
+
96  base::CompareCase::INSENSITIVE_ASCII)) {
+
97  LOG(WARNING) << "--signer is likely required with "
+
98  "--enable_widevine_encryption/decryption.";
+
99  }
+
100 
+
101  const char widevine_encryption_label[] = "--enable_widevine_encryption";
+
102  // content_id and policy (optional) are associated with
+
103  // enable_widevine_encryption.
+
104  if (!ValidateFlag("content_id",
+
105  FLAGS_content_id_bytes,
+
106  FLAGS_enable_widevine_encryption,
+
107  !kOptional,
+
108  widevine_encryption_label)) {
+
109  success = false;
+
110  }
+
111  if (!ValidateFlag("policy",
+
112  FLAGS_policy,
+
113  FLAGS_enable_widevine_encryption,
+
114  kOptional,
+
115  widevine_encryption_label)) {
+
116  success = false;
+
117  }
+
118 
+
119  if (FLAGS_max_sd_pixels <= 0) {
+
120  PrintError("--max_sd_pixels must be positive.");
+
121  success = false;
+
122  }
+
123  if (FLAGS_max_hd_pixels <= 0) {
+
124  PrintError("--max_hd_pixels must be positive.");
+
125  success = false;
+
126  }
+
127  if (FLAGS_max_uhd1_pixels <= 0) {
+
128  PrintError("--max_uhd1_pixels must be positive.");
+
129  success = false;
+
130  }
+
131  if (FLAGS_max_hd_pixels <= FLAGS_max_sd_pixels) {
+
132  PrintError("--max_hd_pixels must be greater than --max_sd_pixels.");
+
133  success = false;
+
134  }
+
135  if (FLAGS_max_uhd1_pixels <= FLAGS_max_hd_pixels) {
+
136  PrintError("--max_uhd1_pixels must be greater than --max_hd_pixels.");
+
137  success = false;
+
138  }
+
139 
+
140  const bool aes = !FLAGS_aes_signing_key_bytes.empty() ||
+
141  !FLAGS_aes_signing_iv_bytes.empty();
+
142  if (aes && (FLAGS_aes_signing_key_bytes.empty() ||
+
143  FLAGS_aes_signing_iv_bytes.empty())) {
+
144  PrintError("--aes_signing_key/iv is required if using aes signing.");
+
145  success = false;
+
146  }
+
147 
+
148  const bool rsa = !FLAGS_rsa_signing_key_path.empty();
+
149 
+
150  if (FLAGS_signer.empty() && (aes || rsa)) {
+
151  PrintError("--signer is required if using aes/rsa signing.");
+
152  success = false;
+
153  }
+
154  if (!FLAGS_signer.empty() && !aes && !rsa) {
+
155  PrintError(
+
156  "--aes_signing_key/iv or --rsa_signing_key_path is required with "
+
157  "--signer.");
+
158  success = false;
+
159  }
+
160  if (aes && rsa) {
+
161  PrintError(
+
162  "Only one of --aes_signing_key/iv and --rsa_signing_key_path should be "
+
163  "specified.");
+
164  success = false;
+
165  }
+
166 
+
167  if (FLAGS_crypto_period_duration < 0) {
+
168  PrintError("--crypto_period_duration should not be negative.");
+
169  success = false;
+
170  }
+
171  return success;
+
172 }
+
173 
+
174 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
+
void PrintError(const std::string &error_message)
+
bool ValidateFlag(const char *flag_name, const FlagType &flag_value, bool condition, bool optional, const char *label)
Definition: validate_flag.h:37
+
bool ValidateWidevineCryptoFlags()
diff --git a/docs/d0/d43/structshaka_1_1Mp4OutputParams.html b/docs/d0/d43/structshaka_1_1Mp4OutputParams.html index ae59a6ee4d..a1cb8c3379 100644 --- a/docs/d0/d43/structshaka_1_1Mp4OutputParams.html +++ b/docs/d0/d43/structshaka_1_1Mp4OutputParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::Mp4OutputParams Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/d46/fourccs_8h_source.html b/docs/d0/d46/fourccs_8h_source.html index 0ea7e5e503..8e3a9d546a 100644 --- a/docs/d0/d46/fourccs_8h_source.html +++ b/docs/d0/d46/fourccs_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/fourccs.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
fourccs.h
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_BASE_FOURCCS_H_
6 #define PACKAGER_MEDIA_BASE_FOURCCS_H_
7 
8 #include <string>
9 
10 namespace shaka {
11 namespace media {
12 
13 enum FourCC : uint32_t {
14  FOURCC_NULL = 0,
15 
16  FOURCC_ID32 = 0x49443332,
17  FOURCC_Head = 0x48656164,
18  FOURCC_Opus = 0x4f707573,
19  FOURCC_PRIV = 0x50524956,
20 
21  FOURCC_aacd = 0x61616364,
22  FOURCC_ac_3 = 0x61632d33, // "ac-3"
23  FOURCC_ac3d = 0x61633364,
24  FOURCC_apad = 0x61706164,
25  FOURCC_av01 = 0x61763031,
26  FOURCC_av1C = 0x61763143,
27  FOURCC_avc1 = 0x61766331,
28  FOURCC_avc3 = 0x61766333,
29  FOURCC_avcC = 0x61766343,
30  FOURCC_bloc = 0x626C6F63,
31  FOURCC_cbc1 = 0x63626331,
32  // This is a fake protection scheme fourcc code to indicate Apple Sample AES.
33  FOURCC_cbca = 0x63626361,
34  FOURCC_cbcs = 0x63626373,
35  FOURCC_cenc = 0x63656e63,
36  FOURCC_cens = 0x63656e73,
37  FOURCC_co64 = 0x636f3634,
38  FOURCC_cmfc = 0x636d6663,
39  FOURCC_cmfs = 0x636d6673,
40  FOURCC_ctim = 0x6374696d,
41  FOURCC_ctts = 0x63747473,
42  FOURCC_dOps = 0x644f7073,
43  FOURCC_dac3 = 0x64616333,
44  FOURCC_dash = 0x64617368,
45  FOURCC_ddts = 0x64647473,
46  FOURCC_dec3 = 0x64656333,
47  FOURCC_dfLa = 0x64664c61,
48  FOURCC_dinf = 0x64696e66,
49  FOURCC_dref = 0x64726566,
50  FOURCC_dtsc = 0x64747363,
51  FOURCC_dtse = 0x64747365,
52  FOURCC_dtsh = 0x64747368,
53  FOURCC_dtsl = 0x6474736c,
54  FOURCC_dtsm = 0x6474732d, // "dts-"
55  FOURCC_dtsp = 0x6474732b, // "dts+"
56  FOURCC_dvcC = 0x64766343,
57  FOURCC_dvh1 = 0x64766831,
58  FOURCC_dvhe = 0x64766865,
59  FOURCC_dvvC = 0x64767643,
60  FOURCC_ec_3 = 0x65632d33, // "ec-3"
61  FOURCC_ec3d = 0x65633364,
62  FOURCC_edts = 0x65647473,
63  FOURCC_elst = 0x656c7374,
64  FOURCC_enca = 0x656e6361,
65  FOURCC_encv = 0x656e6376,
66  FOURCC_esds = 0x65736473,
67  FOURCC_fLaC = 0x664c6143,
68  FOURCC_free = 0x66726565,
69  FOURCC_frma = 0x66726d61,
70  FOURCC_ftyp = 0x66747970,
71  FOURCC_hdlr = 0x68646c72,
72  FOURCC_hev1 = 0x68657631,
73  FOURCC_hint = 0x68696e74,
74  FOURCC_hvc1 = 0x68766331,
75  FOURCC_hvcC = 0x68766343,
76  FOURCC_hvcE = 0x68766345,
77  FOURCC_iden = 0x6964656e,
78  FOURCC_iso6 = 0x69736f36,
79  FOURCC_iso8 = 0x69736f38,
80  FOURCC_isom = 0x69736f6d,
81  FOURCC_iods = 0x696f6473,
82  FOURCC_mdat = 0x6d646174,
83  FOURCC_mdhd = 0x6d646864,
84  FOURCC_mdia = 0x6d646961,
85  FOURCC_meco = 0x6d65636f,
86  FOURCC_mehd = 0x6d656864,
87  FOURCC_meta = 0x6d657461,
88  FOURCC_mfhd = 0x6d666864,
89  FOURCC_mfra = 0x6d667261,
90  FOURCC_minf = 0x6d696e66,
91  FOURCC_moof = 0x6d6f6f66,
92  FOURCC_moov = 0x6d6f6f76,
93  FOURCC_mp41 = 0x6d703431,
94  FOURCC_mp4a = 0x6d703461,
95  FOURCC_mp4v = 0x6d703476,
96  FOURCC_mvex = 0x6d766578,
97  FOURCC_mvhd = 0x6d766864,
98  FOURCC_pasp = 0x70617370,
99  FOURCC_payl = 0x7061796c,
100  FOURCC_pdin = 0x7064696e,
101  FOURCC_prft = 0x70726674,
102  FOURCC_pssh = 0x70737368,
103  FOURCC_roll = 0x726f6c6c,
104  FOURCC_saio = 0x7361696f,
105  FOURCC_saiz = 0x7361697a,
106  FOURCC_sbgp = 0x73626770,
107  FOURCC_schi = 0x73636869,
108  FOURCC_schm = 0x7363686d,
109  FOURCC_sdtp = 0x73647470,
110  FOURCC_seig = 0x73656967,
111  FOURCC_senc = 0x73656e63,
112  FOURCC_sgpd = 0x73677064,
113  FOURCC_sidx = 0x73696478,
114  FOURCC_sinf = 0x73696e66,
115  FOURCC_skip = 0x736b6970,
116  FOURCC_smhd = 0x736d6864,
117  FOURCC_soun = 0x736f756e,
118  FOURCC_ssix = 0x73736978,
119  FOURCC_stbl = 0x7374626c,
120  FOURCC_stco = 0x7374636f,
121  FOURCC_sthd = 0x73746864,
122  FOURCC_stsc = 0x73747363,
123  FOURCC_stsd = 0x73747364,
124  FOURCC_stss = 0x73747373,
125  FOURCC_stsz = 0x7374737a,
126  FOURCC_sttg = 0x73747467,
127  FOURCC_stts = 0x73747473,
128  FOURCC_styp = 0x73747970,
129  FOURCC_stz2 = 0x73747a32,
130  FOURCC_subt = 0x73756274,
131  FOURCC_tenc = 0x74656e63,
132  FOURCC_text = 0x74657874,
133  FOURCC_tfdt = 0x74666474,
134  FOURCC_tfhd = 0x74666864,
135  FOURCC_tkhd = 0x746b6864,
136  FOURCC_traf = 0x74726166,
137  FOURCC_trak = 0x7472616b,
138  FOURCC_trex = 0x74726578,
139  FOURCC_trun = 0x7472756e,
140  FOURCC_udta = 0x75647461,
141  FOURCC_url = 0x75726c20, // "url "
142  FOURCC_urn = 0x75726e20, // "urn "
143  FOURCC_uuid = 0x75756964,
144  FOURCC_vide = 0x76696465,
145  FOURCC_vlab = 0x766c6162,
146  FOURCC_vmhd = 0x766d6864,
147  FOURCC_vp08 = 0x76703038,
148  FOURCC_vp09 = 0x76703039,
149  FOURCC_vpcC = 0x76706343,
150  FOURCC_vsid = 0x76736964,
151  FOURCC_vttC = 0x76747443,
152  FOURCC_vtta = 0x76747461,
153  FOURCC_vttc = 0x76747463,
154  FOURCC_vtte = 0x76747465,
155  FOURCC_wide = 0x77696465,
156  FOURCC_wvtt = 0x77767474,
157  FOURCC_zaac = 0x7A616163,
158  FOURCC_zac3 = 0x7A616333,
159  FOURCC_zach = 0x7A616368,
160  FOURCC_zacp = 0x7A616370,
161  FOURCC_zavc = 0x7A617663,
162  FOURCC_zec3 = 0x7A656333,
163 };
164 
165 const FourCC kAppleSampleAesProtectionScheme = FOURCC_cbca;
166 
167 const inline std::string FourCCToString(FourCC fourcc) {
168  char buf[5];
169  buf[0] = (fourcc >> 24) & 0xff;
170  buf[1] = (fourcc >> 16) & 0xff;
171  buf[2] = (fourcc >> 8) & 0xff;
172  buf[3] = (fourcc) & 0xff;
173  buf[4] = 0;
174  return std::string(buf);
175 }
176 
177 } // namespace media
178 } // namespace shaka
179 
180 #endif // PACKAGER_MEDIA_BASE_FOURCCS_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_BASE_FOURCCS_H_
+
6 #define PACKAGER_MEDIA_BASE_FOURCCS_H_
+
7 
+
8 #include <string>
+
9 
+
10 namespace shaka {
+
11 namespace media {
+
12 
+
13 enum FourCC : uint32_t {
+
14  FOURCC_NULL = 0,
+
15 
+
16  FOURCC_ID32 = 0x49443332,
+
17  FOURCC_Head = 0x48656164,
+
18  FOURCC_Opus = 0x4f707573,
+
19  FOURCC_PRIV = 0x50524956,
+
20 
+
21  FOURCC_aacd = 0x61616364,
+
22  FOURCC_ac_3 = 0x61632d33, // "ac-3"
+
23  FOURCC_ac_4 = 0x61632d34, // "ac-4"
+
24  FOURCC_ac3d = 0x61633364,
+
25  FOURCC_apad = 0x61706164,
+
26  FOURCC_av01 = 0x61763031,
+
27  FOURCC_av1C = 0x61763143,
+
28  FOURCC_avc1 = 0x61766331,
+
29  FOURCC_avc3 = 0x61766333,
+
30  FOURCC_avcC = 0x61766343,
+
31  FOURCC_bloc = 0x626C6F63,
+
32  FOURCC_cbc1 = 0x63626331,
+
33  // This is a fake protection scheme fourcc code to indicate Apple Sample AES.
+
34  FOURCC_cbca = 0x63626361,
+
35  FOURCC_cbcs = 0x63626373,
+
36  FOURCC_cenc = 0x63656e63,
+
37  FOURCC_cens = 0x63656e73,
+
38  FOURCC_co64 = 0x636f3634,
+
39  FOURCC_cmfc = 0x636d6663,
+
40  FOURCC_cmfs = 0x636d6673,
+
41  FOURCC_ctim = 0x6374696d,
+
42  FOURCC_ctts = 0x63747473,
+
43  FOURCC_dOps = 0x644f7073,
+
44  FOURCC_dac3 = 0x64616333,
+
45  FOURCC_dac4 = 0x64616334,
+
46  FOURCC_dash = 0x64617368,
+
47  FOURCC_ddts = 0x64647473,
+
48  FOURCC_dec3 = 0x64656333,
+
49  FOURCC_dfLa = 0x64664c61,
+
50  FOURCC_dinf = 0x64696e66,
+
51  FOURCC_dref = 0x64726566,
+
52  FOURCC_dtsc = 0x64747363,
+
53  FOURCC_dtse = 0x64747365,
+
54  FOURCC_dtsh = 0x64747368,
+
55  FOURCC_dtsl = 0x6474736c,
+
56  FOURCC_dtsm = 0x6474732d, // "dts-"
+
57  FOURCC_dtsp = 0x6474732b, // "dts+"
+
58  FOURCC_dvcC = 0x64766343,
+
59  FOURCC_dvh1 = 0x64766831,
+
60  FOURCC_dvhe = 0x64766865,
+
61  FOURCC_dvvC = 0x64767643,
+
62  FOURCC_ec_3 = 0x65632d33, // "ec-3"
+
63  FOURCC_ec3d = 0x65633364,
+
64  FOURCC_edts = 0x65647473,
+
65  FOURCC_elst = 0x656c7374,
+
66  FOURCC_enca = 0x656e6361,
+
67  FOURCC_encv = 0x656e6376,
+
68  FOURCC_esds = 0x65736473,
+
69  FOURCC_fLaC = 0x664c6143,
+
70  FOURCC_free = 0x66726565,
+
71  FOURCC_frma = 0x66726d61,
+
72  FOURCC_ftyp = 0x66747970,
+
73  FOURCC_hdlr = 0x68646c72,
+
74  FOURCC_hev1 = 0x68657631,
+
75  FOURCC_hint = 0x68696e74,
+
76  FOURCC_hvc1 = 0x68766331,
+
77  FOURCC_hvcC = 0x68766343,
+
78  FOURCC_hvcE = 0x68766345,
+
79  FOURCC_iden = 0x6964656e,
+
80  FOURCC_iso6 = 0x69736f36,
+
81  FOURCC_iso8 = 0x69736f38,
+
82  FOURCC_isom = 0x69736f6d,
+
83  FOURCC_iods = 0x696f6473,
+
84  FOURCC_mdat = 0x6d646174,
+
85  FOURCC_mdhd = 0x6d646864,
+
86  FOURCC_mdia = 0x6d646961,
+
87  FOURCC_meco = 0x6d65636f,
+
88  FOURCC_mehd = 0x6d656864,
+
89  FOURCC_meta = 0x6d657461,
+
90  FOURCC_mfhd = 0x6d666864,
+
91  FOURCC_mfra = 0x6d667261,
+
92  FOURCC_minf = 0x6d696e66,
+
93  FOURCC_moof = 0x6d6f6f66,
+
94  FOURCC_moov = 0x6d6f6f76,
+
95  FOURCC_mp3a = 0x6d703361,
+
96  FOURCC_mp41 = 0x6d703431,
+
97  FOURCC_mp4a = 0x6d703461,
+
98  FOURCC_mp4v = 0x6d703476,
+
99  FOURCC_mvex = 0x6d766578,
+
100  FOURCC_mvhd = 0x6d766864,
+
101  FOURCC_nmhd = 0x6e6d6864,
+
102  FOURCC_pasp = 0x70617370,
+
103  FOURCC_payl = 0x7061796c,
+
104  FOURCC_pdin = 0x7064696e,
+
105  FOURCC_prft = 0x70726674,
+
106  FOURCC_pssh = 0x70737368,
+
107  FOURCC_roll = 0x726f6c6c,
+
108  FOURCC_saio = 0x7361696f,
+
109  FOURCC_saiz = 0x7361697a,
+
110  FOURCC_sbgp = 0x73626770,
+
111  FOURCC_schi = 0x73636869,
+
112  FOURCC_schm = 0x7363686d,
+
113  FOURCC_sdtp = 0x73647470,
+
114  FOURCC_seig = 0x73656967,
+
115  FOURCC_senc = 0x73656e63,
+
116  FOURCC_sgpd = 0x73677064,
+
117  FOURCC_sidx = 0x73696478,
+
118  FOURCC_sinf = 0x73696e66,
+
119  FOURCC_skip = 0x736b6970,
+
120  FOURCC_smhd = 0x736d6864,
+
121  FOURCC_soun = 0x736f756e,
+
122  FOURCC_ssix = 0x73736978,
+
123  FOURCC_stbl = 0x7374626c,
+
124  FOURCC_stco = 0x7374636f,
+
125  FOURCC_sthd = 0x73746864,
+
126  FOURCC_stpp = 0x73747070,
+
127  FOURCC_stsc = 0x73747363,
+
128  FOURCC_stsd = 0x73747364,
+
129  FOURCC_stss = 0x73747373,
+
130  FOURCC_stsz = 0x7374737a,
+
131  FOURCC_sttg = 0x73747467,
+
132  FOURCC_stts = 0x73747473,
+
133  FOURCC_styp = 0x73747970,
+
134  FOURCC_stz2 = 0x73747a32,
+
135  FOURCC_subt = 0x73756274,
+
136  FOURCC_tenc = 0x74656e63,
+
137  FOURCC_text = 0x74657874,
+
138  FOURCC_tfdt = 0x74666474,
+
139  FOURCC_tfhd = 0x74666864,
+
140  FOURCC_tkhd = 0x746b6864,
+
141  FOURCC_traf = 0x74726166,
+
142  FOURCC_trak = 0x7472616b,
+
143  FOURCC_trex = 0x74726578,
+
144  FOURCC_trun = 0x7472756e,
+
145  FOURCC_udta = 0x75647461,
+
146  FOURCC_url = 0x75726c20, // "url "
+
147  FOURCC_urn = 0x75726e20, // "urn "
+
148  FOURCC_uuid = 0x75756964,
+
149  FOURCC_vide = 0x76696465,
+
150  FOURCC_vlab = 0x766c6162,
+
151  FOURCC_vmhd = 0x766d6864,
+
152  FOURCC_vp08 = 0x76703038,
+
153  FOURCC_vp09 = 0x76703039,
+
154  FOURCC_vpcC = 0x76706343,
+
155  FOURCC_vsid = 0x76736964,
+
156  FOURCC_vttC = 0x76747443,
+
157  FOURCC_vtta = 0x76747461,
+
158  FOURCC_vttc = 0x76747463,
+
159  FOURCC_vtte = 0x76747465,
+
160  FOURCC_wide = 0x77696465,
+
161  FOURCC_wvtt = 0x77767474,
+
162  FOURCC_zaac = 0x7A616163,
+
163  FOURCC_zac3 = 0x7A616333,
+
164  FOURCC_zach = 0x7A616368,
+
165  FOURCC_zacp = 0x7A616370,
+
166  FOURCC_zavc = 0x7A617663,
+
167  FOURCC_zec3 = 0x7A656333,
+
168 };
+
169 
+
170 const FourCC kAppleSampleAesProtectionScheme = FOURCC_cbca;
+
171 
+
172 const inline std::string FourCCToString(FourCC fourcc) {
+
173  char buf[5];
+
174  buf[0] = (fourcc >> 24) & 0xff;
+
175  buf[1] = (fourcc >> 16) & 0xff;
+
176  buf[2] = (fourcc >> 8) & 0xff;
+
177  buf[3] = (fourcc) & 0xff;
+
178  buf[4] = 0;
+
179  return std::string(buf);
+
180 }
+
181 
+
182 } // namespace media
+
183 } // namespace shaka
+
184 
+
185 #endif // PACKAGER_MEDIA_BASE_FOURCCS_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d48/structshaka_1_1media_1_1SegmentInfo-members.html b/docs/d0/d48/structshaka_1_1media_1_1SegmentInfo-members.html index 6f69ae887f..20e2c0b61d 100644 --- a/docs/d0/d48/structshaka_1_1media_1_1SegmentInfo-members.html +++ b/docs/d0/d48/structshaka_1_1media_1_1SegmentInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/d49/vod__media__info__dump__muxer__listener_8cc_source.html b/docs/d0/d49/vod__media__info__dump__muxer__listener_8cc_source.html index 0897f33801..48a9e6b9e8 100644 --- a/docs/d0/d49/vod__media__info__dump__muxer__listener_8cc_source.html +++ b/docs/d0/d49/vod__media__info__dump__muxer__listener_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/vod_media_info_dump_muxer_listener.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
vod_media_info_dump_muxer_listener.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/event/vod_media_info_dump_muxer_listener.h"
8 
9 #include <google/protobuf/text_format.h>
10 
11 #include <cmath>
12 
13 #include "packager/base/logging.h"
14 #include "packager/file/file.h"
15 #include "packager/media/base/muxer_options.h"
16 #include "packager/media/base/protection_system_specific_info.h"
17 #include "packager/media/base/stream_info.h"
18 #include "packager/media/event/muxer_listener_internal.h"
19 #include "packager/mpd/base/media_info.pb.h"
20 
21 namespace shaka {
22 namespace media {
23 
24 VodMediaInfoDumpMuxerListener::VodMediaInfoDumpMuxerListener(
25  const std::string& output_file_path)
26  : output_file_name_(output_file_path) {}
27 
28 VodMediaInfoDumpMuxerListener::~VodMediaInfoDumpMuxerListener() {}
29 
31  bool is_initial_encryption_info,
32  FourCC protection_scheme,
33  const std::vector<uint8_t>& default_key_id,
34  const std::vector<uint8_t>& iv,
35  const std::vector<ProtectionSystemSpecificInfo>& key_system_info) {
36  LOG_IF(WARNING, !is_initial_encryption_info)
37  << "Updating (non initial) encryption info is not supported by "
38  "this module.";
39  protection_scheme_ = protection_scheme;
40  default_key_id_ = default_key_id;
41  key_system_info_ = key_system_info;
42  is_encrypted_ = true;
43 }
44 
46  const MuxerOptions& muxer_options,
47  const StreamInfo& stream_info,
48  uint32_t time_scale,
49  ContainerType container_type) {
50  DCHECK(muxer_options.segment_template.empty());
51  media_info_.reset(new MediaInfo());
52  if (!internal::GenerateMediaInfo(muxer_options,
53  stream_info,
54  time_scale,
55  container_type,
56  media_info_.get())) {
57  LOG(ERROR) << "Failed to generate MediaInfo from input.";
58  return;
59  }
60 
61  if (is_encrypted_) {
62  internal::SetContentProtectionFields(protection_scheme_, default_key_id_,
63  key_system_info_, media_info_.get());
64  }
65 }
66 
68 
70  uint32_t sample_duration) {
71  // Assume one VideoInfo.
72  if (media_info_->has_video_info()) {
73  media_info_->mutable_video_info()->set_frame_duration(sample_duration);
74  }
75 }
76 
78  float duration_seconds) {
79  DCHECK(media_info_);
80  if (!internal::SetVodInformation(media_ranges, duration_seconds,
81  media_info_.get())) {
82  LOG(ERROR) << "Failed to generate VOD information from input.";
83  return;
84  }
85  if (!media_info_->has_bandwidth())
86  media_info_->set_bandwidth(max_bitrate_);
87  WriteMediaInfoToFile(*media_info_, output_file_name_);
88 }
89 
90 void VodMediaInfoDumpMuxerListener::OnNewSegment(const std::string& file_name,
91  int64_t start_time,
92  int64_t duration,
93  uint64_t segment_file_size) {
94  const double segment_duration_seconds =
95  static_cast<double>(duration) / media_info_->reference_time_scale();
96 
97  const int kBitsInByte = 8;
98  const uint64_t bitrate =
99  ceil(kBitsInByte * segment_file_size / segment_duration_seconds);
100  max_bitrate_ = std::max(max_bitrate_, bitrate);
101 }
102 
104  uint64_t start_byte_offset,
105  uint64_t size) {}
106 
108  const std::string& cue_data) {
109  NOTIMPLEMENTED();
110 }
111 
112 // static
114  const MediaInfo& media_info,
115  const std::string& output_file_path) {
116  std::string output_string;
117  if (!google::protobuf::TextFormat::PrintToString(media_info,
118  &output_string)) {
119  LOG(ERROR) << "Failed to serialize MediaInfo to string.";
120  return false;
121  }
122 
123  File* file = File::Open(output_file_path.c_str(), "w");
124  if (!file) {
125  LOG(ERROR) << "Failed to open " << output_file_path;
126  return false;
127  }
128  if (file->Write(output_string.data(), output_string.size()) <= 0) {
129  LOG(ERROR) << "Failed to write MediaInfo to file.";
130  file->Close();
131  return false;
132  }
133  if (!file->Close()) {
134  LOG(ERROR) << "Failed to close " << output_file_path;
135  return false;
136  }
137  return true;
138 }
139 
140 } // namespace media
141 } // namespace shaka
virtual int64_t Write(const void *buffer, uint64_t length)=0
-
Abstract class holds stream information.
Definition: stream_info.h:62
-
void OnSampleDurationReady(uint32_t sample_duration) override
-
void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
-
Define an abstract file interface.
Definition: file.h:26
-
All the methods that are virtual are virtual for mocking.
- -
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
-
void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
-
virtual bool Close()=0
-
static bool WriteMediaInfoToFile(const MediaInfo &media_info, const std::string &output_file_path)
- -
void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
-
void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
-
virtual bool Open()=0
Internal open. Should not be used directly.
-
void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
-
void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &default_key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
- +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/event/vod_media_info_dump_muxer_listener.h"
+
8 
+
9 #include <google/protobuf/text_format.h>
+
10 
+
11 #include <cmath>
+
12 
+
13 #include "packager/base/logging.h"
+
14 #include "packager/file/file.h"
+
15 #include "packager/media/base/muxer_options.h"
+
16 #include "packager/media/base/protection_system_specific_info.h"
+
17 #include "packager/media/base/stream_info.h"
+
18 #include "packager/media/event/muxer_listener_internal.h"
+
19 #include "packager/mpd/base/media_info.pb.h"
+
20 
+
21 namespace shaka {
+
22 namespace media {
+
23 
+
24 VodMediaInfoDumpMuxerListener::VodMediaInfoDumpMuxerListener(
+
25  const std::string& output_file_path)
+
26  : output_file_name_(output_file_path) {}
+
27 
+
28 VodMediaInfoDumpMuxerListener::~VodMediaInfoDumpMuxerListener() {}
+
29 
+
30 void VodMediaInfoDumpMuxerListener::OnEncryptionInfoReady(
+
31  bool is_initial_encryption_info,
+
32  FourCC protection_scheme,
+
33  const std::vector<uint8_t>& default_key_id,
+
34  const std::vector<uint8_t>& iv,
+
35  const std::vector<ProtectionSystemSpecificInfo>& key_system_info) {
+
36  LOG_IF(WARNING, !is_initial_encryption_info)
+
37  << "Updating (non initial) encryption info is not supported by "
+
38  "this module.";
+
39  protection_scheme_ = protection_scheme;
+
40  default_key_id_ = default_key_id;
+
41  key_system_info_ = key_system_info;
+
42  is_encrypted_ = true;
+
43 }
+
44 
+
45 void VodMediaInfoDumpMuxerListener::OnMediaStart(
+
46  const MuxerOptions& muxer_options,
+
47  const StreamInfo& stream_info,
+
48  uint32_t time_scale,
+
49  ContainerType container_type) {
+
50  DCHECK(muxer_options.segment_template.empty());
+
51  media_info_.reset(new MediaInfo());
+
52  if (!internal::GenerateMediaInfo(muxer_options,
+
53  stream_info,
+
54  time_scale,
+
55  container_type,
+
56  media_info_.get())) {
+
57  LOG(ERROR) << "Failed to generate MediaInfo from input.";
+
58  return;
+
59  }
+
60 
+
61  if (is_encrypted_) {
+
62  internal::SetContentProtectionFields(protection_scheme_, default_key_id_,
+
63  key_system_info_, media_info_.get());
+
64  }
+
65 }
+
66 
+
67 void VodMediaInfoDumpMuxerListener::OnEncryptionStart() {}
+
68 
+
69 void VodMediaInfoDumpMuxerListener::OnSampleDurationReady(
+
70  uint32_t sample_duration) {
+
71  // Assume one VideoInfo.
+
72  if (media_info_->has_video_info()) {
+
73  media_info_->mutable_video_info()->set_frame_duration(sample_duration);
+
74  }
+
75 }
+
76 
+
77 void VodMediaInfoDumpMuxerListener::OnMediaEnd(const MediaRanges& media_ranges,
+
78  float duration_seconds) {
+
79  DCHECK(media_info_);
+
80  if (!internal::SetVodInformation(media_ranges, duration_seconds,
+
81  media_info_.get())) {
+
82  LOG(ERROR) << "Failed to generate VOD information from input.";
+
83  return;
+
84  }
+
85  if (!media_info_->has_bandwidth())
+
86  media_info_->set_bandwidth(max_bitrate_);
+
87  WriteMediaInfoToFile(*media_info_, output_file_name_);
+
88 }
+
89 
+
90 void VodMediaInfoDumpMuxerListener::OnNewSegment(const std::string& file_name,
+
91  int64_t start_time,
+
92  int64_t duration,
+
93  uint64_t segment_file_size) {
+
94  const double segment_duration_seconds =
+
95  static_cast<double>(duration) / media_info_->reference_time_scale();
+
96 
+
97  const int kBitsInByte = 8;
+
98  const uint64_t bitrate =
+
99  ceil(kBitsInByte * segment_file_size / segment_duration_seconds);
+
100  max_bitrate_ = std::max(max_bitrate_, bitrate);
+
101 }
+
102 
+
103 void VodMediaInfoDumpMuxerListener::OnKeyFrame(int64_t timestamp,
+
104  uint64_t start_byte_offset,
+
105  uint64_t size) {}
+
106 
+
107 void VodMediaInfoDumpMuxerListener::OnCueEvent(int64_t timestamp,
+
108  const std::string& cue_data) {
+
109  NOTIMPLEMENTED();
+
110 }
+
111 
+
112 // static
+
113 bool VodMediaInfoDumpMuxerListener::WriteMediaInfoToFile(
+
114  const MediaInfo& media_info,
+
115  const std::string& output_file_path) {
+
116  std::string output_string;
+
117  if (!google::protobuf::TextFormat::PrintToString(media_info,
+
118  &output_string)) {
+
119  LOG(ERROR) << "Failed to serialize MediaInfo to string.";
+
120  return false;
+
121  }
+
122 
+
123  File* file = File::Open(output_file_path.c_str(), "w");
+
124  if (!file) {
+
125  LOG(ERROR) << "Failed to open " << output_file_path;
+
126  return false;
+
127  }
+
128  if (file->Write(output_string.data(), output_string.size()) <= 0) {
+
129  LOG(ERROR) << "Failed to write MediaInfo to file.";
+
130  file->Close();
+
131  return false;
+
132  }
+
133  if (!file->Close()) {
+
134  LOG(ERROR) << "Failed to close " << output_file_path;
+
135  return false;
+
136  }
+
137  return true;
+
138 }
+
139 
+
140 } // namespace media
+
141 } // namespace shaka
+
Define an abstract file interface.
Definition: file.h:27
+
virtual int64_t Write(const void *buffer, uint64_t length)=0
+
virtual bool Close()=0
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
All the methods that are virtual are virtual for mocking.
+ +
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+
diff --git a/docs/d0/d4b/structshaka_1_1media_1_1mp4_1_1MediaInformation-members.html b/docs/d0/d4b/structshaka_1_1media_1_1mp4_1_1MediaInformation-members.html index 9b932a4f51..8553b0c85b 100644 --- a/docs/d0/d4b/structshaka_1_1media_1_1mp4_1_1MediaInformation-members.html +++ b/docs/d0/d4b/structshaka_1_1media_1_1mp4_1_1MediaInformation-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
dinf (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation HeaderSize() constshaka::media::mp4::Boxvirtual MediaInformation() (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation - Parse(BoxReader *reader)shaka::media::mp4::Box - ReadWriteHeaderInternal(BoxBuffer *buffer)shaka::media::mp4::Boxprotectedvirtual - sample_table (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation - smhd (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation - sthd (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation - vmhd (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation - Write(BufferWriter *writer)shaka::media::mp4::Box - WriteHeader(BufferWriter *writer)shaka::media::mp4::Box - ~ MediaInformation() override (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation - ~Box() (defined in shaka::media::mp4::Box)shaka::media::mp4::Boxvirtual + nmhd (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation + Parse(BoxReader *reader)shaka::media::mp4::Box + ReadWriteHeaderInternal(BoxBuffer *buffer)shaka::media::mp4::Boxprotectedvirtual + sample_table (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation + smhd (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation + sthd (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation + vmhd (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation + Write(BufferWriter *writer)shaka::media::mp4::Box + WriteHeader(BufferWriter *writer)shaka::media::mp4::Box + ~ MediaInformation() override (defined in shaka::media::mp4::MediaInformation)shaka::media::mp4::MediaInformation + ~Box() (defined in shaka::media::mp4::Box)shaka::media::mp4::Boxvirtual
diff --git a/docs/d0/d4c/structshaka_1_1media_1_1StreamData.html b/docs/d0/d4c/structshaka_1_1media_1_1StreamData.html index 86ec3fd84e..0a95a5c716 100644 --- a/docs/d0/d4c/structshaka_1_1media_1_1StreamData.html +++ b/docs/d0/d4c/structshaka_1_1media_1_1StreamData.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::StreamData Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d0/d4d/classshaka_1_1media_1_1AudioTimestampHelper.html b/docs/d0/d4d/classshaka_1_1media_1_1AudioTimestampHelper.html index 574d47763e..bf2cfa7573 100644 --- a/docs/d0/d4d/classshaka_1_1media_1_1AudioTimestampHelper.html +++ b/docs/d0/d4d/classshaka_1_1media_1_1AudioTimestampHelper.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AudioTimestampHelper Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
GetFramesToTarget<
diff --git a/docs/d0/d4e/libcrypto__threading_8cc_source.html b/docs/d0/d4e/libcrypto__threading_8cc_source.html index 6b3fd5bce2..6593a74f5a 100644 --- a/docs/d0/d4e/libcrypto__threading_8cc_source.html +++ b/docs/d0/d4e/libcrypto__threading_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/libcrypto_threading.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
libcrypto_threading.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/libcrypto_threading.h"
8 
9 #include <openssl/thread.h>
10 
11 #include <memory>
12 
13 #include "packager/base/logging.h"
14 #include "packager/base/synchronization/lock.h"
15 #include "packager/base/threading/platform_thread.h"
16 
17 namespace shaka {
18 namespace media {
19 
20 namespace {
21 
22 std::unique_ptr<base::Lock[]> global_locks;
23 
24 void LockFunction(int mode, int n, const char* file, int line) {
25  VLOG(2) << "CryptoLock @ " << file << ":" << line;
26  if (mode & CRYPTO_LOCK)
27  global_locks[n].Acquire();
28  else
29  global_locks[n].Release();
30 }
31 
32 void ThreadIdFunction(CRYPTO_THREADID* id) {
33  CRYPTO_THREADID_set_numeric(
34  id, static_cast<unsigned long>(base::PlatformThread::CurrentId()));
35 }
36 
37 } // namespace
38 
39 LibcryptoThreading::LibcryptoThreading() {
40  global_locks.reset(new base::Lock[CRYPTO_num_locks()]);
41  CRYPTO_THREADID_set_callback(ThreadIdFunction);
42  CRYPTO_set_locking_callback(LockFunction);
43 }
44 
45 LibcryptoThreading::~LibcryptoThreading() {
46  CRYPTO_THREADID_set_callback(NULL);
47  CRYPTO_set_locking_callback(NULL);
48  global_locks.reset();
49 }
50 
51 } // namespace media
52 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/app/libcrypto_threading.h"
+
8 
+
9 #include <openssl/thread.h>
+
10 
+
11 #include <memory>
+
12 
+
13 #include "packager/base/logging.h"
+
14 #include "packager/base/synchronization/lock.h"
+
15 #include "packager/base/threading/platform_thread.h"
+
16 
+
17 namespace shaka {
+
18 namespace media {
+
19 
+
20 namespace {
+
21 
+
22 std::unique_ptr<base::Lock[]> global_locks;
+
23 
+
24 void LockFunction(int mode, int n, const char* file, int line) {
+
25  VLOG(2) << "CryptoLock @ " << file << ":" << line;
+
26  if (mode & CRYPTO_LOCK)
+
27  global_locks[n].Acquire();
+
28  else
+
29  global_locks[n].Release();
+
30 }
+
31 
+
32 void ThreadIdFunction(CRYPTO_THREADID* id) {
+
33  CRYPTO_THREADID_set_numeric(
+
34  id, static_cast<unsigned long>(base::PlatformThread::CurrentId()));
+
35 }
+
36 
+
37 } // namespace
+
38 
+
39 LibcryptoThreading::LibcryptoThreading() {
+
40  global_locks.reset(new base::Lock[CRYPTO_num_locks()]);
+
41  CRYPTO_THREADID_set_callback(ThreadIdFunction);
+
42  CRYPTO_set_locking_callback(LockFunction);
+
43 }
+
44 
+
45 LibcryptoThreading::~LibcryptoThreading() {
+
46  CRYPTO_THREADID_set_callback(NULL);
+
47  CRYPTO_set_locking_callback(NULL);
+
48  global_locks.reset();
+
49 }
+
50 
+
51 } // namespace media
+
52 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d53/classshaka_1_1media_1_1mp2t_1_1TsMuxer-members.html b/docs/d0/d53/classshaka_1_1media_1_1mp2t_1_1TsMuxer-members.html index 57750fd204..b4a4e14cc0 100644 --- a/docs/d0/d53/classshaka_1_1media_1_1mp2t_1_1TsMuxer-members.html +++ b/docs/d0/d53/classshaka_1_1media_1_1mp2t_1_1TsMuxer-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline Cancel()shaka::media::Muxer - Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic + Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic clock() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected @@ -109,9 +112,7 @@ $(function() {
diff --git a/docs/d0/d53/dovi__decoder__configuration__record_8h_source.html b/docs/d0/d53/dovi__decoder__configuration__record_8h_source.html index 3e3ab55aaa..9e8613e1e7 100644 --- a/docs/d0/d53/dovi__decoder__configuration__record_8h_source.html +++ b/docs/d0/d53/dovi__decoder__configuration__record_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/dovi_decoder_configuration_record.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
dovi_decoder_configuration_record.h
-
1 // Copyright 2019 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CODECS_DOVI_DECODER_CONFIGURATION_RECORD_H_
8 #define PACKAGER_MEDIA_CODECS_DOVI_DECODER_CONFIGURATION_RECORD_H_
9 
10 #include <stdint.h>
11 #include <string>
12 #include <vector>
13 
14 #include "packager/media/base/fourccs.h"
15 
16 namespace shaka {
17 namespace media {
18 
20 // Implemented according to Dolby Vision Streams Within the ISO Base Media File
21 // Format Version 2.0:
22 // https://www.dolby.com/us/en/technologies/dolby-vision/dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.0.pdf
23 // and Dolby Vision Streams within the HTTP Live Streaming format Version 2.0:
24 // https://www.dolby.com/us/en/technologies/dolby-vision/dolby-vision-streams-within-the-http-live-streaming-format-v2.0.pdf
26  public:
28  ~DOVIDecoderConfigurationRecord() = default;
29 
32  bool Parse(const std::vector<uint8_t>& data);
33 
36  std::string GetCodecString(FourCC codec_fourcc) const;
37 
38  private:
40  delete;
42  const DOVIDecoderConfigurationRecord&) = delete;
43 
44  uint8_t profile_ = 0;
45  uint8_t level_ = 0;
46 };
47 
48 } // namespace media
49 } // namespace shaka
50 
51 #endif // PACKAGER_MEDIA_CODECS_DOVI_DECODER_CONFIGURATION_RECORD_H_
-
All the methods that are virtual are virtual for mocking.
-
Class for parsing Dolby Vision decoder configuration record.
- +
1 // Copyright 2019 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_DOVI_DECODER_CONFIGURATION_RECORD_H_
+
8 #define PACKAGER_MEDIA_CODECS_DOVI_DECODER_CONFIGURATION_RECORD_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/media/base/fourccs.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+
20 // Implemented according to Dolby Vision Streams Within the ISO Base Media File
+
21 // Format Version 2.0:
+
22 // https://www.dolby.com/us/en/technologies/dolby-vision/dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.0.pdf
+
23 // and Dolby Vision Streams within the HTTP Live Streaming format Version 2.0:
+
24 // https://www.dolby.com/us/en/technologies/dolby-vision/dolby-vision-streams-within-the-http-live-streaming-format-v2.0.pdf
+ +
26  public:
+ +
28  ~DOVIDecoderConfigurationRecord() = default;
+
29 
+
32  bool Parse(const std::vector<uint8_t>& data);
+
33 
+
36  std::string GetCodecString(FourCC codec_fourcc) const;
+
37 
+
38  private:
+ +
40  delete;
+ +
42  const DOVIDecoderConfigurationRecord&) = delete;
+
43 
+
44  uint8_t profile_ = 0;
+
45  uint8_t level_ = 0;
+
46 };
+
47 
+
48 } // namespace media
+
49 } // namespace shaka
+
50 
+
51 #endif // PACKAGER_MEDIA_CODECS_DOVI_DECODER_CONFIGURATION_RECORD_H_
+
Class for parsing Dolby Vision decoder configuration record.
+ + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d59/classshaka_1_1media_1_1Job.html b/docs/d0/d59/classshaka_1_1media_1_1Job.html index 40634fdabc..f7485d1d58 100644 --- a/docs/d0/d59/classshaka_1_1media_1_1Job.html +++ b/docs/d0/d59/classshaka_1_1media_1_1Job.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::Job Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
- - - +

@@ -103,9 +104,7 @@ base::WaitableEvent * 

wait diff --git a/docs/d0/d59/classshaka_1_1media_1_1Job.png b/docs/d0/d59/classshaka_1_1media_1_1Job.png index 461be44c1285edb3df819a65b7779d3736bdc4c6..b2954dd313b6ce96c5e1d1f41147c4eeb58d4e4e 100644 GIT binary patch delta 513 zcmeBY*}$UM8Q|y6%O%Cdz`(%k>ERLtq^p29fP)!GKHM;|ZK9%e{eDju$B+ufw{uVC zwHOGv#K$lD_rIUHB0eHb=%(^fA=M3;-(T~dn=$jOpqi)gmJ5?i0`52L>raqBwJ-6` zr^VHebp+%W^EdAc-B+Dh)@N6Ai@AJzPT-IG@7$x-F>Mq$cxCb5pNBV;-B~c#{Qb(! zAMVXDey=FowYHPlS8E+#bM}YH>(6oV3(i;Rp7e_SX2qLSBftO29??llU*{b9 zoRD?gG-}elYwQ2DaO-+9Zw0xy_+naGFw2LXaSX*K{C}%_lg~TnKZ$(P`J&#c{vkK7 zK@boJV8`JHc{shXC#zVi3~QrtD$Th4EG>D}H#Z!CW;>5-l9oBjUc^}Tsq^NRYqC*7X? tq3Vvjuf+iaU6TV2Abi$!_DtW4{44*u@w&a4bPgD+44$rjF6*2UngDID>l^?8 delta 480 zcmdnM($AvU8Q|y6%O%Cdz`(%k>ERLtr1OC|fP)!GDwyBany6@9KhM*}F{Fa=?cCda zhZT5S`s1zs|37}aW%kY`zTq9~!aRC7Qa&7f@I=yhbL%0M%$a8Xlb*fw|IlY;W#zeQ z>hh$my*A3fz3*8X^F2wAzfpIP`|nJL6Q;{$CY|47z;*1$oL#f`NGQ2@_AlN0WoPZQ z`xDAb>nE+b_WXPJKKtwIUR{2_;7a-$Q_oc;-~SuE*56V&$;5xQy65LFtn+5xv|{|@ z#^2Byb*9?p8k6|vc{`RKxVoo4e*SEBgFqnm$A;^Hf)i%mbV_76y`_@j^Ow{(-u*kL zF3)|UQ~d6&ik!o0^F7a(7xJC|_;KNr-uA}N)~6rJ-w;wgdUCyyzK+$i%b&h%n$Ubu zur2#l$GMB2yxydom;T0|`$OttZ1&5x=QGbQ{BUT&Q&;cOH}gNV?fzE%;&V3t?oE3i z#?HB<5KtcbzS6Au_v>?;Q>L?<=7h}8-57UW{Qy(0+yNU9u5CFVdQ&MBb@05=Tn8~^|S diff --git a/docs/d0/d5b/classshaka_1_1media_1_1MpdNotifyMuxerListener-members.html b/docs/d0/d5b/classshaka_1_1media_1_1MpdNotifyMuxerListener-members.html index 608dc148df..cbec6792a7 100644 --- a/docs/d0/d5b/classshaka_1_1media_1_1MpdNotifyMuxerListener-members.html +++ b/docs/d0/d5b/classshaka_1_1media_1_1MpdNotifyMuxerListener-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/d65/ad__cue__generator__flags_8cc_source.html b/docs/d0/d65/ad__cue__generator__flags_8cc_source.html index 6269f0eaea..a036221d56 100644 --- a/docs/d0/d65/ad__cue__generator__flags_8cc_source.html +++ b/docs/d0/d65/ad__cue__generator__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/ad_cue_generator_flags.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
ad_cue_generator_flags.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines cuepoint generator flags.
8 
9 #include "packager/app/ad_cue_generator_flags.h"
10 
11 DEFINE_string(ad_cues,
12  "",
13  "List of cuepoint markers."
14  "This flag accepts semicolon separated pairs and components in "
15  "the pair are separated by a comma and the second component "
16  "duration is optional. For example --ad_cues "
17  "{start_time}[,{duration}][;{start_time}[,{duration}]]..."
18  "The start_time represents the start of the cue marker in "
19  "seconds relative to the start of the program.");
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines cuepoint generator flags.
+
8 
+
9 #include "packager/app/ad_cue_generator_flags.h"
+
10 
+
11 DEFINE_string(ad_cues,
+
12  "",
+
13  "List of cuepoint markers."
+
14  "This flag accepts semicolon separated pairs and components in "
+
15  "the pair are separated by a comma and the second component "
+
16  "duration is optional. For example --ad_cues "
+
17  "{start_time}[,{duration}][;{start_time}[,{duration}]]..."
+
18  "The start_time represents the start of the cue marker in "
+
19  "seconds relative to the start of the program.");
+
diff --git a/docs/d0/d6c/classshaka_1_1media_1_1mp2t_1_1EsParserDvb.html b/docs/d0/d6c/classshaka_1_1media_1_1mp2t_1_1EsParserDvb.html new file mode 100644 index 0000000000..8a922ffd8a --- /dev/null +++ b/docs/d0/d6c/classshaka_1_1media_1_1mp2t_1_1EsParserDvb.html @@ -0,0 +1,133 @@ + + + + + + + +Shaka Packager SDK: shaka::media::mp2t::EsParserDvb Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::mp2t::EsParserDvb Class Reference
+
+
+
+Inheritance diagram for shaka::media::mp2t::EsParserDvb:
+
+
+ + +shaka::media::mp2t::EsParser + +
+ + + + + + + + + + + + + + + +

+Public Member Functions

EsParserDvb (uint32_t pid, const NewStreamInfoCB &new_stream_info_cb, const EmitTextSampleCB &emit_sample_cb, const uint8_t *descriptor, size_t descriptor_length)
 
+bool Parse (const uint8_t *buf, int size, int64_t pts, int64_t dts) override
 
+bool Flush () override
 
+void Reset () override
 
- Public Member Functions inherited from shaka::media::mp2t::EsParser
EsParser (uint32_t pid)
 
+uint32_t pid ()
 
+ + + + + + + + +

+Additional Inherited Members

- Public Types inherited from shaka::media::mp2t::EsParser
+typedef base::Callback< void(std::shared_ptr< StreamInfo >)> NewStreamInfoCB
 
+typedef base::Callback< void(std::shared_ptr< MediaSample >)> EmitSampleCB
 
+typedef base::Callback< void(std::shared_ptr< TextSample >)> EmitTextSampleCB
 
+

Detailed Description

+
+

Definition at line 21 of file es_parser_dvb.h.

+

The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/d0/d6c/classshaka_1_1media_1_1mp2t_1_1EsParserDvb.png b/docs/d0/d6c/classshaka_1_1media_1_1mp2t_1_1EsParserDvb.png new file mode 100644 index 0000000000000000000000000000000000000000..bc03193dbb26b343f50a2fb49759a34f44b9709f GIT binary patch literal 820 zcmeAS@N?(olHy`uVBq!ia0vp^M}atigBeK9^K~==QW60^A+G=b{|7Q(y!l$%e`o@b z1;z&s9ANFdBM;lCmT&#vi-|%pnQ;v#_MSz>uSH4xlLCRd#&N6clTd1*H;dY$lxaiI=&M5 zr}v(p&RQ)=rbe?FeieO@r(+TFj$+MmjPcwZa#_%!peeV+a*J72df zTH>{N8{dlO-@`04ib5ZoeWnx>^=lCCszP5D5-_YHO1r0pE7Pal%U~^ym>@;4@S$dh)AOFjQmMQVu zIKA)5I`l|#>YwTN(^p^VGfH1zy;$YsYySVc@BcTRyu=&m?=Nlpnw=)uEpb)!EY1Lh zMO8q~?QM5s8RW0=A9(v!RK(u?e#1vm5&jPS13&n>O5GUGEOKQuXcuEW01P$;pdN-Z z3keCt1ac_eiDPL1hBj2S7FU0X;0M8PMxQGCW^Aa~bVKk!KBj7Ixb`0_F1=XJ^Fd)=uRs+# + - + Shaka Packager SDK: shaka::media::mp4::VideoSampleEntry Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -145,7 +148,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 277 of file box_definitions.h.

+

Definition at line 278 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -173,7 +176,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 1465 of file box_definitions.cc.

+

Definition at line 1491 of file box_definitions.cc.

@@ -184,9 +187,7 @@ Additional Inherited Members diff --git a/docs/d0/d73/webvtt__muxer_8h_source.html b/docs/d0/d73/webvtt__muxer_8h_source.html new file mode 100644 index 0000000000..cb88d5f957 --- /dev/null +++ b/docs/d0/d73/webvtt__muxer_8h_source.html @@ -0,0 +1,123 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/webvtt/webvtt_muxer.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
webvtt_muxer.h
+
+
+
1 // Copyright 2020 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MUXER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MUXER_H_
+
9 
+
10 #include <memory>
+
11 
+
12 #include "packager/media/base/text_muxer.h"
+
13 #include "packager/media/formats/webvtt/webvtt_file_buffer.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 namespace webvtt {
+
18 
+
20 class WebVttMuxer : public TextMuxer {
+
21  public:
+
23  explicit WebVttMuxer(const MuxerOptions& options);
+
24  ~WebVttMuxer() override;
+
25 
+
26  private:
+
27  // TextMuxer implementation overrides.
+
28  Status InitializeStream(TextStreamInfo* stream) override;
+
29  Status AddTextSampleInternal(const TextSample& sample) override;
+
30  Status WriteToFile(const std::string& filename, uint64_t* size) override;
+
31 
+
32  std::unique_ptr<WebVttFileBuffer> buffer_;
+
33 };
+
34 
+
35 } // namespace webvtt
+
36 } // namespace media
+
37 } // namespace shaka
+
38 
+
39 #endif // PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MUXER_H_
+ + + + +
Implements WebVtt Muxer.
Definition: webvtt_muxer.h:20
+
WebVttMuxer(const MuxerOptions &options)
Create a WebMMuxer object from MuxerOptions.
Definition: webvtt_muxer.cc:18
+
All the methods that are virtual are virtual for mocking.
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+
+ + + + diff --git a/docs/d0/d7b/structshaka_1_1media_1_1TextFragment-members.html b/docs/d0/d7b/structshaka_1_1media_1_1TextFragment-members.html new file mode 100644 index 0000000000..ff53edf82e --- /dev/null +++ b/docs/d0/d7b/structshaka_1_1media_1_1TextFragment-members.html @@ -0,0 +1,93 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::TextFragment Member List
+
+
+ +

This is the complete list of members for shaka::media::TextFragment, including all inherited members.

+ + + + + + + + + + + + + +
body (defined in shaka::media::TextFragment)shaka::media::TextFragment
imageshaka::media::TextFragment
is_empty() const (defined in shaka::media::TextFragment)shaka::media::TextFragment
newline (defined in shaka::media::TextFragment)shaka::media::TextFragment
style (defined in shaka::media::TextFragment)shaka::media::TextFragment
sub_fragments (defined in shaka::media::TextFragment)shaka::media::TextFragment
TextFragment() (defined in shaka::media::TextFragment)shaka::media::TextFragmentinline
TextFragment(const TextFragmentStyle &style, const std::vector< TextFragment > &sub_fragments) (defined in shaka::media::TextFragment)shaka::media::TextFragmentinline
TextFragment(const TextFragmentStyle &style, const char *body) (defined in shaka::media::TextFragment)shaka::media::TextFragmentinline
TextFragment(const TextFragmentStyle &style, const std::string &body) (defined in shaka::media::TextFragment)shaka::media::TextFragmentinline
TextFragment(const TextFragmentStyle &style, const std::vector< uint8_t > &image) (defined in shaka::media::TextFragment)shaka::media::TextFragmentinline
TextFragment(const TextFragmentStyle &style, bool newline) (defined in shaka::media::TextFragment)shaka::media::TextFragmentinline
+ + + + diff --git a/docs/d0/d7c/structshaka_1_1media_1_1mp4_1_1SampleToGroup.html b/docs/d0/d7c/structshaka_1_1media_1_1mp4_1_1SampleToGroup.html index 10843a7bc1..47ffbf0abe 100644 --- a/docs/d0/d7c/structshaka_1_1media_1_1mp4_1_1SampleToGroup.html +++ b/docs/d0/d7c/structshaka_1_1media_1_1mp4_1_1SampleToGroup.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleToGroup Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -127,7 +130,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 543 of file box_definitions.h.

+

Definition at line 556 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -155,7 +158,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 1098 of file box_definitions.cc.

+

Definition at line 1116 of file box_definitions.cc.

@@ -166,9 +169,7 @@ Additional Inherited Members diff --git a/docs/d0/d7d/decryptor__source_8h_source.html b/docs/d0/d7d/decryptor__source_8h_source.html index c751b33401..55b3b5a719 100644 --- a/docs/d0/d7d/decryptor__source_8h_source.html +++ b/docs/d0/d7d/decryptor__source_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/decryptor_source.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
decryptor_source.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_DECRYPTOR_SOURCE_H_
8 #define PACKAGER_MEDIA_BASE_DECRYPTOR_SOURCE_H_
9 
10 #include <map>
11 #include <memory>
12 #include <vector>
13 
14 #include "packager/media/base/aes_decryptor.h"
15 #include "packager/media/base/decrypt_config.h"
16 #include "packager/media/base/key_source.h"
17 
18 namespace shaka {
19 namespace media {
20 
23  public:
26  explicit DecryptorSource(KeySource* key_source);
27  ~DecryptorSource();
28 
38  bool DecryptSampleBuffer(const DecryptConfig* decrypt_config,
39  const uint8_t* encrypted_buffer,
40  size_t buffer_size,
41  uint8_t* decrypted_buffer);
42 
43  private:
44  KeySource* key_source_;
45  std::map<std::vector<uint8_t>, std::unique_ptr<AesCryptor>> decryptor_map_;
46 
47  DISALLOW_COPY_AND_ASSIGN(DecryptorSource);
48 };
49 
50 } // namespace media
51 } // namespace shaka
52 
53 #endif // PACKAGER_MEDIA_BASE_DECRYPTOR_SOURCE_H_
DecryptorSource(KeySource *key_source)
- -
bool DecryptSampleBuffer(const DecryptConfig *decrypt_config, const uint8_t *encrypted_buffer, size_t buffer_size, uint8_t *decrypted_buffer)
-
All the methods that are virtual are virtual for mocking.
-
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:48
-
DecryptorSource wraps KeySource and is responsible for decryptor management.
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_DECRYPTOR_SOURCE_H_
+
8 #define PACKAGER_MEDIA_BASE_DECRYPTOR_SOURCE_H_
+
9 
+
10 #include <map>
+
11 #include <memory>
+
12 #include <vector>
+
13 
+
14 #include "packager/media/base/aes_decryptor.h"
+
15 #include "packager/media/base/decrypt_config.h"
+
16 #include "packager/media/base/key_source.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 
+ +
23  public:
+
26  explicit DecryptorSource(KeySource* key_source);
+
27  ~DecryptorSource();
+
28 
+
38  bool DecryptSampleBuffer(const DecryptConfig* decrypt_config,
+
39  const uint8_t* encrypted_buffer,
+
40  size_t buffer_size,
+
41  uint8_t* decrypted_buffer);
+
42 
+
43  private:
+
44  KeySource* key_source_;
+
45  std::map<std::vector<uint8_t>, std::unique_ptr<AesCryptor>> decryptor_map_;
+
46 
+
47  DISALLOW_COPY_AND_ASSIGN(DecryptorSource);
+
48 };
+
49 
+
50 } // namespace media
+
51 } // namespace shaka
+
52 
+
53 #endif // PACKAGER_MEDIA_BASE_DECRYPTOR_SOURCE_H_
+ +
DecryptorSource wraps KeySource and is responsible for decryptor management.
+
DecryptorSource(KeySource *key_source)
+
bool DecryptSampleBuffer(const DecryptConfig *decrypt_config, const uint8_t *encrypted_buffer, size_t buffer_size, uint8_t *decrypted_buffer)
+
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:51
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/d80/classshaka_1_1media_1_1AesCbcEncryptor-members.html b/docs/d0/d80/classshaka_1_1media_1_1AesCbcEncryptor-members.html index 4d117f5da5..75333ed517 100644 --- a/docs/d0/d80/classshaka_1_1media_1_1AesCbcEncryptor-members.html +++ b/docs/d0/d80/classshaka_1_1media_1_1AesCbcEncryptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/d86/structshaka_1_1media_1_1ProtectionSystemSpecificInfo.html b/docs/d0/d86/structshaka_1_1media_1_1ProtectionSystemSpecificInfo.html index 4e26314e84..29e3e0a8dd 100644 --- a/docs/d0/d86/structshaka_1_1media_1_1ProtectionSystemSpecificInfo.html +++ b/docs/d0/d86/structshaka_1_1media_1_1ProtectionSystemSpecificInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ProtectionSystemSpecificInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Detailed Description

-

Definition at line 26 of file protection_system_specific_info.h.

+

Definition at line 20 of file protection_system_specific_info.h.

Member Function Documentation

◆ ParseBoxes()

@@ -141,9 +144,7 @@ std::vector< uint8_t > 
diff --git a/docs/d0/d9a/structshaka_1_1media_1_1mp4_1_1Movie.html b/docs/d0/d9a/structshaka_1_1media_1_1mp4_1_1Movie.html index b6c6d63924..3339efa318 100644 --- a/docs/d0/d9a/structshaka_1_1media_1_1mp4_1_1Movie.html +++ b/docs/d0/d9a/structshaka_1_1media_1_1mp4_1_1Movie.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Movie Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -124,7 +127,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 667 of file box_definitions.h.

+

Definition at line 685 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -152,7 +155,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2311 of file box_definitions.cc.

+

Definition at line 2392 of file box_definitions.cc.

@@ -163,9 +166,7 @@ Additional Inherited Members diff --git a/docs/d0/d9f/classshaka_1_1media_1_1SubsampleGenerator.html b/docs/d0/d9f/classshaka_1_1media_1_1SubsampleGenerator.html index b5b2943b35..1f12807583 100644 --- a/docs/d0/d9f/classshaka_1_1media_1_1SubsampleGenerator.html +++ b/docs/d0/d9f/classshaka_1_1media_1_1SubsampleGenerator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SubsampleGenerator Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
InjectAV1ParserForTes -

Definition at line 123 of file subsample_generator.cc.

+

Definition at line 120 of file subsample_generator.cc.

@@ -179,7 +182,7 @@ void InjectAV1ParserForTes
Returns
OK on success, an error status otherwise.
-

Definition at line 213 of file subsample_generator.cc.

+

Definition at line 210 of file subsample_generator.cc.

@@ -225,7 +228,7 @@ void InjectAV1ParserForTes
Returns
OK on success, an error status otherwise.
-

Definition at line 128 of file subsample_generator.cc.

+

Definition at line 125 of file subsample_generator.cc.

@@ -236,9 +239,7 @@ void InjectAV1ParserForTes diff --git a/docs/d0/da2/classshaka_1_1media_1_1AACAudioSpecificConfig.html b/docs/d0/da2/classshaka_1_1media_1_1AACAudioSpecificConfig.html index fc4d95d4a8..77e9e9f56b 100644 --- a/docs/d0/da2/classshaka_1_1media_1_1AACAudioSpecificConfig.html +++ b/docs/d0/da2/classshaka_1_1media_1_1AACAudioSpecificConfig.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AACAudioSpecificConfig Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Public Types

enum  AudioObjectType {
-  AOT_NULL = 0, -AOT_AAC_MAIN = 1, -AOT_AAC_LC = 2, -AOT_AAC_SSR = 3, -
-  AOT_AAC_LTP = 4, -AOT_SBR = 5, -AOT_AAC_SCALABLE = 6, -AOT_TWINVQ = 7, -
-  AOT_CELP = 8, -AOT_HVXC = 9, -AOT_TTSI = 12, -AOT_MAINSYNTH = 13, -
-  AOT_WAVESYNTH = 14, -AOT_MIDI = 15, -AOT_SAFX = 16, -AOT_ER_AAC_LC = 17, -
-  AOT_ER_AAC_LTP = 19, -AOT_ER_AAC_SCALABLE = 20, -AOT_ER_TWINVQ = 21, -AOT_ER_BSAC = 22, -
-  AOT_ER_AAC_LD = 23, -AOT_ER_CELP = 24, -AOT_ER_HVXC = 25, -AOT_ER_HILN = 26, -
-  AOT_ER_PARAM = 27, -AOT_SSC = 28, -AOT_PS = 29, -AOT_SURROUND = 30, -
-  AOT_ESCAPE = 31, -AOT_L1 = 32, -AOT_L2 = 33, -AOT_L3 = 34, -
-  AOT_DST = 35, -AOT_ALS = 36, -AOT_SLS = 37, -AOT_SLS_NON_CORE = 38, -
-  AOT_ER_AAC_ELD = 39, -AOT_SMR_SIMPLE = 40, -AOT_SMR_MAIN = 41, -AOT_USAC_NOSBR = 42, -
-  AOT_SAOC = 43, -AOT_LD_SURROUND = 44, -AOT_USAC = 45 +  AOT_NULL = 0 +, AOT_AAC_MAIN = 1 +, AOT_AAC_LC = 2 +, AOT_AAC_SSR = 3 +,
+  AOT_AAC_LTP = 4 +, AOT_SBR = 5 +, AOT_AAC_SCALABLE = 6 +, AOT_TWINVQ = 7 +,
+  AOT_CELP = 8 +, AOT_HVXC = 9 +, AOT_TTSI = 12 +, AOT_MAINSYNTH = 13 +,
+  AOT_WAVESYNTH = 14 +, AOT_MIDI = 15 +, AOT_SAFX = 16 +, AOT_ER_AAC_LC = 17 +,
+  AOT_ER_AAC_LTP = 19 +, AOT_ER_AAC_SCALABLE = 20 +, AOT_ER_TWINVQ = 21 +, AOT_ER_BSAC = 22 +,
+  AOT_ER_AAC_LD = 23 +, AOT_ER_CELP = 24 +, AOT_ER_HVXC = 25 +, AOT_ER_HILN = 26 +,
+  AOT_ER_PARAM = 27 +, AOT_SSC = 28 +, AOT_PS = 29 +, AOT_SURROUND = 30 +,
+  AOT_ESCAPE = 31 +, AOT_L1 = 32 +, AOT_L2 = 33 +, AOT_L3 = 34 +,
+  AOT_DST = 35 +, AOT_ALS = 36 +, AOT_SLS = 37 +, AOT_SLS_NON_CORE = 38 +,
+  AOT_ER_AAC_ELD = 39 +, AOT_SMR_SIMPLE = 40 +, AOT_SMR_MAIN = 41 +, AOT_USAC_NOSBR = 42 +,
+  AOT_SAOC = 43 +, AOT_LD_SURROUND = 44 +, AOT_USAC = 45
}   @@ -348,9 +351,7 @@ static const size_t  diff --git a/docs/d0/da2/classshaka_1_1media_1_1CommonPsshGenerator.html b/docs/d0/da2/classshaka_1_1media_1_1CommonPsshGenerator.html index 24b33f717f..e72e5ca15a 100644 --- a/docs/d0/da2/classshaka_1_1media_1_1CommonPsshGenerator.html +++ b/docs/d0/da2/classshaka_1_1media_1_1CommonPsshGenerator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::CommonPsshGenerator Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::PsshGenerator - -
+ + @@ -132,9 +135,7 @@ Public Member Functions diff --git a/docs/d0/da2/classshaka_1_1media_1_1RequestSigner-members.html b/docs/d0/da2/classshaka_1_1media_1_1RequestSigner-members.html index 61f8082444..7c877e0169 100644 --- a/docs/d0/da2/classshaka_1_1media_1_1RequestSigner-members.html +++ b/docs/d0/da2/classshaka_1_1media_1_1RequestSigner-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

Public Member Functions

- + +/* @license-end */
diff --git a/docs/d0/da2/structshaka_1_1xml_1_1XmlDeleter-members.html b/docs/d0/da2/structshaka_1_1xml_1_1XmlDeleter-members.html index 24ec8a48c2..e8fdd12171 100644 --- a/docs/d0/da2/structshaka_1_1xml_1_1XmlDeleter-members.html +++ b/docs/d0/da2/structshaka_1_1xml_1_1XmlDeleter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
operator()(xmlSchemaParserCtxtPtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline operator()(xmlSchemaValidCtxtPtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline - operator()(xmlSchemaPtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline - operator()(xmlNodePtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline - operator()(xmlDocPtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline - operator()(xmlChar *ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline + operator()(xmlOutputBufferPtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline + operator()(xmlSchemaPtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline + operator()(xmlNodePtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline + operator()(xmlDocPtr ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline + operator()(xmlChar *ptr) const (defined in shaka::xml::XmlDeleter)shaka::xml::XmlDeleterinline
diff --git a/docs/d0/da6/stream__descriptor_8cc_source.html b/docs/d0/da6/stream__descriptor_8cc_source.html index feadbe4f38..6267b71a01 100644 --- a/docs/d0/da6/stream__descriptor_8cc_source.html +++ b/docs/d0/da6/stream__descriptor_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/stream_descriptor.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
stream_descriptor.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/stream_descriptor.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/base/strings/string_number_conversions.h"
11 #include "packager/base/strings/string_split.h"
12 
13 namespace shaka {
14 
15 namespace {
16 
17 enum FieldType {
18  kUnknownField = 0,
19  kStreamSelectorField,
20  kInputField,
21  kOutputField,
22  kSegmentTemplateField,
23  kBandwidthField,
24  kLanguageField,
25  kOutputFormatField,
26  kHlsNameField,
27  kHlsGroupIdField,
28  kHlsPlaylistNameField,
29  kHlsIframePlaylistNameField,
30  kTrickPlayFactorField,
31  kSkipEncryptionField,
32  kDrmStreamLabelField,
33  kHlsCharacteristicsField,
34  kDashAccessiblitiesField,
35  kDashRolesField,
36 };
37 
38 struct FieldNameToTypeMapping {
39  const char* field_name;
40  FieldType field_type;
41 };
42 
43 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
44  {"stream_selector", kStreamSelectorField},
45  {"stream", kStreamSelectorField},
46  {"input", kInputField},
47  {"in", kInputField},
48  {"output", kOutputField},
49  {"out", kOutputField},
50  {"init_segment", kOutputField},
51  {"segment_template", kSegmentTemplateField},
52  {"template", kSegmentTemplateField},
53  {"bandwidth", kBandwidthField},
54  {"bw", kBandwidthField},
55  {"bitrate", kBandwidthField},
56  {"language", kLanguageField},
57  {"lang", kLanguageField},
58  {"output_format", kOutputFormatField},
59  {"format", kOutputFormatField},
60  {"hls_name", kHlsNameField},
61  {"hls_group_id", kHlsGroupIdField},
62  {"playlist_name", kHlsPlaylistNameField},
63  {"iframe_playlist_name", kHlsIframePlaylistNameField},
64  {"trick_play_factor", kTrickPlayFactorField},
65  {"tpf", kTrickPlayFactorField},
66  {"skip_encryption", kSkipEncryptionField},
67  {"drm_stream_label", kDrmStreamLabelField},
68  {"drm_label", kDrmStreamLabelField},
69  {"hls_characteristics", kHlsCharacteristicsField},
70  {"characteristics", kHlsCharacteristicsField},
71  {"charcs", kHlsCharacteristicsField},
72  {"dash_accessibilities", kDashAccessiblitiesField},
73  {"dash_accessibility", kDashAccessiblitiesField},
74  {"accessibilities", kDashAccessiblitiesField},
75  {"accessibility", kDashAccessiblitiesField},
76  {"dash_roles", kDashRolesField},
77  {"dash_role", kDashRolesField},
78  {"roles", kDashRolesField},
79  {"role", kDashRolesField},
80 };
81 
82 FieldType GetFieldType(const std::string& field_name) {
83  for (size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
84  if (field_name == kFieldNameTypeMappings[idx].field_name)
85  return kFieldNameTypeMappings[idx].field_type;
86  }
87  return kUnknownField;
88 }
89 
90 } // anonymous namespace
91 
92 base::Optional<StreamDescriptor> ParseStreamDescriptor(
93  const std::string& descriptor_string) {
94  StreamDescriptor descriptor;
95 
96  // Split descriptor string into name/value pairs.
97  base::StringPairs pairs;
98  if (!base::SplitStringIntoKeyValuePairs(descriptor_string, '=', ',',
99  &pairs)) {
100  LOG(ERROR) << "Invalid stream descriptors name/value pairs: "
101  << descriptor_string;
102  return base::nullopt;
103  }
104  for (base::StringPairs::const_iterator iter = pairs.begin();
105  iter != pairs.end(); ++iter) {
106  switch (GetFieldType(iter->first)) {
107  case kStreamSelectorField:
108  descriptor.stream_selector = iter->second;
109  break;
110  case kInputField:
111  descriptor.input = iter->second;
112  break;
113  case kOutputField:
114  descriptor.output = iter->second;
115  break;
116  case kSegmentTemplateField:
117  descriptor.segment_template = iter->second;
118  break;
119  case kBandwidthField: {
120  unsigned bw;
121  if (!base::StringToUint(iter->second, &bw)) {
122  LOG(ERROR) << "Non-numeric bandwidth specified.";
123  return base::nullopt;
124  }
125  descriptor.bandwidth = bw;
126  break;
127  }
128  case kLanguageField: {
129  descriptor.language = iter->second;
130  break;
131  }
132  case kOutputFormatField: {
133  descriptor.output_format = iter->second;
134  break;
135  }
136  case kHlsNameField: {
137  descriptor.hls_name = iter->second;
138  break;
139  }
140  case kHlsGroupIdField: {
141  descriptor.hls_group_id = iter->second;
142  break;
143  }
144  case kHlsPlaylistNameField: {
145  descriptor.hls_playlist_name = iter->second;
146  break;
147  }
148  case kHlsIframePlaylistNameField: {
149  descriptor.hls_iframe_playlist_name = iter->second;
150  break;
151  }
152  case kTrickPlayFactorField: {
153  unsigned factor;
154  if (!base::StringToUint(iter->second, &factor)) {
155  LOG(ERROR) << "Non-numeric trick play factor " << iter->second
156  << " specified.";
157  return base::nullopt;
158  }
159  if (factor == 0) {
160  LOG(ERROR) << "Stream trick_play_factor should be > 0.";
161  return base::nullopt;
162  }
163  descriptor.trick_play_factor = factor;
164  break;
165  }
166  case kSkipEncryptionField: {
167  unsigned skip_encryption_value;
168  if (!base::StringToUint(iter->second, &skip_encryption_value)) {
169  LOG(ERROR) << "Non-numeric option for skip encryption field "
170  "specified (" << iter->second << ").";
171  return base::nullopt;
172  }
173  if (skip_encryption_value > 1) {
174  LOG(ERROR) << "skip_encryption should be either 0 or 1.";
175  return base::nullopt;
176  }
177 
178  descriptor.skip_encryption = skip_encryption_value > 0;
179  break;
180  }
181  case kDrmStreamLabelField:
182  descriptor.drm_label = iter->second;
183  break;
184  case kHlsCharacteristicsField:
185  descriptor.hls_characteristics =
186  base::SplitString(iter->second, ";:", base::TRIM_WHITESPACE,
187  base::SPLIT_WANT_NONEMPTY);
188  break;
189  case kDashAccessiblitiesField:
190  descriptor.dash_accessiblities =
191  base::SplitString(iter->second, ";", base::TRIM_WHITESPACE,
192  base::SPLIT_WANT_NONEMPTY);
193  for (const std::string& accessibility :
194  descriptor.dash_accessiblities) {
195  size_t pos = accessibility.find('=');
196  if (pos == std::string::npos) {
197  LOG(ERROR)
198  << "Accessibility should be in scheme=value format, but seeing "
199  << accessibility;
200  return base::nullopt;
201  }
202  }
203  break;
204  case kDashRolesField:
205  descriptor.dash_roles =
206  base::SplitString(iter->second, ";", base::TRIM_WHITESPACE,
207  base::SPLIT_WANT_NONEMPTY);
208  break;
209  default:
210  LOG(ERROR) << "Unknown field in stream descriptor (\"" << iter->first
211  << "\").";
212  return base::nullopt;
213  }
214  }
215  return descriptor;
216 }
217 
218 } // namespace shaka
std::string stream_selector
Definition: packager.h:79
-
Defines a single input/output stream.
Definition: packager.h:73
-
std::string input
Input/source media file path or network stream URL. Required.
Definition: packager.h:75
-
std::string hls_playlist_name
Definition: packager.h:119
-
std::string hls_name
Definition: packager.h:113
-
base::Optional< StreamDescriptor > ParseStreamDescriptor(const std::string &descriptor_string)
-
std::string segment_template
Specifies segment template. Can be empty.
Definition: packager.h:85
-
std::string output_format
Definition: packager.h:89
-
All the methods that are virtual are virtual for mocking.
-
std::string drm_label
Definition: packager.h:97
-
uint32_t trick_play_factor
Definition: packager.h:101
-
std::string output
Definition: packager.h:83
-
std::vector< std::string > hls_characteristics
Definition: packager.h:125
-
std::string hls_iframe_playlist_name
Definition: packager.h:122
- -
std::vector< std::string > dash_accessiblities
Optional for DASH output. It defines Accessibility elements of the stream.
Definition: packager.h:128
-
std::vector< std::string > dash_roles
Optional for DASH output. It defines Role elements of the stream.
Definition: packager.h:130
- -
std::string language
Definition: packager.h:108
-
std::string hls_group_id
Definition: packager.h:116
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/app/stream_descriptor.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/base/strings/string_number_conversions.h"
+
11 #include "packager/base/strings/string_split.h"
+
12 
+
13 namespace shaka {
+
14 
+
15 namespace {
+
16 
+
17 enum FieldType {
+
18  kUnknownField = 0,
+
19  kStreamSelectorField,
+
20  kInputField,
+
21  kOutputField,
+
22  kSegmentTemplateField,
+
23  kBandwidthField,
+
24  kLanguageField,
+
25  kCcIndexField,
+
26  kOutputFormatField,
+
27  kHlsNameField,
+
28  kHlsGroupIdField,
+
29  kHlsPlaylistNameField,
+
30  kHlsIframePlaylistNameField,
+
31  kTrickPlayFactorField,
+
32  kSkipEncryptionField,
+
33  kDrmStreamLabelField,
+
34  kHlsCharacteristicsField,
+
35  kDashAccessiblitiesField,
+
36  kDashRolesField,
+
37  kDashOnlyField,
+
38  kHlsOnlyField,
+
39 };
+
40 
+
41 struct FieldNameToTypeMapping {
+
42  const char* field_name;
+
43  FieldType field_type;
+
44 };
+
45 
+
46 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
+
47  {"stream_selector", kStreamSelectorField},
+
48  {"stream", kStreamSelectorField},
+
49  {"input", kInputField},
+
50  {"in", kInputField},
+
51  {"output", kOutputField},
+
52  {"out", kOutputField},
+
53  {"init_segment", kOutputField},
+
54  {"segment_template", kSegmentTemplateField},
+
55  {"template", kSegmentTemplateField},
+
56  {"bandwidth", kBandwidthField},
+
57  {"bw", kBandwidthField},
+
58  {"bitrate", kBandwidthField},
+
59  {"language", kLanguageField},
+
60  {"lang", kLanguageField},
+
61  {"cc_index", kCcIndexField},
+
62  {"output_format", kOutputFormatField},
+
63  {"format", kOutputFormatField},
+
64  {"hls_name", kHlsNameField},
+
65  {"hls_group_id", kHlsGroupIdField},
+
66  {"playlist_name", kHlsPlaylistNameField},
+
67  {"iframe_playlist_name", kHlsIframePlaylistNameField},
+
68  {"trick_play_factor", kTrickPlayFactorField},
+
69  {"tpf", kTrickPlayFactorField},
+
70  {"skip_encryption", kSkipEncryptionField},
+
71  {"drm_stream_label", kDrmStreamLabelField},
+
72  {"drm_label", kDrmStreamLabelField},
+
73  {"hls_characteristics", kHlsCharacteristicsField},
+
74  {"characteristics", kHlsCharacteristicsField},
+
75  {"charcs", kHlsCharacteristicsField},
+
76  {"dash_accessibilities", kDashAccessiblitiesField},
+
77  {"dash_accessibility", kDashAccessiblitiesField},
+
78  {"accessibilities", kDashAccessiblitiesField},
+
79  {"accessibility", kDashAccessiblitiesField},
+
80  {"dash_roles", kDashRolesField},
+
81  {"dash_role", kDashRolesField},
+
82  {"roles", kDashRolesField},
+
83  {"role", kDashRolesField},
+
84  {"dash_only", kDashOnlyField},
+
85  {"hls_only", kHlsOnlyField},
+
86 };
+
87 
+
88 FieldType GetFieldType(const std::string& field_name) {
+
89  for (size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
+
90  if (field_name == kFieldNameTypeMappings[idx].field_name)
+
91  return kFieldNameTypeMappings[idx].field_type;
+
92  }
+
93  return kUnknownField;
+
94 }
+
95 
+
96 } // anonymous namespace
+
97 
+
98 base::Optional<StreamDescriptor> ParseStreamDescriptor(
+
99  const std::string& descriptor_string) {
+
100  StreamDescriptor descriptor;
+
101 
+
102  // Split descriptor string into name/value pairs.
+
103  base::StringPairs pairs;
+
104  if (!base::SplitStringIntoKeyValuePairs(descriptor_string, '=', ',',
+
105  &pairs)) {
+
106  LOG(ERROR) << "Invalid stream descriptors name/value pairs: "
+
107  << descriptor_string;
+
108  return base::nullopt;
+
109  }
+
110  for (base::StringPairs::const_iterator iter = pairs.begin();
+
111  iter != pairs.end(); ++iter) {
+
112  switch (GetFieldType(iter->first)) {
+
113  case kStreamSelectorField:
+
114  descriptor.stream_selector = iter->second;
+
115  break;
+
116  case kInputField:
+
117  descriptor.input = iter->second;
+
118  break;
+
119  case kOutputField:
+
120  descriptor.output = iter->second;
+
121  break;
+
122  case kSegmentTemplateField:
+
123  descriptor.segment_template = iter->second;
+
124  break;
+
125  case kBandwidthField: {
+
126  unsigned bw;
+
127  if (!base::StringToUint(iter->second, &bw)) {
+
128  LOG(ERROR) << "Non-numeric bandwidth specified.";
+
129  return base::nullopt;
+
130  }
+
131  descriptor.bandwidth = bw;
+
132  break;
+
133  }
+
134  case kLanguageField: {
+
135  descriptor.language = iter->second;
+
136  break;
+
137  }
+
138  case kCcIndexField: {
+
139  unsigned index;
+
140  if (!base::StringToUint(iter->second, &index)) {
+
141  LOG(ERROR) << "Non-numeric cc_index specified.";
+
142  return base::nullopt;
+
143  }
+
144  descriptor.cc_index = index;
+
145  break;
+
146  }
+
147  case kOutputFormatField: {
+
148  descriptor.output_format = iter->second;
+
149  break;
+
150  }
+
151  case kHlsNameField: {
+
152  descriptor.hls_name = iter->second;
+
153  break;
+
154  }
+
155  case kHlsGroupIdField: {
+
156  descriptor.hls_group_id = iter->second;
+
157  break;
+
158  }
+
159  case kHlsPlaylistNameField: {
+
160  descriptor.hls_playlist_name = iter->second;
+
161  break;
+
162  }
+
163  case kHlsIframePlaylistNameField: {
+
164  descriptor.hls_iframe_playlist_name = iter->second;
+
165  break;
+
166  }
+
167  case kTrickPlayFactorField: {
+
168  unsigned factor;
+
169  if (!base::StringToUint(iter->second, &factor)) {
+
170  LOG(ERROR) << "Non-numeric trick play factor " << iter->second
+
171  << " specified.";
+
172  return base::nullopt;
+
173  }
+
174  if (factor == 0) {
+
175  LOG(ERROR) << "Stream trick_play_factor should be > 0.";
+
176  return base::nullopt;
+
177  }
+
178  descriptor.trick_play_factor = factor;
+
179  break;
+
180  }
+
181  case kSkipEncryptionField: {
+
182  unsigned skip_encryption_value;
+
183  if (!base::StringToUint(iter->second, &skip_encryption_value)) {
+
184  LOG(ERROR) << "Non-numeric option for skip encryption field "
+
185  "specified (" << iter->second << ").";
+
186  return base::nullopt;
+
187  }
+
188  if (skip_encryption_value > 1) {
+
189  LOG(ERROR) << "skip_encryption should be either 0 or 1.";
+
190  return base::nullopt;
+
191  }
+
192 
+
193  descriptor.skip_encryption = skip_encryption_value > 0;
+
194  break;
+
195  }
+
196  case kDrmStreamLabelField:
+
197  descriptor.drm_label = iter->second;
+
198  break;
+
199  case kHlsCharacteristicsField:
+
200  descriptor.hls_characteristics =
+
201  base::SplitString(iter->second, ";:", base::TRIM_WHITESPACE,
+
202  base::SPLIT_WANT_NONEMPTY);
+
203  break;
+
204  case kDashAccessiblitiesField:
+
205  descriptor.dash_accessiblities =
+
206  base::SplitString(iter->second, ";", base::TRIM_WHITESPACE,
+
207  base::SPLIT_WANT_NONEMPTY);
+
208  for (const std::string& accessibility :
+
209  descriptor.dash_accessiblities) {
+
210  size_t pos = accessibility.find('=');
+
211  if (pos == std::string::npos) {
+
212  LOG(ERROR)
+
213  << "Accessibility should be in scheme=value format, but seeing "
+
214  << accessibility;
+
215  return base::nullopt;
+
216  }
+
217  }
+
218  break;
+
219  case kDashRolesField:
+
220  descriptor.dash_roles =
+
221  base::SplitString(iter->second, ";", base::TRIM_WHITESPACE,
+
222  base::SPLIT_WANT_NONEMPTY);
+
223  break;
+
224  case kDashOnlyField:
+
225  unsigned dash_only_value;
+
226  if (!base::StringToUint(iter->second, &dash_only_value)) {
+
227  LOG(ERROR) << "Non-numeric option for dash_only field "
+
228  "specified (" << iter->second << ").";
+
229  return base::nullopt;
+
230  }
+
231  if (dash_only_value > 1) {
+
232  LOG(ERROR) << "dash_only should be either 0 or 1.";
+
233  return base::nullopt;
+
234  }
+
235  descriptor.dash_only = dash_only_value > 0;
+
236  break;
+
237  case kHlsOnlyField:
+
238  unsigned hls_only_value;
+
239  if (!base::StringToUint(iter->second, &hls_only_value)) {
+
240  LOG(ERROR) << "Non-numeric option for hls_only field "
+
241  "specified (" << iter->second << ").";
+
242  return base::nullopt;
+
243  }
+
244  if (hls_only_value > 1) {
+
245  LOG(ERROR) << "hls_only should be either 0 or 1.";
+
246  return base::nullopt;
+
247  }
+
248  descriptor.hls_only = hls_only_value > 0;
+
249  break;
+
250  default:
+
251  LOG(ERROR) << "Unknown field in stream descriptor (\"" << iter->first
+
252  << "\").";
+
253  return base::nullopt;
+
254  }
+
255  }
+
256  return descriptor;
+
257 }
+
258 
+
259 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
+
base::Optional< StreamDescriptor > ParseStreamDescriptor(const std::string &descriptor_string)
+
Defines a single input/output stream.
Definition: packager.h:76
+
std::string output_format
Definition: packager.h:92
+
std::vector< std::string > dash_accessiblities
Optional for DASH output. It defines Accessibility elements of the stream.
Definition: packager.h:135
+
std::string hls_iframe_playlist_name
Definition: packager.h:129
+
std::string output
Definition: packager.h:86
+
std::vector< std::string > dash_roles
Optional for DASH output. It defines Role elements of the stream.
Definition: packager.h:137
+
std::string hls_group_id
Definition: packager.h:123
+
bool dash_only
Set to true to indicate that the stream is for dash only.
Definition: packager.h:140
+
std::string stream_selector
Definition: packager.h:82
+ +
uint32_t trick_play_factor
Definition: packager.h:104
+
bool hls_only
Set to true to indicate that the stream is for hls only.
Definition: packager.h:142
+
std::string drm_label
Definition: packager.h:100
+
std::string hls_name
Definition: packager.h:120
+ +
std::string hls_playlist_name
Definition: packager.h:126
+ +
std::vector< std::string > hls_characteristics
Definition: packager.h:132
+
std::string input
Input/source media file path or network stream URL. Required.
Definition: packager.h:78
+
std::string language
Definition: packager.h:111
+
std::string segment_template
Specifies segment template. Can be empty.
Definition: packager.h:88
diff --git a/docs/d0/da8/classshaka_1_1media_1_1PackedAudioWriter-members.html b/docs/d0/da8/classshaka_1_1media_1_1PackedAudioWriter-members.html index bad969cd8f..5a3e403a10 100644 --- a/docs/d0/da8/classshaka_1_1media_1_1PackedAudioWriter-members.html +++ b/docs/d0/da8/classshaka_1_1media_1_1PackedAudioWriter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline Cancel()shaka::media::Muxer - Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic + Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic clock() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected @@ -110,9 +113,7 @@ $(function() {
diff --git a/docs/d0/da8/structshaka_1_1HlsParams.html b/docs/d0/da8/structshaka_1_1HlsParams.html index a4a42c49cb..df12138ff9 100644 --- a/docs/d0/da8/structshaka_1_1HlsParams.html +++ b/docs/d0/da8/structshaka_1_1HlsParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::HlsParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
  std::string default_text_language   + +bool is_independent_segments +  double target_segment_duration = 0   +uint32_t media_sequence_number = 0 + 

Detailed Description

HLS related parameters.

@@ -171,6 +179,23 @@ std::string Definition at line 44 of file hls_params.h.

+
+
+ +

◆ media_sequence_number

+ +
+
+ + + + +
uint32_t shaka::HlsParams::media_sequence_number = 0
+
+

Custom EXT-X-MEDIA-SEQUENCE value to allow continuous media playback across packager restarts. See #691 for details.

+ +

Definition at line 64 of file hls_params.h.

+
@@ -201,9 +226,9 @@ std::string 
-

This is the target segment duration requested by the user. The actual segment duration may be different to the target segment duration. It will be populated from segment duration specified in ChunkingParams if not specified.

+

This is the target segment duration requested by the user. The actual segment duration may be different to the target segment duration. It will be populated from segment duration specified in ChunkingParams if not specified.

-

Definition at line 58 of file hls_params.h.

+

Definition at line 61 of file hls_params.h.

@@ -230,9 +255,7 @@ std::string  diff --git a/docs/d0/dab/classshaka_1_1media_1_1mp4_1_1SingleSegmentSegmenter.html b/docs/d0/dab/classshaka_1_1media_1_1mp4_1_1SingleSegmentSegmenter.html index 0dfc812bf8..533ffd43b9 100644 --- a/docs/d0/dab/classshaka_1_1media_1_1mp4_1_1SingleSegmentSegmenter.html +++ b/docs/d0/dab/classshaka_1_1media_1_1mp4_1_1SingleSegmentSegmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SingleSegmentSegmenter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Segmenter - -
+ + @@ -119,7 +122,7 @@ Additional Inherited Members - + @@ -154,9 +157,9 @@ void 

Public Member Functions

- Protected Member Functions inherited from shaka::media::mp4::Segmenter
void UpdateProgress (uint64_t progress)
 Update segmentation progress using ProgressListener.
 Update segmentation progress using ProgressListener.
 
void SetComplete ()
set_progress_target 

Detailed Description

-

Segmenter for MP4 Dash Video-On-Demand profile. A single MP4 file with a single segment is created, i.e. with only one SIDX box. The generated media file can contain one or many subsegments with subsegment duration defined by MuxerOptions.segment_duration. A subsegment can contain one or many fragments with fragment duration defined by MuxerOptions.fragment_duration. The actual subsegment or fragment duration may not match the requested duration exactly, but will be approximated. That is, the Segmenter tries to end subsegment/fragment at the first sample with overall subsegment/fragment duration not smaller than defined duration and yet meet SAP requirements. SingleSegmentSegmenter ignores MuxerOptions.mp4_params.generate_sidx_in_media_segments.

+

Segmenter for MP4 Dash Video-On-Demand profile. A single MP4 file with a single segment is created, i.e. with only one SIDX box. The generated media file can contain one or many subsegments with subsegment duration defined by MuxerOptions.segment_duration. A subsegment can contain one or many fragments with fragment duration defined by MuxerOptions.fragment_duration. The actual subsegment or fragment duration may not match the requested duration exactly, but will be approximated. That is, the Segmenter tries to end subsegment/fragment at the first sample with overall subsegment/fragment duration not smaller than defined duration and yet meet SAP requirements.

-

Definition at line 29 of file single_segment_segmenter.h.

+

Definition at line 28 of file single_segment_segmenter.h.

Member Function Documentation

◆ GetIndexRange()

@@ -247,9 +250,7 @@ void set_progress_target diff --git a/docs/d0/dab/subtitle__composer_8h_source.html b/docs/d0/dab/subtitle__composer_8h_source.html new file mode 100644 index 0000000000..656cc37b09 --- /dev/null +++ b/docs/d0/dab/subtitle__composer_8h_source.html @@ -0,0 +1,159 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/dvb/subtitle_composer.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
subtitle_composer.h
+
+
+
1 // Copyright 2020 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_DVB_SUBTITLE_COMPOSER_H_
+
8 #define PACKAGER_MEDIA_DVB_SUBTITLE_COMPOSER_H_
+
9 
+
10 #include <memory>
+
11 #include <unordered_map>
+
12 #include <vector>
+
13 
+
14 #include "packager/base/macros.h"
+
15 #include "packager/media/base/text_sample.h"
+
16 #include "packager/media/formats/dvb/dvb_image.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 
+ +
24  public:
+ + +
27 
+
28  DISALLOW_COPY_AND_ASSIGN(SubtitleComposer);
+
29 
+
30  void SetDisplaySize(uint16_t width, uint16_t height);
+
31  bool SetRegionPosition(uint8_t region_id, uint16_t x, uint16_t y);
+
32  bool SetRegionInfo(uint8_t region_id,
+
33  uint8_t color_space_id,
+
34  uint16_t width,
+
35  uint16_t height);
+
36  bool SetObjectInfo(uint16_t object_id,
+
37  uint8_t region_id,
+
38  uint16_t x,
+
39  uint16_t y,
+
40  int default_color_code);
+
41 
+
42  DvbImageColorSpace* GetColorSpace(uint8_t color_space_id);
+
43  DvbImageColorSpace* GetColorSpaceForObject(uint16_t object_id);
+
44  DvbImageBuilder* GetObjectImage(uint16_t object_id);
+
45 
+
46  bool GetSamples(int64_t start,
+
47  int64_t end,
+
48  std::vector<std::shared_ptr<TextSample>>* samples) const;
+
49  void ClearObjects();
+
50 
+
51  private:
+
52  struct RegionInfo {
+
53  DvbImageColorSpace* color_space = nullptr;
+
54  uint16_t x = 0;
+
55  uint16_t y = 0;
+
56  uint16_t width = 0;
+
57  uint16_t height = 0;
+
58  };
+
59 
+
60  struct ObjectInfo {
+
61  RegionInfo* region = nullptr;
+
62  int default_color_code = -1;
+
63  uint16_t x = 0;
+
64  uint16_t y = 0;
+
65  };
+
66 
+
67  // Maps of IDs to their respective object.
+
68  std::unordered_map<uint8_t, RegionInfo> regions_;
+
69  std::unordered_map<uint8_t, DvbImageColorSpace> color_spaces_;
+
70  std::unordered_map<uint16_t, ObjectInfo> objects_;
+
71  std::unordered_map<uint16_t, DvbImageBuilder> images_; // Uses object_id.
+
72  uint16_t display_width_;
+
73  uint16_t display_height_;
+
74 };
+
75 
+
76 } // namespace media
+
77 } // namespace shaka
+
78 
+
79 #endif // PACKAGER_MEDIA_DVB_SUBTITLE_COMPOSER_H_
+ + + +
All the methods that are virtual are virtual for mocking.
+
+ + + + diff --git a/docs/d0/dac/classshaka_1_1media_1_1EncryptionHandler-members.html b/docs/d0/dac/classshaka_1_1media_1_1EncryptionHandler-members.html index a21b72a1e7..a116213fed 100644 --- a/docs/d0/dac/classshaka_1_1media_1_1EncryptionHandler-members.html +++ b/docs/d0/dac/classshaka_1_1media_1_1EncryptionHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::media::EncryptionHandler, including all inherited members.

- + @@ -99,9 +102,7 @@ $(function() {
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
diff --git a/docs/d0/dae/file__util_8h_source.html b/docs/d0/dae/file__util_8h_source.html index 4911397da5..8e10f24089 100644 --- a/docs/d0/dae/file__util_8h_source.html +++ b/docs/d0/dae/file__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/file_util.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
file_util.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include <string>
8 
9 namespace shaka {
10 
16 bool TempFilePath(const std::string& temp_dir, std::string* temp_file_path);
17 
18 } // namespace shaka
bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
Definition: file_util.cc:38
-
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include <string>
+
8 
+
9 namespace shaka {
+
10 
+
16 bool TempFilePath(const std::string& temp_dir, std::string* temp_file_path);
+
17 
+
18 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
+
bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
Definition: file_util.cc:38
diff --git a/docs/d0/db4/structshaka_1_1RawKeyParams.html b/docs/d0/db4/structshaka_1_1RawKeyParams.html index bb030ac6c7..83279f8d5e 100644 --- a/docs/d0/db4/structshaka_1_1RawKeyParams.html +++ b/docs/d0/db4/structshaka_1_1RawKeyParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::RawKeyParams Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */

Detailed Description

Raw key encryption/decryption parameters, i.e. with key parameters provided.

-

Definition at line 86 of file crypto_params.h.

+

Definition at line 123 of file crypto_params.h.

Member Data Documentation

◆ iv

@@ -115,7 +118,7 @@ Public Attributes

An optional initialization vector. If not provided, a random iv will be generated. Note that this parameter should only be used during testing. Not needed for decryption.

-

Definition at line 90 of file crypto_params.h.

+

Definition at line 127 of file crypto_params.h.

@@ -132,7 +135,7 @@ Public Attributes

Defines the KeyInfo for the streams. An empty StreamLabel indicates the default KeyInfo, which applies to all the StreamLabels not present in key_map.

-

Definition at line 104 of file crypto_params.h.

+

Definition at line 142 of file crypto_params.h.

@@ -149,7 +152,7 @@ Public Attributes

Inject a custom pssh or multiple concatenated psshs. If not provided, a common system pssh will be generated. Not needed for decryption.

-

Definition at line 94 of file crypto_params.h.

+

Definition at line 131 of file crypto_params.h.

@@ -159,9 +162,7 @@ Public Attributes diff --git a/docs/d0/dbb/classshaka_1_1media_1_1mp2t_1_1Ac3Header-members.html b/docs/d0/dbb/classshaka_1_1media_1_1mp2t_1_1Ac3Header-members.html index 7ae8fd37a5..1e84430c55 100644 --- a/docs/d0/dbb/classshaka_1_1media_1_1mp2t_1_1Ac3Header-members.html +++ b/docs/d0/dbb/classshaka_1_1media_1_1mp2t_1_1Ac3Header-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d0/dbc/bit__writer_8h_source.html b/docs/d0/dbc/bit__writer_8h_source.html index c4727dcc1d..b18e3b05b1 100644 --- a/docs/d0/dbc/bit__writer_8h_source.html +++ b/docs/d0/dbc/bit__writer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/bit_writer.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
bit_writer.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_BIT_WRITER_H_
8 #define PACKAGER_MEDIA_BASE_BIT_WRITER_H_
9 
10 #include <stdint.h>
11 
12 #include <vector>
13 
14 #include "packager/base/logging.h"
15 
16 namespace shaka {
17 namespace media {
18 
19 class BitWriter {
20  public:
24  explicit BitWriter(std::vector<uint8_t>* storage);
25  ~BitWriter() = default;
26 
33  void WriteBits(uint32_t bits, size_t number_of_bits);
34 
36  void Flush();
37 
39  size_t BitPos() const { return BytePos() * 8 + num_bits_; }
40 
42  size_t BytePos() const { return storage_->size() - initial_storage_size_; }
43 
44  private:
45  BitWriter(const BitWriter&) = delete;
46  BitWriter& operator=(const BitWriter&) = delete;
47 
48  // Accumulator for unwritten bits.
49  uint64_t bits_ = 0;
50  // Number of unwritten bits.
51  int num_bits_ = 0;
52  // Buffer contains the written bits.
53  std::vector<uint8_t>* const storage_ = nullptr;
54  const size_t initial_storage_size_ = 0;
55 };
56 
57 } // namespace media
58 } // namespace shaka
59 
60 #endif // PACKAGER_MEDIA_BASE_BIT_WRITER_H_
All the methods that are virtual are virtual for mocking.
- -
void WriteBits(uint32_t bits, size_t number_of_bits)
Definition: bit_writer.cc:15
-
size_t BytePos() const
Definition: bit_writer.h:42
-
BitWriter(std::vector< uint8_t > *storage)
Definition: bit_writer.cc:12
-
void Flush()
Write pending bits, and align bitstream with extra zero bits.
Definition: bit_writer.cc:31
-
size_t BitPos() const
Definition: bit_writer.h:39
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_BIT_WRITER_H_
+
8 #define PACKAGER_MEDIA_BASE_BIT_WRITER_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <vector>
+
13 
+
14 #include "packager/base/logging.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+
19 class BitWriter {
+
20  public:
+
24  explicit BitWriter(std::vector<uint8_t>* storage);
+
25  ~BitWriter() = default;
+
26 
+
33  void WriteBits(uint32_t bits, size_t number_of_bits);
+
34 
+
36  void Flush();
+
37 
+
39  size_t BitPos() const { return BytePos() * 8 + num_bits_; }
+
40 
+
42  size_t BytePos() const { return storage_->size() - initial_storage_size_; }
+
43 
+
44  private:
+
45  BitWriter(const BitWriter&) = delete;
+
46  BitWriter& operator=(const BitWriter&) = delete;
+
47 
+
48  // Accumulator for unwritten bits.
+
49  uint64_t bits_ = 0;
+
50  // Number of unwritten bits.
+
51  int num_bits_ = 0;
+
52  // Buffer contains the written bits.
+
53  std::vector<uint8_t>* const storage_ = nullptr;
+
54  const size_t initial_storage_size_ = 0;
+
55 };
+
56 
+
57 } // namespace media
+
58 } // namespace shaka
+
59 
+
60 #endif // PACKAGER_MEDIA_BASE_BIT_WRITER_H_
+ +
BitWriter(std::vector< uint8_t > *storage)
Definition: bit_writer.cc:12
+
void Flush()
Write pending bits, and align bitstream with extra zero bits.
Definition: bit_writer.cc:31
+
size_t BitPos() const
Definition: bit_writer.h:39
+
size_t BytePos() const
Definition: bit_writer.h:42
+
void WriteBits(uint32_t bits, size_t number_of_bits)
Definition: bit_writer.cc:15
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/dbc/webvtt__parser_8h_source.html b/docs/d0/dbc/webvtt__parser_8h_source.html index ef29182035..44956bc45a 100644 --- a/docs/d0/dbc/webvtt__parser_8h_source.html +++ b/docs/d0/dbc/webvtt__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/webvtt_parser.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
webvtt_parser.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_PARSER_H_
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_PARSER_H_
9 
10 #include <stdint.h>
11 
12 #include <vector>
13 
14 #include "packager/media/formats/webvtt/text_readers.h"
15 #include "packager/media/origin/origin_handler.h"
16 
17 namespace shaka {
18 namespace media {
19 
20 // Used to parse a WebVTT source into Cues that will be sent downstream.
21 class WebVttParser : public OriginHandler {
22  public:
23  WebVttParser(std::unique_ptr<FileReader> source, const std::string& language);
24 
25  Status Run() override;
26  void Cancel() override;
27 
28  private:
29  WebVttParser(const WebVttParser&) = delete;
30  WebVttParser& operator=(const WebVttParser&) = delete;
31 
32  Status InitializeInternal() override;
33  bool ValidateOutputStreamIndex(size_t stream_index) const override;
34 
35  bool Parse();
36  bool ParseCueWithNoId(const std::vector<std::string>& block);
37  bool ParseCueWithId(const std::vector<std::string>& block);
38  Status ParseCue(const std::string& id,
39  const std::string* block,
40  size_t block_size);
41 
42  Status DispatchTextStreamInfo();
43 
44  BlockReader reader_;
45  std::string language_;
46  std::string style_region_config_;
47  bool stream_info_dispatched_ = false;
48  bool keep_reading_ = true;
49 };
50 
51 } // namespace media
52 } // namespace shaka
53 
54 #endif // MEDIA_FORMATS_WEBVTT_WEBVTT_PARSER_H_
-
All the methods that are virtual are virtual for mocking.
- - - +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_PARSER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_PARSER_H_
+
9 
+
10 #include <map>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/media/base/media_parser.h"
+
15 #include "packager/media/base/text_sample.h"
+
16 #include "packager/media/base/text_stream_info.h"
+
17 #include "packager/media/formats/webvtt/text_readers.h"
+
18 
+
19 namespace shaka {
+
20 namespace media {
+
21 
+
22 // Used to parse a WebVTT source into Cues that will be sent downstream.
+
23 class WebVttParser : public MediaParser {
+
24  public:
+
25  WebVttParser();
+
26 
+
27  void Init(const InitCB& init_cb,
+
28  const NewMediaSampleCB& new_media_sample_cb,
+
29  const NewTextSampleCB& new_text_sample_cb,
+
30  KeySource* decryption_key_source) override;
+
31  bool Flush() override;
+
32  bool Parse(const uint8_t* buf, int size) override;
+
33 
+
34  private:
+
35  bool Parse();
+
36  bool ParseBlock(const std::vector<std::string>& block);
+
37  bool ParseRegion(const std::vector<std::string>& block);
+
38  bool ParseCueWithNoId(const std::vector<std::string>& block);
+
39  bool ParseCueWithId(const std::vector<std::string>& block);
+
40  bool ParseCue(const std::string& id,
+
41  const std::string* block,
+
42  size_t block_size);
+
43 
+
44  void DispatchTextStreamInfo();
+
45 
+
46  InitCB init_cb_;
+
47  NewTextSampleCB new_text_sample_cb_;
+
48 
+
49  BlockReader reader_;
+
50  std::map<std::string, TextRegion> regions_;
+
51  std::string css_styles_;
+
52  bool saw_cue_ = false;
+
53  bool stream_info_dispatched_ = false;
+
54  bool initialized_ = false;
+
55 };
+
56 
+
57 } // namespace media
+
58 } // namespace shaka
+
59 
+
60 #endif // MEDIA_FORMATS_WEBVTT_WEBVTT_PARSER_H_
+ +
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:51
+ +
base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
Definition: media_parser.h:53
+
base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
Definition: media_parser.h:44
+
base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
Definition: media_parser.h:35
+ + +
void Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
+
bool Parse(const uint8_t *buf, int size) override
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/dbd/classshaka_1_1media_1_1webm_1_1MultiSegmentSegmenter-members.html b/docs/d0/dbd/classshaka_1_1media_1_1webm_1_1MultiSegmentSegmenter-members.html index 053d86f035..4161887f4f 100644 --- a/docs/d0/dbd/classshaka_1_1media_1_1webm_1_1MultiSegmentSegmenter-members.html +++ b/docs/d0/dbd/classshaka_1_1media_1_1webm_1_1MultiSegmentSegmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/dbe/structshaka_1_1RawKeyParams_1_1KeyInfo.html b/docs/d0/dbe/structshaka_1_1RawKeyParams_1_1KeyInfo.html index 49ad77d75d..f65021c9e7 100644 --- a/docs/d0/dbe/structshaka_1_1RawKeyParams_1_1KeyInfo.html +++ b/docs/d0/dbe/structshaka_1_1RawKeyParams_1_1KeyInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::RawKeyParams::KeyInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
std::vector< uint8_t > key   + +std::vector< uint8_t > iv

Detailed Description

-

Definition at line 97 of file crypto_params.h.

+

Definition at line 134 of file crypto_params.h.


The documentation for this struct was generated from the following file:
diff --git a/docs/d0/dc0/structshaka_1_1media_1_1SegmentInfo.html b/docs/d0/dc0/structshaka_1_1media_1_1SegmentInfo.html index 032e3d9cac..d73da4d06d 100644 --- a/docs/d0/dc0/structshaka_1_1media_1_1SegmentInfo.html +++ b/docs/d0/dc0/structshaka_1_1media_1_1SegmentInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SegmentInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d0/dc1/structshaka_1_1media_1_1mp4_1_1VTTEmptyCueBox-members.html b/docs/d0/dc1/structshaka_1_1media_1_1mp4_1_1VTTEmptyCueBox-members.html index 924102c419..41c42637ad 100644 --- a/docs/d0/dc1/structshaka_1_1media_1_1mp4_1_1VTTEmptyCueBox-members.html +++ b/docs/d0/dc1/structshaka_1_1media_1_1mp4_1_1VTTEmptyCueBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d0/dc8/classshaka_1_1xml_1_1AdaptationSetXmlNode-members.html b/docs/d0/dc8/classshaka_1_1xml_1_1AdaptationSetXmlNode-members.html index 6f5802f4f3..d266649a14 100644 --- a/docs/d0/dc8/classshaka_1_1xml_1_1AdaptationSetXmlNode-members.html +++ b/docs/d0/dc8/classshaka_1_1xml_1_1AdaptationSetXmlNode-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
This is the complete list of members for shaka::xml::AdaptationSetXmlNode, including all inherited members.

- - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - + + + + + + +
AdaptationSetXmlNode() (defined in shaka::xml::AdaptationSetXmlNode)shaka::xml::AdaptationSetXmlNode
AddAccessibilityElement(const std::string &scheme_id_uri, const std::string &value)shaka::xml::AdaptationSetXmlNode
AddChild(scoped_xml_ptr< xmlNode > child)shaka::xml::XmlNode
AddContentProtectionElements(const std::list< ContentProtectionElement > &content_protection_elements) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNodeprotected
AddElements(const std::vector< Element > &elements)shaka::xml::XmlNode
AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNode
AddRoleElement(const std::string &scheme_id_uri, const std::string &value)shaka::xml::AdaptationSetXmlNode
AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNode
ExtractReferencedNamespaces()shaka::xml::XmlNode
GetRawPtr()shaka::xml::XmlNode
PassScopedPtr()shaka::xml::XmlNode
Release()shaka::xml::XmlNode
RepresentationBaseXmlNode(const char *name) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNodeexplicitprotected
AddAccessibilityElement(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::AdaptationSetXmlNode
AddChild(XmlNode child) WARN_UNUSED_RESULTshaka::xml::XmlNode
AddContent(const std::string &content)shaka::xml::XmlNode
AddContentProtectionElements(const std::list< ContentProtectionElement > &content_protection_elements) WARN_UNUSED_RESULT (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNodeprotected
AddElements(const std::vector< Element > &elements) WARN_UNUSED_RESULTshaka::xml::XmlNode
AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNode
AddRoleElement(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::AdaptationSetXmlNode
AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNode
ExtractReferencedNamespaces() constshaka::xml::XmlNode
GetAttribute(const std::string &name, std::string *value) constshaka::xml::XmlNode
operator=(XmlNode &&) (defined in shaka::xml::XmlNode)shaka::xml::XmlNode
RepresentationBaseXmlNode(const std::string &name) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNodeexplicitprotected
SetContent(const std::string &content)shaka::xml::XmlNode
SetFloatingPointAttribute(const char *attribute_name, double number)shaka::xml::XmlNode
SetId(uint32_t id)shaka::xml::XmlNode
SetIntegerAttribute(const char *attribute_name, uint64_t number)shaka::xml::XmlNode
SetStringAttribute(const char *attribute_name, const std::string &attribute)shaka::xml::XmlNode
XmlNode(const char *name)shaka::xml::XmlNodeexplicit
SetFloatingPointAttribute(const std::string &attribute_name, double number) WARN_UNUSED_RESULTshaka::xml::XmlNode
SetId(uint32_t id) WARN_UNUSED_RESULTshaka::xml::XmlNode
SetIntegerAttribute(const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULTshaka::xml::XmlNode
SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULTshaka::xml::XmlNode
ToString(const std::string &comment) constshaka::xml::XmlNode
XmlNode(const std::string &name)shaka::xml::XmlNodeexplicit
XmlNode(XmlNode &&) (defined in shaka::xml::XmlNode)shaka::xml::XmlNode
~AdaptationSetXmlNode() override (defined in shaka::xml::AdaptationSetXmlNode)shaka::xml::AdaptationSetXmlNode
~RepresentationBaseXmlNode() override (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
~XmlNode() (defined in shaka::xml::XmlNode)shaka::xml::XmlNodevirtual
diff --git a/docs/d0/dce/classshaka_1_1media_1_1RsaPrivateKey.html b/docs/d0/dce/classshaka_1_1media_1_1RsaPrivateKey.html index 58a8e4c41c..b55e475caa 100644 --- a/docs/d0/dce/classshaka_1_1media_1_1RsaPrivateKey.html +++ b/docs/d0/dce/classshaka_1_1media_1_1RsaPrivateKey.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::RsaPrivateKey Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-

Create an RsaPrivateKey object using a DER encoded PKCS#1 RSAPrivateKey.

Returns
The created RsaPrivateKey object on success, NULL otherwise.
+

Create an RsaPrivateKey object using a DER encoded PKCS#1 RSAPrivateKey.

Returns
The created RsaPrivateKey object on success, NULL otherwise.

Definition at line 96 of file rsa_key.cc.

@@ -203,9 +206,7 @@ Static Public Member Functions
diff --git a/docs/d0/dd0/structshaka_1_1media_1_1mp4_1_1CueSettingsBox.html b/docs/d0/dd0/structshaka_1_1media_1_1mp4_1_1CueSettingsBox.html index 1abe1fb86c..040bef33fc 100644 --- a/docs/d0/dd0/structshaka_1_1media_1_1mp4_1_1CueSettingsBox.html +++ b/docs/d0/dd0/structshaka_1_1media_1_1mp4_1_1CueSettingsBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CueSettingsBox Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 822 of file box_definitions.h.

+

Definition at line 840 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2776 of file box_definitions.cc.

+

Definition at line 2880 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d0/dd6/webm__crypto__helpers_8cc_source.html b/docs/d0/dd6/webm__crypto__helpers_8cc_source.html index 5b2b8a0534..dc5b3a558b 100644 --- a/docs/d0/dd6/webm__crypto__helpers_8cc_source.html +++ b/docs/d0/dd6/webm__crypto__helpers_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_crypto_helpers.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webm_crypto_helpers.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/webm/webm_crypto_helpers.h"
6 
7 #include "packager/base/logging.h"
8 #include "packager/base/sys_byteorder.h"
9 #include "packager/media/base/buffer_reader.h"
10 #include "packager/media/formats/webm/webm_constants.h"
11 
12 namespace shaka {
13 namespace media {
14 namespace {
15 
16 // Generates a 16 byte CTR counter block. The CTR counter block format is a
17 // CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV.
18 // |iv_size| is the size of |iv| in btyes. Returns a string of
19 // kDecryptionKeySize bytes.
20 std::vector<uint8_t> GenerateWebMCounterBlock(const uint8_t* iv, int iv_size) {
21  std::vector<uint8_t> counter_block(iv, iv + iv_size);
22  counter_block.insert(counter_block.end(),
24  return counter_block;
25 }
26 
27 } // namespace anonymous
28 
29 // TODO(tinskip): Add unit test for this function.
30 bool WebMCreateDecryptConfig(const uint8_t* data,
31  int data_size,
32  const uint8_t* key_id,
33  size_t key_id_size,
34  std::unique_ptr<DecryptConfig>* decrypt_config,
35  int* data_offset) {
36  int header_size = kWebMSignalByteSize;
37  if (data_size < header_size) {
38  DVLOG(1) << "Empty WebM sample.";
39  return false;
40  }
41  uint8_t signal_byte = data[0];
42 
43  if (signal_byte & kWebMEncryptedSignal) {
44  // Encrypted sample.
45  header_size += kWebMIvSize;
46  if (data_size < header_size) {
47  DVLOG(1) << "Encrypted WebM sample too small to hold IV: " << data_size;
48  return false;
49  }
50  std::vector<SubsampleEntry> subsamples;
51  if (signal_byte & kWebMPartitionedSignal) {
52  // Encrypted sample with subsamples / partitioning.
53  header_size += kWebMNumPartitionsSize;
54  if (data_size < header_size) {
55  DVLOG(1)
56  << "Encrypted WebM sample too small to hold number of partitions: "
57  << data_size;
58  return false;
59  }
60  uint8_t num_partitions = data[kWebMSignalByteSize + kWebMIvSize];
61  BufferReader offsets_buffer(data + header_size, data_size - header_size);
62  header_size += num_partitions * kWebMPartitionOffsetSize;
63  uint32_t subsample_offset = 0;
64  bool encrypted_subsample = false;
65  uint16_t clear_size = 0;
66  uint32_t encrypted_size = 0;
67  for (uint8_t partition_idx = 0; partition_idx < num_partitions;
68  ++partition_idx) {
69  uint32_t partition_offset;
70  if (!offsets_buffer.Read4(&partition_offset)) {
71  DVLOG(1)
72  << "Encrypted WebM sample too small to hold partition offsets: "
73  << data_size;
74  return false;
75  }
76  if (partition_offset < subsample_offset) {
77  DVLOG(1) << "Partition offsets out of order.";
78  return false;
79  }
80  if (encrypted_subsample) {
81  encrypted_size = partition_offset - subsample_offset;
82  subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
83  } else {
84  clear_size = partition_offset - subsample_offset;
85  if (partition_idx == (num_partitions - 1)) {
86  encrypted_size = data_size - header_size - subsample_offset - clear_size;
87  subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
88  }
89  }
90  subsample_offset = partition_offset;
91  encrypted_subsample = !encrypted_subsample;
92  }
93  if (!(num_partitions % 2)) {
94  // Even number of partitions. Add one last all-clear subsample.
95  clear_size = data_size - header_size - subsample_offset;
96  encrypted_size = 0;
97  subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
98  }
99  }
100  decrypt_config->reset(new DecryptConfig(
101  std::vector<uint8_t>(key_id, key_id + key_id_size),
102  GenerateWebMCounterBlock(data + kWebMSignalByteSize, kWebMIvSize),
103  subsamples));
104  } else {
105  // Clear sample.
106  decrypt_config->reset();
107  }
108 
109  *data_offset = header_size;
110  return true;
111 }
112 
113 } // namespace media
114 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
static const size_t kDecryptionKeySize
Keys are always 128 bits.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/webm/webm_crypto_helpers.h"
+
6 
+
7 #include "packager/base/logging.h"
+
8 #include "packager/base/sys_byteorder.h"
+
9 #include "packager/media/base/buffer_reader.h"
+
10 #include "packager/media/formats/webm/webm_constants.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 namespace {
+
15 
+
16 // Generates a 16 byte CTR counter block. The CTR counter block format is a
+
17 // CTR IV appended with a CTR block counter. |iv| is an 8 byte CTR IV.
+
18 // |iv_size| is the size of |iv| in btyes. Returns a string of
+
19 // kDecryptionKeySize bytes.
+
20 std::vector<uint8_t> GenerateWebMCounterBlock(const uint8_t* iv, int iv_size) {
+
21  std::vector<uint8_t> counter_block(iv, iv + iv_size);
+
22  counter_block.insert(counter_block.end(),
+ +
24  return counter_block;
+
25 }
+
26 
+
27 } // namespace anonymous
+
28 
+
29 // TODO(tinskip): Add unit test for this function.
+
30 bool WebMCreateDecryptConfig(const uint8_t* data,
+
31  int data_size,
+
32  const uint8_t* key_id,
+
33  size_t key_id_size,
+
34  std::unique_ptr<DecryptConfig>* decrypt_config,
+
35  int* data_offset) {
+
36  int header_size = kWebMSignalByteSize;
+
37  if (data_size < header_size) {
+
38  DVLOG(1) << "Empty WebM sample.";
+
39  return false;
+
40  }
+
41  uint8_t signal_byte = data[0];
+
42 
+
43  if (signal_byte & kWebMEncryptedSignal) {
+
44  // Encrypted sample.
+
45  header_size += kWebMIvSize;
+
46  if (data_size < header_size) {
+
47  DVLOG(1) << "Encrypted WebM sample too small to hold IV: " << data_size;
+
48  return false;
+
49  }
+
50  std::vector<SubsampleEntry> subsamples;
+
51  if (signal_byte & kWebMPartitionedSignal) {
+
52  // Encrypted sample with subsamples / partitioning.
+
53  header_size += kWebMNumPartitionsSize;
+
54  if (data_size < header_size) {
+
55  DVLOG(1)
+
56  << "Encrypted WebM sample too small to hold number of partitions: "
+
57  << data_size;
+
58  return false;
+
59  }
+
60  uint8_t num_partitions = data[kWebMSignalByteSize + kWebMIvSize];
+
61  BufferReader offsets_buffer(data + header_size, data_size - header_size);
+
62  header_size += num_partitions * kWebMPartitionOffsetSize;
+
63  uint32_t subsample_offset = 0;
+
64  bool encrypted_subsample = false;
+
65  uint16_t clear_size = 0;
+
66  uint32_t encrypted_size = 0;
+
67  for (uint8_t partition_idx = 0; partition_idx < num_partitions;
+
68  ++partition_idx) {
+
69  uint32_t partition_offset;
+
70  if (!offsets_buffer.Read4(&partition_offset)) {
+
71  DVLOG(1)
+
72  << "Encrypted WebM sample too small to hold partition offsets: "
+
73  << data_size;
+
74  return false;
+
75  }
+
76  if (partition_offset < subsample_offset) {
+
77  DVLOG(1) << "Partition offsets out of order.";
+
78  return false;
+
79  }
+
80  if (encrypted_subsample) {
+
81  encrypted_size = partition_offset - subsample_offset;
+
82  subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
+
83  } else {
+
84  clear_size = partition_offset - subsample_offset;
+
85  if (partition_idx == (num_partitions - 1)) {
+
86  encrypted_size = data_size - header_size - subsample_offset - clear_size;
+
87  subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
+
88  }
+
89  }
+
90  subsample_offset = partition_offset;
+
91  encrypted_subsample = !encrypted_subsample;
+
92  }
+
93  if (!(num_partitions % 2)) {
+
94  // Even number of partitions. Add one last all-clear subsample.
+
95  clear_size = data_size - header_size - subsample_offset;
+
96  encrypted_size = 0;
+
97  subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
+
98  }
+
99  }
+
100  decrypt_config->reset(new DecryptConfig(
+
101  std::vector<uint8_t>(key_id, key_id + key_id_size),
+
102  GenerateWebMCounterBlock(data + kWebMSignalByteSize, kWebMIvSize),
+
103  subsamples));
+
104  } else {
+
105  // Clear sample.
+
106  decrypt_config->reset();
+
107  }
+
108 
+
109  *data_offset = header_size;
+
110  return true;
+
111 }
+
112 
+
113 } // namespace media
+
114 } // namespace shaka
+
static const size_t kDecryptionKeySize
Keys are always 128 bits.
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/dd8/classshaka_1_1media_1_1AesCtrEncryptor.html b/docs/d0/dd8/classshaka_1_1media_1_1AesCtrEncryptor.html index c99cc0e67b..7b6d9c2416 100644 --- a/docs/d0/dd8/classshaka_1_1media_1_1AesCtrEncryptor.html +++ b/docs/d0/dd8/classshaka_1_1media_1_1AesCtrEncryptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AesCtrEncryptor Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::AesEncryptor shaka::media::AesCryptor - -
+ + @@ -116,8 +119,8 @@ bool  - @@ -141,9 +144,7 @@ AES_KEY * 

Public Member Functions

Crypt (const uint

Additional Inherited Members

- Public Types inherited from shaka::media::AesCryptor
enum  ConstantIvFlag { kUseConstantIv, -kDontUseConstantIv +
enum  ConstantIvFlag { kUseConstantIv +, kDontUseConstantIv }
 
- Static Public Member Functions inherited from shaka::media::AesCryptor
mutable_aes_key< diff --git a/docs/d0/de9/classshaka_1_1media_1_1DecoderSpecificInfoDescriptor.html b/docs/d0/de9/classshaka_1_1media_1_1DecoderSpecificInfoDescriptor.html index 31f27f5117..c226f3cf1d 100644 --- a/docs/d0/de9/classshaka_1_1media_1_1DecoderSpecificInfoDescriptor.html +++ b/docs/d0/de9/classshaka_1_1media_1_1DecoderSpecificInfoDescriptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::DecoderSpecificInfoDescriptor Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::BaseDescriptor - -
+ + @@ -115,7 +118,7 @@ void 

Public Member Functions

Detailed Description

Implements DecoderSpecificInfo descriptor according to ISO 14496-1:2004 7.2.6.7 DecoderSpecificInfo.

-

Definition at line 84 of file es_descriptor.h.

+

Definition at line 86 of file es_descriptor.h.


The documentation for this class was generated from the following files:
diff --git a/docs/d0/dea/classshaka_1_1media_1_1SyncPointQueue.html b/docs/d0/dea/classshaka_1_1media_1_1SyncPointQueue.html index ae6f0dfd8a..3bab8a16b8 100644 --- a/docs/d0/dea/classshaka_1_1media_1_1SyncPointQueue.html +++ b/docs/d0/dea/classshaka_1_1media_1_1SyncPointQueue.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SyncPointQueue Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
-
Returns
The next cue based on a previous hint. If a cue has been promoted that comes after hint_in_seconds it is returned. If no cue after hint_in_seconds has been promoted, this will block until either a cue is promoted or all threads are blocked (in which case, the unpromoted cue at hint_in_seconds will be self-promoted and returned) or Cancel() is called.
+
Returns
The next cue based on a previous hint. If a cue has been promoted that comes after hint_in_seconds it is returned. If no cue after hint_in_seconds has been promoted, this will block until either a cue is promoted or all threads are blocked (in which case, the unpromoted cue at hint_in_seconds will be self-promoted and returned) or Cancel() is called.

Definition at line 54 of file sync_point_queue.cc.

@@ -211,9 +214,7 @@ void  diff --git a/docs/d0/dee/segmenter__test__base_8h_source.html b/docs/d0/dee/segmenter__test__base_8h_source.html index b1f4f593ca..fa02d67215 100644 --- a/docs/d0/dee/segmenter__test__base_8h_source.html +++ b/docs/d0/dee/segmenter__test__base_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/segmenter_test_base.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
segmenter_test_base.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_TEST_UTILS_H_
8 #define PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_TEST_UTILS_H_
9 
10 #include <gtest/gtest.h>
11 
12 #include "packager/file/file_closer.h"
13 #include "packager/file/file_test_util.h"
14 #include "packager/file/memory_file.h"
15 #include "packager/media/base/media_sample.h"
16 #include "packager/media/base/muxer_options.h"
17 #include "packager/media/base/stream_info.h"
18 #include "packager/media/base/video_stream_info.h"
19 #include "packager/media/formats/webm/mkv_writer.h"
20 #include "packager/media/formats/webm/segmenter.h"
21 #include "packager/media/formats/webm/webm_parser.h"
22 #include "packager/status.h"
23 #include "packager/status_test_util.h"
24 
25 namespace shaka {
26 namespace media {
27 
28 class SegmentTestBase : public ::testing::Test {
29  public:
30  enum KeyFrameFlag {
31  kKeyFrame,
32  kNotKeyFrame,
33  };
34  enum SideDataFlag {
35  kGenerateSideData,
36  kNoSideData,
37  };
38 
39  protected:
41 
42  void SetUp() override;
43  void TearDown() override;
44 
46  template <typename S>
48  const MuxerOptions& options,
49  const StreamInfo& info,
50  std::unique_ptr<webm::Segmenter>* result) const {
51  std::unique_ptr<S> segmenter(new S(options));
52 
53  ASSERT_OK(segmenter->Initialize(info, nullptr /* progress_listener */,
54  nullptr /* muxer_listener */));
55  *result = std::move(segmenter);
56  }
57 
59  std::shared_ptr<MediaSample> CreateSample(KeyFrameFlag key_frame_flag,
60  uint64_t duration,
61  SideDataFlag side_data_flag);
65  VideoStreamInfo* CreateVideoStreamInfo(uint32_t time_scale) const;
66 
68  std::string OutputFileName() const;
70  std::string TemplateFileName(int number) const;
71 
72  protected:
73  // A helper class used to determine the number of clusters and frames for a
74  // given WebM file.
75  class ClusterParser : private WebMParserClient {
76  public:
77  ClusterParser();
78  ~ClusterParser() override;
79 
80  // Make sure to use ASSERT_NO_FATAL_FAILURE.
81  void PopulateFromCluster(const std::string& file_name);
82  void PopulateFromSegment(const std::string& file_name);
83 
84  size_t GetFrameCountForCluster(size_t cluster_index) const;
85  int64_t GetFrameTimecode(size_t cluster_index, size_t frame_index) const;
86 
87  size_t cluster_count() const;
88 
89  private:
90  // WebMParserClient overrides.
91  WebMParserClient* OnListStart(int id) override;
92  bool OnListEnd(int id) override;
93  bool OnUInt(int id, int64_t val) override;
94  bool OnFloat(int id, double val) override;
95  bool OnBinary(int id, const uint8_t* data, int size) override;
96  bool OnString(int id, const std::string& str) override;
97 
98  private:
99  int64_t cluster_timecode_ = -1;
100  // frame_timecodes_[cluster_index][frame_index].
101  std::vector<std::vector<int64_t>> frame_timecodes_;
102  bool in_cluster_ = false;
103  };
104 
105  protected:
106  void set_cur_timestamp(uint64_t timestamp) { cur_timestamp_ = timestamp; }
107 
108  std::string output_file_name_;
109  std::string segment_template_;
110  uint64_t cur_timestamp_;
111  bool single_segment_;
112 };
113 
114 } // namespace media
115 } // namespace shaka
116 
117 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_TEST_UTILS_H_
-
Abstract class holds stream information.
Definition: stream_info.h:62
-
VideoStreamInfo * CreateVideoStreamInfo(uint32_t time_scale) const
Creates a video stream info object for testing.
-
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
-
void CreateAndInitializeSegmenter(const MuxerOptions &options, const StreamInfo &info, std::unique_ptr< webm::Segmenter > *result) const
Creates a Segmenter of the given type and initializes it.
-
MuxerOptions CreateMuxerOptions() const
Creates a Muxer options object for testing.
-
std::shared_ptr< MediaSample > CreateSample(KeyFrameFlag key_frame_flag, uint64_t duration, SideDataFlag side_data_flag)
Creates a new media sample.
-
std::string OutputFileName() const
Gets the file name of the current output file.
-
std::string TemplateFileName(int number) const
Gets the file name of the given template file.
-
Holds video stream information.
- - +
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_TEST_UTILS_H_
+
8 #define PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_TEST_UTILS_H_
+
9 
+
10 #include <gtest/gtest.h>
+
11 
+
12 #include "packager/file/file_closer.h"
+
13 #include "packager/file/file_test_util.h"
+
14 #include "packager/file/memory_file.h"
+
15 #include "packager/media/base/media_sample.h"
+
16 #include "packager/media/base/muxer_options.h"
+
17 #include "packager/media/base/stream_info.h"
+
18 #include "packager/media/base/video_stream_info.h"
+
19 #include "packager/media/formats/webm/mkv_writer.h"
+
20 #include "packager/media/formats/webm/segmenter.h"
+
21 #include "packager/media/formats/webm/webm_parser.h"
+
22 #include "packager/status.h"
+
23 #include "packager/status_test_util.h"
+
24 
+
25 namespace shaka {
+
26 namespace media {
+
27 
+
28 class SegmentTestBase : public ::testing::Test {
+
29  public:
+
30  enum KeyFrameFlag {
+
31  kKeyFrame,
+
32  kNotKeyFrame,
+
33  };
+
34  enum SideDataFlag {
+
35  kGenerateSideData,
+
36  kNoSideData,
+
37  };
+
38 
+
39  protected:
+ +
41 
+
42  void SetUp() override;
+
43  void TearDown() override;
+
44 
+
46  template <typename S>
+ +
48  const MuxerOptions& options,
+
49  const StreamInfo& info,
+
50  std::unique_ptr<webm::Segmenter>* result) const {
+
51  std::unique_ptr<S> segmenter(new S(options));
+
52 
+
53  ASSERT_OK(segmenter->Initialize(info, nullptr /* progress_listener */,
+
54  nullptr /* muxer_listener */));
+
55  *result = std::move(segmenter);
+
56  }
+
57 
+
59  std::shared_ptr<MediaSample> CreateSample(KeyFrameFlag key_frame_flag,
+
60  uint64_t duration,
+
61  SideDataFlag side_data_flag);
+ +
65  VideoStreamInfo* CreateVideoStreamInfo(uint32_t time_scale) const;
+
66 
+
68  std::string OutputFileName() const;
+
70  std::string TemplateFileName(int number) const;
+
71 
+
72  protected:
+
73  // A helper class used to determine the number of clusters and frames for a
+
74  // given WebM file.
+
75  class ClusterParser : private WebMParserClient {
+
76  public:
+
77  ClusterParser();
+
78  ~ClusterParser() override;
+
79 
+
80  // Make sure to use ASSERT_NO_FATAL_FAILURE.
+
81  void PopulateFromCluster(const std::string& file_name);
+
82  void PopulateFromSegment(const std::string& file_name);
+
83 
+
84  size_t GetFrameCountForCluster(size_t cluster_index) const;
+
85  int64_t GetFrameTimecode(size_t cluster_index, size_t frame_index) const;
+
86 
+
87  size_t cluster_count() const;
+
88 
+
89  private:
+
90  // WebMParserClient overrides.
+
91  WebMParserClient* OnListStart(int id) override;
+
92  bool OnListEnd(int id) override;
+
93  bool OnUInt(int id, int64_t val) override;
+
94  bool OnFloat(int id, double val) override;
+
95  bool OnBinary(int id, const uint8_t* data, int size) override;
+
96  bool OnString(int id, const std::string& str) override;
+
97 
+
98  private:
+
99  int64_t cluster_timecode_ = -1;
+
100  // frame_timecodes_[cluster_index][frame_index].
+
101  std::vector<std::vector<int64_t>> frame_timecodes_;
+
102  bool in_cluster_ = false;
+
103  };
+
104 
+
105  protected:
+
106  void set_cur_timestamp(uint64_t timestamp) { cur_timestamp_ = timestamp; }
+
107 
+
108  std::string output_file_name_;
+
109  std::string segment_template_;
+
110  uint64_t cur_timestamp_;
+
111  bool single_segment_;
+
112 };
+
113 
+
114 } // namespace media
+
115 } // namespace shaka
+
116 
+
117 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_TEST_UTILS_H_
+ + +
std::string TemplateFileName(int number) const
Gets the file name of the given template file.
+
MuxerOptions CreateMuxerOptions() const
Creates a Muxer options object for testing.
+
void CreateAndInitializeSegmenter(const MuxerOptions &options, const StreamInfo &info, std::unique_ptr< webm::Segmenter > *result) const
Creates a Segmenter of the given type and initializes it.
+
std::string OutputFileName() const
Gets the file name of the current output file.
+
VideoStreamInfo * CreateVideoStreamInfo(uint32_t time_scale) const
Creates a video stream info object for testing.
+
std::shared_ptr< MediaSample > CreateSample(KeyFrameFlag key_frame_flag, uint64_t duration, SideDataFlag side_data_flag)
Creates a new media sample.
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
Holds video stream information.
+ +
All the methods that are virtual are virtual for mocking.
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
diff --git a/docs/d6/d2a/classshaka_1_1media_1_1WebVttTextOutputHandler.html b/docs/d0/df2/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler.html similarity index 85% rename from docs/d6/d2a/classshaka_1_1media_1_1WebVttTextOutputHandler.html rename to docs/d0/df2/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler.html index 0baa18ab39..d0215e3707 100644 --- a/docs/d6/d2a/classshaka_1_1media_1_1WebVttTextOutputHandler.html +++ b/docs/d0/df2/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler.html @@ -1,11 +1,11 @@ - + - + -Shaka Packager SDK: shaka::media::WebVttTextOutputHandler Class Reference +Shaka Packager SDK: shaka::media::ttml::TtmlToMp4Handler Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
-
shaka::media::WebVttTextOutputHandler Class Reference
+
shaka::media::ttml::TtmlToMp4Handler Class Reference
-Inheritance diagram for shaka::media::WebVttTextOutputHandler:
+Inheritance diagram for shaka::media::ttml::TtmlToMp4Handler:
- - -shaka::media::MediaHandler - -
+ + +shaka::media::MediaHandler + + - - - + @@ -99,14 +98,15 @@ Public Member Functions bool  -

-Public Member Functions

WebVttTextOutputHandler (const MuxerOptions &muxer_options, std::unique_ptr< MuxerListener > muxer_listener)
 

+Additional Inherited Members

- Public Member Functions inherited from shaka::media::MediaHandler
Status SetHandler (size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
IsConnected ()
 Validate if the handler is connected to its upstream handler.
 
- - - + + + + + @@ -160,17 +160,15 @@ const std::map< size_t, std::pair< std::shared_ptr<

Detailed Description

-

Definition at line 22 of file webvtt_text_output_handler.h.

+

Definition at line 22 of file ttml_to_mp4_handler.h.


The documentation for this class was generated from the following files: diff --git a/docs/d0/df2/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler.png b/docs/d0/df2/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler.png new file mode 100644 index 0000000000000000000000000000000000000000..be9efec8f1e27e9e40110f671a3b62ba5a96a3cc GIT binary patch literal 795 zcmeAS@N?(olHy`uVBq!ia0vp^cYrv6gBeJ=etRtdq$C1-LR|m<{|{uoc=NTi|Ih>= z3ycpOIKbL@M;^%KC<*clW&kPzfvcxNj2IZ0R(ZNOhEy=VoqMt9u>y}P|8?WP|NZYR zk(l6cZr9~4yA4W;f}7X3@=ZFaeY{X+b(iy`YggJPFOl5(P$kptZmajCTgUrVG_M@K zW_`M%b!U0h88!xm+;mj{4k{`#Zj`E|}lB#CU#5pPl&0=1qB#Kj+lexSKJT zC*~BS)(Czm*6|GgWgWx!gD2c+`UYNO=`*h$8h<-^-EDLIw{_pYKAom7gPZq}%1Ui-UkjqJq-QGDxKZa&&|{dSymY;;>e`hoHT zt+&nJ%v&9EfAie8TMIKzuPEByxApe>m<@+aV}5k)`1bFVb-CyV^;?^+uI00dEZK3h z=w`%5!zdjqUDcPZ@BW?hyi{_lV3NsVvpFhfSMaKP8fTU6cx=(<%KD-E7ehp-_TkzZ z9iQz+cbao!cP)MREtAt=xtYv?o?8VB##x6M&#d5OH&{$a;Dg-KDVJ6$F|Jt&Q~m0J z%}d{R?Q6@+f}dJh9g$mHyv_Xk$|s!$D-~M5A7p%2%owiMUY+--MdH~$#&Wy)$vGX zCud!Ckl5zNThk-Aw!VAVbx|+n`>HpaT8r1l&U^XmRO+k$u{Uc@hwKp8*}ggMf1aD> zjG!aAHy_PlE1Z(LdDGF-_p={p&0Ie#`?SD2pTrh!^TqeMh2CCP|FZ4W*Mc-<{awfO zjSs|{++Mxraa%om%=fUbQ@Opq9o?2wy19LJHS@8>t8TR|K9byW+{b#c@9Q6YotL`( zPJbxpdtiUby!dtj!+#g=!;Ce~(tHVSxfTtQU;oVX(Ohc!mECBsUVm-x;R0YvX7F_N Kb6Mw<&;$Sk3yEm} literal 0 HcmV?d00001 diff --git a/docs/d0/df3/packager__util_8cc_source.html b/docs/d0/df3/packager__util_8cc_source.html index 1f120f4955..9c7c4c1c10 100644 --- a/docs/d0/df3/packager__util_8cc_source.html +++ b/docs/d0/df3/packager__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/packager_util.cc Source File @@ -29,18 +29,21 @@

-Additional Inherited Members

- Static Public Member Functions inherited from shaka::media::MediaHandler
-static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
 
+static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
 
- Protected Member Functions inherited from shaka::media::MediaHandler
+virtual Status OnFlushRequest (size_t input_stream_index)
 Event handler for flush request at the specific input stream index.
 
virtual bool ValidateOutputStreamIndex (size_t stream_index) const
 Validate if the stream at the specified index actually exists.
- + +/* @license-end */
packager_util.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/packager_util.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/base/strings/string_number_conversions.h"
11 #include "packager/base/strings/string_split.h"
12 #include "packager/file/file.h"
13 #include "packager/media/base/media_handler.h"
14 #include "packager/media/base/muxer_options.h"
15 #include "packager/media/base/playready_key_source.h"
16 #include "packager/media/base/raw_key_source.h"
17 #include "packager/media/base/request_signer.h"
18 #include "packager/media/base/widevine_key_source.h"
19 #include "packager/mpd/base/mpd_options.h"
20 #include "packager/status.h"
21 
22 namespace shaka {
23 namespace media {
24 namespace {
25 
26 std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
27  std::unique_ptr<RequestSigner> request_signer;
28  switch (signer.signing_key_type) {
29  case WidevineSigner::SigningKeyType::kAes:
30  request_signer.reset(AesRequestSigner::CreateSigner(
31  signer.signer_name, signer.aes.key, signer.aes.iv));
32  break;
33  case WidevineSigner::SigningKeyType::kRsa:
34  request_signer.reset(
35  RsaRequestSigner::CreateSigner(signer.signer_name, signer.rsa.key));
36  break;
37  case WidevineSigner::SigningKeyType::kNone:
38  break;
39  }
40  if (!request_signer)
41  LOG(ERROR) << "Failed to create the signer object.";
42  return request_signer;
43 }
44 
45 int GetProtectionSystemsFlag(
46  const std::vector<EncryptionParams::ProtectionSystem>& protection_systems) {
47  int protection_systems_flags = 0;
48  for (const auto protection_system : protection_systems) {
49  switch (protection_system) {
50  case EncryptionParams::ProtectionSystem::kCommonSystem:
51  protection_systems_flags |= COMMON_PROTECTION_SYSTEM_FLAG;
52  break;
53  case EncryptionParams::ProtectionSystem::kFairPlay:
54  protection_systems_flags |= FAIRPLAY_PROTECTION_SYSTEM_FLAG;
55  break;
56  case EncryptionParams::ProtectionSystem::kMarlin:
57  protection_systems_flags |= MARLIN_PROTECTION_SYSTEM_FLAG;
58  break;
59  case EncryptionParams::ProtectionSystem::kPlayReady:
60  protection_systems_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG;
61  break;
62  case EncryptionParams::ProtectionSystem::kWidevine:
63  protection_systems_flags |= WIDEVINE_PROTECTION_SYSTEM_FLAG;
64  break;
65  }
66  }
67  return protection_systems_flags;
68 }
69 
70 } // namespace
71 
72 std::unique_ptr<KeySource> CreateEncryptionKeySource(
73  FourCC protection_scheme,
74  const EncryptionParams& encryption_params) {
75  int protection_systems_flags =
76  GetProtectionSystemsFlag(encryption_params.protection_systems);
77 
78  std::unique_ptr<KeySource> encryption_key_source;
79  switch (encryption_params.key_provider) {
80  case KeyProvider::kWidevine: {
81  const WidevineEncryptionParams& widevine = encryption_params.widevine;
82  if (widevine.key_server_url.empty()) {
83  LOG(ERROR) << "'key_server_url' should not be empty.";
84  return nullptr;
85  }
86  if (widevine.content_id.empty()) {
87  LOG(ERROR) << "'content_id' should not be empty.";
88  return nullptr;
89  }
90  std::unique_ptr<WidevineKeySource> widevine_key_source(
91  new WidevineKeySource(widevine.key_server_url,
92  protection_systems_flags, protection_scheme));
93  if (!widevine.signer.signer_name.empty()) {
94  std::unique_ptr<RequestSigner> request_signer(
95  CreateSigner(widevine.signer));
96  if (!request_signer)
97  return nullptr;
98  widevine_key_source->set_signer(std::move(request_signer));
99  }
100  widevine_key_source->set_group_id(widevine.group_id);
101  widevine_key_source->set_enable_entitlement_license(
102  widevine.enable_entitlement_license);
103 
104  Status status =
105  widevine_key_source->FetchKeys(widevine.content_id, widevine.policy);
106  if (!status.ok()) {
107  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
108  << status.ToString();
109  return nullptr;
110  }
111  encryption_key_source = std::move(widevine_key_source);
112  break;
113  }
114  case KeyProvider::kRawKey: {
115  encryption_key_source =
116  RawKeySource::Create(encryption_params.raw_key,
117  protection_systems_flags, protection_scheme);
118  break;
119  }
120  case KeyProvider::kPlayReady: {
121  const PlayReadyEncryptionParams& playready = encryption_params.playready;
122  if (!playready.key_server_url.empty() ||
123  !playready.program_identifier.empty()) {
124  if (playready.key_server_url.empty() ||
125  playready.program_identifier.empty()) {
126  LOG(ERROR) << "Either PlayReady key_server_url or program_identifier "
127  "is not set.";
128  return nullptr;
129  }
130  std::unique_ptr<PlayReadyKeySource> playready_key_source;
131  // private_key_password is allowed to be empty for unencrypted key.
132  if (!playready.client_cert_file.empty() ||
133  !playready.client_cert_private_key_file.empty()) {
134  if (playready.client_cert_file.empty() ||
135  playready.client_cert_private_key_file.empty()) {
136  LOG(ERROR) << "Either PlayReady client_cert_file or "
137  "client_cert_private_key_file is not set.";
138  return nullptr;
139  }
140  playready_key_source.reset(new PlayReadyKeySource(
141  playready.key_server_url, playready.client_cert_file,
142  playready.client_cert_private_key_file,
143  playready.client_cert_private_key_password,
144  protection_systems_flags, protection_scheme));
145  } else {
146  playready_key_source.reset(new PlayReadyKeySource(
147  playready.key_server_url, protection_systems_flags,
148  protection_scheme));
149  }
150  if (!playready.ca_file.empty()) {
151  playready_key_source->SetCaFile(playready.ca_file);
152  }
153  Status status = playready_key_source->FetchKeysWithProgramIdentifier(
154  playready.program_identifier);
155  if (!status.ok()) {
156  LOG(ERROR) << "PlayReady encryption key source failed to fetch keys: "
157  << status.ToString();
158  return nullptr;
159  }
160  encryption_key_source = std::move(playready_key_source);
161  } else {
162  LOG(ERROR) << "Error creating PlayReady key source.";
163  return nullptr;
164  }
165  break;
166  }
167  case KeyProvider::kNone:
168  break;
169  }
170  return encryption_key_source;
171 }
172 
173 std::unique_ptr<KeySource> CreateDecryptionKeySource(
174  const DecryptionParams& decryption_params) {
175  std::unique_ptr<KeySource> decryption_key_source;
176  switch (decryption_params.key_provider) {
177  case KeyProvider::kWidevine: {
178  const WidevineDecryptionParams& widevine = decryption_params.widevine;
179  if (widevine.key_server_url.empty()) {
180  LOG(ERROR) << "'key_server_url' should not be empty.";
181  return std::unique_ptr<KeySource>();
182  }
183  std::unique_ptr<WidevineKeySource> widevine_key_source(
184  new WidevineKeySource(
185  widevine.key_server_url,
186  WIDEVINE_PROTECTION_SYSTEM_FLAG /* value does not matter here */,
187  FOURCC_NULL /* value does not matter here */));
188  if (!widevine.signer.signer_name.empty()) {
189  std::unique_ptr<RequestSigner> request_signer(
190  CreateSigner(widevine.signer));
191  if (!request_signer)
192  return std::unique_ptr<KeySource>();
193  widevine_key_source->set_signer(std::move(request_signer));
194  }
195 
196  decryption_key_source = std::move(widevine_key_source);
197  break;
198  }
199  case KeyProvider::kRawKey: {
200  decryption_key_source = RawKeySource::Create(
201  decryption_params.raw_key,
202  COMMON_PROTECTION_SYSTEM_FLAG /* value does not matter here */,
203  FOURCC_NULL /* value does not matter here */);
204  break;
205  }
206  case KeyProvider::kNone:
207  case KeyProvider::kPlayReady:
208  break;
209  }
210  return decryption_key_source;
211 }
212 
213 MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) {
214  MpdOptions mpd_options;
215  mpd_options.dash_profile =
216  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
217  mpd_options.mpd_type =
218  (on_demand_profile || mpd_params.generate_static_live_mpd)
219  ? MpdType::kStatic
220  : MpdType::kDynamic;
221  mpd_options.mpd_params = mpd_params;
222  return mpd_options;
223 }
224 
225 } // namespace media
226 } // namespace shaka
static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
-
std::string ToString() const
Definition: status.cc:83
-
static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key, int protection_system_flags, FourCC protection_scheme)
-
static AesRequestSigner * CreateSigner(const std::string &signer_name, const std::vector< uint8_t > &aes_key, const std::vector< uint8_t > &iv)
-
All the methods that are virtual are virtual for mocking.
-
void SetCaFile(const std::string &ca_file)
Sets the Certificate Authority file for validating self-signed certificates.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/app/packager_util.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/base/strings/string_number_conversions.h"
+
11 #include "packager/base/strings/string_split.h"
+
12 #include "packager/file/file.h"
+
13 #include "packager/media/base/media_handler.h"
+
14 #include "packager/media/base/muxer_options.h"
+
15 #include "packager/media/base/playready_key_source.h"
+
16 #include "packager/media/base/raw_key_source.h"
+
17 #include "packager/media/base/request_signer.h"
+
18 #include "packager/media/base/widevine_key_source.h"
+
19 #include "packager/mpd/base/mpd_options.h"
+
20 #include "packager/status.h"
+
21 
+
22 namespace shaka {
+
23 namespace media {
+
24 namespace {
+
25 
+
26 std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
+
27  std::unique_ptr<RequestSigner> request_signer;
+
28  switch (signer.signing_key_type) {
+
29  case WidevineSigner::SigningKeyType::kAes:
+
30  request_signer.reset(AesRequestSigner::CreateSigner(
+
31  signer.signer_name, signer.aes.key, signer.aes.iv));
+
32  break;
+
33  case WidevineSigner::SigningKeyType::kRsa:
+
34  request_signer.reset(
+
35  RsaRequestSigner::CreateSigner(signer.signer_name, signer.rsa.key));
+
36  break;
+
37  case WidevineSigner::SigningKeyType::kNone:
+
38  break;
+
39  }
+
40  if (!request_signer)
+
41  LOG(ERROR) << "Failed to create the signer object.";
+
42  return request_signer;
+
43 }
+
44 
+
45 } // namespace
+
46 
+
47 std::unique_ptr<KeySource> CreateEncryptionKeySource(
+
48  FourCC protection_scheme,
+
49  const EncryptionParams& encryption_params) {
+
50  std::unique_ptr<KeySource> encryption_key_source;
+
51  switch (encryption_params.key_provider) {
+
52  case KeyProvider::kWidevine: {
+
53  const WidevineEncryptionParams& widevine = encryption_params.widevine;
+
54  if (widevine.key_server_url.empty()) {
+
55  LOG(ERROR) << "'key_server_url' should not be empty.";
+
56  return nullptr;
+
57  }
+
58  if (widevine.content_id.empty()) {
+
59  LOG(ERROR) << "'content_id' should not be empty.";
+
60  return nullptr;
+
61  }
+
62  std::unique_ptr<WidevineKeySource> widevine_key_source(
+
63  new WidevineKeySource(widevine.key_server_url,
+
64  encryption_params.protection_systems,
+
65  protection_scheme));
+
66  if (!widevine.signer.signer_name.empty()) {
+
67  std::unique_ptr<RequestSigner> request_signer(
+
68  CreateSigner(widevine.signer));
+
69  if (!request_signer)
+
70  return nullptr;
+
71  widevine_key_source->set_signer(std::move(request_signer));
+
72  }
+
73  widevine_key_source->set_group_id(widevine.group_id);
+
74  widevine_key_source->set_enable_entitlement_license(
+
75  widevine.enable_entitlement_license);
+
76 
+
77  Status status =
+
78  widevine_key_source->FetchKeys(widevine.content_id, widevine.policy);
+
79  if (!status.ok()) {
+
80  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
+
81  << status.ToString();
+
82  return nullptr;
+
83  }
+
84  encryption_key_source = std::move(widevine_key_source);
+
85  break;
+
86  }
+
87  case KeyProvider::kRawKey: {
+
88  encryption_key_source = RawKeySource::Create(encryption_params.raw_key);
+
89  break;
+
90  }
+
91  case KeyProvider::kPlayReady: {
+
92  const PlayReadyEncryptionParams& playready = encryption_params.playready;
+
93  if (!playready.key_server_url.empty() ||
+
94  !playready.program_identifier.empty()) {
+
95  if (playready.key_server_url.empty() ||
+
96  playready.program_identifier.empty()) {
+
97  LOG(ERROR) << "Either PlayReady key_server_url or program_identifier "
+
98  "is not set.";
+
99  return nullptr;
+
100  }
+
101  std::unique_ptr<PlayReadyKeySource> playready_key_source;
+
102  // private_key_password is allowed to be empty for unencrypted key.
+
103  playready_key_source.reset(new PlayReadyKeySource(
+
104  playready.key_server_url, encryption_params.protection_systems));
+
105  Status status = playready_key_source->FetchKeysWithProgramIdentifier(
+
106  playready.program_identifier);
+
107  if (!status.ok()) {
+
108  LOG(ERROR) << "PlayReady encryption key source failed to fetch keys: "
+
109  << status.ToString();
+
110  return nullptr;
+
111  }
+
112  encryption_key_source = std::move(playready_key_source);
+
113  } else {
+
114  LOG(ERROR) << "Error creating PlayReady key source.";
+
115  return nullptr;
+
116  }
+
117  break;
+
118  }
+
119  default:
+
120  break;
+
121  }
+
122  return encryption_key_source;
+
123 }
+
124 
+
125 std::unique_ptr<KeySource> CreateDecryptionKeySource(
+
126  const DecryptionParams& decryption_params) {
+
127  std::unique_ptr<KeySource> decryption_key_source;
+
128  switch (decryption_params.key_provider) {
+
129  case KeyProvider::kWidevine: {
+
130  const WidevineDecryptionParams& widevine = decryption_params.widevine;
+
131  if (widevine.key_server_url.empty()) {
+
132  LOG(ERROR) << "'key_server_url' should not be empty.";
+
133  return std::unique_ptr<KeySource>();
+
134  }
+
135  std::unique_ptr<WidevineKeySource> widevine_key_source(
+
136  new WidevineKeySource(
+
137  widevine.key_server_url,
+
138  ProtectionSystem::kWidevine /* value does not matter here */,
+
139  FOURCC_NULL /* value does not matter here */));
+
140  if (!widevine.signer.signer_name.empty()) {
+
141  std::unique_ptr<RequestSigner> request_signer(
+
142  CreateSigner(widevine.signer));
+
143  if (!request_signer)
+
144  return std::unique_ptr<KeySource>();
+
145  widevine_key_source->set_signer(std::move(request_signer));
+
146  }
+
147 
+
148  decryption_key_source = std::move(widevine_key_source);
+
149  break;
+
150  }
+
151  case KeyProvider::kRawKey: {
+
152  decryption_key_source = RawKeySource::Create(decryption_params.raw_key);
+
153  break;
+
154  }
+
155  default:
+
156  break;
+
157  }
+
158  return decryption_key_source;
+
159 }
+
160 
+
161 MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) {
+
162  MpdOptions mpd_options;
+
163  mpd_options.dash_profile =
+
164  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
+
165  mpd_options.mpd_type =
+
166  (on_demand_profile || mpd_params.generate_static_live_mpd)
+
167  ? MpdType::kStatic
+
168  : MpdType::kDynamic;
+
169  mpd_options.mpd_params = mpd_params;
+
170  return mpd_options;
+
171 }
+
172 
+
173 } // namespace media
+
174 } // namespace shaka
+
static AesRequestSigner * CreateSigner(const std::string &signer_name, const std::vector< uint8_t > &aes_key, const std::vector< uint8_t > &iv)
+
static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key)
+
static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d0/df4/classshaka_1_1hls_1_1MasterPlaylist-members.html b/docs/d0/df4/classshaka_1_1hls_1_1MasterPlaylist-members.html index 1c5e33c18b..d2cff65199 100644 --- a/docs/d0/df4/classshaka_1_1hls_1_1MasterPlaylist-members.html +++ b/docs/d0/df4/classshaka_1_1hls_1_1MasterPlaylist-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::hls::MasterPlaylist, including all inherited members.

- - + +
MasterPlaylist(const std::string &file_name, const std::string &default_audio_language, const std::string &default_text_language)shaka::hls::MasterPlaylist
WriteMasterPlaylist(const std::string &base_url, const std::string &output_dir, const std::list< MediaPlaylist *> &playlists)shaka::hls::MasterPlaylistvirtual
MasterPlaylist(const std::string &file_name, const std::string &default_audio_language, const std::string &default_text_language, const bool is_independent_segments)shaka::hls::MasterPlaylist
WriteMasterPlaylist(const std::string &base_url, const std::string &output_dir, const std::list< MediaPlaylist * > &playlists)shaka::hls::MasterPlaylistvirtual
~MasterPlaylist() (defined in shaka::hls::MasterPlaylist)shaka::hls::MasterPlaylistvirtual
diff --git a/docs/d0/dfc/structshaka_1_1media_1_1mp4_1_1AudioSampleEntry-members.html b/docs/d0/dfc/structshaka_1_1media_1_1mp4_1_1AudioSampleEntry-members.html index b4ba256aa0..028c20ec78 100644 --- a/docs/d0/dfc/structshaka_1_1media_1_1mp4_1_1AudioSampleEntry-members.html +++ b/docs/d0/dfc/structshaka_1_1media_1_1mp4_1_1AudioSampleEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
channelcount (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry ComputeSize()shaka::media::mp4::Box dac3 (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - data_reference_index (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - ddts (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - dec3 (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - dfla (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - dops (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - esds (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - format (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - GetActualFormat() const (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntryinline - HeaderSize() constshaka::media::mp4::Boxvirtual - Parse(BoxReader *reader)shaka::media::mp4::Box - ReadWriteHeaderInternal(BoxBuffer *buffer)shaka::media::mp4::Boxprotectedvirtual - samplerate (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - samplesize (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - sinf (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - Write(BufferWriter *writer)shaka::media::mp4::Box - WriteHeader(BufferWriter *writer)shaka::media::mp4::Box - ~ AudioSampleEntry() override (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry - ~Box() (defined in shaka::media::mp4::Box)shaka::media::mp4::Boxvirtual + dac4 (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + data_reference_index (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + ddts (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + dec3 (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + dfla (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + dops (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + esds (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + format (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + GetActualFormat() const (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntryinline + HeaderSize() constshaka::media::mp4::Boxvirtual + Parse(BoxReader *reader)shaka::media::mp4::Box + ReadWriteHeaderInternal(BoxBuffer *buffer)shaka::media::mp4::Boxprotectedvirtual + samplerate (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + samplesize (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + sinf (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + Write(BufferWriter *writer)shaka::media::mp4::Box + WriteHeader(BufferWriter *writer)shaka::media::mp4::Box + ~ AudioSampleEntry() override (defined in shaka::media::mp4::AudioSampleEntry)shaka::media::mp4::AudioSampleEntry + ~Box() (defined in shaka::media::mp4::Box)shaka::media::mp4::Boxvirtual
diff --git a/docs/d1/d03/structshaka_1_1media_1_1MuxerListener_1_1MediaRanges.html b/docs/d1/d03/structshaka_1_1media_1_1MuxerListener_1_1MediaRanges.html index f421d718f4..310a22ef83 100644 --- a/docs/d1/d03/structshaka_1_1media_1_1MuxerListener_1_1MediaRanges.html +++ b/docs/d1/d03/structshaka_1_1media_1_1MuxerListener_1_1MediaRanges.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MuxerListener::MediaRanges Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d07/structshaka_1_1AdCueGeneratorParams-members.html b/docs/d1/d07/structshaka_1_1AdCueGeneratorParams-members.html index cc3de4edfe..6a70959801 100644 --- a/docs/d1/d07/structshaka_1_1AdCueGeneratorParams-members.html +++ b/docs/d1/d07/structshaka_1_1AdCueGeneratorParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d07/structshaka_1_1Cuepoint-members.html b/docs/d1/d07/structshaka_1_1Cuepoint-members.html index f3a5b40e2b..6c9a64dcb8 100644 --- a/docs/d1/d07/structshaka_1_1Cuepoint-members.html +++ b/docs/d1/d07/structshaka_1_1Cuepoint-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d0a/classshaka_1_1media_1_1MkvWriter.html b/docs/d1/d0a/classshaka_1_1media_1_1MkvWriter.html index 8063759684..9516924cb9 100644 --- a/docs/d1/d0a/classshaka_1_1media_1_1MkvWriter.html +++ b/docs/d1/d0a/classshaka_1_1media_1_1MkvWriter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MkvWriter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-

An implementation of IMkvWriter using our File type. +

An implementation of IMkvWriter using our File type. More...

#include <mkv_writer.h>

@@ -78,9 +81,7 @@ $(function() { Inheritance diagram for shaka::media::MkvWriter:
- - - +

@@ -110,7 +111,7 @@ Public Member Functions

 

Detailed Description

-

An implementation of IMkvWriter using our File type.

+

An implementation of IMkvWriter using our File type.

Definition at line 21 of file mkv_writer.h.

Member Function Documentation

@@ -231,7 +232,7 @@ Public Member Functions
-

Set the current File position.

Returns
0 on success.
+

Set the current File position.

Returns
0 on success.

Definition at line 78 of file mkv_writer.cc.

@@ -363,9 +364,7 @@ Public Member Functions
diff --git a/docs/d1/d0a/classshaka_1_1media_1_1MkvWriter.png b/docs/d1/d0a/classshaka_1_1media_1_1MkvWriter.png index ca4a940a412016dfa02f949989489eb0c6651271..4eab85666317d012832de0aebfbc868c59ca98b3 100644 GIT binary patch delta 572 zcmcb>(!)9-x}Hhe)5S5Qg7NL#)6*6k@VKluTlxS0<2J_IpPGBDCbyoKSsKgE6I7`C zFs*y$&AdY@nfj_zR9vS7OcJ>$e8qi*d(g?^iRdTgF=YFKxxGH|HKPW^JnAzq&@H*m;>*n|N8n zC$W7>&gS*ZSHn~%ODn%)G2QF*_uud7-+mU9pZvZcPxj=Uh}<2jA^8*MOM3oVD&#du z$xFktOJkvm<|5`(XL5`gYdq`q8}4pVzVdpj;?=$Y_RDo4(N0g_F?VP#WB{sd=n&#k zSk%JQp@EzGUlwSRc_KqKObgqJc?Kt{TY4v^+TF8KcjaGsznN)Q;hR@Q72IDZ++DE# z!RdE@;sdW2`o`?xwtQS4o+ul_`C{R@BcCguKfV3BZDm0DyM%{6Sq+CHp8Ys;@rdF% zVA#lp#NYZ|=-ewm?cU6g+uX18oWkYGGgsW-RJ&D__tmVPfO3!PPwm!-ZnDkbEnR*t z;Ph92{j~6vPm9!7xLy99^x_%UtA(1Um+!4!zAQE@e&N4!>2I@3S52OmvDNf<%#EzW zx(oljJAIzVA%>GxAkc}?Wl8{p;9U7yzopr08e=j AtpET3 delta 511 zcmVWnX!ms0*#lH&YOs;XU= z%Gd8#%o$(Wk`&{O^0jIE?I?CC%*Jggk`&-aQZ)%KJ;S3Ze}9q`iAcNxFxGlv=`PA0wrW`+6x*MbqdrH+LxbzH-pK z*Foujx=byXdy~3sd@ZJGuB4t6WjWicJ#{-}eGB + - + Shaka Packager SDK: shaka::media::H264Sps Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
chroma_array_type<

Detailed Description

Definition at line 37 of file h264_parser.h.

-

The documentation for this struct was generated from the following files:
    +

The documentation for this struct was generated from the following file: diff --git a/docs/d1/d0b/hevc__decoder__configuration__record_8cc_source.html b/docs/d1/d0b/hevc__decoder__configuration__record_8cc_source.html index f012d039c7..cdd8ed06a4 100644 --- a/docs/d1/d0b/hevc__decoder__configuration__record_8cc_source.html +++ b/docs/d1/d0b/hevc__decoder__configuration__record_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/hevc_decoder_configuration_record.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
hevc_decoder_configuration_record.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
8 
9 #include "packager/base/strings/string_number_conversions.h"
10 #include "packager/base/strings/string_util.h"
11 #include "packager/media/base/buffer_reader.h"
12 #include "packager/media/base/rcheck.h"
13 #include "packager/media/codecs/h265_parser.h"
14 
15 namespace shaka {
16 namespace media {
17 
18 namespace {
19 
20 // ISO/IEC 14496-15:2014 Annex E.
21 std::string GeneralProfileSpaceAsString(uint8_t general_profile_space) {
22  switch (general_profile_space) {
23  case 0:
24  return "";
25  case 1:
26  return "A";
27  case 2:
28  return "B";
29  case 3:
30  return "C";
31  default:
32  LOG(WARNING) << "Unexpected general_profile_space "
33  << general_profile_space;
34  return "";
35  }
36 }
37 
38 std::string TrimLeadingZeros(const std::string& str) {
39  DCHECK_GT(str.size(), 0u);
40  for (size_t i = 0; i < str.size(); ++i) {
41  if (str[i] == '0') continue;
42  return str.substr(i);
43  }
44  return "0";
45 }
46 
47 // Encode the 32 bits input, but in reverse bit order, i.e. bit [31] as the most
48 // significant bit, followed by, bit [30], and down to bit [0] as the least
49 // significant bit, where bits [i] for i in the range of 0 to 31, inclusive, are
50 // specified in ISO/IEC 23008‐2, encoded in hexadecimal (leading zeroes may be
51 // omitted).
52 std::string ReverseBitsAndHexEncode(uint32_t x) {
53  x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1);
54  x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2);
55  x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4);
56  const uint8_t bytes[] = {static_cast<uint8_t>(x & 0xFF),
57  static_cast<uint8_t>((x >> 8) & 0xFF),
58  static_cast<uint8_t>((x >> 16) & 0xFF),
59  static_cast<uint8_t>((x >> 24) & 0xFF)};
60  return TrimLeadingZeros(base::HexEncode(bytes, arraysize(bytes)));
61 }
62 
63 } // namespace
64 
65 HEVCDecoderConfigurationRecord::HEVCDecoderConfigurationRecord() = default;
66 
67 HEVCDecoderConfigurationRecord::~HEVCDecoderConfigurationRecord() = default;
68 
69 bool HEVCDecoderConfigurationRecord::ParseInternal() {
70  BufferReader reader(data(), data_size());
71 
72  uint8_t profile_indication = 0;
73  uint8_t length_size_minus_one = 0;
74  uint8_t num_of_arrays = 0;
75  RCHECK(reader.Read1(&version_) && version_ == 1 &&
76  reader.Read1(&profile_indication) &&
77  reader.Read4(&general_profile_compatibility_flags_) &&
78  reader.ReadToVector(&general_constraint_indicator_flags_, 6) &&
79  reader.Read1(&general_level_idc_) &&
80  reader.SkipBytes(8) && // Skip uninterested fields.
81  reader.Read1(&length_size_minus_one) &&
82  reader.Read1(&num_of_arrays));
83 
84  general_profile_space_ = profile_indication >> 6;
85  RCHECK(general_profile_space_ <= 3u);
86  general_tier_flag_ = ((profile_indication >> 5) & 1) == 1;
87  general_profile_idc_ = profile_indication & 0x1f;
88 
89  if ((length_size_minus_one & 0x3) == 2) {
90  LOG(ERROR) << "Invalid NALU length size.";
91  return false;
92  }
93  set_nalu_length_size((length_size_minus_one & 0x3) + 1);
94 
95  for (int i = 0; i < num_of_arrays; i++) {
96  uint8_t nal_unit_type;
97  uint16_t num_nalus;
98  RCHECK(reader.Read1(&nal_unit_type));
99  nal_unit_type &= 0x3f;
100  RCHECK(reader.Read2(&num_nalus));
101  for (int j = 0; j < num_nalus; j++) {
102  uint16_t nalu_length;
103  RCHECK(reader.Read2(&nalu_length));
104  uint64_t nalu_offset = reader.pos();
105  RCHECK(reader.SkipBytes(nalu_length));
106 
107  Nalu nalu;
108  RCHECK(nalu.Initialize(Nalu::kH265, data() + nalu_offset, nalu_length));
109  RCHECK(nalu.type() == nal_unit_type);
110  AddNalu(nalu);
111 
112  if (nalu.type() == Nalu::H265_SPS) {
113  H265Parser parser;
114  int sps_id = 0;
115  RCHECK(parser.ParseSps(nalu, &sps_id) == H265Parser::kOk);
117  parser.GetSps(sps_id)->vui_parameters.transfer_characteristics);
118  }
119  }
120  }
121 
122  // TODO(kqyang): Parse SPS to get resolutions.
123  return true;
124 }
125 
127  FourCC codec_fourcc) const {
128  // ISO/IEC 14496-15:2014 Annex E.
129  std::vector<std::string> fields;
130  fields.push_back(FourCCToString(codec_fourcc));
131  fields.push_back(GeneralProfileSpaceAsString(general_profile_space_) +
132  base::IntToString(general_profile_idc_));
133  fields.push_back(
134  ReverseBitsAndHexEncode(general_profile_compatibility_flags_));
135  fields.push_back((general_tier_flag_ ? "H" : "L") +
136  base::IntToString(general_level_idc_));
137 
138  // Remove trailing bytes that are zero.
139  std::vector<uint8_t> constraints = general_constraint_indicator_flags_;
140  size_t size = constraints.size();
141  for (; size > 0; --size) {
142  if (constraints[size - 1] != 0) break;
143  }
144  constraints.resize(size);
145  for (uint8_t constraint : constraints)
146  fields.push_back(TrimLeadingZeros(base::HexEncode(&constraint, 1)));
147 
148  return base::JoinString(fields, ".");
149 }
150 
151 } // namespace media
152 } // namespace shaka
void AddNalu(const Nalu &nalu)
Adds the given Nalu to the configuration.
- -
All the methods that are virtual are virtual for mocking.
-
void set_transfer_characteristics(uint8_t transfer_characteristics)
Sets the transfer characteristics.
-
void set_nalu_length_size(uint8_t nalu_length_size)
Sets the size of the NAL unit length field.
- - - +
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
+
8 
+
9 #include "packager/base/strings/string_number_conversions.h"
+
10 #include "packager/base/strings/string_util.h"
+
11 #include "packager/media/base/buffer_reader.h"
+
12 #include "packager/media/base/rcheck.h"
+
13 #include "packager/media/codecs/h265_parser.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 
+
18 namespace {
+
19 
+
20 // ISO/IEC 14496-15:2014 Annex E.
+
21 std::string GeneralProfileSpaceAsString(uint8_t general_profile_space) {
+
22  switch (general_profile_space) {
+
23  case 0:
+
24  return "";
+
25  case 1:
+
26  return "A";
+
27  case 2:
+
28  return "B";
+
29  case 3:
+
30  return "C";
+
31  default:
+
32  LOG(WARNING) << "Unexpected general_profile_space "
+
33  << general_profile_space;
+
34  return "";
+
35  }
+
36 }
+
37 
+
38 std::string TrimLeadingZeros(const std::string& str) {
+
39  DCHECK_GT(str.size(), 0u);
+
40  for (size_t i = 0; i < str.size(); ++i) {
+
41  if (str[i] == '0') continue;
+
42  return str.substr(i);
+
43  }
+
44  return "0";
+
45 }
+
46 
+
47 // Encode the 32 bits input, but in reverse bit order, i.e. bit [31] as the most
+
48 // significant bit, followed by, bit [30], and down to bit [0] as the least
+
49 // significant bit, where bits [i] for i in the range of 0 to 31, inclusive, are
+
50 // specified in ISO/IEC 23008‐2, encoded in hexadecimal (leading zeroes may be
+
51 // omitted).
+
52 std::string ReverseBitsAndHexEncode(uint32_t x) {
+
53  x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1);
+
54  x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2);
+
55  x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4);
+
56  const uint8_t bytes[] = {static_cast<uint8_t>(x & 0xFF),
+
57  static_cast<uint8_t>((x >> 8) & 0xFF),
+
58  static_cast<uint8_t>((x >> 16) & 0xFF),
+
59  static_cast<uint8_t>((x >> 24) & 0xFF)};
+
60  return TrimLeadingZeros(base::HexEncode(bytes, arraysize(bytes)));
+
61 }
+
62 
+
63 } // namespace
+
64 
+
65 HEVCDecoderConfigurationRecord::HEVCDecoderConfigurationRecord() = default;
+
66 
+
67 HEVCDecoderConfigurationRecord::~HEVCDecoderConfigurationRecord() = default;
+
68 
+
69 bool HEVCDecoderConfigurationRecord::ParseInternal() {
+
70  BufferReader reader(data(), data_size());
+
71 
+
72  uint8_t profile_indication = 0;
+
73  uint8_t length_size_minus_one = 0;
+
74  uint8_t num_of_arrays = 0;
+
75  RCHECK(reader.Read1(&version_) && version_ == 1 &&
+
76  reader.Read1(&profile_indication) &&
+
77  reader.Read4(&general_profile_compatibility_flags_) &&
+
78  reader.ReadToVector(&general_constraint_indicator_flags_, 6) &&
+
79  reader.Read1(&general_level_idc_) &&
+
80  reader.SkipBytes(8) && // Skip uninterested fields.
+
81  reader.Read1(&length_size_minus_one) &&
+
82  reader.Read1(&num_of_arrays));
+
83 
+
84  general_profile_space_ = profile_indication >> 6;
+
85  RCHECK(general_profile_space_ <= 3u);
+
86  general_tier_flag_ = ((profile_indication >> 5) & 1) == 1;
+
87  general_profile_idc_ = profile_indication & 0x1f;
+
88 
+
89  if ((length_size_minus_one & 0x3) == 2) {
+
90  LOG(ERROR) << "Invalid NALU length size.";
+
91  return false;
+
92  }
+
93  set_nalu_length_size((length_size_minus_one & 0x3) + 1);
+
94 
+
95  for (int i = 0; i < num_of_arrays; i++) {
+
96  uint8_t nal_unit_type;
+
97  uint16_t num_nalus;
+
98  RCHECK(reader.Read1(&nal_unit_type));
+
99  nal_unit_type &= 0x3f;
+
100  RCHECK(reader.Read2(&num_nalus));
+
101  for (int j = 0; j < num_nalus; j++) {
+
102  uint16_t nalu_length;
+
103  RCHECK(reader.Read2(&nalu_length));
+
104  uint64_t nalu_offset = reader.pos();
+
105  RCHECK(reader.SkipBytes(nalu_length));
+
106 
+
107  Nalu nalu;
+
108  RCHECK(nalu.Initialize(Nalu::kH265, data() + nalu_offset, nalu_length));
+
109  RCHECK(nalu.type() == nal_unit_type);
+
110  AddNalu(nalu);
+
111 
+
112  if (nalu.type() == Nalu::H265_SPS) {
+
113  H265Parser parser;
+
114  int sps_id = 0;
+
115  RCHECK(parser.ParseSps(nalu, &sps_id) == H265Parser::kOk);
+ +
117  parser.GetSps(sps_id)->vui_parameters.transfer_characteristics);
+
118  }
+
119  }
+
120  }
+
121 
+
122  // TODO(kqyang): Parse SPS to get resolutions.
+
123  return true;
+
124 }
+
125 
+ +
127  FourCC codec_fourcc) const {
+
128  // ISO/IEC 14496-15:2014 Annex E.
+
129  std::vector<std::string> fields;
+
130  fields.push_back(FourCCToString(codec_fourcc));
+
131  fields.push_back(GeneralProfileSpaceAsString(general_profile_space_) +
+
132  base::IntToString(general_profile_idc_));
+
133  fields.push_back(
+
134  ReverseBitsAndHexEncode(general_profile_compatibility_flags_));
+
135  fields.push_back((general_tier_flag_ ? "H" : "L") +
+
136  base::IntToString(general_level_idc_));
+
137 
+
138  // Remove trailing bytes that are zero.
+
139  std::vector<uint8_t> constraints = general_constraint_indicator_flags_;
+
140  size_t size = constraints.size();
+
141  for (; size > 0; --size) {
+
142  if (constraints[size - 1] != 0) break;
+
143  }
+
144  constraints.resize(size);
+
145  for (uint8_t constraint : constraints)
+
146  fields.push_back(TrimLeadingZeros(base::HexEncode(&constraint, 1)));
+
147 
+
148  return base::JoinString(fields, ".");
+
149 }
+
150 
+
151 } // namespace media
+
152 } // namespace shaka
+ +
void AddNalu(const Nalu &nalu)
Adds the given Nalu to the configuration.
+
void set_transfer_characteristics(uint8_t transfer_characteristics)
Sets the transfer characteristics.
+
void set_nalu_length_size(uint8_t nalu_length_size)
Sets the size of the NAL unit length field.
+ + + +
int type() const
Definition: nalu_reader.h:113
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/d12/classshaka_1_1media_1_1mp2t_1_1EsParserH264-members.html b/docs/d1/d12/classshaka_1_1media_1_1mp2t_1_1EsParserH264-members.html index 9d1132fe50..54cfe8de33 100644 --- a/docs/d1/d12/classshaka_1_1media_1_1mp2t_1_1EsParserH264-members.html +++ b/docs/d1/d12/classshaka_1_1media_1_1mp2t_1_1EsParserH264-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::media::mp2t::EsParserH264, including all inherited members.

- - - - - - - - - - - - + + + + + + + + + + + + +
EmitSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
EsParserH264(uint32_t pid, const NewStreamInfoCB &new_stream_info_cb, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH264)shaka::media::mp2t::EsParserH264
EsParserH26x(Nalu::CodecType type, std::unique_ptr< H26xByteToUnitStreamConverter > stream_converter, uint32_t pid, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
Flush() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
Reset() override (defined in shaka::media::mp2t::EsParserH264)shaka::media::mp2t::EsParserH264virtual
stream_converter() const (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xinlineprotected
~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
~EsParserH264() override (defined in shaka::media::mp2t::EsParserH264)shaka::media::mp2t::EsParserH264
~EsParserH26x() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
EmitTextSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
EsParserH264(uint32_t pid, const NewStreamInfoCB &new_stream_info_cb, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH264)shaka::media::mp2t::EsParserH264
EsParserH26x(Nalu::CodecType type, std::unique_ptr< H26xByteToUnitStreamConverter > stream_converter, uint32_t pid, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
Flush() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
Reset() override (defined in shaka::media::mp2t::EsParserH264)shaka::media::mp2t::EsParserH264virtual
stream_converter() const (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xinlineprotected
~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
~EsParserH264() override (defined in shaka::media::mp2t::EsParserH264)shaka::media::mp2t::EsParserH264
~EsParserH26x() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
diff --git a/docs/d1/d12/range_8h_source.html b/docs/d1/d12/range_8h_source.html index a893faca08..cec2d60efc 100644 --- a/docs/d1/d12/range_8h_source.html +++ b/docs/d1/d12/range_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/range.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
range.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Event handler for events fired by Muxer.
8 
9 #ifndef PACKAGER_MEDIA_BASE_RANGE_H_
10 #define PACKAGER_MEDIA_BASE_RANGE_H_
11 
12 #include <stdint.h>
13 
14 namespace shaka {
15 namespace media {
16 
19 struct Range {
20  uint64_t start;
21  uint64_t end;
22 };
23 
24 } // namespace media
25 } // namespace shaka
26 
27 #endif // PACKAGER_MEDIA_BASE_RANGE_H_
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Event handler for events fired by Muxer.
+
8 
+
9 #ifndef PACKAGER_MEDIA_BASE_RANGE_H_
+
10 #define PACKAGER_MEDIA_BASE_RANGE_H_
+
11 
+
12 #include <stdint.h>
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 
+
19 struct Range {
+
20  uint64_t start;
+
21  uint64_t end;
+
22 };
+
23 
+
24 } // namespace media
+
25 } // namespace shaka
+
26 
+
27 #endif // PACKAGER_MEDIA_BASE_RANGE_H_
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d1/d13/status_8h_source.html b/docs/d1/d13/status_8h_source.html index cf74e52a9d..10a7503cae 100644 --- a/docs/d1/d13/status_8h_source.html +++ b/docs/d1/d13/status_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/status.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
status.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_STATUS_H_
8 #define PACKAGER_STATUS_H_
9 
10 #include <iostream>
11 #include <string>
12 
13 #if defined(SHARED_LIBRARY_BUILD)
14 #if defined(_WIN32)
15 
16 #if defined(SHAKA_IMPLEMENTATION)
17 #define SHAKA_EXPORT __declspec(dllexport)
18 #else
19 #define SHAKA_EXPORT __declspec(dllimport)
20 #endif // defined(SHAKA_IMPLEMENTATION)
21 
22 #else // defined(_WIN32)
23 
24 #if defined(SHAKA_IMPLEMENTATION)
25 #define SHAKA_EXPORT __attribute__((visibility("default")))
26 #else
27 #define SHAKA_EXPORT
28 #endif
29 
30 #endif // defined(_WIN32)
31 
32 #else // defined(SHARED_LIBRARY_BUILD)
33 #define SHAKA_EXPORT
34 #endif // defined(SHARED_LIBRARY_BUILD)
35 
36 namespace shaka {
37 
38 namespace error {
39 
41 enum Code {
42  // Not an error; returned on success
43  OK,
44 
45  // Unknown error. An example of where this error may be returned is
46  // errors raised by APIs that do not return enough error information
47  // may be converted to this error.
48  UNKNOWN,
49 
50  // The operation was cancelled (typically by the caller).
51  CANCELLED,
52 
53  // Client specified an invalid argument. INVALID_ARGUMENT indicates
54  // arguments that are problematic regardless of the state of the system
55  // (e.g. a malformed file name).
56  INVALID_ARGUMENT,
57 
58  // Operation is not implemented or not supported/enabled.
59  UNIMPLEMENTED,
60 
61  // Cannot open file.
62  FILE_FAILURE,
63 
64  // End of stream.
65  END_OF_STREAM,
66 
67  // Failure to get HTTP response successfully,
68  HTTP_FAILURE,
69 
70  // Unable to parse the media file.
71  PARSER_FAILURE,
72 
73  // Failed to do the encryption.
74  ENCRYPTION_FAILURE,
75 
76  // Error when trying to do chunking.
77  CHUNKING_ERROR,
78 
79  // Fail to mux the media file.
80  MUXER_FAILURE,
81 
82  // This track fragment is finalized.
83  FRAGMENT_FINALIZED,
84 
85  // Server errors. Receives malformed response from server.
86  SERVER_ERROR,
87 
88  // Internal errors. Some invariants have been broken.
89  INTERNAL_ERROR,
90 
91  // The operation was stopped.
92  STOPPED,
93 
94  // The operation timed out.
95  TIME_OUT,
96 
97  // Value was not found.
98  NOT_FOUND,
99 
100  // The entity that a client attempted to create (e.g., file or directory)
101  // already exists.
102  ALREADY_EXISTS,
103 
104  // Error when trying to generate trick play stream.
105  TRICK_PLAY_ERROR,
106 };
107 
108 } // namespace error
109 
110 class SHAKA_EXPORT Status {
111  public:
113  Status() : error_code_(error::OK) {}
114 
118  Status(error::Code error_code, const std::string& error_message);
119 
122  static const Status OK; // Identical to 0-arg constructor.
123  static const Status UNKNOWN;
125 
134  void Update(Status new_status);
135 
136  bool ok() const { return error_code_ == error::OK; }
137  error::Code error_code() const { return error_code_; }
138  const std::string& error_message() const { return error_message_; }
139 
140  bool operator==(const Status& x) const {
141  return error_code_ == x.error_code() && error_message_ == x.error_message();
142  }
143  bool operator!=(const Status& x) const { return !(*this == x); }
144 
146  std::string ToString() const;
147 
148  private:
149  error::Code error_code_;
150  std::string error_message_;
151 
152  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
153  // generated copy constructor and assignment operator.
154 };
155 
156 SHAKA_EXPORT std::ostream& operator<<(std::ostream& os, const Status& x);
157 
158 } // namespace shaka
159 
160 #endif // PACKAGER_STATUS_H_
All the methods that are virtual are virtual for mocking.
- -
Status()
Creates a "successful" status.
Definition: status.h:113
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_STATUS_H_
+
8 #define PACKAGER_STATUS_H_
+
9 
+
10 #include <iostream>
+
11 #include <string>
+
12 
+
13 #if defined(SHARED_LIBRARY_BUILD)
+
14 #if defined(_WIN32)
+
15 
+
16 #if defined(SHAKA_IMPLEMENTATION)
+
17 #define SHAKA_EXPORT __declspec(dllexport)
+
18 #else
+
19 #define SHAKA_EXPORT __declspec(dllimport)
+
20 #endif // defined(SHAKA_IMPLEMENTATION)
+
21 
+
22 #else // defined(_WIN32)
+
23 
+
24 #if defined(SHAKA_IMPLEMENTATION)
+
25 #define SHAKA_EXPORT __attribute__((visibility("default")))
+
26 #else
+
27 #define SHAKA_EXPORT
+
28 #endif
+
29 
+
30 #endif // defined(_WIN32)
+
31 
+
32 #else // defined(SHARED_LIBRARY_BUILD)
+
33 #define SHAKA_EXPORT
+
34 #endif // defined(SHARED_LIBRARY_BUILD)
+
35 
+
36 namespace shaka {
+
37 
+
38 namespace error {
+
39 
+
41 enum Code {
+
42  // Not an error; returned on success
+
43  OK,
+
44 
+
45  // Unknown error. An example of where this error may be returned is
+
46  // errors raised by APIs that do not return enough error information
+
47  // may be converted to this error.
+
48  UNKNOWN,
+
49 
+
50  // The operation was cancelled (typically by the caller).
+
51  CANCELLED,
+
52 
+
53  // Client specified an invalid argument. INVALID_ARGUMENT indicates
+
54  // arguments that are problematic regardless of the state of the system
+
55  // (e.g. a malformed file name).
+
56  INVALID_ARGUMENT,
+
57 
+
58  // Operation is not implemented or not supported/enabled.
+
59  UNIMPLEMENTED,
+
60 
+
61  // Cannot open file.
+
62  FILE_FAILURE,
+
63 
+
64  // End of stream.
+
65  END_OF_STREAM,
+
66 
+
67  // Failure to get HTTP response successfully,
+
68  HTTP_FAILURE,
+
69 
+
70  // Unable to parse the media file.
+
71  PARSER_FAILURE,
+
72 
+
73  // Failed to do the encryption.
+
74  ENCRYPTION_FAILURE,
+
75 
+
76  // Error when trying to do chunking.
+
77  CHUNKING_ERROR,
+
78 
+
79  // Fail to mux the media file.
+
80  MUXER_FAILURE,
+
81 
+
82  // This track fragment is finalized.
+
83  FRAGMENT_FINALIZED,
+
84 
+
85  // Server errors. Receives malformed response from server.
+
86  SERVER_ERROR,
+
87 
+
88  // Internal errors. Some invariants have been broken.
+
89  INTERNAL_ERROR,
+
90 
+
91  // The operation was stopped.
+
92  STOPPED,
+
93 
+
94  // The operation timed out.
+
95  TIME_OUT,
+
96 
+
97  // Value was not found.
+
98  NOT_FOUND,
+
99 
+
100  // The entity that a client attempted to create (e.g., file or directory)
+
101  // already exists.
+
102  ALREADY_EXISTS,
+
103 
+
104  // Error when trying to generate trick play stream.
+
105  TRICK_PLAY_ERROR,
+
106 };
+
107 
+
108 } // namespace error
+
109 
+
110 class SHAKA_EXPORT Status {
+
111  public:
+
113  Status() : error_code_(error::OK) {}
+
114 
+
118  Status(error::Code error_code, const std::string& error_message);
+
119 
+
122  static const Status OK; // Identical to 0-arg constructor.
+
123  static const Status UNKNOWN;
+
125 
+
134  void Update(Status new_status);
+
135 
+
136  bool ok() const { return error_code_ == error::OK; }
+
137  error::Code error_code() const { return error_code_; }
+
138  const std::string& error_message() const { return error_message_; }
+
139 
+
140  bool operator==(const Status& x) const {
+
141  return error_code_ == x.error_code() && error_message_ == x.error_message();
+
142  }
+
143  bool operator!=(const Status& x) const { return !(*this == x); }
+
144 
+
146  std::string ToString() const;
+
147 
+
148  private:
+
149  error::Code error_code_;
+
150  std::string error_message_;
+
151 
+
152  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
+
153  // generated copy constructor and assignment operator.
+
154 };
+
155 
+
156 SHAKA_EXPORT std::ostream& operator<<(std::ostream& os, const Status& x);
+
157 
+
158 } // namespace shaka
+
159 
+
160 #endif // PACKAGER_STATUS_H_
+ +
Status()
Creates a "successful" status.
Definition: status.h:113
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/d17/structshaka_1_1WidevineDecryptionParams-members.html b/docs/d1/d17/structshaka_1_1WidevineDecryptionParams-members.html index 11a6f07027..eaf060066a 100644 --- a/docs/d1/d17/structshaka_1_1WidevineDecryptionParams-members.html +++ b/docs/d1/d17/structshaka_1_1WidevineDecryptionParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d1b/classshaka_1_1media_1_1MockAesCryptor.html b/docs/d1/d1b/classshaka_1_1media_1_1MockAesCryptor.html index 3ccb511a3b..c36573e6ca 100644 --- a/docs/d1/d1b/classshaka_1_1media_1_1MockAesCryptor.html +++ b/docs/d1/d1b/classshaka_1_1media_1_1MockAesCryptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MockAesCryptor Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::AesCryptor - -
+ + @@ -118,8 +121,8 @@ bool  - @@ -142,9 +145,7 @@ AES_KEY * 

Public Member Functions

Crypt (const uint

Additional Inherited Members

- Public Types inherited from shaka::media::AesCryptor
enum  ConstantIvFlag { kUseConstantIv, -kDontUseConstantIv +
enum  ConstantIvFlag { kUseConstantIv +, kDontUseConstantIv }
 
- Static Public Member Functions inherited from shaka::media::AesCryptor
mutable_aes_key< diff --git a/docs/d1/d1c/two__pass__single__segment__segmenter_8cc_source.html b/docs/d1/d1c/two__pass__single__segment__segmenter_8cc_source.html index e8f430bf50..ad3403f772 100644 --- a/docs/d1/d1c/two__pass__single__segment__segmenter_8cc_source.html +++ b/docs/d1/d1c/two__pass__single__segment__segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/two_pass_single_segment_segmenter.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
two_pass_single_segment_segmenter.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webm/two_pass_single_segment_segmenter.h"
8 
9 #include <algorithm>
10 
11 #include "packager/file/file_util.h"
12 #include "packager/media/base/media_sample.h"
13 #include "packager/media/base/muxer_options.h"
14 #include "packager/media/base/stream_info.h"
15 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
16 #include "packager/third_party/libwebm/src/mkvmuxerutil.hpp"
17 #include "packager/third_party/libwebm/src/webmids.hpp"
18 
19 namespace shaka {
20 namespace media {
21 namespace webm {
22 namespace {
23 // Cues will be inserted before clusters. All clusters will be shifted down by
24 // the size of cues. However, cluster positions affect the size of cues. This
25 // function adjusts cues size iteratively until it is stable.
26 // Returns the size of updated Cues.
27 uint64_t UpdateCues(mkvmuxer::Cues* cues) {
28  uint64_t cues_size = cues->Size();
29  uint64_t adjustment = cues_size;
30  while (adjustment != 0) {
31  for (int i = 0; i < cues->cue_entries_size(); ++i) {
32  mkvmuxer::CuePoint* cue = cues->GetCueByIndex(i);
33  cue->set_cluster_pos(cue->cluster_pos() + adjustment);
34  }
35  uint64_t new_cues_size = cues->Size();
36  DCHECK_LE(cues_size, new_cues_size);
37  adjustment = new_cues_size - cues_size;
38  cues_size = new_cues_size;
39  }
40  return cues_size;
41 }
42 
43 // Skips a given number of bytes in a file by reading. This allows
44 // forward-seeking in non-seekable files.
45 bool ReadSkip(File* file, int64_t byte_count) {
46  const int64_t kBufferSize = 0x40000; // 256KB.
47  std::unique_ptr<char[]> buffer(new char[kBufferSize]);
48  int64_t bytes_read = 0;
49  while (bytes_read < byte_count) {
50  int64_t size = std::min(kBufferSize, byte_count - bytes_read);
51  int64_t result = file->Read(buffer.get(), size);
52  // Only give success if there are no errors, not at EOF, and read exactly
53  // byte_count bytes.
54  if (result <= 0)
55  return false;
56 
57  bytes_read += result;
58  }
59 
60  DCHECK_EQ(bytes_read, byte_count);
61  return true;
62 }
63 } // namespace
64 
65 TwoPassSingleSegmentSegmenter::TwoPassSingleSegmentSegmenter(
66  const MuxerOptions& options)
67  : SingleSegmentSegmenter(options) {}
68 
69 TwoPassSingleSegmentSegmenter::~TwoPassSingleSegmentSegmenter() {}
70 
71 Status TwoPassSingleSegmentSegmenter::DoInitialize() {
72  // Assume the amount of time to copy the temp file as the same amount
73  // of time as to make it.
74  set_progress_target(duration() * 2);
75 
76  if (!TempFilePath(options().temp_dir, &temp_file_name_))
77  return Status(error::FILE_FAILURE, "Unable to create temporary file.");
78  std::unique_ptr<MkvWriter> temp(new MkvWriter);
79  Status status = temp->Open(temp_file_name_);
80  if (!status.ok())
81  return status;
82  set_writer(std::move(temp));
83 
84  return SingleSegmentSegmenter::DoInitialize();
85 }
86 
87 Status TwoPassSingleSegmentSegmenter::DoFinalize() {
88  const uint64_t header_size = init_end() + 1;
89  const uint64_t cues_pos = header_size - segment_payload_pos();
90  const uint64_t cues_size = UpdateCues(cues());
91  seek_head()->set_cues_pos(cues_pos);
92  seek_head()->set_cluster_pos(cues_pos + cues_size);
93 
94  // Write the header to the real output file.
95  std::unique_ptr<MkvWriter> real_writer(new MkvWriter);
96  Status status = real_writer->Open(options().output_file_name);
97  if (!status.ok())
98  return status;
99 
100  const uint64_t file_size = writer()->Position() + cues_size;
101  Status temp = WriteSegmentHeader(file_size, real_writer.get());
102  if (!temp.ok())
103  return temp;
104  DCHECK_EQ(real_writer->Position(), static_cast<int64_t>(header_size));
105 
106  // Write the cues to the real output file.
107  set_index_start(real_writer->Position());
108  if (!cues()->Write(real_writer.get()))
109  return Status(error::FILE_FAILURE, "Error writing Cues data.");
110  set_index_end(real_writer->Position() - 1);
111  DCHECK_EQ(real_writer->Position(),
112  static_cast<int64_t>(segment_payload_pos() + cues_pos + cues_size));
113 
114  // Close the temp file and open it for reading.
115  set_writer(std::unique_ptr<MkvWriter>());
116  std::unique_ptr<File, FileCloser> temp_reader(
117  File::Open(temp_file_name_.c_str(), "r"));
118  if (!temp_reader)
119  return Status(error::FILE_FAILURE, "Error opening temp file.");
120 
121  // Skip the header that has already been written.
122  if (!ReadSkip(temp_reader.get(), header_size))
123  return Status(error::FILE_FAILURE, "Error reading temp file.");
124 
125  // Copy the rest of the data over.
126  if (!CopyFileWithClusterRewrite(temp_reader.get(), real_writer.get(),
127  cluster()->Size())) {
128  return Status(error::FILE_FAILURE, "Error copying temp file.");
129  }
130 
131  // Close and delete the temp file.
132  temp_reader.reset();
133  if (!File::Delete(temp_file_name_.c_str())) {
134  LOG(WARNING) << "Unable to delete temporary file " << temp_file_name_;
135  }
136 
137  return real_writer->Close();
138 }
139 
140 bool TwoPassSingleSegmentSegmenter::CopyFileWithClusterRewrite(
141  File* source,
142  MkvWriter* dest,
143  uint64_t last_size) {
144  const int cluster_id_size = mkvmuxer::GetUIntSize(mkvmuxer::kMkvCluster);
145  const int cluster_size_size = 8; // The size of the Cluster size integer.
146  const int cluster_header_size = cluster_id_size + cluster_size_size;
147 
148  // We are at the start of a cluster, so copy the ID.
149  if (dest->WriteFromFile(source, cluster_id_size) != cluster_id_size)
150  return false;
151 
152  for (int i = 0; i < cues()->cue_entries_size() - 1; ++i) {
153  // Write the size of the cluster.
154  const mkvmuxer::CuePoint* cue = cues()->GetCueByIndex(i);
155  const mkvmuxer::CuePoint* next_cue = cues()->GetCueByIndex(i + 1);
156  const int64_t cluster_payload_size =
157  next_cue->cluster_pos() - cue->cluster_pos() - cluster_header_size;
158  if (mkvmuxer::WriteUIntSize(dest, cluster_payload_size, cluster_size_size))
159  return false;
160  if (!ReadSkip(source, cluster_size_size))
161  return false;
162 
163  // Copy the cluster and the next cluster's ID.
164  int64_t to_copy = cluster_payload_size + cluster_id_size;
165  if (dest->WriteFromFile(source, to_copy) != to_copy)
166  return false;
167 
168  // Update the progress; need to convert from WebM timecode to ISO BMFF.
169  const uint64_t webm_delta_time = next_cue->time() - cue->time();
170  const uint64_t delta_time = FromWebMTimecode(webm_delta_time);
171  UpdateProgress(delta_time);
172  }
173 
174  // The last cluster takes up until the cues.
175  const uint64_t last_cluster_payload_size = last_size - cluster_header_size;
176  if (mkvmuxer::WriteUIntSize(dest, last_cluster_payload_size,
177  cluster_size_size))
178  return false;
179  if (!ReadSkip(source, cluster_size_size))
180  return false;
181 
182  // Copy the last cluster.
183  return dest->WriteFromFile(source) ==
184  static_cast<int64_t>(last_cluster_payload_size);
185 }
186 
187 } // namespace webm
188 } // namespace media
189 } // namespace shaka
static bool Delete(const char *file_name)
Definition: file.cc:198
-
bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
Definition: file_util.cc:38
-
All the methods that are virtual are virtual for mocking.
-
virtual bool Open()=0
Internal open. Should not be used directly.
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/webm/two_pass_single_segment_segmenter.h"
+
8 
+
9 #include <algorithm>
+
10 
+
11 #include "packager/file/file_util.h"
+
12 #include "packager/media/base/media_sample.h"
+
13 #include "packager/media/base/muxer_options.h"
+
14 #include "packager/media/base/stream_info.h"
+
15 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
+
16 #include "packager/third_party/libwebm/src/mkvmuxerutil.hpp"
+
17 #include "packager/third_party/libwebm/src/webmids.hpp"
+
18 
+
19 namespace shaka {
+
20 namespace media {
+
21 namespace webm {
+
22 namespace {
+
23 // Cues will be inserted before clusters. All clusters will be shifted down by
+
24 // the size of cues. However, cluster positions affect the size of cues. This
+
25 // function adjusts cues size iteratively until it is stable.
+
26 // Returns the size of updated Cues.
+
27 uint64_t UpdateCues(mkvmuxer::Cues* cues) {
+
28  uint64_t cues_size = cues->Size();
+
29  uint64_t adjustment = cues_size;
+
30  while (adjustment != 0) {
+
31  for (int i = 0; i < cues->cue_entries_size(); ++i) {
+
32  mkvmuxer::CuePoint* cue = cues->GetCueByIndex(i);
+
33  cue->set_cluster_pos(cue->cluster_pos() + adjustment);
+
34  }
+
35  uint64_t new_cues_size = cues->Size();
+
36  DCHECK_LE(cues_size, new_cues_size);
+
37  adjustment = new_cues_size - cues_size;
+
38  cues_size = new_cues_size;
+
39  }
+
40  return cues_size;
+
41 }
+
42 
+
43 // Skips a given number of bytes in a file by reading. This allows
+
44 // forward-seeking in non-seekable files.
+
45 bool ReadSkip(File* file, int64_t byte_count) {
+
46  const int64_t kBufferSize = 0x40000; // 256KB.
+
47  std::unique_ptr<char[]> buffer(new char[kBufferSize]);
+
48  int64_t bytes_read = 0;
+
49  while (bytes_read < byte_count) {
+
50  int64_t size = std::min(kBufferSize, byte_count - bytes_read);
+
51  int64_t result = file->Read(buffer.get(), size);
+
52  // Only give success if there are no errors, not at EOF, and read exactly
+
53  // byte_count bytes.
+
54  if (result <= 0)
+
55  return false;
+
56 
+
57  bytes_read += result;
+
58  }
+
59 
+
60  DCHECK_EQ(bytes_read, byte_count);
+
61  return true;
+
62 }
+
63 } // namespace
+
64 
+
65 TwoPassSingleSegmentSegmenter::TwoPassSingleSegmentSegmenter(
+
66  const MuxerOptions& options)
+
67  : SingleSegmentSegmenter(options) {}
+
68 
+
69 TwoPassSingleSegmentSegmenter::~TwoPassSingleSegmentSegmenter() {}
+
70 
+
71 Status TwoPassSingleSegmentSegmenter::DoInitialize() {
+
72  // Assume the amount of time to copy the temp file as the same amount
+
73  // of time as to make it.
+
74  set_progress_target(duration() * 2);
+
75 
+
76  if (!TempFilePath(options().temp_dir, &temp_file_name_))
+
77  return Status(error::FILE_FAILURE, "Unable to create temporary file.");
+
78  std::unique_ptr<MkvWriter> temp(new MkvWriter);
+
79  Status status = temp->Open(temp_file_name_);
+
80  if (!status.ok())
+
81  return status;
+
82  set_writer(std::move(temp));
+
83 
+
84  return SingleSegmentSegmenter::DoInitialize();
+
85 }
+
86 
+
87 Status TwoPassSingleSegmentSegmenter::DoFinalize() {
+
88  const uint64_t header_size = init_end() + 1;
+
89  const uint64_t cues_pos = header_size - segment_payload_pos();
+
90  const uint64_t cues_size = UpdateCues(cues());
+
91  seek_head()->set_cues_pos(cues_pos);
+
92  seek_head()->set_cluster_pos(cues_pos + cues_size);
+
93 
+
94  // Write the header to the real output file.
+
95  std::unique_ptr<MkvWriter> real_writer(new MkvWriter);
+
96  Status status = real_writer->Open(options().output_file_name);
+
97  if (!status.ok())
+
98  return status;
+
99 
+
100  const uint64_t file_size = writer()->Position() + cues_size;
+
101  Status temp = WriteSegmentHeader(file_size, real_writer.get());
+
102  if (!temp.ok())
+
103  return temp;
+
104  DCHECK_EQ(real_writer->Position(), static_cast<int64_t>(header_size));
+
105 
+
106  // Write the cues to the real output file.
+
107  set_index_start(real_writer->Position());
+
108  if (!cues()->Write(real_writer.get()))
+
109  return Status(error::FILE_FAILURE, "Error writing Cues data.");
+
110  set_index_end(real_writer->Position() - 1);
+
111  DCHECK_EQ(real_writer->Position(),
+
112  static_cast<int64_t>(segment_payload_pos() + cues_pos + cues_size));
+
113 
+
114  // Close the temp file and open it for reading.
+
115  set_writer(std::unique_ptr<MkvWriter>());
+
116  std::unique_ptr<File, FileCloser> temp_reader(
+
117  File::Open(temp_file_name_.c_str(), "r"));
+
118  if (!temp_reader)
+
119  return Status(error::FILE_FAILURE, "Error opening temp file.");
+
120 
+
121  // Skip the header that has already been written.
+
122  if (!ReadSkip(temp_reader.get(), header_size))
+
123  return Status(error::FILE_FAILURE, "Error reading temp file.");
+
124 
+
125  // Copy the rest of the data over.
+
126  if (!CopyFileWithClusterRewrite(temp_reader.get(), real_writer.get(),
+
127  cluster()->Size())) {
+
128  return Status(error::FILE_FAILURE, "Error copying temp file.");
+
129  }
+
130 
+
131  // Close and delete the temp file.
+
132  temp_reader.reset();
+
133  if (!File::Delete(temp_file_name_.c_str())) {
+
134  LOG(WARNING) << "Unable to delete temporary file " << temp_file_name_;
+
135  }
+
136 
+
137  return real_writer->Close();
+
138 }
+
139 
+
140 bool TwoPassSingleSegmentSegmenter::CopyFileWithClusterRewrite(
+
141  File* source,
+
142  MkvWriter* dest,
+
143  uint64_t last_size) {
+
144  const int cluster_id_size = mkvmuxer::GetUIntSize(mkvmuxer::kMkvCluster);
+
145  const int cluster_size_size = 8; // The size of the Cluster size integer.
+
146  const int cluster_header_size = cluster_id_size + cluster_size_size;
+
147 
+
148  // We are at the start of a cluster, so copy the ID.
+
149  if (dest->WriteFromFile(source, cluster_id_size) != cluster_id_size)
+
150  return false;
+
151 
+
152  for (int i = 0; i < cues()->cue_entries_size() - 1; ++i) {
+
153  // Write the size of the cluster.
+
154  const mkvmuxer::CuePoint* cue = cues()->GetCueByIndex(i);
+
155  const mkvmuxer::CuePoint* next_cue = cues()->GetCueByIndex(i + 1);
+
156  const int64_t cluster_payload_size =
+
157  next_cue->cluster_pos() - cue->cluster_pos() - cluster_header_size;
+
158  if (mkvmuxer::WriteUIntSize(dest, cluster_payload_size, cluster_size_size))
+
159  return false;
+
160  if (!ReadSkip(source, cluster_size_size))
+
161  return false;
+
162 
+
163  // Copy the cluster and the next cluster's ID.
+
164  int64_t to_copy = cluster_payload_size + cluster_id_size;
+
165  if (dest->WriteFromFile(source, to_copy) != to_copy)
+
166  return false;
+
167 
+
168  // Update the progress; need to convert from WebM timecode to ISO BMFF.
+
169  const uint64_t webm_delta_time = next_cue->time() - cue->time();
+
170  const uint64_t delta_time = FromWebMTimecode(webm_delta_time);
+
171  UpdateProgress(delta_time);
+
172  }
+
173 
+
174  // The last cluster takes up until the cues.
+
175  const uint64_t last_cluster_payload_size = last_size - cluster_header_size;
+
176  if (mkvmuxer::WriteUIntSize(dest, last_cluster_payload_size,
+
177  cluster_size_size))
+
178  return false;
+
179  if (!ReadSkip(source, cluster_size_size))
+
180  return false;
+
181 
+
182  // Copy the last cluster.
+
183  return dest->WriteFromFile(source) ==
+
184  static_cast<int64_t>(last_cluster_payload_size);
+
185 }
+
186 
+
187 } // namespace webm
+
188 } // namespace media
+
189 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
+
bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
Definition: file_util.cc:38
diff --git a/docs/d1/d1d/muxer__flags_8cc_source.html b/docs/d1/d1d/muxer__flags_8cc_source.html index 0a4861e4c8..debd557eff 100644 --- a/docs/d1/d1d/muxer__flags_8cc_source.html +++ b/docs/d1/d1d/muxer__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/muxer_flags.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
muxer_flags.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines Muxer flags.
8 
9 #include "packager/app/muxer_flags.h"
10 
11 DEFINE_double(clear_lead,
12  5.0f,
13  "Clear lead in seconds if encryption is enabled. Note that we do "
14  "not support partial segment encryption, so it is rounded up to "
15  "full segments. Set it to a value smaller than segment_duration "
16  "so only the first segment is in clear since the first segment "
17  "could be smaller than segment_duration if there is small "
18  "non-zero starting timestamp.");
19 DEFINE_double(segment_duration,
20  6.0f,
21  "Segment duration in seconds. If single_segment is specified, "
22  "this parameter sets the duration of a subsegment; otherwise, "
23  "this parameter sets the duration of a segment. Actual segment "
24  "durations may not be exactly as requested.");
25 DEFINE_bool(segment_sap_aligned,
26  true,
27  "Force segments to begin with stream access points.");
28 DEFINE_double(fragment_duration,
29  0,
30  "Fragment duration in seconds. Should not be larger than "
31  "the segment duration. Actual fragment durations may not be "
32  "exactly as requested.");
33 DEFINE_bool(fragment_sap_aligned,
34  true,
35  "Force fragments to begin with stream access points. This flag "
36  "implies segment_sap_aligned.");
37 DEFINE_bool(generate_sidx_in_media_segments,
38  true,
39  "For ISO BMFF with DASH live profile only. Indicates whether to "
40  "generate 'sidx' box in media segments. Note that it is required "
41  "by spec if segment template contains $Time$ specifier.");
42 DEFINE_string(temp_dir,
43  "",
44  "Specify a directory in which to store temporary (intermediate) "
45  " files. Used only if single_segment=true.");
46 DEFINE_bool(mp4_include_pssh_in_stream,
47  true,
48  "MP4 only: include pssh in the encrypted stream.");
49 DEFINE_int32(transport_stream_timestamp_offset_ms,
50  100,
51  "A positive value, in milliseconds, by which output timestamps "
52  "are offset to compensate for possible negative timestamps in the "
53  "input. For example, timestamps from ISO-BMFF after adjusted by "
54  "EditList could be negative. In transport streams, timestamps are "
55  "not allowed to be less than zero.");
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines Muxer flags.
+
8 
+
9 #include "packager/app/muxer_flags.h"
+
10 
+
11 DEFINE_double(clear_lead,
+
12  5.0f,
+
13  "Clear lead in seconds if encryption is enabled. Note that we do "
+
14  "not support partial segment encryption, so it is rounded up to "
+
15  "full segments. Set it to a value smaller than segment_duration "
+
16  "so only the first segment is in clear since the first segment "
+
17  "could be smaller than segment_duration if there is small "
+
18  "non-zero starting timestamp.");
+
19 DEFINE_double(segment_duration,
+
20  6.0f,
+
21  "Segment duration in seconds. If single_segment is specified, "
+
22  "this parameter sets the duration of a subsegment; otherwise, "
+
23  "this parameter sets the duration of a segment. Actual segment "
+
24  "durations may not be exactly as requested.");
+
25 DEFINE_bool(segment_sap_aligned,
+
26  true,
+
27  "Force segments to begin with stream access points.");
+
28 DEFINE_double(fragment_duration,
+
29  0,
+
30  "Fragment duration in seconds. Should not be larger than "
+
31  "the segment duration. Actual fragment durations may not be "
+
32  "exactly as requested.");
+
33 DEFINE_bool(fragment_sap_aligned,
+
34  true,
+
35  "Force fragments to begin with stream access points. This flag "
+
36  "implies segment_sap_aligned.");
+
37 DEFINE_bool(generate_sidx_in_media_segments,
+
38  true,
+
39  "Indicates whether to generate 'sidx' box in media segments. Note "
+
40  "that it is required for DASH on-demand profile (not using segment "
+
41  "template).");
+
42 DEFINE_string(temp_dir,
+
43  "",
+
44  "Specify a directory in which to store temporary (intermediate) "
+
45  " files. Used only if single_segment=true.");
+
46 DEFINE_bool(mp4_include_pssh_in_stream,
+
47  true,
+
48  "MP4 only: include pssh in the encrypted stream.");
+
49 DEFINE_int32(transport_stream_timestamp_offset_ms,
+
50  100,
+
51  "A positive value, in milliseconds, by which output timestamps "
+
52  "are offset to compensate for possible negative timestamps in the "
+
53  "input. For example, timestamps from ISO-BMFF after adjusted by "
+
54  "EditList could be negative. In transport streams, timestamps are "
+
55  "not allowed to be less than zero.");
+
diff --git a/docs/d1/d1e/hls__notifier_8h_source.html b/docs/d1/d1e/hls__notifier_8h_source.html index 053aa0ee1d..3dc6f1c22a 100644 --- a/docs/d1/d1e/hls__notifier_8h_source.html +++ b/docs/d1/d1e/hls__notifier_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/hls_notifier.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
hls_notifier.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_HLS_BASE_HLS_NOTIFIER_H_
8 #define PACKAGER_HLS_BASE_HLS_NOTIFIER_H_
9 
10 #include <string>
11 #include <vector>
12 
13 #include "packager/hls/public/hls_params.h"
14 #include "packager/mpd/base/media_info.pb.h"
15 
16 namespace shaka {
17 namespace hls {
18 
19 // TODO(rkuroiwa): Consider merging this with MpdNotifier.
20 class HlsNotifier {
21  public:
22  explicit HlsNotifier(const HlsParams& hls_params) : hls_params_(hls_params) {}
23  virtual ~HlsNotifier() {}
24 
27  virtual bool Init() = 0;
28 
38  virtual bool NotifyNewStream(const MediaInfo& media_info,
39  const std::string& playlist_name,
40  const std::string& stream_name,
41  const std::string& group_id,
42  uint32_t* stream_id) = 0;
43 
50  virtual bool NotifySampleDuration(uint32_t stream_id,
51  uint32_t sample_duration) = 0;
52 
61  virtual bool NotifyNewSegment(uint32_t stream_id,
62  const std::string& segment_name,
63  uint64_t start_time,
64  uint64_t duration,
65  uint64_t start_byte_offset,
66  uint64_t size) = 0;
67 
74  virtual bool NotifyKeyFrame(uint32_t stream_id,
75  uint64_t timestamp,
76  uint64_t start_byte_offset,
77  uint64_t size) = 0;
78 
82  virtual bool NotifyCueEvent(uint32_t stream_id, uint64_t timestamp) = 0;
83 
92  virtual bool NotifyEncryptionUpdate(
93  uint32_t stream_id,
94  const std::vector<uint8_t>& key_id,
95  const std::vector<uint8_t>& system_id,
96  const std::vector<uint8_t>& iv,
97  const std::vector<uint8_t>& protection_system_specific_data) = 0;
98 
101  virtual bool Flush() = 0;
102 
104  const HlsParams& hls_params() const { return hls_params_; }
105 
106  private:
107  const HlsParams hls_params_;
108 };
109 
110 } // namespace hls
111 } // namespace shaka
112 
113 #endif // PACKAGER_HLS_BASE_HLS_NOTIFIER_H_
virtual bool Init()=0
-
virtual bool NotifySampleDuration(uint32_t stream_id, uint32_t sample_duration)=0
-
HLS related parameters.
Definition: hls_params.h:23
-
virtual bool NotifyKeyFrame(uint32_t stream_id, uint64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
-
All the methods that are virtual are virtual for mocking.
-
virtual bool Flush()=0
- -
const HlsParams & hls_params() const
Definition: hls_notifier.h:104
-
virtual bool NotifyNewSegment(uint32_t stream_id, const std::string &segment_name, uint64_t start_time, uint64_t duration, uint64_t start_byte_offset, uint64_t size)=0
-
virtual bool NotifyNewStream(const MediaInfo &media_info, const std::string &playlist_name, const std::string &stream_name, const std::string &group_id, uint32_t *stream_id)=0
-
virtual bool NotifyEncryptionUpdate(uint32_t stream_id, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &system_id, const std::vector< uint8_t > &iv, const std::vector< uint8_t > &protection_system_specific_data)=0
-
virtual bool NotifyCueEvent(uint32_t stream_id, uint64_t timestamp)=0
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_HLS_BASE_HLS_NOTIFIER_H_
+
8 #define PACKAGER_HLS_BASE_HLS_NOTIFIER_H_
+
9 
+
10 #include <string>
+
11 #include <vector>
+
12 
+
13 #include "packager/hls/public/hls_params.h"
+
14 #include "packager/mpd/base/media_info.pb.h"
+
15 
+
16 namespace shaka {
+
17 namespace hls {
+
18 
+
19 // TODO(rkuroiwa): Consider merging this with MpdNotifier.
+
20 class HlsNotifier {
+
21  public:
+
22  explicit HlsNotifier(const HlsParams& hls_params) : hls_params_(hls_params) {}
+
23  virtual ~HlsNotifier() {}
+
24 
+
27  virtual bool Init() = 0;
+
28 
+
38  virtual bool NotifyNewStream(const MediaInfo& media_info,
+
39  const std::string& playlist_name,
+
40  const std::string& stream_name,
+
41  const std::string& group_id,
+
42  uint32_t* stream_id) = 0;
+
43 
+
50  virtual bool NotifySampleDuration(uint32_t stream_id,
+
51  uint32_t sample_duration) = 0;
+
52 
+
61  virtual bool NotifyNewSegment(uint32_t stream_id,
+
62  const std::string& segment_name,
+
63  uint64_t start_time,
+
64  uint64_t duration,
+
65  uint64_t start_byte_offset,
+
66  uint64_t size) = 0;
+
67 
+
74  virtual bool NotifyKeyFrame(uint32_t stream_id,
+
75  uint64_t timestamp,
+
76  uint64_t start_byte_offset,
+
77  uint64_t size) = 0;
+
78 
+
82  virtual bool NotifyCueEvent(uint32_t stream_id, uint64_t timestamp) = 0;
+
83 
+
92  virtual bool NotifyEncryptionUpdate(
+
93  uint32_t stream_id,
+
94  const std::vector<uint8_t>& key_id,
+
95  const std::vector<uint8_t>& system_id,
+
96  const std::vector<uint8_t>& iv,
+
97  const std::vector<uint8_t>& protection_system_specific_data) = 0;
+
98 
+
101  virtual bool Flush() = 0;
+
102 
+
104  const HlsParams& hls_params() const { return hls_params_; }
+
105 
+
106  private:
+
107  const HlsParams hls_params_;
+
108 };
+
109 
+
110 } // namespace hls
+
111 } // namespace shaka
+
112 
+
113 #endif // PACKAGER_HLS_BASE_HLS_NOTIFIER_H_
+ +
virtual bool NotifyCueEvent(uint32_t stream_id, uint64_t timestamp)=0
+
virtual bool NotifyNewStream(const MediaInfo &media_info, const std::string &playlist_name, const std::string &stream_name, const std::string &group_id, uint32_t *stream_id)=0
+
virtual bool NotifyEncryptionUpdate(uint32_t stream_id, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &system_id, const std::vector< uint8_t > &iv, const std::vector< uint8_t > &protection_system_specific_data)=0
+
const HlsParams & hls_params() const
Definition: hls_notifier.h:104
+
virtual bool Flush()=0
+
virtual bool NotifySampleDuration(uint32_t stream_id, uint32_t sample_duration)=0
+
virtual bool Init()=0
+
virtual bool NotifyKeyFrame(uint32_t stream_id, uint64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
+
virtual bool NotifyNewSegment(uint32_t stream_id, const std::string &segment_name, uint64_t start_time, uint64_t duration, uint64_t start_byte_offset, uint64_t size)=0
+
All the methods that are virtual are virtual for mocking.
+
HLS related parameters.
Definition: hls_params.h:23
diff --git a/docs/d1/d1f/classshaka_1_1media_1_1KeySource.html b/docs/d1/d1f/classshaka_1_1media_1_1KeySource.html index 70af65fa4a..f26215feed 100644 --- a/docs/d1/d1f/classshaka_1_1media_1_1KeySource.html +++ b/docs/d1/d1f/classshaka_1_1media_1_1KeySource.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::KeySource Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::KeySource Class Referenceabstract
-

KeySource is responsible for encryption key acquisition. +

KeySource is responsible for encryption key acquisition. More...

#include <key_source.h>

@@ -81,17 +83,14 @@ Inheritance diagram for shaka::media::KeySource:
-shaka::media::PlayReadyKeySource -shaka::media::RawKeySource +shaka::media::PlayReadyKeySource +shaka::media::RawKeySource shaka::media::WidevineKeySource - -
+ + - - @@ -100,16 +99,11 @@ Public Member Functions -

Public Member Functions

KeySource (int protection_systems_flags, FourCC protection_scheme)
 
virtual Status FetchKeys (EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data)=0
 
virtual Status GetKey (const std::string &stream_label, EncryptionKey *key)=0
 
virtual Status GetCryptoPeriodKey (uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key)=0
 
- - -

-Protected Member Functions

Status UpdateProtectionSystemInfo (EncryptionKeyMap *encryption_key_map)
 

Detailed Description

-

KeySource is responsible for encryption key acquisition.

+

KeySource is responsible for encryption key acquisition.

-

Definition at line 48 of file key_source.h.

+

Definition at line 51 of file key_source.h.

Member Function Documentation

◆ FetchKeys()

@@ -153,7 +147,7 @@ Protected Member Functions
Returns
OK on success, an error status otherwise.
-

Implemented in shaka::media::PlayReadyKeySource, shaka::media::WidevineKeySource, and shaka::media::RawKeySource.

+

Implemented in shaka::media::WidevineKeySource, shaka::media::RawKeySource, and shaka::media::PlayReadyKeySource.

@@ -213,7 +207,7 @@ Protected Member Functions
Returns
OK on success, an error status otherwise.
-

Implemented in shaka::media::PlayReadyKeySource, shaka::media::WidevineKeySource, and shaka::media::RawKeySource.

+

Implemented in shaka::media::WidevineKeySource, shaka::media::RawKeySource, and shaka::media::PlayReadyKeySource.

@@ -259,7 +253,7 @@ Protected Member Functions
Returns
OK on success, an error status otherwise.
-

Implemented in shaka::media::PlayReadyKeySource, shaka::media::WidevineKeySource, and shaka::media::RawKeySource.

+

Implemented in shaka::media::WidevineKeySource, shaka::media::RawKeySource, and shaka::media::PlayReadyKeySource.

@@ -305,41 +299,7 @@ Protected Member Functions
Returns
OK on success, or an error status otherwise.
-

Implemented in shaka::media::PlayReadyKeySource, shaka::media::WidevineKeySource, and shaka::media::RawKeySource.

- - - - -

◆ UpdateProtectionSystemInfo()

- -
-
- - - - - -
- - - - - - - - -
Status shaka::media::KeySource::UpdateProtectionSystemInfo (EncryptionKeyMap * encryption_key_map)
-
-protected
-
-

Update the protection sysmtem specific info for the encryption keys.

Parameters
- - -
encryption_key_mapis a map of encryption keys for all tracks.
-
-
- -

Definition at line 48 of file key_source.cc.

+

Implemented in shaka::media::WidevineKeySource, shaka::media::RawKeySource, and shaka::media::PlayReadyKeySource.

@@ -350,9 +310,7 @@ Protected Member Functions diff --git a/docs/d1/d20/classshaka_1_1media_1_1mp4_1_1DecodingTimeIterator.html b/docs/d1/d20/classshaka_1_1media_1_1mp4_1_1DecodingTimeIterator.html index 19398e2746..b275534fe0 100644 --- a/docs/d1/d20/classshaka_1_1media_1_1mp4_1_1DecodingTimeIterator.html +++ b/docs/d1/d20/classshaka_1_1media_1_1mp4_1_1DecodingTimeIterator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::DecodingTimeIterator Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d25/classshaka_1_1media_1_1MediaHandlerTestBase-members.html b/docs/d1/d25/classshaka_1_1media_1_1MediaHandlerTestBase-members.html index e73d9a5046..13504fa0a7 100644 --- a/docs/d1/d25/classshaka_1_1media_1_1MediaHandlerTestBase-members.html +++ b/docs/d1/d25/classshaka_1_1media_1_1MediaHandlerTestBase-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d27/key__fetcher_8h_source.html b/docs/d1/d27/key__fetcher_8h_source.html index eac17917ce..272cdc8018 100644 --- a/docs/d1/d27/key__fetcher_8h_source.html +++ b/docs/d1/d27/key__fetcher_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/key_fetcher.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
key_fetcher.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_KEY_FETCHER_H_
8 #define PACKAGER_MEDIA_BASE_KEY_FETCHER_H_
9 
10 #include "base/macros.h"
11 #include "packager/status.h"
12 
13 namespace shaka {
14 namespace media {
15 
17 class KeyFetcher {
18  public:
19  KeyFetcher();
20  virtual ~KeyFetcher();
21 
28  virtual Status FetchKeys(const std::string& service_address,
29  const std::string& request,
30  std::string* response) = 0;
31 
32  private:
33  DISALLOW_COPY_AND_ASSIGN(KeyFetcher);
34 };
35 
36 } // namespace media
37 } // namespace shaka
38 
39 #endif // PACKAGER_MEDIA_BASE_KEY_FETCHER_H_
40 
All the methods that are virtual are virtual for mocking.
- -
virtual Status FetchKeys(const std::string &service_address, const std::string &request, std::string *response)=0
-
Base class for fetching keys from the license service.
Definition: key_fetcher.h:17
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_KEY_FETCHER_H_
+
8 #define PACKAGER_MEDIA_BASE_KEY_FETCHER_H_
+
9 
+
10 #include "base/macros.h"
+
11 #include "packager/status.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
17 class KeyFetcher {
+
18  public:
+
19  KeyFetcher();
+
20  virtual ~KeyFetcher();
+
21 
+
28  virtual Status FetchKeys(const std::string& service_address,
+
29  const std::string& request,
+
30  std::string* response) = 0;
+
31 
+
32  private:
+
33  DISALLOW_COPY_AND_ASSIGN(KeyFetcher);
+
34 };
+
35 
+
36 } // namespace media
+
37 } // namespace shaka
+
38 
+
39 #endif // PACKAGER_MEDIA_BASE_KEY_FETCHER_H_
+
40 
+ +
Base class for fetching keys from the license service.
Definition: key_fetcher.h:17
+
virtual Status FetchKeys(const std::string &service_address, const std::string &request, std::string *response)=0
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/d28/classshaka_1_1media_1_1mp2t_1_1AdtsHeader-members.html b/docs/d1/d28/classshaka_1_1media_1_1mp2t_1_1AdtsHeader-members.html index 39b1437311..07fb5f3b9e 100644 --- a/docs/d1/d28/classshaka_1_1media_1_1mp2t_1_1AdtsHeader-members.html +++ b/docs/d1/d28/classshaka_1_1media_1_1mp2t_1_1AdtsHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d2a/decryptor__source_8cc_source.html b/docs/d1/d2a/decryptor__source_8cc_source.html index fa588c3e51..e33bb73f6f 100644 --- a/docs/d1/d2a/decryptor__source_8cc_source.html +++ b/docs/d1/d2a/decryptor__source_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/decryptor_source.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
decryptor_source.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/decryptor_source.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/media/base/aes_decryptor.h"
11 #include "packager/media/base/aes_pattern_cryptor.h"
12 
13 namespace {
14 // Return true if [encrypted_buffer, encrypted_buffer + buffer_size) overlaps
15 // with [decrypted_buffer, decrypted_buffer + buffer_size).
16 bool CheckMemoryOverlap(const uint8_t* encrypted_buffer,
17  size_t buffer_size,
18  uint8_t* decrypted_buffer) {
19  return (decrypted_buffer < encrypted_buffer)
20  ? (encrypted_buffer < decrypted_buffer + buffer_size)
21  : (decrypted_buffer < encrypted_buffer + buffer_size);
22 }
23 } // namespace
24 
25 namespace shaka {
26 namespace media {
27 
29  : key_source_(key_source) {
30  CHECK(key_source);
31 }
32 DecryptorSource::~DecryptorSource() {}
33 
35  const uint8_t* encrypted_buffer,
36  size_t buffer_size,
37  uint8_t* decrypted_buffer) {
38  DCHECK(decrypt_config);
39  DCHECK(encrypted_buffer);
40  DCHECK(decrypted_buffer);
41 
42  if (CheckMemoryOverlap(encrypted_buffer, buffer_size, decrypted_buffer)) {
43  LOG(ERROR) << "Encrypted buffer and decrypted buffer cannot overlap.";
44  return false;
45  }
46 
47  // Get the decryptor object.
48  AesCryptor* decryptor = nullptr;
49  auto found = decryptor_map_.find(decrypt_config->key_id());
50  if (found == decryptor_map_.end()) {
51  // Create new AesDecryptor based on decryption mode.
52  EncryptionKey key;
53  Status status(key_source_->GetKey(decrypt_config->key_id(), &key));
54  if (!status.ok()) {
55  LOG(ERROR) << "Error retrieving decryption key: " << status;
56  return false;
57  }
58 
59  std::unique_ptr<AesCryptor> aes_decryptor;
60  switch (decrypt_config->protection_scheme()) {
61  case FOURCC_cenc:
62  aes_decryptor.reset(new AesCtrDecryptor);
63  break;
64  case FOURCC_cbc1:
65  aes_decryptor.reset(new AesCbcDecryptor(kNoPadding));
66  break;
67  case FOURCC_cens:
68  aes_decryptor.reset(new AesPatternCryptor(
69  decrypt_config->crypt_byte_block(),
70  decrypt_config->skip_byte_block(),
72  AesCryptor::kDontUseConstantIv,
73  std::unique_ptr<AesCryptor>(new AesCtrDecryptor())));
74  break;
75  case FOURCC_cbcs:
76  aes_decryptor.reset(new AesPatternCryptor(
77  decrypt_config->crypt_byte_block(),
78  decrypt_config->skip_byte_block(),
80  AesCryptor::kUseConstantIv,
81  std::unique_ptr<AesCryptor>(new AesCbcDecryptor(kNoPadding))));
82  break;
83  default:
84  LOG(ERROR) << "Unsupported protection scheme: "
85  << decrypt_config->protection_scheme();
86  return false;
87  }
88 
89  if (!aes_decryptor->InitializeWithIv(key.key, decrypt_config->iv())) {
90  LOG(ERROR) << "Failed to initialize AesDecryptor for decryption.";
91  return false;
92  }
93  decryptor = aes_decryptor.get();
94  decryptor_map_[decrypt_config->key_id()] = std::move(aes_decryptor);
95  } else {
96  decryptor = found->second.get();
97  }
98  if (!decryptor->SetIv(decrypt_config->iv())) {
99  LOG(ERROR) << "Invalid initialization vector.";
100  return false;
101  }
102 
103  if (decrypt_config->subsamples().empty()) {
104  // Sample not encrypted using subsample encryption. Decrypt whole.
105  if (!decryptor->Crypt(encrypted_buffer, buffer_size, decrypted_buffer)) {
106  LOG(ERROR) << "Error during bulk sample decryption.";
107  return false;
108  }
109  return true;
110  }
111 
112  // Subsample decryption.
113  const std::vector<SubsampleEntry>& subsamples = decrypt_config->subsamples();
114  const uint8_t* current_ptr = encrypted_buffer;
115  const uint8_t* const buffer_end = encrypted_buffer + buffer_size;
116  for (const auto& subsample : subsamples) {
117  if ((current_ptr + subsample.clear_bytes + subsample.cipher_bytes) >
118  buffer_end) {
119  LOG(ERROR) << "Subsamples overflow sample buffer.";
120  return false;
121  }
122  memcpy(decrypted_buffer, current_ptr, subsample.clear_bytes);
123  current_ptr += subsample.clear_bytes;
124  decrypted_buffer += subsample.clear_bytes;
125  if (!decryptor->Crypt(current_ptr, subsample.cipher_bytes,
126  decrypted_buffer)) {
127  LOG(ERROR) << "Error decrypting subsample buffer.";
128  return false;
129  }
130  current_ptr += subsample.cipher_bytes;
131  decrypted_buffer += subsample.cipher_bytes;
132  }
133  return true;
134 }
135 
136 } // namespace media
137 } // namespace shaka
-
DecryptorSource(KeySource *key_source)
- -
virtual Status GetKey(const std::string &stream_label, EncryptionKey *key)=0
-
Class which implements AES-CBC (Cipher block chaining) decryption.
Definition: aes_decryptor.h:25
-
bool DecryptSampleBuffer(const DecryptConfig *decrypt_config, const uint8_t *encrypted_buffer, size_t buffer_size, uint8_t *decrypted_buffer)
-
All the methods that are virtual are virtual for mocking.
- - - -
Implements pattern-based encryption/decryption.
- -
bool SetIv(const std::vector< uint8_t > &iv)
Definition: aes_cryptor.cc:70
-
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:48
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/decryptor_source.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/media/base/aes_decryptor.h"
+
11 #include "packager/media/base/aes_pattern_cryptor.h"
+
12 
+
13 namespace {
+
14 // Return true if [encrypted_buffer, encrypted_buffer + buffer_size) overlaps
+
15 // with [decrypted_buffer, decrypted_buffer + buffer_size).
+
16 bool CheckMemoryOverlap(const uint8_t* encrypted_buffer,
+
17  size_t buffer_size,
+
18  uint8_t* decrypted_buffer) {
+
19  return (decrypted_buffer < encrypted_buffer)
+
20  ? (encrypted_buffer < decrypted_buffer + buffer_size)
+
21  : (decrypted_buffer < encrypted_buffer + buffer_size);
+
22 }
+
23 } // namespace
+
24 
+
25 namespace shaka {
+
26 namespace media {
+
27 
+ +
29  : key_source_(key_source) {
+
30  CHECK(key_source);
+
31 }
+
32 DecryptorSource::~DecryptorSource() {}
+
33 
+ +
35  const uint8_t* encrypted_buffer,
+
36  size_t buffer_size,
+
37  uint8_t* decrypted_buffer) {
+
38  DCHECK(decrypt_config);
+
39  DCHECK(encrypted_buffer);
+
40  DCHECK(decrypted_buffer);
+
41 
+
42  if (CheckMemoryOverlap(encrypted_buffer, buffer_size, decrypted_buffer)) {
+
43  LOG(ERROR) << "Encrypted buffer and decrypted buffer cannot overlap.";
+
44  return false;
+
45  }
+
46 
+
47  // Get the decryptor object.
+
48  AesCryptor* decryptor = nullptr;
+
49  auto found = decryptor_map_.find(decrypt_config->key_id());
+
50  if (found == decryptor_map_.end()) {
+
51  // Create new AesDecryptor based on decryption mode.
+
52  EncryptionKey key;
+
53  Status status(key_source_->GetKey(decrypt_config->key_id(), &key));
+
54  if (!status.ok()) {
+
55  LOG(ERROR) << "Error retrieving decryption key: " << status;
+
56  return false;
+
57  }
+
58 
+
59  std::unique_ptr<AesCryptor> aes_decryptor;
+
60  switch (decrypt_config->protection_scheme()) {
+
61  case FOURCC_cenc:
+
62  aes_decryptor.reset(new AesCtrDecryptor);
+
63  break;
+
64  case FOURCC_cbc1:
+
65  aes_decryptor.reset(new AesCbcDecryptor(kNoPadding));
+
66  break;
+
67  case FOURCC_cens:
+
68  aes_decryptor.reset(new AesPatternCryptor(
+
69  decrypt_config->crypt_byte_block(),
+
70  decrypt_config->skip_byte_block(),
+ +
72  AesCryptor::kDontUseConstantIv,
+
73  std::unique_ptr<AesCryptor>(new AesCtrDecryptor())));
+
74  break;
+
75  case FOURCC_cbcs:
+
76  aes_decryptor.reset(new AesPatternCryptor(
+
77  decrypt_config->crypt_byte_block(),
+
78  decrypt_config->skip_byte_block(),
+ +
80  AesCryptor::kUseConstantIv,
+
81  std::unique_ptr<AesCryptor>(new AesCbcDecryptor(kNoPadding))));
+
82  break;
+
83  default:
+
84  LOG(ERROR) << "Unsupported protection scheme: "
+
85  << decrypt_config->protection_scheme();
+
86  return false;
+
87  }
+
88 
+
89  if (!aes_decryptor->InitializeWithIv(key.key, decrypt_config->iv())) {
+
90  LOG(ERROR) << "Failed to initialize AesDecryptor for decryption.";
+
91  return false;
+
92  }
+
93  decryptor = aes_decryptor.get();
+
94  decryptor_map_[decrypt_config->key_id()] = std::move(aes_decryptor);
+
95  } else {
+
96  decryptor = found->second.get();
+
97  }
+
98  if (!decryptor->SetIv(decrypt_config->iv())) {
+
99  LOG(ERROR) << "Invalid initialization vector.";
+
100  return false;
+
101  }
+
102 
+
103  if (decrypt_config->subsamples().empty()) {
+
104  // Sample not encrypted using subsample encryption. Decrypt whole.
+
105  if (!decryptor->Crypt(encrypted_buffer, buffer_size, decrypted_buffer)) {
+
106  LOG(ERROR) << "Error during bulk sample decryption.";
+
107  return false;
+
108  }
+
109  return true;
+
110  }
+
111 
+
112  // Subsample decryption.
+
113  const std::vector<SubsampleEntry>& subsamples = decrypt_config->subsamples();
+
114  const uint8_t* current_ptr = encrypted_buffer;
+
115  const uint8_t* const buffer_end = encrypted_buffer + buffer_size;
+
116  for (const auto& subsample : subsamples) {
+
117  if ((current_ptr + subsample.clear_bytes + subsample.cipher_bytes) >
+
118  buffer_end) {
+
119  LOG(ERROR) << "Subsamples overflow sample buffer.";
+
120  return false;
+
121  }
+
122  memcpy(decrypted_buffer, current_ptr, subsample.clear_bytes);
+
123  current_ptr += subsample.clear_bytes;
+
124  decrypted_buffer += subsample.clear_bytes;
+
125  if (!decryptor->Crypt(current_ptr, subsample.cipher_bytes,
+
126  decrypted_buffer)) {
+
127  LOG(ERROR) << "Error decrypting subsample buffer.";
+
128  return false;
+
129  }
+
130  current_ptr += subsample.cipher_bytes;
+
131  decrypted_buffer += subsample.cipher_bytes;
+
132  }
+
133  return true;
+
134 }
+
135 
+
136 } // namespace media
+
137 } // namespace shaka
+ +
Class which implements AES-CBC (Cipher block chaining) decryption.
Definition: aes_decryptor.h:25
+ +
bool SetIv(const std::vector< uint8_t > &iv)
Definition: aes_cryptor.cc:70
+ +
Implements pattern-based encryption/decryption.
+ + +
DecryptorSource(KeySource *key_source)
+
bool DecryptSampleBuffer(const DecryptConfig *decrypt_config, const uint8_t *encrypted_buffer, size_t buffer_size, uint8_t *decrypted_buffer)
+
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:51
+
virtual Status GetKey(const std::string &stream_label, EncryptionKey *key)=0
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d1/d2b/file__util_8cc_source.html b/docs/d1/d2b/file__util_8cc_source.html index 43eff45012..ee02a3a8aa 100644 --- a/docs/d1/d2b/file__util_8cc_source.html +++ b/docs/d1/d2b/file__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/file_util.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
file_util.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/file/file_util.h"
8 
9 #include <inttypes.h>
10 
11 #include "packager/base/files/file_path.h"
12 #include "packager/base/files/file_util.h"
13 #include "packager/base/process/process_handle.h"
14 #include "packager/base/strings/stringprintf.h"
15 #include "packager/base/threading/platform_thread.h"
16 #include "packager/base/time/time.h"
17 
18 namespace shaka {
19 namespace {
20 // Create a temp file name using process id, thread id and current time.
21 std::string TempFileName() {
22  const int32_t process_id = static_cast<int32_t>(base::GetCurrentProcId());
23  const int32_t thread_id =
24  static_cast<int32_t>(base::PlatformThread::CurrentId());
25 
26  // We may need two or more temporary files in the same thread. There might be
27  // name collision if they are requested around the same time, e.g. called
28  // consecutively. Use a thread_local instance to avoid that.
29  static thread_local int32_t instance_id = 0;
30  ++instance_id;
31 
32  const int64_t current_time = base::Time::Now().ToInternalValue();
33  return base::StringPrintf("packager-tempfile-%x-%x-%x-%" PRIx64, process_id,
34  thread_id, instance_id, current_time);
35 }
36 } // namespace
37 
38 bool TempFilePath(const std::string& temp_dir, std::string* temp_file_path) {
39  if (temp_dir.empty()) {
40  base::FilePath file_path;
41  if (!base::CreateTemporaryFile(&file_path)) {
42  LOG(ERROR) << "Failed to create temporary file.";
43  return false;
44  }
45  *temp_file_path = file_path.AsUTF8Unsafe();
46  } else {
47  *temp_file_path =
48  base::FilePath::FromUTF8Unsafe(temp_dir)
49  .Append(base::FilePath::FromUTF8Unsafe(TempFileName()))
50  .AsUTF8Unsafe();
51  }
52  return true;
53 }
54 
55 } // namespace shaka
bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
Definition: file_util.cc:38
-
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/file/file_util.h"
+
8 
+
9 #include <inttypes.h>
+
10 
+
11 #include "packager/base/files/file_path.h"
+
12 #include "packager/base/files/file_util.h"
+
13 #include "packager/base/process/process_handle.h"
+
14 #include "packager/base/strings/stringprintf.h"
+
15 #include "packager/base/threading/platform_thread.h"
+
16 #include "packager/base/time/time.h"
+
17 
+
18 namespace shaka {
+
19 namespace {
+
20 // Create a temp file name using process id, thread id and current time.
+
21 std::string TempFileName() {
+
22  const int32_t process_id = static_cast<int32_t>(base::GetCurrentProcId());
+
23  const int32_t thread_id =
+
24  static_cast<int32_t>(base::PlatformThread::CurrentId());
+
25 
+
26  // We may need two or more temporary files in the same thread. There might be
+
27  // name collision if they are requested around the same time, e.g. called
+
28  // consecutively. Use a thread_local instance to avoid that.
+
29  static thread_local int32_t instance_id = 0;
+
30  ++instance_id;
+
31 
+
32  const int64_t current_time = base::Time::Now().ToInternalValue();
+
33  return base::StringPrintf("packager-tempfile-%x-%x-%x-%" PRIx64, process_id,
+
34  thread_id, instance_id, current_time);
+
35 }
+
36 } // namespace
+
37 
+
38 bool TempFilePath(const std::string& temp_dir, std::string* temp_file_path) {
+
39  if (temp_dir.empty()) {
+
40  base::FilePath file_path;
+
41  if (!base::CreateTemporaryFile(&file_path)) {
+
42  LOG(ERROR) << "Failed to create temporary file.";
+
43  return false;
+
44  }
+
45  *temp_file_path = file_path.AsUTF8Unsafe();
+
46  } else {
+
47  *temp_file_path =
+
48  base::FilePath::FromUTF8Unsafe(temp_dir)
+
49  .Append(base::FilePath::FromUTF8Unsafe(TempFileName()))
+
50  .AsUTF8Unsafe();
+
51  }
+
52  return true;
+
53 }
+
54 
+
55 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
+
bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
Definition: file_util.cc:38
diff --git a/docs/d1/d2c/structshaka_1_1media_1_1mp4_1_1DataReference-members.html b/docs/d1/d2c/structshaka_1_1media_1_1mp4_1_1DataReference-members.html index a0037dd913..bbbd5a1c5b 100644 --- a/docs/d1/d2c/structshaka_1_1media_1_1mp4_1_1DataReference-members.html +++ b/docs/d1/d2c/structshaka_1_1media_1_1mp4_1_1DataReference-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d2d/structshaka_1_1media_1_1mp4_1_1Box.html b/docs/d1/d2d/structshaka_1_1media_1_1mp4_1_1Box.html index a6b89fb66a..76d49a9125 100644 --- a/docs/d1/d2d/structshaka_1_1media_1_1mp4_1_1Box.html +++ b/docs/d1/d2d/structshaka_1_1media_1_1mp4_1_1Box.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Box Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::AC3Specific -shaka::media::mp4::AudioSampleEntry -shaka::media::mp4::CodecConfiguration -shaka::media::mp4::CueIDBox -shaka::media::mp4::CuePayloadBox -shaka::media::mp4::CueSettingsBox -shaka::media::mp4::CueSourceIDBox -shaka::media::mp4::CueTimeBox -shaka::media::mp4::DataInformation +shaka::media::mp4::AC4Specific +shaka::media::mp4::AudioSampleEntry +shaka::media::mp4::CodecConfiguration +shaka::media::mp4::CueIDBox +shaka::media::mp4::CuePayloadBox +shaka::media::mp4::CueSettingsBox +shaka::media::mp4::CueSourceIDBox +shaka::media::mp4::CueTimeBox shaka::media::mp4::DTSSpecific -shaka::media::mp4::EC3Specific -shaka::media::mp4::Edit -shaka::media::mp4::FileType -shaka::media::mp4::FullBox -shaka::media::mp4::Media -shaka::media::mp4::MediaData -shaka::media::mp4::MediaInformation -shaka::media::mp4::Movie -shaka::media::mp4::MovieExtends -shaka::media::mp4::MovieFragment -shaka::media::mp4::OpusSpecific -shaka::media::mp4::OriginalFormat -shaka::media::mp4::PixelAspectRatio -shaka::media::mp4::ProtectionSchemeInfo -shaka::media::mp4::SampleTable -shaka::media::mp4::SchemeInfo -shaka::media::mp4::TextSampleEntry -shaka::media::mp4::Track -shaka::media::mp4::TrackFragment -shaka::media::mp4::VideoSampleEntry +shaka::media::mp4::DataInformation +shaka::media::mp4::EC3Specific +shaka::media::mp4::Edit +shaka::media::mp4::FileType +shaka::media::mp4::FullBox +shaka::media::mp4::Media +shaka::media::mp4::MediaData +shaka::media::mp4::MediaInformation +shaka::media::mp4::Movie +shaka::media::mp4::MovieExtends +shaka::media::mp4::MovieFragment +shaka::media::mp4::OpusSpecific +shaka::media::mp4::OriginalFormat +shaka::media::mp4::PixelAspectRatio +shaka::media::mp4::ProtectionSchemeInfo +shaka::media::mp4::SampleTable +shaka::media::mp4::SchemeInfo +shaka::media::mp4::TextSampleEntry +shaka::media::mp4::Track +shaka::media::mp4::TrackFragment shaka::media::mp4::VTTAdditionalTextBox shaka::media::mp4::VTTCueBox shaka::media::mp4::VTTEmptyCueBox -shaka::media::mp4::WebVTTConfigurationBox -shaka::media::mp4::WebVTTSourceLabelBox - -
+shaka::media::mp4::VideoSampleEntry +shaka::media::mp4::WebVTTConfigurationBox +shaka::media::mp4::WebVTTSourceLabelBox + + @@ -202,7 +206,7 @@ class 
Returns
box type.
-

Implemented in shaka::media::mp4::VTTCueBox, shaka::media::mp4::VTTAdditionalTextBox, shaka::media::mp4::VTTEmptyCueBox, shaka::media::mp4::CuePayloadBox, shaka::media::mp4::CueSettingsBox, shaka::media::mp4::CueIDBox, shaka::media::mp4::CueTimeBox, shaka::media::mp4::CueSourceIDBox, shaka::media::mp4::MediaData, shaka::media::mp4::SegmentIndex, shaka::media::mp4::MovieFragment, shaka::media::mp4::TrackFragment, shaka::media::mp4::TrackFragmentRun, shaka::media::mp4::TrackFragmentHeader, shaka::media::mp4::MovieFragmentHeader, shaka::media::mp4::TrackFragmentDecodeTime, shaka::media::mp4::Movie, shaka::media::mp4::MovieExtends, shaka::media::mp4::TrackExtends, shaka::media::mp4::MovieExtendsHeader, shaka::media::mp4::Track, shaka::media::mp4::Media, shaka::media::mp4::MediaInformation, shaka::media::mp4::DataInformation, shaka::media::mp4::DataReference, shaka::media::mp4::DataEntryUrl, shaka::media::mp4::SubtitleMediaHeader, shaka::media::mp4::SoundMediaHeader, shaka::media::mp4::VideoMediaHeader, shaka::media::mp4::MediaHeader, shaka::media::mp4::SampleTable, shaka::media::mp4::SampleToGroup, shaka::media::mp4::SampleGroupDescription, shaka::media::mp4::SyncSample, shaka::media::mp4::ChunkOffset, shaka::media::mp4::ChunkLargeOffset, shaka::media::mp4::CompactSampleSize, shaka::media::mp4::SampleSize, shaka::media::mp4::SampleToChunk, shaka::media::mp4::CompositionTimeToSample, shaka::media::mp4::DecodingTimeToSample, shaka::media::mp4::SampleDescription, shaka::media::mp4::TextSampleEntry, shaka::media::mp4::WebVTTSourceLabelBox, shaka::media::mp4::WebVTTConfigurationBox, shaka::media::mp4::AudioSampleEntry, shaka::media::mp4::FlacSpecific, shaka::media::mp4::OpusSpecific, shaka::media::mp4::EC3Specific, shaka::media::mp4::AC3Specific, shaka::media::mp4::DTSSpecific, shaka::media::mp4::ElementaryStreamDescriptor, shaka::media::mp4::VideoSampleEntry, shaka::media::mp4::PixelAspectRatio, shaka::media::mp4::CodecConfiguration, shaka::media::mp4::Metadata, shaka::media::mp4::ID3v2, shaka::media::mp4::HandlerReference, shaka::media::mp4::Edit, shaka::media::mp4::EditList, shaka::media::mp4::TrackHeader, shaka::media::mp4::MovieHeader, shaka::media::mp4::ProtectionSchemeInfo, shaka::media::mp4::SchemeInfo, shaka::media::mp4::TrackEncryption, shaka::media::mp4::SchemeType, shaka::media::mp4::OriginalFormat, shaka::media::mp4::SampleEncryption, shaka::media::mp4::SampleAuxiliaryInformationSize, shaka::media::mp4::SampleAuxiliaryInformationOffset, shaka::media::mp4::ProtectionSystemSpecificHeader, shaka::media::mp4::SegmentType, and shaka::media::mp4::FileType.

+

Implemented in shaka::media::mp4::VTTCueBox, shaka::media::mp4::VTTAdditionalTextBox, shaka::media::mp4::VTTEmptyCueBox, shaka::media::mp4::CuePayloadBox, shaka::media::mp4::CueSettingsBox, shaka::media::mp4::CueIDBox, shaka::media::mp4::CueTimeBox, shaka::media::mp4::CueSourceIDBox, shaka::media::mp4::MediaData, shaka::media::mp4::SegmentIndex, shaka::media::mp4::MovieFragment, shaka::media::mp4::TrackFragment, shaka::media::mp4::TrackFragmentRun, shaka::media::mp4::TrackFragmentHeader, shaka::media::mp4::MovieFragmentHeader, shaka::media::mp4::TrackFragmentDecodeTime, shaka::media::mp4::Movie, shaka::media::mp4::MovieExtends, shaka::media::mp4::TrackExtends, shaka::media::mp4::MovieExtendsHeader, shaka::media::mp4::Track, shaka::media::mp4::Media, shaka::media::mp4::MediaInformation, shaka::media::mp4::DataInformation, shaka::media::mp4::DataReference, shaka::media::mp4::DataEntryUrl, shaka::media::mp4::SubtitleMediaHeader, shaka::media::mp4::NullMediaHeader, shaka::media::mp4::SoundMediaHeader, shaka::media::mp4::VideoMediaHeader, shaka::media::mp4::MediaHeader, shaka::media::mp4::SampleTable, shaka::media::mp4::SampleToGroup, shaka::media::mp4::SampleGroupDescription, shaka::media::mp4::SyncSample, shaka::media::mp4::ChunkOffset, shaka::media::mp4::ChunkLargeOffset, shaka::media::mp4::CompactSampleSize, shaka::media::mp4::SampleSize, shaka::media::mp4::SampleToChunk, shaka::media::mp4::CompositionTimeToSample, shaka::media::mp4::DecodingTimeToSample, shaka::media::mp4::SampleDescription, shaka::media::mp4::TextSampleEntry, shaka::media::mp4::WebVTTSourceLabelBox, shaka::media::mp4::WebVTTConfigurationBox, shaka::media::mp4::AudioSampleEntry, shaka::media::mp4::FlacSpecific, shaka::media::mp4::OpusSpecific, shaka::media::mp4::AC4Specific, shaka::media::mp4::EC3Specific, shaka::media::mp4::AC3Specific, shaka::media::mp4::DTSSpecific, shaka::media::mp4::ElementaryStreamDescriptor, shaka::media::mp4::VideoSampleEntry, shaka::media::mp4::PixelAspectRatio, shaka::media::mp4::CodecConfiguration, shaka::media::mp4::Metadata, shaka::media::mp4::ID3v2, shaka::media::mp4::HandlerReference, shaka::media::mp4::Edit, shaka::media::mp4::EditList, shaka::media::mp4::TrackHeader, shaka::media::mp4::MovieHeader, shaka::media::mp4::ProtectionSchemeInfo, shaka::media::mp4::SchemeInfo, shaka::media::mp4::TrackEncryption, shaka::media::mp4::SchemeType, shaka::media::mp4::OriginalFormat, shaka::media::mp4::SampleEncryption, shaka::media::mp4::SampleAuxiliaryInformationSize, shaka::media::mp4::SampleAuxiliaryInformationOffset, shaka::media::mp4::ProtectionSystemSpecificHeader, shaka::media::mp4::SegmentType, and shaka::media::mp4::FileType.

@@ -273,7 +277,7 @@ class 

Parse the mp4 box.

Parameters

Public Member Functions

BoxBuffer BoxBuffer
- +
readerpoints to a BoxReader object which parses the box.
readerpoints to a BoxReader object which parses the box.
@@ -372,9 +376,7 @@ class BoxBuffer diff --git a/docs/d1/d2d/structshaka_1_1media_1_1mp4_1_1Box.png b/docs/d1/d2d/structshaka_1_1media_1_1mp4_1_1Box.png index e1c7ec7a426b9e0d93b532ea9aaab8fed25d99ab..b02268476979c225b2f7b4d58c1ab92f1bba2039 100644 GIT binary patch literal 21090 zcmdsf2UJt(*0yDA;{Y={ibjNC9AF$pM2!@IjABEibLd3|5e-TNL~1|>1zP|`0R=(C z0*4Zc5Nbftpdg?lp%@@yK#&%S5FnI)pU`Bkcm4PK*ZuyroLOtIBqry)=Xv*j_OqY; zUewjzC-g1u+c|UQ2x;u!tv_eZJlvc)iv}0Zhrcm-b5aL@SoIQ+J?qu({? zNih6Q@PA=p;ev~G67a{xr}VWA=D?e<|Cl9)TjtEs>(SV~)6jixXMMdhN0GX>u~_#8 zcl?^$ALfK}$BH%VAE>f@EX~&H&C|$8`6g2Nw)Vr5$~y~vnr=7Y3(w_+X^&T9*4WTg;ovSaC6rBOV&6-lorz8 z#XP6pVDG|6vAoI|<*)9x$KLQvG#5Ro`8Kn+=U&9g=bh;(>de8BwcB?Xt{Gep-|CYQ zbNs%KF(>pzXrKA>S8n3*PMf=4>E2y95<610<7VZbv72~G-1-kT%q;h9p?9|ZIQVcV zNpy$9a_c7V6FY*6GM^GqT>Ij&3vqMTjUQC6bzp2?m7f)Qwlv?V{9;k6(dAf8Rvi)< zH@Bc-M?r{hPwm}>S9Vk4<}SaxxAM#q4;c@k&63<-sB@+NWx=!`zF8l6cVV7{{o?OW zD&AfA%_^m64*a};`~FZ<(Uq*ZbBlh!|5Uj4hxzli!K+7i3oU*Huib&a{Cyqq_cQSM zbKr~S;`IJ&Z^#S7m8Na9F?~nvJ3=%>&ci+Hts@qmi~9k8XjkP0+-6DQZlUmQGF}_W zkl@6j#FBkAORuUwS5_pCIQj+^p=fyvB`8-;&7ks3@rW0EgsT1Xp<9g!BD6+22M5tX0i2w)Hxr$8hTG*@ZAQF~n%7*B%&1X1Km`@machxO^SH>%h~hlpLJj zJpRh@rNqdJmOj2N(ytt1c9KUHnFPl#**EUk1_mkl8eY=JzoQKvQTKS&5Zye15yP$} zC-M`TM;xE+;CFqijWCx33P$v1qb0uWWFqsAm)&iTGfSMZv~iB&k&1?QP?QSm+AE7k zQJ-k;%JFC&6uq?^f9Mx%rN77DU3k!aKD;)z9d1qlso4+2#xzuFBLE;z>c5AA|2LrV z^lh-S#S03x5>>HNkF@X&aTv(-!&A9qcvF=xQ}|0n%@nsx4!1N zIGg-jWD-5HK2)h9gX1DDLo7EG9sU#W%huxzSCQm=`~J|XIX(1dI)L~&EZS@A`0O4v zOU~QkF50#No|v}*Mc#&%m#I&eDQM|TNKxOytyE0hT%wq)Y88iiUWAV$9Q)P$MFTTS z*t47@sm}Jex0hc|auE?~vI=p!JiY*5-qJTjhWFmqkah1S2f6+cC*p!PTFsc35$|;U zo!M+yA({3FNxUSD=t zomID{B@z`bHj`z1M-@N*tVz*A=7jk+8Q~RiXxj$tsx@J)*e$uw##=&A^aCLL;`DMi z{0^@bXjPuMI(rKXfMpVDw?q?y2ub6=A4&d47~1K`i>)tXr4?y&O{! zVftK&MbY(GW)YTj>*3%Y23aG_$k8hMI?3K=Efn0V!Qx6-|MKAWH}#QTPU6(zR}jVs zoSV3?I&xFTtuR(=Z)UNG%P5^>Oc*1t%#>AZ>fD~w=|p3!%n>er)-|81u&G+jF90?j zEaTp&I43f{IxLsY8kHi25z^iFGmn?A%Czr)_x5=`&f%gdm-fuRYB;IJI_n=*Fq@eoz{DiwMNQ^B2_8aJ2SIDQ#t z{motoqP}+-#!m2_F)}PvL*SP)Mass~WucIw8m|3!^VI(cU0AMUc*Un;*Ro(tne<>U zfB~j2&s^A5&=@}NAM3iww)%jw#yaV4&~9=r$D_kPV92t>kOj#35(oL(kVP=!7$SW6Koou8eJ=ldkMESoBPhC1EzFd3Tn0f1 z(y$T*$$Jr|OW;lVkpk4;7T?hq?XeqSx?%8Gj^C8Mqh8;A^a$yNvQHs!<@Z$rt{kwN zWS{U&kz?7_3Uk5=EOm%fW*vDKdO_B}yjOVcqSX&3k+hTI)ACc%VSR*o8C&R^xZ*$P zQln$)Txqdoyp0`B%<%Z0p*3v>;0rIp7cLUAOW@?TV(QgfB zRDFzg-v4gjas`YT?fn8XdT;V`70&s#w>gm{%X#rQ97RbO`ICXoHmXMWI3Ga@c72}5 z8p#mnhaLV+uCOx=O@S!U9r`~G75`;g-JnUqu4Q9)wZ~S#^Q>DCu;~eohfoZV&SFL2 ze!V{o>}ry4`qYzv;s)~+v&|6ZP@NOb66rq&TVebW4nZoEKJ++yDzv{~qPReW!Oa1B z-n3u}B0rN>EBZtMM9d~3vdz(+raDkRe9~gbv3T^uWkFqKMrr5g=YNouwGB+31(Txa z?HwC}c4$9A(J1TzNa2OqJ#Q=QC5HXH$two3h>5;xzP81ys*YBZUVAmeX2ob0RpENl z0WMKY|8(L~b18P|*gCxMi`((3a;`O8?Sj$adyJ8Xm5R|7ExZ_DEz%k9;!4ToURW;M z^a5gz#*12B9`#_wTOHiD-VtHA58geGSLDt8VJ~7;2t% zgrmO(R3`q7ANfNgla@$H~GyK zjrTXzg(`JDQfqN)OTggdv6Esx+E6-(U+*=KcE<0!H%hiO$(jlt_U6pZ9>#xPzYGBYAP3pQjm5Nu)^Jm_mM&^m8N{SX{4Nea+b(nW&+>V`GlH zdP4Q?KUKZUf4c027v36h!=89WsF@JY81hyt5P?c@%h0Z%oVu1g-}fR33@O%|WtE!c znD278B#5vc9|kPxNu#SnGVItePbIufN`8%3=oVFd`NAdM}_lg@xN z=97Vp-3eIb)#zsS<|R0J@nu_R!7*GF zecM)19#QN_gN8y}YUfZKam0Q)TCEQ;d*y84sw~En=vBuD)jQ{w)X9&$8dO z`}f|7CzJ}HwYE<&OTHo6KKtYA-hxg=!-sNp7`Eysu;uCWIY;`baI=Rsk?)nKWYMPD z>h8Sx0ZP<{o23fiMJJ9T$oOxwf>A*%tgAVM`Y+Yhp?0QEmVsJi4nO|4)S>?^yv~DSbTfsD$FT~SEJ~0wv0Rt+F>p>}^KL<%-b(~OfO9tTNezF3HA-iEQCS(9H z7cZsT>va))qn`I9PYlJXIqyf+Ds_9q&WRCfOO45khpzZSHRry+^Ym$!ZAA8OuM}!4 zv%V{k#UR9mDz1fQT;P!^#r^(s2(3yRKNP~31?Ym#^<06e=v{1nNm{~Fp)nY>w+TvM zhw&h#e7PYllhb6tQkUNPMgp#*gGV_N5Rl z^i^bcx(Pkd#*1}&;=UbGVjurCeS6QI^6Jb!#p9(M$%uUmtcbt*;k=Gc-eBwmW*&4@ zeN(lgFQwv=ll9M;!pX2tXclT7D@uJ^n^sCeFcMq6S zCEDea%!Q}4W+&3K;Nc$0O#AGW;hBI(W9%~man;p6Ui^PmosD)l#?wdh&AT^~#to2u zOd$ZtG5K*@N$6S53%{oVhIC3vTvnhM38)GvMrEHXMvTE2oyt`?B{?7HMNs@qa_Ri? zdn?6UvnxEf+p+vrn)FR4F>zdMyaBmuC^U$t*XoLY;!PFyVM)Iq9H|*o^9jv`dWsI3 z>X#Lxz)dHl4tJQ)3fdz_+ghK-%s~(`h&@+Hg2LWAcX<3Hh?VOgCC^CKq&t8oHq;~g zrv+aDMHQ6F8%xv9NkKhL`{jQ}fc}p{3?_p2SP`*nu{&E(9sxIlsdqECFfEZjDV-f= zc)@R4NIoqmdxox2J57;dY|l@SAmMm=}mx|SN}^rHS_=#zGPGJjhT zdk|6;Ya&%yzNM|_6RI@=8r5i>{Gkf*R7cp0SAdqvL73?atENl$hgMi#b12;D|1nbj zxN(#F_&ZC&noV`R1h$(*UX9fR2a;UF-$3f;Z`z>F_FcI>0Y~nw&*3?$d0arzhZqQ< zO8RXS)2Y*)CrWrmosf`S_{b$(@$>NqQ@|m=0N|v%MECI@sp@m2^$l#_>e6*NkAFhu z`xFB4sgkBYABuTHSj^f;L~QkiK?o`xxfj!cw_S5(efC5nLm*ARZ~e<`m!rX3adSO0 zTB}gAvb`@fJqVl?P`3C)8*ec}`l++x%OEE3=L>x~!hday`R~HCh?1pGdu=Dz$pq>z zfiS%fMMtr8&c!xQr21d9^qIEC>zTGjMQ`_Ns_B})a+*(4ym63_5^?E<5(g>Zh+%<%vh z6cwLES^iN;$wzNCCl+_k83}Z;u7h=uhixHH-&+zlJsNEHs669)26_?Ka^J|Fuci(U zsFI=w@$W)ku$V!<(dSPr6;EK;lxo&E9YL6af@A}+?l->GJE}&mopbKU&9bS+XYPP} zc@jE|#q5z#T<*evr~M+M;q0CYQJVnNX{d~gAfv&6nu51e0$?QXliFesm_O9c1dY*o z(A=tQR%>zlNRDG@-5VDn7P7j{C!+;cCY`tlJh!M0MG07TA-oaje0$|SSB@2PP9;dP z>hkY`LL>M}jG%J+HuT>?+Z<*EWNsq7Qh+hK>56(r`}o@05Cr{MQeJjIT?!w)=2p=Onm3TOIR}{KdgYm#uZ#%Bf^C_fN3=iUczp1((k<7=8}vagRyYO_>%JYaYN0MsKGObK$wP4Tc=X3*A`f!@KKP>OgjD+@ zT6LkJ91Y;Bo%Vo$o+17&N~6xCiWeYcx1kr<>cLEmtungzQ{R>^PZN#ZTAlDp(TjS}&TS*|{K{HEqs{l-wS7Vum@eE6}dYnHnr2>?-@1f}N z`bvtPzqJ>@8c|BslAywloeQ@%7K%xGt1Yt>+MRo7g356b(Zbm+=YIF_0``{eKJU$O z)1-AU*CRFF$@GKB9&GJh@KtH_rKulWUcQs6E)LEWs4pfzf!9F-vbGi$E3V?aGOMb2-_GDG&*R8h=1RA(&I?5jcP8}jy% zfG1Nj$x(HnneWuon*7cEn8Jc*(5##RMzgyaejqy**A6jo5yoPkeX07rCwAP0x6svG z0di08B7wx~`)UPz!+vUmd zwpWv9;)h~f=rmtzHL1<3y&w#u37lZNV~vKNZ|rFdJwE4oO=;z>YL)v+g?3W+0O zgZZ^Unfh}{fhr;nQuh<&&F`aaEbNKh_D{RfFCY^mE4O^Qy^nY$L~0V3N9=Lwm?BeG;(Gl4$deY?wY_t$1DX%m@?PQ(0o9E30P#@ zfqeXb@yYyKC~)sHuxnX4*q(P2ZUyA9FI7<^x__e$X;JkjPA?uBA&+Z7QwV!PrLZSd zTY^8bJ_hqMOYBZ&EyKTa8>HjH4&HWLlIxRB6B!zu>kG=Pxj>l}mTF9C^uA&KRJmas z6#0b!8F~@}zcuW~M2-Arm#`+>$^D#D(6`>;oK;}ykyf&^jAIJnAA8&v0SpdSnTBFI zUCvqedykoHSZ_&jx-oj}L%T7Ok2NeLK-|B=C0Z;}ol?t2-d8{AIea4~=3o^S^*pbj z$MIH+W(NQUw+vkp$gpk^0SM=hLifI*-;Vv-UC|xlzhy)Bq^HW$O)>OAae~F4#aZB+ zDul%HuV#m?kdfmzl1dUe{jdcD9ZhSX&g>Qz+XG0(Y)UDLVdG~kJ3vxcG7SrXW9e(F zL#+PJE)wnCBI*OYqtvYV8D+5xRo+WrSyU&kCkz20fY)h&zuozb=?j39SOje~1hF|ALvhCZi;uIEi zG2K&2mJ(G~-6IzA26JLwemf$nMA$aC$i{pu0F|%(l~`!qm@8yQUClc5^6BSA2(Q1n z6v@m<+uQH&Z0TbSB0LRbW(+HrcSCB;g=?BI#Eb>Pwj^OJZ92<*y-bv?`!^;ESP8MJ zqfS&GV-GMsp|rL#D@r^WC_31uX62E$R6oQoV{cuu&j^3xar15yyfE?jnldAZADG!} z>>$PAh+1Eo6lfW$r0VIWPUG0==GLb@uqy+w=wXXLEo5Yz`O8|JoF(RKJ;bXHfZpnR z5v(TWrtB%7)CMp|gm-706gyaRxx@)eRejRaK0BF%^!GC+%wN3ohA@)=;b#P{AuC1& zf`>Cb^LDX~c}@WOdi&dP4UpYGgsmyjZ3>DWY9Khi5f<%wqPBq%JM3&?$K&YmLE&OZ zpqO=K#KR8=gz&7$Kr@8x!-h`zmm>4mrf=~o6+gE`bxF3@*56Zq-pu=?WaSOP)nIHb z#Kx#}8BbMJi+B|0-lzon&l0%=rx%qULsQyiyf!Qf;PSS<3%xN_hze3k&g-laS@-(Z zJ}WP}`ALMi0o&LJ0AiDd;yvO^7XIB&Mbqg-N%?hopiYK0p{x53najA%jcbSh?Wg2i(M=oZg|ZgEn3#idg6G7kJb^r|7;hQV}?&kqU6`0(>hA4MTt?FH z@{Z*RXcT5)zzbrDumtz$t6$=+&u3igJr6|+=aO5Os{5ZPDu_2Aik3i;a_fOS#zj_O zox2~3lT)}#%JRy!G|x}pK+JQWw#^M+dlBY7O;W=)1}aFzJ6ZcYxNkQAZ`9F%vbK5( zKD7X!RAbcxyfGb}PpfiCH=uJ|sDu0W$VrZ=dm66tcpw?ZQdrf;jA1}$Tk~`$V;dEUV zS&4u5!}v8pGJ3#w9zI(2CW1;ZMAl-aK`KO|`r<_%T4g6r@elG&SA{S#2(iJpm4x;4!kAg~Zk882Pw^MWrHaotPt-VE>JIG($^Fe; z4f2Pq4&ioYD{>~oXy(rJ!CzpM56ao`T|;9X&nlk1l_%*__^9f5@1H{k?Oz6*@tM*+O1`2mtL(*M2By|VpyY2{9x+(I<@xFXvrk=BNO&H z)sQegtJZ2yRpASc#kluadc3^F>fa!!WBbuM-bt&uS&OQXfBzU(WKWw@sLGV$#)|a& zT;n){&f@BROs85(6x)*S^U_U88uh->@?zW8jaT zENKwuTUfXf4n?CT4V)qWUg)%%Jg#sa7DOxqQNLKJm_cELY^S+AQN zlDwXO>@!A+IgV#P-sL=Pi4dPJu?MrkpAf{P{T0oLTDPDth<_zbM;RPo-s`3~Lsunt#Wud!6icq7wCmg=Jxmg zR-ISho2}_A^jUV>l5vdJUbirU9AVB|9b=$$TkDcmgs*)N!{{fpcch*UGZ`Qq|=kjQv9o8YI` ztaLUaFl5U8GYB`Rai7mU^?vU>JcuA=wT@)}wLg<&yDtx@TT6B(%lr-B+mSUj-U+|M#N3ool0lfot%|I@8quB zmb6)2{iZ04xXEGtBkt#I0z2o57Il0VO{_AU0HzyJEV@j3Fh6`S>a7-do?f??R(W8MBF$nnTkYXf~P# zR$DSui-k7DR;07KS@*HL#H-AbZo1|-EdXvg*mA`t_vd}p+xK*}_+~tIOTe0qqy%~T zu(|edfREzaXt^i;SCSVr9^D_Yz5EKU+Z_1G@iH4s^iwLB5dA`~1gZ%w9T0*NXo^Aa z0E}2F`%hZp{!$6OQ@c!LJ3xco#QMDRtkJO5(~#2>CD4tbg^5Xi2U(v>ej!yZqb_xQ zK7M)>*J>0M#mXx!LE+AoPD9(UrJ13{dFO#h`-VYCo`%89EbG@+YfhVOZ*jkJ^!n+TpJo?!O&bad3Qn$$nG;T@Noh16`1j!We#h2FM;@z)PCO=(qo{iR)W zn5WC%08OTLHy>ksmr-8(!H_3?zf)KoBanAMCWK+S&)k%)e*S4P{V}+7X(&A122W4S znz)?$+mxA0GF}{eHw`>(C z6u#D!u=iLgCxzAT*g)t%08<5bXXPg6rAn5*2y$CgArbY&JR1c9L-#^a@iM?s`^dDH zfk|^dIr5Y+&vA90<>(;K6kOcF1MNfjqiHtK(Z}{=0MR17_vRg0thJz&yHMMu$E`?TYC8q?+Z_M3U0jO_ z4M?n=s>8(G{$p7?p(+gc{Bb|=!a^@~mP9x+P58ChvH#YSrUk$0H%6G*R^HwPD3PK0 z7<)>B@_TF3@aroP5MJ28^F`dXChhzMZ?Q8Ro=D849h~YXoZQbw3+-Qx`g@UA&r7B; zI;o`vMz-)g^X@TZH+VT$?e6e1pLR&T@~mPwMdBS5mt-Ayl}Q4-wJPR2O2CxlWHCDX z^&Nhs&uTD97Qf4H_x|y0M&);NAEF$m0y4tHKGZuwkbrEzxcr-EV(?E|d zC2BxCg&P8z;NuEh$=DK-pS(P+t)Ss%0NLmYU&I?jP4U3iC0Mz)*@gvdRuUG?3dWgX z_UNNmGU|DjV6g#iY5Y%|dM*s7t6^&@gEEp}uLbiH3J3ma>%Y9Ybt4zYA^g!bg!_U1`ho={X9^Bn=dpH}r$mqUzVp z_2LC|%>iM_=$?uvnG1qUbCO1NDebpde?>3luBlUfpIOy%zQ5{3{E4>~*I~c%h;?lP zR&=Uq?egpe)A1*{jH&2Y6{dFl6>Y}|j6sX@Dv${`upveAn8Ql5iY(1aN%e{%dNOXG zLzhK+822q>yNkh5>IPOnydADd9D3r5xx~5#r_!MbcC2{MrBzIeB7f5wQdxo9)t!`7 zVqW@`y~-7;^o`@HE%{dniMX&wLUy)y8Ai%h`ry{>65lMefd1@Jj7oV)pLWl-=`^jiEs`h#NzgO-G%P&`N=`0kDm`J*=~wXa58tX_FPjT;l$m?IuOmP z+Qr1_KuvK_Fi#>a1i1bOmsdW2OJO3}QMcPpDFebZs|g6$Od=rYW5Y=k_8Q@jmdu)m z4c5mJ#?P*ShY5VSKQ|wS16EkOIFAqs^Qw*~UB!+h398Lcs;{h>SH)tfi}|xfu>o74 z%M;GsnzU1kr>k=dFAYjjbZ$S?RsvC(x$0Wxhm8I!szbaXFY$p+IMZfmL?{D%Z&+!9 z@#SY;FxM6_HP_~}*^#SYjiz!pUyqpaX_5mpWLK5?PKByc^;-8mlpZS>ArWRfenxsU zn}c7uZeHaad}qbI)G_Z0%s1>?^99f5D&k{9N|KaibzW!6ipZFJXlY?aIzb)5_ofaS zBcroV8lhp+lb9!QrW5w{rnv=w7j-71QXO!Db;X)*E-dPsIKyFR5#)UsBJoJT@hdst zI4Nu#R_XfKfudJoWhBRbHR%;+qmMUp&Jwq4&x6uZLmV!*V%fvw3Or|!a# z_JygyqiUnSl+nvJUgktu3KZToG2Vla`H&!ndqK_Q#9%sD?rsJyuI3I+PBl-=)gX*R))lP zL~PP(#0wT$kt~wQ3q>3Z5j=)0INoM}D(6O~@iiMZ`5x&FMr&c@q@wL{h7;4Kx2<$% z483Mm0Wp6`j+_C4$I5*dys!q#`7h1>jY?jDQCLIlQ$^}HjNb0skvq~=2B(wA{_E)^ zsqDID_m>|V<)w)oJzqGTq-hAPaJ$F%P~_&tLVP9YaS|{UcAO5pf`sW8)4lqy*YC4) zwiqPd>yf#oE_Y0c`SFypSaevjFWTnrZQ+%}?Z~cLG0Cg2rgVkUFHM^GD9a&6X8M^S zeK4e(FtdE3Xg@ZnRhfSq@FA{)jNSrJ}ON==P4fOD}g!v^`2cR%U^BS%3eG{^hcYXDili3R8 zN z4}5YLuEfaM4ev;L)I4c+7E2h7W2BVCa8Fftxv0ja%B2&!jZ~`i5^$uriAgH2Cr7N! zGLF|W|EjV~!_Hej7Id`uEkFd9%c{ZczJM#u3dhtu^C7ZSYz%pf8#L_rpBPt`PtvixMBq-k&G`oKuNR9Fk5>R4uqVe Nu}6D%@~%UF{vWTPm_Yyl literal 20518 zcmd^n2~<;Ox3;sj3ba}U148*!v?@^4Fhgo_s3HQ&VG4s7ks5|D$V`YW3RQ_Xf-*&9 zKFlH^LI^0DfFN-ofJ_ksM47@Mgqi!EFiCH_?*0Gueg9ha?^;zc$DHAP-o2mw>}Q`# zM#m0`eU18h(V|6Shkx0Be9@vMs6~rbmVC7o{7v@gvQhAxl+jU>15;B|;Ex}=20g=` zTmyd+{a;d2viwq`9Qg68bH|UJSOgA2{^LA1*}Z6yVcy~W`%HWmcQ-Y;^VG8rwy=zD z3#M*(pTc4;oMjz$NYdd3T3c>1UUE1uds(z*%&}xw&3z?-tud|Wk_+^k^c8omdEcmA zw66bHKkDSq&4+E49vyz>y<2JU{S!Gm<^4VK$!xiCCF7+Bn|~7XsoED@@m8>HH@>7y zK)#6;H2~n% zB?g-D!pp-4uw^g3WmDaL?0IQ)f5mwGc#YQG>fhs)gc^dTb~_HuXK(nuz26Ndk7P({ zIj*y94RF>9E2Tcgz^KlzCjUrTym{)V-djhes#Fmz{I`lCx2j8}Ii^?Q^&1+Y=#<69 zY^~y(q`tTJSA^~-rz~D~|6uj`RleJN#eS3*Y{^=z@ZTQTvE(;DMBiUQmvi{)8&~!F zE0#%VPwdAXUV_i=fxrA|GybRZ;QJSW z6D>v=|Jx3rN1!Sm?6R|Xmo;z(ZvtHe_iVfwUveSkTlC4FtN%d#D39MScBhw!J_hB< z@ls&?^Fwv3uj`d*suRauNMWTgT*W7c6)NkVs6Njc_Xl60<4`sd*^(xa|4;xv-H3Vl zFMNp(_c-rHVOaDg#(VVHkcT!mGy^{vmQt68(3=kyU31Di?Q^-?PKh*j41#RGL7!~Z z!dr1iyW0phjmK&V&DM$gQeJE<^*Ru|BuC}D+t}v<(?&^MC1YstYp~pmROX#*tPS=D z?oAT+>)4P@Iy5t!|9NAkTX)~j5Jw+D%wfH^M}{()o-aKDS8p7x+Klcw^0X$q02Q=k zY{S%Qd^DRsFlGb|YTmST6%r+8z_I1g?R&VZVHzZp%g530@`ump`MzwXv`u5gq-T|L zQCi!$%QLO9p0AHVoOJ*N#&N)@t+wqwC+>Le&94h_9bLvN3sXTJ0fJxQ=(Lmlu|?!xQ2jy5jw6%DeO%E2*)^~A8y zqK^9RT7JU^Dys>F{h%o$Stvnordf@xk*xs`1uO1*pE=lVYuhvGB8;G0PgcH{hjKM= zb+Mcv$Iaf3>08efaW_b-Hau)@t&d2BBLUc3AE81nIBR@N^b3#HImCV<{;0qV7pgl% zIl<}s)gi*xc00aA%{MO2Y0%G%r}^P-f#LJLUFIs{#P_s@qvRG91$ zs8*-2`NBB3LmoktnE2TaB;1%6_n6)T(P$N|)A;7vPd||xg3KU;!<_Ti`C@JR9>mT- zOS`9B6V5pnXh62mx`OIu1tiCHp>fiocOOm1AQ7tWllp6a2*H%zZ{WI>PsnFEWMmj< zr^6k{y(b-nID!G~LlDG$H~8%Sihz(QWqiQ5Qs5@1E}?9n9RNE*$Vq|yv=&6JIhZ|p zuuI<@#2+91|3^XSZ{a6MWFptHVYrii7X?A`_>y1dVv=a5h+w7-EkKy>8V%w&+~In3 z15Kj9hRAs9D6tNGZy+oM1dM20q;j&YGkTSueU>Ce1K{pDDx#4XaHIBC|xroLtk8?C+VYt*f$f#>6|l97`BA1^y5OqGZ`pbf)s?P`jG) zkazLQH5PX(ktlUl=zS;{&Gcm6E403fZ|ue#g{Rjgof#X#xh;=56ePQ)-=Z!7-=9@w_!wJ!Fq#PzWw#1FJr}=9(RuxOXV0lcH3mY5(i?+U}t| zkgqB?i(=KvOR4baiAkrANMc-v*ZyH81SuooniP*uw@!vT4k5AD8$lL8&SyFCi$&JB zIr#+C%~A&ey8qjupIcR0KlP=-s9~!!ML97h(8L|&NfZENvNg_(Moz$}tDI~$sr_59 z^8i-M46A9aJ?HdW2BV6$b`CElEla$Lt-dh=01^C9-)$TKiPMrCox-Q($1U=a>m*$)m^4_IX5Uc$2ea+EI<&^My zZmEC;9U8IFyPJ1O*_}a+VcD@RNVtRwB}TX#P?xI=8NvQz(Yck^n4x@8iP2W1p@A0<%)27 zizjOV1Hyt|{!@(SZ-dR}>C{IVjaJ)h4EzEJF7HA%3f=zQuy5e9^s^Sz5P40D zX&S2Y?ksg{E8HZEQof7;z!9A(5DrD=KMd6bYJhT_7obbwh5*)b=X2`3g=G1=!d3_F0Asg~Bj)V(US}Kpc8SsP z+-Nz?si15{hmgumuj@NY^zlwt#O*&WS3~&Gy*QcUx#9*$QXK0Vt}Xx&jgN)}bc?6B1G2ifyO88I5M8W{Kdm9PKjbugt4W=vvjdM11#A zeyCmHzk~+wQ@A$f%!^k$<*LLz+s^V+;R$5_N1{Rm!$ZuFEwW-AXPfxiYy7RyLk9Vm zU13dGZ!K&6=P?ij86roLgCB4{T9dIT%PNAr9@jU4`BJ%uqh2Xv8k?%3dTS~H#UB_M z*ENBN<*loAI@~D(lb0~*s0b%ReIsR!QdjsO>g#b-7W$S&-{imejt#ytRN?s=I&&=S z^~A|!6|YSYq=V#NL)3GdJ=Di{G8{M38m0NsusF+7amC``^0DI$+=e1zH?CLlTo@VE zyT=9zJ3`;YDl@2vDVMnc$y)o!adr?yq=?cP#H;xk5b|HZ$`mI90@d(0boNUNQCt5q zM4b-IgYm5%#b__BRM-!x`leDuX-uIvvKpkZ5e^J9;rD!uvf*XakNllzrAJy#$9*Qg zBY?s^0u=7LHKM{jWZc=o(Ivl$+Tlj`OoXq*GI|a9S|f$D1#*#M{d3mI2Gr;PJF~?!w?PM6(w8o%v{5A zJQJk1?LW=H>XhEw=L4C{?(Y0(?$5!DfnUgRwvB0ScYL=s-D6Vu@o*o-cs5!kAI0yh zFyMT2Z6uXRaMaI`EYUR;Y>rgy9O9jch3@{D2_ zt_ZfgrA65K@a%Jr6tt+cm6+Ns=xcXP72e~OKfVLQ8pzEaN8mLA51K&}X$ykUl@bzq0>73VFPuYUElfmXKo9Kq0nc!7a?kQ$d;=3{Oab%Ho9X z6PrJ@gONH8Ekmi*RW=MSXikAgzXcCtQU`>%SdYr?wsT28L7WSR`et|{7OCd?UfB$| zN?WgWA3v>ZJ1F0}XA-IAvAAeul9*~~TJ^==~k5E<~H>4F{{dr>D7CB%PvODT?fZUPk@1&^Krc#%8cMQh)D z&Wp?)n$vO!?&m%fr_K`VtUamA4_WtkG#9=oh20MKJzUm=zN5);eb@;y96um8uCo5A zq=s!n6)#&cEW}B6y-#Y~8hlsW%ngRk#G?n;b>@P~Qr(?Q;-xyxGUu>7kERN5BCIp{ z{gD|-A{@Y?n4Q0a1aUAweU6S6F+ey*8~$bmzVM7D>pnXELLj50Yulfvlh)yb?0yzf zFjUENB68!Gv$v+g1-vnv{bDrU`q`k9PN1~+Nl$%c?ooJ9SFB+JU4Kl~eu}U8@yA9! zm57;oySc^y01heQm!mTYll}Fz3C;bF^xehO%YKa66Wo1SMj%J;bSS-uo#c=81W7i4 zJ$JpfTKzPR)Rqy*wYUE;#(r`JiZ^6nh0QOvNdQKHaB}Xi+p&pU4o%$8)MYx0-6@QV zTXWOam?t#?KsUpSl!2s(^Xl;kq)-px8~5Y!N2Q-j;gHF?sk2oR;2-Lx|(MxV{NHl=6s|9xAREnhN3ttewW0z=ywkE z`=WaO2oq>R>lf5jBtyWF^8cnP-c|A7!d4&}=5P7WD2M;+_|j*CN3O;Gx8kZOK-L!C z!hC5cTDdO(DfT4Ua5 zJ%KwliCH!^JyS1 zT9XGUJZ|BUTkzsyrW(jdlQS8K+V)`mAD84BxGc7NzA?lxL$*nL@Ppb==O6vt6qiQ$ z^P*31TFld)y-Liu5W1;z$U7$2c2kV{cR*ZJMs$Q}agks)C07OV`~H7yd>Lk-k^w5* zOhA#ax$9z?PV2dm42S$;79e)~0VbO8~`bE`6S8(%Xd(%>`W`>&)d z76#~(^?P)6D@q;cXPkfO3@=6Zp9Kji2VZ%dxLt>*=frj&X;Awgal@(Gi=7J1JM9JN zIM8rI15S{wgE+TyKFO_#+|rWAidInR>VvGDb6^SwFvBJRT~jS`u{)B99YPS{mVY~YgG~5K6U=N=D>j1$^^gh~ zD09;SphxqYvG0Mv9O*C>HK*LHK8k;A95EKnO%%qV)UHorQWg_R37|}h8lEYWwgy_F z#XZvCzwBO#l;igwUS|Y5c?d5bpE)H$P>b1F)j^=d2eD%URpi7JGz*w z+sUgP|JGIieRl_|nEiyhJPg96t9H_{joqVt8bI|zD1{vCwzJnirdZ*_os7>)o+(<} ztILXTQyM%f3r-Z6$&9^=cEeg;-3It7m2wdvfG=2$4#v!?c&fKD$^cv4{T5-XsM5`7 z=6CsUP8D`a!xZL4g0wTBFb9dv3&gx17(4f6M5cQ>I-LTDl!w6CnvKplzrPZl<;-`h z3x5{^;eOqohPsJPgKf3}zyk10j5UD(k*}KFd^dz>8frn*Fip)PYr&m1Vx+6hA zF2$|9>0|hlPRW3Zy5UQNvsTlJUK+DS(EcomX@3{<9irB3x%DnSuea(X@O zi28#2%_o6LG>159NFG0g?|N(b=Ak{`=e2=)LZ3xl96n&OCq`OHR@w;S2$68Y2lS(( z5S5>hH(L}3x!Iy`O>IS20g;6WYKb2}6RNsRm#i4F5_KPOzYUd`<`+hDrE%EL%180y2t2!Se@{v}at%E3*{KfL$ zXFdxB6b!VTYDv{>2909-B%CnMO< zLo40YY+CD8Kvr5+C|f2AV(lwNQ}$&+$B>7s%ohN>P{6?MrZ}; z17gDt!)<@XJc;%`$UhWaSP0kx6S^eR#WQhmE=jZ~g4%A>dqGy2w@M(!gG;Dy-YJ4# z{*xYu|FKf}Uz#BF{!APEyz<}5w+;v=wxz--WG^bGAw5RDBto)YPs5Ig$1O*y&vRSG z@K(D$3$}KRzG&8M<*ghC%B;(@GJESnY48B#@@=Qj6j0=)5y((cwUt)KvlRxz+1584 zOXSIKK;JsEtYy-xt$fEybeIDO|HyK0L%`ts_PCq&ql%XB=gD>%3FpvEXejw^mhH4L zBCyejx|@;aw&~MsVCcJIyP9FaCVVj+0P03dl z^Iq`N65>iQrGTNPmw--UUbnV*XH$!Lq->V^Dp?+A%`YJ}8x2L~h%FTJX@>o|5OqiH z)mpFxY7x*90htP<5J-GLG7c@ML#z><idM zU8@>~>ivU+WKq7%?f@-k4Y`9S4#RNIaJZ!L(w^ZXWc{RL`4?h<#UZL#yyj>+<>OqC zc&nSzck*_{J5UBUN}iSI9bvoGOQIFaMN^H)39Enk(;TFwWqmO zOpPxddR*I$B$`^h%#G~gkET??4V8yu4l_{cacR;YZ9NOavPc#CEcn6gL2Gj7y=}Y= zyFbMo!iWBVMZf~u3Q{AK6SGxp@=?Zn+;K$g$N*x;cQiBJ;~mQ28n3~NxxCKc-8*}2 zTgP9%le^$NA_p^1$EPeNT@GG7`K4b=PZSTXQ(E1s@CMxqct!9Qoj^YfztijMtL z9ywbqZYoxTaw{C|6Xa$)KgMy?Q*xa5ViVyGL^B-OgU-A=QdtpRjnx&>t(VR=bwb7( zZpW`2``JgrP>Ey$HEiGM6-~_GoO3W@``6Hy{IA)(|V>EEv@V~U>W}6-dEu8)a z$G4{o2|hrGybAVlMmnfV9*EopmX9~1#hIHrUg=I4nGD&7Bu6?4ZJoByH1>*^t!dhG z871SZfDER2pe(_Ay9coNU57>Ds>IizTb!SX*{LKvtUXLMu$;Op)qii`lPcK%h_eFl zk-tGp=SA#Y3l2@^>C3~DH^r7W2S*@0gJ@G_4b*g`g*O)*T0|*Xd;yl`W5}15W&YG3 zmIYbHK=XnX@X}@VA8`fuO|lYYnYBbMV)!V*0<2mH{r=~uDdvWq$D;llYOuYYac*gS zt1`9dCOA;3(eE(_iMGxC@(`{$bMeZJNg@kw=|uPQSC_n~j@8r-!)(KJ*blKV)K(+% zs73%ie&5Z6!1XmpfchOUd39&=BjLMMAiE&(23SXSb{3)>Bbf*nG3^DNyF)UCPZ<0U zPd}XIcDz~#VjgeaHm9#(`+lCJK2UEC05#Fb-SF_Y$bnlyS!?6CeHuPz0DM?BgWH?N zFgmYrT?`0xj+X#G!rvmNFxY(^u76pBo++e*RKPn$joq1U|n{GoAuQ8K#I zQ}Hq0!jQn2G=e;VZ#k5n$=vEKC)bKb=fCRS)AYt|EtEm=juN#U|UKI zRfmN=(0SEH;AX-dh%?*9lsEc>ARrFBzeZDh_kHPfjYBW)QNLSI6H(~Tx&~ZiA`z;8 z6Iz@rh<#-GOxP;CMO?3%g}Qk_oP(q8lgNZeL73mnb=i*1Yet$gvlfHlOPJ$06Sty# z!2s86maj0*B zeO|6F5_m3STz;SjrsP+KQidZl8#rMk%0=hZ&5|Jv-3^Tm7d|dczkS9!MdxV*1PE+s zL^aL+jKRyuWW|gApY?%H@YH#)POZG|vRH`p?3N=CgLv1@=droByL4`cz`IY68P^5D zDwj01OA@!FFK@M}ChP@NGX}_B85&*q#vAhu;Z-DKvh!detP<>kd|9;GoRvTl7@u%I zBb+z&5I&tdnTFRsyItZ4uxxr92eFM4-2eR^_Oxpb+b%v*80|7uX?h9O%O1#`hE7uJ z0>>OGAN4@s%{8JvtKoO3vgCox^^ zQ?@`5vL6EyndsXQYDJ*PPC|<8Ide*J$6nbG3_F}*8+R;E&bAh5H!7#Nl~s8`1s=FOWWI41% zns0?+WuVQ^6+UorANFW+s~Z?f@wWrE zRV4Z9i;$Id6VR$ZFj0UaEzo1ew<2J=^v?hj@Gt(kiEImP3M*Wmbmi(g3c+tpz;_$L z6Um>p9Oy*ks-8vM@;^ll!>BMIYlI%1^<#F@iH}%@gPTtpyb?8%vy(f#22`D=_^u3P zKde3W6s;gEcw1rUkiB3vRDE8nheKo3R-{=CcvbL~%F&-?x98PKO<5k&PD9QvO@wjI zO#>LwK~hmXX?jt;=}o~6>eR@;x{T1eBvw<8X~4Y-n}!v7^?_lhf%$(cuyWVPc%f^K zUPUT0A|F&_r&hFFJNgKPjq?GR7uq>Tc2B%3 z2NNt&z?U!(I7K_5E!N;Z=*jV+3-^;*>s}kZW6@uVv>awW>GS5YwXgXJV$(2{-S>o1 zQO8#>J0va6Yf34?9}x3-x*sGmuEUKmkj@qu5PGu^Lnh;&LAZyh3){H5u@&YO6bT#KcoO3E$<0Li60+XLxW2Q_h*BU@&db4d7Js~J(e#YK3OAXZ*v}$``-hi&8YpnO;D~wk>Jp{ z?nb!D{WG&#vmVSSY`Lw-^K>vv8Qb|NDhE?qUr`h6eyOk!IVs4^jCfIXAM;&cz9Eov z7P=Ayh;)i5hV%W$dD`@)DaGp+D#and7cSsf2cMm3@D-v>VerM)TJ$6) zu%X~&Ajn|kD}QAS)ASy{gUihmtR%W41P5@)evx>$>5uN`RRZmy3d-@ z(T5djV_=?cFtaxsFy;|!4h`FvxyRsZ_ENM<7#7GoKqdskbf38?<0VkfW2-~(m64$E z9rvjhYl5b-pjdb(47WHB0ASJ%aMElSWakd1klTz zC*@N5j+_L!c8Z9$xqJnbauG-^vhAONsqxDTbCY80xd{mJv}pvqSmeTmk(T5}E1$if zEX^92^D;o(=a2i=O?^eP@AVqwaUH<;wO)M|zxG~vFzDzb?E+w9c=6ofcPbKD_+2R1 zYj)GEg@nl@=8ukC@coEQX2b*SC1z?y-M`7OU{wfV!lEu6FB2pv0JE?{q-@p~vv(B# z+!m)URm-W17?~d^!Mxu`lc<>n>A`T2`4&5lj@Q&0Nm zW3{%x_vY8vHvuNEm6soyE5EOG9@^sq!V3{N-Z1abv(8#Pq3zx9D$=sX-E;i}d1BfU z%08iV&!GKRv}RO(vC@SMyn5^ zhwQ!3!PyLUJlNZ@{qtUzC59bi+WevhZ7?dbU$$Q@JcWlR-X81kJvjz?YrtZ>jst{+OOWfgkcCY!4(+C?PJ^MV$7$F@RXl}?2v^@52hDEjZ6c3%RNx; zm0oZLY&HZy+t&agxBNuGBe-Mvq-zGaB`_tvrW?$0jv>gWq@eOAL7dS8(E3N!;YfE%wWF0#^eqc;MZvi6DD`J=ueyD+)-(L8Qu z;P}`s;K99<-%y`#!76WHV4*v^sI08tYNaC_DUVA*ghCAbU`~=T(OF^5?Vh}mUqQL6 zoq$&b&CFasS7$5FJM>X^qZDOTW|k%4_nrz9=mpYgw<7Dkrbd4{uA^TS8}DE@0IN)R zbYYTV-m5C5V*gw)^n67U7$UMnhKSU$grlWb*WyftJ!{Cq+$q5Q{l=%LAAj$ytD zF1vf=4*}z`ynzT{owXC@>0*fuPj@M52Gf%;fcjX-lWo&kKI@ z@tpb@6)?}70vF&wD^r}s4;@Q`prwG!1R|0tU*`2gSVhXUVxS1cR{Qm!C$`wCQ!1QUhqb{2xx6HtXk%^#<{CW%sZ9J z)pbH{Vc9*VIl9^6v#R~a@Tu4V8>XBoS-(E`fr>G1=O*P;FwE^OaVK~Q_f)-+tV5e` zvJZ-yc>0%0O<)i!Xix3%0Wy}sqY8>KIbH{pp?yD34|V6B`@Du%iC}YR8IP2U$ow#x zFy1+l?e7?eCxgZZPC=wp-&_IgA_^d?&CgFxB2r}YKcv@+G5%Ap)rx)0Q!@r2EU}XU z22eX+08b;rAGs!gGiZc-%EWh_5M({%OqI;c7L7JFANLu%oTZ@=mHJTiK3vcN1)!EHvkaxWzMz5|}OQrqP)h?gspt!`Oj(KW6Os z*tm|wm>0)2t5xCbFQQrd{vBIEYW}HA>Dj$sha_YRLp1&ZSm_-evG+{$% zTk&lFy)DiOH2Qp$L6<#bL0OjQ{>ukVsWlqEy!`sLIf=nXI(8VRzi@@G$vX)%Yi?vZ zHha~5UG>stZukM|tTN2T)8N1;fbRJk42u{5|0&+C-~T2mxs<~2bzb7xr$N3Dgm_rT zgODnXe~k{2i5-1((42QA$_meUK^&y-%tt2NM!K7IpBBl;6qkpcM@u@kz5zCk*p?tU z#YfIPiT57XKUB)rX}23rL`K|VVK-uGzIS2bsfx$)GooSg$h&$EbbX^;_dYVOZ4!9- zJ-~^{RJtJ12zF~eL^!Ml%q&3HrY*s6SOS=4i+ zN8hc(bJM$FLn@|%yY0X7Ab;3@REb$?{!@-5BMr;UV2QyPHmnli`7 zt4+G0YDv5P0Wlg5;*I(u!N{EOgUsuKz$^J_wT42Z=^6y*xI8>4rrK!VFGbWSR>~nz zd*~|~opT7e$BGr@Kx|544jyP~u5EuNe+64|?Q*$j8uwj&pHrwG%#j4*{u#)N{BuwnaI&X)Pk4y7qf*03&n_ zxhCatSnP}L)S5&IL$`Aoihkq8T~Xrtp!R$VXnlHvRzq`}{QCKE2odHYQ*%tC-7fMH za6M!9dBHb#0wbgbtWq=5P~rT{*KjgELHlbhlYRtr?CQEB^+E53zVlw;#GpRNWr1&g zTnc*zHalbkP;VkunR}#m9mk3I8;*MVF9f;-%KNY@zZTYka^(KXn z4_)t4Q_~aMd5jz%35;rh;~_5|SU4Qc`qYieXquApG+SA7V~>+B_M?wOhC%1eHNv5W zT5yN4*@(tHCgXSj;zR+yFwf?PlMxvd>2%Kj-TWK0L~kM)mwWcgKT+jiAOv3Ox9ISJ MWBW6IKKc890q + - + Shaka Packager SDK: shaka::media::mp2t::TsSectionPes Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp2t::TsSection - -
+ + @@ -87,9 +90,9 @@ Public Member Functions - - + + @@ -98,11 +101,11 @@ void  @@ -118,9 +121,7 @@ Additional Inherited Members diff --git a/docs/d1/d31/classshaka_1_1xml_1_1XmlNode.html b/docs/d1/d31/classshaka_1_1xml_1_1XmlNode.html index 0f13ba5e35..7c9b9be92d 100644 --- a/docs/d1/d31/classshaka_1_1xml_1_1XmlNode.html +++ b/docs/d1/d31/classshaka_1_1xml_1_1XmlNode.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::xml::XmlNode Class Reference @@ -29,18 +29,21 @@

Public Member Functions

bool Parse (bool payload_unit_start_indicator, const uint8_t *buf, int size) override
 
-void Flush () override
 
+bool Flush () override
 
void Reset () override
 
Reset () override Additional Inherited Members
- Public Types inherited from shaka::media::mp2t::TsSection
enum  SpecialPid {
-  kPidPat = 0x0, -kPidCat = 0x1, -kPidTsdt = 0x2, -kPidNullPacket = 0x1fff, -
+  kPidPat = 0x0 +, kPidCat = 0x1 +, kPidTsdt = 0x2 +, kPidNullPacket = 0x1fff +,
  kPidMax = 0x1fff
}
- + +/* @license-end */
shaka::xml::XmlNode Class Reference
@@ -78,47 +82,61 @@ Inheritance diagram for shaka::xml::XmlNode:
shaka::xml::RepresentationBaseXmlNode -shaka::xml::AdaptationSetXmlNode -shaka::xml::RepresentationXmlNode - - +shaka::xml::AdaptationSetXmlNode +shaka::xml::RepresentationXmlNode + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + +

Public Member Functions

 XmlNode (const char *name)
 
bool AddChild (scoped_xml_ptr< xmlNode > child)
 
-bool AddElements (const std::vector< Element > &elements)
 Adds Elements to this node using the Element struct.
 
void SetStringAttribute (const char *attribute_name, const std::string &attribute)
 
void SetIntegerAttribute (const char *attribute_name, uint64_t number)
 
void SetFloatingPointAttribute (const char *attribute_name, double number)
 
void SetId (uint32_t id)
 
 XmlNode (const std::string &name)
 
XmlNode (XmlNode &&)
 
+XmlNodeoperator= (XmlNode &&)
 
bool AddChild (XmlNode child) WARN_UNUSED_RESULT
 
+bool AddElements (const std::vector< Element > &elements) WARN_UNUSED_RESULT
 Adds Elements to this node using the Element struct.
 
bool SetStringAttribute (const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
 
bool SetIntegerAttribute (const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULT
 
bool SetFloatingPointAttribute (const std::string &attribute_name, double number) WARN_UNUSED_RESULT
 
bool SetId (uint32_t id) WARN_UNUSED_RESULT
 
+void AddContent (const std::string &content)
 Similar to SetContent, but appends to the end of existing content.
 
void SetContent (const std::string &content)
 
std::set< std::string > ExtractReferencedNamespaces ()
 
scoped_xml_ptr< xmlNode > PassScopedPtr ()
 
xmlNodePtr Release ()
 
xmlNodePtr GetRawPtr ()
 
std::set< std::string > ExtractReferencedNamespaces () const
 
std::string ToString (const std::string &comment) const
 
bool GetAttribute (const std::string &name, std::string *value) const
 
+ + +

+Friends

+bool shaka::XmlEqual (const std::string &xml1, const xml::XmlNode &xml2)
 

Detailed Description

These classes are wrapper classes for XML elements for generating MPD. None of the pointer parameters should be NULL. None of the methods are meant to be overridden.

-

Definition at line 33 of file xml_node.h.

+

Definition at line 44 of file xml_node.h.

Constructor & Destructor Documentation

- -

◆ XmlNode()

+ +

◆ XmlNode()

Member Function Documentation

- -

◆ AddChild()

+ +

◆ AddChild()

- -

◆ ExtractReferencedNamespaces()

+ +

◆ ExtractReferencedNamespaces()

- -

◆ GetRawPtr()

+ +

◆ GetAttribute()

- + - - + + -
xmlNodePtr shaka::xml::XmlNode::GetRawPtr bool shaka::xml::XmlNode::GetAttribute ()const std::string & name,
-
-
Returns
Raw pointer to the element.
- -

Definition at line 216 of file xml_node.cc.

- -
-
- -

◆ PassScopedPtr()

- -
-
- - - - + + + -
scoped_xml_ptr< xmlNode > shaka::xml::XmlNode::PassScopedPtr () std::string * value 
-
-

Transfer the ownership of the xmlNodePtr. After calling this method, the behavior of any methods, except the destructor, is undefined.

Returns
The resource of this object.
- -

Definition at line 204 of file xml_node.cc.

- -
-
- -

◆ Release()

- -
-
- - - - + +
xmlNodePtr shaka::xml::XmlNode::Release () ) const
-

Release the xmlNodePtr of this object. After calling this method, the behavior of any methods, except the destructor, is undefined.

+

Gets the attribute with the given name.

Parameters
+ + + +
nameThe name of the attribute to get.
value[OUT] where to put the resulting value.
+
+
+
Returns
True if the attribute exists, false if not.
-

Definition at line 210 of file xml_node.cc.

+

Definition at line 248 of file xml_node.cc.

@@ -281,20 +277,20 @@ bool Definition at line 193 of file xml_node.cc.

+

Definition at line 213 of file xml_node.cc.

- -

◆ SetFloatingPointAttribute()

+ +

◆ SetFloatingPointAttribute()

- + - + @@ -318,18 +314,18 @@ bool 
void shaka::xml::XmlNode::SetFloatingPointAttribute bool shaka::xml::XmlNode::SetFloatingPointAttribute (const char * const std::string &  attribute_name,
Definition at line 181 of file xml_node.cc.

+

Definition at line 197 of file xml_node.cc.

- -

◆ SetId()

+ +

◆ SetId()

- + @@ -344,20 +340,20 @@ bool 
void shaka::xml::XmlNode::SetId bool shaka::xml::XmlNode::SetId ( uint32_t  id)Definition at line 189 of file xml_node.cc.

+

Definition at line 204 of file xml_node.cc.

- -

◆ SetIntegerAttribute()

+ +

◆ SetIntegerAttribute()

- + - + @@ -381,20 +377,20 @@ bool 
void shaka::xml::XmlNode::SetIntegerAttribute bool shaka::xml::XmlNode::SetIntegerAttribute (const char * const std::string &  attribute_name,
Definition at line 173 of file xml_node.cc.

+

Definition at line 190 of file xml_node.cc.

- -

◆ SetStringAttribute()

+ +

◆ SetStringAttribute()

- + - + @@ -418,7 +414,34 @@ bool 
void shaka::xml::XmlNode::SetStringAttribute bool shaka::xml::XmlNode::SetStringAttribute (const char * const std::string &  attribute_name,
Definition at line 166 of file xml_node.cc.

+

Definition at line 183 of file xml_node.cc.

+ + + + +

◆ ToString()

+ +
+
+ + + + + + + + +
std::string shaka::xml::XmlNode::ToString (const std::string & comment) const
+
+
Parameters
+ + +
commentThe body of a comment to add to the top of the XML.
+
+
+
Returns
A string containing the XML.
+ +

Definition at line 224 of file xml_node.cc.

@@ -429,9 +452,7 @@ bool 
diff --git a/docs/d1/d34/structshaka_1_1media_1_1SubsampleEntry.html b/docs/d1/d34/structshaka_1_1media_1_1SubsampleEntry.html index 6b2c1e623d..26f501e314 100644 --- a/docs/d1/d34/structshaka_1_1media_1_1SubsampleEntry.html +++ b/docs/d1/d34/structshaka_1_1media_1_1SubsampleEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SubsampleEntry Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
cipher_bytes< diff --git a/docs/d1/d35/classshaka_1_1hls_1_1Tag-members.html b/docs/d1/d35/classshaka_1_1hls_1_1Tag-members.html index 5911ed1408..c128046ca5 100644 --- a/docs/d1/d35/classshaka_1_1hls_1_1Tag-members.html +++ b/docs/d1/d35/classshaka_1_1hls_1_1Tag-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d37/es__parser__h264_8h_source.html b/docs/d1/d37/es__parser__h264_8h_source.html index ba8ca86d9b..954fb3295e 100644 --- a/docs/d1/d37/es__parser__h264_8h_source.html +++ b/docs/d1/d37/es__parser__h264_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser_h264.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
es_parser_h264.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H264_H_
6 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H264_H_
7 
8 #include <stdint.h>
9 #include <memory>
10 #include "packager/base/callback.h"
11 #include "packager/media/formats/mp2t/es_parser_h26x.h"
12 
13 namespace shaka {
14 namespace media {
15 
16 class H264Parser;
17 
18 namespace mp2t {
19 
20 // Remark:
21 // In this h264 parser, frame splitting is based on AUD nals.
22 // Mpeg2 TS spec: "2.14 Carriage of Rec. ITU-T H.264 | ISO/IEC 14496-10 video"
23 // "Each AVC access unit shall contain an access unit delimiter NAL Unit;"
24 //
25 class EsParserH264 : public EsParserH26x {
26  public:
27  EsParserH264(uint32_t pid,
28  const NewStreamInfoCB& new_stream_info_cb,
29  const EmitSampleCB& emit_sample_cb);
30  ~EsParserH264() override;
31 
32  // EsParserH26x implementation override.
33  void Reset() override;
34 
35  private:
36  // Processes a NAL unit found in ParseInternal.
37  bool ProcessNalu(const Nalu& nalu, VideoSliceInfo* video_slice_info) override;
38 
39  // Update the video decoder config based on an H264 SPS.
40  // Return true if successful.
41  bool UpdateVideoDecoderConfig(int sps_id) override;
42 
43  // Callback to pass the stream configuration.
44  NewStreamInfoCB new_stream_info_cb_;
45 
46  std::shared_ptr<StreamInfo> last_video_decoder_config_;
47  bool decoder_config_check_pending_;
48 
49  std::unique_ptr<H264Parser> h264_parser_;
50 };
51 
52 } // namespace mp2t
53 } // namespace media
54 } // namespace shaka
55 
56 #endif
- - -
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H264_H_
+
6 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H264_H_
+
7 
+
8 #include <stdint.h>
+
9 #include <memory>
+
10 #include "packager/base/callback.h"
+
11 #include "packager/media/formats/mp2t/es_parser_h26x.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
16 class H264Parser;
+
17 
+
18 namespace mp2t {
+
19 
+
20 // Remark:
+
21 // In this h264 parser, frame splitting is based on AUD nals.
+
22 // Mpeg2 TS spec: "2.14 Carriage of Rec. ITU-T H.264 | ISO/IEC 14496-10 video"
+
23 // "Each AVC access unit shall contain an access unit delimiter NAL Unit;"
+
24 //
+
25 class EsParserH264 : public EsParserH26x {
+
26  public:
+
27  EsParserH264(uint32_t pid,
+
28  const NewStreamInfoCB& new_stream_info_cb,
+
29  const EmitSampleCB& emit_sample_cb);
+
30  ~EsParserH264() override;
+
31 
+
32  // EsParserH26x implementation override.
+
33  void Reset() override;
+
34 
+
35  private:
+
36  // Processes a NAL unit found in ParseInternal.
+
37  bool ProcessNalu(const Nalu& nalu, VideoSliceInfo* video_slice_info) override;
+
38 
+
39  // Update the video decoder config based on an H264 SPS.
+
40  // Return true if successful.
+
41  bool UpdateVideoDecoderConfig(int sps_id) override;
+
42 
+
43  // Callback to pass the stream configuration.
+
44  NewStreamInfoCB new_stream_info_cb_;
+
45 
+
46  std::shared_ptr<StreamInfo> last_video_decoder_config_;
+
47  bool decoder_config_check_pending_;
+
48 
+
49  std::unique_ptr<H264Parser> h264_parser_;
+
50 };
+
51 
+
52 } // namespace mp2t
+
53 } // namespace media
+
54 } // namespace shaka
+
55 
+
56 #endif
+ + + +
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d1/d3b/mpd__generator__flags_8h_source.html b/docs/d1/d3b/mpd__generator__flags_8h_source.html index 76a2f64aa9..a1c7e6f352 100644 --- a/docs/d1/d3b/mpd__generator__flags_8h_source.html +++ b/docs/d1/d3b/mpd__generator__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/mpd_generator_flags.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mpd_generator_flags.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef APP_MPD_GENERATOR_FLAGS_H_
8 #define APP_MPD_GENERATOR_FLAGS_H_
9 
10 #include <gflags/gflags.h>
11 
12 DEFINE_string(input, "", "Comma separated list of MediaInfo input files.");
13 DEFINE_string(output, "", "MPD output file name.");
14 DEFINE_string(base_urls,
15  "",
16  "Comma separated BaseURLs for the MPD. The values will be added "
17  "as <BaseURL> element(s) immediately under the <MPD> element.");
18 #endif // APP_MPD_GENERATOR_FLAGS_H_
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef APP_MPD_GENERATOR_FLAGS_H_
+
8 #define APP_MPD_GENERATOR_FLAGS_H_
+
9 
+
10 #include <gflags/gflags.h>
+
11 
+
12 DEFINE_string(input, "", "Comma separated list of MediaInfo input files.");
+
13 DEFINE_string(output, "", "MPD output file name.");
+
14 DEFINE_string(base_urls,
+
15  "",
+
16  "Comma separated BaseURLs for the MPD. The values will be added "
+
17  "as <BaseURL> element(s) immediately under the <MPD> element.");
+
18 #endif // APP_MPD_GENERATOR_FLAGS_H_
+
diff --git a/docs/d1/d3e/structshaka_1_1media_1_1mp4_1_1MovieExtends.html b/docs/d1/d3e/structshaka_1_1media_1_1mp4_1_1MovieExtends.html index 725b08bf71..821883e3a6 100644 --- a/docs/d1/d3e/structshaka_1_1media_1_1mp4_1_1MovieExtends.html +++ b/docs/d1/d3e/structshaka_1_1media_1_1mp4_1_1MovieExtends.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MovieExtends Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -115,7 +118,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 660 of file box_definitions.h.

+

Definition at line 678 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -143,7 +146,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2281 of file box_definitions.cc.

+

Definition at line 2362 of file box_definitions.cc.

@@ -154,9 +157,7 @@ Additional Inherited Members diff --git a/docs/d1/d40/classshaka_1_1MpdWriter-members.html b/docs/d1/d40/classshaka_1_1MpdWriter-members.html index 509b2ebfc0..7d97e4389d 100644 --- a/docs/d1/d40/classshaka_1_1MpdWriter-members.html +++ b/docs/d1/d40/classshaka_1_1MpdWriter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d41/structshaka_1_1media_1_1Scte35Event.html b/docs/d1/d41/structshaka_1_1media_1_1Scte35Event.html index de40217595..e2b871df55 100644 --- a/docs/d1/d41/structshaka_1_1media_1_1Scte35Event.html +++ b/docs/d1/d41/structshaka_1_1media_1_1Scte35Event.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::Scte35Event Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
cue_data diff --git a/docs/d1/d45/classshaka_1_1hls_1_1MediaPlaylistFactory-members.html b/docs/d1/d45/classshaka_1_1hls_1_1MediaPlaylistFactory-members.html index 8c285f4660..4dd26b588a 100644 --- a/docs/d1/d45/classshaka_1_1hls_1_1MediaPlaylistFactory-members.html +++ b/docs/d1/d45/classshaka_1_1hls_1_1MediaPlaylistFactory-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d45/decoding__time__iterator_8cc_source.html b/docs/d1/d45/decoding__time__iterator_8cc_source.html index b8b6000e11..d7cdd055c2 100644 --- a/docs/d1/d45/decoding__time__iterator_8cc_source.html +++ b/docs/d1/d45/decoding__time__iterator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/decoding_time_iterator.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
decoding_time_iterator.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp4/decoding_time_iterator.h"
8 
9 #include <algorithm>
10 
11 #include "packager/base/logging.h"
12 
13 namespace shaka {
14 namespace media {
15 namespace mp4 {
16 
18  const DecodingTimeToSample& decoding_time_to_sample)
19  : sample_index_(0),
20  decoding_time_table_(decoding_time_to_sample.decoding_time),
21  iterator_(decoding_time_table_.begin()) {}
22 DecodingTimeIterator::~DecodingTimeIterator() {}
23 
25  ++sample_index_;
26  if (sample_index_ >= iterator_->sample_count) {
27  ++iterator_;
28  if (iterator_ == decoding_time_table_.end())
29  return false;
30  sample_index_ = 0;
31  }
32  return true;
33 }
34 
36  return iterator_ != decoding_time_table_.end() &&
37  sample_index_ < iterator_->sample_count;
38 }
39 
40 uint64_t DecodingTimeIterator::Duration(uint32_t start_sample,
41  uint32_t end_sample) const {
42  DCHECK_LE(start_sample, end_sample);
43  uint32_t current_sample = 0;
44  uint32_t prev_sample = 0;
45  uint64_t duration = 0;
46  std::vector<DecodingTime>::const_iterator it = decoding_time_table_.begin();
47  for (; it != decoding_time_table_.end(); ++it) {
48  current_sample += it->sample_count;
49  if (current_sample >= start_sample) {
50  duration += (std::min(end_sample, current_sample) -
51  std::max(start_sample, prev_sample + 1) + 1) *
52  it->sample_delta;
53  if (current_sample >= end_sample)
54  break;
55  }
56  prev_sample = current_sample;
57  }
58  return duration;
59 }
60 
62  uint32_t num_samples = 0;
63  std::vector<DecodingTime>::const_iterator it = decoding_time_table_.begin();
64  for (; it != decoding_time_table_.end(); ++it) {
65  num_samples += it->sample_count;
66  }
67  return num_samples;
68 }
69 
70 } // namespace mp4
71 } // namespace media
72 } // namespace shaka
-
All the methods that are virtual are virtual for mocking.
-
uint64_t Duration(uint32_t start_sample, uint32_t end_sample) const
-
DecodingTimeIterator(const DecodingTimeToSample &decoding_time_to_sample)
Create DecodingTimeIterator from decoding time to sample box.
- - - +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp4/decoding_time_iterator.h"
+
8 
+
9 #include <algorithm>
+
10 
+
11 #include "packager/base/logging.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 namespace mp4 {
+
16 
+ +
18  const DecodingTimeToSample& decoding_time_to_sample)
+
19  : sample_index_(0),
+
20  decoding_time_table_(decoding_time_to_sample.decoding_time),
+
21  iterator_(decoding_time_table_.begin()) {}
+
22 DecodingTimeIterator::~DecodingTimeIterator() {}
+
23 
+ +
25  ++sample_index_;
+
26  if (sample_index_ >= iterator_->sample_count) {
+
27  ++iterator_;
+
28  if (iterator_ == decoding_time_table_.end())
+
29  return false;
+
30  sample_index_ = 0;
+
31  }
+
32  return true;
+
33 }
+
34 
+ +
36  return iterator_ != decoding_time_table_.end() &&
+
37  sample_index_ < iterator_->sample_count;
+
38 }
+
39 
+
40 uint64_t DecodingTimeIterator::Duration(uint32_t start_sample,
+
41  uint32_t end_sample) const {
+
42  DCHECK_LE(start_sample, end_sample);
+
43  uint32_t current_sample = 0;
+
44  uint32_t prev_sample = 0;
+
45  uint64_t duration = 0;
+
46  std::vector<DecodingTime>::const_iterator it = decoding_time_table_.begin();
+
47  for (; it != decoding_time_table_.end(); ++it) {
+
48  current_sample += it->sample_count;
+
49  if (current_sample >= start_sample) {
+
50  duration += (std::min(end_sample, current_sample) -
+
51  std::max(start_sample, prev_sample + 1) + 1) *
+
52  it->sample_delta;
+
53  if (current_sample >= end_sample)
+
54  break;
+
55  }
+
56  prev_sample = current_sample;
+
57  }
+
58  return duration;
+
59 }
+
60 
+ +
62  uint32_t num_samples = 0;
+
63  std::vector<DecodingTime>::const_iterator it = decoding_time_table_.begin();
+
64  for (; it != decoding_time_table_.end(); ++it) {
+
65  num_samples += it->sample_count;
+
66  }
+
67  return num_samples;
+
68 }
+
69 
+
70 } // namespace mp4
+
71 } // namespace media
+
72 } // namespace shaka
+
uint64_t Duration(uint32_t start_sample, uint32_t end_sample) const
+ +
DecodingTimeIterator(const DecodingTimeToSample &decoding_time_to_sample)
Create DecodingTimeIterator from decoding time to sample box.
+ + +
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d1/d46/classshaka_1_1media_1_1CachingMediaHandler-members.html b/docs/d1/d46/classshaka_1_1media_1_1CachingMediaHandler-members.html index f08eead022..0af60dd210 100644 --- a/docs/d1/d46/classshaka_1_1media_1_1CachingMediaHandler-members.html +++ b/docs/d1/d46/classshaka_1_1media_1_1CachingMediaHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline Cache() const (defined in shaka::media::CachingMediaHandler)shaka::media::CachingMediaHandlerinline - Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic + Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic Clear() (defined in shaka::media::CachingMediaHandler)shaka::media::CachingMediaHandlerinline Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected @@ -94,9 +97,7 @@ $(function() {
diff --git a/docs/d1/d48/text__track__config_8h_source.html b/docs/d1/d48/text__track__config_8h_source.html index b721649b9a..2e971acf6e 100644 --- a/docs/d1/d48/text__track__config_8h_source.html +++ b/docs/d1/d48/text__track__config_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/text_track_config.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
text_track_config.h
-
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_BASE_TEXT_TRACK_CONFIG_H_
6 #define PACKAGER_MEDIA_BASE_TEXT_TRACK_CONFIG_H_
7 
8 #include <string>
9 
10 namespace shaka {
11 namespace media {
12 
13 // Specifies the varieties of text tracks.
14 enum TextKind {
15  kTextSubtitles,
16  kTextCaptions,
17  kTextDescriptions,
18  kTextMetadata,
19  kTextNone
20 };
21 
23  public:
25  TextTrackConfig(TextKind kind,
26  const std::string& label,
27  const std::string& language,
28  const std::string& id);
29 
30  // Returns true if all fields in |config| match this config.
31  bool Matches(const TextTrackConfig& config) const;
32 
33  TextKind kind() const { return kind_; }
34  const std::string& label() const { return label_; }
35  const std::string& language() const { return language_; }
36  const std::string& id() const { return id_; }
37 
38  private:
39  TextKind kind_;
40  std::string label_;
41  std::string language_;
42  std::string id_;
43 };
44 
45 } // namespace media
46 } // namespace shaka
47 
48 #endif // PACKAGER_MEDIA_BASE_TEXT_TRACK_H_
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2013 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_BASE_TEXT_TRACK_CONFIG_H_
+
6 #define PACKAGER_MEDIA_BASE_TEXT_TRACK_CONFIG_H_
+
7 
+
8 #include <string>
+
9 
+
10 namespace shaka {
+
11 namespace media {
+
12 
+
13 // Specifies the varieties of text tracks.
+
14 enum TextKind {
+
15  kTextSubtitles,
+
16  kTextCaptions,
+
17  kTextDescriptions,
+
18  kTextMetadata,
+
19  kTextNone
+
20 };
+
21 
+ +
23  public:
+ +
25  TextTrackConfig(TextKind kind,
+
26  const std::string& label,
+
27  const std::string& language,
+
28  const std::string& id);
+
29 
+
30  // Returns true if all fields in |config| match this config.
+
31  bool Matches(const TextTrackConfig& config) const;
+
32 
+
33  TextKind kind() const { return kind_; }
+
34  const std::string& label() const { return label_; }
+
35  const std::string& language() const { return language_; }
+
36  const std::string& id() const { return id_; }
+
37 
+
38  private:
+
39  TextKind kind_;
+
40  std::string label_;
+
41  std::string language_;
+
42  std::string id_;
+
43 };
+
44 
+
45 } // namespace media
+
46 } // namespace shaka
+
47 
+
48 #endif // PACKAGER_MEDIA_BASE_TEXT_TRACK_H_
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/d4e/classshaka_1_1media_1_1TextMuxer.html b/docs/d1/d4e/classshaka_1_1media_1_1TextMuxer.html new file mode 100644 index 0000000000..51c1cdcb02 --- /dev/null +++ b/docs/d1/d4e/classshaka_1_1media_1_1TextMuxer.html @@ -0,0 +1,219 @@ + + + + + + + +Shaka Packager SDK: shaka::media::TextMuxer Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::TextMuxer Class Referenceabstract
+
+
+ +

#include <text_muxer.h>

+
+Inheritance diagram for shaka::media::TextMuxer:
+
+
+ + +shaka::media::Muxer +shaka::media::MediaHandler +shaka::media::ttml::TtmlMuxer +shaka::media::webvtt::WebVttMuxer + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

TextMuxer (const MuxerOptions &options)
 
- Public Member Functions inherited from shaka::media::Muxer
Muxer (const MuxerOptions &options)
 
void Cancel ()
 
void SetMuxerListener (std::unique_ptr< MuxerListener > muxer_listener)
 
void SetProgressListener (std::unique_ptr< ProgressListener > progress_listener)
 
+const std::vector< std::shared_ptr< const StreamInfo > > & streams () const
 
void set_clock (base::Clock *clock)
 
- Public Member Functions inherited from shaka::media::MediaHandler
+Status SetHandler (size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
 Connect downstream handler at the specified output stream index.
 
+Status AddHandler (std::shared_ptr< MediaHandler > handler)
 Connect downstream handler to the next available output stream index.
 
Status Initialize ()
 
+bool IsConnected ()
 Validate if the handler is connected to its upstream handler.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Static Public Member Functions inherited from shaka::media::MediaHandler
+static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
 
- Protected Member Functions inherited from shaka::media::Muxer
+const MuxerOptionsoptions () const
 
+MuxerListenermuxer_listener ()
 
+ProgressListenerprogress_listener ()
 
+base::Clock * clock ()
 
Status InitializeInternal () override
 
Status Process (std::unique_ptr< StreamData > stream_data) override
 
+Status OnFlushRequest (size_t input_stream_index) override
 Event handler for flush request at the specific input stream index.
 
- Protected Member Functions inherited from shaka::media::MediaHandler
+virtual bool ValidateOutputStreamIndex (size_t stream_index) const
 Validate if the stream at the specified index actually exists.
 
Status Dispatch (std::unique_ptr< StreamData > stream_data) const
 
+Status DispatchStreamInfo (size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
 Dispatch the stream info to downstream handlers.
 
+Status DispatchMediaSample (size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
 Dispatch the media sample to downstream handlers.
 
+Status DispatchTextSample (size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
 Dispatch the text sample to downstream handlers.
 
+Status DispatchSegmentInfo (size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) const
 Dispatch the segment info to downstream handlers.
 
+Status DispatchScte35Event (size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) const
 Dispatch the scte35 event to downstream handlers.
 
+Status DispatchCueEvent (size_t stream_index, std::shared_ptr< const CueEvent > cue_event) const
 Dispatch the cue event to downstream handlers.
 
+Status FlushDownstream (size_t output_stream_index)
 Flush the downstream connected at the specified output stream index.
 
+Status FlushAllDownstreams ()
 Flush all connected downstream handlers.
 
+bool initialized ()
 
+size_t num_input_streams () const
 
+size_t next_output_stream_index () const
 
+const std::map< size_t, std::pair< std::shared_ptr< MediaHandler >, size_t > > & output_handlers ()
 
+

Detailed Description

+

Defines a base class for text format (i.e. not MP4) muxers. This handles separating the single-segment and multi-segment modes. Derived classes are expected to buffer cues (or text) and write them out in WriteToFile.

+ +

Definition at line 20 of file text_muxer.h.

+

The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/d1/d4e/classshaka_1_1media_1_1TextMuxer.png b/docs/d1/d4e/classshaka_1_1media_1_1TextMuxer.png new file mode 100644 index 0000000000000000000000000000000000000000..53b368a46bab03ad00335aa3d4f8e9bb45928928 GIT binary patch literal 1968 zcmb_dc~Fx_6#oJOf(8{tU4F-b&Q=dN9CuV(r7SrBLg+gJH z*+sz2nF*1hQ4n_M_n~U0uY@2oU)bM|eh4@Ctu|gnojW6^pn2GECx6%6z;)v zC|9!F8c)6+x4zpmvf#Km@mV1KW(6&>Iz)8JOt-;Ck+P^vT9U}9ULy{uJx?+to+f5# z+qH&>EhU=Jz6#*jdufE{1_z{;0-|?J)3QugxTA!GL&zt0Y0hOCi)stx9Y5+z>=0Fu zT-M2_4?9}PUy5A!T?Y7iv_&1$HhTDpUKbdt9NwSK9BxMj?c$m_=In`29L7B*?DX}B z_5|iI>3FhJ&vPM|7<%-Dw@F- z-4}~>e*x|fBn5H&8t&jZXZ(!}{ki^EO?J-DRzwiX+j|g92>ZJx-h&BNND8l%B5OOG z&?a%5Pb$ektJQ`g2}|V_x2z%Yp-8^~NwH;qE=yt@Y*yWFA@B7RE=r=t)X-XI`6Ioz zX|6%$j)$Z3$26sQEph?G4K0C{^N>cv&;nt7+Rgak}2M4c1W8&D^n+SDM(ncEzm#|9VeYMk1%Vr-uov|mlTTlA| z#5xe+%D;>A&x-v$@B^`kj;eGqS`5|SGg%BxC1CkKdY4!M&Bnkms}TNV(Kmo0_P+o8 zbdv~^?S6FJmbnPDz~AP7Hb>^QxrgjE>MPFO7x(TviD#1IyC_#q=U()^+yNv?z7v8~ z%%`jKrXsK94ib&(6_uM4@AlRRKU~^-dkxf+tHs_`#G^bICXOC@b%Tv zFY}Tf_Ey9;^$32r*CvgsAn)O=zO{lmJy|e$BIOk?XJDIa`q!gVB1SwqCOVwqBU6PP zDPkbykB)-D$P`YxSuxIIHPcIt-Zlm3Sz*{Bx_AKa7}RTk=BOaN)`N^|@rSx|fQH#6 z0UNy!JcRPo9=I!ZFttvz?YB>g?cEiLwd9gPSuKlZoZNsLvg>-&P|VTpGvyYs9DdAZ z2C>trnN+Ar=A8b=Ug&!Wgls|RjJ43AoLOt3SI;mojI)EHaSJhIETcni+bEPS017_! z!M}G?AB&uQx4#(5&D6=CzMJ>|0{4h=lZR3_^N5p-Df^o~p2Ov5(okM7vgIeQh-TEqSI ziTcCgqWkW2eKxvcimk0lbIFUOY|~of4=jHyT|wcHhWo5q$FggYIAxE|v{(OfFpYW% zB%oy@=y)V;@@_x_KnC~TPxABUF}0VAZP1q6y$JJne^wg}$j}m><4rB2$yp zw9KMK1|i_dW53|KE4a~(1;?FyZXBemu1*?k(FvOIm4=c@5z@_NTdNvxSc>EwVhQiT z;}_XM%%$j&z}B-a_I&}`veAb7Oaa@jTHTfRl+0VhY@t@8jreeW%R-N}aFxs7^7va~ kuLE!R`~pbI8?b&sSUOau?=Y8EVc#nRZwU3TShxMyZx)$)EC2ui literal 0 HcmV?d00001 diff --git a/docs/d1/d4f/classshaka_1_1media_1_1OffsetByteQueue-members.html b/docs/d1/d4f/classshaka_1_1media_1_1OffsetByteQueue-members.html index baf543cafd..978c9437ff 100644 --- a/docs/d1/d4f/classshaka_1_1media_1_1OffsetByteQueue-members.html +++ b/docs/d1/d4f/classshaka_1_1media_1_1OffsetByteQueue-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d4f/structshaka_1_1DecryptionParams.html b/docs/d1/d4f/structshaka_1_1DecryptionParams.html index de70e5a7e4..99a0451a38 100644 --- a/docs/d1/d4f/structshaka_1_1DecryptionParams.html +++ b/docs/d1/d4f/structshaka_1_1DecryptionParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::DecryptionParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Detailed Description

Decryption parameters.

-

Definition at line 186 of file crypto_params.h.

+

Definition at line 228 of file crypto_params.h.

Member Data Documentation

◆ key_provider

@@ -104,7 +107,7 @@ Public Attributes

Specifies the key provider, which determines which key provider is used and which encryption params is valid. 'kNone' means not to decrypt the streams.

-

Definition at line 190 of file crypto_params.h.

+

Definition at line 232 of file crypto_params.h.

@@ -114,9 +117,7 @@ Public Attributes diff --git a/docs/d1/d5a/structshaka_1_1media_1_1EncryptionKey-members.html b/docs/d1/d5a/structshaka_1_1media_1_1EncryptionKey-members.html index 285280b3ad..d3ac035259 100644 --- a/docs/d1/d5a/structshaka_1_1media_1_1EncryptionKey-members.html +++ b/docs/d1/d5a/structshaka_1_1media_1_1EncryptionKey-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */ diff --git a/docs/d1/d6e/structshaka_1_1media_1_1mp4_1_1TrackFragmentHeader.html b/docs/d1/d6e/structshaka_1_1media_1_1mp4_1_1TrackFragmentHeader.html index 53e412fe17..95be2a1813 100644 --- a/docs/d1/d6e/structshaka_1_1media_1_1mp4_1_1TrackFragmentHeader.html +++ b/docs/d1/d6e/structshaka_1_1media_1_1mp4_1_1TrackFragmentHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TrackFragmentHeader Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -161,7 +164,7 @@ Additional Inherited Members

Public Types

enum  TrackFragmentFlagsMasks {
-  kBaseDataOffsetPresentMask = 0x000001, -kSampleDescriptionIndexPresentMask = 0x000002, -kDefaultSampleDurationPresentMask = 0x000008, -kDefaultSampleSizePresentMask = 0x000010, -
-  kDefaultSampleFlagsPresentMask = 0x000020, -kDurationIsEmptyMask = 0x010000, -kDefaultBaseIsMoofMask = 0x020000 +  kBaseDataOffsetPresentMask = 0x000001 +, kSampleDescriptionIndexPresentMask = 0x000002 +, kDefaultSampleDurationPresentMask = 0x000008 +, kDefaultSampleSizePresentMask = 0x000010 +,
+  kDefaultSampleFlagsPresentMask = 0x000020 +, kDurationIsEmptyMask = 0x010000 +, kDefaultBaseIsMoofMask = 0x020000
}
 
enum  SampleFlagsMasks {
-  kReservedMask = 0xFC000000, -kSampleDependsOnMask = 0x03000000, -kSampleIsDependedOnMask = 0x00C00000, -kSampleHasRedundancyMask = 0x00300000, -
-  kSamplePaddingValueMask = 0x000E0000, -kNonKeySampleMask = 0x00010000, -kSampleDegradationPriorityMask = 0x0000FFFF +  kReservedMask = 0xFC000000 +, kSampleDependsOnMask = 0x03000000 +, kSampleIsDependedOnMask = 0x00C00000 +, kSampleHasRedundancyMask = 0x00300000 +,
+  kSamplePaddingValueMask = 0x000E0000 +, kNonKeySampleMask = 0x00010000 +, kSampleDegradationPriorityMask = 0x0000FFFF
}
 

Detailed Description

-

Definition at line 689 of file box_definitions.h.

+

Definition at line 707 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -189,7 +192,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2388 of file box_definitions.cc.

+

Definition at line 2477 of file box_definitions.cc.

@@ -200,9 +203,7 @@ Additional Inherited Members diff --git a/docs/d1/d70/vp8__parser_8cc_source.html b/docs/d1/d70/vp8__parser_8cc_source.html index 2dd7de5f78..e52655011e 100644 --- a/docs/d1/d70/vp8__parser_8cc_source.html +++ b/docs/d1/d70/vp8__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/vp8_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
vp8_parser.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/vp8_parser.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/base/rcheck.h"
12 
13 namespace shaka {
14 namespace media {
15 namespace {
16 
17 const uint32_t MB_FEATURE_TREE_PROBS = 3;
18 const uint32_t MAX_MB_SEGMENTS = 4;
19 const uint32_t MAX_REF_LF_DELTAS = 4;
20 const uint32_t MAX_MODE_LF_DELTAS = 4;
21 const uint32_t MB_LVL_MAX = 2;
22 const uint32_t MB_FEATURE_DATA_BITS[MB_LVL_MAX] = {7, 6};
23 
24 bool VerifySyncCode(const uint8_t* data) {
25  return data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a;
26 }
27 
28 bool ReadSegmentation(BitReader* reader) {
29  bool enabled;
30  RCHECK(reader->ReadBits(1, &enabled));
31  if (!enabled)
32  return true;
33 
34  bool update_map;
35  RCHECK(reader->ReadBits(1, &update_map));
36  bool update_data;
37  RCHECK(reader->ReadBits(1, &update_data));
38 
39  if (update_data) {
40  RCHECK(reader->SkipBits(1)); // abs_delta
41  for (uint32_t i = 0; i < MAX_MB_SEGMENTS; ++i)
42  for (uint32_t j = 0; j < MB_LVL_MAX; ++j) {
43  RCHECK(reader->SkipBitsConditional(true, MB_FEATURE_DATA_BITS[j] + 1));
44  }
45  }
46  if (update_map) {
47  for (uint32_t i = 0; i < MB_FEATURE_TREE_PROBS; ++i)
48  RCHECK(reader->SkipBitsConditional(true, 8));
49  }
50  return true;
51 }
52 
53 bool ReadLoopFilter(BitReader* reader) {
54  RCHECK(reader->SkipBits(10)); // filter_type, filter_evel, sharness_level
55 
56  bool mode_ref_delta_enabled;
57  RCHECK(reader->ReadBits(1, &mode_ref_delta_enabled));
58  if (!mode_ref_delta_enabled)
59  return true;
60  bool mode_ref_delta_update;
61  RCHECK(reader->ReadBits(1, &mode_ref_delta_update));
62  if (!mode_ref_delta_update)
63  return true;
64 
65  for (uint32_t i = 0; i < MAX_REF_LF_DELTAS + MAX_MODE_LF_DELTAS; ++i)
66  RCHECK(reader->SkipBitsConditional(true, 6 + 1));
67  return true;
68 }
69 
70 bool ReadQuantization(BitReader* reader) {
71  uint32_t yac_index;
72  RCHECK(reader->ReadBits(7, &yac_index));
73  VLOG(4) << "yac_index: " << yac_index;
74  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y dc delta
75  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y2 dc delta
76  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y2 ac delta
77  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // chroma dc delta
78  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // chroma ac delta
79  return true;
80 }
81 
82 bool ReadRefreshFrame(BitReader* reader) {
83  bool refresh_golden_frame;
84  RCHECK(reader->ReadBits(1, &refresh_golden_frame));
85  bool refresh_altref_frame;
86  RCHECK(reader->ReadBits(1, &refresh_altref_frame));
87  if (!refresh_golden_frame)
88  RCHECK(reader->SkipBits(2)); // buffer copy flag
89  if (!refresh_altref_frame)
90  RCHECK(reader->SkipBits(2)); // buffer copy flag
91  RCHECK(reader->SkipBits(2)); // sign bias flags
92  return true;
93 }
94 
95 } // namespace
96 
97 VP8Parser::VP8Parser() : width_(0), height_(0) {}
98 VP8Parser::~VP8Parser() {}
99 
100 bool VP8Parser::Parse(const uint8_t* data,
101  size_t data_size,
102  std::vector<VPxFrameInfo>* vpx_frames) {
103  DCHECK(data);
104  DCHECK(vpx_frames);
105 
106  BitReader reader(data, data_size);
107  // The following 3 bytes are read directly from |data|.
108  RCHECK(reader.SkipBytes(3));
109 
110  // One bit for frame type.
111  bool is_interframe = data[0] & 1;
112  // 3-bit version number with 2 bits for profile and the other bit reserved for
113  // future variants.
114  uint8_t profile = (data[0] >> 1) & 3;
115  // One bit for show frame flag.
116  // Then 19 bits (the remaining 3 bits in the first byte + next two bytes) for
117  // header size.
118  uint32_t header_size = (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
119  RCHECK(header_size <= data_size);
120 
121  if (!is_interframe) {
122  // The following 7 bytes are read directly from |data|.
123  RCHECK(reader.SkipBytes(7));
124 
125  RCHECK(VerifySyncCode(&data[3]));
126 
127  // Bits 0b11000000 for data[7] and data[9] are scaling.
128  width_ = data[6] | ((data[7] & 0x3f) << 8);
129  height_ = data[8] | ((data[9] & 0x3f) << 8);
130 
131  RCHECK(reader.SkipBits(2)); // colorspace and pixel value clamping.
132  }
133 
134  RCHECK(ReadSegmentation(&reader));
135  RCHECK(ReadLoopFilter(&reader));
136  RCHECK(reader.SkipBits(2)); // partitions bits
137  RCHECK(ReadQuantization(&reader));
138 
139  if (is_interframe) {
140  RCHECK(ReadRefreshFrame(&reader));
141  RCHECK(reader.SkipBits(1)); // refresh_entropy_probs
142  RCHECK(reader.SkipBits(1)); // refresh last frame flag
143  } else {
144  RCHECK(reader.SkipBits(1)); // refresh_entropy_probs
145  }
146 
147  // The next field is entropy header (coef probability tree), which is encoded
148  // using bool entropy encoder, i.e. compressed. We don't consider it as part
149  // of uncompressed header.
150 
151  writable_codec_config()->set_profile(profile);
152  // VP8 uses an 8-bit YUV 4:2:0 format.
153  // http://tools.ietf.org/html/rfc6386 Section 2.
154  writable_codec_config()->set_bit_depth(8);
155  writable_codec_config()->SetChromaSubsampling(
156  VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA);
157 
158  VPxFrameInfo vpx_frame;
159  vpx_frame.frame_size = data_size;
160  vpx_frame.uncompressed_header_size =
161  vpx_frame.frame_size - reader.bits_available() / 8;
162  vpx_frame.is_keyframe = !is_interframe;
163  vpx_frame.width = width_;
164  vpx_frame.height = height_;
165 
166  vpx_frames->clear();
167  vpx_frames->push_back(vpx_frame);
168 
169  VLOG(3) << "\n frame_size: " << vpx_frame.frame_size
170  << "\n uncompressed_header_size: "
171  << vpx_frame.uncompressed_header_size
172  << "\n bits read: " << reader.bit_position()
173  << "\n header_size: " << header_size
174  << "\n width: " << vpx_frame.width
175  << "\n height: " << vpx_frame.height;
176  return true;
177 }
178 
179 bool VP8Parser::IsKeyframe(const uint8_t* data, size_t data_size) {
180  // Make sure the block is big enough for the minimal keyframe header size.
181  if (data_size < 10)
182  return false;
183 
184  // The LSb of the first byte must be a 0 for a keyframe.
185  if ((data[0] & 0x01) != 0)
186  return false;
187  return VerifySyncCode(&data[3]);
188 }
189 
190 } // namespace media
191 } // namespace shaka
A class to read bit streams.
Definition: bit_reader.h:17
- -
bool Parse(const uint8_t *data, size_t data_size, std::vector< VPxFrameInfo > *vpx_frames) override
Definition: vp8_parser.cc:100
-
All the methods that are virtual are virtual for mocking.
-
size_t bit_position() const
Definition: bit_reader.h:94
-
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
-
static bool IsKeyframe(const uint8_t *data, size_t data_size)
Definition: vp8_parser.cc:179
-
bool SkipBytes(size_t num_bytes)
Definition: bit_reader.cc:63
-
size_t bits_available() const
Definition: bit_reader.h:89
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/vp8_parser.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/media/base/bit_reader.h"
+
11 #include "packager/media/base/rcheck.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 namespace {
+
16 
+
17 const uint32_t MB_FEATURE_TREE_PROBS = 3;
+
18 const uint32_t MAX_MB_SEGMENTS = 4;
+
19 const uint32_t MAX_REF_LF_DELTAS = 4;
+
20 const uint32_t MAX_MODE_LF_DELTAS = 4;
+
21 const uint32_t MB_LVL_MAX = 2;
+
22 const uint32_t MB_FEATURE_DATA_BITS[MB_LVL_MAX] = {7, 6};
+
23 
+
24 bool VerifySyncCode(const uint8_t* data) {
+
25  return data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a;
+
26 }
+
27 
+
28 bool ReadSegmentation(BitReader* reader) {
+
29  bool enabled;
+
30  RCHECK(reader->ReadBits(1, &enabled));
+
31  if (!enabled)
+
32  return true;
+
33 
+
34  bool update_map;
+
35  RCHECK(reader->ReadBits(1, &update_map));
+
36  bool update_data;
+
37  RCHECK(reader->ReadBits(1, &update_data));
+
38 
+
39  if (update_data) {
+
40  RCHECK(reader->SkipBits(1)); // abs_delta
+
41  for (uint32_t i = 0; i < MAX_MB_SEGMENTS; ++i)
+
42  for (uint32_t j = 0; j < MB_LVL_MAX; ++j) {
+
43  RCHECK(reader->SkipBitsConditional(true, MB_FEATURE_DATA_BITS[j] + 1));
+
44  }
+
45  }
+
46  if (update_map) {
+
47  for (uint32_t i = 0; i < MB_FEATURE_TREE_PROBS; ++i)
+
48  RCHECK(reader->SkipBitsConditional(true, 8));
+
49  }
+
50  return true;
+
51 }
+
52 
+
53 bool ReadLoopFilter(BitReader* reader) {
+
54  RCHECK(reader->SkipBits(10)); // filter_type, filter_evel, sharness_level
+
55 
+
56  bool mode_ref_delta_enabled;
+
57  RCHECK(reader->ReadBits(1, &mode_ref_delta_enabled));
+
58  if (!mode_ref_delta_enabled)
+
59  return true;
+
60  bool mode_ref_delta_update;
+
61  RCHECK(reader->ReadBits(1, &mode_ref_delta_update));
+
62  if (!mode_ref_delta_update)
+
63  return true;
+
64 
+
65  for (uint32_t i = 0; i < MAX_REF_LF_DELTAS + MAX_MODE_LF_DELTAS; ++i)
+
66  RCHECK(reader->SkipBitsConditional(true, 6 + 1));
+
67  return true;
+
68 }
+
69 
+
70 bool ReadQuantization(BitReader* reader) {
+
71  uint32_t yac_index;
+
72  RCHECK(reader->ReadBits(7, &yac_index));
+
73  VLOG(4) << "yac_index: " << yac_index;
+
74  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y dc delta
+
75  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y2 dc delta
+
76  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // y2 ac delta
+
77  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // chroma dc delta
+
78  RCHECK(reader->SkipBitsConditional(true, 4 + 1)); // chroma ac delta
+
79  return true;
+
80 }
+
81 
+
82 bool ReadRefreshFrame(BitReader* reader) {
+
83  bool refresh_golden_frame;
+
84  RCHECK(reader->ReadBits(1, &refresh_golden_frame));
+
85  bool refresh_altref_frame;
+
86  RCHECK(reader->ReadBits(1, &refresh_altref_frame));
+
87  if (!refresh_golden_frame)
+
88  RCHECK(reader->SkipBits(2)); // buffer copy flag
+
89  if (!refresh_altref_frame)
+
90  RCHECK(reader->SkipBits(2)); // buffer copy flag
+
91  RCHECK(reader->SkipBits(2)); // sign bias flags
+
92  return true;
+
93 }
+
94 
+
95 } // namespace
+
96 
+
97 VP8Parser::VP8Parser() : width_(0), height_(0) {}
+
98 VP8Parser::~VP8Parser() {}
+
99 
+
100 bool VP8Parser::Parse(const uint8_t* data,
+
101  size_t data_size,
+
102  std::vector<VPxFrameInfo>* vpx_frames) {
+
103  DCHECK(data);
+
104  DCHECK(vpx_frames);
+
105 
+
106  BitReader reader(data, data_size);
+
107  // The following 3 bytes are read directly from |data|.
+
108  RCHECK(reader.SkipBytes(3));
+
109 
+
110  // One bit for frame type.
+
111  bool is_interframe = data[0] & 1;
+
112  // 3-bit version number with 2 bits for profile and the other bit reserved for
+
113  // future variants.
+
114  uint8_t profile = (data[0] >> 1) & 3;
+
115  // One bit for show frame flag.
+
116  // Then 19 bits (the remaining 3 bits in the first byte + next two bytes) for
+
117  // header size.
+
118  uint32_t header_size = (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
+
119  RCHECK(header_size <= data_size);
+
120 
+
121  if (!is_interframe) {
+
122  // The following 7 bytes are read directly from |data|.
+
123  RCHECK(reader.SkipBytes(7));
+
124 
+
125  RCHECK(VerifySyncCode(&data[3]));
+
126 
+
127  // Bits 0b11000000 for data[7] and data[9] are scaling.
+
128  width_ = data[6] | ((data[7] & 0x3f) << 8);
+
129  height_ = data[8] | ((data[9] & 0x3f) << 8);
+
130 
+
131  RCHECK(reader.SkipBits(2)); // colorspace and pixel value clamping.
+
132  }
+
133 
+
134  RCHECK(ReadSegmentation(&reader));
+
135  RCHECK(ReadLoopFilter(&reader));
+
136  RCHECK(reader.SkipBits(2)); // partitions bits
+
137  RCHECK(ReadQuantization(&reader));
+
138 
+
139  if (is_interframe) {
+
140  RCHECK(ReadRefreshFrame(&reader));
+
141  RCHECK(reader.SkipBits(1)); // refresh_entropy_probs
+
142  RCHECK(reader.SkipBits(1)); // refresh last frame flag
+
143  } else {
+
144  RCHECK(reader.SkipBits(1)); // refresh_entropy_probs
+
145  }
+
146 
+
147  // The next field is entropy header (coef probability tree), which is encoded
+
148  // using bool entropy encoder, i.e. compressed. We don't consider it as part
+
149  // of uncompressed header.
+
150 
+
151  writable_codec_config()->set_profile(profile);
+
152  // VP8 uses an 8-bit YUV 4:2:0 format.
+
153  // http://tools.ietf.org/html/rfc6386 Section 2.
+
154  writable_codec_config()->set_bit_depth(8);
+
155  writable_codec_config()->SetChromaSubsampling(
+
156  VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA);
+
157 
+
158  VPxFrameInfo vpx_frame;
+
159  vpx_frame.frame_size = data_size;
+
160  vpx_frame.uncompressed_header_size =
+
161  vpx_frame.frame_size - reader.bits_available() / 8;
+
162  vpx_frame.is_keyframe = !is_interframe;
+
163  vpx_frame.width = width_;
+
164  vpx_frame.height = height_;
+
165 
+
166  vpx_frames->clear();
+
167  vpx_frames->push_back(vpx_frame);
+
168 
+
169  VLOG(3) << "\n frame_size: " << vpx_frame.frame_size
+
170  << "\n uncompressed_header_size: "
+
171  << vpx_frame.uncompressed_header_size
+
172  << "\n bits read: " << reader.bit_position()
+
173  << "\n header_size: " << header_size
+
174  << "\n width: " << vpx_frame.width
+
175  << "\n height: " << vpx_frame.height;
+
176  return true;
+
177 }
+
178 
+
179 bool VP8Parser::IsKeyframe(const uint8_t* data, size_t data_size) {
+
180  // Make sure the block is big enough for the minimal keyframe header size.
+
181  if (data_size < 10)
+
182  return false;
+
183 
+
184  // The LSb of the first byte must be a 0 for a keyframe.
+
185  if ((data[0] & 0x01) != 0)
+
186  return false;
+
187  return VerifySyncCode(&data[3]);
+
188 }
+
189 
+
190 } // namespace media
+
191 } // namespace shaka
+
A class to read bit streams.
Definition: bit_reader.h:17
+
size_t bit_position() const
Definition: bit_reader.h:94
+
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
+
bool SkipBytes(size_t num_bytes)
Definition: bit_reader.cc:63
+
size_t bits_available() const
Definition: bit_reader.h:89
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d1/d72/language__utils_8cc_source.html b/docs/d1/d72/language__utils_8cc_source.html index 8b384f6460..51e45b729f 100644 --- a/docs/d1/d72/language__utils_8cc_source.html +++ b/docs/d1/d72/language__utils_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/language_utils.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
language_utils.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/language_utils.h"
8 
9 #include "packager/base/logging.h"
10 
11 namespace {
12 
13 // A map from 3-letter language codes (ISO 639-2) to 2-letter language codes
14 // (ISO 639-1) for all languages which have both in the registry.
15 typedef struct {
16  const char iso_639_2[4]; // 3 letters + nul
17  const char iso_639_1[3]; // 2 letters + nul
18 } LanguageMapPairType;
19 const LanguageMapPairType kLanguageMap[] = {
20  { "aar", "aa" }, { "abk", "ab" }, { "afr", "af" }, { "aka", "ak" },
21  { "alb", "sq" }, { "amh", "am" }, { "ara", "ar" }, { "arg", "an" },
22  { "arm", "hy" }, { "asm", "as" }, { "ava", "av" }, { "ave", "ae" },
23  { "aym", "ay" }, { "aze", "az" }, { "bak", "ba" }, { "bam", "bm" },
24  { "baq", "eu" }, { "bel", "be" }, { "ben", "bn" }, { "bih", "bh" },
25  { "bis", "bi" }, { "bod", "bo" }, { "bos", "bs" }, { "bre", "br" },
26  { "bul", "bg" }, { "bur", "my" }, { "cat", "ca" }, { "ces", "cs" },
27  { "cha", "ch" }, { "che", "ce" }, { "chi", "zh" }, { "chu", "cu" },
28  { "chv", "cv" }, { "cor", "kw" }, { "cos", "co" }, { "cre", "cr" },
29  { "cym", "cy" }, { "cze", "cs" }, { "dan", "da" }, { "deu", "de" },
30  { "div", "dv" }, { "dut", "nl" }, { "dzo", "dz" }, { "ell", "el" },
31  { "eng", "en" }, { "epo", "eo" }, { "est", "et" }, { "eus", "eu" },
32  { "ewe", "ee" }, { "fao", "fo" }, { "fas", "fa" }, { "fij", "fj" },
33  { "fin", "fi" }, { "fra", "fr" }, { "fre", "fr" }, { "fry", "fy" },
34  { "ful", "ff" }, { "geo", "ka" }, { "ger", "de" }, { "gla", "gd" },
35  { "gle", "ga" }, { "glg", "gl" }, { "glv", "gv" }, { "gre", "el" },
36  { "grn", "gn" }, { "guj", "gu" }, { "hat", "ht" }, { "hau", "ha" },
37  { "heb", "he" }, { "her", "hz" }, { "hin", "hi" }, { "hmo", "ho" },
38  { "hrv", "hr" }, { "hun", "hu" }, { "hye", "hy" }, { "ibo", "ig" },
39  { "ice", "is" }, { "ido", "io" }, { "iii", "ii" }, { "iku", "iu" },
40  { "ile", "ie" }, { "ina", "ia" }, { "ind", "id" }, { "ipk", "ik" },
41  { "isl", "is" }, { "ita", "it" }, { "jav", "jv" }, { "jpn", "ja" },
42  { "kal", "kl" }, { "kan", "kn" }, { "kas", "ks" }, { "kat", "ka" },
43  { "kau", "kr" }, { "kaz", "kk" }, { "khm", "km" }, { "kik", "ki" },
44  { "kin", "rw" }, { "kir", "ky" }, { "kom", "kv" }, { "kon", "kg" },
45  { "kor", "ko" }, { "kua", "kj" }, { "kur", "ku" }, { "lao", "lo" },
46  { "lat", "la" }, { "lav", "lv" }, { "lim", "li" }, { "lin", "ln" },
47  { "lit", "lt" }, { "ltz", "lb" }, { "lub", "lu" }, { "lug", "lg" },
48  { "mac", "mk" }, { "mah", "mh" }, { "mal", "ml" }, { "mao", "mi" },
49  { "mar", "mr" }, { "may", "ms" }, { "mkd", "mk" }, { "mlg", "mg" },
50  { "mlt", "mt" }, { "mon", "mn" }, { "mri", "mi" }, { "msa", "ms" },
51  { "mya", "my" }, { "nau", "na" }, { "nav", "nv" }, { "nbl", "nr" },
52  { "nde", "nd" }, { "ndo", "ng" }, { "nep", "ne" }, { "nld", "nl" },
53  { "nno", "nn" }, { "nob", "nb" }, { "nor", "no" }, { "nya", "ny" },
54  { "oci", "oc" }, { "oji", "oj" }, { "ori", "or" }, { "orm", "om" },
55  { "oss", "os" }, { "pan", "pa" }, { "per", "fa" }, { "pli", "pi" },
56  { "pol", "pl" }, { "por", "pt" }, { "pus", "ps" }, { "que", "qu" },
57  { "roh", "rm" }, { "ron", "ro" }, { "rum", "ro" }, { "run", "rn" },
58  { "rus", "ru" }, { "sag", "sg" }, { "san", "sa" }, { "sin", "si" },
59  { "slk", "sk" }, { "slo", "sk" }, { "slv", "sl" }, { "sme", "se" },
60  { "smo", "sm" }, { "sna", "sn" }, { "snd", "sd" }, { "som", "so" },
61  { "sot", "st" }, { "spa", "es" }, { "sqi", "sq" }, { "srd", "sc" },
62  { "srp", "sr" }, { "ssw", "ss" }, { "sun", "su" }, { "swa", "sw" },
63  { "swe", "sv" }, { "tah", "ty" }, { "tam", "ta" }, { "tat", "tt" },
64  { "tel", "te" }, { "tgk", "tg" }, { "tgl", "tl" }, { "tha", "th" },
65  { "tib", "bo" }, { "tir", "ti" }, { "ton", "to" }, { "tsn", "tn" },
66  { "tso", "ts" }, { "tuk", "tk" }, { "tur", "tr" }, { "twi", "tw" },
67  { "uig", "ug" }, { "ukr", "uk" }, { "urd", "ur" }, { "uzb", "uz" },
68  { "ven", "ve" }, { "vie", "vi" }, { "vol", "vo" }, { "wel", "cy" },
69  { "wln", "wa" }, { "wol", "wo" }, { "xho", "xh" }, { "yid", "yi" },
70  { "yor", "yo" }, { "zha", "za" }, { "zho", "zh" }, { "zul", "zu" },
71 };
72 
73 void SplitLanguageTag(const std::string& tag,
74  std::string* main_language, std::string* subtag) {
75  // Split the main language from its subtag (if any).
76  *main_language = tag;
77  subtag->clear();
78  size_t dash = main_language->find('-');
79  if (dash != std::string::npos) {
80  *subtag = main_language->substr(dash);
81  main_language->erase(dash);
82  }
83 }
84 
85 } // namespace
86 
87 namespace shaka {
88 
89 std::string LanguageToShortestForm(const std::string& language) {
90  // Do not try to mangle blank strings.
91  if (language.size() == 0) {
92  return language;
93  }
94 
95  std::string main_language;
96  std::string subtag;
97  SplitLanguageTag(language, &main_language, &subtag);
98 
99  if (main_language.size() == 2) {
100  // Presumably already a valid ISO-639-1 code, and therefore conforms to
101  // BCP-47's requirement to use the shortest possible code.
102  return main_language + subtag;
103  }
104 
105  for (size_t i = 0; i < arraysize(kLanguageMap); ++i) {
106  if (main_language == kLanguageMap[i].iso_639_2) {
107  return kLanguageMap[i].iso_639_1 + subtag;
108  }
109  }
110 
111  // This could happen legitimately for languages which have no 2-letter code,
112  // but that would imply that the input language code is a 3-letter code.
113  DCHECK_EQ(3u, main_language.size()) << main_language;
114  return main_language + subtag;
115 }
116 
117 std::string LanguageToISO_639_2(const std::string& language) {
118  std::string main_language;
119  std::string subtag;
120  SplitLanguageTag(language, &main_language, &subtag);
121 
122  if (main_language.size() == 3) {
123  // Presumably already a valid ISO-639-2 code.
124  return main_language + subtag;
125  }
126 
127  for (size_t i = 0; i < arraysize(kLanguageMap); ++i) {
128  if (main_language == kLanguageMap[i].iso_639_1) {
129  return kLanguageMap[i].iso_639_2 + subtag;
130  }
131  }
132 
133  LOG(WARNING) << "No equivalent 3-letter language code for " << main_language;
134  // This is probably a mistake on the part of the user and should be treated
135  // as invalid input.
136  return "und";
137 }
138 
139 } // namespace shaka
std::string LanguageToShortestForm(const std::string &language)
-
All the methods that are virtual are virtual for mocking.
-
std::string LanguageToISO_639_2(const std::string &language)
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/language_utils.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 
+
11 namespace {
+
12 
+
13 // A map from 3-letter language codes (ISO 639-2) to 2-letter language codes
+
14 // (ISO 639-1) for all languages which have both in the registry.
+
15 typedef struct {
+
16  const char iso_639_2[4]; // 3 letters + nul
+
17  const char iso_639_1[3]; // 2 letters + nul
+
18 } LanguageMapPairType;
+
19 const LanguageMapPairType kLanguageMap[] = {
+
20  { "aar", "aa" }, { "abk", "ab" }, { "afr", "af" }, { "aka", "ak" },
+
21  { "alb", "sq" }, { "amh", "am" }, { "ara", "ar" }, { "arg", "an" },
+
22  { "arm", "hy" }, { "asm", "as" }, { "ava", "av" }, { "ave", "ae" },
+
23  { "aym", "ay" }, { "aze", "az" }, { "bak", "ba" }, { "bam", "bm" },
+
24  { "baq", "eu" }, { "bel", "be" }, { "ben", "bn" }, { "bih", "bh" },
+
25  { "bis", "bi" }, { "bod", "bo" }, { "bos", "bs" }, { "bre", "br" },
+
26  { "bul", "bg" }, { "bur", "my" }, { "cat", "ca" }, { "ces", "cs" },
+
27  { "cha", "ch" }, { "che", "ce" }, { "chi", "zh" }, { "chu", "cu" },
+
28  { "chv", "cv" }, { "cor", "kw" }, { "cos", "co" }, { "cre", "cr" },
+
29  { "cym", "cy" }, { "cze", "cs" }, { "dan", "da" }, { "deu", "de" },
+
30  { "div", "dv" }, { "dut", "nl" }, { "dzo", "dz" }, { "ell", "el" },
+
31  { "eng", "en" }, { "epo", "eo" }, { "est", "et" }, { "eus", "eu" },
+
32  { "ewe", "ee" }, { "fao", "fo" }, { "fas", "fa" }, { "fij", "fj" },
+
33  { "fin", "fi" }, { "fra", "fr" }, { "fre", "fr" }, { "fry", "fy" },
+
34  { "ful", "ff" }, { "geo", "ka" }, { "ger", "de" }, { "gla", "gd" },
+
35  { "gle", "ga" }, { "glg", "gl" }, { "glv", "gv" }, { "gre", "el" },
+
36  { "grn", "gn" }, { "guj", "gu" }, { "hat", "ht" }, { "hau", "ha" },
+
37  { "heb", "he" }, { "her", "hz" }, { "hin", "hi" }, { "hmo", "ho" },
+
38  { "hrv", "hr" }, { "hun", "hu" }, { "hye", "hy" }, { "ibo", "ig" },
+
39  { "ice", "is" }, { "ido", "io" }, { "iii", "ii" }, { "iku", "iu" },
+
40  { "ile", "ie" }, { "ina", "ia" }, { "ind", "id" }, { "ipk", "ik" },
+
41  { "isl", "is" }, { "ita", "it" }, { "jav", "jv" }, { "jpn", "ja" },
+
42  { "kal", "kl" }, { "kan", "kn" }, { "kas", "ks" }, { "kat", "ka" },
+
43  { "kau", "kr" }, { "kaz", "kk" }, { "khm", "km" }, { "kik", "ki" },
+
44  { "kin", "rw" }, { "kir", "ky" }, { "kom", "kv" }, { "kon", "kg" },
+
45  { "kor", "ko" }, { "kua", "kj" }, { "kur", "ku" }, { "lao", "lo" },
+
46  { "lat", "la" }, { "lav", "lv" }, { "lim", "li" }, { "lin", "ln" },
+
47  { "lit", "lt" }, { "ltz", "lb" }, { "lub", "lu" }, { "lug", "lg" },
+
48  { "mac", "mk" }, { "mah", "mh" }, { "mal", "ml" }, { "mao", "mi" },
+
49  { "mar", "mr" }, { "may", "ms" }, { "mkd", "mk" }, { "mlg", "mg" },
+
50  { "mlt", "mt" }, { "mon", "mn" }, { "mri", "mi" }, { "msa", "ms" },
+
51  { "mya", "my" }, { "nau", "na" }, { "nav", "nv" }, { "nbl", "nr" },
+
52  { "nde", "nd" }, { "ndo", "ng" }, { "nep", "ne" }, { "nld", "nl" },
+
53  { "nno", "nn" }, { "nob", "nb" }, { "nor", "no" }, { "nya", "ny" },
+
54  { "oci", "oc" }, { "oji", "oj" }, { "ori", "or" }, { "orm", "om" },
+
55  { "oss", "os" }, { "pan", "pa" }, { "per", "fa" }, { "pli", "pi" },
+
56  { "pol", "pl" }, { "por", "pt" }, { "pus", "ps" }, { "que", "qu" },
+
57  { "roh", "rm" }, { "ron", "ro" }, { "rum", "ro" }, { "run", "rn" },
+
58  { "rus", "ru" }, { "sag", "sg" }, { "san", "sa" }, { "sin", "si" },
+
59  { "slk", "sk" }, { "slo", "sk" }, { "slv", "sl" }, { "sme", "se" },
+
60  { "smo", "sm" }, { "sna", "sn" }, { "snd", "sd" }, { "som", "so" },
+
61  { "sot", "st" }, { "spa", "es" }, { "sqi", "sq" }, { "srd", "sc" },
+
62  { "srp", "sr" }, { "ssw", "ss" }, { "sun", "su" }, { "swa", "sw" },
+
63  { "swe", "sv" }, { "tah", "ty" }, { "tam", "ta" }, { "tat", "tt" },
+
64  { "tel", "te" }, { "tgk", "tg" }, { "tgl", "tl" }, { "tha", "th" },
+
65  { "tib", "bo" }, { "tir", "ti" }, { "ton", "to" }, { "tsn", "tn" },
+
66  { "tso", "ts" }, { "tuk", "tk" }, { "tur", "tr" }, { "twi", "tw" },
+
67  { "uig", "ug" }, { "ukr", "uk" }, { "urd", "ur" }, { "uzb", "uz" },
+
68  { "ven", "ve" }, { "vie", "vi" }, { "vol", "vo" }, { "wel", "cy" },
+
69  { "wln", "wa" }, { "wol", "wo" }, { "xho", "xh" }, { "yid", "yi" },
+
70  { "yor", "yo" }, { "zha", "za" }, { "zho", "zh" }, { "zul", "zu" },
+
71 };
+
72 
+
73 void SplitLanguageTag(const std::string& tag,
+
74  std::string* main_language, std::string* subtag) {
+
75  // Split the main language from its subtag (if any).
+
76  *main_language = tag;
+
77  subtag->clear();
+
78  size_t dash = main_language->find('-');
+
79  if (dash != std::string::npos) {
+
80  *subtag = main_language->substr(dash);
+
81  main_language->erase(dash);
+
82  }
+
83 }
+
84 
+
85 } // namespace
+
86 
+
87 namespace shaka {
+
88 
+
89 std::string LanguageToShortestForm(const std::string& language) {
+
90  // Do not try to mangle blank strings.
+
91  if (language.size() == 0) {
+
92  return language;
+
93  }
+
94 
+
95  std::string main_language;
+
96  std::string subtag;
+
97  SplitLanguageTag(language, &main_language, &subtag);
+
98 
+
99  if (main_language.size() == 2) {
+
100  // Presumably already a valid ISO-639-1 code, and therefore conforms to
+
101  // BCP-47's requirement to use the shortest possible code.
+
102  return main_language + subtag;
+
103  }
+
104 
+
105  for (size_t i = 0; i < arraysize(kLanguageMap); ++i) {
+
106  if (main_language == kLanguageMap[i].iso_639_2) {
+
107  return kLanguageMap[i].iso_639_1 + subtag;
+
108  }
+
109  }
+
110 
+
111  // This could happen legitimately for languages which have no 2-letter code,
+
112  // but that would imply that the input language code is a 3-letter code.
+
113  DCHECK_EQ(3u, main_language.size()) << main_language;
+
114  return main_language + subtag;
+
115 }
+
116 
+
117 std::string LanguageToISO_639_2(const std::string& language) {
+
118  std::string main_language;
+
119  std::string subtag;
+
120  SplitLanguageTag(language, &main_language, &subtag);
+
121 
+
122  if (main_language.size() == 3) {
+
123  // Presumably already a valid ISO-639-2 code.
+
124  return main_language + subtag;
+
125  }
+
126 
+
127  for (size_t i = 0; i < arraysize(kLanguageMap); ++i) {
+
128  if (main_language == kLanguageMap[i].iso_639_1) {
+
129  return kLanguageMap[i].iso_639_2 + subtag;
+
130  }
+
131  }
+
132 
+
133  LOG(WARNING) << "No equivalent 3-letter language code for " << main_language;
+
134  // This is probably a mistake on the part of the user and should be treated
+
135  // as invalid input.
+
136  return "und";
+
137 }
+
138 
+
139 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
+
std::string LanguageToISO_639_2(const std::string &language)
+
std::string LanguageToShortestForm(const std::string &language)
diff --git a/docs/d1/d74/classshaka_1_1media_1_1PackedAudioSegmenter-members.html b/docs/d1/d74/classshaka_1_1media_1_1PackedAudioSegmenter-members.html index 7fc235db66..5bcf2b2aa6 100644 --- a/docs/d1/d74/classshaka_1_1media_1_1PackedAudioSegmenter-members.html +++ b/docs/d1/d74/classshaka_1_1media_1_1PackedAudioSegmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d74/mp2t__media__parser_8cc_source.html b/docs/d1/d74/mp2t__media__parser_8cc_source.html index 52c212103a..7716cb637d 100644 --- a/docs/d1/d74/mp2t__media__parser_8cc_source.html +++ b/docs/d1/d74/mp2t__media__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/mp2t_media_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
mp2t_media_parser.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/mp2t/mp2t_media_parser.h"
6 
7 #include <memory>
8 #include "packager/base/bind.h"
9 #include "packager/media/base/media_sample.h"
10 #include "packager/media/base/stream_info.h"
11 #include "packager/media/formats/mp2t/es_parser.h"
12 #include "packager/media/formats/mp2t/es_parser_audio.h"
13 #include "packager/media/formats/mp2t/es_parser_h264.h"
14 #include "packager/media/formats/mp2t/es_parser_h265.h"
15 #include "packager/media/formats/mp2t/mp2t_common.h"
16 #include "packager/media/formats/mp2t/ts_packet.h"
17 #include "packager/media/formats/mp2t/ts_section.h"
18 #include "packager/media/formats/mp2t/ts_section_pat.h"
19 #include "packager/media/formats/mp2t/ts_section_pes.h"
20 #include "packager/media/formats/mp2t/ts_section_pmt.h"
21 #include "packager/media/formats/mp2t/ts_stream_type.h"
22 
23 namespace shaka {
24 namespace media {
25 namespace mp2t {
26 
27 class PidState {
28  public:
29  enum PidType {
30  kPidPat,
31  kPidPmt,
32  kPidAudioPes,
33  kPidVideoPes,
34  };
35 
36  PidState(int pid,
37  PidType pid_type,
38  std::unique_ptr<TsSection> section_parser);
39 
40  // Extract the content of the TS packet and parse it.
41  // Return true if successful.
42  bool PushTsPacket(const TsPacket& ts_packet);
43 
44  // Flush the PID state (possibly emitting some pending frames)
45  // and reset its state.
46  void Flush();
47 
48  // Enable/disable the PID.
49  // Disabling a PID will reset its state and ignore any further incoming TS
50  // packets.
51  void Enable();
52  void Disable();
53  bool IsEnabled() const;
54 
55  PidType pid_type() const { return pid_type_; }
56 
57  std::shared_ptr<StreamInfo>& config() { return config_; }
58  void set_config(const std::shared_ptr<StreamInfo>& config) {
59  config_ = config;
60  }
61 
62  SampleQueue& sample_queue() { return sample_queue_; }
63 
64  private:
65  void ResetState();
66 
67  int pid_;
68  PidType pid_type_;
69  std::unique_ptr<TsSection> section_parser_;
70 
71  bool enable_;
72  int continuity_counter_;
73  std::shared_ptr<StreamInfo> config_;
74  SampleQueue sample_queue_;
75 };
76 
77 PidState::PidState(int pid,
78  PidType pid_type,
79  std::unique_ptr<TsSection> section_parser)
80  : pid_(pid),
81  pid_type_(pid_type),
82  section_parser_(std::move(section_parser)),
83  enable_(false),
84  continuity_counter_(-1) {
85  DCHECK(section_parser_);
86 }
87 
88 bool PidState::PushTsPacket(const TsPacket& ts_packet) {
89  DCHECK_EQ(ts_packet.pid(), pid_);
90 
91  // The current PID is not part of the PID filter,
92  // just discard the incoming TS packet.
93  if (!enable_)
94  return true;
95 
96  int expected_continuity_counter = (continuity_counter_ + 1) % 16;
97  if (continuity_counter_ >= 0 &&
98  ts_packet.continuity_counter() != expected_continuity_counter) {
99  DVLOG(1) << "TS discontinuity detected for pid: " << pid_;
100  // TODO(tinskip): Handle discontinuity better.
101  return false;
102  }
103 
104  bool status = section_parser_->Parse(
105  ts_packet.payload_unit_start_indicator(),
106  ts_packet.payload(),
107  ts_packet.payload_size());
108 
109  // At the minimum, when parsing failed, auto reset the section parser.
110  // Components that use the Mp2tMediaParser can take further action if needed.
111  if (!status) {
112  DVLOG(1) << "Parsing failed for pid = " << pid_;
113  ResetState();
114  }
115 
116  return status;
117 }
118 
119 void PidState::Flush() {
120  section_parser_->Flush();
121  ResetState();
122 }
123 
124 void PidState::Enable() {
125  enable_ = true;
126 }
127 
128 void PidState::Disable() {
129  if (!enable_)
130  return;
131 
132  ResetState();
133  enable_ = false;
134 }
135 
136 bool PidState::IsEnabled() const {
137  return enable_;
138 }
139 
140 void PidState::ResetState() {
141  section_parser_->Reset();
142  continuity_counter_ = -1;
143 }
144 
145 Mp2tMediaParser::Mp2tMediaParser()
146  : sbr_in_mimetype_(false),
147  is_initialized_(false) {
148 }
149 
150 Mp2tMediaParser::~Mp2tMediaParser() {}
151 
153  const InitCB& init_cb,
154  const NewSampleCB& new_sample_cb,
155  KeySource* decryption_key_source) {
156  DCHECK(!is_initialized_);
157  DCHECK(init_cb_.is_null());
158  DCHECK(!init_cb.is_null());
159  DCHECK(!new_sample_cb.is_null());
160 
161  init_cb_ = init_cb;
162  new_sample_cb_ = new_sample_cb;
163 }
164 
166  DVLOG(1) << "Mp2tMediaParser::Flush";
167 
168  // Flush the buffers and reset the pids.
169  for (const auto& pair : pids_) {
170  DVLOG(1) << "Flushing PID: " << pair.first;
171  PidState* pid_state = pair.second.get();
172  pid_state->Flush();
173  }
174  bool result = EmitRemainingSamples();
175  pids_.clear();
176 
177  // Remove any bytes left in the TS buffer.
178  // (i.e. any partial TS packet => less than 188 bytes).
179  ts_byte_queue_.Reset();
180  return result;
181 }
182 
183 bool Mp2tMediaParser::Parse(const uint8_t* buf, int size) {
184  DVLOG(1) << "Mp2tMediaParser::Parse size=" << size;
185 
186  // Add the data to the parser state.
187  ts_byte_queue_.Push(buf, size);
188 
189  while (true) {
190  const uint8_t* ts_buffer;
191  int ts_buffer_size;
192  ts_byte_queue_.Peek(&ts_buffer, &ts_buffer_size);
193  if (ts_buffer_size < TsPacket::kPacketSize)
194  break;
195 
196  // Synchronization.
197  int skipped_bytes = TsPacket::Sync(ts_buffer, ts_buffer_size);
198  if (skipped_bytes > 0) {
199  DVLOG(1) << "Packet not aligned on a TS syncword:"
200  << " skipped_bytes=" << skipped_bytes;
201  ts_byte_queue_.Pop(skipped_bytes);
202  continue;
203  }
204 
205  // Parse the TS header, skipping 1 byte if the header is invalid.
206  std::unique_ptr<TsPacket> ts_packet(
207  TsPacket::Parse(ts_buffer, ts_buffer_size));
208  if (!ts_packet) {
209  DVLOG(1) << "Error: invalid TS packet";
210  ts_byte_queue_.Pop(1);
211  continue;
212  }
213  DVLOG(LOG_LEVEL_TS)
214  << "Processing PID=" << ts_packet->pid()
215  << " start_unit=" << ts_packet->payload_unit_start_indicator();
216 
217  // Parse the section.
218  std::map<int, std::unique_ptr<PidState>>::iterator it =
219  pids_.find(ts_packet->pid());
220  if (it == pids_.end() &&
221  ts_packet->pid() == TsSection::kPidPat) {
222  // Create the PAT state here if needed.
223  std::unique_ptr<TsSection> pat_section_parser(new TsSectionPat(
224  base::Bind(&Mp2tMediaParser::RegisterPmt, base::Unretained(this))));
225  std::unique_ptr<PidState> pat_pid_state(new PidState(
226  ts_packet->pid(), PidState::kPidPat, std::move(pat_section_parser)));
227  pat_pid_state->Enable();
228  it = pids_
229  .insert(std::pair<int, std::unique_ptr<PidState>>(
230  ts_packet->pid(), std::move(pat_pid_state)))
231  .first;
232  }
233 
234  if (it != pids_.end()) {
235  if (!it->second->PushTsPacket(*ts_packet))
236  return false;
237  } else {
238  DVLOG(LOG_LEVEL_TS) << "Ignoring TS packet for pid: " << ts_packet->pid();
239  }
240 
241  // Go to the next packet.
242  ts_byte_queue_.Pop(TsPacket::kPacketSize);
243  }
244 
245  // Emit the A/V buffers that kept accumulating during TS parsing.
246  return EmitRemainingSamples();
247 }
248 
249 void Mp2tMediaParser::RegisterPmt(int program_number, int pmt_pid) {
250  DVLOG(1) << "RegisterPmt:"
251  << " program_number=" << program_number
252  << " pmt_pid=" << pmt_pid;
253 
254  // Only one TS program is allowed. Ignore the incoming program map table,
255  // if there is already one registered.
256  for (const auto& pair : pids_) {
257  if (pair.second->pid_type() == PidState::kPidPmt) {
258  DVLOG_IF(1, pmt_pid != pair.first) << "More than one program is defined";
259  return;
260  }
261  }
262 
263  // Create the PMT state here if needed.
264  DVLOG(1) << "Create a new PMT parser";
265  std::unique_ptr<TsSection> pmt_section_parser(new TsSectionPmt(base::Bind(
266  &Mp2tMediaParser::RegisterPes, base::Unretained(this), pmt_pid)));
267  std::unique_ptr<PidState> pmt_pid_state(
268  new PidState(pmt_pid, PidState::kPidPmt, std::move(pmt_section_parser)));
269  pmt_pid_state->Enable();
270  pids_.insert(std::pair<int, std::unique_ptr<PidState>>(
271  pmt_pid, std::move(pmt_pid_state)));
272 }
273 
274 void Mp2tMediaParser::RegisterPes(int pmt_pid,
275  int pes_pid,
276  int stream_type) {
277  DVLOG(1) << "RegisterPes:"
278  << " pes_pid=" << pes_pid
279  << " stream_type=" << std::hex << stream_type << std::dec;
280  std::map<int, std::unique_ptr<PidState>>::iterator it = pids_.find(pes_pid);
281  if (it != pids_.end())
282  return;
283 
284  // Create a stream parser corresponding to the stream type.
285  bool is_audio = false;
286  std::unique_ptr<EsParser> es_parser;
287  switch (static_cast<TsStreamType>(stream_type)) {
288  case TsStreamType::kAvc:
289  es_parser.reset(new EsParserH264(
290  pes_pid,
291  base::Bind(&Mp2tMediaParser::OnNewStreamInfo, base::Unretained(this)),
292  base::Bind(&Mp2tMediaParser::OnEmitSample, base::Unretained(this))));
293  break;
294  case TsStreamType::kHevc:
295  es_parser.reset(new EsParserH265(
296  pes_pid,
297  base::Bind(&Mp2tMediaParser::OnNewStreamInfo, base::Unretained(this)),
298  base::Bind(&Mp2tMediaParser::OnEmitSample, base::Unretained(this))));
299  break;
300  case TsStreamType::kAdtsAac:
301  case TsStreamType::kAc3:
302  es_parser.reset(new EsParserAudio(
303  pes_pid, static_cast<TsStreamType>(stream_type),
304  base::Bind(&Mp2tMediaParser::OnNewStreamInfo, base::Unretained(this)),
305  base::Bind(&Mp2tMediaParser::OnEmitSample, base::Unretained(this)),
306  sbr_in_mimetype_));
307  is_audio = true;
308  break;
309  default: {
310  LOG_IF(ERROR, !stream_type_logged_once_[stream_type])
311  << "Ignore unsupported MPEG2TS stream type 0x" << std::hex
312  << stream_type << std::dec;
313  stream_type_logged_once_[stream_type] = true;
314  return;
315  }
316  }
317 
318  // Create the PES state here.
319  DVLOG(1) << "Create a new PES state";
320  std::unique_ptr<TsSection> pes_section_parser(
321  new TsSectionPes(std::move(es_parser)));
322  PidState::PidType pid_type =
323  is_audio ? PidState::kPidAudioPes : PidState::kPidVideoPes;
324  std::unique_ptr<PidState> pes_pid_state(
325  new PidState(pes_pid, pid_type, std::move(pes_section_parser)));
326  pes_pid_state->Enable();
327  pids_.insert(std::pair<int, std::unique_ptr<PidState>>(
328  pes_pid, std::move(pes_pid_state)));
329 }
330 
331 void Mp2tMediaParser::OnNewStreamInfo(
332  const std::shared_ptr<StreamInfo>& new_stream_info) {
333  DCHECK(new_stream_info);
334  DVLOG(1) << "OnVideoConfigChanged for pid=" << new_stream_info->track_id();
335 
336  PidMap::iterator pid_state = pids_.find(new_stream_info->track_id());
337  if (pid_state == pids_.end()) {
338  LOG(ERROR) << "PID State for new stream not found (pid = "
339  << new_stream_info->track_id() << ").";
340  return;
341  }
342 
343  // Set the stream configuration information for the PID.
344  pid_state->second->set_config(new_stream_info);
345 
346  // Finish initialization if all streams have configs.
347  FinishInitializationIfNeeded();
348 }
349 
350 bool Mp2tMediaParser::FinishInitializationIfNeeded() {
351  // Nothing to be done if already initialized.
352  if (is_initialized_)
353  return true;
354 
355  // Wait for more data to come to finish initialization.
356  if (pids_.empty())
357  return true;
358 
359  std::vector<std::shared_ptr<StreamInfo>> all_stream_info;
360  uint32_t num_es(0);
361  for (PidMap::const_iterator iter = pids_.begin(); iter != pids_.end();
362  ++iter) {
363  if (((iter->second->pid_type() == PidState::kPidAudioPes) ||
364  (iter->second->pid_type() == PidState::kPidVideoPes))) {
365  ++num_es;
366  if (iter->second->config())
367  all_stream_info.push_back(iter->second->config());
368  }
369  }
370  if (num_es && (all_stream_info.size() == num_es)) {
371  // All stream configurations have been received. Initialization can
372  // be completed.
373  init_cb_.Run(all_stream_info);
374  DVLOG(1) << "Mpeg2TS stream parser initialization done";
375  is_initialized_ = true;
376  }
377  return true;
378 }
379 
380 void Mp2tMediaParser::OnEmitSample(
381  uint32_t pes_pid,
382  const std::shared_ptr<MediaSample>& new_sample) {
383  DCHECK(new_sample);
384  DVLOG(LOG_LEVEL_ES)
385  << "OnEmitSample: "
386  << " pid="
387  << pes_pid
388  << " size="
389  << new_sample->data_size()
390  << " dts="
391  << new_sample->dts()
392  << " pts="
393  << new_sample->pts();
394 
395  // Add the sample to the appropriate PID sample queue.
396  PidMap::iterator pid_state = pids_.find(pes_pid);
397  if (pid_state == pids_.end()) {
398  LOG(ERROR) << "PID State for new sample not found (pid = "
399  << pes_pid << ").";
400  return;
401  }
402  pid_state->second->sample_queue().push_back(new_sample);
403 }
404 
405 bool Mp2tMediaParser::EmitRemainingSamples() {
406  DVLOG(LOG_LEVEL_ES) << "Mp2tMediaParser::EmitRemainingBuffers";
407 
408  // No buffer should be sent until fully initialized.
409  if (!is_initialized_)
410  return true;
411 
412  // Buffer emission.
413  for (PidMap::const_iterator pid_iter = pids_.begin(); pid_iter != pids_.end();
414  ++pid_iter) {
415  SampleQueue& sample_queue = pid_iter->second->sample_queue();
416  for (SampleQueue::iterator sample_iter = sample_queue.begin();
417  sample_iter != sample_queue.end();
418  ++sample_iter) {
419  if (!new_sample_cb_.Run(pid_iter->first, *sample_iter)) {
420  // Error processing sample. Propagate error condition.
421  return false;
422  }
423  }
424  sample_queue.clear();
425  }
426 
427  return true;
428 }
429 
430 } // namespace mp2t
431 } // namespace media
432 } // namespace shaka
- -
STL namespace.
-
void Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
-
All the methods that are virtual are virtual for mocking.
-
base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
Definition: media_parser.h:34
-
bool Flush() override WARN_UNUSED_RESULT
-
base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
Definition: media_parser.h:43
- -
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:48
- - -
bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/mp2t/mp2t_media_parser.h"
+
6 
+
7 #include <memory>
+
8 
+
9 #include "packager/base/bind.h"
+
10 #include "packager/media/base/media_sample.h"
+
11 #include "packager/media/base/stream_info.h"
+
12 #include "packager/media/base/text_sample.h"
+
13 #include "packager/media/formats/mp2t/es_parser.h"
+
14 #include "packager/media/formats/mp2t/es_parser_audio.h"
+
15 #include "packager/media/formats/mp2t/es_parser_dvb.h"
+
16 #include "packager/media/formats/mp2t/es_parser_h264.h"
+
17 #include "packager/media/formats/mp2t/es_parser_h265.h"
+
18 #include "packager/media/formats/mp2t/mp2t_common.h"
+
19 #include "packager/media/formats/mp2t/ts_packet.h"
+
20 #include "packager/media/formats/mp2t/ts_section.h"
+
21 #include "packager/media/formats/mp2t/ts_section_pat.h"
+
22 #include "packager/media/formats/mp2t/ts_section_pes.h"
+
23 #include "packager/media/formats/mp2t/ts_section_pmt.h"
+
24 #include "packager/media/formats/mp2t/ts_stream_type.h"
+
25 
+
26 namespace shaka {
+
27 namespace media {
+
28 namespace mp2t {
+
29 
+
30 class PidState {
+
31  public:
+
32  enum PidType {
+
33  kPidPat,
+
34  kPidPmt,
+
35  kPidAudioPes,
+
36  kPidVideoPes,
+
37  kPidTextPes,
+
38  };
+
39 
+
40  PidState(int pid,
+
41  PidType pid_type,
+
42  std::unique_ptr<TsSection> section_parser);
+
43 
+
44  // Extract the content of the TS packet and parse it.
+
45  // Return true if successful.
+
46  bool PushTsPacket(const TsPacket& ts_packet);
+
47 
+
48  // Flush the PID state (possibly emitting some pending frames)
+
49  // and reset its state.
+
50  bool Flush();
+
51 
+
52  // Enable/disable the PID.
+
53  // Disabling a PID will reset its state and ignore any further incoming TS
+
54  // packets.
+
55  void Enable();
+
56  void Disable();
+
57  bool IsEnabled() const;
+
58 
+
59  PidType pid_type() const { return pid_type_; }
+
60 
+
61  std::shared_ptr<StreamInfo>& config() { return config_; }
+
62  void set_config(const std::shared_ptr<StreamInfo>& config) {
+
63  config_ = config;
+
64  }
+
65 
+
66  private:
+
67  friend Mp2tMediaParser;
+
68  void ResetState();
+
69 
+
70  int pid_;
+
71  PidType pid_type_;
+
72  std::unique_ptr<TsSection> section_parser_;
+
73 
+
74  std::deque<std::shared_ptr<MediaSample>> media_sample_queue_;
+
75  std::deque<std::shared_ptr<TextSample>> text_sample_queue_;
+
76 
+
77  bool enable_;
+
78  int continuity_counter_;
+
79  std::shared_ptr<StreamInfo> config_;
+
80 };
+
81 
+
82 PidState::PidState(int pid,
+
83  PidType pid_type,
+
84  std::unique_ptr<TsSection> section_parser)
+
85  : pid_(pid),
+
86  pid_type_(pid_type),
+
87  section_parser_(std::move(section_parser)),
+
88  enable_(false),
+
89  continuity_counter_(-1) {
+
90  DCHECK(section_parser_);
+
91 }
+
92 
+
93 bool PidState::PushTsPacket(const TsPacket& ts_packet) {
+
94  DCHECK_EQ(ts_packet.pid(), pid_);
+
95 
+
96  // The current PID is not part of the PID filter,
+
97  // just discard the incoming TS packet.
+
98  if (!enable_)
+
99  return true;
+
100 
+
101  int expected_continuity_counter = (continuity_counter_ + 1) % 16;
+
102  if (continuity_counter_ >= 0 &&
+
103  ts_packet.continuity_counter() != expected_continuity_counter) {
+
104  LOG(ERROR) << "TS discontinuity detected for pid: " << pid_;
+
105  // TODO(tinskip): Handle discontinuity better.
+
106  return false;
+
107  }
+
108 
+
109  bool status = section_parser_->Parse(
+
110  ts_packet.payload_unit_start_indicator(),
+
111  ts_packet.payload(),
+
112  ts_packet.payload_size());
+
113 
+
114  // At the minimum, when parsing failed, auto reset the section parser.
+
115  // Components that use the Mp2tMediaParser can take further action if needed.
+
116  if (!status) {
+
117  LOG(ERROR) << "Parsing failed for pid = " << pid_ << ", type=" << pid_type_;
+
118  ResetState();
+
119  }
+
120 
+
121  return status;
+
122 }
+
123 
+
124 bool PidState::Flush() {
+
125  RCHECK(section_parser_->Flush());
+
126  ResetState();
+
127  return true;
+
128 }
+
129 
+
130 void PidState::Enable() {
+
131  enable_ = true;
+
132 }
+
133 
+
134 void PidState::Disable() {
+
135  if (!enable_)
+
136  return;
+
137 
+
138  ResetState();
+
139  enable_ = false;
+
140 }
+
141 
+
142 bool PidState::IsEnabled() const {
+
143  return enable_;
+
144 }
+
145 
+
146 void PidState::ResetState() {
+
147  section_parser_->Reset();
+
148  continuity_counter_ = -1;
+
149 }
+
150 
+
151 Mp2tMediaParser::Mp2tMediaParser()
+
152  : sbr_in_mimetype_(false),
+
153  is_initialized_(false) {
+
154 }
+
155 
+
156 Mp2tMediaParser::~Mp2tMediaParser() {}
+
157 
+
158 void Mp2tMediaParser::Init(const InitCB& init_cb,
+
159  const NewMediaSampleCB& new_media_sample_cb,
+
160  const NewTextSampleCB& new_text_sample_cb,
+
161  KeySource* decryption_key_source) {
+
162  DCHECK(!is_initialized_);
+
163  DCHECK(init_cb_.is_null());
+
164  DCHECK(!init_cb.is_null());
+
165  DCHECK(!new_media_sample_cb.is_null());
+
166  DCHECK(!new_text_sample_cb.is_null());
+
167 
+
168  init_cb_ = init_cb;
+
169  new_media_sample_cb_ = new_media_sample_cb;
+
170  new_text_sample_cb_ = new_text_sample_cb;
+
171 }
+
172 
+
173 bool Mp2tMediaParser::Flush() {
+
174  DVLOG(1) << "Mp2tMediaParser::Flush";
+
175 
+
176  // Flush the buffers and reset the pids.
+
177  for (const auto& pair : pids_) {
+
178  DVLOG(1) << "Flushing PID: " << pair.first;
+
179  PidState* pid_state = pair.second.get();
+
180  RCHECK(pid_state->Flush());
+
181  }
+
182  bool result = EmitRemainingSamples();
+
183  pids_.clear();
+
184 
+
185  // Remove any bytes left in the TS buffer.
+
186  // (i.e. any partial TS packet => less than 188 bytes).
+
187  ts_byte_queue_.Reset();
+
188  return result;
+
189 }
+
190 
+
191 bool Mp2tMediaParser::Parse(const uint8_t* buf, int size) {
+
192  DVLOG(2) << "Mp2tMediaParser::Parse size=" << size;
+
193 
+
194  // Add the data to the parser state.
+
195  ts_byte_queue_.Push(buf, size);
+
196 
+
197  while (true) {
+
198  const uint8_t* ts_buffer;
+
199  int ts_buffer_size;
+
200  ts_byte_queue_.Peek(&ts_buffer, &ts_buffer_size);
+
201  if (ts_buffer_size < TsPacket::kPacketSize)
+
202  break;
+
203 
+
204  // Synchronization.
+
205  int skipped_bytes = TsPacket::Sync(ts_buffer, ts_buffer_size);
+
206  if (skipped_bytes > 0) {
+
207  DVLOG(1) << "Packet not aligned on a TS syncword:"
+
208  << " skipped_bytes=" << skipped_bytes;
+
209  ts_byte_queue_.Pop(skipped_bytes);
+
210  continue;
+
211  }
+
212 
+
213  // Parse the TS header, skipping 1 byte if the header is invalid.
+
214  std::unique_ptr<TsPacket> ts_packet(
+
215  TsPacket::Parse(ts_buffer, ts_buffer_size));
+
216  if (!ts_packet) {
+
217  DVLOG(1) << "Error: invalid TS packet";
+
218  ts_byte_queue_.Pop(1);
+
219  continue;
+
220  }
+
221  DVLOG(LOG_LEVEL_TS)
+
222  << "Processing PID=" << ts_packet->pid()
+
223  << " start_unit=" << ts_packet->payload_unit_start_indicator();
+
224 
+
225  // Parse the section.
+
226  auto it = pids_.find(ts_packet->pid());
+
227  if (it == pids_.end() &&
+
228  ts_packet->pid() == TsSection::kPidPat) {
+
229  // Create the PAT state here if needed.
+
230  std::unique_ptr<TsSection> pat_section_parser(new TsSectionPat(
+
231  base::Bind(&Mp2tMediaParser::RegisterPmt, base::Unretained(this))));
+
232  std::unique_ptr<PidState> pat_pid_state(new PidState(
+
233  ts_packet->pid(), PidState::kPidPat, std::move(pat_section_parser)));
+
234  pat_pid_state->Enable();
+
235  it = pids_.emplace(ts_packet->pid(), std::move(pat_pid_state)).first;
+
236  }
+
237 
+
238  if (it != pids_.end()) {
+
239  RCHECK(it->second->PushTsPacket(*ts_packet));
+
240  } else {
+
241  DVLOG(LOG_LEVEL_TS) << "Ignoring TS packet for pid: " << ts_packet->pid();
+
242  }
+
243 
+
244  // Go to the next packet.
+
245  ts_byte_queue_.Pop(TsPacket::kPacketSize);
+
246  }
+
247 
+
248  // Emit the A/V buffers that kept accumulating during TS parsing.
+
249  return EmitRemainingSamples();
+
250 }
+
251 
+
252 void Mp2tMediaParser::RegisterPmt(int program_number, int pmt_pid) {
+
253  DVLOG(1) << "RegisterPmt:"
+
254  << " program_number=" << program_number
+
255  << " pmt_pid=" << pmt_pid;
+
256 
+
257  // Only one TS program is allowed. Ignore the incoming program map table,
+
258  // if there is already one registered.
+
259  for (const auto& pair : pids_) {
+
260  if (pair.second->pid_type() == PidState::kPidPmt) {
+
261  DVLOG_IF(1, pmt_pid != pair.first) << "More than one program is defined";
+
262  return;
+
263  }
+
264  }
+
265 
+
266  // Create the PMT state here if needed.
+
267  DVLOG(1) << "Create a new PMT parser";
+
268  std::unique_ptr<TsSection> pmt_section_parser(new TsSectionPmt(base::Bind(
+
269  &Mp2tMediaParser::RegisterPes, base::Unretained(this), pmt_pid)));
+
270  std::unique_ptr<PidState> pmt_pid_state(
+
271  new PidState(pmt_pid, PidState::kPidPmt, std::move(pmt_section_parser)));
+
272  pmt_pid_state->Enable();
+
273  pids_.emplace(pmt_pid, std::move(pmt_pid_state));
+
274 }
+
275 
+
276 void Mp2tMediaParser::RegisterPes(int pmt_pid,
+
277  int pes_pid,
+
278  TsStreamType stream_type,
+
279  const uint8_t* descriptor,
+
280  size_t descriptor_length) {
+
281  if (pids_.count(pes_pid) != 0)
+
282  return;
+
283  DVLOG(1) << "RegisterPes:"
+
284  << " pes_pid=" << pes_pid << " stream_type=" << std::hex
+
285  << static_cast<int>(stream_type) << std::dec;
+
286 
+
287  // Create a stream parser corresponding to the stream type.
+
288  PidState::PidType pid_type = PidState::kPidVideoPes;
+
289  std::unique_ptr<EsParser> es_parser;
+
290  auto on_new_stream = base::Bind(&Mp2tMediaParser::OnNewStreamInfo,
+
291  base::Unretained(this), pes_pid);
+
292  auto on_emit_media = base::Bind(&Mp2tMediaParser::OnEmitMediaSample,
+
293  base::Unretained(this), pes_pid);
+
294  auto on_emit_text = base::Bind(&Mp2tMediaParser::OnEmitTextSample,
+
295  base::Unretained(this), pes_pid);
+
296  switch (stream_type) {
+
297  case TsStreamType::kAvc:
+
298  es_parser.reset(new EsParserH264(pes_pid, on_new_stream, on_emit_media));
+
299  break;
+
300  case TsStreamType::kHevc:
+
301  es_parser.reset(new EsParserH265(pes_pid, on_new_stream, on_emit_media));
+
302  break;
+
303  case TsStreamType::kAdtsAac:
+
304  case TsStreamType::kMpeg1Audio:
+
305  case TsStreamType::kAc3:
+
306  es_parser.reset(
+
307  new EsParserAudio(pes_pid, static_cast<TsStreamType>(stream_type),
+
308  on_new_stream, on_emit_media, sbr_in_mimetype_));
+
309  pid_type = PidState::kPidAudioPes;
+
310  break;
+
311  case TsStreamType::kDvbSubtitles:
+
312  es_parser.reset(new EsParserDvb(pes_pid, on_new_stream, on_emit_text,
+
313  descriptor, descriptor_length));
+
314  pid_type = PidState::kPidTextPes;
+
315  break;
+
316  default: {
+
317  auto type = static_cast<int>(stream_type);
+
318  DCHECK(type <= 0xff);
+
319  LOG_IF(ERROR, !stream_type_logged_once_[type])
+
320  << "Ignore unsupported MPEG2TS stream type 0x" << std::hex << type
+
321  << std::dec;
+
322  stream_type_logged_once_[type] = true;
+
323  return;
+
324  }
+
325  }
+
326 
+
327  // Create the PES state here.
+
328  DVLOG(1) << "Create a new PES state";
+
329  std::unique_ptr<TsSection> pes_section_parser(
+
330  new TsSectionPes(std::move(es_parser)));
+
331  std::unique_ptr<PidState> pes_pid_state(
+
332  new PidState(pes_pid, pid_type, std::move(pes_section_parser)));
+
333  pes_pid_state->Enable();
+
334  pids_.emplace(pes_pid, std::move(pes_pid_state));
+
335 }
+
336 
+
337 void Mp2tMediaParser::OnNewStreamInfo(
+
338  uint32_t pes_pid,
+
339  std::shared_ptr<StreamInfo> new_stream_info) {
+
340  DCHECK(!new_stream_info || new_stream_info->track_id() == pes_pid);
+
341  DVLOG(1) << "OnVideoConfigChanged for pid=" << pes_pid
+
342  << ", has_info=" << (new_stream_info ? "true" : "false");
+
343 
+
344  auto pid_state = pids_.find(pes_pid);
+
345  if (pid_state == pids_.end()) {
+
346  LOG(ERROR) << "PID State for new stream not found (pid = "
+
347  << new_stream_info->track_id() << ").";
+
348  return;
+
349  }
+
350 
+
351  if (new_stream_info) {
+
352  // Set the stream configuration information for the PID.
+
353  pid_state->second->set_config(new_stream_info);
+
354  } else {
+
355  LOG(WARNING) << "Ignoring unsupported stream with pid=" << pes_pid;
+
356  pid_state->second->Disable();
+
357  }
+
358 
+
359  // Finish initialization if all streams have configs.
+
360  FinishInitializationIfNeeded();
+
361 }
+
362 
+
363 bool Mp2tMediaParser::FinishInitializationIfNeeded() {
+
364  // Nothing to be done if already initialized.
+
365  if (is_initialized_)
+
366  return true;
+
367 
+
368  // Wait for more data to come to finish initialization.
+
369  if (pids_.empty())
+
370  return true;
+
371 
+
372  std::vector<std::shared_ptr<StreamInfo>> all_stream_info;
+
373  uint32_t num_es(0);
+
374  for (const auto& pair : pids_) {
+
375  if ((pair.second->pid_type() == PidState::kPidAudioPes ||
+
376  pair.second->pid_type() == PidState::kPidVideoPes ||
+
377  pair.second->pid_type() == PidState::kPidTextPes) &&
+
378  pair.second->IsEnabled()) {
+
379  ++num_es;
+
380  if (pair.second->config())
+
381  all_stream_info.push_back(pair.second->config());
+
382  }
+
383  }
+
384  if (num_es && (all_stream_info.size() == num_es)) {
+
385  // All stream configurations have been received. Initialization can
+
386  // be completed.
+
387  init_cb_.Run(all_stream_info);
+
388  DVLOG(1) << "Mpeg2TS stream parser initialization done";
+
389  is_initialized_ = true;
+
390  }
+
391  return true;
+
392 }
+
393 
+
394 void Mp2tMediaParser::OnEmitMediaSample(
+
395  uint32_t pes_pid,
+
396  std::shared_ptr<MediaSample> new_sample) {
+
397  DCHECK(new_sample);
+
398  DVLOG(LOG_LEVEL_ES) << "OnEmitMediaSample: "
+
399  << " pid=" << pes_pid
+
400  << " size=" << new_sample->data_size()
+
401  << " dts=" << new_sample->dts()
+
402  << " pts=" << new_sample->pts();
+
403 
+
404  // Add the sample to the appropriate PID sample queue.
+
405  auto pid_state = pids_.find(pes_pid);
+
406  if (pid_state == pids_.end()) {
+
407  LOG(ERROR) << "PID State for new sample not found (pid = " << pes_pid
+
408  << ").";
+
409  return;
+
410  }
+
411  pid_state->second->media_sample_queue_.push_back(std::move(new_sample));
+
412 }
+
413 
+
414 void Mp2tMediaParser::OnEmitTextSample(uint32_t pes_pid,
+
415  std::shared_ptr<TextSample> new_sample) {
+
416  DCHECK(new_sample);
+
417  DVLOG(LOG_LEVEL_ES) << "OnEmitTextSample: "
+
418  << " pid=" << pes_pid
+
419  << " start=" << new_sample->start_time();
+
420 
+
421  // Add the sample to the appropriate PID sample queue.
+
422  auto pid_state = pids_.find(pes_pid);
+
423  if (pid_state == pids_.end()) {
+
424  LOG(ERROR) << "PID State for new sample not found (pid = "
+
425  << pes_pid << ").";
+
426  return;
+
427  }
+
428  pid_state->second->text_sample_queue_.push_back(std::move(new_sample));
+
429 }
+
430 
+
431 bool Mp2tMediaParser::EmitRemainingSamples() {
+
432  DVLOG(LOG_LEVEL_ES) << "Mp2tMediaParser::EmitRemainingBuffers";
+
433 
+
434  // No buffer should be sent until fully initialized.
+
435  if (!is_initialized_)
+
436  return true;
+
437 
+
438  // Buffer emission.
+
439  for (const auto& pid_pair : pids_) {
+
440  for (auto sample : pid_pair.second->media_sample_queue_) {
+
441  RCHECK(new_media_sample_cb_.Run(pid_pair.first, sample));
+
442  }
+
443  pid_pair.second->media_sample_queue_.clear();
+
444 
+
445  for (auto sample : pid_pair.second->text_sample_queue_) {
+
446  RCHECK(new_text_sample_cb_.Run(pid_pair.first, sample));
+
447  }
+
448  pid_pair.second->text_sample_queue_.clear();
+
449  }
+
450 
+
451  return true;
+
452 }
+
453 
+
454 } // namespace mp2t
+
455 } // namespace media
+
456 } // namespace shaka
+
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:51
+
base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
Definition: media_parser.h:53
+
base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
Definition: media_parser.h:44
+
base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
Definition: media_parser.h:35
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/d79/classshaka_1_1media_1_1H265VideoSliceHeaderParser.html b/docs/d1/d79/classshaka_1_1media_1_1H265VideoSliceHeaderParser.html index 878d2d077a..d40ead3a50 100644 --- a/docs/d1/d79/classshaka_1_1media_1_1H265VideoSliceHeaderParser.html +++ b/docs/d1/d79/classshaka_1_1media_1_1H265VideoSliceHeaderParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265VideoSliceHeaderParser Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::VideoSliceHeaderParser - -
+ + @@ -121,7 +124,7 @@ int64_t 

Public Member Functions

shaka::media::VideoSliceHeaderParser.

-

Definition at line 71 of file video_slice_header_parser.cc.

+

Definition at line 70 of file video_slice_header_parser.cc.

@@ -152,7 +155,7 @@ int64_t 
shaka::media::VideoSliceHeaderParser.

-

Definition at line 94 of file video_slice_header_parser.cc.

+

Definition at line 93 of file video_slice_header_parser.cc.

@@ -163,9 +166,7 @@ int64_t 
diff --git a/docs/d1/d79/structshaka_1_1media_1_1Scte35Event-members.html b/docs/d1/d79/structshaka_1_1media_1_1Scte35Event-members.html index 017b20b883..91f48b7341 100644 --- a/docs/d1/d79/structshaka_1_1media_1_1Scte35Event-members.html +++ b/docs/d1/d79/structshaka_1_1media_1_1Scte35Event-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d7d/webm__video__client_8cc_source.html b/docs/d1/d7d/webm__video__client_8cc_source.html index 4757558174..2d196da7df 100644 --- a/docs/d1/d7d/webm__video__client_8cc_source.html +++ b/docs/d1/d7d/webm__video__client_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_video_client.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webm_video_client.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/webm/webm_video_client.h"
6 
7 #include "packager/base/logging.h"
8 #include "packager/media/base/video_util.h"
9 #include "packager/media/codecs/av1_codec_configuration_record.h"
10 #include "packager/media/codecs/vp_codec_configuration_record.h"
11 #include "packager/media/formats/webm/webm_constants.h"
12 
13 namespace {
14 
15 // Timestamps are represented in double in WebM. Convert to uint64_t in us.
16 const uint32_t kWebMTimeScale = 1000000u;
17 
18 } // namespace
19 
20 namespace shaka {
21 namespace media {
22 
23 WebMVideoClient::WebMVideoClient() {}
24 
25 WebMVideoClient::~WebMVideoClient() {}
26 
28  pixel_width_ = -1;
29  pixel_height_ = -1;
30  crop_bottom_ = -1;
31  crop_top_ = -1;
32  crop_left_ = -1;
33  crop_right_ = -1;
34  display_width_ = -1;
35  display_height_ = -1;
36  display_unit_ = -1;
37  alpha_mode_ = -1;
38 
39  matrix_coefficients_ = -1;
40  bits_per_channel_ = -1;
41  chroma_subsampling_horz_ = -1;
42  chroma_subsampling_vert_ = -1;
43  chroma_siting_horz_ = -1;
44  chroma_siting_vert_ = -1;
45  color_range_ = -1;
46  transfer_characteristics_ = -1;
47  color_primaries_ = -1;
48 }
49 
50 std::shared_ptr<VideoStreamInfo> WebMVideoClient::GetVideoStreamInfo(
51  int64_t track_num,
52  const std::string& codec_id,
53  const std::vector<uint8_t>& codec_private,
54  bool is_encrypted) {
55  std::string codec_string;
56  Codec video_codec = kUnknownCodec;
57  if (codec_id == "V_AV1") {
58  video_codec = kCodecAV1;
59 
60  // CodecPrivate is mandatory per AV in Matroska / WebM specification.
61  // https://github.com/Matroska-Org/matroska-specification/blob/av1-mappin/codec/av1.md#codecprivate-1
62  AV1CodecConfigurationRecord av1_config;
63  if (!av1_config.Parse(codec_private)) {
64  LOG(ERROR) << "Failed to parse AV1 codec_private.";
65  return nullptr;
66  }
67  codec_string = av1_config.GetCodecString();
68  } else if (codec_id == "V_VP8") {
69  video_codec = kCodecVP8;
70  // codec_string for VP8 is parsed later.
71  } else if (codec_id == "V_VP9") {
72  video_codec = kCodecVP9;
73  // codec_string for VP9 is parsed later.
74  } else {
75  LOG(ERROR) << "Unsupported video codec_id " << codec_id;
76  return nullptr;
77  }
78 
79  if (pixel_width_ <= 0 || pixel_height_ <= 0)
80  return nullptr;
81 
82  // Set crop and display unit defaults if these elements are not present.
83  if (crop_bottom_ == -1)
84  crop_bottom_ = 0;
85 
86  if (crop_top_ == -1)
87  crop_top_ = 0;
88 
89  if (crop_left_ == -1)
90  crop_left_ = 0;
91 
92  if (crop_right_ == -1)
93  crop_right_ = 0;
94 
95  if (display_unit_ == -1)
96  display_unit_ = 0;
97 
98  uint16_t width_after_crop = pixel_width_ - (crop_left_ + crop_right_);
99  uint16_t height_after_crop = pixel_height_ - (crop_top_ + crop_bottom_);
100 
101  if (display_unit_ == 0) {
102  if (display_width_ <= 0)
103  display_width_ = width_after_crop;
104  if (display_height_ <= 0)
105  display_height_ = height_after_crop;
106  } else if (display_unit_ == 3) {
107  if (display_width_ <= 0 || display_height_ <= 0)
108  return nullptr;
109  } else {
110  LOG(ERROR) << "Unsupported display unit type " << display_unit_;
111  return nullptr;
112  }
113 
114  // Calculate sample aspect ratio.
115  uint32_t pixel_width;
116  uint32_t pixel_height;
117  DerivePixelWidthHeight(width_after_crop, height_after_crop, display_width_,
118  display_height_, &pixel_width, &pixel_height);
119 
120  // |codec_private| may be overriden later for some codecs, e.g. VP9 since for
121  // VP9, the format for MP4 and WebM are different; MP4 format is used as the
122  // intermediate format.
123  return std::make_shared<VideoStreamInfo>(
124  track_num, kWebMTimeScale, 0, video_codec, H26xStreamFormat::kUnSpecified,
125  codec_string, codec_private.data(), codec_private.size(),
126  width_after_crop, height_after_crop, pixel_width, pixel_height, 0, 0,
127  0 /* transfer_characteristics */, std::string(), is_encrypted);
128 }
129 
131  const std::vector<uint8_t>& codec_private) {
132  VPCodecConfigurationRecord vp_config;
133  vp_config.ParseWebM(codec_private);
134  if (matrix_coefficients_ != -1) {
135  vp_config.set_matrix_coefficients(matrix_coefficients_);
136  }
137  if (bits_per_channel_ != -1) {
138  vp_config.set_bit_depth(bits_per_channel_);
139  }
140  if (chroma_subsampling_horz_ != -1 && chroma_subsampling_vert_ != -1) {
141  vp_config.SetChromaSubsampling(chroma_subsampling_horz_,
142  chroma_subsampling_vert_);
143  }
144  if (chroma_siting_horz_ != -1 && chroma_siting_vert_ != -1) {
145  vp_config.SetChromaLocation(chroma_siting_horz_, chroma_siting_vert_);
146  }
147  if (color_range_ != -1) {
148  if (color_range_ == 0)
149  vp_config.set_video_full_range_flag(false);
150  else if (color_range_ == 1)
151  vp_config.set_video_full_range_flag(true);
152  // Ignore for other values.
153  }
154  if (transfer_characteristics_ != -1) {
155  vp_config.set_transfer_characteristics(transfer_characteristics_);
156  }
157  if (color_primaries_ != -1) {
158  vp_config.set_color_primaries(color_primaries_);
159  }
160  return vp_config;
161 }
162 
163 WebMParserClient* WebMVideoClient::OnListStart(int id) {
164  return id == kWebMIdColor ? this : WebMParserClient::OnListStart(id);
165 }
166 
167 bool WebMVideoClient::OnListEnd(int id) {
168  return id == kWebMIdColor ? true : WebMParserClient::OnListEnd(id);
169 }
170 
171 bool WebMVideoClient::OnUInt(int id, int64_t val) {
172  int64_t* dst = nullptr;
173 
174  switch (id) {
175  case kWebMIdPixelWidth:
176  dst = &pixel_width_;
177  break;
178  case kWebMIdPixelHeight:
179  dst = &pixel_height_;
180  break;
181  case kWebMIdPixelCropTop:
182  dst = &crop_top_;
183  break;
184  case kWebMIdPixelCropBottom:
185  dst = &crop_bottom_;
186  break;
187  case kWebMIdPixelCropLeft:
188  dst = &crop_left_;
189  break;
190  case kWebMIdPixelCropRight:
191  dst = &crop_right_;
192  break;
193  case kWebMIdDisplayWidth:
194  dst = &display_width_;
195  break;
196  case kWebMIdDisplayHeight:
197  dst = &display_height_;
198  break;
199  case kWebMIdDisplayUnit:
200  dst = &display_unit_;
201  break;
202  case kWebMIdAlphaMode:
203  dst = &alpha_mode_;
204  break;
205  case kWebMIdColorMatrixCoefficients:
206  dst = &matrix_coefficients_;
207  break;
208  case kWebMIdColorBitsPerChannel:
209  dst = &bits_per_channel_;
210  break;
211  case kWebMIdColorChromaSubsamplingHorz:
212  dst = &chroma_subsampling_horz_;
213  break;
214  case kWebMIdColorChromaSubsamplingVert:
215  dst = &chroma_subsampling_vert_;
216  break;
217  case kWebMIdColorChromaSitingHorz:
218  dst = &chroma_siting_horz_;
219  break;
220  case kWebMIdColorChromaSitingVert:
221  dst = &chroma_siting_vert_;
222  break;
223  case kWebMIdColorRange:
224  dst = &color_range_;
225  break;
226  case kWebMIdColorTransferCharacteristics:
227  dst = &transfer_characteristics_;
228  break;
229  case kWebMIdColorPrimaries:
230  dst = &color_primaries_;
231  break;
232  case kWebMIdColorMaxCLL:
233  case kWebMIdColorMaxFALL:
234  NOTIMPLEMENTED() << "HDR is not supported yet.";
235  return true;
236  default:
237  return true;
238  }
239 
240  if (*dst != -1) {
241  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified ("
242  << *dst << " and " << val << ")";
243  return false;
244  }
245 
246  *dst = val;
247  return true;
248 }
249 
250 bool WebMVideoClient::OnBinary(int id, const uint8_t* data, int size) {
251  // Accept binary fields we don't care about for now.
252  return true;
253 }
254 
255 bool WebMVideoClient::OnFloat(int id, double val) {
256  // Accept float fields we don't care about for now.
257  return true;
258 }
259 
260 } // namespace media
261 } // namespace shaka
std::shared_ptr< VideoStreamInfo > GetVideoStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, bool is_encrypted)
-
VPCodecConfigurationRecord GetVpCodecConfig(const std::vector< uint8_t > &codec_private)
-
void Reset()
Reset this object&#39;s state so it can process a new video track element.
-
Class for parsing or writing VP codec configuration record.
-
All the methods that are virtual are virtual for mocking.
- -
bool Parse(const std::vector< uint8_t > &data)
-
Class for parsing AV1 codec configuration record.
-
bool ParseWebM(const std::vector< uint8_t > &data)
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/webm/webm_video_client.h"
+
6 
+
7 #include "packager/base/logging.h"
+
8 #include "packager/media/base/video_util.h"
+
9 #include "packager/media/codecs/av1_codec_configuration_record.h"
+
10 #include "packager/media/codecs/vp_codec_configuration_record.h"
+
11 #include "packager/media/formats/webm/webm_constants.h"
+
12 
+
13 namespace {
+
14 
+
15 // Timestamps are represented in double in WebM. Convert to uint64_t in us.
+
16 const uint32_t kWebMTimeScale = 1000000u;
+
17 
+
18 } // namespace
+
19 
+
20 namespace shaka {
+
21 namespace media {
+
22 
+
23 WebMVideoClient::WebMVideoClient() {}
+
24 
+
25 WebMVideoClient::~WebMVideoClient() {}
+
26 
+ +
28  pixel_width_ = -1;
+
29  pixel_height_ = -1;
+
30  crop_bottom_ = -1;
+
31  crop_top_ = -1;
+
32  crop_left_ = -1;
+
33  crop_right_ = -1;
+
34  display_width_ = -1;
+
35  display_height_ = -1;
+
36  display_unit_ = -1;
+
37  alpha_mode_ = -1;
+
38 
+
39  matrix_coefficients_ = -1;
+
40  bits_per_channel_ = -1;
+
41  chroma_subsampling_horz_ = -1;
+
42  chroma_subsampling_vert_ = -1;
+
43  chroma_siting_horz_ = -1;
+
44  chroma_siting_vert_ = -1;
+
45  color_range_ = -1;
+
46  transfer_characteristics_ = -1;
+
47  color_primaries_ = -1;
+
48 }
+
49 
+
50 std::shared_ptr<VideoStreamInfo> WebMVideoClient::GetVideoStreamInfo(
+
51  int64_t track_num,
+
52  const std::string& codec_id,
+
53  const std::vector<uint8_t>& codec_private,
+
54  bool is_encrypted) {
+
55  std::string codec_string;
+
56  Codec video_codec = kUnknownCodec;
+
57  if (codec_id == "V_AV1") {
+
58  video_codec = kCodecAV1;
+
59 
+
60  // CodecPrivate is mandatory per AV in Matroska / WebM specification.
+
61  // https://github.com/Matroska-Org/matroska-specification/blob/av1-mappin/codec/av1.md#codecprivate-1
+
62  AV1CodecConfigurationRecord av1_config;
+
63  if (!av1_config.Parse(codec_private)) {
+
64  LOG(ERROR) << "Failed to parse AV1 codec_private.";
+
65  return nullptr;
+
66  }
+
67  codec_string = av1_config.GetCodecString();
+
68  } else if (codec_id == "V_VP8") {
+
69  video_codec = kCodecVP8;
+
70  // codec_string for VP8 is parsed later.
+
71  } else if (codec_id == "V_VP9") {
+
72  video_codec = kCodecVP9;
+
73  // codec_string for VP9 is parsed later.
+
74  } else {
+
75  LOG(ERROR) << "Unsupported video codec_id " << codec_id;
+
76  return nullptr;
+
77  }
+
78 
+
79  if (pixel_width_ <= 0 || pixel_height_ <= 0)
+
80  return nullptr;
+
81 
+
82  // Set crop and display unit defaults if these elements are not present.
+
83  if (crop_bottom_ == -1)
+
84  crop_bottom_ = 0;
+
85 
+
86  if (crop_top_ == -1)
+
87  crop_top_ = 0;
+
88 
+
89  if (crop_left_ == -1)
+
90  crop_left_ = 0;
+
91 
+
92  if (crop_right_ == -1)
+
93  crop_right_ = 0;
+
94 
+
95  if (display_unit_ == -1)
+
96  display_unit_ = 0;
+
97 
+
98  uint16_t width_after_crop = pixel_width_ - (crop_left_ + crop_right_);
+
99  uint16_t height_after_crop = pixel_height_ - (crop_top_ + crop_bottom_);
+
100 
+
101  if (display_unit_ == 0) {
+
102  if (display_width_ <= 0)
+
103  display_width_ = width_after_crop;
+
104  if (display_height_ <= 0)
+
105  display_height_ = height_after_crop;
+
106  } else if (display_unit_ == 3) {
+
107  if (display_width_ <= 0 || display_height_ <= 0)
+
108  return nullptr;
+
109  } else {
+
110  LOG(ERROR) << "Unsupported display unit type " << display_unit_;
+
111  return nullptr;
+
112  }
+
113 
+
114  // Calculate sample aspect ratio.
+
115  uint32_t pixel_width;
+
116  uint32_t pixel_height;
+
117  DerivePixelWidthHeight(width_after_crop, height_after_crop, display_width_,
+
118  display_height_, &pixel_width, &pixel_height);
+
119 
+
120  // |codec_private| may be overriden later for some codecs, e.g. VP9 since for
+
121  // VP9, the format for MP4 and WebM are different; MP4 format is used as the
+
122  // intermediate format.
+
123  return std::make_shared<VideoStreamInfo>(
+
124  track_num, kWebMTimeScale, 0, video_codec, H26xStreamFormat::kUnSpecified,
+
125  codec_string, codec_private.data(), codec_private.size(),
+
126  width_after_crop, height_after_crop, pixel_width, pixel_height, 0, 0,
+
127  0 /* transfer_characteristics */, std::string(), is_encrypted);
+
128 }
+
129 
+ +
131  const std::vector<uint8_t>& codec_private) {
+
132  VPCodecConfigurationRecord vp_config;
+
133  vp_config.ParseWebM(codec_private);
+
134  if (matrix_coefficients_ != -1) {
+
135  vp_config.set_matrix_coefficients(matrix_coefficients_);
+
136  }
+
137  if (bits_per_channel_ != -1) {
+
138  vp_config.set_bit_depth(bits_per_channel_);
+
139  }
+
140  if (chroma_subsampling_horz_ != -1 && chroma_subsampling_vert_ != -1) {
+
141  vp_config.SetChromaSubsampling(chroma_subsampling_horz_,
+
142  chroma_subsampling_vert_);
+
143  }
+
144  if (chroma_siting_horz_ != -1 && chroma_siting_vert_ != -1) {
+
145  vp_config.SetChromaLocation(chroma_siting_horz_, chroma_siting_vert_);
+
146  }
+
147  if (color_range_ != -1) {
+
148  if (color_range_ == 0)
+
149  vp_config.set_video_full_range_flag(false);
+
150  else if (color_range_ == 1)
+
151  vp_config.set_video_full_range_flag(true);
+
152  // Ignore for other values.
+
153  }
+
154  if (transfer_characteristics_ != -1) {
+
155  vp_config.set_transfer_characteristics(transfer_characteristics_);
+
156  }
+
157  if (color_primaries_ != -1) {
+
158  vp_config.set_color_primaries(color_primaries_);
+
159  }
+
160  return vp_config;
+
161 }
+
162 
+
163 WebMParserClient* WebMVideoClient::OnListStart(int id) {
+
164  return id == kWebMIdColor ? this : WebMParserClient::OnListStart(id);
+
165 }
+
166 
+
167 bool WebMVideoClient::OnListEnd(int id) {
+
168  return id == kWebMIdColor ? true : WebMParserClient::OnListEnd(id);
+
169 }
+
170 
+
171 bool WebMVideoClient::OnUInt(int id, int64_t val) {
+
172  int64_t* dst = nullptr;
+
173 
+
174  switch (id) {
+
175  case kWebMIdPixelWidth:
+
176  dst = &pixel_width_;
+
177  break;
+
178  case kWebMIdPixelHeight:
+
179  dst = &pixel_height_;
+
180  break;
+
181  case kWebMIdPixelCropTop:
+
182  dst = &crop_top_;
+
183  break;
+
184  case kWebMIdPixelCropBottom:
+
185  dst = &crop_bottom_;
+
186  break;
+
187  case kWebMIdPixelCropLeft:
+
188  dst = &crop_left_;
+
189  break;
+
190  case kWebMIdPixelCropRight:
+
191  dst = &crop_right_;
+
192  break;
+
193  case kWebMIdDisplayWidth:
+
194  dst = &display_width_;
+
195  break;
+
196  case kWebMIdDisplayHeight:
+
197  dst = &display_height_;
+
198  break;
+
199  case kWebMIdDisplayUnit:
+
200  dst = &display_unit_;
+
201  break;
+
202  case kWebMIdAlphaMode:
+
203  dst = &alpha_mode_;
+
204  break;
+
205  case kWebMIdColorMatrixCoefficients:
+
206  dst = &matrix_coefficients_;
+
207  break;
+
208  case kWebMIdColorBitsPerChannel:
+
209  dst = &bits_per_channel_;
+
210  break;
+
211  case kWebMIdColorChromaSubsamplingHorz:
+
212  dst = &chroma_subsampling_horz_;
+
213  break;
+
214  case kWebMIdColorChromaSubsamplingVert:
+
215  dst = &chroma_subsampling_vert_;
+
216  break;
+
217  case kWebMIdColorChromaSitingHorz:
+
218  dst = &chroma_siting_horz_;
+
219  break;
+
220  case kWebMIdColorChromaSitingVert:
+
221  dst = &chroma_siting_vert_;
+
222  break;
+
223  case kWebMIdColorRange:
+
224  dst = &color_range_;
+
225  break;
+
226  case kWebMIdColorTransferCharacteristics:
+
227  dst = &transfer_characteristics_;
+
228  break;
+
229  case kWebMIdColorPrimaries:
+
230  dst = &color_primaries_;
+
231  break;
+
232  case kWebMIdColorMaxCLL:
+
233  case kWebMIdColorMaxFALL:
+
234  NOTIMPLEMENTED() << "HDR is not supported yet.";
+
235  return true;
+
236  default:
+
237  return true;
+
238  }
+
239 
+
240  if (*dst != -1) {
+
241  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified ("
+
242  << *dst << " and " << val << ")";
+
243  return false;
+
244  }
+
245 
+
246  *dst = val;
+
247  return true;
+
248 }
+
249 
+
250 bool WebMVideoClient::OnBinary(int id, const uint8_t* data, int size) {
+
251  // Accept binary fields we don't care about for now.
+
252  return true;
+
253 }
+
254 
+
255 bool WebMVideoClient::OnFloat(int id, double val) {
+
256  // Accept float fields we don't care about for now.
+
257  return true;
+
258 }
+
259 
+
260 } // namespace media
+
261 } // namespace shaka
+
Class for parsing AV1 codec configuration record.
+ +
bool Parse(const std::vector< uint8_t > &data)
+
Class for parsing or writing VP codec configuration record.
+
bool ParseWebM(const std::vector< uint8_t > &data)
+ +
std::shared_ptr< VideoStreamInfo > GetVideoStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, bool is_encrypted)
+
VPCodecConfigurationRecord GetVpCodecConfig(const std::vector< uint8_t > &codec_private)
+
void Reset()
Reset this object's state so it can process a new video track element.
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/d7e/classshaka_1_1hls_1_1Tag.html b/docs/d1/d7e/classshaka_1_1hls_1_1Tag.html index 9e75fb314b..ea560d09ef 100644 --- a/docs/d1/d7e/classshaka_1_1hls_1_1Tag.html +++ b/docs/d1/d7e/classshaka_1_1hls_1_1Tag.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::hls::Tag Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/d7e/classshaka_1_1media_1_1BlockReader-members.html b/docs/d1/d7e/classshaka_1_1media_1_1BlockReader-members.html index b5d8c6ebf0..e062a33dec 100644 --- a/docs/d1/d7e/classshaka_1_1media_1_1BlockReader-members.html +++ b/docs/d1/d7e/classshaka_1_1media_1_1BlockReader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::media::BlockReader, including all inherited members.

- - + + + +
BlockReader(std::unique_ptr< FileReader > source) (defined in shaka::media::BlockReader)shaka::media::BlockReaderexplicit
Next(std::vector< std::string > *out) (defined in shaka::media::BlockReader)shaka::media::BlockReader
BlockReader() (defined in shaka::media::BlockReader)shaka::media::BlockReader
Flush()shaka::media::BlockReader
Next(std::vector< std::string > *out)shaka::media::BlockReader
PushData(const uint8_t *data, size_t data_size)shaka::media::BlockReader
diff --git a/docs/d1/d81/structshaka_1_1media_1_1H265ReferencePictureSet-members.html b/docs/d1/d81/structshaka_1_1media_1_1H265ReferencePictureSet-members.html index f353ab0104..87b629421e 100644 --- a/docs/d1/d81/structshaka_1_1media_1_1H265ReferencePictureSet-members.html +++ b/docs/d1/d81/structshaka_1_1media_1_1H265ReferencePictureSet-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d82/classshaka_1_1media_1_1WebMParserClient-members.html b/docs/d1/d82/classshaka_1_1media_1_1WebMParserClient-members.html index 7004693e43..a52eec1ee7 100644 --- a/docs/d1/d82/classshaka_1_1media_1_1WebMParserClient-members.html +++ b/docs/d1/d82/classshaka_1_1media_1_1WebMParserClient-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d83/classshaka_1_1media_1_1AV1CodecConfigurationRecord.html b/docs/d1/d83/classshaka_1_1media_1_1AV1CodecConfigurationRecord.html index f5f045a7aa..7deb0ec3b4 100644 --- a/docs/d1/d83/classshaka_1_1media_1_1AV1CodecConfigurationRecord.html +++ b/docs/d1/d83/classshaka_1_1media_1_1AV1CodecConfigurationRecord.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AV1CodecConfigurationRecord Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d84/classshaka_1_1media_1_1SingleThreadJobManager-members.html b/docs/d1/d84/classshaka_1_1media_1_1SingleThreadJobManager-members.html new file mode 100644 index 0000000000..c68bdbba8f --- /dev/null +++ b/docs/d1/d84/classshaka_1_1media_1_1SingleThreadJobManager-members.html @@ -0,0 +1,94 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::SingleThreadJobManager Member List
+
+
+ +

This is the complete list of members for shaka::media::SingleThreadJobManager, including all inherited members.

+ + + + + + + + + + + + + + +
Add(const std::string &name, std::shared_ptr< OriginHandler > handler) (defined in shaka::media::JobManager)shaka::media::JobManager
CancelJobs() (defined in shaka::media::JobManager)shaka::media::JobManager
InitializeJobs() override (defined in shaka::media::SingleThreadJobManager)shaka::media::SingleThreadJobManagervirtual
job_entries_ (defined in shaka::media::JobManager)shaka::media::JobManagerprotected
JobManager(std::unique_ptr< SyncPointQueue > sync_points) (defined in shaka::media::JobManager)shaka::media::JobManagerexplicit
JobManager(const JobManager &)=delete (defined in shaka::media::JobManager)shaka::media::JobManagerprotected
jobs_ (defined in shaka::media::JobManager)shaka::media::JobManagerprotected
operator=(const JobManager &)=delete (defined in shaka::media::JobManager)shaka::media::JobManagerprotected
RunJobs() override (defined in shaka::media::SingleThreadJobManager)shaka::media::SingleThreadJobManagervirtual
SingleThreadJobManager(std::unique_ptr< SyncPointQueue > sync_points) (defined in shaka::media::SingleThreadJobManager)shaka::media::SingleThreadJobManagerexplicit
sync_points() (defined in shaka::media::JobManager)shaka::media::JobManagerinline
sync_points_ (defined in shaka::media::JobManager)shaka::media::JobManagerprotected
~JobManager()=default (defined in shaka::media::JobManager)shaka::media::JobManagervirtual
+ + + + diff --git a/docs/d1/d87/classshaka_1_1hls_1_1MasterPlaylist.html b/docs/d1/d87/classshaka_1_1hls_1_1MasterPlaylist.html index 26310236e5..7227e6df5c 100644 --- a/docs/d1/d87/classshaka_1_1hls_1_1MasterPlaylist.html +++ b/docs/d1/d87/classshaka_1_1hls_1_1MasterPlaylist.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::hls::MasterPlaylist Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Public Member Functions

MasterPlaylist (const std::string &file_name, const std::string &default_audio_language, const std::string &default_text_language) -  -virtual bool WriteMasterPlaylist (const std::string &base_url, const std::string &output_dir, const std::list< MediaPlaylist *> &playlists) -  + MasterPlaylist (const std::string &file_name, const std::string &default_audio_language, const std::string &default_text_language, const bool is_independent_segments) +  +virtual bool WriteMasterPlaylist (const std::string &base_url, const std::string &output_dir, const std::list< MediaPlaylist * > &playlists) + 

Detailed Description

Class to generate HLS Master Playlist. Methods are virtual for mocking.

Definition at line 20 of file master_playlist.h.

Constructor & Destructor Documentation

- -

◆ MasterPlaylist()

+ +

◆ MasterPlaylist()

@@ -106,7 +109,13 @@ Public Member Functions const std::string &  - default_text_language  + default_text_language, + + + + + const bool  + is_independent_segments  @@ -124,13 +133,13 @@ Public Member Functions -

Definition at line 439 of file master_playlist.cc.

+

Definition at line 487 of file master_playlist.cc.

Member Function Documentation

- -

◆ WriteMasterPlaylist()

+ +

◆ WriteMasterPlaylist()

@@ -153,7 +162,7 @@ Public Member Functions - const std::list< MediaPlaylist *> &  + const std::list< MediaPlaylist * > &  playlists  @@ -168,16 +177,16 @@ Public Member Functions
-

Writes Master Playlist to output_dir + <name of="" playlist>="">. This assumes that base_url is used as the prefix for Media Playlists.

Parameters
+

Writes Master Playlist to output_dir + <name of playlist>. This assumes that base_url is used as the prefix for Media Playlists.

Parameters
- +
base_urlis the prefix for the Media Playlist files. This should be in URI form such that base_url+file_name is a valid HLS URI.
output_diris where the playlist files are written. This is not necessarily the same as base_url. It must be in a form that File interface can open.
output_diris where the playlist files are written. This is not necessarily the same as base_url. It must be in a form that File interface can open.
Returns
true if the playlist is updated successfully or there is no difference since the last write, false otherwise.
-

Definition at line 448 of file master_playlist.cc.

+

Definition at line 498 of file master_playlist.cc.

@@ -188,9 +197,7 @@ Public Member Functions
diff --git a/docs/d1/d8e/webm__audio__client_8cc_source.html b/docs/d1/d8e/webm__audio__client_8cc_source.html index 16552c35fe..5504bef0e4 100644 --- a/docs/d1/d8e/webm__audio__client_8cc_source.html +++ b/docs/d1/d8e/webm__audio__client_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_audio_client.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webm_audio_client.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/webm/webm_audio_client.h"
6 
7 #include "packager/base/logging.h"
8 #include "packager/media/formats/webm/webm_constants.h"
9 
10 namespace {
11 // Timestamps are represented in double in WebM. Convert to uint64_t in us.
12 const uint32_t kWebMTimeScale = 1000000u;
13 } // namespace
14 
15 namespace shaka {
16 namespace media {
17 
18 WebMAudioClient::WebMAudioClient() {
19  Reset();
20 }
21 
22 WebMAudioClient::~WebMAudioClient() {
23 }
24 
26  channels_ = -1;
27  samples_per_second_ = -1;
28  output_samples_per_second_ = -1;
29 }
30 
31 std::shared_ptr<AudioStreamInfo> WebMAudioClient::GetAudioStreamInfo(
32  int64_t track_num,
33  const std::string& codec_id,
34  const std::vector<uint8_t>& codec_private,
35  int64_t seek_preroll,
36  int64_t codec_delay,
37  const std::string& language,
38  bool is_encrypted) {
39  Codec audio_codec = kUnknownCodec;
40  if (codec_id == "A_VORBIS") {
41  audio_codec = kCodecVorbis;
42  } else if (codec_id == "A_OPUS") {
43  audio_codec = kCodecOpus;
44  } else {
45  LOG(ERROR) << "Unsupported audio codec_id " << codec_id;
46  return std::shared_ptr<AudioStreamInfo>();
47  }
48 
49  if (samples_per_second_ <= 0)
50  return std::shared_ptr<AudioStreamInfo>();
51 
52  // Set channel layout default if a Channels element was not present.
53  if (channels_ == -1)
54  channels_ = 1;
55 
56  uint32_t sampling_frequency = samples_per_second_;
57  // Always use 48kHz for OPUS. See the "Input Sample Rate" section of the
58  // spec: http://tools.ietf.org/html/draft-terriberry-oggopus-01#page-11
59  if (audio_codec == kCodecOpus) {
60  sampling_frequency = 48000;
61  }
62 
63  const uint8_t* codec_config = NULL;
64  size_t codec_config_size = 0;
65  if (codec_private.size() > 0) {
66  codec_config = &codec_private[0];
67  codec_config_size = codec_private.size();
68  }
69 
70  const uint8_t kSampleSizeInBits = 16u;
71  return std::make_shared<AudioStreamInfo>(
72  track_num, kWebMTimeScale, 0, audio_codec,
73  AudioStreamInfo::GetCodecString(audio_codec, 0), codec_config,
74  codec_config_size, kSampleSizeInBits, channels_, sampling_frequency,
75  seek_preroll < 0 ? 0 : seek_preroll, codec_delay < 0 ? 0 : codec_delay, 0,
76  0, language, is_encrypted);
77 }
78 
79 bool WebMAudioClient::OnUInt(int id, int64_t val) {
80  if (id == kWebMIdChannels) {
81  if (channels_ != -1) {
82  LOG(ERROR) << "Multiple values for id " << std::hex << id
83  << " specified. (" << channels_ << " and " << val << ")";
84  return false;
85  }
86 
87  channels_ = val;
88  }
89  return true;
90 }
91 
92 bool WebMAudioClient::OnFloat(int id, double val) {
93  double* dst = NULL;
94 
95  switch (id) {
96  case kWebMIdSamplingFrequency:
97  dst = &samples_per_second_;
98  break;
99  case kWebMIdOutputSamplingFrequency:
100  dst = &output_samples_per_second_;
101  break;
102  default:
103  return true;
104  }
105 
106  if (val <= 0)
107  return false;
108 
109  if (*dst != -1) {
110  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified ("
111  << *dst << " and " << val << ")";
112  return false;
113  }
114 
115  *dst = val;
116  return true;
117 }
118 
119 } // namespace media
120 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
std::shared_ptr< AudioStreamInfo > GetAudioStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, int64_t seek_preroll, int64_t codec_delay, const std::string &language, bool is_encrypted)
-
static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
-
void Reset()
Reset this object&#39;s state so it can process a new audio track element.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/webm/webm_audio_client.h"
+
6 
+
7 #include "packager/base/logging.h"
+
8 #include "packager/media/formats/webm/webm_constants.h"
+
9 
+
10 namespace {
+
11 // Timestamps are represented in double in WebM. Convert to uint64_t in us.
+
12 const uint32_t kWebMTimeScale = 1000000u;
+
13 } // namespace
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 
+
18 WebMAudioClient::WebMAudioClient() {
+
19  Reset();
+
20 }
+
21 
+
22 WebMAudioClient::~WebMAudioClient() {
+
23 }
+
24 
+ +
26  channels_ = -1;
+
27  samples_per_second_ = -1;
+
28  output_samples_per_second_ = -1;
+
29 }
+
30 
+
31 std::shared_ptr<AudioStreamInfo> WebMAudioClient::GetAudioStreamInfo(
+
32  int64_t track_num,
+
33  const std::string& codec_id,
+
34  const std::vector<uint8_t>& codec_private,
+
35  int64_t seek_preroll,
+
36  int64_t codec_delay,
+
37  const std::string& language,
+
38  bool is_encrypted) {
+
39  Codec audio_codec = kUnknownCodec;
+
40  if (codec_id == "A_VORBIS") {
+
41  audio_codec = kCodecVorbis;
+
42  } else if (codec_id == "A_OPUS") {
+
43  audio_codec = kCodecOpus;
+
44  } else {
+
45  LOG(ERROR) << "Unsupported audio codec_id " << codec_id;
+
46  return std::shared_ptr<AudioStreamInfo>();
+
47  }
+
48 
+
49  if (samples_per_second_ <= 0)
+
50  return std::shared_ptr<AudioStreamInfo>();
+
51 
+
52  // Set channel layout default if a Channels element was not present.
+
53  if (channels_ == -1)
+
54  channels_ = 1;
+
55 
+
56  uint32_t sampling_frequency = samples_per_second_;
+
57  // Always use 48kHz for OPUS. See the "Input Sample Rate" section of the
+
58  // spec: http://tools.ietf.org/html/draft-terriberry-oggopus-01#page-11
+
59  if (audio_codec == kCodecOpus) {
+
60  sampling_frequency = 48000;
+
61  }
+
62 
+
63  const uint8_t* codec_config = NULL;
+
64  size_t codec_config_size = 0;
+
65  if (codec_private.size() > 0) {
+
66  codec_config = &codec_private[0];
+
67  codec_config_size = codec_private.size();
+
68  }
+
69 
+
70  const uint8_t kSampleSizeInBits = 16u;
+
71  return std::make_shared<AudioStreamInfo>(
+
72  track_num, kWebMTimeScale, 0, audio_codec,
+
73  AudioStreamInfo::GetCodecString(audio_codec, 0), codec_config,
+
74  codec_config_size, kSampleSizeInBits, channels_, sampling_frequency,
+
75  seek_preroll < 0 ? 0 : seek_preroll, codec_delay < 0 ? 0 : codec_delay, 0,
+
76  0, language, is_encrypted);
+
77 }
+
78 
+
79 bool WebMAudioClient::OnUInt(int id, int64_t val) {
+
80  if (id == kWebMIdChannels) {
+
81  if (channels_ != -1) {
+
82  LOG(ERROR) << "Multiple values for id " << std::hex << id
+
83  << " specified. (" << channels_ << " and " << val << ")";
+
84  return false;
+
85  }
+
86 
+
87  channels_ = val;
+
88  }
+
89  return true;
+
90 }
+
91 
+
92 bool WebMAudioClient::OnFloat(int id, double val) {
+
93  double* dst = NULL;
+
94 
+
95  switch (id) {
+
96  case kWebMIdSamplingFrequency:
+
97  dst = &samples_per_second_;
+
98  break;
+
99  case kWebMIdOutputSamplingFrequency:
+
100  dst = &output_samples_per_second_;
+
101  break;
+
102  default:
+
103  return true;
+
104  }
+
105 
+
106  if (val <= 0)
+
107  return false;
+
108 
+
109  if (*dst != -1) {
+
110  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified ("
+
111  << *dst << " and " << val << ")";
+
112  return false;
+
113  }
+
114 
+
115  *dst = val;
+
116  return true;
+
117 }
+
118 
+
119 } // namespace media
+
120 } // namespace shaka
+
static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
+
std::shared_ptr< AudioStreamInfo > GetAudioStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, int64_t seek_preroll, int64_t codec_delay, const std::string &language, bool is_encrypted)
+
void Reset()
Reset this object's state so it can process a new audio track element.
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/d8f/retired__flags_8h_source.html b/docs/d1/d8f/retired__flags_8h_source.html index 313cd1da1c..e863c69350 100644 --- a/docs/d1/d8f/retired__flags_8h_source.html +++ b/docs/d1/d8f/retired__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/retired_flags.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
retired_flags.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include <gflags/gflags.h>
8 
9 DECLARE_string(profile);
10 DECLARE_bool(single_segment);
11 DECLARE_bool(webm_subsample_encryption);
12 DECLARE_double(availability_time_offset);
13 DECLARE_string(playready_key_id);
14 DECLARE_string(playready_key);
15 DECLARE_bool(mp4_use_decoding_timestamp_in_timeline);
16 DECLARE_int32(num_subsegments_per_sidx);
17 DECLARE_bool(generate_widevine_pssh);
18 DECLARE_bool(generate_playready_pssh);
19 DECLARE_bool(generate_common_pssh);
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include <gflags/gflags.h>
+
8 
+
9 DECLARE_string(profile);
+
10 DECLARE_bool(single_segment);
+
11 DECLARE_bool(webm_subsample_encryption);
+
12 DECLARE_double(availability_time_offset);
+
13 DECLARE_string(playready_key_id);
+
14 DECLARE_string(playready_key);
+
15 DECLARE_bool(mp4_use_decoding_timestamp_in_timeline);
+
16 DECLARE_int32(num_subsegments_per_sidx);
+
17 DECLARE_bool(generate_widevine_pssh);
+
18 DECLARE_bool(generate_playready_pssh);
+
19 DECLARE_bool(generate_common_pssh);
+
diff --git a/docs/d1/d91/classshaka_1_1media_1_1H26xBitReader-members.html b/docs/d1/d91/classshaka_1_1media_1_1H26xBitReader-members.html index dbd2e58131..f01c7e93b0 100644 --- a/docs/d1/d91/classshaka_1_1media_1_1H26xBitReader-members.html +++ b/docs/d1/d91/classshaka_1_1media_1_1H26xBitReader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d95/structshaka_1_1WidevineEncryptionParams-members.html b/docs/d1/d95/structshaka_1_1WidevineEncryptionParams-members.html index 2d5817cf2a..aacf5d174c 100644 --- a/docs/d1/d95/structshaka_1_1WidevineEncryptionParams-members.html +++ b/docs/d1/d95/structshaka_1_1WidevineEncryptionParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d9d/classshaka_1_1media_1_1ByteQueue-members.html b/docs/d1/d9d/classshaka_1_1media_1_1ByteQueue-members.html index ecda77a041..98090de901 100644 --- a/docs/d1/d9d/classshaka_1_1media_1_1ByteQueue-members.html +++ b/docs/d1/d9d/classshaka_1_1media_1_1ByteQueue-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/d9d/tracks__builder_8h_source.html b/docs/d1/d9d/tracks__builder_8h_source.html index d5d20dbb8d..1b2c52410a 100644 --- a/docs/d1/d9d/tracks__builder_8h_source.html +++ b/docs/d1/d9d/tracks__builder_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/tracks_builder.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
tracks_builder.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_TRACKS_BUILDER_H_
6 #define PACKAGER_MEDIA_FORMATS_WEBM_TRACKS_BUILDER_H_
7 
8 #include <stdint.h>
9 
10 #include <list>
11 #include <string>
12 #include <vector>
13 
14 #include "packager/base/macros.h"
15 
16 namespace shaka {
17 namespace media {
18 
20  public:
21  // If |allow_invalid_values| is false, some AddTrack() parameters will be
22  // basically checked and will assert if out of valid range. |codec_id|,
23  // |name|, |language| and any device-specific constraints are not checked.
24  explicit TracksBuilder(bool allow_invalid_values);
25  TracksBuilder(); // Sets |allow_invalid_values| to false.
26  ~TracksBuilder();
27 
28  // Only a non-negative |default_duration| will result in a serialized
29  // kWebMIdDefaultDuration element. Note, 0 is allowed here for testing only
30  // if |allow_invalid_values_| is true, since it is an illegal value for
31  // DefaultDuration. Similar applies to |audio_channels|,
32  // |audio_sampling_frequency|, |video_pixel_width| and |video_pixel_height|.
33  void AddVideoTrack(int track_num,
34  uint64_t track_uid,
35  const std::string& codec_id,
36  const std::string& name,
37  const std::string& language,
38  int default_duration,
39  int video_pixel_width,
40  int video_pixel_height);
41  void AddAudioTrack(int track_num,
42  uint64_t track_uid,
43  const std::string& codec_id,
44  const std::string& name,
45  const std::string& language,
46  int default_duration,
47  int audio_channels,
48  double audio_sampling_frequency);
49  void AddTextTrack(int track_num,
50  uint64_t track_uid,
51  const std::string& codec_id,
52  const std::string& name,
53  const std::string& language);
54 
55  std::vector<uint8_t> Finish();
56 
57  private:
58  void AddTrackInternal(int track_num,
59  int track_type,
60  uint64_t track_uid,
61  const std::string& codec_id,
62  const std::string& name,
63  const std::string& language,
64  int default_duration,
65  int video_pixel_width,
66  int video_pixel_height,
67  int audio_channels,
68  double audio_sampling_frequency);
69  int GetTracksSize() const;
70  int GetTracksPayloadSize() const;
71  void WriteTracks(uint8_t* buffer, int buffer_size) const;
72 
73  class Track {
74  public:
75  Track(int track_num,
76  int track_type,
77  uint64_t track_uid,
78  const std::string& codec_id,
79  const std::string& name,
80  const std::string& language,
81  int default_duration,
82  int video_pixel_width,
83  int video_pixel_height,
84  int audio_channels,
85  double audio_sampling_frequency,
86  bool allow_invalid_values);
87 
88  int GetSize() const;
89  void Write(uint8_t** buf, int* buf_size) const;
90 
91  private:
92  int GetPayloadSize() const;
93  int GetVideoPayloadSize() const;
94  int GetAudioPayloadSize() const;
95 
96  int track_num_;
97  int track_type_;
98  int track_uid_;
99  std::string codec_id_;
100  std::string name_;
101  std::string language_;
102  int default_duration_;
103  int video_pixel_width_;
104  int video_pixel_height_;
105  int audio_channels_;
106  double audio_sampling_frequency_;
107  };
108 
109  typedef std::list<Track> TrackList;
110  TrackList tracks_;
111  bool allow_invalid_values_;
112 
113  DISALLOW_COPY_AND_ASSIGN(TracksBuilder);
114 };
115 
116 } // namespace media
117 } // namespace shaka
118 
119 #endif // PACKAGER_MEDIA_FORMATS_WEBM_TRACKS_BUILDER_H_
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_TRACKS_BUILDER_H_
+
6 #define PACKAGER_MEDIA_FORMATS_WEBM_TRACKS_BUILDER_H_
+
7 
+
8 #include <stdint.h>
+
9 
+
10 #include <list>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/base/macros.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+ +
20  public:
+
21  // If |allow_invalid_values| is false, some AddTrack() parameters will be
+
22  // basically checked and will assert if out of valid range. |codec_id|,
+
23  // |name|, |language| and any device-specific constraints are not checked.
+
24  explicit TracksBuilder(bool allow_invalid_values);
+
25  TracksBuilder(); // Sets |allow_invalid_values| to false.
+
26  ~TracksBuilder();
+
27 
+
28  // Only a non-negative |default_duration| will result in a serialized
+
29  // kWebMIdDefaultDuration element. Note, 0 is allowed here for testing only
+
30  // if |allow_invalid_values_| is true, since it is an illegal value for
+
31  // DefaultDuration. Similar applies to |audio_channels|,
+
32  // |audio_sampling_frequency|, |video_pixel_width| and |video_pixel_height|.
+
33  void AddVideoTrack(int track_num,
+
34  uint64_t track_uid,
+
35  const std::string& codec_id,
+
36  const std::string& name,
+
37  const std::string& language,
+
38  int default_duration,
+
39  int video_pixel_width,
+
40  int video_pixel_height);
+
41  void AddAudioTrack(int track_num,
+
42  uint64_t track_uid,
+
43  const std::string& codec_id,
+
44  const std::string& name,
+
45  const std::string& language,
+
46  int default_duration,
+
47  int audio_channels,
+
48  double audio_sampling_frequency);
+
49  void AddTextTrack(int track_num,
+
50  uint64_t track_uid,
+
51  const std::string& codec_id,
+
52  const std::string& name,
+
53  const std::string& language);
+
54 
+
55  std::vector<uint8_t> Finish();
+
56 
+
57  private:
+
58  void AddTrackInternal(int track_num,
+
59  int track_type,
+
60  uint64_t track_uid,
+
61  const std::string& codec_id,
+
62  const std::string& name,
+
63  const std::string& language,
+
64  int default_duration,
+
65  int video_pixel_width,
+
66  int video_pixel_height,
+
67  int audio_channels,
+
68  double audio_sampling_frequency);
+
69  int GetTracksSize() const;
+
70  int GetTracksPayloadSize() const;
+
71  void WriteTracks(uint8_t* buffer, int buffer_size) const;
+
72 
+
73  class Track {
+
74  public:
+
75  Track(int track_num,
+
76  int track_type,
+
77  uint64_t track_uid,
+
78  const std::string& codec_id,
+
79  const std::string& name,
+
80  const std::string& language,
+
81  int default_duration,
+
82  int video_pixel_width,
+
83  int video_pixel_height,
+
84  int audio_channels,
+
85  double audio_sampling_frequency,
+
86  bool allow_invalid_values);
+
87 
+
88  int GetSize() const;
+
89  void Write(uint8_t** buf, int* buf_size) const;
+
90 
+
91  private:
+
92  int GetPayloadSize() const;
+
93  int GetVideoPayloadSize() const;
+
94  int GetAudioPayloadSize() const;
+
95 
+
96  int track_num_;
+
97  int track_type_;
+
98  int track_uid_;
+
99  std::string codec_id_;
+
100  std::string name_;
+
101  std::string language_;
+
102  int default_duration_;
+
103  int video_pixel_width_;
+
104  int video_pixel_height_;
+
105  int audio_channels_;
+
106  double audio_sampling_frequency_;
+
107  };
+
108 
+
109  typedef std::list<Track> TrackList;
+
110  TrackList tracks_;
+
111  bool allow_invalid_values_;
+
112 
+
113  DISALLOW_COPY_AND_ASSIGN(TracksBuilder);
+
114 };
+
115 
+
116 } // namespace media
+
117 } // namespace shaka
+
118 
+
119 #endif // PACKAGER_MEDIA_FORMATS_WEBM_TRACKS_BUILDER_H_
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/d9e/structshaka_1_1media_1_1mp4_1_1CodecConfiguration-members.html b/docs/d1/d9e/structshaka_1_1media_1_1mp4_1_1CodecConfiguration-members.html index 4fc0cc74b0..9645c64636 100644 --- a/docs/d1/d9e/structshaka_1_1media_1_1mp4_1_1CodecConfiguration-members.html +++ b/docs/d1/d9e/structshaka_1_1media_1_1mp4_1_1CodecConfiguration-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/da1/classshaka_1_1media_1_1mp4_1_1BoxBuffer.html b/docs/d1/da1/classshaka_1_1media_1_1mp4_1_1BoxBuffer.html index 7bbb8e041c..5227e29abd 100644 --- a/docs/d1/da1/classshaka_1_1media_1_1mp4_1_1BoxBuffer.html +++ b/docs/d1/da1/classshaka_1_1media_1_1mp4_1_1BoxBuffer.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::BoxBuffer Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
ReadWriteVector (   bool ReadWriteString (std::string *str, size_t size)   + +bool ReadWriteCString (std::string *str) +  bool ReadWriteFourCC (FourCC *fourcc)   @@ -135,7 +141,7 @@ bool ReadWriteInt64 (i  

Detailed Description

-

Class for MP4 box I/O. Box I/O is symmetric and exclusive, so we can define a single method to do either reading or writing box objects. BoxBuffer wraps either BoxReader for reading or BufferWriter for writing. Thus it is capable of doing either reading or writing, but not both.

+

Class for MP4 box I/O. Box I/O is symmetric and exclusive, so we can define a single method to do either reading or writing box objects. BoxBuffer wraps either BoxReader for reading or BufferWriter for writing. Thus it is capable of doing either reading or writing, but not both.

Definition at line 25 of file box_buffer.h.

Constructor & Destructor Documentation

@@ -267,7 +273,7 @@ bool ReadWriteInt64 (i
Returns
true on success, false otherwise.
-

Definition at line 189 of file box_buffer.h.

+

Definition at line 199 of file box_buffer.h.

@@ -323,7 +329,7 @@ bool ReadWriteInt64 (i

Prepare child boxes for reading/writing.

Returns
true on success, false otherwise.
-

Definition at line 157 of file box_buffer.h.

+

Definition at line 167 of file box_buffer.h.

@@ -351,7 +357,7 @@ bool ReadWriteInt64 (i
Returns
A pointer to the inner reader object.
-

Definition at line 198 of file box_buffer.h.

+

Definition at line 208 of file box_buffer.h.

@@ -408,7 +414,7 @@ bool ReadWriteInt64 (i

Read/write child box.

Returns
true on success, false otherwise.
-

Definition at line 166 of file box_buffer.h.

+

Definition at line 176 of file box_buffer.h.

@@ -549,7 +555,7 @@ bool ReadWriteInt64 (i

Read/write child box if exists.

Returns
true on success, false otherwise.
-

Definition at line 177 of file box_buffer.h.

+

Definition at line 187 of file box_buffer.h.

@@ -577,7 +583,7 @@ bool ReadWriteInt64 (i
Returns
A pointer to the inner writer object.
-

Definition at line 200 of file box_buffer.h.

+

Definition at line 210 of file box_buffer.h.

@@ -587,9 +593,7 @@ bool ReadWriteInt64 (i diff --git a/docs/d1/da1/structshaka_1_1media_1_1wvm_1_1DemuxStreamIdMediaSample.html b/docs/d1/da1/structshaka_1_1media_1_1wvm_1_1DemuxStreamIdMediaSample.html index a887c0386b..dc2c616b80 100644 --- a/docs/d1/da1/structshaka_1_1media_1_1wvm_1_1DemuxStreamIdMediaSample.html +++ b/docs/d1/da1/structshaka_1_1media_1_1wvm_1_1DemuxStreamIdMediaSample.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::wvm::DemuxStreamIdMediaSample Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/da2/classshaka_1_1media_1_1NalUnitToByteStreamConverter-members.html b/docs/d1/da2/classshaka_1_1media_1_1NalUnitToByteStreamConverter-members.html index 5a9aab1b76..0983446c3b 100644 --- a/docs/d1/da2/classshaka_1_1media_1_1NalUnitToByteStreamConverter-members.html +++ b/docs/d1/da2/classshaka_1_1media_1_1NalUnitToByteStreamConverter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/da5/classshaka_1_1media_1_1VPCodecConfigurationRecord.html b/docs/d1/da5/classshaka_1_1media_1_1VPCodecConfigurationRecord.html index 900be49c45..811b48f943 100644 --- a/docs/d1/da5/classshaka_1_1media_1_1VPCodecConfigurationRecord.html +++ b/docs/d1/da5/classshaka_1_1media_1_1VPCodecConfigurationRecord.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::VPCodecConfigurationRecord Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Public Types

enum  ChromaSubsampling {
-  CHROMA_420_VERTICAL = 0, -CHROMA_420_COLLOCATED_WITH_LUMA = 1, -CHROMA_422 = 2, -CHROMA_444 = 3, -
+  CHROMA_420_VERTICAL = 0 +, CHROMA_420_COLLOCATED_WITH_LUMA = 1 +, CHROMA_422 = 2 +, CHROMA_444 = 3 +,
  CHROMA_440 = 4
}   -enum  ChromaSitingValues { kUnspecified = 0, -kLeftCollocated = 1, -kTopCollocated = kLeftCollocated, -kHalf = 2 +enum  ChromaSitingValues { kUnspecified = 0 +, kLeftCollocated = 1 +, kTopCollocated = kLeftCollocated +, kHalf = 2 }   @@ -349,9 +352,7 @@ uint8_t 
chroma_location diff --git a/docs/d1/dad/classshaka_1_1media_1_1Demuxer-members.html b/docs/d1/dad/classshaka_1_1media_1_1Demuxer-members.html index f27984f2b2..6c9605944f 100644 --- a/docs/d1/dad/classshaka_1_1media_1_1Demuxer-members.html +++ b/docs/d1/dad/classshaka_1_1media_1_1Demuxer-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline Cancel() overrideshaka::media::Demuxervirtual - Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic + Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic container_name()shaka::media::Demuxerinline Demuxer(const std::string &file_name)shaka::media::Demuxerexplicit Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected @@ -106,9 +109,7 @@ $(function() {
diff --git a/docs/d1/db0/structshaka_1_1media_1_1mp4_1_1VideoMediaHeader.html b/docs/d1/db0/structshaka_1_1media_1_1mp4_1_1VideoMediaHeader.html index 85ffbaa240..961aafabc3 100644 --- a/docs/d1/db0/structshaka_1_1media_1_1mp4_1_1VideoMediaHeader.html +++ b/docs/d1/db0/structshaka_1_1media_1_1mp4_1_1VideoMediaHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::VideoMediaHeader Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -130,7 +133,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 578 of file box_definitions.h.

+

Definition at line 591 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -158,7 +161,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2014 of file box_definitions.cc.

+

Definition at line 2074 of file box_definitions.cc.

@@ -169,9 +172,7 @@ Additional Inherited Members diff --git a/docs/d1/db2/decoder__configuration__record_8h_source.html b/docs/d1/db2/decoder__configuration__record_8h_source.html index a78407f82a..943413b114 100644 --- a/docs/d1/db2/decoder__configuration__record_8h_source.html +++ b/docs/d1/db2/decoder__configuration__record_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/decoder_configuration_record.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
decoder_configuration_record.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CODECS_DECODER_CONFIGURATION_RECORD_H_
8 #define PACKAGER_MEDIA_CODECS_DECODER_CONFIGURATION_RECORD_H_
9 
10 #include <vector>
11 
12 #include "packager/base/logging.h"
13 #include "packager/base/macros.h"
14 #include "packager/media/codecs/nalu_reader.h"
15 
16 namespace shaka {
17 namespace media {
18 
19 // Defines a base class for decoder configuration record.
21  public:
22  virtual ~DecoderConfigurationRecord();
23 
27  bool Parse(const std::vector<uint8_t>& data) {
28  return Parse(data.data(), data.size());
29  }
30 
34  bool Parse(const uint8_t* data, size_t data_size);
35 
37  uint8_t nalu_length_size() const { return nalu_length_size_; }
38 
40  size_t nalu_count() const { return nalu_.size(); }
41 
44  const Nalu& nalu(size_t i) const { return nalu_[i]; }
45 
47  uint8_t transfer_characteristics() const { return transfer_characteristics_; }
48 
49  protected:
51 
53  void AddNalu(const Nalu& nalu);
54 
56  const uint8_t* data() const { return data_.data(); }
57 
59  size_t data_size() const { return data_.size(); }
60 
63  DCHECK(nalu_length_size <= 2 || nalu_length_size == 4);
64  nalu_length_size_ = nalu_length_size;
65  }
66 
69  transfer_characteristics_ = transfer_characteristics;
70  }
71 
72  private:
73  // Performs the actual parsing of the data.
74  virtual bool ParseInternal() = 0;
75 
76  // Contains a copy of the data. This manages the pointer lifetime so the
77  // extracted Nalu can accessed.
78  std::vector<uint8_t> data_;
79  std::vector<Nalu> nalu_;
80  uint8_t nalu_length_size_ = 0;
81 
82  // Indicates the opto-electronic transfer characteristics of the source
83  // picture, which can be used to determine whether the video is HDR or SDR.
84  // The parameter is extracted from SPS.
85  uint8_t transfer_characteristics_ = 0;
86 
87  DISALLOW_COPY_AND_ASSIGN(DecoderConfigurationRecord);
88 };
89 
90 } // namespace media
91 } // namespace shaka
92 
93 #endif // PACKAGER_MEDIA_CODECS_DECODER_CONFIGURATION_RECORD_H_
- -
void AddNalu(const Nalu &nalu)
Adds the given Nalu to the configuration.
- -
All the methods that are virtual are virtual for mocking.
-
void set_transfer_characteristics(uint8_t transfer_characteristics)
Sets the transfer characteristics.
-
void set_nalu_length_size(uint8_t nalu_length_size)
Sets the size of the NAL unit length field.
-
bool Parse(const std::vector< uint8_t > &data)
- - - - - +
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_DECODER_CONFIGURATION_RECORD_H_
+
8 #define PACKAGER_MEDIA_CODECS_DECODER_CONFIGURATION_RECORD_H_
+
9 
+
10 #include <vector>
+
11 
+
12 #include "packager/base/logging.h"
+
13 #include "packager/base/macros.h"
+
14 #include "packager/media/codecs/nalu_reader.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+
19 // Defines a base class for decoder configuration record.
+ +
21  public:
+
22  virtual ~DecoderConfigurationRecord();
+
23 
+
27  bool Parse(const std::vector<uint8_t>& data) {
+
28  return Parse(data.data(), data.size());
+
29  }
+
30 
+
34  bool Parse(const uint8_t* data, size_t data_size);
+
35 
+
37  uint8_t nalu_length_size() const { return nalu_length_size_; }
+
38 
+
40  size_t nalu_count() const { return nalu_.size(); }
+
41 
+
44  const Nalu& nalu(size_t i) const { return nalu_[i]; }
+
45 
+
47  uint8_t transfer_characteristics() const { return transfer_characteristics_; }
+
48 
+
49  protected:
+ +
51 
+
53  void AddNalu(const Nalu& nalu);
+
54 
+
56  const uint8_t* data() const { return data_.data(); }
+
57 
+
59  size_t data_size() const { return data_.size(); }
+
60 
+ +
63  DCHECK(nalu_length_size <= 2 || nalu_length_size == 4);
+
64  nalu_length_size_ = nalu_length_size;
+
65  }
+
66 
+ +
69  transfer_characteristics_ = transfer_characteristics;
+
70  }
+
71 
+
72  private:
+
73  // Performs the actual parsing of the data.
+
74  virtual bool ParseInternal() = 0;
+
75 
+
76  // Contains a copy of the data. This manages the pointer lifetime so the
+
77  // extracted Nalu can accessed.
+
78  std::vector<uint8_t> data_;
+
79  std::vector<Nalu> nalu_;
+
80  uint8_t nalu_length_size_ = 0;
+
81 
+
82  // Indicates the opto-electronic transfer characteristics of the source
+
83  // picture, which can be used to determine whether the video is HDR or SDR.
+
84  // The parameter is extracted from SPS.
+
85  uint8_t transfer_characteristics_ = 0;
+
86 
+
87  DISALLOW_COPY_AND_ASSIGN(DecoderConfigurationRecord);
+
88 };
+
89 
+
90 } // namespace media
+
91 } // namespace shaka
+
92 
+
93 #endif // PACKAGER_MEDIA_CODECS_DECODER_CONFIGURATION_RECORD_H_
+ + + + +
void AddNalu(const Nalu &nalu)
Adds the given Nalu to the configuration.
+
void set_transfer_characteristics(uint8_t transfer_characteristics)
Sets the transfer characteristics.
+
bool Parse(const std::vector< uint8_t > &data)
+
void set_nalu_length_size(uint8_t nalu_length_size)
Sets the size of the NAL unit length field.
+ + + + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/dba/classshaka_1_1media_1_1mp2t_1_1AudioHeader.html b/docs/d1/dba/classshaka_1_1media_1_1mp2t_1_1AudioHeader.html index fedaae0b58..42841ab4b1 100644 --- a/docs/d1/dba/classshaka_1_1media_1_1mp2t_1_1AudioHeader.html +++ b/docs/d1/dba/classshaka_1_1media_1_1mp2t_1_1AudioHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::AudioHeader Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
-shaka::media::mp2t::Ac3Header -shaka::media::mp2t::AdtsHeader - -
+shaka::media::mp2t::Ac3Header +shaka::media::mp2t::AdtsHeader +shaka::media::mp2t::Mpeg1Header + + @@ -140,7 +144,7 @@ Public Member Functions
Returns
true if successful, false otherwise.
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -168,7 +172,7 @@ Public Member Functions

Should only be called after a successful Parse.

Returns
the size of frame (header + payload).
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -207,7 +211,7 @@ Public Member Functions

Obtain the size of the frame from the header data without doing a full Parse.

Returns
the size of the frame (header + payload).
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -235,7 +239,7 @@ Public Member Functions

Should only be called after a successful Parse.

Returns
The size of audio header.
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -263,7 +267,7 @@ Public Member Functions @@ -291,7 +295,7 @@ Public Member Functions

Should only be called after a successful Parse.

Returns
Number of channels for this frame.
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -319,7 +323,7 @@ Public Member Functions

Should only be called after a successful Parse.

Returns
The audio profile for this frame. Only meaningful for AAC.
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -347,7 +351,7 @@ Public Member Functions @@ -375,7 +379,7 @@ Public Member Functions

Should only be called after a successful Parse.

Returns
The sampling frequency for this frame.
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -410,7 +414,7 @@ Public Member Functions
Returns
true if corresponds to a syncword.
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -456,7 +460,7 @@ Public Member Functions
Returns
true if successful, false otherwise.
-

Implemented in shaka::media::mp2t::Ac3Header, and shaka::media::mp2t::AdtsHeader.

+

Implemented in shaka::media::mp2t::Mpeg1Header, shaka::media::mp2t::AdtsHeader, and shaka::media::mp2t::Ac3Header.

@@ -466,9 +470,7 @@ Public Member Functions diff --git a/docs/d1/dba/classshaka_1_1media_1_1mp2t_1_1AudioHeader.png b/docs/d1/dba/classshaka_1_1media_1_1mp2t_1_1AudioHeader.png index f4e62dd93dcfbb24dda55927e0c62d5b8b79c7b3..50c69334b958f7dd91f63d0baa9b6207d1b1a20c 100644 GIT binary patch literal 1403 zcmeAS@N?(olHy`uVBq!ia0y~yU@8T&12~w0q{sE*Q$R{0z$e7@|Ns9$=8HF9OZyK^ z0J6aNz<~p-opOQ!Ag+2X!R&D%NA%^#2J^W$xu|~swRqFlw$r!QBwgOP!*@g8Z1q`rzeSjCSTz(+ z*s|q!w&faiGtEU!9ur>8*phSm;iT7=TW`DE3V#(Ao-2D`=ZSFL9OKta>7@r(J9RDI z^dsIVQ1hzQ*T?HC7Co6zmIHLDb!z+FTTvVG{!Ms2#Y6Den+WkGap~N1w`9c{)NA@I z>vp?s)et;!O=v2+w%JsdoV2(`5jSZJ`<%6C+tNXQMTA!psRqo$HGqr66`-Ef<)jn=YowqYd zcfS8EtA@=Vzi!P^YhKH2!M=^}0K=BU;J}PYUz;O)z;Z(=1KR>wByn&c_a#cSbu%O| zocWv2WB^pa2~uE^JZp_?17k+(T4n==vpYP~-vZ-6IR_-vITtAO7Q0!<5e8P=4$==& zENkq0Ib~VqtX=F6lwyja3p5(~J~A=RVT@+KV93XM!7xst!8qYHgVnKxK+Mfjz?LKH zaNI(~;dn(O!?}jF%r7L`nO;cf3mlLH8TL2;h*_B|n78pQNS5JRki5r%Asv`-N_w0b zYmQm;J-$BkSfR}RKIh)Y7XPGsoq8vga6V$4w8XpMVnCdN=PR*jbx+yk*D5c0ZdiG~ zl7RExM3{SUt^YDvC3NRh+qE)n)t)iad_`l|-+PnLrq2Ckvd_mK{XuVAv!7J*^Mk+TJ1?Yx4oVlq3-D}llJPIm8X@G|L1}NYmcB)Ixp>`x3AcDCr9*u zVaKw%nvH=c_x@Xvv-jaAv(+AMs@HPM`_(u-FFX9c_E+a}mE!G#_dP;6ubTL##9BT5 zb>nB;cdu=ScKwum=GpY)_4I9X_ubd6dT?vT7M)Vfbv`GqssD3(>^V(i(xU6@O81`@ zId**O`z2b=TYWd*+iA5Y>8|(9tZPSwT+02+PCr@g!|$GY()gIL>fe|DF7Nm+dVZoz z*V^AFcEzW9)%;coy}GL{GwJoJ^Sj?J&riAicEjy5Nu#s!pW1!ZxRc9_TG!{y&CM2k zIm2WB2br6mo*!Rlw*PfpmRqw)e$T|L{fD=CZq6$|+I&r?)-*aZ_Ure+KLVS#1->-g zZNKA9RiWa0*PFjuFRqXNzS}2thIw!((20|yr@wnKmG8Gn^xDH=yFY(!_q|>BvAMdk z_0!jtzMsn4{{}7#_>{RSt37v4+U<>6-&aR|H@W?pPrA zzDjgQ!R(Uh{eJn6w@se(==y8fZIR2~X8*Ui$}Ritb>^WqskIk>-I!UbpSrpoz6U`b6L&PS%FJ* z%-`nBw$#owTe2lJEq9;pQk@>t3q0Xl?S4AiNBn;~DP_^0zV1uU+OqEDhc0*gDRpu) zH`fE78^);y?%&gH%dy>U+okIx1MFM(=5CCyC`hB z_si{k5yvBy@*Y0xu`2w@RAD-Q=DGE02H1+E^9ACAtSyn*RK=LDt)eF01ldVn+mTrlPI(;`b@2K)0T zrxkcG7PygtkEvhs)Li<#2uy4%nWXa9VylSfuR^CT6-(tM9+QmW47VUP&!^Y#d0v{Z zf5YyHmrHn89-g&u)%U~awz=Jy{Ap^=t8e|!KYM9T+H!oBv#4dM<%LXVA1mpagJn^@Qv{aW~c;{(4{S&=#YhqW4!7ey%&0;e6`)rk#5;%KlxfSu-W| z#?IYYns=(s^{>Ahdfy@|`S6>N>l545I;(_UJ6?-<_ioDj)Zkm!H@1I%x#UXmlxVZr zXM581s}sM<8&A+=yuP&f@5_CMW8R#*KjqWfoSwe+&yv&E@44+Ib=voLZQ7PgY0ACZ zcC9-bt$EDvXWz4jjmA%_Z$9~!_FVq#a_blD+RG;2d~@cY*}a&iv%lZD?!G%)#rw5# z(7x%u^N%V2FVdQ&MBb@0KilRD*ylh diff --git a/docs/d1/dbe/classshaka_1_1media_1_1PlayReadyKeySource-members.html b/docs/d1/dbe/classshaka_1_1media_1_1PlayReadyKeySource-members.html index 86b2ae6afb..ed33dd6645 100644 --- a/docs/d1/dbe/classshaka_1_1media_1_1PlayReadyKeySource-members.html +++ b/docs/d1/dbe/classshaka_1_1media_1_1PlayReadyKeySource-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

Public Member Functions

- + +/* @license-end */
GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) overrideshaka::media::PlayReadyKeySourcevirtual GetKey(const std::string &stream_label, EncryptionKey *key) overrideshaka::media::PlayReadyKeySourcevirtual GetKey(const std::vector< uint8_t > &key_id, EncryptionKey *key) overrideshaka::media::PlayReadyKeySourcevirtual - KeySource(int protection_systems_flags, FourCC protection_scheme) (defined in shaka::media::KeySource)shaka::media::KeySource - PlayReadyKeySource(const std::string &server_url, int protection_systems_flags, FourCC protection_scheme)shaka::media::PlayReadyKeySource - PlayReadyKeySource(const std::string &server_url, const std::string &client_cert_file, const std::string &client_cert_private_key_file, const std::string &client_cert_private_key_password, int protection_systems_flags, FourCC protection_scheme)shaka::media::PlayReadyKeySource - SetCaFile(const std::string &ca_file)shaka::media::PlayReadyKeySourceinline - UpdateProtectionSystemInfo(EncryptionKeyMap *encryption_key_map)shaka::media::KeySourceprotected - ~KeySource() (defined in shaka::media::KeySource)shaka::media::KeySourcevirtual - ~PlayReadyKeySource() override (defined in shaka::media::PlayReadyKeySource)shaka::media::PlayReadyKeySource + KeySource() (defined in shaka::media::KeySource)shaka::media::KeySource + PlayReadyKeySource(const std::string &server_url, ProtectionSystem protection_systems)shaka::media::PlayReadyKeySource + ~KeySource() (defined in shaka::media::KeySource)shaka::media::KeySourcevirtual + ~PlayReadyKeySource() override (defined in shaka::media::PlayReadyKeySource)shaka::media::PlayReadyKeySource
diff --git a/docs/d1/dc2/h26x__bit__reader_8h_source.html b/docs/d1/dc2/h26x__bit__reader_8h_source.html index 0751686b15..688aa6e3ba 100644 --- a/docs/d1/dc2/h26x__bit__reader_8h_source.html +++ b/docs/d1/dc2/h26x__bit__reader_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h26x_bit_reader.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
h26x_bit_reader.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // This file contains an implementation of an H264 Annex-B video stream parser.
6 
7 #ifndef PACKAGER_MEDIA_CODECS_H264_BIT_READER_H_
8 #define PACKAGER_MEDIA_CODECS_H264_BIT_READER_H_
9 
10 #include <stdint.h>
11 #include <sys/types.h>
12 
13 #include "packager/base/macros.h"
14 
15 namespace shaka {
16 namespace media {
17 
18 // A class to provide bit-granularity reading of H.264/H.265 streams.
19 // This is not a generic bit reader class, as it takes into account
20 // H.264 stream-specific constraints, such as skipping emulation-prevention
21 // bytes and stop bits. See spec for more details.
23  public:
24  H26xBitReader();
25  ~H26xBitReader();
26 
27  // Initialize the reader to start reading at |data|, |size| being size
28  // of |data| in bytes.
29  // Return false on insufficient size of stream..
30  bool Initialize(const uint8_t* data, off_t size);
31 
32  // Read |num_bits| next bits from stream and return in |*out|, first bit
33  // from the stream starting at |num_bits| position in |*out|.
34  // |num_bits| may be 1-32, inclusive.
35  // Return false if the given number of bits cannot be read (not enough
36  // bits in the stream), true otherwise.
37  bool ReadBits(int num_bits, int* out);
38 
39  // Read a single bit and return in |*out|.
40  // Return false if the bit cannot be read (not enough bits in the stream),
41  // true otherwise.
42  bool ReadBool(bool* out) {
43  int value;
44  if (!ReadBits(1, &value))
45  return false;
46  *out = (value != 0);
47  return true;
48  }
49 
50  // Skips the given number of bits (does not have to be less than 32 bits).
51  // Return false if there aren't enough bits in the stream, true otherwise.
52  bool SkipBits(int num_bits);
53 
54  // Exp-Golomb code parsing as specified in chapter 9.1 of the spec.
55  // Read one unsigned exp-Golomb code from the stream and return in |*val|.
56  bool ReadUE(int* val);
57 
58  // Read one signed exp-Golomb code from the stream and return in |*val|.
59  bool ReadSE(int* val);
60 
61  // Return the number of bits left in the stream.
62  off_t NumBitsLeft();
63 
64  // See the definition of more_rbsp_data() in spec.
65  bool HasMoreRBSPData();
66 
67  // Return the number of emulation prevention bytes already read.
68  size_t NumEmulationPreventionBytesRead();
69 
70  private:
71  // Advance to the next byte, loading it into curr_byte_.
72  // Return false on end of stream.
73  bool UpdateCurrByte();
74 
75  // Pointer to the next unread (not in curr_byte_) byte in the stream.
76  const uint8_t* data_;
77 
78  // Bytes left in the stream (without the curr_byte_).
79  off_t bytes_left_;
80 
81  // Contents of the current byte; first unread bit starting at position
82  // 8 - num_remaining_bits_in_curr_byte_ from MSB.
83  int curr_byte_;
84 
85  // Number of bits remaining in curr_byte_
86  int num_remaining_bits_in_curr_byte_;
87 
88  // Used in emulation prevention three byte detection (see spec).
89  // Initially set to 0xffff to accept all initial two-byte sequences.
90  int prev_two_bytes_;
91 
92  // Number of emulation preventation bytes (0x000003) we met.
93  size_t emulation_prevention_bytes_;
94 
95  DISALLOW_COPY_AND_ASSIGN(H26xBitReader);
96 };
97 
98 } // namespace media
99 } // namespace shaka
100 
101 #endif // PACKAGER_MEDIA_CODECS_H264_BIT_READER_H_
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 //
+
5 // This file contains an implementation of an H264 Annex-B video stream parser.
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_H264_BIT_READER_H_
+
8 #define PACKAGER_MEDIA_CODECS_H264_BIT_READER_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <sys/types.h>
+
12 
+
13 #include "packager/base/macros.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 
+
18 // A class to provide bit-granularity reading of H.264/H.265 streams.
+
19 // This is not a generic bit reader class, as it takes into account
+
20 // H.264 stream-specific constraints, such as skipping emulation-prevention
+
21 // bytes and stop bits. See spec for more details.
+ +
23  public:
+
24  H26xBitReader();
+
25  ~H26xBitReader();
+
26 
+
27  // Initialize the reader to start reading at |data|, |size| being size
+
28  // of |data| in bytes.
+
29  // Return false on insufficient size of stream..
+
30  bool Initialize(const uint8_t* data, off_t size);
+
31 
+
32  // Read |num_bits| next bits from stream and return in |*out|, first bit
+
33  // from the stream starting at |num_bits| position in |*out|.
+
34  // |num_bits| may be 1-32, inclusive.
+
35  // Return false if the given number of bits cannot be read (not enough
+
36  // bits in the stream), true otherwise.
+
37  bool ReadBits(int num_bits, int* out);
+
38 
+
39  // Read a single bit and return in |*out|.
+
40  // Return false if the bit cannot be read (not enough bits in the stream),
+
41  // true otherwise.
+
42  bool ReadBool(bool* out) {
+
43  int value;
+
44  if (!ReadBits(1, &value))
+
45  return false;
+
46  *out = (value != 0);
+
47  return true;
+
48  }
+
49 
+
50  // Skips the given number of bits (does not have to be less than 32 bits).
+
51  // Return false if there aren't enough bits in the stream, true otherwise.
+
52  bool SkipBits(int num_bits);
+
53 
+
54  // Exp-Golomb code parsing as specified in chapter 9.1 of the spec.
+
55  // Read one unsigned exp-Golomb code from the stream and return in |*val|.
+
56  bool ReadUE(int* val);
+
57 
+
58  // Read one signed exp-Golomb code from the stream and return in |*val|.
+
59  bool ReadSE(int* val);
+
60 
+
61  // Return the number of bits left in the stream.
+
62  off_t NumBitsLeft();
+
63 
+
64  // See the definition of more_rbsp_data() in spec.
+
65  bool HasMoreRBSPData();
+
66 
+
67  // Return the number of emulation prevention bytes already read.
+
68  size_t NumEmulationPreventionBytesRead();
+
69 
+
70  private:
+
71  // Advance to the next byte, loading it into curr_byte_.
+
72  // Return false on end of stream.
+
73  bool UpdateCurrByte();
+
74 
+
75  // Pointer to the next unread (not in curr_byte_) byte in the stream.
+
76  const uint8_t* data_;
+
77 
+
78  // Bytes left in the stream (without the curr_byte_).
+
79  off_t bytes_left_;
+
80 
+
81  // Contents of the current byte; first unread bit starting at position
+
82  // 8 - num_remaining_bits_in_curr_byte_ from MSB.
+
83  int curr_byte_;
+
84 
+
85  // Number of bits remaining in curr_byte_
+
86  int num_remaining_bits_in_curr_byte_;
+
87 
+
88  // Used in emulation prevention three byte detection (see spec).
+
89  // Initially set to 0xffff to accept all initial two-byte sequences.
+
90  int prev_two_bytes_;
+
91 
+
92  // Number of emulation preventation bytes (0x000003) we met.
+
93  size_t emulation_prevention_bytes_;
+
94 
+
95  DISALLOW_COPY_AND_ASSIGN(H26xBitReader);
+
96 };
+
97 
+
98 } // namespace media
+
99 } // namespace shaka
+
100 
+
101 #endif // PACKAGER_MEDIA_CODECS_H264_BIT_READER_H_
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/dc7/classshaka_1_1HttpFile.html b/docs/d1/dc7/classshaka_1_1HttpFile.html new file mode 100644 index 0000000000..b60f645568 --- /dev/null +++ b/docs/d1/dc7/classshaka_1_1HttpFile.html @@ -0,0 +1,442 @@ + + + + + + + +Shaka Packager SDK: shaka::HttpFile Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::HttpFile Class Reference
+
+
+ +

#include <http_file.h>

+
+Inheritance diagram for shaka::HttpFile:
+
+
+ + +shaka::File + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

HttpFile (HttpMethod method, const std::string &url)
 
HttpFile (HttpMethod method, const std::string &url, const std::string &upload_content_type, const std::vector< std::string > &headers, uint32_t timeout_in_seconds)
 
HttpFile (const HttpFile &)=delete
 
+HttpFileoperator= (const HttpFile &)=delete
 
+Status CloseWithStatus ()
 
File implementation overrides.
bool Close () override
 
int64_t Read (void *buffer, uint64_t length) override
 
int64_t Write (const void *buffer, uint64_t length) override
 
int64_t Size () override
 
bool Flush () override
 
bool Seek (uint64_t position) override
 
bool Tell (uint64_t *position) override
 
+bool Open () override
 Internal open. Should not be used directly.
 
- Public Member Functions inherited from shaka::File
const std::string & file_name () const
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Additional Inherited Members

- Static Public Member Functions inherited from shaka::File
static FileOpen (const char *file_name, const char *mode)
 
static FileOpenWithNoBuffering (const char *file_name, const char *mode)
 
static bool Delete (const char *file_name)
 
static int64_t GetFileSize (const char *file_name)
 
static bool ReadFileToString (const char *file_name, std::string *contents)
 
static bool WriteStringToFile (const char *file_name, const std::string &contents)
 
static bool WriteFileAtomically (const char *file_name, const std::string &contents)
 
static bool Copy (const char *from_file_name, const char *to_file_name)
 
static int64_t CopyFile (File *source, File *destination)
 
static int64_t CopyFile (File *source, File *destination, int64_t max_copy)
 
static bool IsLocalRegularFile (const char *file_name)
 
static std::string MakeCallbackFileName (const BufferCallbackParams &callback_params, const std::string &name)
 
static bool ParseCallbackFileName (const std::string &callback_file_name, const BufferCallbackParams **callback_params, std::string *name)
 
- Protected Member Functions inherited from shaka::File
File (const std::string &file_name)
 
virtual ~File ()
 
+

Detailed Description

+

HttpFile reads or writes network requests.

+

Note that calling Flush will indicate EOF for the upload and no more can be uploaded.

+

About how to use this, please visit the corresponding documentation [1].

+

[1] https://google.github.io/shaka-packager/html/tutorials/http_upload.html

+ +

Definition at line 38 of file http_file.h.

+

Member Function Documentation

+ +

◆ Close()

+ +
+
+ + + + + +
+ + + + + + + +
bool shaka::HttpFile::Close ()
+
+overridevirtual
+
+

Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

Returns
true on success. For writable files, returning false MAY INDICATE DATA LOSS.
+ +

Implements shaka::File.

+ +

Definition at line 224 of file http_file.cc.

+ +
+
+ +

◆ Flush()

+ +
+
+ + + + + +
+ + + + + + + +
bool shaka::HttpFile::Flush ()
+
+overridevirtual
+
+

Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

Returns
true on success, false otherwise.
+ +

Implements shaka::File.

+ +

Definition at line 243 of file http_file.cc.

+ +
+
+ +

◆ Read()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int64_t shaka::HttpFile::Read (void * buffer,
uint64_t length 
)
+
+overridevirtual
+
+

Read data and return it in buffer.

Parameters
+ + + +
[out]bufferpoints to a block of memory with a size of at least length bytes.
lengthindicates number of bytes to be read.
+
+
+
Returns
Number of bytes read, or a value < 0 on error. Zero on end-of-file, or if 'length' is zero.
+ +

Implements shaka::File.

+ +

Definition at line 228 of file http_file.cc.

+ +
+
+ +

◆ Seek()

+ +
+
+ + + + + +
+ + + + + + + + +
bool shaka::HttpFile::Seek (uint64_t position)
+
+overridevirtual
+
+

Seek to the specifield position in the file.

Parameters
+ + +
positionis the position to seek to.
+
+
+
Returns
true on success, false otherwise.
+ +

Implements shaka::File.

+ +

Definition at line 248 of file http_file.cc.

+ +
+
+ +

◆ Size()

+ +
+
+ + + + + +
+ + + + + + + +
int64_t shaka::HttpFile::Size ()
+
+overridevirtual
+
+
Returns
Size of the file in bytes. A return value less than zero indicates a problem getting the size.
+ +

Implements shaka::File.

+ +

Definition at line 238 of file http_file.cc.

+ +
+
+ +

◆ Tell()

+ +
+
+ + + + + +
+ + + + + + + + +
bool shaka::HttpFile::Tell (uint64_t * position)
+
+overridevirtual
+
+

Get the current file position.

Parameters
+ + +
positionis a pointer to contain the current file position upon successful return.
+
+
+
Returns
true on succcess, false otherwise.
+ +

Implements shaka::File.

+ +

Definition at line 253 of file http_file.cc.

+ +
+
+ +

◆ Write()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int64_t shaka::HttpFile::Write (const void * buffer,
uint64_t length 
)
+
+overridevirtual
+
+

Write block of data.

Parameters
+ + + +
bufferpoints to a block of memory with at least length bytes.
lengthindicates number of bytes to write.
+
+
+
Returns
Number of bytes written, or a value < 0 on error.
+ +

Implements shaka::File.

+ +

Definition at line 233 of file http_file.cc.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/d1/dc7/classshaka_1_1HttpFile.png b/docs/d1/dc7/classshaka_1_1HttpFile.png new file mode 100644 index 0000000000000000000000000000000000000000..df965bf57c98c8ae00404950a97216cc0a8c1435 GIT binary patch literal 486 zcmV@P)vTJkN^MxkN^Mxkifve1&Q1r00008bW%=J0RR90|NsC0)yh;d0004XNkl=` z?I=!#UsxKf{v1DDo#2m}o*|(-ij08J#kqz#SeoL`1DA7$?);EbY4!HuAq;#$B|r`> zAJO{T_+(B#bitp*fjKFeq^cQLTf1^KXNZ@iizeRpS$YS)>;1)?QhOd;uJ-kpBS~-4 z#!Hf+jh7@t>+#-uzf1sk^Z;0=wfM(lDSs{gNngodjQ`^=XX61ZZ9IUXjR!Ea@c@Q4 z9>CDX0~p$P07IXJch0$W!U3$(#se7ozxX!SAak60{>Rq5zHai3c$<*MNA_bF#-Wyk zh=UfNUv=78rL6)o{w%1}6}l9gr@QJqN1Es!Ur=dluDX1*HmB5aZh|kTJdaoKXY9!P z%EH=$98h0vyS+E(27Yk0m+d`bjDOYpi#etCJZP>qJerqZ4#0i=EBK@F05feofT8tx c=bT%nFJ?;=y{>*pGynhq07*qoM6N<$f-{=orvLx| literal 0 HcmV?d00001 diff --git a/docs/d1/dd5/av1__codec__configuration__record_8cc_source.html b/docs/d1/dd5/av1__codec__configuration__record_8cc_source.html index d5be4ae380..4399f8344a 100644 --- a/docs/d1/dd5/av1__codec__configuration__record_8cc_source.html +++ b/docs/d1/dd5/av1__codec__configuration__record_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/av1_codec_configuration_record.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
av1_codec_configuration_record.cc
-
1 // Copyright 2018 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/av1_codec_configuration_record.h"
8 
9 #include "packager/base/strings/stringprintf.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/base/rcheck.h"
12 
13 namespace shaka {
14 namespace media {
15 
16 AV1CodecConfigurationRecord::AV1CodecConfigurationRecord() = default;
17 
18 AV1CodecConfigurationRecord::~AV1CodecConfigurationRecord() = default;
19 
20 // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-section
21 // aligned (8) class AV1CodecConfigurationRecord {
22 // unsigned int (1) marker = 1;
23 // unsigned int (7) version = 1;
24 // unsigned int (3) seq_profile;
25 // unsigned int (5) seq_level_idx_0;
26 // unsigned int (1) seq_tier_0;
27 // unsigned int (1) high_bitdepth;
28 // unsigned int (1) twelve_bit;
29 // unsigned int (1) monochrome;
30 // unsigned int (1) chroma_subsampling_x;
31 // unsigned int (1) chroma_subsampling_y;
32 // unsigned int (2) chroma_sample_position;
33 // unsigned int (3) reserved = 0;
34 //
35 // unsigned int (1) initial_presentation_delay_present;
36 // if (initial_presentation_delay_present) {
37 // unsigned int (4) initial_presentation_delay_minus_one;
38 // } else {
39 // unsigned int (4) reserved = 0;
40 // }
41 //
42 // unsigned int (8)[] configOBUs;
43 // }
44 bool AV1CodecConfigurationRecord::Parse(const uint8_t* data, size_t data_size) {
45  RCHECK(data_size > 0);
46 
47  BitReader reader(data, data_size);
48 
49  int marker;
50  RCHECK(reader.ReadBits(1, &marker));
51  RCHECK(marker == 1);
52 
53  int version;
54  RCHECK(reader.ReadBits(7, &version));
55  RCHECK(version == 1);
56 
57  RCHECK(reader.ReadBits(3, &profile_));
58  RCHECK(reader.ReadBits(5, &level_));
59  RCHECK(reader.ReadBits(1, &tier_));
60 
61  int high_bitdepth;
62  int twelve_bit;
63  RCHECK(reader.ReadBits(1, &high_bitdepth));
64  RCHECK(reader.ReadBits(1, &twelve_bit));
65  bit_depth_ = twelve_bit ? 12 : (high_bitdepth ? 10 : 8);
66 
67  RCHECK(reader.ReadBits(1, &mono_chrome_));
68  RCHECK(reader.ReadBits(1, &chroma_subsampling_x_));
69  RCHECK(reader.ReadBits(1, &chroma_subsampling_y_));
70  RCHECK(reader.ReadBits(2, &chroma_sample_position_));
71 
72  // Skip other fields (e.g. initial_presentation_delay) which we do not need.
73  return true;
74 }
75 
76 // https://aomediacodec.github.io/av1-isobmff/#codecsparam
77 // <sample entry 4CC>.<profile>.<level><tier>.<bitDepth>.<monochrome>.
78 // <chromaSubsampling>.<colorPrimaries>.<transferCharacteristics>.
79 // <matrixCoefficients>.<videoFullRangeFlag>
80 // The parameters sample entry 4CC, profile, level, tier, and bitDepth are all
81 // mandatory fields.
82 // All the other fields (including their leading '.') are optional, mutually
83 // inclusive (all or none) fields.
84 // Since some of the optional fields (e.g. colorPrimaries) are not present in
85 // AV1CodecConfigurationRecord, we omit all the optional fields.
87  return base::StringPrintf("av01.%d.%02d%c.%02d", profile_, level_,
88  tier_ ? 'H' : 'M', bit_depth_);
89 }
90 
91 } // namespace media
92 } // namespace shaka
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:35
-
A class to read bit streams.
Definition: bit_reader.h:17
-
All the methods that are virtual are virtual for mocking.
- -
bool Parse(const std::vector< uint8_t > &data)
+
1 // Copyright 2018 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/av1_codec_configuration_record.h"
+
8 
+
9 #include "packager/base/strings/stringprintf.h"
+
10 #include "packager/media/base/bit_reader.h"
+
11 #include "packager/media/base/rcheck.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
16 AV1CodecConfigurationRecord::AV1CodecConfigurationRecord() = default;
+
17 
+
18 AV1CodecConfigurationRecord::~AV1CodecConfigurationRecord() = default;
+
19 
+
20 // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-section
+
21 // aligned (8) class AV1CodecConfigurationRecord {
+
22 // unsigned int (1) marker = 1;
+
23 // unsigned int (7) version = 1;
+
24 // unsigned int (3) seq_profile;
+
25 // unsigned int (5) seq_level_idx_0;
+
26 // unsigned int (1) seq_tier_0;
+
27 // unsigned int (1) high_bitdepth;
+
28 // unsigned int (1) twelve_bit;
+
29 // unsigned int (1) monochrome;
+
30 // unsigned int (1) chroma_subsampling_x;
+
31 // unsigned int (1) chroma_subsampling_y;
+
32 // unsigned int (2) chroma_sample_position;
+
33 // unsigned int (3) reserved = 0;
+
34 //
+
35 // unsigned int (1) initial_presentation_delay_present;
+
36 // if (initial_presentation_delay_present) {
+
37 // unsigned int (4) initial_presentation_delay_minus_one;
+
38 // } else {
+
39 // unsigned int (4) reserved = 0;
+
40 // }
+
41 //
+
42 // unsigned int (8)[] configOBUs;
+
43 // }
+
44 bool AV1CodecConfigurationRecord::Parse(const uint8_t* data, size_t data_size) {
+
45  RCHECK(data_size > 0);
+
46 
+
47  BitReader reader(data, data_size);
+
48 
+
49  int marker;
+
50  RCHECK(reader.ReadBits(1, &marker));
+
51  RCHECK(marker == 1);
+
52 
+
53  int version;
+
54  RCHECK(reader.ReadBits(7, &version));
+
55  RCHECK(version == 1);
+
56 
+
57  RCHECK(reader.ReadBits(3, &profile_));
+
58  RCHECK(reader.ReadBits(5, &level_));
+
59  RCHECK(reader.ReadBits(1, &tier_));
+
60 
+
61  int high_bitdepth;
+
62  int twelve_bit;
+
63  RCHECK(reader.ReadBits(1, &high_bitdepth));
+
64  RCHECK(reader.ReadBits(1, &twelve_bit));
+
65  bit_depth_ = twelve_bit ? 12 : (high_bitdepth ? 10 : 8);
+
66 
+
67  RCHECK(reader.ReadBits(1, &mono_chrome_));
+
68  RCHECK(reader.ReadBits(1, &chroma_subsampling_x_));
+
69  RCHECK(reader.ReadBits(1, &chroma_subsampling_y_));
+
70  RCHECK(reader.ReadBits(2, &chroma_sample_position_));
+
71 
+
72  // Skip other fields (e.g. initial_presentation_delay) which we do not need.
+
73  return true;
+
74 }
+
75 
+
76 // https://aomediacodec.github.io/av1-isobmff/#codecsparam
+
77 // <sample entry 4CC>.<profile>.<level><tier>.<bitDepth>.<monochrome>.
+
78 // <chromaSubsampling>.<colorPrimaries>.<transferCharacteristics>.
+
79 // <matrixCoefficients>.<videoFullRangeFlag>
+
80 // The parameters sample entry 4CC, profile, level, tier, and bitDepth are all
+
81 // mandatory fields.
+
82 // All the other fields (including their leading '.') are optional, mutually
+
83 // inclusive (all or none) fields.
+
84 // Since some of the optional fields (e.g. colorPrimaries) are not present in
+
85 // AV1CodecConfigurationRecord, we omit all the optional fields.
+ +
87  return base::StringPrintf("av01.%d.%02d%c.%02d", profile_, level_,
+
88  tier_ ? 'H' : 'M', bit_depth_);
+
89 }
+
90 
+
91 } // namespace media
+
92 } // namespace shaka
+ +
bool Parse(const std::vector< uint8_t > &data)
+
A class to read bit streams.
Definition: bit_reader.h:17
+
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:35
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/dd5/classshaka_1_1media_1_1Cluster.html b/docs/d1/dd5/classshaka_1_1media_1_1Cluster.html index fc98a178dd..87e7971991 100644 --- a/docs/d1/dd5/classshaka_1_1media_1_1Cluster.html +++ b/docs/d1/dd5/classshaka_1_1media_1_1Cluster.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::Cluster Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
size () const
diff --git a/docs/d1/dd6/structshaka_1_1media_1_1mp4_1_1DataInformation-members.html b/docs/d1/dd6/structshaka_1_1media_1_1mp4_1_1DataInformation-members.html index e825318ebb..973d694dd1 100644 --- a/docs/d1/dd6/structshaka_1_1media_1_1mp4_1_1DataInformation-members.html +++ b/docs/d1/dd6/structshaka_1_1media_1_1mp4_1_1DataInformation-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/dd8/structshaka_1_1PackagingParams-members.html b/docs/d1/dd8/structshaka_1_1PackagingParams-members.html index c6540b6c8b..6ec2554b1e 100644 --- a/docs/d1/dd8/structshaka_1_1PackagingParams-members.html +++ b/docs/d1/dd8/structshaka_1_1PackagingParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */ diff --git a/docs/d1/dda/structshaka_1_1media_1_1EncryptionConfig-members.html b/docs/d1/dda/structshaka_1_1media_1_1EncryptionConfig-members.html index 4f5d493232..e17041123e 100644 --- a/docs/d1/dda/structshaka_1_1media_1_1EncryptionConfig-members.html +++ b/docs/d1/dda/structshaka_1_1media_1_1EncryptionConfig-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/de2/classshaka_1_1media_1_1VideoStreamInfo-members.html b/docs/d1/de2/classshaka_1_1media_1_1VideoStreamInfo-members.html index 21e65e4f4c..41ad50ba05 100644 --- a/docs/d1/de2/classshaka_1_1media_1_1VideoStreamInfo-members.html +++ b/docs/d1/de2/classshaka_1_1media_1_1VideoStreamInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d1/de2/composition__offset__iterator_8cc_source.html b/docs/d1/de2/composition__offset__iterator_8cc_source.html index 7cd217ba53..d4a97a9ed2 100644 --- a/docs/d1/de2/composition__offset__iterator_8cc_source.html +++ b/docs/d1/de2/composition__offset__iterator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/composition_offset_iterator.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
composition_offset_iterator.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp4/composition_offset_iterator.h"
8 
9 #include "packager/base/logging.h"
10 
11 namespace shaka {
12 namespace media {
13 namespace mp4 {
14 
16  const CompositionTimeToSample& composition_time_to_sample)
17  : sample_index_(0),
18  composition_offset_table_(composition_time_to_sample.composition_offset),
19  iterator_(composition_offset_table_.begin()) {}
20 CompositionOffsetIterator::~CompositionOffsetIterator() {}
21 
23  ++sample_index_;
24  if (sample_index_ >= iterator_->sample_count) {
25  ++iterator_;
26  if (iterator_ == composition_offset_table_.end())
27  return false;
28  sample_index_ = 0;
29  }
30  return true;
31 }
32 
34  return iterator_ != composition_offset_table_.end() &&
35  sample_index_ < iterator_->sample_count;
36 }
37 
38 int64_t CompositionOffsetIterator::SampleOffset(uint32_t sample) const {
39  uint32_t current_sample = 0;
40  std::vector<CompositionOffset>::const_iterator it =
41  composition_offset_table_.begin();
42  for (; it != composition_offset_table_.end(); ++it) {
43  current_sample += it->sample_count;
44  if (current_sample >= sample)
45  return it->sample_offset;
46  }
47  DCHECK_LE(sample, current_sample) << " Sample is invalid";
48  return 0;
49 }
50 
52  uint32_t num_samples = 0;
53  std::vector<CompositionOffset>::const_iterator it =
54  composition_offset_table_.begin();
55  for (; it != composition_offset_table_.end(); ++it) {
56  num_samples += it->sample_count;
57  }
58  return num_samples;
59 }
60 
61 } // namespace mp4
62 } // namespace media
63 } // namespace shaka
- -
All the methods that are virtual are virtual for mocking.
- - -
CompositionOffsetIterator(const CompositionTimeToSample &composition_time_to_sample)
Create CompositionOffsetIterator from composition time to sample box.
- +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp4/composition_offset_iterator.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 
+
11 namespace shaka {
+
12 namespace media {
+
13 namespace mp4 {
+
14 
+ +
16  const CompositionTimeToSample& composition_time_to_sample)
+
17  : sample_index_(0),
+
18  composition_offset_table_(composition_time_to_sample.composition_offset),
+
19  iterator_(composition_offset_table_.begin()) {}
+
20 CompositionOffsetIterator::~CompositionOffsetIterator() {}
+
21 
+ +
23  ++sample_index_;
+
24  if (sample_index_ >= iterator_->sample_count) {
+
25  ++iterator_;
+
26  if (iterator_ == composition_offset_table_.end())
+
27  return false;
+
28  sample_index_ = 0;
+
29  }
+
30  return true;
+
31 }
+
32 
+ +
34  return iterator_ != composition_offset_table_.end() &&
+
35  sample_index_ < iterator_->sample_count;
+
36 }
+
37 
+
38 int64_t CompositionOffsetIterator::SampleOffset(uint32_t sample) const {
+
39  uint32_t current_sample = 0;
+
40  std::vector<CompositionOffset>::const_iterator it =
+
41  composition_offset_table_.begin();
+
42  for (; it != composition_offset_table_.end(); ++it) {
+
43  current_sample += it->sample_count;
+
44  if (current_sample >= sample)
+
45  return it->sample_offset;
+
46  }
+
47  DCHECK_LE(sample, current_sample) << " Sample is invalid";
+
48  return 0;
+
49 }
+
50 
+ +
52  uint32_t num_samples = 0;
+
53  std::vector<CompositionOffset>::const_iterator it =
+
54  composition_offset_table_.begin();
+
55  for (; it != composition_offset_table_.end(); ++it) {
+
56  num_samples += it->sample_count;
+
57  }
+
58  return num_samples;
+
59 }
+
60 
+
61 } // namespace mp4
+
62 } // namespace media
+
63 } // namespace shaka
+ +
CompositionOffsetIterator(const CompositionTimeToSample &composition_time_to_sample)
Create CompositionOffsetIterator from composition time to sample box.
+ + + +
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d1/de4/classshaka_1_1media_1_1KeyFetcher-members.html b/docs/d1/de4/classshaka_1_1media_1_1KeyFetcher-members.html index 493193500e..67e1e77574 100644 --- a/docs/d1/de4/classshaka_1_1media_1_1KeyFetcher-members.html +++ b/docs/d1/de4/classshaka_1_1media_1_1KeyFetcher-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/de7/classshaka_1_1xml_1_1AdaptationSetXmlNode.html b/docs/d1/de7/classshaka_1_1xml_1_1AdaptationSetXmlNode.html index 94abbd3ffc..872aa9d608 100644 --- a/docs/d1/de7/classshaka_1_1xml_1_1AdaptationSetXmlNode.html +++ b/docs/d1/de7/classshaka_1_1xml_1_1AdaptationSetXmlNode.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::xml::AdaptationSetXmlNode Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::xml::RepresentationBaseXmlNode shaka::xml::XmlNode - -
+ + - - - - + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + +

Public Member Functions

void AddAccessibilityElement (const std::string &scheme_id_uri, const std::string &value)
 
void AddRoleElement (const std::string &scheme_id_uri, const std::string &value)
 
bool AddAccessibilityElement (const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
 
bool AddRoleElement (const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
 
- Public Member Functions inherited from shaka::xml::RepresentationBaseXmlNode
-bool AddContentProtectionElements (const std::list< ContentProtectionElement > &content_protection_elements)
 
void AddSupplementalProperty (const std::string &scheme_id_uri, const std::string &value)
 
void AddEssentialProperty (const std::string &scheme_id_uri, const std::string &value)
 
+bool AddContentProtectionElements (const std::list< ContentProtectionElement > &content_protection_elements) WARN_UNUSED_RESULT
 
bool AddSupplementalProperty (const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
 
bool AddEssentialProperty (const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
 
- Public Member Functions inherited from shaka::xml::XmlNode
 XmlNode (const char *name)
 
bool AddChild (scoped_xml_ptr< xmlNode > child)
 
-bool AddElements (const std::vector< Element > &elements)
 Adds Elements to this node using the Element struct.
 
void SetStringAttribute (const char *attribute_name, const std::string &attribute)
 
void SetIntegerAttribute (const char *attribute_name, uint64_t number)
 
void SetFloatingPointAttribute (const char *attribute_name, double number)
 
void SetId (uint32_t id)
 
 XmlNode (const std::string &name)
 
XmlNode (XmlNode &&)
 
+XmlNodeoperator= (XmlNode &&)
 
bool AddChild (XmlNode child) WARN_UNUSED_RESULT
 
+bool AddElements (const std::vector< Element > &elements) WARN_UNUSED_RESULT
 Adds Elements to this node using the Element struct.
 
bool SetStringAttribute (const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
 
bool SetIntegerAttribute (const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULT
 
bool SetFloatingPointAttribute (const std::string &attribute_name, double number) WARN_UNUSED_RESULT
 
bool SetId (uint32_t id) WARN_UNUSED_RESULT
 
+void AddContent (const std::string &content)
 Similar to SetContent, but appends to the end of existing content.
 
void SetContent (const std::string &content)
 
std::set< std::string > ExtractReferencedNamespaces ()
 
scoped_xml_ptr< xmlNode > PassScopedPtr ()
 
xmlNodePtr Release ()
 
xmlNodePtr GetRawPtr ()
 
std::set< std::string > ExtractReferencedNamespaces () const
 
std::string ToString (const std::string &comment) const
 
bool GetAttribute (const std::string &name, std::string *value) const
 
- - - - + + + +

Additional Inherited Members

- Protected Member Functions inherited from shaka::xml::RepresentationBaseXmlNode
RepresentationBaseXmlNode (const char *name)
 
bool AddDescriptor (const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value)
 
RepresentationBaseXmlNode (const std::string &name)
 
bool AddDescriptor (const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
 

Detailed Description

AdaptationSetType specified in MPD.

-

Definition at line 136 of file xml_node.h.

+

Definition at line 162 of file xml_node.h.

Member Function Documentation

- -

◆ AddAccessibilityElement()

+ +

◆ AddAccessibilityElement()

- + @@ -174,18 +185,18 @@ Additional Inherited Members -

Definition at line 294 of file xml_node.cc.

+

Definition at line 322 of file xml_node.cc.

- -

◆ AddRoleElement()

+ +

◆ AddRoleElement()

void shaka::xml::AdaptationSetXmlNode::AddAccessibilityElement bool shaka::xml::AdaptationSetXmlNode::AddAccessibilityElement ( const std::string &  scheme_id_uri,
- + @@ -211,7 +222,7 @@ Additional Inherited Members -

Definition at line 300 of file xml_node.cc.

+

Definition at line 328 of file xml_node.cc.

@@ -222,9 +233,7 @@ Additional Inherited Members diff --git a/docs/d1/de7/structshaka_1_1media_1_1H265ReferencePictureListModifications-members.html b/docs/d1/de7/structshaka_1_1media_1_1H265ReferencePictureListModifications-members.html index 49923ed9e4..95191fe158 100644 --- a/docs/d1/de7/structshaka_1_1media_1_1H265ReferencePictureListModifications-members.html +++ b/docs/d1/de7/structshaka_1_1media_1_1H265ReferencePictureListModifications-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
void shaka::xml::AdaptationSetXmlNode::AddRoleElement bool shaka::xml::AdaptationSetXmlNode::AddRoleElement ( const std::string &  scheme_id_uri,
- + +/* @license-end */
diff --git a/docs/d1/de9/classshaka_1_1media_1_1ProgressListener-members.html b/docs/d1/de9/classshaka_1_1media_1_1ProgressListener-members.html index fbfdbae6b7..18924a791e 100644 --- a/docs/d1/de9/classshaka_1_1media_1_1ProgressListener-members.html +++ b/docs/d1/de9/classshaka_1_1media_1_1ProgressListener-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d1/dee/classshaka_1_1media_1_1mp4_1_1BoxReader.html b/docs/d1/dee/classshaka_1_1media_1_1mp4_1_1BoxReader.html index 0f7d1692e1..7be5cd6ced 100644 --- a/docs/d1/dee/classshaka_1_1media_1_1mp4_1_1BoxReader.html +++ b/docs/d1/dee/classshaka_1_1media_1_1mp4_1_1BoxReader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::BoxReader Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::BufferReader - -
+ + @@ -123,6 +126,10 @@ bool  + + +

Public Member Functions

ReadToVector (std
bool ReadToString (std::string *str, size_t size) WARN_UNUSED_RESULT
 
+bool ReadCString (std::string *str) WARN_UNUSED_RESULT
 Reads a null-terminated string.
 
bool SkipBytes (size_t num_bytes) WARN_UNUSED_RESULT
 
@@ -258,15 +265,15 @@ template<typename T >
-

Create a BoxReader from a buffer.

Parameters
+

Create a BoxReader from a buffer.

Parameters
- +
bufis retained but not owned, and must outlive the BoxReader instance.
bufis retained but not owned, and must outlive the BoxReader instance.
buf_sizeindicates the size of the input buffer.
[out]erris set to true if there was a stream-level error when reading the box.
-
Returns
New box reader if successful, NULL otherwise. Note that this function may return NULL if an intact, complete box is not available in the buffer. For MDAT box only, a BoxReader object is returned as long as the box header is available.
+
Returns
New box reader if successful, NULL otherwise. Note that this function may return NULL if an intact, complete box is not available in the buffer. For MDAT box only, a BoxReader object is returned as long as the box header is available.

Definition at line 36 of file box_reader.cc.

@@ -454,9 +461,7 @@ template<typename T >
diff --git a/docs/d1/dee/structshaka_1_1media_1_1mp4_1_1SampleTable.html b/docs/d1/dee/structshaka_1_1media_1_1mp4_1_1SampleTable.html index c5e34258d2..2ff9bd8169 100644 --- a/docs/d1/dee/structshaka_1_1media_1_1mp4_1_1SampleTable.html +++ b/docs/d1/dee/structshaka_1_1media_1_1mp4_1_1SampleTable.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleTable Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -136,7 +139,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 551 of file box_definitions.h.

+

Definition at line 564 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -164,7 +167,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 1137 of file box_definitions.cc.

+

Definition at line 1155 of file box_definitions.cc.

@@ -175,9 +178,7 @@ Additional Inherited Members diff --git a/docs/d1/df0/aes__encryptor_8h_source.html b/docs/d1/df0/aes__encryptor_8h_source.html index e49a5b3389..e9e604dc77 100644 --- a/docs/d1/df0/aes__encryptor_8h_source.html +++ b/docs/d1/df0/aes__encryptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/aes_encryptor.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
aes_encryptor.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // AES Encryptor implementation using openssl.
8 
9 #ifndef PACKAGER_MEDIA_BASE_AES_ENCRYPTOR_H_
10 #define PACKAGER_MEDIA_BASE_AES_ENCRYPTOR_H_
11 
12 #include <string>
13 #include <vector>
14 
15 #include "packager/base/macros.h"
16 #include "packager/media/base/aes_cryptor.h"
17 
18 namespace shaka {
19 namespace media {
20 
21 class AesEncryptor : public AesCryptor {
22  public:
29  explicit AesEncryptor(ConstantIvFlag constant_iv_flag);
30  ~AesEncryptor() override;
31 
34  bool InitializeWithIv(const std::vector<uint8_t>& key,
35  const std::vector<uint8_t>& iv) override;
36 
37  private:
38  DISALLOW_COPY_AND_ASSIGN(AesEncryptor);
39 };
40 
41 // Class which implements AES-CTR counter-mode encryption.
42 class AesCtrEncryptor : public AesEncryptor {
43  public:
45  ~AesCtrEncryptor() override;
46 
47  uint32_t block_offset() const { return block_offset_; }
48 
49  private:
50  bool CryptInternal(const uint8_t* plaintext,
51  size_t plaintext_size,
52  uint8_t* ciphertext,
53  size_t* ciphertext_size) override;
54  void SetIvInternal() override;
55 
56  // Current block offset.
57  uint32_t block_offset_;
58  // Current AES-CTR counter.
59  std::vector<uint8_t> counter_;
60  // Encrypted counter.
61  std::vector<uint8_t> encrypted_counter_;
62 
63  DISALLOW_COPY_AND_ASSIGN(AesCtrEncryptor);
64 };
65 
66 enum CbcPaddingScheme {
67  // Residual block is left unencrypted.
68  kNoPadding,
69  // Residual block is padded with pkcs5 and encrypted.
70  kPkcs5Padding,
71  // Residual block and the next-to-last block are encrypted using ciphertext
72  // stealing method.
73  kCtsPadding,
74 };
75 
76 // Class which implements AES-CBC (Cipher block chaining) encryption.
77 class AesCbcEncryptor : public AesEncryptor {
78  public:
83  explicit AesCbcEncryptor(CbcPaddingScheme padding_scheme);
84 
92  AesCbcEncryptor(CbcPaddingScheme padding_scheme,
93  ConstantIvFlag constant_iv_flag);
94 
95  ~AesCbcEncryptor() override;
96 
97  private:
98  bool CryptInternal(const uint8_t* plaintext,
99  size_t plaintext_size,
100  uint8_t* ciphertext,
101  size_t* ciphertext_size) override;
102  void SetIvInternal() override;
103  size_t NumPaddingBytes(size_t size) const override;
104 
105  const CbcPaddingScheme padding_scheme_;
106  // 16-byte internal iv for crypto operations.
107  std::vector<uint8_t> internal_iv_;
108 
109  DISALLOW_COPY_AND_ASSIGN(AesCbcEncryptor);
110 };
111 
112 } // namespace media
113 } // namespace shaka
114 
115 #endif // PACKAGER_MEDIA_BASE_AES_ENCRYPTOR_H_
-
bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
-
All the methods that are virtual are virtual for mocking.
-
AesEncryptor(ConstantIvFlag constant_iv_flag)
- -
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
- - +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // AES Encryptor implementation using openssl.
+
8 
+
9 #ifndef PACKAGER_MEDIA_BASE_AES_ENCRYPTOR_H_
+
10 #define PACKAGER_MEDIA_BASE_AES_ENCRYPTOR_H_
+
11 
+
12 #include <string>
+
13 #include <vector>
+
14 
+
15 #include "packager/base/macros.h"
+
16 #include "packager/media/base/aes_cryptor.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 
+
21 class AesEncryptor : public AesCryptor {
+
22  public:
+
29  explicit AesEncryptor(ConstantIvFlag constant_iv_flag);
+
30  ~AesEncryptor() override;
+
31 
+
34  bool InitializeWithIv(const std::vector<uint8_t>& key,
+
35  const std::vector<uint8_t>& iv) override;
+
36 
+
37  private:
+
38  DISALLOW_COPY_AND_ASSIGN(AesEncryptor);
+
39 };
+
40 
+
41 // Class which implements AES-CTR counter-mode encryption.
+
42 class AesCtrEncryptor : public AesEncryptor {
+
43  public:
+ +
45  ~AesCtrEncryptor() override;
+
46 
+
47  uint32_t block_offset() const { return block_offset_; }
+
48 
+
49  private:
+
50  bool CryptInternal(const uint8_t* plaintext,
+
51  size_t plaintext_size,
+
52  uint8_t* ciphertext,
+
53  size_t* ciphertext_size) override;
+
54  void SetIvInternal() override;
+
55 
+
56  // Current block offset.
+
57  uint32_t block_offset_;
+
58  // Current AES-CTR counter.
+
59  std::vector<uint8_t> counter_;
+
60  // Encrypted counter.
+
61  std::vector<uint8_t> encrypted_counter_;
+
62 
+
63  DISALLOW_COPY_AND_ASSIGN(AesCtrEncryptor);
+
64 };
+
65 
+
66 enum CbcPaddingScheme {
+
67  // Residual block is left unencrypted.
+
68  kNoPadding,
+
69  // Residual block is padded with pkcs5 and encrypted.
+
70  kPkcs5Padding,
+
71  // Residual block and the next-to-last block are encrypted using ciphertext
+
72  // stealing method.
+
73  kCtsPadding,
+
74 };
+
75 
+
76 // Class which implements AES-CBC (Cipher block chaining) encryption.
+
77 class AesCbcEncryptor : public AesEncryptor {
+
78  public:
+
83  explicit AesCbcEncryptor(CbcPaddingScheme padding_scheme);
+
84 
+
92  AesCbcEncryptor(CbcPaddingScheme padding_scheme,
+
93  ConstantIvFlag constant_iv_flag);
+
94 
+
95  ~AesCbcEncryptor() override;
+
96 
+
97  private:
+
98  bool CryptInternal(const uint8_t* plaintext,
+
99  size_t plaintext_size,
+
100  uint8_t* ciphertext,
+
101  size_t* ciphertext_size) override;
+
102  void SetIvInternal() override;
+
103  size_t NumPaddingBytes(size_t size) const override;
+
104 
+
105  const CbcPaddingScheme padding_scheme_;
+
106  // 16-byte internal iv for crypto operations.
+
107  std::vector<uint8_t> internal_iv_;
+
108 
+
109  DISALLOW_COPY_AND_ASSIGN(AesCbcEncryptor);
+
110 };
+
111 
+
112 } // namespace media
+
113 } // namespace shaka
+
114 
+
115 #endif // PACKAGER_MEDIA_BASE_AES_ENCRYPTOR_H_
+ +
AesCbcEncryptor(CbcPaddingScheme padding_scheme)
+ +
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
+ + +
bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
+
AesEncryptor(ConstantIvFlag constant_iv_flag)
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d1/df3/structshaka_1_1MpdOptions.html b/docs/d1/df3/structshaka_1_1MpdOptions.html index 956a35b88f..833c58409f 100644 --- a/docs/d1/df3/structshaka_1_1MpdOptions.html +++ b/docs/d1/df3/structshaka_1_1MpdOptions.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MpdOptions Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
mpd_type = Mpd
diff --git a/docs/d1/df5/nalu__reader_8cc_source.html b/docs/d1/df5/nalu__reader_8cc_source.html index f46d6c6b69..3ebe3336d1 100644 --- a/docs/d1/df5/nalu__reader_8cc_source.html +++ b/docs/d1/df5/nalu__reader_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/nalu_reader.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
nalu_reader.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/nalu_reader.h"
8 
9 #include <iostream>
10 
11 #include "packager/base/logging.h"
12 #include "packager/media/base/buffer_reader.h"
13 #include "packager/media/codecs/h264_parser.h"
14 
15 namespace shaka {
16 namespace media {
17 
18 namespace {
19 inline bool IsStartCode(const uint8_t* data) {
20  return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01;
21 }
22 
23 // Edits |subsamples| given the number of consumed bytes.
24 void UpdateSubsamples(uint64_t consumed_bytes,
25  std::vector<SubsampleEntry>* subsamples) {
26  if (consumed_bytes == 0 || subsamples->empty()) {
27  return;
28  }
29  size_t num_entries_to_delete = 0;
30  for (SubsampleEntry& subsample : *subsamples) {
31  if (subsample.clear_bytes > consumed_bytes) {
32  subsample.clear_bytes -= consumed_bytes;
33  consumed_bytes = 0;
34  break;
35  }
36  consumed_bytes -= subsample.clear_bytes;
37  subsample.clear_bytes = 0;
38 
39  if (subsample.cipher_bytes > consumed_bytes) {
40  subsample.cipher_bytes -= consumed_bytes;
41  consumed_bytes = 0;
42  break;
43  }
44  consumed_bytes -= subsample.cipher_bytes;
45  subsample.cipher_bytes = 0;
46  ++num_entries_to_delete;
47  }
48 
49  subsamples->erase(subsamples->begin(),
50  subsamples->begin() + num_entries_to_delete);
51 }
52 
53 bool IsNaluLengthEncrypted(
54  uint8_t nalu_length_size,
55  const std::vector<SubsampleEntry>& subsamples) {
56  if (subsamples.empty())
57  return false;
58 
59  for (const SubsampleEntry& subsample : subsamples) {
60  if (subsample.clear_bytes >= nalu_length_size) {
61  return false;
62  }
63  nalu_length_size -= subsample.clear_bytes;
64  if (subsample.cipher_bytes > 0) {
65  return true;
66  }
67  }
68  // Ran out of subsamples. Assume the rest is in the clear.
69  return false;
70 }
71 } // namespace
72 
73 Nalu::Nalu() = default;
74 
75 bool Nalu::Initialize(CodecType type,
76  const uint8_t* data,
77  uint64_t size) {
78  if (type == Nalu::kH264) {
79  return InitializeFromH264(data, size);
80  } else {
81  DCHECK_EQ(Nalu::kH265, type);
82  return InitializeFromH265(data, size);
83  }
84 }
85 
86 // ITU-T H.264 (02/2014) 7.4.1 NAL unit semantics
87 bool Nalu::InitializeFromH264(const uint8_t* data, uint64_t size) {
88  DCHECK(data);
89  if (size == 0)
90  return false;
91  const uint8_t header = data[0];
92  if ((header & 0x80) != 0) {
93  LOG(WARNING) << "forbidden_zero_bit shall be equal to 0 (header 0x"
94  << std::hex << static_cast<int>(header) << ").";
95  return false;
96  }
97 
98  data_ = data;
99  header_size_ = 1;
100  payload_size_ = size - header_size_;
101  ref_idc_ = (header >> 5) & 0x3;
102  type_ = header & 0x1F;
103 
104  // Reserved NAL units are not treated as valid NAL units here.
105  if (type_ == Nalu::H264_Unspecified || type_ == Nalu::H264_Reserved17 ||
106  type_ == Nalu::H264_Reserved18 || type_ >= Nalu::H264_Reserved22) {
107  VLOG(1) << "Unspecified or reserved nal_unit_type " << type_
108  << " (header 0x" << std::hex << static_cast<int>(header) << ").";
109  // Allow reserved NAL units. Some encoders and extended codecs use the
110  // reserved NAL units to carry their private data.
111  } else if (type_ == Nalu::H264_IDRSlice || type_ == Nalu::H264_SPS ||
112  type_ == Nalu::H264_SPSExtension ||
113  type_ == Nalu::H264_SubsetSPS || type_ == Nalu::H264_PPS) {
114  if (ref_idc_ == 0) {
115  LOG(WARNING) << "nal_ref_idc shall not be equal to 0 for nalu type "
116  << type_ << " (header 0x" << std::hex
117  << static_cast<int>(header) << ").";
118  return false;
119  }
120  } else if (type_ == Nalu::H264_SEIMessage ||
121  (type_ >= Nalu::H264_AUD && type_ <= Nalu::H264_FillerData)) {
122  if (ref_idc_ != 0) {
123  LOG(WARNING) << "nal_ref_idc shall be equal to 0 for nalu type " << type_
124  << " (header 0x" << std::hex << static_cast<int>(header)
125  << ").";
126  return false;
127  }
128  }
129 
130  is_aud_ = type_ == H264_AUD;
131  is_vcl_ = (type_ >= Nalu::H264_NonIDRSlice && type_ <= Nalu::H264_IDRSlice);
132  is_video_slice_ =
133  (type_ == Nalu::H264_NonIDRSlice || type_ == Nalu::H264_IDRSlice);
134  can_start_access_unit_ =
135  (is_vcl_ || type_ == Nalu::H264_AUD || type_ == Nalu::H264_SPS ||
136  type_ == Nalu::H264_PPS || type_ == Nalu::H264_SEIMessage ||
137  (type_ >= Nalu::H264_PrefixNALUnit && type_ <= Nalu::H264_Reserved18));
138  return true;
139 }
140 
141 // ITU-T H.265 (04/2015) 7.4.2.2 NAL unit header semantics
142 bool Nalu::InitializeFromH265(const uint8_t* data, uint64_t size) {
143  DCHECK(data);
144  if (size < 2)
145  return false;
146  const uint16_t header = (data[0] << 8) | data[1];
147  if ((header & 0x8000) != 0) {
148  LOG(WARNING) << "forbidden_zero_bit shall be equal to 0 (header 0x"
149  << std::hex << header << ").";
150  return false;
151  }
152 
153  data_ = data;
154  header_size_ = 2;
155  payload_size_ = size - header_size_;
156 
157  type_ = (header >> 9) & 0x3F;
158  nuh_layer_id_ = (header >> 3) & 0x3F;
159  const int nuh_temporal_id_plus1 = header & 0x7;
160  if (nuh_temporal_id_plus1 == 0) {
161  LOG(WARNING) << "nul_temporal_id_plus1 shall not be equal to 0 (header 0x"
162  << std::hex << header << ").";
163  return false;
164  }
165  nuh_temporal_id_ = nuh_temporal_id_plus1 - 1;
166 
167  if (type_ == Nalu::H265_EOB && nuh_layer_id_ != 0) {
168  LOG(WARNING) << "nuh_layer_id shall be equal to 0 for nalu type " << type_
169  << " (header 0x" << std::hex << header << ").";
170  return false;
171  }
172 
173  // Reserved NAL units are not treated as valid NAL units here.
174  if ((type_ >= Nalu::H265_RSV_VCL_N10 && type_ <= Nalu::H265_RSV_VCL_R15) ||
175  (type_ >= Nalu::H265_RSV_IRAP_VCL22 && type_ < Nalu::H265_RSV_VCL31) ||
176  (type_ >= Nalu::H265_RSV_NVCL41)) {
177  VLOG(1) << "Unspecified or reserved nal_unit_type " << type_
178  << " (header 0x" << std::hex << header << ").";
179  // Allow reserved NAL units. Some encoders and extended codecs use the
180  // reserved NAL units to carry their private data. For example, Dolby Vision
181  // uses NAL unit type 62.
182  } else if ((type_ >= Nalu::H265_BLA_W_LP &&
183  type_ <= Nalu::H265_RSV_IRAP_VCL23) ||
184  type_ == Nalu::H265_VPS || type_ == Nalu::H265_SPS ||
185  type_ == Nalu::H265_EOS || type_ == Nalu::H265_EOB) {
186  if (nuh_temporal_id_ != 0) {
187  LOG(WARNING) << "TemporalId shall be equal to 0 for nalu type " << type_
188  << " (header 0x" << std::hex << header << ").";
189  return false;
190  }
191  } else if (type_ == Nalu::H265_TSA_N || type_ == Nalu::H265_TSA_R ||
192  (nuh_layer_id_ == 0 &&
193  (type_ == Nalu::H265_STSA_N || type_ == Nalu::H265_STSA_R))) {
194  if (nuh_temporal_id_ == 0) {
195  LOG(WARNING) << "TemporalId shall not be equal to 0 for nalu type "
196  << type_ << " (header 0x" << std::hex << header << ").";
197  return false;
198  }
199  }
200 
201  is_aud_ = type_ == H265_AUD;
202  is_vcl_ = type_ >= Nalu::H265_TRAIL_N && type_ <= Nalu::H265_RSV_VCL31;
203  is_video_slice_ = is_vcl_;
204  can_start_access_unit_ =
205  nuh_layer_id_ == 0 &&
206  (is_vcl_ || type_ == Nalu::H265_AUD || type_ == Nalu::H265_VPS ||
207  type_ == Nalu::H265_SPS || type_ == Nalu::H265_PPS ||
208  type_ == Nalu::H265_PREFIX_SEI ||
209  (type_ >= Nalu::H265_RSV_NVCL41 && type_ <= Nalu::H265_RSV_NVCL44) ||
210  (type_ >= Nalu::H265_UNSPEC48 && type_ <= Nalu::H265_UNSPEC55));
211  return true;
212 }
213 
214 NaluReader::NaluReader(Nalu::CodecType type,
215  uint8_t nal_length_size,
216  const uint8_t* stream,
217  uint64_t stream_size)
218  : NaluReader(type,
219  nal_length_size,
220  stream,
221  stream_size,
222  std::vector<SubsampleEntry>()) {}
223 
224 NaluReader::NaluReader(Nalu::CodecType type,
225  uint8_t nal_length_size,
226  const uint8_t* stream,
227  uint64_t stream_size,
228  const std::vector<SubsampleEntry>& subsamples)
229  : stream_(stream),
230  stream_size_(stream_size),
231  nalu_type_(type),
232  nalu_length_size_(nal_length_size),
233  format_(nal_length_size == 0 ? kAnnexbByteStreamFormat
234  : kNalUnitStreamFormat),
235  subsamples_(subsamples) {
236  DCHECK(stream);
237 }
238 
239 NaluReader::~NaluReader() {}
240 
241 NaluReader::Result NaluReader::Advance(Nalu* nalu) {
242  if (stream_size_ <= 0)
243  return NaluReader::kEOStream;
244 
245  uint8_t nalu_length_size_or_start_code_size;
246  uint64_t nalu_length;
247  if (format_ == kAnnexbByteStreamFormat) {
248  // This will move |stream_| to the start code.
249  uint64_t nalu_length_with_header;
250  if (!LocateNaluByStartCode(&nalu_length_with_header,
251  &nalu_length_size_or_start_code_size)) {
252  LOG(ERROR) << "Could not find next NALU, bytes left in stream: "
253  << stream_size_;
254  // This is actually an error. Since we always move to past the end of
255  // each NALU, if there is no next start code, then this is the first call
256  // and there are no start codes in the stream.
257  return NaluReader::kInvalidStream;
258  }
259  nalu_length = nalu_length_with_header - nalu_length_size_or_start_code_size;
260  } else {
261  BufferReader reader(stream_, stream_size_);
262  if (IsNaluLengthEncrypted(nalu_length_size_, subsamples_)) {
263  LOG(ERROR) << "NALU length is encrypted.";
264  return NaluReader::kInvalidStream;
265  }
266  if (!reader.ReadNBytesInto8(&nalu_length, nalu_length_size_))
267  return NaluReader::kInvalidStream;
268  nalu_length_size_or_start_code_size = nalu_length_size_;
269 
270  if (nalu_length + nalu_length_size_ > stream_size_) {
271  LOG(ERROR) << "NALU length exceeds stream size: "
272  << stream_size_ << " < " << nalu_length;
273  return NaluReader::kInvalidStream;
274  }
275  if (nalu_length == 0) {
276  LOG(ERROR) << "NALU size 0";
277  return NaluReader::kInvalidStream;
278  }
279  }
280 
281  const uint8_t* nalu_data = stream_ + nalu_length_size_or_start_code_size;
282  if (!nalu->Initialize(nalu_type_, nalu_data, nalu_length))
283  return NaluReader::kInvalidStream;
284 
285  // Move parser state to after this NALU, so next time Advance
286  // is called, we will effectively be skipping it.
287  stream_ += nalu_length_size_or_start_code_size + nalu_length;
288  stream_size_ -= nalu_length_size_or_start_code_size + nalu_length;
289  UpdateSubsamples(nalu_length_size_or_start_code_size + nalu_length,
290  &subsamples_);
291 
292  DVLOG(4) << "NALU type: " << static_cast<int>(nalu->type())
293  << " at: " << reinterpret_cast<const void*>(nalu->data())
294  << " data size: " << nalu->payload_size();
295 
296  return NaluReader::kOk;
297 }
298 
300  if (stream_size_ >= 3) {
301  if (IsStartCode(stream_))
302  return true;
303  }
304  if (stream_size_ >= 4) {
305  if (stream_[0] == 0x00 && IsStartCode(stream_ + 1))
306  return true;
307  }
308  return false;
309 }
310 
311 // static
312 bool NaluReader::FindStartCode(const uint8_t* data,
313  uint64_t data_size,
314  uint64_t* offset,
315  uint8_t* start_code_size) {
316  uint64_t bytes_left = data_size;
317 
318  while (bytes_left >= 3) {
319  if (IsStartCode(data)) {
320  // Found three-byte start code, set pointer at its beginning.
321  *offset = data_size - bytes_left;
322  *start_code_size = 3;
323 
324  // If there is a zero byte before this start code,
325  // then it's actually a four-byte start code, so backtrack one byte.
326  if (*offset > 0 && *(data - 1) == 0x00) {
327  --(*offset);
328  ++(*start_code_size);
329  }
330 
331  return true;
332  }
333 
334  ++data;
335  --bytes_left;
336  }
337 
338  // End of data: offset is pointing to the first byte that was not considered
339  // as a possible start of a start code.
340  *offset = data_size - bytes_left;
341  *start_code_size = 0;
342  return false;
343 }
344 
345 // static
347  const uint8_t* data,
348  uint64_t data_size,
349  uint64_t* offset,
350  uint8_t* start_code_size,
351  const std::vector<SubsampleEntry>& subsamples) {
352  if (subsamples.empty()) {
353  return FindStartCode(data, data_size, offset, start_code_size);
354  }
355 
356  uint64_t current_offset = 0;
357  for (const SubsampleEntry& subsample : subsamples) {
358  uint16_t clear_bytes = subsample.clear_bytes;
359  if (current_offset + clear_bytes > data_size) {
360  LOG(WARNING) << "The sum of subsample sizes is greater than data_size.";
361  clear_bytes = data_size - current_offset;
362  }
363 
364  // Note that calling FindStartCode() here should get the correct
365  // start_code_size, even tho data + current_offset may be in the middle of
366  // the buffer because data + current_offset - 1 is either it shouldn't be
367  // accessed because it's data - 1 or it is encrypted.
368  const bool found_start_code = FindStartCode(
369  data + current_offset, clear_bytes, offset, start_code_size);
370  if (found_start_code) {
371  *offset += current_offset;
372  return true;
373  }
374  const uint64_t subsample_size =
375  subsample.clear_bytes + subsample.cipher_bytes;
376  current_offset += subsample_size;
377  if (current_offset > data_size) {
378  // Assign data_size here so that the returned offset points to the end of
379  // the data.
380  current_offset = data_size;
381  LOG(WARNING) << "The sum of subsamples is greater than data_size.";
382  break;
383  }
384  }
385 
386  // If there is more that's not specified by the subsample entries, assume it
387  // is in the clear.
388  if (current_offset < data_size) {
389  const bool found_start_code =
390  FindStartCode(data + current_offset, data_size - current_offset, offset,
391  start_code_size);
392  *offset += current_offset;
393  return found_start_code;
394  }
395 
396  // End of data: offset is pointing to the first byte that was not considered
397  // as a possible start of a start code.
398  *offset = current_offset;
399  *start_code_size = 0;
400  return false;
401 }
402 
403 bool NaluReader::LocateNaluByStartCode(uint64_t* nalu_size,
404  uint8_t* start_code_size) {
405  // Find the start code of next NALU.
406  uint64_t nalu_start_off = 0;
407  uint8_t annexb_start_code_size = 0;
409  stream_, stream_size_,
410  &nalu_start_off, &annexb_start_code_size, subsamples_)) {
411  DVLOG(4) << "Could not find start code, end of stream?";
412  return false;
413  }
414 
415  // Move the stream to the beginning of the NALU (pointing at the start code).
416  stream_ += nalu_start_off;
417  stream_size_ -= nalu_start_off;
418  // Shift the subsamples so that next call to FindStartCode() takes the updated
419  // subsample info.
420  UpdateSubsamples(nalu_start_off, &subsamples_);
421 
422  const uint8_t* nalu_data = stream_ + annexb_start_code_size;
423  // This is a temporary subsample entries for finding next nalu. subsamples_
424  // should not be updated below.
425  std::vector<SubsampleEntry> subsamples_for_finding_next_nalu;
426  if (!subsamples_.empty()) {
427  subsamples_for_finding_next_nalu = subsamples_;
428  UpdateSubsamples(annexb_start_code_size, &subsamples_for_finding_next_nalu);
429  }
430  uint64_t max_nalu_data_size = stream_size_ - annexb_start_code_size;
431  if (max_nalu_data_size <= 0) {
432  DVLOG(3) << "End of stream";
433  return false;
434  }
435 
436  // Find the start code of next NALU;
437  // if successful, |nalu_size_without_start_code| is the number of bytes from
438  // after previous start code to before this one;
439  // if next start code is not found, it is still a valid NALU since there
440  // are some bytes left after the first start code: all the remaining bytes
441  // belong to the current NALU.
442  uint64_t nalu_size_without_start_code = 0;
443  uint8_t next_start_code_size = 0;
444  while (true) {
446  nalu_data, max_nalu_data_size,
447  &nalu_size_without_start_code, &next_start_code_size,
448  subsamples_for_finding_next_nalu)) {
449  nalu_data += max_nalu_data_size;
450  break;
451  }
452 
453  nalu_data += nalu_size_without_start_code + next_start_code_size;
454  max_nalu_data_size -= nalu_size_without_start_code + next_start_code_size;
455  UpdateSubsamples(nalu_size_without_start_code + next_start_code_size,
456  &subsamples_for_finding_next_nalu);
457  // If it is not a valid NAL unit, we will continue searching. This is to
458  // handle the case where emulation prevention are not applied.
459  Nalu nalu;
460  if (nalu.Initialize(nalu_type_, nalu_data, max_nalu_data_size)) {
461  nalu_data -= next_start_code_size;
462  break;
463  }
464  LOG(WARNING) << "Seeing invalid NAL unit. Emulation prevention may not "
465  "have been applied properly. Assuming it is part of the "
466  "previous NAL unit.";
467  }
468  *nalu_size = nalu_data - stream_;
469  *start_code_size = annexb_start_code_size;
470  return true;
471 }
472 
473 } // namespace media
474 } // namespace shaka
-
const uint8_t * data() const
This is the pointer to the Nalu data, pointing to the header.
Definition: nalu_reader.h:97
- -
STL namespace.
- -
All the methods that are virtual are virtual for mocking.
-
bool ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULT
-
Result Advance(Nalu *nalu)
Definition: nalu_reader.cc:241
- -
NaluReader(Nalu::CodecType type, uint8_t nal_length_size, const uint8_t *stream, uint64_t stream_size)
Definition: nalu_reader.cc:214
-
int type() const
Definition: nalu_reader.h:113
- -
static bool FindStartCodeInClearRange(const uint8_t *data, uint64_t data_size, uint64_t *offset, uint8_t *start_code_size, const std::vector< SubsampleEntry > &subsamples)
Definition: nalu_reader.cc:346
-
uint64_t payload_size() const
Size of this Nalu minus header_size().
Definition: nalu_reader.h:102
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/nalu_reader.h"
+
8 
+
9 #include <iostream>
+
10 
+
11 #include "packager/base/logging.h"
+
12 #include "packager/media/base/buffer_reader.h"
+
13 #include "packager/media/codecs/h264_parser.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 
+
18 namespace {
+
19 inline bool IsStartCode(const uint8_t* data) {
+
20  return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01;
+
21 }
+
22 
+
23 // Edits |subsamples| given the number of consumed bytes.
+
24 void UpdateSubsamples(uint64_t consumed_bytes,
+
25  std::vector<SubsampleEntry>* subsamples) {
+
26  if (consumed_bytes == 0 || subsamples->empty()) {
+
27  return;
+
28  }
+
29  size_t num_entries_to_delete = 0;
+
30  for (SubsampleEntry& subsample : *subsamples) {
+
31  if (subsample.clear_bytes > consumed_bytes) {
+
32  subsample.clear_bytes -= consumed_bytes;
+
33  consumed_bytes = 0;
+
34  break;
+
35  }
+
36  consumed_bytes -= subsample.clear_bytes;
+
37  subsample.clear_bytes = 0;
+
38 
+
39  if (subsample.cipher_bytes > consumed_bytes) {
+
40  subsample.cipher_bytes -= consumed_bytes;
+
41  consumed_bytes = 0;
+
42  break;
+
43  }
+
44  consumed_bytes -= subsample.cipher_bytes;
+
45  subsample.cipher_bytes = 0;
+
46  ++num_entries_to_delete;
+
47  }
+
48 
+
49  subsamples->erase(subsamples->begin(),
+
50  subsamples->begin() + num_entries_to_delete);
+
51 }
+
52 
+
53 bool IsNaluLengthEncrypted(
+
54  uint8_t nalu_length_size,
+
55  const std::vector<SubsampleEntry>& subsamples) {
+
56  if (subsamples.empty())
+
57  return false;
+
58 
+
59  for (const SubsampleEntry& subsample : subsamples) {
+
60  if (subsample.clear_bytes >= nalu_length_size) {
+
61  return false;
+
62  }
+
63  nalu_length_size -= subsample.clear_bytes;
+
64  if (subsample.cipher_bytes > 0) {
+
65  return true;
+
66  }
+
67  }
+
68  // Ran out of subsamples. Assume the rest is in the clear.
+
69  return false;
+
70 }
+
71 } // namespace
+
72 
+
73 Nalu::Nalu() = default;
+
74 
+
75 bool Nalu::Initialize(CodecType type,
+
76  const uint8_t* data,
+
77  uint64_t size) {
+
78  if (type == Nalu::kH264) {
+
79  return InitializeFromH264(data, size);
+
80  } else {
+
81  DCHECK_EQ(Nalu::kH265, type);
+
82  return InitializeFromH265(data, size);
+
83  }
+
84 }
+
85 
+
86 // ITU-T H.264 (02/2014) 7.4.1 NAL unit semantics
+
87 bool Nalu::InitializeFromH264(const uint8_t* data, uint64_t size) {
+
88  DCHECK(data);
+
89  if (size == 0)
+
90  return false;
+
91  const uint8_t header = data[0];
+
92  if ((header & 0x80) != 0) {
+
93  LOG(WARNING) << "forbidden_zero_bit shall be equal to 0 (header 0x"
+
94  << std::hex << static_cast<int>(header) << ").";
+
95  return false;
+
96  }
+
97 
+
98  data_ = data;
+
99  header_size_ = 1;
+
100  payload_size_ = size - header_size_;
+
101  ref_idc_ = (header >> 5) & 0x3;
+
102  type_ = header & 0x1F;
+
103 
+
104  // Reserved NAL units are not treated as valid NAL units here.
+
105  if (type_ == Nalu::H264_Unspecified || type_ == Nalu::H264_Reserved17 ||
+
106  type_ == Nalu::H264_Reserved18 || type_ >= Nalu::H264_Reserved22) {
+
107  VLOG(1) << "Unspecified or reserved nal_unit_type " << type_
+
108  << " (header 0x" << std::hex << static_cast<int>(header) << ").";
+
109  // Allow reserved NAL units. Some encoders and extended codecs use the
+
110  // reserved NAL units to carry their private data.
+
111  } else if (type_ == Nalu::H264_IDRSlice || type_ == Nalu::H264_SPS ||
+
112  type_ == Nalu::H264_SPSExtension ||
+
113  type_ == Nalu::H264_SubsetSPS || type_ == Nalu::H264_PPS) {
+
114  if (ref_idc_ == 0) {
+
115  LOG(WARNING) << "nal_ref_idc shall not be equal to 0 for nalu type "
+
116  << type_ << " (header 0x" << std::hex
+
117  << static_cast<int>(header) << ").";
+
118  return false;
+
119  }
+
120  } else if (type_ == Nalu::H264_SEIMessage ||
+
121  (type_ >= Nalu::H264_AUD && type_ <= Nalu::H264_FillerData)) {
+
122  if (ref_idc_ != 0) {
+
123  LOG(WARNING) << "nal_ref_idc shall be equal to 0 for nalu type " << type_
+
124  << " (header 0x" << std::hex << static_cast<int>(header)
+
125  << ").";
+
126  return false;
+
127  }
+
128  }
+
129 
+
130  is_aud_ = type_ == H264_AUD;
+
131  is_vcl_ = (type_ >= Nalu::H264_NonIDRSlice && type_ <= Nalu::H264_IDRSlice);
+
132  is_video_slice_ =
+
133  (type_ == Nalu::H264_NonIDRSlice || type_ == Nalu::H264_IDRSlice);
+
134  can_start_access_unit_ =
+
135  (is_vcl_ || type_ == Nalu::H264_AUD || type_ == Nalu::H264_SPS ||
+
136  type_ == Nalu::H264_PPS || type_ == Nalu::H264_SEIMessage ||
+
137  (type_ >= Nalu::H264_PrefixNALUnit && type_ <= Nalu::H264_Reserved18));
+
138  return true;
+
139 }
+
140 
+
141 // ITU-T H.265 (04/2015) 7.4.2.2 NAL unit header semantics
+
142 bool Nalu::InitializeFromH265(const uint8_t* data, uint64_t size) {
+
143  DCHECK(data);
+
144  if (size < 2)
+
145  return false;
+
146  const uint16_t header = (data[0] << 8) | data[1];
+
147  if ((header & 0x8000) != 0) {
+
148  LOG(WARNING) << "forbidden_zero_bit shall be equal to 0 (header 0x"
+
149  << std::hex << header << ").";
+
150  return false;
+
151  }
+
152 
+
153  data_ = data;
+
154  header_size_ = 2;
+
155  payload_size_ = size - header_size_;
+
156 
+
157  type_ = (header >> 9) & 0x3F;
+
158  nuh_layer_id_ = (header >> 3) & 0x3F;
+
159  const int nuh_temporal_id_plus1 = header & 0x7;
+
160  if (nuh_temporal_id_plus1 == 0) {
+
161  LOG(WARNING) << "nul_temporal_id_plus1 shall not be equal to 0 (header 0x"
+
162  << std::hex << header << ").";
+
163  return false;
+
164  }
+
165  nuh_temporal_id_ = nuh_temporal_id_plus1 - 1;
+
166 
+
167  if (type_ == Nalu::H265_EOB && nuh_layer_id_ != 0) {
+
168  LOG(WARNING) << "nuh_layer_id shall be equal to 0 for nalu type " << type_
+
169  << " (header 0x" << std::hex << header << ").";
+
170  return false;
+
171  }
+
172 
+
173  // Reserved NAL units are not treated as valid NAL units here.
+
174  if ((type_ >= Nalu::H265_RSV_VCL_N10 && type_ <= Nalu::H265_RSV_VCL_R15) ||
+
175  (type_ >= Nalu::H265_RSV_IRAP_VCL22 && type_ < Nalu::H265_RSV_VCL31) ||
+
176  (type_ >= Nalu::H265_RSV_NVCL41)) {
+
177  VLOG(1) << "Unspecified or reserved nal_unit_type " << type_
+
178  << " (header 0x" << std::hex << header << ").";
+
179  // Allow reserved NAL units. Some encoders and extended codecs use the
+
180  // reserved NAL units to carry their private data. For example, Dolby Vision
+
181  // uses NAL unit type 62.
+
182  } else if ((type_ >= Nalu::H265_BLA_W_LP &&
+
183  type_ <= Nalu::H265_RSV_IRAP_VCL23) ||
+
184  type_ == Nalu::H265_VPS || type_ == Nalu::H265_SPS ||
+
185  type_ == Nalu::H265_EOS || type_ == Nalu::H265_EOB) {
+
186  if (nuh_temporal_id_ != 0) {
+
187  LOG(WARNING) << "TemporalId shall be equal to 0 for nalu type " << type_
+
188  << " (header 0x" << std::hex << header << ").";
+
189  return false;
+
190  }
+
191  } else if (type_ == Nalu::H265_TSA_N || type_ == Nalu::H265_TSA_R ||
+
192  (nuh_layer_id_ == 0 &&
+
193  (type_ == Nalu::H265_STSA_N || type_ == Nalu::H265_STSA_R))) {
+
194  if (nuh_temporal_id_ == 0) {
+
195  LOG(WARNING) << "TemporalId shall not be equal to 0 for nalu type "
+
196  << type_ << " (header 0x" << std::hex << header << ").";
+
197  return false;
+
198  }
+
199  }
+
200 
+
201  is_aud_ = type_ == H265_AUD;
+
202  is_vcl_ = type_ >= Nalu::H265_TRAIL_N && type_ <= Nalu::H265_RSV_VCL31;
+
203  is_video_slice_ = is_vcl_;
+
204  can_start_access_unit_ =
+
205  nuh_layer_id_ == 0 &&
+
206  (is_vcl_ || type_ == Nalu::H265_AUD || type_ == Nalu::H265_VPS ||
+
207  type_ == Nalu::H265_SPS || type_ == Nalu::H265_PPS ||
+
208  type_ == Nalu::H265_PREFIX_SEI ||
+
209  (type_ >= Nalu::H265_RSV_NVCL41 && type_ <= Nalu::H265_RSV_NVCL44) ||
+
210  (type_ >= Nalu::H265_UNSPEC48 && type_ <= Nalu::H265_UNSPEC55));
+
211  return true;
+
212 }
+
213 
+
214 NaluReader::NaluReader(Nalu::CodecType type,
+
215  uint8_t nal_length_size,
+
216  const uint8_t* stream,
+
217  uint64_t stream_size)
+
218  : NaluReader(type,
+
219  nal_length_size,
+
220  stream,
+
221  stream_size,
+
222  std::vector<SubsampleEntry>()) {}
+
223 
+
224 NaluReader::NaluReader(Nalu::CodecType type,
+
225  uint8_t nal_length_size,
+
226  const uint8_t* stream,
+
227  uint64_t stream_size,
+
228  const std::vector<SubsampleEntry>& subsamples)
+
229  : stream_(stream),
+
230  stream_size_(stream_size),
+
231  nalu_type_(type),
+
232  nalu_length_size_(nal_length_size),
+
233  format_(nal_length_size == 0 ? kAnnexbByteStreamFormat
+
234  : kNalUnitStreamFormat),
+
235  subsamples_(subsamples) {
+
236  DCHECK(stream);
+
237 }
+
238 
+
239 NaluReader::~NaluReader() {}
+
240 
+
241 NaluReader::Result NaluReader::Advance(Nalu* nalu) {
+
242  if (stream_size_ <= 0)
+
243  return NaluReader::kEOStream;
+
244 
+
245  uint8_t nalu_length_size_or_start_code_size;
+
246  uint64_t nalu_length;
+
247  if (format_ == kAnnexbByteStreamFormat) {
+
248  // This will move |stream_| to the start code.
+
249  uint64_t nalu_length_with_header;
+
250  if (!LocateNaluByStartCode(&nalu_length_with_header,
+
251  &nalu_length_size_or_start_code_size)) {
+
252  LOG(ERROR) << "Could not find next NALU, bytes left in stream: "
+
253  << stream_size_;
+
254  // This is actually an error. Since we always move to past the end of
+
255  // each NALU, if there is no next start code, then this is the first call
+
256  // and there are no start codes in the stream.
+
257  return NaluReader::kInvalidStream;
+
258  }
+
259  nalu_length = nalu_length_with_header - nalu_length_size_or_start_code_size;
+
260  } else {
+
261  BufferReader reader(stream_, stream_size_);
+
262  if (IsNaluLengthEncrypted(nalu_length_size_, subsamples_)) {
+
263  LOG(ERROR) << "NALU length is encrypted.";
+
264  return NaluReader::kInvalidStream;
+
265  }
+
266  if (!reader.ReadNBytesInto8(&nalu_length, nalu_length_size_))
+
267  return NaluReader::kInvalidStream;
+
268  nalu_length_size_or_start_code_size = nalu_length_size_;
+
269 
+
270  if (nalu_length + nalu_length_size_ > stream_size_) {
+
271  LOG(ERROR) << "NALU length exceeds stream size: "
+
272  << stream_size_ << " < " << nalu_length;
+
273  return NaluReader::kInvalidStream;
+
274  }
+
275  if (nalu_length == 0) {
+
276  LOG(ERROR) << "NALU size 0";
+
277  return NaluReader::kInvalidStream;
+
278  }
+
279  }
+
280 
+
281  const uint8_t* nalu_data = stream_ + nalu_length_size_or_start_code_size;
+
282  if (!nalu->Initialize(nalu_type_, nalu_data, nalu_length))
+
283  return NaluReader::kInvalidStream;
+
284 
+
285  // Move parser state to after this NALU, so next time Advance
+
286  // is called, we will effectively be skipping it.
+
287  stream_ += nalu_length_size_or_start_code_size + nalu_length;
+
288  stream_size_ -= nalu_length_size_or_start_code_size + nalu_length;
+
289  UpdateSubsamples(nalu_length_size_or_start_code_size + nalu_length,
+
290  &subsamples_);
+
291 
+
292  DVLOG(4) << "NALU type: " << static_cast<int>(nalu->type())
+
293  << " at: " << reinterpret_cast<const void*>(nalu->data())
+
294  << " data size: " << nalu->payload_size();
+
295 
+
296  return NaluReader::kOk;
+
297 }
+
298 
+ +
300  if (stream_size_ >= 3) {
+
301  if (IsStartCode(stream_))
+
302  return true;
+
303  }
+
304  if (stream_size_ >= 4) {
+
305  if (stream_[0] == 0x00 && IsStartCode(stream_ + 1))
+
306  return true;
+
307  }
+
308  return false;
+
309 }
+
310 
+
311 // static
+
312 bool NaluReader::FindStartCode(const uint8_t* data,
+
313  uint64_t data_size,
+
314  uint64_t* offset,
+
315  uint8_t* start_code_size) {
+
316  uint64_t bytes_left = data_size;
+
317 
+
318  while (bytes_left >= 3) {
+
319  if (IsStartCode(data)) {
+
320  // Found three-byte start code, set pointer at its beginning.
+
321  *offset = data_size - bytes_left;
+
322  *start_code_size = 3;
+
323 
+
324  // If there is a zero byte before this start code,
+
325  // then it's actually a four-byte start code, so backtrack one byte.
+
326  if (*offset > 0 && *(data - 1) == 0x00) {
+
327  --(*offset);
+
328  ++(*start_code_size);
+
329  }
+
330 
+
331  return true;
+
332  }
+
333 
+
334  ++data;
+
335  --bytes_left;
+
336  }
+
337 
+
338  // End of data: offset is pointing to the first byte that was not considered
+
339  // as a possible start of a start code.
+
340  *offset = data_size - bytes_left;
+
341  *start_code_size = 0;
+
342  return false;
+
343 }
+
344 
+
345 // static
+ +
347  const uint8_t* data,
+
348  uint64_t data_size,
+
349  uint64_t* offset,
+
350  uint8_t* start_code_size,
+
351  const std::vector<SubsampleEntry>& subsamples) {
+
352  if (subsamples.empty()) {
+
353  return FindStartCode(data, data_size, offset, start_code_size);
+
354  }
+
355 
+
356  uint64_t current_offset = 0;
+
357  for (const SubsampleEntry& subsample : subsamples) {
+
358  uint16_t clear_bytes = subsample.clear_bytes;
+
359  if (current_offset + clear_bytes > data_size) {
+
360  LOG(WARNING) << "The sum of subsample sizes is greater than data_size.";
+
361  clear_bytes = data_size - current_offset;
+
362  }
+
363 
+
364  // Note that calling FindStartCode() here should get the correct
+
365  // start_code_size, even tho data + current_offset may be in the middle of
+
366  // the buffer because data + current_offset - 1 is either it shouldn't be
+
367  // accessed because it's data - 1 or it is encrypted.
+
368  const bool found_start_code = FindStartCode(
+
369  data + current_offset, clear_bytes, offset, start_code_size);
+
370  if (found_start_code) {
+
371  *offset += current_offset;
+
372  return true;
+
373  }
+
374  const uint64_t subsample_size =
+
375  subsample.clear_bytes + subsample.cipher_bytes;
+
376  current_offset += subsample_size;
+
377  if (current_offset > data_size) {
+
378  // Assign data_size here so that the returned offset points to the end of
+
379  // the data.
+
380  current_offset = data_size;
+
381  LOG(WARNING) << "The sum of subsamples is greater than data_size.";
+
382  break;
+
383  }
+
384  }
+
385 
+
386  // If there is more that's not specified by the subsample entries, assume it
+
387  // is in the clear.
+
388  if (current_offset < data_size) {
+
389  const bool found_start_code =
+
390  FindStartCode(data + current_offset, data_size - current_offset, offset,
+
391  start_code_size);
+
392  *offset += current_offset;
+
393  return found_start_code;
+
394  }
+
395 
+
396  // End of data: offset is pointing to the first byte that was not considered
+
397  // as a possible start of a start code.
+
398  *offset = current_offset;
+
399  *start_code_size = 0;
+
400  return false;
+
401 }
+
402 
+
403 bool NaluReader::LocateNaluByStartCode(uint64_t* nalu_size,
+
404  uint8_t* start_code_size) {
+
405  // Find the start code of next NALU.
+
406  uint64_t nalu_start_off = 0;
+
407  uint8_t annexb_start_code_size = 0;
+ +
409  stream_, stream_size_,
+
410  &nalu_start_off, &annexb_start_code_size, subsamples_)) {
+
411  DVLOG(4) << "Could not find start code, end of stream?";
+
412  return false;
+
413  }
+
414 
+
415  // Move the stream to the beginning of the NALU (pointing at the start code).
+
416  stream_ += nalu_start_off;
+
417  stream_size_ -= nalu_start_off;
+
418  // Shift the subsamples so that next call to FindStartCode() takes the updated
+
419  // subsample info.
+
420  UpdateSubsamples(nalu_start_off, &subsamples_);
+
421 
+
422  const uint8_t* nalu_data = stream_ + annexb_start_code_size;
+
423  // This is a temporary subsample entries for finding next nalu. subsamples_
+
424  // should not be updated below.
+
425  std::vector<SubsampleEntry> subsamples_for_finding_next_nalu;
+
426  if (!subsamples_.empty()) {
+
427  subsamples_for_finding_next_nalu = subsamples_;
+
428  UpdateSubsamples(annexb_start_code_size, &subsamples_for_finding_next_nalu);
+
429  }
+
430  uint64_t max_nalu_data_size = stream_size_ - annexb_start_code_size;
+
431  if (max_nalu_data_size <= 0) {
+
432  DVLOG(3) << "End of stream";
+
433  return false;
+
434  }
+
435 
+
436  // Find the start code of next NALU;
+
437  // if successful, |nalu_size_without_start_code| is the number of bytes from
+
438  // after previous start code to before this one;
+
439  // if next start code is not found, it is still a valid NALU since there
+
440  // are some bytes left after the first start code: all the remaining bytes
+
441  // belong to the current NALU.
+
442  uint64_t nalu_size_without_start_code = 0;
+
443  uint8_t next_start_code_size = 0;
+
444  while (true) {
+ +
446  nalu_data, max_nalu_data_size,
+
447  &nalu_size_without_start_code, &next_start_code_size,
+
448  subsamples_for_finding_next_nalu)) {
+
449  nalu_data += max_nalu_data_size;
+
450  break;
+
451  }
+
452 
+
453  nalu_data += nalu_size_without_start_code + next_start_code_size;
+
454  max_nalu_data_size -= nalu_size_without_start_code + next_start_code_size;
+
455  UpdateSubsamples(nalu_size_without_start_code + next_start_code_size,
+
456  &subsamples_for_finding_next_nalu);
+
457  // If it is not a valid NAL unit, we will continue searching. This is to
+
458  // handle the case where emulation prevention are not applied.
+
459  Nalu nalu;
+
460  if (nalu.Initialize(nalu_type_, nalu_data, max_nalu_data_size)) {
+
461  nalu_data -= next_start_code_size;
+
462  break;
+
463  }
+
464  LOG(WARNING) << "Seeing invalid NAL unit. Emulation prevention may not "
+
465  "have been applied properly. Assuming it is part of the "
+
466  "previous NAL unit.";
+
467  }
+
468  *nalu_size = nalu_data - stream_;
+
469  *start_code_size = annexb_start_code_size;
+
470  return true;
+
471 }
+
472 
+
473 } // namespace media
+
474 } // namespace shaka
+ +
bool ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULT
+ +
NaluReader(Nalu::CodecType type, uint8_t nal_length_size, const uint8_t *stream, uint64_t stream_size)
Definition: nalu_reader.cc:214
+ +
static bool FindStartCodeInClearRange(const uint8_t *data, uint64_t data_size, uint64_t *offset, uint8_t *start_code_size, const std::vector< SubsampleEntry > &subsamples)
Definition: nalu_reader.cc:346
+
Result Advance(Nalu *nalu)
Definition: nalu_reader.cc:241
+ +
const uint8_t * data() const
This is the pointer to the Nalu data, pointing to the header.
Definition: nalu_reader.h:97
+
int type() const
Definition: nalu_reader.h:113
+
uint64_t payload_size() const
Size of this Nalu minus header_size().
Definition: nalu_reader.h:102
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d1/df9/structshaka_1_1media_1_1mp4_1_1VideoMediaHeader-members.html b/docs/d1/df9/structshaka_1_1media_1_1mp4_1_1VideoMediaHeader-members.html index 991b4a6533..5790fbe7c5 100644 --- a/docs/d1/df9/structshaka_1_1media_1_1mp4_1_1VideoMediaHeader-members.html +++ b/docs/d1/df9/structshaka_1_1media_1_1mp4_1_1VideoMediaHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d02/timestamp_8h_source.html b/docs/d2/d02/timestamp_8h_source.html index 1533786049..ada2695928 100644 --- a/docs/d2/d02/timestamp_8h_source.html +++ b/docs/d2/d02/timestamp_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/timestamp.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
timestamp.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 
8 #ifndef PACKAGER_MEDIA_BASE_TIMESTAMP_H_
9 #define PACKAGER_MEDIA_BASE_TIMESTAMP_H_
10 
11 #include <stdint.h>
12 
13 #include <limits>
14 
15 namespace shaka {
16 namespace media {
17 
18 const int64_t kNoTimestamp = std::numeric_limits<int64_t>::min();
19 const int64_t kInfiniteDuration = std::numeric_limits<int64_t>::max();
20 
21 } // namespace media
22 } // namespace shaka
23 
24 #endif // PACKAGER_MEDIA_BASE_TIMESTAMP_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 
+
8 #ifndef PACKAGER_MEDIA_BASE_TIMESTAMP_H_
+
9 #define PACKAGER_MEDIA_BASE_TIMESTAMP_H_
+
10 
+
11 #include <stdint.h>
+
12 
+
13 #include <limits>
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 
+
18 const int64_t kNoTimestamp = std::numeric_limits<int64_t>::min();
+
19 const int64_t kInfiniteDuration = std::numeric_limits<int64_t>::max();
+
20 
+
21 } // namespace media
+
22 } // namespace shaka
+
23 
+
24 #endif // PACKAGER_MEDIA_BASE_TIMESTAMP_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d0b/classshaka_1_1media_1_1SeekHead-members.html b/docs/d2/d0b/classshaka_1_1media_1_1SeekHead-members.html index d3bece9e21..ad96cf4341 100644 --- a/docs/d2/d0b/classshaka_1_1media_1_1SeekHead-members.html +++ b/docs/d2/d0b/classshaka_1_1media_1_1SeekHead-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d0e/structshaka_1_1media_1_1mp4_1_1NullMediaHeader.html b/docs/d2/d0e/structshaka_1_1media_1_1mp4_1_1NullMediaHeader.html new file mode 100644 index 0000000000..818feb2389 --- /dev/null +++ b/docs/d2/d0e/structshaka_1_1media_1_1mp4_1_1NullMediaHeader.html @@ -0,0 +1,162 @@ + + + + + + + +Shaka Packager SDK: shaka::media::mp4::NullMediaHeader Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::mp4::NullMediaHeader Struct Reference
+
+
+
+Inheritance diagram for shaka::media::mp4::NullMediaHeader:
+
+
+ + +shaka::media::mp4::FullBox +shaka::media::mp4::Box + +
+ + + + + + + + + + + + + + + + + + +

+Public Member Functions

FourCC BoxType () const override
 
- Public Member Functions inherited from shaka::media::mp4::FullBox
uint32_t HeaderSize () const final
 
- Public Member Functions inherited from shaka::media::mp4::Box
bool Parse (BoxReader *reader)
 
void Write (BufferWriter *writer)
 
void WriteHeader (BufferWriter *writer)
 
uint32_t ComputeSize ()
 
uint32_t box_size ()
 
+ + + + + + + + + +

+Additional Inherited Members

- Public Attributes inherited from shaka::media::mp4::FullBox
+uint8_t version = 0
 
+uint32_t flags = 0
 
- Protected Member Functions inherited from shaka::media::mp4::FullBox
bool ReadWriteHeaderInternal (BoxBuffer *buffer) final
 
+

Detailed Description

+
+

Definition at line 606 of file box_definitions.h.

+

Member Function Documentation

+ +

◆ BoxType()

+ +
+
+ + + + + +
+ + + + + + + +
FourCC shaka::media::mp4::NullMediaHeader::BoxType () const
+
+overridevirtual
+
+
Returns
box type.
+ +

Implements shaka::media::mp4::Box.

+ +

Definition at line 2111 of file box_definitions.cc.

+ +
+
+
The documentation for this struct was generated from the following files: +
+ + + + diff --git a/docs/d2/d0e/structshaka_1_1media_1_1mp4_1_1NullMediaHeader.png b/docs/d2/d0e/structshaka_1_1media_1_1mp4_1_1NullMediaHeader.png new file mode 100644 index 0000000000000000000000000000000000000000..3ecf658f1a1c9c9106401bbc2abe2e2da2251629 GIT binary patch literal 1107 zcmeAS@N?(olHy`uVBq!ia0vp^w}7~VgBeI}Yh@J$QW60^A+G=b{|7Q(y!l$%e`o@b z1;z&s9ANFdBM;b*$mZ87uH!SmB9-#OoN;@qN>{iC`1Q}1p&yzXO?$4=GfD|P)d%60!ny6@rp zrFBdBgqU`5uK3IA?42ifn=jiY>hinV+G&#BE8ZD znlb5#Z=;&$y)6sQezxJ)Y`FiD&0yIv*WGv9Ql-Un6{V-2E#oPu>1v^ z^PguVOE*SHAwn zadyp(%}syUqRRDk@@9Xw+j}^6b@iiqjT3P*ZBOpB%|83=R#g6lQ#YjEF3w$|=~4XY zvhUfeuP5~CmY#T5_GII?z2AQFX?n(Ac%7f%W&+Y!s&{8ae7TM@pAY^kAa!8pw78gfvyA9R>Y97Hx1HO0$L>*H z`Rn!l(vQuj?f!pen);f6H&1N0H1Fh&GLwkkcY2?0%FO%6e1vbY_#AjQ<5rl!+4r$q z9$C+D$iTtm+Fpzc=Uf-^)uP{~EWKg-@tFoZB1H zlQ}nMg3+?sdwVnHy}j`1@Zz1P*X3@^im$qnsXX`Vt@SLzPqVk}jPsmvrrb8)`ki_P zdvQ2xq-2$DS^c$L?GHSc&b^i6W>zM3wdLpU$m*yG&$cX|ZPgnmo}IJOdE4?l>yNfu zChxq>x6@Sjw&L#hrVahCc5h~u0S3ptO9wI-{(CmEJ@5tL@8PdZd@pzWVxM?5;?AWf S|EB><00vK2KbLh*2~7ab!W%*W literal 0 HcmV?d00001 diff --git a/docs/d2/d0f/classshaka_1_1MpdBuilder-members.html b/docs/d2/d0f/classshaka_1_1MpdBuilder-members.html index 24e178b57d..b327fa7768 100644 --- a/docs/d2/d0f/classshaka_1_1MpdBuilder-members.html +++ b/docs/d2/d0f/classshaka_1_1MpdBuilder-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
MakePathsRelativeToMpd(const std::string &mpd_path, MediaInfo *media_info)shaka::MpdBuilderstatic MpdBuilder(const MpdOptions &mpd_options)shaka::MpdBuilderexplicit MpdBuilderTest (defined in shaka::MpdBuilder)shaka::MpdBuilderfriend - ToString(std::string *output)shaka::MpdBuildervirtual + ToString(std::string *output) WARN_UNUSED_RESULTshaka::MpdBuildervirtual ~MpdBuilder() (defined in shaka::MpdBuilder)shaka::MpdBuildervirtual
diff --git a/docs/d2/d0f/structshaka_1_1media_1_1wvm_1_1PrevSampleData.html b/docs/d2/d0f/structshaka_1_1media_1_1wvm_1_1PrevSampleData.html index e40e87b4cb..b9c9dc5351 100644 --- a/docs/d2/d0f/structshaka_1_1media_1_1wvm_1_1PrevSampleData.html +++ b/docs/d2/d0f/structshaka_1_1media_1_1wvm_1_1PrevSampleData.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::wvm::PrevSampleData Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
video_sample_durat
diff --git a/docs/d2/d11/classshaka_1_1media_1_1MuxerListener-members.html b/docs/d2/d11/classshaka_1_1media_1_1MuxerListener-members.html index 2995522eb5..4878d4bb21 100644 --- a/docs/d2/d11/classshaka_1_1media_1_1MuxerListener-members.html +++ b/docs/d2/d11/classshaka_1_1media_1_1MuxerListener-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d2/d17/ts__section__pat_8cc_source.html b/docs/d2/d17/ts__section__pat_8cc_source.html index e19d7ea1a0..061e87a859 100644 --- a/docs/d2/d17/ts__section__pat_8cc_source.html +++ b/docs/d2/d17/ts__section__pat_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section_pat.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
ts_section_pat.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/mp2t/ts_section_pat.h"
6 
7 #include <vector>
8 
9 #include "packager/base/logging.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/formats/mp2t/mp2t_common.h"
12 
13 namespace shaka {
14 namespace media {
15 namespace mp2t {
16 
17 TsSectionPat::TsSectionPat(const RegisterPmtCb& register_pmt_cb)
18  : register_pmt_cb_(register_pmt_cb),
19  version_number_(-1) {
20 }
21 
22 TsSectionPat::~TsSectionPat() {
23 }
24 
25 bool TsSectionPat::ParsePsiSection(BitReader* bit_reader) {
26  // Read the fixed section length.
27  int table_id;
28  int section_syntax_indicator;
29  int dummy_zero;
30  int reserved;
31  int section_length;
32  int transport_stream_id;
33  int version_number;
34  int current_next_indicator;
35  int section_number;
36  int last_section_number;
37  RCHECK(bit_reader->ReadBits(8, &table_id));
38  RCHECK(bit_reader->ReadBits(1, &section_syntax_indicator));
39  RCHECK(bit_reader->ReadBits(1, &dummy_zero));
40  RCHECK(bit_reader->ReadBits(2, &reserved));
41  RCHECK(bit_reader->ReadBits(12, &section_length));
42  RCHECK(section_length >= 5);
43  RCHECK(section_length <= 1021);
44  RCHECK(bit_reader->ReadBits(16, &transport_stream_id));
45  RCHECK(bit_reader->ReadBits(2, &reserved));
46  RCHECK(bit_reader->ReadBits(5, &version_number));
47  RCHECK(bit_reader->ReadBits(1, &current_next_indicator));
48  RCHECK(bit_reader->ReadBits(8, &section_number));
49  RCHECK(bit_reader->ReadBits(8, &last_section_number));
50  section_length -= 5;
51 
52  // Perform a few verifications:
53  // - Table ID should be 0 for a PAT.
54  // - section_syntax_indicator should be one.
55  // - section length should not exceed 1021
56  RCHECK(table_id == 0x0);
57  RCHECK(section_syntax_indicator);
58  RCHECK(!dummy_zero);
59 
60  // Both the program table and the CRC have a size multiple of 4.
61  // Note for pmt_pid_count: minus 4 to account for the CRC.
62  RCHECK((section_length % 4) == 0);
63  int pmt_pid_count = (section_length - 4) / 4;
64 
65  // Read the variable length section: program table & crc.
66  std::vector<int> program_number_array(pmt_pid_count);
67  std::vector<int> pmt_pid_array(pmt_pid_count);
68  for (int k = 0; k < pmt_pid_count; k++) {
69  int reserved;
70  RCHECK(bit_reader->ReadBits(16, &program_number_array[k]));
71  RCHECK(bit_reader->ReadBits(3, &reserved));
72  RCHECK(bit_reader->ReadBits(13, &pmt_pid_array[k]));
73  }
74  int crc32;
75  RCHECK(bit_reader->ReadBits(32, &crc32));
76 
77  // Just ignore the PAT if not applicable yet.
78  if (!current_next_indicator) {
79  DVLOG(1) << "Not supported: received a PAT not applicable yet";
80  return true;
81  }
82 
83  // Ignore the program table if it hasn't changed.
84  if (version_number == version_number_)
85  return true;
86 
87  // Both the MSE and the HLS spec specifies that TS streams should convey
88  // exactly one program.
89  if (pmt_pid_count > 1) {
90  DVLOG(1) << "Multiple programs detected in the Mpeg2 TS stream";
91  return false;
92  }
93 
94  // Can now register the PMT.
95 #if !defined(NDEBUG)
96  int expected_version_number = version_number;
97  if (version_number_ >= 0)
98  expected_version_number = (version_number_ + 1) % 32;
99  DVLOG_IF(1, version_number != expected_version_number)
100  << "Unexpected version number: "
101  << version_number << " vs " << version_number_;
102 #endif
103  for (int k = 0; k < pmt_pid_count; k++) {
104  if (program_number_array[k] != 0) {
105  // Program numbers different from 0 correspond to PMT.
106  register_pmt_cb_.Run(program_number_array[k], pmt_pid_array[k]);
107  // Even if there are multiple programs, only one can be supported now.
108  // HLS: "Transport Stream segments MUST contain a single MPEG-2 Program."
109  break;
110  }
111  }
112  version_number_ = version_number;
113 
114  return true;
115 }
116 
117 void TsSectionPat::ResetPsiSection() {
118  version_number_ = -1;
119 }
120 
121 } // namespace mp2t
122 } // namespace media
123 } // namespace shaka
124 
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/mp2t/ts_section_pat.h"
+
6 
+
7 #include <vector>
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/media/base/bit_reader.h"
+
11 #include "packager/media/formats/mp2t/mp2t_common.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 namespace mp2t {
+
16 
+
17 TsSectionPat::TsSectionPat(const RegisterPmtCb& register_pmt_cb)
+
18  : register_pmt_cb_(register_pmt_cb),
+
19  version_number_(-1) {
+
20 }
+
21 
+
22 TsSectionPat::~TsSectionPat() {
+
23 }
+
24 
+
25 bool TsSectionPat::ParsePsiSection(BitReader* bit_reader) {
+
26  // Read the fixed section length.
+
27  int table_id;
+
28  int section_syntax_indicator;
+
29  int dummy_zero;
+
30  int reserved;
+
31  int section_length;
+
32  int transport_stream_id;
+
33  int version_number;
+
34  int current_next_indicator;
+
35  int section_number;
+
36  int last_section_number;
+
37  RCHECK(bit_reader->ReadBits(8, &table_id));
+
38  RCHECK(bit_reader->ReadBits(1, &section_syntax_indicator));
+
39  RCHECK(bit_reader->ReadBits(1, &dummy_zero));
+
40  RCHECK(bit_reader->ReadBits(2, &reserved));
+
41  RCHECK(bit_reader->ReadBits(12, &section_length));
+
42  RCHECK(section_length >= 5);
+
43  RCHECK(section_length <= 1021);
+
44  RCHECK(bit_reader->ReadBits(16, &transport_stream_id));
+
45  RCHECK(bit_reader->ReadBits(2, &reserved));
+
46  RCHECK(bit_reader->ReadBits(5, &version_number));
+
47  RCHECK(bit_reader->ReadBits(1, &current_next_indicator));
+
48  RCHECK(bit_reader->ReadBits(8, &section_number));
+
49  RCHECK(bit_reader->ReadBits(8, &last_section_number));
+
50  section_length -= 5;
+
51 
+
52  // Perform a few verifications:
+
53  // - Table ID should be 0 for a PAT.
+
54  // - section_syntax_indicator should be one.
+
55  // - section length should not exceed 1021
+
56  RCHECK(table_id == 0x0);
+
57  RCHECK(section_syntax_indicator);
+
58  RCHECK(!dummy_zero);
+
59 
+
60  // Both the program table and the CRC have a size multiple of 4.
+
61  // Note for pmt_pid_count: minus 4 to account for the CRC.
+
62  RCHECK((section_length % 4) == 0);
+
63  int pmt_pid_count = (section_length - 4) / 4;
+
64 
+
65  // Read the variable length section: program table & crc.
+
66  std::vector<int> program_number_array(pmt_pid_count);
+
67  std::vector<int> pmt_pid_array(pmt_pid_count);
+
68  for (int k = 0; k < pmt_pid_count; k++) {
+
69  int reserved;
+
70  RCHECK(bit_reader->ReadBits(16, &program_number_array[k]));
+
71  RCHECK(bit_reader->ReadBits(3, &reserved));
+
72  RCHECK(bit_reader->ReadBits(13, &pmt_pid_array[k]));
+
73  }
+
74  int crc32;
+
75  RCHECK(bit_reader->ReadBits(32, &crc32));
+
76 
+
77  // Just ignore the PAT if not applicable yet.
+
78  if (!current_next_indicator) {
+
79  DVLOG(1) << "Not supported: received a PAT not applicable yet";
+
80  return true;
+
81  }
+
82 
+
83  // Ignore the program table if it hasn't changed.
+
84  if (version_number == version_number_)
+
85  return true;
+
86 
+
87  // Both the MSE and the HLS spec specifies that TS streams should convey
+
88  // exactly one program.
+
89  if (pmt_pid_count > 1) {
+
90  LOG(ERROR) << "Multiple programs detected in the Mpeg2 TS stream";
+
91  return false;
+
92  }
+
93 
+
94  // Can now register the PMT.
+
95 #if !defined(NDEBUG)
+
96  int expected_version_number = version_number;
+
97  if (version_number_ >= 0)
+
98  expected_version_number = (version_number_ + 1) % 32;
+
99  DVLOG_IF(1, version_number != expected_version_number)
+
100  << "Unexpected version number: "
+
101  << version_number << " vs " << version_number_;
+
102 #endif
+
103  for (int k = 0; k < pmt_pid_count; k++) {
+
104  if (program_number_array[k] != 0) {
+
105  // Program numbers different from 0 correspond to PMT.
+
106  register_pmt_cb_.Run(program_number_array[k], pmt_pid_array[k]);
+
107  // Even if there are multiple programs, only one can be supported now.
+
108  // HLS: "Transport Stream segments MUST contain a single MPEG-2 Program."
+
109  break;
+
110  }
+
111  }
+
112  version_number_ = version_number;
+
113 
+
114  return true;
+
115 }
+
116 
+
117 void TsSectionPat::ResetPsiSection() {
+
118  version_number_ = -1;
+
119 }
+
120 
+
121 } // namespace mp2t
+
122 } // namespace media
+
123 } // namespace shaka
+
124 
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d1f/structshaka_1_1ChunkingParams.html b/docs/d2/d1f/structshaka_1_1ChunkingParams.html index 0dc8d39079..3d499218bd 100644 --- a/docs/d2/d1f/structshaka_1_1ChunkingParams.html +++ b/docs/d2/d1f/structshaka_1_1ChunkingParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::ChunkingParams Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d20/classshaka_1_1Status.html b/docs/d2/d20/classshaka_1_1Status.html index 1bae7ecc6b..6846b24ae6 100644 --- a/docs/d2/d20/classshaka_1_1Status.html +++ b/docs/d2/d20/classshaka_1_1Status.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::Status Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
Status<
diff --git a/docs/d2/d23/threaded__io__file_8cc_source.html b/docs/d2/d23/threaded__io__file_8cc_source.html index ced1f915cd..b855011c6a 100644 --- a/docs/d2/d23/threaded__io__file_8cc_source.html +++ b/docs/d2/d23/threaded__io__file_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/threaded_io_file.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
threaded_io_file.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/file/threaded_io_file.h"
8 
9 #include "packager/base/bind.h"
10 #include "packager/base/bind_helpers.h"
11 #include "packager/base/location.h"
12 #include "packager/base/threading/worker_pool.h"
13 
14 namespace shaka {
15 
16 ThreadedIoFile::ThreadedIoFile(std::unique_ptr<File, FileCloser> internal_file,
17  Mode mode,
18  uint64_t io_cache_size,
19  uint64_t io_block_size)
20  : File(internal_file->file_name()),
21  internal_file_(std::move(internal_file)),
22  mode_(mode),
23  cache_(io_cache_size),
24  io_buffer_(io_block_size),
25  position_(0),
26  size_(0),
27  eof_(false),
28  flushing_(false),
29  flush_complete_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
30  base::WaitableEvent::InitialState::NOT_SIGNALED),
31  internal_file_error_(0),
32  task_exit_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
33  base::WaitableEvent::InitialState::NOT_SIGNALED) {
34  DCHECK(internal_file_);
35 }
36 
37 ThreadedIoFile::~ThreadedIoFile() {}
38 
40  DCHECK(internal_file_);
41 
42  if (!internal_file_->Open())
43  return false;
44 
45  position_ = 0;
46  size_ = internal_file_->Size();
47 
48  base::WorkerPool::PostTask(
49  FROM_HERE,
50  base::Bind(&ThreadedIoFile::TaskHandler, base::Unretained(this)),
51  true /* task_is_slow */);
52  return true;
53 }
54 
56  DCHECK(internal_file_);
57 
58  bool result = true;
59  if (mode_ == kOutputMode)
60  result = Flush();
61 
62  cache_.Close();
63  task_exit_event_.Wait();
64 
65  result &= internal_file_.release()->Close();
66  delete this;
67  return result;
68 }
69 
70 int64_t ThreadedIoFile::Read(void* buffer, uint64_t length) {
71  DCHECK(internal_file_);
72  DCHECK_EQ(kInputMode, mode_);
73 
74  if (eof_.load(std::memory_order_relaxed) && !cache_.BytesCached())
75  return 0;
76 
77  if (internal_file_error_.load(std::memory_order_relaxed))
78  return internal_file_error_.load(std::memory_order_relaxed);
79 
80  uint64_t bytes_read = cache_.Read(buffer, length);
81  position_ += bytes_read;
82 
83  return bytes_read;
84 }
85 
86 int64_t ThreadedIoFile::Write(const void* buffer, uint64_t length) {
87  DCHECK(internal_file_);
88  DCHECK_EQ(kOutputMode, mode_);
89 
90  if (internal_file_error_.load(std::memory_order_relaxed))
91  return internal_file_error_.load(std::memory_order_relaxed);
92 
93  uint64_t bytes_written = cache_.Write(buffer, length);
94  position_ += bytes_written;
95  if (position_ > size_)
96  size_ = position_;
97 
98  return bytes_written;
99 }
100 
102  DCHECK(internal_file_);
103 
104  return size_;
105 }
106 
108  DCHECK(internal_file_);
109  DCHECK_EQ(kOutputMode, mode_);
110 
111  if (internal_file_error_.load(std::memory_order_relaxed))
112  return false;
113 
114  flushing_ = true;
115  cache_.Close();
116  flush_complete_event_.Wait();
117  return internal_file_->Flush();
118 }
119 
120 bool ThreadedIoFile::Seek(uint64_t position) {
121  if (mode_ == kOutputMode) {
122  // Writing. Just flush the cache and seek.
123  if (!Flush())
124  return false;
125  if (!internal_file_->Seek(position))
126  return false;
127  } else {
128  // Reading. Close cache, wait for thread task to exit, seek, and re-post
129  // the task.
130  cache_.Close();
131  task_exit_event_.Wait();
132  bool result = internal_file_->Seek(position);
133  if (!result) {
134  // Seek failed. Seek to logical position instead.
135  if (!internal_file_->Seek(position_) && (position != position_)) {
136  LOG(WARNING) << "Seek failed. ThreadedIoFile left in invalid state.";
137  }
138  }
139  cache_.Reopen();
140  eof_ = false;
141  base::WorkerPool::PostTask(
142  FROM_HERE,
143  base::Bind(&ThreadedIoFile::TaskHandler, base::Unretained(this)),
144  true /* task_is_slow */);
145  if (!result)
146  return false;
147  }
148  position_ = position;
149  return true;
150 }
151 
152 bool ThreadedIoFile::Tell(uint64_t* position) {
153  DCHECK(position);
154 
155  *position = position_;
156  return true;
157 }
158 
159 void ThreadedIoFile::TaskHandler() {
160  if (mode_ == kInputMode)
161  RunInInputMode();
162  else
163  RunInOutputMode();
164  task_exit_event_.Signal();
165 }
166 
167 void ThreadedIoFile::RunInInputMode() {
168  DCHECK(internal_file_);
169  DCHECK_EQ(kInputMode, mode_);
170 
171  while (true) {
172  int64_t read_result =
173  internal_file_->Read(&io_buffer_[0], io_buffer_.size());
174  if (read_result <= 0) {
175  eof_.store(read_result == 0, std::memory_order_relaxed);
176  internal_file_error_.store(read_result, std::memory_order_relaxed);
177  cache_.Close();
178  return;
179  }
180  if (cache_.Write(&io_buffer_[0], read_result) == 0) {
181  return;
182  }
183  }
184 }
185 
186 void ThreadedIoFile::RunInOutputMode() {
187  DCHECK(internal_file_);
188  DCHECK_EQ(kOutputMode, mode_);
189 
190  while (true) {
191  uint64_t write_bytes = cache_.Read(&io_buffer_[0], io_buffer_.size());
192  if (write_bytes == 0) {
193  if (flushing_) {
194  cache_.Reopen();
195  flushing_ = false;
196  flush_complete_event_.Signal();
197  } else {
198  return;
199  }
200  } else {
201  uint64_t bytes_written(0);
202  while (bytes_written < write_bytes) {
203  int64_t write_result = internal_file_->Write(
204  &io_buffer_[bytes_written], write_bytes - bytes_written);
205  if (write_result < 0) {
206  internal_file_error_.store(write_result, std::memory_order_relaxed);
207  cache_.Close();
208  if (flushing_) {
209  flushing_ = false;
210  flush_complete_event_.Signal();
211  }
212  return;
213  }
214  bytes_written += write_result;
215  }
216  }
217  }
218 }
219 
220 } // namespace shaka
int64_t Size() override
-
int64_t Write(const void *buffer, uint64_t length) override
-
STL namespace.
- -
All the methods that are virtual are virtual for mocking.
-
bool Open() override
Internal open. Should not be used directly.
- -
bool Seek(uint64_t position) override
- -
bool Tell(uint64_t *position) override
-
int64_t Read(void *buffer, uint64_t length) override
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/file/threaded_io_file.h"
+
8 
+
9 #include "packager/base/bind.h"
+
10 #include "packager/base/bind_helpers.h"
+
11 #include "packager/base/location.h"
+
12 #include "packager/base/threading/worker_pool.h"
+
13 
+
14 namespace shaka {
+
15 
+
16 ThreadedIoFile::ThreadedIoFile(std::unique_ptr<File, FileCloser> internal_file,
+
17  Mode mode,
+
18  uint64_t io_cache_size,
+
19  uint64_t io_block_size)
+
20  : File(internal_file->file_name()),
+
21  internal_file_(std::move(internal_file)),
+
22  mode_(mode),
+
23  cache_(io_cache_size),
+
24  io_buffer_(io_block_size),
+
25  position_(0),
+
26  size_(0),
+
27  eof_(false),
+
28  flushing_(false),
+
29  flush_complete_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+
30  base::WaitableEvent::InitialState::NOT_SIGNALED),
+
31  internal_file_error_(0),
+
32  task_exit_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+
33  base::WaitableEvent::InitialState::NOT_SIGNALED) {
+
34  DCHECK(internal_file_);
+
35 }
+
36 
+
37 ThreadedIoFile::~ThreadedIoFile() {}
+
38 
+
39 bool ThreadedIoFile::Open() {
+
40  DCHECK(internal_file_);
+
41 
+
42  if (!internal_file_->Open())
+
43  return false;
+
44 
+
45  position_ = 0;
+
46  size_ = internal_file_->Size();
+
47 
+
48  base::WorkerPool::PostTask(
+
49  FROM_HERE,
+
50  base::Bind(&ThreadedIoFile::TaskHandler, base::Unretained(this)),
+
51  true /* task_is_slow */);
+
52  return true;
+
53 }
+
54 
+
55 bool ThreadedIoFile::Close() {
+
56  DCHECK(internal_file_);
+
57 
+
58  bool result = true;
+
59  if (mode_ == kOutputMode)
+
60  result = Flush();
+
61 
+
62  cache_.Close();
+
63  task_exit_event_.Wait();
+
64 
+
65  result &= internal_file_.release()->Close();
+
66  delete this;
+
67  return result;
+
68 }
+
69 
+
70 int64_t ThreadedIoFile::Read(void* buffer, uint64_t length) {
+
71  DCHECK(internal_file_);
+
72  DCHECK_EQ(kInputMode, mode_);
+
73 
+
74  if (eof_.load(std::memory_order_relaxed) && !cache_.BytesCached())
+
75  return 0;
+
76 
+
77  if (internal_file_error_.load(std::memory_order_relaxed))
+
78  return internal_file_error_.load(std::memory_order_relaxed);
+
79 
+
80  uint64_t bytes_read = cache_.Read(buffer, length);
+
81  position_ += bytes_read;
+
82 
+
83  return bytes_read;
+
84 }
+
85 
+
86 int64_t ThreadedIoFile::Write(const void* buffer, uint64_t length) {
+
87  DCHECK(internal_file_);
+
88  DCHECK_EQ(kOutputMode, mode_);
+
89 
+
90  if (internal_file_error_.load(std::memory_order_relaxed))
+
91  return internal_file_error_.load(std::memory_order_relaxed);
+
92 
+
93  uint64_t bytes_written = cache_.Write(buffer, length);
+
94  position_ += bytes_written;
+
95  if (position_ > size_)
+
96  size_ = position_;
+
97 
+
98  return bytes_written;
+
99 }
+
100 
+
101 int64_t ThreadedIoFile::Size() {
+
102  DCHECK(internal_file_);
+
103 
+
104  return size_;
+
105 }
+
106 
+
107 bool ThreadedIoFile::Flush() {
+
108  DCHECK(internal_file_);
+
109  DCHECK_EQ(kOutputMode, mode_);
+
110 
+
111  if (internal_file_error_.load(std::memory_order_relaxed))
+
112  return false;
+
113 
+
114  flushing_ = true;
+
115  cache_.Close();
+
116  flush_complete_event_.Wait();
+
117  return internal_file_->Flush();
+
118 }
+
119 
+
120 bool ThreadedIoFile::Seek(uint64_t position) {
+
121  if (mode_ == kOutputMode) {
+
122  // Writing. Just flush the cache and seek.
+
123  if (!Flush())
+
124  return false;
+
125  if (!internal_file_->Seek(position))
+
126  return false;
+
127  } else {
+
128  // Reading. Close cache, wait for thread task to exit, seek, and re-post
+
129  // the task.
+
130  cache_.Close();
+
131  task_exit_event_.Wait();
+
132  bool result = internal_file_->Seek(position);
+
133  if (!result) {
+
134  // Seek failed. Seek to logical position instead.
+
135  if (!internal_file_->Seek(position_) && (position != position_)) {
+
136  LOG(WARNING) << "Seek failed. ThreadedIoFile left in invalid state.";
+
137  }
+
138  }
+
139  cache_.Reopen();
+
140  eof_ = false;
+
141  base::WorkerPool::PostTask(
+
142  FROM_HERE,
+
143  base::Bind(&ThreadedIoFile::TaskHandler, base::Unretained(this)),
+
144  true /* task_is_slow */);
+
145  if (!result)
+
146  return false;
+
147  }
+
148  position_ = position;
+
149  return true;
+
150 }
+
151 
+
152 bool ThreadedIoFile::Tell(uint64_t* position) {
+
153  DCHECK(position);
+
154 
+
155  *position = position_;
+
156  return true;
+
157 }
+
158 
+
159 void ThreadedIoFile::TaskHandler() {
+
160  if (mode_ == kInputMode)
+
161  RunInInputMode();
+
162  else
+
163  RunInOutputMode();
+
164  task_exit_event_.Signal();
+
165 }
+
166 
+
167 void ThreadedIoFile::RunInInputMode() {
+
168  DCHECK(internal_file_);
+
169  DCHECK_EQ(kInputMode, mode_);
+
170 
+
171  while (true) {
+
172  int64_t read_result =
+
173  internal_file_->Read(&io_buffer_[0], io_buffer_.size());
+
174  if (read_result <= 0) {
+
175  eof_.store(read_result == 0, std::memory_order_relaxed);
+
176  internal_file_error_.store(read_result, std::memory_order_relaxed);
+
177  cache_.Close();
+
178  return;
+
179  }
+
180  if (cache_.Write(&io_buffer_[0], read_result) == 0) {
+
181  return;
+
182  }
+
183  }
+
184 }
+
185 
+
186 void ThreadedIoFile::RunInOutputMode() {
+
187  DCHECK(internal_file_);
+
188  DCHECK_EQ(kOutputMode, mode_);
+
189 
+
190  while (true) {
+
191  uint64_t write_bytes = cache_.Read(&io_buffer_[0], io_buffer_.size());
+
192  if (write_bytes == 0) {
+
193  if (flushing_) {
+
194  cache_.Reopen();
+
195  flushing_ = false;
+
196  flush_complete_event_.Signal();
+
197  } else {
+
198  return;
+
199  }
+
200  } else {
+
201  uint64_t bytes_written(0);
+
202  while (bytes_written < write_bytes) {
+
203  int64_t write_result = internal_file_->Write(
+
204  &io_buffer_[bytes_written], write_bytes - bytes_written);
+
205  if (write_result < 0) {
+
206  internal_file_error_.store(write_result, std::memory_order_relaxed);
+
207  cache_.Close();
+
208  if (flushing_) {
+
209  flushing_ = false;
+
210  flush_complete_event_.Signal();
+
211  }
+
212  return;
+
213  }
+
214  bytes_written += write_result;
+
215  }
+
216  }
+
217  }
+
218 }
+
219 
+
220 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d24/classshaka_1_1media_1_1PsshBoxBuilder.html b/docs/d2/d24/classshaka_1_1media_1_1PsshBoxBuilder.html index 4e6709d9d1..687f87d73c 100644 --- a/docs/d2/d24/classshaka_1_1media_1_1PsshBoxBuilder.html +++ b/docs/d2/d24/classshaka_1_1media_1_1PsshBoxBuilder.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::PsshBoxBuilder Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */

Detailed Description

-

Definition at line 39 of file protection_system_specific_info.h.

+

Definition at line 33 of file protection_system_specific_info.h.

Member Function Documentation

◆ ParseFromBox()

@@ -160,9 +163,7 @@ Static Public Member Functions
diff --git a/docs/d2/d24/packager__util_8h_source.html b/docs/d2/d24/packager__util_8h_source.html index 5e583e2817..ea52b84f73 100644 --- a/docs/d2/d24/packager__util_8h_source.html +++ b/docs/d2/d24/packager__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/packager_util.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
packager_util.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Packager utility functions.
8 
9 #ifndef PACKAGER_APP_PACKAGER_UTIL_H_
10 #define PACKAGER_APP_PACKAGER_UTIL_H_
11 
12 #include <memory>
13 #include <vector>
14 
15 #include "packager/media/base/fourccs.h"
16 
17 namespace shaka {
18 
19 class Status;
20 struct DecryptionParams;
21 struct EncryptionParams;
22 struct MpdOptions;
23 struct MpdParams;
24 
25 namespace media {
26 
27 class MediaHandler;
28 class KeySource;
29 
36 std::unique_ptr<KeySource> CreateEncryptionKeySource(
37  FourCC protection_scheme,
38  const EncryptionParams& encryption_params);
39 
44 std::unique_ptr<KeySource> CreateDecryptionKeySource(
45  const DecryptionParams& decryption_params);
46 
48 MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params);
49 
50 } // namespace media
51 } // namespace shaka
52 
53 #endif // PACKAGER_APP_PACKAGER_UTIL_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Packager utility functions.
+
8 
+
9 #ifndef PACKAGER_APP_PACKAGER_UTIL_H_
+
10 #define PACKAGER_APP_PACKAGER_UTIL_H_
+
11 
+
12 #include <memory>
+
13 #include <vector>
+
14 
+
15 #include "packager/media/base/fourccs.h"
+
16 
+
17 namespace shaka {
+
18 
+
19 class Status;
+
20 struct DecryptionParams;
+
21 struct EncryptionParams;
+
22 struct MpdOptions;
+
23 struct MpdParams;
+
24 
+
25 namespace media {
+
26 
+
27 class MediaHandler;
+
28 class KeySource;
+
29 
+
36 std::unique_ptr<KeySource> CreateEncryptionKeySource(
+
37  FourCC protection_scheme,
+
38  const EncryptionParams& encryption_params);
+
39 
+
44 std::unique_ptr<KeySource> CreateDecryptionKeySource(
+
45  const DecryptionParams& decryption_params);
+
46 
+
48 MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params);
+
49 
+
50 } // namespace media
+
51 } // namespace shaka
+
52 
+
53 #endif // PACKAGER_APP_PACKAGER_UTIL_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d26/classshaka_1_1media_1_1LineReader-members.html b/docs/d2/d26/classshaka_1_1media_1_1LineReader-members.html index 2d673cb9b8..8fa5eb11cd 100644 --- a/docs/d2/d26/classshaka_1_1media_1_1LineReader-members.html +++ b/docs/d2/d26/classshaka_1_1media_1_1LineReader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::media::LineReader, including all inherited members.

- - + + + +
LineReader(std::unique_ptr< FileReader > source) (defined in shaka::media::LineReader)shaka::media::LineReaderexplicit
Next(std::string *out) (defined in shaka::media::LineReader)shaka::media::LineReader
Flush()shaka::media::LineReader
LineReader() (defined in shaka::media::LineReader)shaka::media::LineReader
Next(std::string *out)shaka::media::LineReader
PushData(const uint8_t *data, size_t data_size)shaka::media::LineReader
diff --git a/docs/d2/d27/aes__encryptor__factory_8cc_source.html b/docs/d2/d27/aes__encryptor__factory_8cc_source.html index ce7dce6b2f..a00e0c92d3 100644 --- a/docs/d2/d27/aes__encryptor__factory_8cc_source.html +++ b/docs/d2/d27/aes__encryptor__factory_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto/aes_encryptor_factory.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
aes_encryptor_factory.cc
-
1 // Copyright 2018 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/crypto/aes_encryptor_factory.h"
8 
9 #include "packager/media/base/aes_encryptor.h"
10 #include "packager/media/base/aes_pattern_cryptor.h"
11 #include "packager/media/crypto/sample_aes_ec3_cryptor.h"
12 
13 namespace shaka {
14 namespace media {
15 
16 std::unique_ptr<AesCryptor> AesEncryptorFactory::CreateEncryptor(
17  FourCC protection_scheme,
18  uint8_t crypt_byte_block,
19  uint8_t skip_byte_block,
20  Codec codec,
21  const std::vector<uint8_t>& key,
22  const std::vector<uint8_t>& iv) {
23  std::unique_ptr<AesCryptor> encryptor;
24  switch (protection_scheme) {
25  case FOURCC_cenc:
26  encryptor.reset(new AesCtrEncryptor);
27  break;
28  case FOURCC_cbc1:
29  encryptor.reset(new AesCbcEncryptor(kNoPadding));
30  break;
31  case FOURCC_cens:
32  encryptor.reset(new AesPatternCryptor(
33  crypt_byte_block, skip_byte_block,
35  AesCryptor::kDontUseConstantIv,
36  std::unique_ptr<AesCryptor>(new AesCtrEncryptor)));
37  break;
38  case FOURCC_cbcs:
39  encryptor.reset(new AesPatternCryptor(
40  crypt_byte_block, skip_byte_block,
42  AesCryptor::kUseConstantIv,
43  std::unique_ptr<AesCryptor>(new AesCbcEncryptor(kNoPadding))));
44  break;
45  case kAppleSampleAesProtectionScheme:
46  if (crypt_byte_block == 0 && skip_byte_block == 0) {
47  if (codec == kCodecEAC3) {
48  encryptor.reset(new SampleAesEc3Cryptor(
49  std::unique_ptr<AesCryptor>(new AesCbcEncryptor(kNoPadding))));
50  } else {
51  encryptor.reset(
52  new AesCbcEncryptor(kNoPadding, AesCryptor::kUseConstantIv));
53  }
54  } else {
55  encryptor.reset(new AesPatternCryptor(
56  crypt_byte_block, skip_byte_block,
58  AesCryptor::kUseConstantIv,
59  std::unique_ptr<AesCryptor>(new AesCbcEncryptor(kNoPadding))));
60  }
61  break;
62  default:
63  LOG(ERROR) << "Unsupported protection scheme.";
64  return nullptr;
65  }
66 
67  if (iv.empty()) {
68  std::vector<uint8_t> random_iv;
69  if (!AesCryptor::GenerateRandomIv(protection_scheme, &random_iv)) {
70  LOG(ERROR) << "Failed to generate random iv.";
71  return nullptr;
72  }
73  if (!encryptor->InitializeWithIv(key, random_iv))
74  return nullptr;
75  } else {
76  if (!encryptor->InitializeWithIv(key, iv))
77  return nullptr;
78  }
79 
80  return encryptor;
81 }
82 
83 } // namespace media
84 } // namespace shaka
-
All the methods that are virtual are virtual for mocking.
- -
static bool GenerateRandomIv(FourCC protection_scheme, std::vector< uint8_t > *iv)
Definition: aes_cryptor.cc:110
+
1 // Copyright 2018 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/crypto/aes_encryptor_factory.h"
+
8 
+
9 #include "packager/media/base/aes_encryptor.h"
+
10 #include "packager/media/base/aes_pattern_cryptor.h"
+
11 #include "packager/media/crypto/sample_aes_ec3_cryptor.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
16 std::unique_ptr<AesCryptor> AesEncryptorFactory::CreateEncryptor(
+
17  FourCC protection_scheme,
+
18  uint8_t crypt_byte_block,
+
19  uint8_t skip_byte_block,
+
20  Codec codec,
+
21  const std::vector<uint8_t>& key,
+
22  const std::vector<uint8_t>& iv) {
+
23  std::unique_ptr<AesCryptor> encryptor;
+
24  switch (protection_scheme) {
+
25  case FOURCC_cenc:
+
26  encryptor.reset(new AesCtrEncryptor);
+
27  break;
+
28  case FOURCC_cbc1:
+
29  encryptor.reset(new AesCbcEncryptor(kNoPadding));
+
30  break;
+
31  case FOURCC_cens:
+
32  encryptor.reset(new AesPatternCryptor(
+
33  crypt_byte_block, skip_byte_block,
+ +
35  AesCryptor::kDontUseConstantIv,
+
36  std::unique_ptr<AesCryptor>(new AesCtrEncryptor)));
+
37  break;
+
38  case FOURCC_cbcs:
+
39  encryptor.reset(new AesPatternCryptor(
+
40  crypt_byte_block, skip_byte_block,
+ +
42  AesCryptor::kUseConstantIv,
+
43  std::unique_ptr<AesCryptor>(new AesCbcEncryptor(kNoPadding))));
+
44  break;
+
45  case kAppleSampleAesProtectionScheme:
+
46  if (crypt_byte_block == 0 && skip_byte_block == 0) {
+
47  if (codec == kCodecEAC3) {
+
48  encryptor.reset(new SampleAesEc3Cryptor(
+
49  std::unique_ptr<AesCryptor>(new AesCbcEncryptor(kNoPadding))));
+
50  } else {
+
51  encryptor.reset(
+
52  new AesCbcEncryptor(kNoPadding, AesCryptor::kUseConstantIv));
+
53  }
+
54  } else {
+
55  encryptor.reset(new AesPatternCryptor(
+
56  crypt_byte_block, skip_byte_block,
+ +
58  AesCryptor::kUseConstantIv,
+
59  std::unique_ptr<AesCryptor>(new AesCbcEncryptor(kNoPadding))));
+
60  }
+
61  break;
+
62  default:
+
63  LOG(ERROR) << "Unsupported protection scheme.";
+
64  return nullptr;
+
65  }
+
66 
+
67  if (iv.empty()) {
+
68  std::vector<uint8_t> random_iv;
+
69  if (!AesCryptor::GenerateRandomIv(protection_scheme, &random_iv)) {
+
70  LOG(ERROR) << "Failed to generate random iv.";
+
71  return nullptr;
+
72  }
+
73  if (!encryptor->InitializeWithIv(key, random_iv))
+
74  return nullptr;
+
75  } else {
+
76  if (!encryptor->InitializeWithIv(key, iv))
+
77  return nullptr;
+
78  }
+
79 
+
80  return encryptor;
+
81 }
+
82 
+
83 } // namespace media
+
84 } // namespace shaka
+
static bool GenerateRandomIv(FourCC protection_scheme, std::vector< uint8_t > *iv)
Definition: aes_cryptor.cc:110
+ + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d2a/classshaka_1_1IoCache-members.html b/docs/d2/d2a/classshaka_1_1IoCache-members.html index 96eaa4a5f0..cb945f1450 100644 --- a/docs/d2/d2a/classshaka_1_1IoCache-members.html +++ b/docs/d2/d2a/classshaka_1_1IoCache-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d30/tracks__builder_8cc_source.html b/docs/d2/d30/tracks__builder_8cc_source.html index 13e9707cd5..d65a7cd4ae 100644 --- a/docs/d2/d30/tracks__builder_8cc_source.html +++ b/docs/d2/d30/tracks__builder_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/tracks_builder.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
tracks_builder.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/webm/tracks_builder.h"
6 
7 #include "packager/base/logging.h"
8 #include "packager/media/formats/webm/webm_constants.h"
9 
10 namespace shaka {
11 namespace media {
12 
13 // Returns size of an integer, formatted using Matroska serialization.
14 static int GetUIntMkvSize(uint64_t value) {
15  if (value < 0x07FULL)
16  return 1;
17  if (value < 0x03FFFULL)
18  return 2;
19  if (value < 0x01FFFFFULL)
20  return 3;
21  if (value < 0x0FFFFFFFULL)
22  return 4;
23  if (value < 0x07FFFFFFFFULL)
24  return 5;
25  if (value < 0x03FFFFFFFFFFULL)
26  return 6;
27  if (value < 0x01FFFFFFFFFFFFULL)
28  return 7;
29  return 8;
30 }
31 
32 // Returns the minimium size required to serialize an integer value.
33 static int GetUIntSize(uint64_t value) {
34  if (value < 0x0100ULL)
35  return 1;
36  if (value < 0x010000ULL)
37  return 2;
38  if (value < 0x01000000ULL)
39  return 3;
40  if (value < 0x0100000000ULL)
41  return 4;
42  if (value < 0x010000000000ULL)
43  return 5;
44  if (value < 0x01000000000000ULL)
45  return 6;
46  if (value < 0x0100000000000000ULL)
47  return 7;
48  return 8;
49 }
50 
51 static int MasterElementSize(int element_id, int payload_size) {
52  return GetUIntSize(element_id) + GetUIntMkvSize(payload_size) + payload_size;
53 }
54 
55 static int UIntElementSize(int element_id, uint64_t value) {
56  return GetUIntSize(element_id) + 1 + GetUIntSize(value);
57 }
58 
59 static int DoubleElementSize(int element_id) {
60  return GetUIntSize(element_id) + 1 + 8;
61 }
62 
63 static int StringElementSize(int element_id, const std::string& value) {
64  return GetUIntSize(element_id) + GetUIntMkvSize(value.length()) +
65  static_cast<int>(value.length());
66 }
67 
68 static void SerializeInt(uint8_t** buf_ptr,
69  int* buf_size_ptr,
70  int64_t value,
71  int size) {
72  uint8_t*& buf = *buf_ptr;
73  int& buf_size = *buf_size_ptr;
74 
75  for (int idx = 1; idx <= size; ++idx) {
76  *buf++ = static_cast<uint8_t>(value >> ((size - idx) * 8));
77  --buf_size;
78  }
79 }
80 
81 static void SerializeDouble(uint8_t** buf_ptr,
82  int* buf_size_ptr,
83  double value) {
84  // Use a union to convert |value| to native endian integer bit pattern.
85  union {
86  double src;
87  int64_t dst;
88  } tmp;
89  tmp.src = value;
90 
91  // Write the bytes from native endian |tmp.dst| to big-endian form in |buf|.
92  SerializeInt(buf_ptr, buf_size_ptr, tmp.dst, 8);
93 }
94 
95 static void WriteElementId(uint8_t** buf, int* buf_size, int element_id) {
96  SerializeInt(buf, buf_size, element_id, GetUIntSize(element_id));
97 }
98 
99 static void WriteUInt(uint8_t** buf, int* buf_size, uint64_t value) {
100  const int size = GetUIntMkvSize(value);
101  value |= (1ULL << (size * 7)); // Matroska formatting
102  SerializeInt(buf, buf_size, value, size);
103 }
104 
105 static void WriteMasterElement(uint8_t** buf,
106  int* buf_size,
107  int element_id,
108  int payload_size) {
109  WriteElementId(buf, buf_size, element_id);
110  WriteUInt(buf, buf_size, payload_size);
111 }
112 
113 static void WriteUIntElement(uint8_t** buf,
114  int* buf_size,
115  int element_id,
116  uint64_t value) {
117  WriteElementId(buf, buf_size, element_id);
118 
119  const int size = GetUIntSize(value);
120  WriteUInt(buf, buf_size, size);
121 
122  SerializeInt(buf, buf_size, value, size);
123 }
124 
125 static void WriteDoubleElement(uint8_t** buf,
126  int* buf_size,
127  int element_id,
128  double value) {
129  WriteElementId(buf, buf_size, element_id);
130  WriteUInt(buf, buf_size, 8);
131  SerializeDouble(buf, buf_size, value);
132 }
133 
134 static void WriteStringElement(uint8_t** buf_ptr,
135  int* buf_size_ptr,
136  int element_id,
137  const std::string& value) {
138  uint8_t*& buf = *buf_ptr;
139  int& buf_size = *buf_size_ptr;
140 
141  WriteElementId(&buf, &buf_size, element_id);
142 
143  const uint64_t size = value.length();
144  WriteUInt(&buf, &buf_size, size);
145 
146  memcpy(buf, value.data(), size);
147  buf += size;
148  buf_size -= size;
149 }
150 
151 TracksBuilder::TracksBuilder(bool allow_invalid_values)
152  : allow_invalid_values_(allow_invalid_values) {}
153 TracksBuilder::TracksBuilder()
154  : allow_invalid_values_(false) {}
155 TracksBuilder::~TracksBuilder() {}
156 
157 void TracksBuilder::AddVideoTrack(int track_num,
158  uint64_t track_uid,
159  const std::string& codec_id,
160  const std::string& name,
161  const std::string& language,
162  int default_duration,
163  int video_pixel_width,
164  int video_pixel_height) {
165  AddTrackInternal(track_num, kWebMTrackTypeVideo, track_uid, codec_id, name,
166  language, default_duration, video_pixel_width,
167  video_pixel_height, -1, -1);
168 }
169 
170 void TracksBuilder::AddAudioTrack(int track_num,
171  uint64_t track_uid,
172  const std::string& codec_id,
173  const std::string& name,
174  const std::string& language,
175  int default_duration,
176  int audio_channels,
177  double audio_sampling_frequency) {
178  AddTrackInternal(track_num, kWebMTrackTypeAudio, track_uid, codec_id, name,
179  language, default_duration, -1, -1, audio_channels,
180  audio_sampling_frequency);
181 }
182 
183 void TracksBuilder::AddTextTrack(int track_num,
184  uint64_t track_uid,
185  const std::string& codec_id,
186  const std::string& name,
187  const std::string& language) {
188  AddTrackInternal(track_num, kWebMTrackTypeSubtitlesOrCaptions, track_uid,
189  codec_id, name, language, -1, -1, -1, -1, -1);
190 }
191 
192 std::vector<uint8_t> TracksBuilder::Finish() {
193  // Allocate the storage
194  std::vector<uint8_t> buffer;
195  buffer.resize(GetTracksSize());
196 
197  // Populate the storage with a tracks header
198  WriteTracks(&buffer[0], static_cast<int>(buffer.size()));
199 
200  return buffer;
201 }
202 
203 void TracksBuilder::AddTrackInternal(int track_num,
204  int track_type,
205  uint64_t track_uid,
206  const std::string& codec_id,
207  const std::string& name,
208  const std::string& language,
209  int default_duration,
210  int video_pixel_width,
211  int video_pixel_height,
212  int audio_channels,
213  double audio_sampling_frequency) {
214  tracks_.push_back(Track(track_num, track_type, track_uid, codec_id, name,
215  language, default_duration, video_pixel_width,
216  video_pixel_height, audio_channels,
217  audio_sampling_frequency, allow_invalid_values_));
218 }
219 
220 int TracksBuilder::GetTracksSize() const {
221  return MasterElementSize(kWebMIdTracks, GetTracksPayloadSize());
222 }
223 
224 int TracksBuilder::GetTracksPayloadSize() const {
225  int payload_size = 0;
226 
227  for (TrackList::const_iterator itr = tracks_.begin();
228  itr != tracks_.end(); ++itr) {
229  payload_size += itr->GetSize();
230  }
231 
232  return payload_size;
233 }
234 
235 void TracksBuilder::WriteTracks(uint8_t* buf, int buf_size) const {
236  WriteMasterElement(&buf, &buf_size, kWebMIdTracks, GetTracksPayloadSize());
237 
238  for (TrackList::const_iterator itr = tracks_.begin();
239  itr != tracks_.end(); ++itr) {
240  itr->Write(&buf, &buf_size);
241  }
242 }
243 
244 TracksBuilder::Track::Track(int track_num,
245  int track_type,
246  uint64_t track_uid,
247  const std::string& codec_id,
248  const std::string& name,
249  const std::string& language,
250  int default_duration,
251  int video_pixel_width,
252  int video_pixel_height,
253  int audio_channels,
254  double audio_sampling_frequency,
255  bool allow_invalid_values)
256  : track_num_(track_num),
257  track_type_(track_type),
258  track_uid_(track_uid),
259  codec_id_(codec_id),
260  name_(name),
261  language_(language),
262  default_duration_(default_duration),
263  video_pixel_width_(video_pixel_width),
264  video_pixel_height_(video_pixel_height),
265  audio_channels_(audio_channels),
266  audio_sampling_frequency_(audio_sampling_frequency) {
267  if (!allow_invalid_values) {
268  CHECK_GT(track_num_, 0);
269  CHECK_GT(track_type_, 0);
270  CHECK_LT(track_type_, 255);
271  CHECK_GT(track_uid_, 0);
272  if (track_type != kWebMTrackTypeVideo &&
273  track_type != kWebMTrackTypeAudio) {
274  CHECK_EQ(default_duration_, -1);
275  } else {
276  CHECK(default_duration_ == -1 || default_duration_ > 0);
277  }
278 
279  if (track_type == kWebMTrackTypeVideo) {
280  CHECK_GT(video_pixel_width_, 0);
281  CHECK_GT(video_pixel_height_, 0);
282  } else {
283  CHECK_EQ(video_pixel_width_, -1);
284  CHECK_EQ(video_pixel_height_, -1);
285  }
286 
287  if (track_type == kWebMTrackTypeAudio) {
288  CHECK_GT(audio_channels_, 0);
289  CHECK_GT(audio_sampling_frequency_, 0.0);
290  } else {
291  CHECK_EQ(audio_channels_, -1);
292  CHECK_EQ(audio_sampling_frequency_, -1.0);
293  }
294  }
295 }
296 
297 int TracksBuilder::Track::GetSize() const {
298  return MasterElementSize(kWebMIdTrackEntry, GetPayloadSize());
299 }
300 
301 int TracksBuilder::Track::GetVideoPayloadSize() const {
302  int payload_size = 0;
303 
304  if (video_pixel_width_ >= 0)
305  payload_size += UIntElementSize(kWebMIdPixelWidth, video_pixel_width_);
306  if (video_pixel_height_ >= 0)
307  payload_size += UIntElementSize(kWebMIdPixelHeight, video_pixel_height_);
308 
309  return payload_size;
310 }
311 
312 int TracksBuilder::Track::GetAudioPayloadSize() const {
313  int payload_size = 0;
314 
315  if (audio_channels_ >= 0)
316  payload_size += UIntElementSize(kWebMIdChannels, audio_channels_);
317  if (audio_sampling_frequency_ >= 0)
318  payload_size += DoubleElementSize(kWebMIdSamplingFrequency);
319 
320  return payload_size;
321 }
322 
323 int TracksBuilder::Track::GetPayloadSize() const {
324  int size = 0;
325 
326  size += UIntElementSize(kWebMIdTrackNumber, track_num_);
327  size += UIntElementSize(kWebMIdTrackType, track_type_);
328  size += UIntElementSize(kWebMIdTrackUID, track_uid_);
329 
330  if (default_duration_ >= 0)
331  size += UIntElementSize(kWebMIdDefaultDuration, default_duration_);
332 
333  if (!codec_id_.empty())
334  size += StringElementSize(kWebMIdCodecID, codec_id_);
335 
336  if (!name_.empty())
337  size += StringElementSize(kWebMIdName, name_);
338 
339  if (!language_.empty())
340  size += StringElementSize(kWebMIdLanguage, language_);
341 
342  if (GetVideoPayloadSize() > 0) {
343  size += MasterElementSize(kWebMIdVideo, GetVideoPayloadSize());
344  }
345 
346  if (GetAudioPayloadSize() > 0) {
347  size += MasterElementSize(kWebMIdAudio, GetAudioPayloadSize());
348  }
349 
350  return size;
351 }
352 
353 void TracksBuilder::Track::Write(uint8_t** buf, int* buf_size) const {
354  WriteMasterElement(buf, buf_size, kWebMIdTrackEntry, GetPayloadSize());
355 
356  WriteUIntElement(buf, buf_size, kWebMIdTrackNumber, track_num_);
357  WriteUIntElement(buf, buf_size, kWebMIdTrackType, track_type_);
358  WriteUIntElement(buf, buf_size, kWebMIdTrackUID, track_uid_);
359 
360  if (default_duration_ >= 0)
361  WriteUIntElement(buf, buf_size, kWebMIdDefaultDuration, default_duration_);
362 
363  if (!codec_id_.empty())
364  WriteStringElement(buf, buf_size, kWebMIdCodecID, codec_id_);
365 
366  if (!name_.empty())
367  WriteStringElement(buf, buf_size, kWebMIdName, name_);
368 
369  if (!language_.empty())
370  WriteStringElement(buf, buf_size, kWebMIdLanguage, language_);
371 
372  if (GetVideoPayloadSize() > 0) {
373  WriteMasterElement(buf, buf_size, kWebMIdVideo, GetVideoPayloadSize());
374 
375  if (video_pixel_width_ >= 0)
376  WriteUIntElement(buf, buf_size, kWebMIdPixelWidth, video_pixel_width_);
377 
378  if (video_pixel_height_ >= 0)
379  WriteUIntElement(buf, buf_size, kWebMIdPixelHeight, video_pixel_height_);
380  }
381 
382  if (GetAudioPayloadSize() > 0) {
383  WriteMasterElement(buf, buf_size, kWebMIdAudio, GetAudioPayloadSize());
384 
385  if (audio_channels_ >= 0)
386  WriteUIntElement(buf, buf_size, kWebMIdChannels, audio_channels_);
387 
388  if (audio_sampling_frequency_ >= 0) {
389  WriteDoubleElement(buf, buf_size, kWebMIdSamplingFrequency,
390  audio_sampling_frequency_);
391  }
392  }
393 }
394 
395 } // namespace media
396 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/webm/tracks_builder.h"
+
6 
+
7 #include "packager/base/logging.h"
+
8 #include "packager/media/formats/webm/webm_constants.h"
+
9 
+
10 namespace shaka {
+
11 namespace media {
+
12 
+
13 // Returns size of an integer, formatted using Matroska serialization.
+
14 static int GetUIntMkvSize(uint64_t value) {
+
15  if (value < 0x07FULL)
+
16  return 1;
+
17  if (value < 0x03FFFULL)
+
18  return 2;
+
19  if (value < 0x01FFFFFULL)
+
20  return 3;
+
21  if (value < 0x0FFFFFFFULL)
+
22  return 4;
+
23  if (value < 0x07FFFFFFFFULL)
+
24  return 5;
+
25  if (value < 0x03FFFFFFFFFFULL)
+
26  return 6;
+
27  if (value < 0x01FFFFFFFFFFFFULL)
+
28  return 7;
+
29  return 8;
+
30 }
+
31 
+
32 // Returns the minimium size required to serialize an integer value.
+
33 static int GetUIntSize(uint64_t value) {
+
34  if (value < 0x0100ULL)
+
35  return 1;
+
36  if (value < 0x010000ULL)
+
37  return 2;
+
38  if (value < 0x01000000ULL)
+
39  return 3;
+
40  if (value < 0x0100000000ULL)
+
41  return 4;
+
42  if (value < 0x010000000000ULL)
+
43  return 5;
+
44  if (value < 0x01000000000000ULL)
+
45  return 6;
+
46  if (value < 0x0100000000000000ULL)
+
47  return 7;
+
48  return 8;
+
49 }
+
50 
+
51 static int MasterElementSize(int element_id, int payload_size) {
+
52  return GetUIntSize(element_id) + GetUIntMkvSize(payload_size) + payload_size;
+
53 }
+
54 
+
55 static int UIntElementSize(int element_id, uint64_t value) {
+
56  return GetUIntSize(element_id) + 1 + GetUIntSize(value);
+
57 }
+
58 
+
59 static int DoubleElementSize(int element_id) {
+
60  return GetUIntSize(element_id) + 1 + 8;
+
61 }
+
62 
+
63 static int StringElementSize(int element_id, const std::string& value) {
+
64  return GetUIntSize(element_id) + GetUIntMkvSize(value.length()) +
+
65  static_cast<int>(value.length());
+
66 }
+
67 
+
68 static void SerializeInt(uint8_t** buf_ptr,
+
69  int* buf_size_ptr,
+
70  int64_t value,
+
71  int size) {
+
72  uint8_t*& buf = *buf_ptr;
+
73  int& buf_size = *buf_size_ptr;
+
74 
+
75  for (int idx = 1; idx <= size; ++idx) {
+
76  *buf++ = static_cast<uint8_t>(value >> ((size - idx) * 8));
+
77  --buf_size;
+
78  }
+
79 }
+
80 
+
81 static void SerializeDouble(uint8_t** buf_ptr,
+
82  int* buf_size_ptr,
+
83  double value) {
+
84  // Use a union to convert |value| to native endian integer bit pattern.
+
85  union {
+
86  double src;
+
87  int64_t dst;
+
88  } tmp;
+
89  tmp.src = value;
+
90 
+
91  // Write the bytes from native endian |tmp.dst| to big-endian form in |buf|.
+
92  SerializeInt(buf_ptr, buf_size_ptr, tmp.dst, 8);
+
93 }
+
94 
+
95 static void WriteElementId(uint8_t** buf, int* buf_size, int element_id) {
+
96  SerializeInt(buf, buf_size, element_id, GetUIntSize(element_id));
+
97 }
+
98 
+
99 static void WriteUInt(uint8_t** buf, int* buf_size, uint64_t value) {
+
100  const int size = GetUIntMkvSize(value);
+
101  value |= (1ULL << (size * 7)); // Matroska formatting
+
102  SerializeInt(buf, buf_size, value, size);
+
103 }
+
104 
+
105 static void WriteMasterElement(uint8_t** buf,
+
106  int* buf_size,
+
107  int element_id,
+
108  int payload_size) {
+
109  WriteElementId(buf, buf_size, element_id);
+
110  WriteUInt(buf, buf_size, payload_size);
+
111 }
+
112 
+
113 static void WriteUIntElement(uint8_t** buf,
+
114  int* buf_size,
+
115  int element_id,
+
116  uint64_t value) {
+
117  WriteElementId(buf, buf_size, element_id);
+
118 
+
119  const int size = GetUIntSize(value);
+
120  WriteUInt(buf, buf_size, size);
+
121 
+
122  SerializeInt(buf, buf_size, value, size);
+
123 }
+
124 
+
125 static void WriteDoubleElement(uint8_t** buf,
+
126  int* buf_size,
+
127  int element_id,
+
128  double value) {
+
129  WriteElementId(buf, buf_size, element_id);
+
130  WriteUInt(buf, buf_size, 8);
+
131  SerializeDouble(buf, buf_size, value);
+
132 }
+
133 
+
134 static void WriteStringElement(uint8_t** buf_ptr,
+
135  int* buf_size_ptr,
+
136  int element_id,
+
137  const std::string& value) {
+
138  uint8_t*& buf = *buf_ptr;
+
139  int& buf_size = *buf_size_ptr;
+
140 
+
141  WriteElementId(&buf, &buf_size, element_id);
+
142 
+
143  const uint64_t size = value.length();
+
144  WriteUInt(&buf, &buf_size, size);
+
145 
+
146  memcpy(buf, value.data(), size);
+
147  buf += size;
+
148  buf_size -= size;
+
149 }
+
150 
+
151 TracksBuilder::TracksBuilder(bool allow_invalid_values)
+
152  : allow_invalid_values_(allow_invalid_values) {}
+
153 TracksBuilder::TracksBuilder()
+
154  : allow_invalid_values_(false) {}
+
155 TracksBuilder::~TracksBuilder() {}
+
156 
+
157 void TracksBuilder::AddVideoTrack(int track_num,
+
158  uint64_t track_uid,
+
159  const std::string& codec_id,
+
160  const std::string& name,
+
161  const std::string& language,
+
162  int default_duration,
+
163  int video_pixel_width,
+
164  int video_pixel_height) {
+
165  AddTrackInternal(track_num, kWebMTrackTypeVideo, track_uid, codec_id, name,
+
166  language, default_duration, video_pixel_width,
+
167  video_pixel_height, -1, -1);
+
168 }
+
169 
+
170 void TracksBuilder::AddAudioTrack(int track_num,
+
171  uint64_t track_uid,
+
172  const std::string& codec_id,
+
173  const std::string& name,
+
174  const std::string& language,
+
175  int default_duration,
+
176  int audio_channels,
+
177  double audio_sampling_frequency) {
+
178  AddTrackInternal(track_num, kWebMTrackTypeAudio, track_uid, codec_id, name,
+
179  language, default_duration, -1, -1, audio_channels,
+
180  audio_sampling_frequency);
+
181 }
+
182 
+
183 void TracksBuilder::AddTextTrack(int track_num,
+
184  uint64_t track_uid,
+
185  const std::string& codec_id,
+
186  const std::string& name,
+
187  const std::string& language) {
+
188  AddTrackInternal(track_num, kWebMTrackTypeSubtitlesOrCaptions, track_uid,
+
189  codec_id, name, language, -1, -1, -1, -1, -1);
+
190 }
+
191 
+
192 std::vector<uint8_t> TracksBuilder::Finish() {
+
193  // Allocate the storage
+
194  std::vector<uint8_t> buffer;
+
195  buffer.resize(GetTracksSize());
+
196 
+
197  // Populate the storage with a tracks header
+
198  WriteTracks(&buffer[0], static_cast<int>(buffer.size()));
+
199 
+
200  return buffer;
+
201 }
+
202 
+
203 void TracksBuilder::AddTrackInternal(int track_num,
+
204  int track_type,
+
205  uint64_t track_uid,
+
206  const std::string& codec_id,
+
207  const std::string& name,
+
208  const std::string& language,
+
209  int default_duration,
+
210  int video_pixel_width,
+
211  int video_pixel_height,
+
212  int audio_channels,
+
213  double audio_sampling_frequency) {
+
214  tracks_.push_back(Track(track_num, track_type, track_uid, codec_id, name,
+
215  language, default_duration, video_pixel_width,
+
216  video_pixel_height, audio_channels,
+
217  audio_sampling_frequency, allow_invalid_values_));
+
218 }
+
219 
+
220 int TracksBuilder::GetTracksSize() const {
+
221  return MasterElementSize(kWebMIdTracks, GetTracksPayloadSize());
+
222 }
+
223 
+
224 int TracksBuilder::GetTracksPayloadSize() const {
+
225  int payload_size = 0;
+
226 
+
227  for (TrackList::const_iterator itr = tracks_.begin();
+
228  itr != tracks_.end(); ++itr) {
+
229  payload_size += itr->GetSize();
+
230  }
+
231 
+
232  return payload_size;
+
233 }
+
234 
+
235 void TracksBuilder::WriteTracks(uint8_t* buf, int buf_size) const {
+
236  WriteMasterElement(&buf, &buf_size, kWebMIdTracks, GetTracksPayloadSize());
+
237 
+
238  for (TrackList::const_iterator itr = tracks_.begin();
+
239  itr != tracks_.end(); ++itr) {
+
240  itr->Write(&buf, &buf_size);
+
241  }
+
242 }
+
243 
+
244 TracksBuilder::Track::Track(int track_num,
+
245  int track_type,
+
246  uint64_t track_uid,
+
247  const std::string& codec_id,
+
248  const std::string& name,
+
249  const std::string& language,
+
250  int default_duration,
+
251  int video_pixel_width,
+
252  int video_pixel_height,
+
253  int audio_channels,
+
254  double audio_sampling_frequency,
+
255  bool allow_invalid_values)
+
256  : track_num_(track_num),
+
257  track_type_(track_type),
+
258  track_uid_(track_uid),
+
259  codec_id_(codec_id),
+
260  name_(name),
+
261  language_(language),
+
262  default_duration_(default_duration),
+
263  video_pixel_width_(video_pixel_width),
+
264  video_pixel_height_(video_pixel_height),
+
265  audio_channels_(audio_channels),
+
266  audio_sampling_frequency_(audio_sampling_frequency) {
+
267  if (!allow_invalid_values) {
+
268  CHECK_GT(track_num_, 0);
+
269  CHECK_GT(track_type_, 0);
+
270  CHECK_LT(track_type_, 255);
+
271  CHECK_GT(track_uid_, 0);
+
272  if (track_type != kWebMTrackTypeVideo &&
+
273  track_type != kWebMTrackTypeAudio) {
+
274  CHECK_EQ(default_duration_, -1);
+
275  } else {
+
276  CHECK(default_duration_ == -1 || default_duration_ > 0);
+
277  }
+
278 
+
279  if (track_type == kWebMTrackTypeVideo) {
+
280  CHECK_GT(video_pixel_width_, 0);
+
281  CHECK_GT(video_pixel_height_, 0);
+
282  } else {
+
283  CHECK_EQ(video_pixel_width_, -1);
+
284  CHECK_EQ(video_pixel_height_, -1);
+
285  }
+
286 
+
287  if (track_type == kWebMTrackTypeAudio) {
+
288  CHECK_GT(audio_channels_, 0);
+
289  CHECK_GT(audio_sampling_frequency_, 0.0);
+
290  } else {
+
291  CHECK_EQ(audio_channels_, -1);
+
292  CHECK_EQ(audio_sampling_frequency_, -1.0);
+
293  }
+
294  }
+
295 }
+
296 
+
297 int TracksBuilder::Track::GetSize() const {
+
298  return MasterElementSize(kWebMIdTrackEntry, GetPayloadSize());
+
299 }
+
300 
+
301 int TracksBuilder::Track::GetVideoPayloadSize() const {
+
302  int payload_size = 0;
+
303 
+
304  if (video_pixel_width_ >= 0)
+
305  payload_size += UIntElementSize(kWebMIdPixelWidth, video_pixel_width_);
+
306  if (video_pixel_height_ >= 0)
+
307  payload_size += UIntElementSize(kWebMIdPixelHeight, video_pixel_height_);
+
308 
+
309  return payload_size;
+
310 }
+
311 
+
312 int TracksBuilder::Track::GetAudioPayloadSize() const {
+
313  int payload_size = 0;
+
314 
+
315  if (audio_channels_ >= 0)
+
316  payload_size += UIntElementSize(kWebMIdChannels, audio_channels_);
+
317  if (audio_sampling_frequency_ >= 0)
+
318  payload_size += DoubleElementSize(kWebMIdSamplingFrequency);
+
319 
+
320  return payload_size;
+
321 }
+
322 
+
323 int TracksBuilder::Track::GetPayloadSize() const {
+
324  int size = 0;
+
325 
+
326  size += UIntElementSize(kWebMIdTrackNumber, track_num_);
+
327  size += UIntElementSize(kWebMIdTrackType, track_type_);
+
328  size += UIntElementSize(kWebMIdTrackUID, track_uid_);
+
329 
+
330  if (default_duration_ >= 0)
+
331  size += UIntElementSize(kWebMIdDefaultDuration, default_duration_);
+
332 
+
333  if (!codec_id_.empty())
+
334  size += StringElementSize(kWebMIdCodecID, codec_id_);
+
335 
+
336  if (!name_.empty())
+
337  size += StringElementSize(kWebMIdName, name_);
+
338 
+
339  if (!language_.empty())
+
340  size += StringElementSize(kWebMIdLanguage, language_);
+
341 
+
342  if (GetVideoPayloadSize() > 0) {
+
343  size += MasterElementSize(kWebMIdVideo, GetVideoPayloadSize());
+
344  }
+
345 
+
346  if (GetAudioPayloadSize() > 0) {
+
347  size += MasterElementSize(kWebMIdAudio, GetAudioPayloadSize());
+
348  }
+
349 
+
350  return size;
+
351 }
+
352 
+
353 void TracksBuilder::Track::Write(uint8_t** buf, int* buf_size) const {
+
354  WriteMasterElement(buf, buf_size, kWebMIdTrackEntry, GetPayloadSize());
+
355 
+
356  WriteUIntElement(buf, buf_size, kWebMIdTrackNumber, track_num_);
+
357  WriteUIntElement(buf, buf_size, kWebMIdTrackType, track_type_);
+
358  WriteUIntElement(buf, buf_size, kWebMIdTrackUID, track_uid_);
+
359 
+
360  if (default_duration_ >= 0)
+
361  WriteUIntElement(buf, buf_size, kWebMIdDefaultDuration, default_duration_);
+
362 
+
363  if (!codec_id_.empty())
+
364  WriteStringElement(buf, buf_size, kWebMIdCodecID, codec_id_);
+
365 
+
366  if (!name_.empty())
+
367  WriteStringElement(buf, buf_size, kWebMIdName, name_);
+
368 
+
369  if (!language_.empty())
+
370  WriteStringElement(buf, buf_size, kWebMIdLanguage, language_);
+
371 
+
372  if (GetVideoPayloadSize() > 0) {
+
373  WriteMasterElement(buf, buf_size, kWebMIdVideo, GetVideoPayloadSize());
+
374 
+
375  if (video_pixel_width_ >= 0)
+
376  WriteUIntElement(buf, buf_size, kWebMIdPixelWidth, video_pixel_width_);
+
377 
+
378  if (video_pixel_height_ >= 0)
+
379  WriteUIntElement(buf, buf_size, kWebMIdPixelHeight, video_pixel_height_);
+
380  }
+
381 
+
382  if (GetAudioPayloadSize() > 0) {
+
383  WriteMasterElement(buf, buf_size, kWebMIdAudio, GetAudioPayloadSize());
+
384 
+
385  if (audio_channels_ >= 0)
+
386  WriteUIntElement(buf, buf_size, kWebMIdChannels, audio_channels_);
+
387 
+
388  if (audio_sampling_frequency_ >= 0) {
+
389  WriteDoubleElement(buf, buf_size, kWebMIdSamplingFrequency,
+
390  audio_sampling_frequency_);
+
391  }
+
392  }
+
393 }
+
394 
+
395 } // namespace media
+
396 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d33/video__slice__header__parser_8h_source.html b/docs/d2/d33/video__slice__header__parser_8h_source.html index c405d5a9d7..edd18a463e 100644 --- a/docs/d2/d33/video__slice__header__parser_8h_source.html +++ b/docs/d2/d33/video__slice__header__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/video_slice_header_parser.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
video_slice_header_parser.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CODECS_VIDEO_SLICE_HEADER_PARSER_H_
8 #define PACKAGER_MEDIA_CODECS_VIDEO_SLICE_HEADER_PARSER_H_
9 
10 #include <vector>
11 
12 #include "packager/media/base/macros.h"
13 #include "packager/media/codecs/h264_parser.h"
14 #include "packager/media/codecs/h265_parser.h"
15 
16 namespace shaka {
17 namespace media {
18 
20  public:
22  virtual ~VideoSliceHeaderParser() {}
23 
26  virtual bool Initialize(
27  const std::vector<uint8_t>& decoder_configuration) = 0;
28 
35  virtual bool ProcessNalu(const Nalu& nalu) = 0;
36 
38  virtual int64_t GetHeaderSize(const Nalu& nalu) = 0;
39 
40  private:
41  DISALLOW_COPY_AND_ASSIGN(VideoSliceHeaderParser);
42 };
43 
45  public:
47  ~H264VideoSliceHeaderParser() override;
48 
51  bool Initialize(const std::vector<uint8_t>& decoder_configuration) override;
52  bool ProcessNalu(const Nalu& nalu) override;
53  int64_t GetHeaderSize(const Nalu& nalu) override;
55 
56  private:
57  H264Parser parser_;
58 
59  DISALLOW_COPY_AND_ASSIGN(H264VideoSliceHeaderParser);
60 };
61 
63  public:
65  ~H265VideoSliceHeaderParser() override;
66 
69  bool Initialize(const std::vector<uint8_t>& decoder_configuration) override;
70  bool ProcessNalu(const Nalu& nalu) override;
71  int64_t GetHeaderSize(const Nalu& nalu) override;
73 
74  private:
75  H265Parser parser_;
76 
77  DISALLOW_COPY_AND_ASSIGN(H265VideoSliceHeaderParser);
78 };
79 
80 } // namespace media
81 } // namespace shaka
82 
83 #endif // PACKAGER_MEDIA_CODECS_VIDEO_SLICE_HEADER_PARSER_H_
- -
virtual bool ProcessNalu(const Nalu &nalu)=0
-
virtual int64_t GetHeaderSize(const Nalu &nalu)=0
Gets the header size of the given NALU. Returns < 0 on error.
-
All the methods that are virtual are virtual for mocking.
- - - - -
virtual bool Initialize(const std::vector< uint8_t > &decoder_configuration)=0
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_VIDEO_SLICE_HEADER_PARSER_H_
+
8 #define PACKAGER_MEDIA_CODECS_VIDEO_SLICE_HEADER_PARSER_H_
+
9 
+
10 #include <vector>
+
11 
+
12 #include "packager/media/base/macros.h"
+
13 #include "packager/media/codecs/h264_parser.h"
+
14 #include "packager/media/codecs/h265_parser.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+ +
20  public:
+ +
22  virtual ~VideoSliceHeaderParser() {}
+
23 
+
26  virtual bool Initialize(
+
27  const std::vector<uint8_t>& decoder_configuration) = 0;
+
28 
+
35  virtual bool ProcessNalu(const Nalu& nalu) = 0;
+
36 
+
38  virtual int64_t GetHeaderSize(const Nalu& nalu) = 0;
+
39 
+
40  private:
+
41  DISALLOW_COPY_AND_ASSIGN(VideoSliceHeaderParser);
+
42 };
+
43 
+ +
45  public:
+ +
47  ~H264VideoSliceHeaderParser() override;
+
48 
+
51  bool Initialize(const std::vector<uint8_t>& decoder_configuration) override;
+
52  bool ProcessNalu(const Nalu& nalu) override;
+
53  int64_t GetHeaderSize(const Nalu& nalu) override;
+
55 
+
56  private:
+
57  H264Parser parser_;
+
58 
+
59  DISALLOW_COPY_AND_ASSIGN(H264VideoSliceHeaderParser);
+
60 };
+
61 
+ +
63  public:
+ +
65  ~H265VideoSliceHeaderParser() override;
+
66 
+
69  bool Initialize(const std::vector<uint8_t>& decoder_configuration) override;
+
70  bool ProcessNalu(const Nalu& nalu) override;
+
71  int64_t GetHeaderSize(const Nalu& nalu) override;
+
73 
+
74  private:
+
75  H265Parser parser_;
+
76 
+
77  DISALLOW_COPY_AND_ASSIGN(H265VideoSliceHeaderParser);
+
78 };
+
79 
+
80 } // namespace media
+
81 } // namespace shaka
+
82 
+
83 #endif // PACKAGER_MEDIA_CODECS_VIDEO_SLICE_HEADER_PARSER_H_
+ + + +
bool Initialize(const std::vector< uint8_t > &decoder_configuration) override
+
int64_t GetHeaderSize(const Nalu &nalu) override
Gets the header size of the given NALU. Returns < 0 on error.
+ + +
int64_t GetHeaderSize(const Nalu &nalu) override
Gets the header size of the given NALU. Returns < 0 on error.
+
bool Initialize(const std::vector< uint8_t > &decoder_configuration) override
+ + + +
virtual int64_t GetHeaderSize(const Nalu &nalu)=0
Gets the header size of the given NALU. Returns < 0 on error.
+
virtual bool Initialize(const std::vector< uint8_t > &decoder_configuration)=0
+
virtual bool ProcessNalu(const Nalu &nalu)=0
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d35/classshaka_1_1media_1_1WidevineKeySource-members.html b/docs/d2/d35/classshaka_1_1media_1_1WidevineKeySource-members.html index d4113e6ef4..ab744d5348 100644 --- a/docs/d2/d35/classshaka_1_1media_1_1WidevineKeySource-members.html +++ b/docs/d2/d35/classshaka_1_1media_1_1WidevineKeySource-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) overrideshaka::media::WidevineKeySourcevirtual GetKey(const std::string &stream_label, EncryptionKey *key) overrideshaka::media::WidevineKeySourcevirtual GetKey(const std::vector< uint8_t > &key_id, EncryptionKey *key) overrideshaka::media::WidevineKeySourcevirtual - KeySource(int protection_systems_flags, FourCC protection_scheme) (defined in shaka::media::KeySource)shaka::media::KeySource + KeySource() (defined in shaka::media::KeySource)shaka::media::KeySource set_enable_entitlement_license(bool enable_entitlement_license) (defined in shaka::media::WidevineKeySource)shaka::media::WidevineKeySourceinline set_group_id(const std::vector< uint8_t > &group_id) (defined in shaka::media::WidevineKeySource)shaka::media::WidevineKeySourceinline set_key_fetcher(std::unique_ptr< KeyFetcher > key_fetcher)shaka::media::WidevineKeySource set_signer(std::unique_ptr< RequestSigner > signer)shaka::media::WidevineKeySource - UpdateProtectionSystemInfo(EncryptionKeyMap *encryption_key_map)shaka::media::KeySourceprotected - WidevineKeySource(const std::string &server_url, int protection_systems_flags, FourCC protection_scheme)shaka::media::WidevineKeySource - ~KeySource() (defined in shaka::media::KeySource)shaka::media::KeySourcevirtual - ~WidevineKeySource() override (defined in shaka::media::WidevineKeySource)shaka::media::WidevineKeySource + WidevineKeySource(const std::string &server_url, ProtectionSystem protection_systems, FourCC protection_scheme)shaka::media::WidevineKeySource + ~KeySource() (defined in shaka::media::KeySource)shaka::media::KeySourcevirtual + ~WidevineKeySource() override (defined in shaka::media::WidevineKeySource)shaka::media::WidevineKeySource
diff --git a/docs/d2/d37/classshaka_1_1media_1_1Job-members.html b/docs/d2/d37/classshaka_1_1media_1_1Job-members.html index 55f2571ca9..e4517aa970 100644 --- a/docs/d2/d37/classshaka_1_1media_1_1Job-members.html +++ b/docs/d2/d37/classshaka_1_1media_1_1Job-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d2/d3b/manifest__flags_8cc_source.html b/docs/d2/d3b/manifest__flags_8cc_source.html index 998b393894..d411aaa7a0 100644 --- a/docs/d2/d3b/manifest__flags_8cc_source.html +++ b/docs/d2/d3b/manifest__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/manifest_flags.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
manifest_flags.cc
-
1 // Copyright 2018 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/manifest_flags.h"
8 
9 DEFINE_double(time_shift_buffer_depth,
10  1800.0,
11  "Guaranteed duration of the time shifting buffer for HLS LIVE "
12  "playlists and DASH dynamic media presentations, in seconds.");
13 DEFINE_uint64(
14  preserved_segments_outside_live_window,
15  50,
16  "Segments outside the live window (defined by '--time_shift_buffer_depth') "
17  "are automatically removed except for the most recent X segments defined "
18  "by this parameter. This is needed to accommodate latencies in various "
19  "stages of content serving pipeline, so that the segments stay accessible "
20  "as they may still be accessed by the player."
21  "The segments are not removed if the value is zero.");
22 DEFINE_string(default_language,
23  "",
24  "For DASH, any audio/text tracks tagged with this language will "
25  "have <Role ... value=\"main\" /> in the manifest; For HLS, the "
26  "first audio/text rendition in a group tagged with this language "
27  "will have 'DEFAULT' attribute set to 'YES'. This allows the "
28  "player to choose the correct default language for the content."
29  "This applies to both audio and text tracks. The default "
30  "language for text tracks can be overriden by "
31  "'--default_text_language'.");
32 DEFINE_string(default_text_language,
33  "",
34  "Same as above, but this applies to text tracks only, and "
35  "overrides the default language for text tracks.");
+
1 // Copyright 2018 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/app/manifest_flags.h"
+
8 
+
9 DEFINE_double(time_shift_buffer_depth,
+
10  1800.0,
+
11  "Guaranteed duration of the time shifting buffer for HLS LIVE "
+
12  "playlists and DASH dynamic media presentations, in seconds.");
+
13 DEFINE_uint64(
+
14  preserved_segments_outside_live_window,
+
15  50,
+
16  "Segments outside the live window (defined by '--time_shift_buffer_depth') "
+
17  "are automatically removed except for the most recent X segments defined "
+
18  "by this parameter. This is needed to accommodate latencies in various "
+
19  "stages of content serving pipeline, so that the segments stay accessible "
+
20  "as they may still be accessed by the player."
+
21  "The segments are not removed if the value is zero.");
+
22 DEFINE_string(default_language,
+
23  "",
+
24  "For DASH, any audio/text tracks tagged with this language will "
+
25  "have <Role ... value=\"main\" /> in the manifest; For HLS, the "
+
26  "first audio/text rendition in a group tagged with this language "
+
27  "will have 'DEFAULT' attribute set to 'YES'. This allows the "
+
28  "player to choose the correct default language for the content."
+
29  "This applies to both audio and text tracks. The default "
+
30  "language for text tracks can be overriden by "
+
31  "'--default_text_language'.");
+
32 DEFINE_string(default_text_language,
+
33  "",
+
34  "Same as above, but this applies to text tracks only, and "
+
35  "overrides the default language for text tracks.");
+
diff --git a/docs/d2/d3c/muxer__factory_8cc_source.html b/docs/d2/d3c/muxer__factory_8cc_source.html index 94d7a6ae1b..1db657de88 100644 --- a/docs/d2/d3c/muxer__factory_8cc_source.html +++ b/docs/d2/d3c/muxer__factory_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/muxer_factory.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
muxer_factory.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/muxer_factory.h"
8 
9 #include "packager/base/time/clock.h"
10 #include "packager/media/base/muxer.h"
11 #include "packager/media/base/muxer_options.h"
12 #include "packager/media/formats/mp2t/ts_muxer.h"
13 #include "packager/media/formats/mp4/mp4_muxer.h"
14 #include "packager/media/formats/packed_audio/packed_audio_writer.h"
15 #include "packager/media/formats/webm/webm_muxer.h"
16 #include "packager/packager.h"
17 
18 namespace shaka {
19 namespace media {
20 
21 MuxerFactory::MuxerFactory(const PackagingParams& packaging_params)
22  : mp4_params_(packaging_params.mp4_output_params),
23  transport_stream_timestamp_offset_ms_(
24  packaging_params.transport_stream_timestamp_offset_ms),
25  temp_dir_(packaging_params.temp_dir) {}
26 
27 std::shared_ptr<Muxer> MuxerFactory::CreateMuxer(
28  MediaContainerName output_format,
29  const StreamDescriptor& stream) {
30  MuxerOptions options;
31  options.mp4_params = mp4_params_;
32  options.transport_stream_timestamp_offset_ms =
33  transport_stream_timestamp_offset_ms_;
34  options.temp_dir = temp_dir_;
35  options.output_file_name = stream.output;
36  options.segment_template = stream.segment_template;
37  options.bandwidth = stream.bandwidth;
38 
39  std::shared_ptr<Muxer> muxer;
40 
41  switch (output_format) {
42  case CONTAINER_AAC:
43  case CONTAINER_AC3:
44  case CONTAINER_EAC3:
45  muxer = std::make_shared<PackedAudioWriter>(options);
46  break;
47  case CONTAINER_WEBM:
48  muxer = std::make_shared<webm::WebMMuxer>(options);
49  break;
50  case CONTAINER_MPEG2TS:
51  muxer = std::make_shared<mp2t::TsMuxer>(options);
52  break;
53  case CONTAINER_MOV:
54  muxer = std::make_shared<mp4::MP4Muxer>(options);
55  break;
56  default:
57  LOG(ERROR) << "Cannot support muxing to " << output_format;
58  break;
59  }
60 
61  if (!muxer) {
62  return nullptr;
63  }
64 
65  // We successfully created a muxer, then there is a couple settings
66  // we should set before returning it.
67  if (clock_) {
68  muxer->set_clock(clock_);
69  }
70 
71  return muxer;
72 }
73 
74 void MuxerFactory::OverrideClock(base::Clock* clock) {
75  clock_ = clock;
76 }
77 } // namespace media
78 } // namespace shaka
Defines a single input/output stream.
Definition: packager.h:73
- -
std::string segment_template
Specifies segment template. Can be empty.
Definition: packager.h:85
-
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
-
std::shared_ptr< Muxer > CreateMuxer(MediaContainerName output_format, const StreamDescriptor &stream)
-
Mp4OutputParams mp4_params
MP4 (ISO-BMFF) specific parameters.
Definition: muxer_options.h:25
-
std::string output
Definition: packager.h:83
-
void OverrideClock(base::Clock *clock)
-
std::string temp_dir
Specify temporary directory for intermediate files.
Definition: muxer_options.h:43
- - - +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/app/muxer_factory.h"
+
8 
+
9 #include "packager/base/time/clock.h"
+
10 #include "packager/media/base/muxer.h"
+
11 #include "packager/media/base/muxer_options.h"
+
12 #include "packager/media/formats/mp2t/ts_muxer.h"
+
13 #include "packager/media/formats/mp4/mp4_muxer.h"
+
14 #include "packager/media/formats/packed_audio/packed_audio_writer.h"
+
15 #include "packager/media/formats/ttml/ttml_muxer.h"
+
16 #include "packager/media/formats/webm/webm_muxer.h"
+
17 #include "packager/media/formats/webvtt/webvtt_muxer.h"
+
18 #include "packager/packager.h"
+
19 
+
20 namespace shaka {
+
21 namespace media {
+
22 
+
23 MuxerFactory::MuxerFactory(const PackagingParams& packaging_params)
+
24  : mp4_params_(packaging_params.mp4_output_params),
+
25  temp_dir_(packaging_params.temp_dir),
+
26  transport_stream_timestamp_offset_ms_(
+
27  packaging_params.transport_stream_timestamp_offset_ms) {}
+
28 
+
29 std::shared_ptr<Muxer> MuxerFactory::CreateMuxer(
+
30  MediaContainerName output_format,
+
31  const StreamDescriptor& stream) {
+
32  MuxerOptions options;
+
33  options.mp4_params = mp4_params_;
+
34  options.transport_stream_timestamp_offset_ms =
+
35  transport_stream_timestamp_offset_ms_;
+
36  options.temp_dir = temp_dir_;
+
37  options.output_file_name = stream.output;
+
38  options.segment_template = stream.segment_template;
+
39  options.bandwidth = stream.bandwidth;
+
40 
+
41  std::shared_ptr<Muxer> muxer;
+
42 
+
43  switch (output_format) {
+
44  case CONTAINER_AAC:
+
45  case CONTAINER_MP3:
+
46  case CONTAINER_AC3:
+
47  case CONTAINER_EAC3:
+
48  muxer = std::make_shared<PackedAudioWriter>(options);
+
49  break;
+
50  case CONTAINER_WEBM:
+
51  muxer = std::make_shared<webm::WebMMuxer>(options);
+
52  break;
+
53  case CONTAINER_TTML:
+
54  muxer = std::make_shared<ttml::TtmlMuxer>(options);
+
55  break;
+
56  case CONTAINER_WEBVTT:
+
57  muxer = std::make_shared<webvtt::WebVttMuxer>(options);
+
58  break;
+
59  case CONTAINER_MPEG2TS:
+
60  muxer = std::make_shared<mp2t::TsMuxer>(options);
+
61  break;
+
62  case CONTAINER_MOV:
+
63  muxer = std::make_shared<mp4::MP4Muxer>(options);
+
64  break;
+
65  default:
+
66  LOG(ERROR) << "Cannot support muxing to " << output_format;
+
67  break;
+
68  }
+
69 
+
70  if (!muxer) {
+
71  return nullptr;
+
72  }
+
73 
+
74  // We successfully created a muxer, then there is a couple settings
+
75  // we should set before returning it.
+
76  if (clock_) {
+
77  muxer->set_clock(clock_);
+
78  }
+
79 
+
80  return muxer;
+
81 }
+
82 
+
83 void MuxerFactory::OverrideClock(base::Clock* clock) {
+
84  clock_ = clock;
+
85 }
+
86 } // namespace media
+
87 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
+
Defines a single input/output stream.
Definition: packager.h:76
+
std::string output
Definition: packager.h:86
+ +
std::string segment_template
Specifies segment template. Can be empty.
Definition: packager.h:88
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+ +
std::string temp_dir
Specify temporary directory for intermediate files.
Definition: muxer_options.h:43
+ +
Mp4OutputParams mp4_params
MP4 (ISO-BMFF) specific parameters.
Definition: muxer_options.h:25
+
diff --git a/docs/d2/d3c/structshaka_1_1media_1_1mp4_1_1TrackFragmentHeader-members.html b/docs/d2/d3c/structshaka_1_1media_1_1mp4_1_1TrackFragmentHeader-members.html index 43ed75acde..85ecc9f98c 100644 --- a/docs/d2/d3c/structshaka_1_1media_1_1mp4_1_1TrackFragmentHeader-members.html +++ b/docs/d2/d3c/structshaka_1_1media_1_1mp4_1_1TrackFragmentHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d42/webvtt__to__mp4__handler_8h_source.html b/docs/d2/d42/webvtt__to__mp4__handler_8h_source.html index d84c3e8bd8..fb2133316c 100644 --- a/docs/d2/d42/webvtt__to__mp4__handler_8h_source.html +++ b/docs/d2/d42/webvtt__to__mp4__handler_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/webvtt_to_mp4_handler.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webvtt_to_mp4_handler.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MP4_CUE_HANDLER_H_
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MP4_CUE_HANDLER_H_
9 
10 #include <stdint.h>
11 
12 #include <list>
13 #include <queue>
14 
15 #include "packager/media/base/buffer_writer.h"
16 #include "packager/media/base/media_handler.h"
17 
18 namespace shaka {
19 namespace media {
20 
21 // A media handler that should come after the cue aligner and segmenter and
22 // should come before the muxer. This handler is to convert text samples
23 // to media samples so that they can be sent to a mp4 muxer.
25  public:
26  WebVttToMp4Handler() = default;
27  virtual ~WebVttToMp4Handler() override = default;
28 
29  private:
30  WebVttToMp4Handler(const WebVttToMp4Handler&) = delete;
31  WebVttToMp4Handler& operator=(const WebVttToMp4Handler&) = delete;
32 
33  Status InitializeInternal() override;
34  Status Process(std::unique_ptr<StreamData> stream_data) override;
35 
36  Status OnStreamInfo(std::unique_ptr<StreamData> stream_data);
37  Status OnCueEvent(std::unique_ptr<StreamData> stream_data);
38  Status OnSegmentInfo(std::unique_ptr<StreamData> stream_data);
39  Status OnTextSample(std::unique_ptr<StreamData> stream_data);
40 
41  Status DispatchCurrentSegment(int64_t segment_start, int64_t segment_end);
42  Status MergeDispatchSamples(int64_t start_in_seconds,
43  int64_t end_in_seconds,
44  const std::list<const TextSample*>& state);
45 
46  std::list<std::shared_ptr<const TextSample>> current_segment_;
47 
48  // This is the current state of the box we are writing.
49  BufferWriter box_writer_;
50 };
51 
52 } // namespace media
53 } // namespace shaka
54 #endif // PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MP4_CUE_HANDLER_H_
-
All the methods that are virtual are virtual for mocking.
- - - +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MP4_CUE_HANDLER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MP4_CUE_HANDLER_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <list>
+
13 #include <queue>
+
14 
+
15 #include "packager/media/base/buffer_writer.h"
+
16 #include "packager/media/base/media_handler.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 
+
21 // A media handler that should come after the cue aligner and segmenter and
+
22 // should come before the muxer. This handler is to convert text samples
+
23 // to media samples so that they can be sent to a mp4 muxer.
+ +
25  public:
+
26  WebVttToMp4Handler() = default;
+
27  virtual ~WebVttToMp4Handler() override = default;
+
28 
+
29  private:
+
30  WebVttToMp4Handler(const WebVttToMp4Handler&) = delete;
+
31  WebVttToMp4Handler& operator=(const WebVttToMp4Handler&) = delete;
+
32 
+
33  Status InitializeInternal() override;
+
34  Status Process(std::unique_ptr<StreamData> stream_data) override;
+
35 
+
36  Status OnStreamInfo(std::unique_ptr<StreamData> stream_data);
+
37  Status OnCueEvent(std::unique_ptr<StreamData> stream_data);
+
38  Status OnSegmentInfo(std::unique_ptr<StreamData> stream_data);
+
39  Status OnTextSample(std::unique_ptr<StreamData> stream_data);
+
40 
+
41  Status DispatchCurrentSegment(int64_t segment_start, int64_t segment_end);
+
42  Status MergeDispatchSamples(int64_t start_in_seconds,
+
43  int64_t end_in_seconds,
+
44  const std::list<const TextSample*>& state);
+
45 
+
46  std::list<std::shared_ptr<const TextSample>> current_segment_;
+
47 
+
48  // This is the current state of the box we are writing.
+
49  BufferWriter box_writer_;
+
50 };
+
51 
+
52 } // namespace media
+
53 } // namespace shaka
+
54 #endif // PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_MP4_CUE_HANDLER_H_
+ + + + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d45/program__map__table__writer_8cc_source.html b/docs/d2/d45/program__map__table__writer_8cc_source.html index a1d5a06e71..a84f7cddde 100644 --- a/docs/d2/d45/program__map__table__writer_8cc_source.html +++ b/docs/d2/d45/program__map__table__writer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/program_map_table_writer.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
program_map_table_writer.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp2t/program_map_table_writer.h"
8 
9 #include <algorithm>
10 
11 #include "packager/base/logging.h"
12 #include "packager/media/base/buffer_writer.h"
13 #include "packager/media/base/fourccs.h"
14 #include "packager/media/codecs/hls_audio_util.h"
15 #include "packager/media/formats/mp2t/ts_packet_writer_util.h"
16 #include "packager/media/formats/mp2t/ts_stream_type.h"
17 
18 namespace shaka {
19 namespace media {
20 namespace mp2t {
21 
22 namespace {
23 
24 // Values for version. Only 0 and 1 are necessary for the implementation.
25 const int kVersion0 = 0;
26 const int kVersion1 = 1;
27 
28 // Values for current_next_indicator.
29 const int kCurrent = 1;
30 const int kNext= 0;
31 
32 // Program number is 16 bits but 8 bits is sufficient.
33 const uint8_t kProgramNumber = 0x01;
34 const uint8_t kProgramMapTableId = 0x02;
35 
36 // Table for CRC32/MPEG2.
37 const uint32_t kCrcTable[] = {
38  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
39  0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
40  0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
41  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
42  0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
43  0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
44  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
45  0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
46  0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
47  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
48  0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
49  0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
50  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
51  0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
52  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
53  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
54  0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
55  0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
56  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
57  0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
58  0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
59  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
60  0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
61  0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
62  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
63  0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
64  0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
65  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
66  0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
67  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
68  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
69  0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
70  0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
71  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
72  0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
73  0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
74  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
75  0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
76  0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
77  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
78  0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
79  0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
80  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
81  0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
82  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
83  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
84  0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
85  0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
86  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
87  0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
88  0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
89  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
90  0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
91  0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
92  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
93  0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
94  0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
95  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
96  0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
97  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
98  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
99  0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
100  0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
101  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4,
102 };
103 
104 // Note there are dozens of CRCs. This is one of them.
105 // http://reveng.sourceforge.net/crc-catalogue/all.htm
106 uint32_t Crc32Mpeg2(const uint8_t* data, size_t data_size) {
107  uint32_t crc = 0xFFFFFFFF;
108  for (size_t i = 0; i < data_size; ++i) {
109  crc = kCrcTable[((crc >> 24) ^ data[i]) & 0xFF] ^ (crc << 8);
110  }
111  return crc;
112 }
113 
114 void WritePmtToBuffer(const uint8_t* pmt,
115  size_t pmt_size,
116  ContinuityCounter* continuity_counter,
117  BufferWriter* writer) {
118  const bool kPayloadUnitStartIndicator = true;
119  const bool kHasPcr = true;
120  const uint64_t kAnyPcrBase = 0;
121  WritePayloadToBufferWriter(pmt, pmt_size, kPayloadUnitStartIndicator,
122  ProgramMapTableWriter::kPmtPid, !kHasPcr,
123  kAnyPcrBase, continuity_counter, writer);
124 }
125 
126 void WritePrivateDataIndicatorDescriptor(FourCC fourcc, BufferWriter* output) {
127  const uint8_t kPrivateDataIndicatorDescriptor = 15;
128  output->AppendInt(kPrivateDataIndicatorDescriptor);
129  output->AppendInt(static_cast<uint8_t>(sizeof(fourcc)));
130  output->AppendInt(fourcc);
131 }
132 
133 bool WriteRegistrationDescriptorForEncryptedAudio(Codec codec,
134  const uint8_t* setup_data,
135  size_t setup_data_size,
136  BufferWriter* output) {
137  const uint8_t kRegistrationDescriptor = 5;
138  BufferWriter audio_setup_information;
139  if (!WriteAudioSetupInformation(codec, setup_data, setup_data_size,
140  &audio_setup_information)) {
141  return false;
142  }
143 
144  const size_t registration_descriptor_size =
145  audio_setup_information.Size() + sizeof(FOURCC_apad);
146  if (registration_descriptor_size > std::numeric_limits<uint8_t>::max()) {
147  LOG(ERROR) << "Audio setup data of size: " << setup_data_size
148  << " will not fit in the descriptor.";
149  return false;
150  }
151 
152  output->AppendInt(kRegistrationDescriptor);
153  output->AppendInt(static_cast<uint8_t>(registration_descriptor_size));
154  output->AppendInt(FOURCC_apad);
155  output->AppendBuffer(audio_setup_information);
156  return true;
157 }
158 
159 void WritePmtWithParameters(uint8_t stream_type,
160  int version,
161  int current_next_indicator,
162  const uint8_t* descriptors,
163  size_t descriptors_size,
164  BufferWriter* pmt) {
165  DCHECK(current_next_indicator == kCurrent || current_next_indicator == kNext);
166  // Body starting from program number.
167  BufferWriter pmt_body;
168  pmt_body.AppendInt(static_cast<uint8_t>(0x00));
169  pmt_body.AppendInt(kProgramNumber);
170  // resevered bits then version and current_next_indicator.
171  pmt_body.AppendInt(
172  static_cast<uint8_t>(0xC0 |
173  static_cast<uint8_t>(version) << 1 |
174  static_cast<uint8_t>(current_next_indicator)));
175  // section number.
176  pmt_body.AppendInt(static_cast<uint8_t>(0x00));
177  // last section number.
178  pmt_body.AppendInt(static_cast<uint8_t>(0x00));
179  // first 3 bits reserved. Rest is unused bits for PCR PID.
180  pmt_body.AppendInt(static_cast<uint8_t>(0xE0));
181  pmt_body.AppendInt(ProgramMapTableWriter::kElementaryPid);
182  // First 4 bits are reserved. Next 12 bits is program_info_length which is 0.
183  pmt_body.AppendInt(static_cast<uint8_t>(0xF0));
184  pmt_body.AppendInt(static_cast<uint8_t>(0x00));
185 
186  pmt_body.AppendInt(stream_type);
187  // 3 reserved bits followed by 13 bit elementary_PID.
188  pmt_body.AppendInt(static_cast<uint8_t>(0xE0));
189  pmt_body.AppendInt(ProgramMapTableWriter::kElementaryPid);
190 
191  // 4 reserved bits followed by ES_info_length.
192  pmt_body.AppendInt(static_cast<uint16_t>(0xF000 | descriptors_size));
193  if (descriptors_size > 0) {
194  DCHECK(descriptors);
195  pmt_body.AppendArray(descriptors, descriptors_size);
196  }
197 
198  pmt->Clear();
199  // Pointer field is not really part of the PMT but it's there so that an extra
200  // buffer isn't required to prepend the 0x00 byte.
201  const uint8_t kPointerField = 0;
202  pmt->AppendInt(kPointerField);
203  pmt->AppendInt(kProgramMapTableId);
204  // First four bits must be '1011'. +4 for CRC.
205  pmt->AppendInt(static_cast<uint16_t>(0xB000 | (pmt_body.Size() + 4)));
206  pmt->AppendBuffer(pmt_body);
207 
208  // Don't include the pointer field.
209  const uint32_t crc = Crc32Mpeg2(pmt->Buffer() + 1, pmt->Size() - 1);
210  pmt->AppendInt(crc);
211 }
212 
213 } // namespace
214 
215 ProgramMapTableWriter::ProgramMapTableWriter(Codec codec) : codec_(codec) {}
216 
218  if (encrypted_pmt_.Size() == 0) {
219  TsStreamType stream_type;
220  switch (codec_) {
221  case kCodecH264:
222  stream_type = TsStreamType::kEncryptedAvc;
223  break;
224  case kCodecAAC:
225  stream_type = TsStreamType::kEncryptedAdtsAac;
226  break;
227  case kCodecAC3:
228  stream_type = TsStreamType::kEncryptedAc3;
229  break;
230  case kCodecEAC3:
231  stream_type = TsStreamType::kEncryptedEac3;
232  break;
233  default:
234  LOG(ERROR) << "Codec " << codec_ << " is not supported in TS yet.";
235  return false;
236  }
237 
238  BufferWriter descriptors;
239  if (!WriteDescriptors(&descriptors))
240  return false;
241 
242  const bool has_clear_lead = clear_pmt_.Size() > 0;
243  WritePmtWithParameters(static_cast<uint8_t>(stream_type),
244  has_clear_lead ? kVersion1 : kVersion0, kCurrent,
245  descriptors.Buffer(), descriptors.Size(),
246  &encrypted_pmt_);
247  DCHECK_NE(encrypted_pmt_.Size(), 0u);
248  }
249  WritePmtToBuffer(encrypted_pmt_.Buffer(), encrypted_pmt_.Size(),
250  &continuity_counter_, writer);
251  return true;
252 }
253 
255  if (clear_pmt_.Size() == 0) {
256  TsStreamType stream_type;
257  switch (codec_) {
258  case kCodecH264:
259  stream_type = TsStreamType::kAvc;
260  break;
261  case kCodecAAC:
262  stream_type = TsStreamType::kAdtsAac;
263  break;
264  case kCodecAC3:
265  stream_type = TsStreamType::kAc3;
266  break;
267  case kCodecEAC3:
268  stream_type = TsStreamType::kEac3;
269  break;
270  default:
271  LOG(ERROR) << "Codec " << codec_ << " is not supported in TS yet.";
272  return false;
273  }
274 
275  WritePmtWithParameters(static_cast<uint8_t>(stream_type), kVersion0,
276  kCurrent, nullptr, 0, &clear_pmt_);
277  DCHECK_NE(clear_pmt_.Size(), 0u);
278  }
279  WritePmtToBuffer(clear_pmt_.Buffer(), clear_pmt_.Size(), &continuity_counter_,
280  writer);
281  return true;
282 }
283 
284 VideoProgramMapTableWriter::VideoProgramMapTableWriter(Codec codec)
285  : ProgramMapTableWriter(codec) {}
286 
287 bool VideoProgramMapTableWriter::WriteDescriptors(
288  BufferWriter* descriptors) const {
289  FourCC fourcc;
290  switch (codec()) {
291  case kCodecH264:
292  fourcc = FOURCC_zavc;
293  break;
294  default:
295  LOG(ERROR) << "Codec " << codec() << " is not supported in TS yet.";
296  return false;
297  }
298  WritePrivateDataIndicatorDescriptor(fourcc, descriptors);
299  return true;
300 }
301 
302 AudioProgramMapTableWriter::AudioProgramMapTableWriter(
303  Codec codec,
304  const std::vector<uint8_t>& audio_specific_config)
305  : ProgramMapTableWriter(codec),
306  audio_specific_config_(audio_specific_config) {
307  DCHECK(!audio_specific_config.empty());
308 }
309 
310 bool AudioProgramMapTableWriter::WriteDescriptors(
311  BufferWriter* descriptors) const {
312  FourCC fourcc;
313  switch (codec()) {
314  case kCodecAAC:
315  fourcc = FOURCC_aacd;
316  break;
317  case kCodecAC3:
318  fourcc = FOURCC_ac3d;
319  break;
320  case kCodecEAC3:
321  fourcc = FOURCC_ec3d;
322  break;
323  default:
324  LOG(ERROR) << "Codec " << codec() << " is not supported in TS yet.";
325  return false;
326  }
327  WritePrivateDataIndicatorDescriptor(fourcc, descriptors);
328 
329  // NOTE: There are two specifications of carrying AC-3 bit stream in MPEG-2
330  // transport stream (ISO/IEC 13818-1):
331  // System A used by ATSC (TS 102 366 Digital Audio Compression Standard)
332  // stream_type: 0x81
333  // system_id: 0xBD (private_stream_1)
334  // Requires Registration_descriptor, AC-3_audio_stream_descriptor.
335  // Optional ISO_639_language_code descriptor.
336  // System B used by DVB (TS 101 154 DVB specification for ... based on the
337  // MPEG-2 Transport Stream)
338  // stream_type: 0x06 (private data)
339  // stream_id: 0xBD (private_stream_1)
340  // Requires AC-3_descriptor (not the same as AC-3_audio_stream_descriptor
341  // in ATSC)
342  // Optional ISO_639_language_code descriptor.
343  // We follow "System A" but not strictly as we do not include Registration
344  // descriptor and AC-3_audio_stream_descriptor right now.
345 
346  return WriteRegistrationDescriptorForEncryptedAudio(
347  codec(), audio_specific_config_.data(), audio_specific_config_.size(),
348  descriptors);
349 }
350 
351 } // namespace mp2t
352 } // namespace media
353 } // namespace shaka
const uint8_t * Buffer() const
Definition: buffer_writer.h:61
-
All the methods that are virtual are virtual for mocking.
- -
virtual bool ClearSegmentPmt(BufferWriter *writer)
Writes TS packets with PMT for clear segments.
-
virtual bool EncryptedSegmentPmt(BufferWriter *writer)
Writes TS packets with PMT for encrypted segments.
-
Puts PMT into TS packets and writes them to buffer.
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp2t/program_map_table_writer.h"
+
8 
+
9 #include <algorithm>
+
10 
+
11 #include "packager/base/logging.h"
+
12 #include "packager/media/base/buffer_writer.h"
+
13 #include "packager/media/base/fourccs.h"
+
14 #include "packager/media/codecs/hls_audio_util.h"
+
15 #include "packager/media/formats/mp2t/ts_packet_writer_util.h"
+
16 #include "packager/media/formats/mp2t/ts_stream_type.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 namespace mp2t {
+
21 
+
22 namespace {
+
23 
+
24 // Values for version. Only 0 and 1 are necessary for the implementation.
+
25 const int kVersion0 = 0;
+
26 const int kVersion1 = 1;
+
27 
+
28 // Values for current_next_indicator.
+
29 const int kCurrent = 1;
+
30 const int kNext= 0;
+
31 
+
32 // Program number is 16 bits but 8 bits is sufficient.
+
33 const uint8_t kProgramNumber = 0x01;
+
34 const uint8_t kProgramMapTableId = 0x02;
+
35 
+
36 // Table for CRC32/MPEG2.
+
37 const uint32_t kCrcTable[] = {
+
38  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
+
39  0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+
40  0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+
41  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+
42  0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
+
43  0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+
44  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
+
45  0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+
46  0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+
47  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+
48  0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
+
49  0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+
50  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
+
51  0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+
52  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+
53  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+
54  0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
+
55  0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+
56  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+
57  0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
+
58  0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+
59  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+
60  0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
+
61  0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+
62  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
+
63  0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+
64  0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+
65  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+
66  0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+
67  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+
68  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
+
69  0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+
70  0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+
71  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+
72  0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
+
73  0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+
74  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
+
75  0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+
76  0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+
77  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+
78  0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
+
79  0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+
80  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
+
81  0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+
82  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+
83  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+
84  0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
+
85  0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+
86  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+
87  0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+
88  0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+
89  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+
90  0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
+
91  0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+
92  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
+
93  0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+
94  0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+
95  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+
96  0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+
97  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+
98  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
+
99  0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+
100  0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+
101  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4,
+
102 };
+
103 
+
104 // Note there are dozens of CRCs. This is one of them.
+
105 // http://reveng.sourceforge.net/crc-catalogue/all.htm
+
106 uint32_t Crc32Mpeg2(const uint8_t* data, size_t data_size) {
+
107  uint32_t crc = 0xFFFFFFFF;
+
108  for (size_t i = 0; i < data_size; ++i) {
+
109  crc = kCrcTable[((crc >> 24) ^ data[i]) & 0xFF] ^ (crc << 8);
+
110  }
+
111  return crc;
+
112 }
+
113 
+
114 void WritePmtToBuffer(const uint8_t* pmt,
+
115  size_t pmt_size,
+
116  ContinuityCounter* continuity_counter,
+
117  BufferWriter* writer) {
+
118  const bool kPayloadUnitStartIndicator = true;
+
119  const bool kHasPcr = true;
+
120  const uint64_t kAnyPcrBase = 0;
+
121  WritePayloadToBufferWriter(pmt, pmt_size, kPayloadUnitStartIndicator,
+
122  ProgramMapTableWriter::kPmtPid, !kHasPcr,
+
123  kAnyPcrBase, continuity_counter, writer);
+
124 }
+
125 
+
126 void WritePrivateDataIndicatorDescriptor(FourCC fourcc, BufferWriter* output) {
+
127  const uint8_t kPrivateDataIndicatorDescriptor = 15;
+
128  output->AppendInt(kPrivateDataIndicatorDescriptor);
+
129  output->AppendInt(static_cast<uint8_t>(sizeof(fourcc)));
+
130  output->AppendInt(fourcc);
+
131 }
+
132 
+
133 bool WriteRegistrationDescriptorForEncryptedAudio(Codec codec,
+
134  const uint8_t* setup_data,
+
135  size_t setup_data_size,
+
136  BufferWriter* output) {
+
137  const uint8_t kRegistrationDescriptor = 5;
+
138  BufferWriter audio_setup_information;
+
139  if (!WriteAudioSetupInformation(codec, setup_data, setup_data_size,
+
140  &audio_setup_information)) {
+
141  return false;
+
142  }
+
143 
+
144  const size_t registration_descriptor_size =
+
145  audio_setup_information.Size() + sizeof(FOURCC_apad);
+
146  if (registration_descriptor_size > std::numeric_limits<uint8_t>::max()) {
+
147  LOG(ERROR) << "Audio setup data of size: " << setup_data_size
+
148  << " will not fit in the descriptor.";
+
149  return false;
+
150  }
+
151 
+
152  output->AppendInt(kRegistrationDescriptor);
+
153  output->AppendInt(static_cast<uint8_t>(registration_descriptor_size));
+
154  output->AppendInt(FOURCC_apad);
+
155  output->AppendBuffer(audio_setup_information);
+
156  return true;
+
157 }
+
158 
+
159 void WritePmtWithParameters(uint8_t stream_type,
+
160  int version,
+
161  int current_next_indicator,
+
162  const uint8_t* descriptors,
+
163  size_t descriptors_size,
+
164  BufferWriter* pmt) {
+
165  DCHECK(current_next_indicator == kCurrent || current_next_indicator == kNext);
+
166  // Body starting from program number.
+
167  BufferWriter pmt_body;
+
168  pmt_body.AppendInt(static_cast<uint8_t>(0x00));
+
169  pmt_body.AppendInt(kProgramNumber);
+
170  // resevered bits then version and current_next_indicator.
+
171  pmt_body.AppendInt(
+
172  static_cast<uint8_t>(0xC0 |
+
173  static_cast<uint8_t>(version) << 1 |
+
174  static_cast<uint8_t>(current_next_indicator)));
+
175  // section number.
+
176  pmt_body.AppendInt(static_cast<uint8_t>(0x00));
+
177  // last section number.
+
178  pmt_body.AppendInt(static_cast<uint8_t>(0x00));
+
179  // first 3 bits reserved. Rest is unused bits for PCR PID.
+
180  pmt_body.AppendInt(static_cast<uint8_t>(0xE0));
+
181  pmt_body.AppendInt(ProgramMapTableWriter::kElementaryPid);
+
182  // First 4 bits are reserved. Next 12 bits is program_info_length which is 0.
+
183  pmt_body.AppendInt(static_cast<uint8_t>(0xF0));
+
184  pmt_body.AppendInt(static_cast<uint8_t>(0x00));
+
185 
+
186  pmt_body.AppendInt(stream_type);
+
187  // 3 reserved bits followed by 13 bit elementary_PID.
+
188  pmt_body.AppendInt(static_cast<uint8_t>(0xE0));
+
189  pmt_body.AppendInt(ProgramMapTableWriter::kElementaryPid);
+
190 
+
191  // 4 reserved bits followed by ES_info_length.
+
192  pmt_body.AppendInt(static_cast<uint16_t>(0xF000 | descriptors_size));
+
193  if (descriptors_size > 0) {
+
194  DCHECK(descriptors);
+
195  pmt_body.AppendArray(descriptors, descriptors_size);
+
196  }
+
197 
+
198  pmt->Clear();
+
199  // Pointer field is not really part of the PMT but it's there so that an extra
+
200  // buffer isn't required to prepend the 0x00 byte.
+
201  const uint8_t kPointerField = 0;
+
202  pmt->AppendInt(kPointerField);
+
203  pmt->AppendInt(kProgramMapTableId);
+
204  // First four bits must be '1011'. +4 for CRC.
+
205  pmt->AppendInt(static_cast<uint16_t>(0xB000 | (pmt_body.Size() + 4)));
+
206  pmt->AppendBuffer(pmt_body);
+
207 
+
208  // Don't include the pointer field.
+
209  const uint32_t crc = Crc32Mpeg2(pmt->Buffer() + 1, pmt->Size() - 1);
+
210  pmt->AppendInt(crc);
+
211 }
+
212 
+
213 } // namespace
+
214 
+
215 ProgramMapTableWriter::ProgramMapTableWriter(Codec codec) : codec_(codec) {}
+
216 
+
217 bool ProgramMapTableWriter::EncryptedSegmentPmt(BufferWriter* writer) {
+
218  if (encrypted_pmt_.Size() == 0) {
+
219  TsStreamType stream_type;
+
220  switch (codec_) {
+
221  case kCodecH264:
+
222  stream_type = TsStreamType::kEncryptedAvc;
+
223  break;
+
224  case kCodecAAC:
+
225  stream_type = TsStreamType::kEncryptedAdtsAac;
+
226  break;
+
227  case kCodecAC3:
+
228  stream_type = TsStreamType::kEncryptedAc3;
+
229  break;
+
230  case kCodecEAC3:
+
231  stream_type = TsStreamType::kEncryptedEac3;
+
232  break;
+
233  default:
+
234  LOG(ERROR) << "Codec " << codec_ << " is not supported in TS yet.";
+
235  return false;
+
236  }
+
237 
+
238  BufferWriter descriptors;
+
239  if (!WriteDescriptors(&descriptors))
+
240  return false;
+
241 
+
242  const bool has_clear_lead = clear_pmt_.Size() > 0;
+
243  WritePmtWithParameters(static_cast<uint8_t>(stream_type),
+
244  has_clear_lead ? kVersion1 : kVersion0, kCurrent,
+
245  descriptors.Buffer(), descriptors.Size(),
+
246  &encrypted_pmt_);
+
247  DCHECK_NE(encrypted_pmt_.Size(), 0u);
+
248  }
+
249  WritePmtToBuffer(encrypted_pmt_.Buffer(), encrypted_pmt_.Size(),
+
250  &continuity_counter_, writer);
+
251  return true;
+
252 }
+
253 
+
254 bool ProgramMapTableWriter::ClearSegmentPmt(BufferWriter* writer) {
+
255  if (clear_pmt_.Size() == 0) {
+
256  TsStreamType stream_type;
+
257  switch (codec_) {
+
258  case kCodecH264:
+
259  stream_type = TsStreamType::kAvc;
+
260  break;
+
261  case kCodecAAC:
+
262  stream_type = TsStreamType::kAdtsAac;
+
263  break;
+
264  case kCodecMP3:
+
265  stream_type = TsStreamType::kMpeg1Audio;
+
266  break;
+
267  case kCodecAC3:
+
268  stream_type = TsStreamType::kAc3;
+
269  break;
+
270  case kCodecEAC3:
+
271  stream_type = TsStreamType::kEac3;
+
272  break;
+
273  default:
+
274  LOG(ERROR) << "Codec " << codec_ << " is not supported in TS yet.";
+
275  return false;
+
276  }
+
277 
+
278  WritePmtWithParameters(static_cast<uint8_t>(stream_type), kVersion0,
+
279  kCurrent, nullptr, 0, &clear_pmt_);
+
280  DCHECK_NE(clear_pmt_.Size(), 0u);
+
281  }
+
282  WritePmtToBuffer(clear_pmt_.Buffer(), clear_pmt_.Size(), &continuity_counter_,
+
283  writer);
+
284  return true;
+
285 }
+
286 
+
287 VideoProgramMapTableWriter::VideoProgramMapTableWriter(Codec codec)
+
288  : ProgramMapTableWriter(codec) {}
+
289 
+
290 bool VideoProgramMapTableWriter::WriteDescriptors(
+
291  BufferWriter* descriptors) const {
+
292  FourCC fourcc;
+
293  switch (codec()) {
+
294  case kCodecH264:
+
295  fourcc = FOURCC_zavc;
+
296  break;
+
297  default:
+
298  LOG(ERROR) << "Codec " << codec() << " is not supported in TS yet.";
+
299  return false;
+
300  }
+
301  WritePrivateDataIndicatorDescriptor(fourcc, descriptors);
+
302  return true;
+
303 }
+
304 
+
305 AudioProgramMapTableWriter::AudioProgramMapTableWriter(
+
306  Codec codec,
+
307  const std::vector<uint8_t>& audio_specific_config)
+
308  : ProgramMapTableWriter(codec),
+
309  audio_specific_config_(audio_specific_config) {
+
310  DCHECK(!audio_specific_config.empty());
+
311 }
+
312 
+
313 bool AudioProgramMapTableWriter::WriteDescriptors(
+
314  BufferWriter* descriptors) const {
+
315  FourCC fourcc;
+
316  switch (codec()) {
+
317  case kCodecAAC:
+
318  fourcc = FOURCC_aacd;
+
319  break;
+
320  case kCodecMP3:
+
321  fourcc = FOURCC_mp3a;
+
322  break;
+
323  case kCodecAC3:
+
324  fourcc = FOURCC_ac3d;
+
325  break;
+
326  case kCodecEAC3:
+
327  fourcc = FOURCC_ec3d;
+
328  break;
+
329  default:
+
330  LOG(ERROR) << "Codec " << codec() << " is not supported in TS yet.";
+
331  return false;
+
332  }
+
333  WritePrivateDataIndicatorDescriptor(fourcc, descriptors);
+
334 
+
335  // NOTE: There are two specifications of carrying AC-3 bit stream in MPEG-2
+
336  // transport stream (ISO/IEC 13818-1):
+
337  // System A used by ATSC (TS 102 366 Digital Audio Compression Standard)
+
338  // stream_type: 0x81
+
339  // system_id: 0xBD (private_stream_1)
+
340  // Requires Registration_descriptor, AC-3_audio_stream_descriptor.
+
341  // Optional ISO_639_language_code descriptor.
+
342  // System B used by DVB (TS 101 154 DVB specification for ... based on the
+
343  // MPEG-2 Transport Stream)
+
344  // stream_type: 0x06 (private data)
+
345  // stream_id: 0xBD (private_stream_1)
+
346  // Requires AC-3_descriptor (not the same as AC-3_audio_stream_descriptor
+
347  // in ATSC)
+
348  // Optional ISO_639_language_code descriptor.
+
349  // We follow "System A" but not strictly as we do not include Registration
+
350  // descriptor and AC-3_audio_stream_descriptor right now.
+
351 
+
352  return WriteRegistrationDescriptorForEncryptedAudio(
+
353  codec(), audio_specific_config_.data(), audio_specific_config_.size(),
+
354  descriptors);
+
355 }
+
356 
+
357 } // namespace mp2t
+
358 } // namespace media
+
359 } // namespace shaka
+ +
const uint8_t * Buffer() const
Definition: buffer_writer.h:61
+
Puts PMT into TS packets and writes them to buffer.
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d4c/nal__unit__to__byte__stream__converter_8cc_source.html b/docs/d2/d4c/nal__unit__to__byte__stream__converter_8cc_source.html index 6ace881a94..423009c957 100644 --- a/docs/d2/d4c/nal__unit__to__byte__stream__converter_8cc_source.html +++ b/docs/d2/d4c/nal__unit__to__byte__stream__converter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/nal_unit_to_byte_stream_converter.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
nal_unit_to_byte_stream_converter.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/nal_unit_to_byte_stream_converter.h"
8 
9 #include <list>
10 
11 #include "packager/base/logging.h"
12 #include "packager/media/base/bit_reader.h"
13 #include "packager/media/base/buffer_reader.h"
14 #include "packager/media/base/buffer_writer.h"
15 #include "packager/media/base/macros.h"
16 #include "packager/media/codecs/nalu_reader.h"
17 
18 namespace shaka {
19 namespace media {
20 
21 namespace {
22 
23 const bool kEscapeData = true;
24 const uint8_t kNaluStartCode[] = {0x00, 0x00, 0x00, 0x01};
25 
26 const uint8_t kEmulationPreventionByte = 0x03;
27 
28 const uint8_t kAccessUnitDelimiterRbspAnyPrimaryPicType = 0xF0;
29 
30 bool IsNaluEqual(const Nalu& left, const Nalu& right) {
31  if (left.type() != right.type())
32  return false;
33  const size_t left_size = left.header_size() + left.payload_size();
34  const size_t right_size = right.header_size() + right.payload_size();
35  if (left_size != right_size)
36  return false;
37  return memcmp(left.data(), right.data(), left_size) == 0;
38 }
39 
40 void AppendNalu(const Nalu& nalu,
41  int nalu_length_size,
42  bool escape_data,
43  BufferWriter* buffer_writer) {
44  if (escape_data) {
45  EscapeNalByteSequence(nalu.data(), nalu.header_size() + nalu.payload_size(),
46  buffer_writer);
47  } else {
48  buffer_writer->AppendArray(nalu.data(),
49  nalu.header_size() + nalu.payload_size());
50  }
51 }
52 
53 void AddAccessUnitDelimiter(BufferWriter* buffer_writer) {
54  buffer_writer->AppendInt(static_cast<uint8_t>(Nalu::H264_AUD));
55  // For now, primary_pic_type is 7 which is "anything".
56  buffer_writer->AppendInt(kAccessUnitDelimiterRbspAnyPrimaryPicType);
57 }
58 
59 } // namespace
60 
61 void EscapeNalByteSequence(const uint8_t* input,
62  size_t input_size,
63  BufferWriter* output_writer) {
64  // Keep track of consecutive zeros that it has seen (not including the current
65  // byte), so that the algorithm doesn't need to go back to check the same
66  // bytes.
67  int consecutive_zero_count = 0;
68  for (size_t i = 0; i < input_size; ++i) {
69  if (consecutive_zero_count <= 1) {
70  output_writer->AppendInt(input[i]);
71  } else if (consecutive_zero_count == 2) {
72  if (input[i] == 0 || input[i] == 1 || input[i] == 2 || input[i] == 3) {
73  // Must be escaped.
74  output_writer->AppendInt(kEmulationPreventionByte);
75  }
76 
77  output_writer->AppendInt(input[i]);
78  // Note that input[i] can be 0.
79  // 00 00 00 00 00 00 should become
80  // 00 00 03 00 00 03 00 00 03
81  // So consecutive_zero_count is reset here and incremented below if
82  // input[i] is 0.
83  consecutive_zero_count = 0;
84  }
85 
86  consecutive_zero_count = input[i] == 0 ? consecutive_zero_count + 1 : 0;
87  }
88 
89  // ISO 14496-10 Section 7.4.1.1 mentions that if the last byte is 0 (which
90  // only happens if RBSP has cabac_zero_word), 0x03 must be appended.
91  if (consecutive_zero_count > 0) {
92  DCHECK_GT(input_size, 0u);
93  DCHECK_EQ(input[input_size - 1], 0u);
94  output_writer->AppendInt(kEmulationPreventionByte);
95  }
96 }
97 
98 // This functions creates a new subsample entry (|clear_bytes|, |cipher_bytes|)
99 // and appends it to |subsamples|. It splits the oversized (64KB) clear_bytes
100 // into smaller ones.
101 void AppendSubsamples(uint32_t clear_bytes,
102  uint32_t cipher_bytes,
103  std::vector<SubsampleEntry>* subsamples) {
104  while (clear_bytes > UINT16_MAX) {
105  subsamples->emplace_back(UINT16_MAX, 0);
106  clear_bytes -= UINT16_MAX;
107  }
108  subsamples->emplace_back(clear_bytes, cipher_bytes);
109 }
110 
111 // TODO(hmchen): Wrap methods of processing subsamples into a separate class,
112 // e.g., SubsampleReader.
113 // This function finds the range of the subsamples corresponding a NAL unit
114 // size. If a subsample crosses the boundary of two NAL units, it is split into
115 // smaller subsamples. Each call processes one NAL unit and it assumes the input
116 // NAL unit is already aligned with subsamples->at(start_subsample_id).
117 //
118 // An example of calling multiple times on each NAL unit is as follow:
119 //
120 // Input:
121 //
122 // Nalu 0 Nalu 1 Nalu 2
123 // | | |
124 // v v v
125 // | clear | cipher | clear | clear | clear | cipher |
126 //
127 // | Subsample 0 | Subsample 1 |
128 //
129 // Output:
130 //
131 // | Subsample 0 | Subsample 1 | Subsample 2 | Subsample 3 |
132 //
133 // Nalu 0: start_subsample_id = 0, next_subsample_id = 2
134 // Nalu 1: start_subsample_id = 2, next_subsample_id = 3
135 // Nalu 2: start_subsample_id = 3, next_subsample_id = 4
136 bool AlignSubsamplesWithNalu(size_t nalu_size,
137  size_t start_subsample_id,
138  std::vector<SubsampleEntry>* subsamples,
139  size_t* next_subsample_id) {
140  DCHECK(subsamples && !subsamples->empty());
141  size_t subsample_id = start_subsample_id;
142  size_t nalu_size_remain = nalu_size;
143  size_t subsample_bytes = 0;
144  while (subsample_id < subsamples->size()) {
145  subsample_bytes = subsamples->at(subsample_id).clear_bytes +
146  subsamples->at(subsample_id).cipher_bytes;
147  if (nalu_size_remain <= subsample_bytes) {
148  break;
149  }
150  nalu_size_remain -= subsample_bytes;
151  subsample_id++;
152  }
153 
154  if (subsample_id == subsamples->size()) {
155  DCHECK_GT(nalu_size_remain, 0u);
156  LOG(ERROR)
157  << "Total size of NAL unit is larger than the size of subsamples.";
158  return false;
159  }
160 
161  if (nalu_size_remain == subsample_bytes) {
162  *next_subsample_id = subsample_id + 1;
163  return true;
164  }
165 
166  DCHECK_GT(subsample_bytes, nalu_size_remain);
167  size_t clear_bytes = subsamples->at(subsample_id).clear_bytes;
168  size_t new_clear_bytes = 0;
169  size_t new_cipher_bytes = 0;
170  if (nalu_size_remain < clear_bytes) {
171  new_clear_bytes = nalu_size_remain;
172  } else {
173  new_clear_bytes = clear_bytes;
174  new_cipher_bytes = nalu_size_remain - clear_bytes;
175  }
176  subsamples->insert(subsamples->begin() + subsample_id,
177  SubsampleEntry(static_cast<uint16_t>(new_clear_bytes),
178  static_cast<uint32_t>(new_cipher_bytes)));
179  subsample_id++;
180  subsamples->at(subsample_id).clear_bytes -=
181  static_cast<uint16_t>(new_clear_bytes);
182  subsamples->at(subsample_id).cipher_bytes -=
183  static_cast<uint32_t>(new_cipher_bytes);
184  *next_subsample_id = subsample_id;
185  return true;
186 }
187 
188 // This function tries to merge clear-only into clear+cipher subsamples. This
189 // merge makes sure the clear_bytes will not exceed the clear size limits
190 // (2^16 bytes).
191 std::vector<SubsampleEntry> MergeSubsamples(
192  const std::vector<SubsampleEntry>& subsamples) {
193  std::vector<SubsampleEntry> new_subsamples;
194  uint32_t clear_bytes = 0;
195  for (size_t i = 0; i < subsamples.size(); ++i) {
196  clear_bytes += subsamples[i].clear_bytes;
197  // Add new subsample(s).
198  if (subsamples[i].cipher_bytes > 0 || i == subsamples.size() - 1) {
199  AppendSubsamples(clear_bytes, subsamples[i].cipher_bytes,
200  &new_subsamples);
201  clear_bytes = 0;
202  }
203  }
204  return new_subsamples;
205 }
206 
207 NalUnitToByteStreamConverter::NalUnitToByteStreamConverter()
208  : nalu_length_size_(0) {}
209 NalUnitToByteStreamConverter::~NalUnitToByteStreamConverter() {}
210 
212  const uint8_t* decoder_configuration_data,
213  size_t decoder_configuration_data_size) {
214  if (!decoder_configuration_data || decoder_configuration_data_size == 0) {
215  LOG(ERROR) << "Decoder conguration is empty.";
216  return false;
217  }
218 
219  if (!decoder_config_.Parse(std::vector<uint8_t>(
220  decoder_configuration_data,
221  decoder_configuration_data + decoder_configuration_data_size))) {
222  return false;
223  }
224 
225  if (decoder_config_.nalu_count() < 2) {
226  LOG(ERROR) << "Cannot find SPS or PPS.";
227  return false;
228  }
229 
230  nalu_length_size_ = decoder_config_.nalu_length_size();
231 
232  BufferWriter buffer_writer(decoder_configuration_data_size);
233  bool found_sps = false;
234  bool found_pps = false;
235  for (uint32_t i = 0; i < decoder_config_.nalu_count(); ++i) {
236  const Nalu& nalu = decoder_config_.nalu(i);
237  if (nalu.type() == Nalu::H264NaluType::H264_SPS) {
238  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
239  AppendNalu(nalu, nalu_length_size_, !kEscapeData, &buffer_writer);
240  found_sps = true;
241  } else if (nalu.type() == Nalu::H264NaluType::H264_PPS) {
242  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
243  AppendNalu(nalu, nalu_length_size_, !kEscapeData, &buffer_writer);
244  found_pps = true;
245  }
246  }
247  if (!found_sps || !found_pps) {
248  LOG(ERROR) << "Failed to find SPS or PPS.";
249  return false;
250  }
251 
252  buffer_writer.SwapBuffer(&decoder_configuration_in_byte_stream_);
253  return true;
254 }
255 
257  const uint8_t* sample,
258  size_t sample_size,
259  bool is_key_frame,
260  std::vector<uint8_t>* output) {
261  return ConvertUnitToByteStreamWithSubsamples(
262  sample, sample_size, is_key_frame, false, output,
263  nullptr); // Skip subsample update.
264 }
265 
266 // This ignores all AUD, SPS, and PPS in the sample. Instead uses the data
267 // parsed in Initialize(). However, if the SPS and PPS are different to
268 // those parsed in Initialized(), they are kept.
270  const uint8_t* sample,
271  size_t sample_size,
272  bool is_key_frame,
273  bool escape_encrypted_nalu,
274  std::vector<uint8_t>* output,
275  std::vector<SubsampleEntry>* subsamples) {
276  if (!sample || sample_size == 0) {
277  LOG(WARNING) << "Sample is empty.";
278  return true;
279  }
280 
281  std::vector<SubsampleEntry> temp_subsamples;
282 
283  BufferWriter buffer_writer(sample_size);
284  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
285  AddAccessUnitDelimiter(&buffer_writer);
286  if (is_key_frame)
287  buffer_writer.AppendVector(decoder_configuration_in_byte_stream_);
288 
289  if (subsamples && !subsamples->empty()) {
290  // The inserted part in buffer_writer is all clear. Add a corresponding
291  // all-clear subsample.
292  AppendSubsamples(static_cast<uint32_t>(buffer_writer.Size()), 0u,
293  &temp_subsamples);
294  }
295 
296  NaluReader nalu_reader(Nalu::kH264, nalu_length_size_, sample, sample_size);
297  Nalu nalu;
298  NaluReader::Result result = nalu_reader.Advance(&nalu);
299 
300  size_t start_subsample_id = 0;
301  size_t next_subsample_id = 0;
302  while (result == NaluReader::kOk) {
303  const size_t old_nalu_size =
304  nalu_length_size_ + nalu.header_size() + nalu.payload_size();
305  if (subsamples && !subsamples->empty()) {
306  if (!AlignSubsamplesWithNalu(old_nalu_size, start_subsample_id,
307  subsamples, &next_subsample_id)) {
308  return false;
309  }
310  }
311  switch (nalu.type()) {
312  case Nalu::H264_AUD:
313  break;
314  case Nalu::H264_SPS:
315  FALLTHROUGH_INTENDED;
316  case Nalu::H264_PPS: {
317  // Also write this SPS/PPS if it is not the same as SPS/PPS in decoder
318  // configuration, which is already written.
319  //
320  // For more information see:
321  // - github.com/google/shaka-packager/issues/327
322  // - ISO/IEC 14496-15 5.4.5 Sync Sample
323  //
324  // TODO(kqyang): Parse sample data to figure out which SPS/PPS the
325  // sample actually uses and include that only.
326  bool new_decoder_config = true;
327  for (size_t i = 0; i < decoder_config_.nalu_count(); ++i) {
328  if (IsNaluEqual(decoder_config_.nalu(i), nalu)) {
329  new_decoder_config = false;
330  break;
331  }
332  }
333  if (!new_decoder_config)
334  break;
335  FALLTHROUGH_INTENDED;
336  }
337  default:
338  bool escape_data = false;
339  if (subsamples && !subsamples->empty()) {
340  if (escape_encrypted_nalu) {
341  for (size_t i = start_subsample_id; i < next_subsample_id; ++i) {
342  if (subsamples->at(i).cipher_bytes != 0) {
343  escape_data = true;
344  break;
345  }
346  }
347  }
348  }
349  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
350  AppendNalu(nalu, nalu_length_size_, escape_data, &buffer_writer);
351 
352  if (subsamples && !subsamples->empty()) {
353  temp_subsamples.emplace_back(
354  static_cast<uint16_t>(arraysize(kNaluStartCode)), 0u);
355  // Update the first subsample of each NAL unit, which replaces NAL
356  // unit length field with start code. Note that if the escape_data is
357  // true, the total data size and the cipher_bytes may be changed.
358  // However, since the escape_data for encrypted nalu is only used in
359  // Sample-AES, which means the subsample is not really used,
360  // inaccurate subsamples should not be a big deal.
361  if (subsamples->at(start_subsample_id).clear_bytes <
362  nalu_length_size_) {
363  LOG(ERROR) << "Clear bytes ("
364  << subsamples->at(start_subsample_id).clear_bytes
365  << ") in start subsample of NAL unit is less than NAL "
366  "unit length size ("
367  << nalu_length_size_
368  << "). The NAL unit length size is (partially) "
369  "encrypted. In that case, it cannot be "
370  "converted to byte stream.";
371  return false;
372  }
373  subsamples->at(start_subsample_id).clear_bytes -= nalu_length_size_;
374  temp_subsamples.insert(temp_subsamples.end(),
375  subsamples->begin() + start_subsample_id,
376  subsamples->begin() + next_subsample_id);
377  }
378  break;
379  }
380 
381  start_subsample_id = next_subsample_id;
382  result = nalu_reader.Advance(&nalu);
383  }
384 
385  DCHECK_NE(result, NaluReader::kOk);
386  if (result != NaluReader::kEOStream) {
387  LOG(ERROR) << "Stopped reading before end of stream.";
388  return false;
389  }
390 
391  buffer_writer.SwapBuffer(output);
392  if (subsamples && !subsamples->empty()) {
393  if (next_subsample_id < subsamples->size()) {
394  LOG(ERROR)
395  << "The total size of NAL unit is shorter than the subsample size.";
396  return false;
397  }
398  // This function may modify the new_subsamples. But since it creates a
399  // merged verion and assign to the output subsamples, the input one is no
400  // longer used.
401  *subsamples = MergeSubsamples(temp_subsamples);
402  }
403  return true;
404 }
405 
406 } // namespace media
407 } // namespace shaka
-
virtual bool ConvertUnitToByteStream(const uint8_t *sample, size_t sample_size, bool is_key_frame, std::vector< uint8_t > *output)
-
virtual bool Initialize(const uint8_t *decoder_configuration_data, size_t decoder_configuration_data_size)
-
All the methods that are virtual are virtual for mocking.
-
uint64_t header_size() const
The size of the header, e.g. 1 for H.264.
Definition: nalu_reader.h:100
- -
Result Advance(Nalu *nalu)
Definition: nalu_reader.cc:241
- -
virtual bool ConvertUnitToByteStreamWithSubsamples(const uint8_t *sample, size_t sample_size, bool is_key_frame, bool escape_encrypted_nalu, std::vector< uint8_t > *output, std::vector< SubsampleEntry > *subsamples)
-
int type() const
Definition: nalu_reader.h:113
-
uint64_t payload_size() const
Size of this Nalu minus header_size().
Definition: nalu_reader.h:102
- +
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/nal_unit_to_byte_stream_converter.h"
+
8 
+
9 #include <list>
+
10 
+
11 #include "packager/base/logging.h"
+
12 #include "packager/media/base/bit_reader.h"
+
13 #include "packager/media/base/buffer_reader.h"
+
14 #include "packager/media/base/buffer_writer.h"
+
15 #include "packager/media/base/macros.h"
+
16 #include "packager/media/codecs/nalu_reader.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 
+
21 namespace {
+
22 
+
23 const bool kEscapeData = true;
+
24 const uint8_t kNaluStartCode[] = {0x00, 0x00, 0x00, 0x01};
+
25 
+
26 const uint8_t kEmulationPreventionByte = 0x03;
+
27 
+
28 const uint8_t kAccessUnitDelimiterRbspAnyPrimaryPicType = 0xF0;
+
29 
+
30 bool IsNaluEqual(const Nalu& left, const Nalu& right) {
+
31  if (left.type() != right.type())
+
32  return false;
+
33  const size_t left_size = left.header_size() + left.payload_size();
+
34  const size_t right_size = right.header_size() + right.payload_size();
+
35  if (left_size != right_size)
+
36  return false;
+
37  return memcmp(left.data(), right.data(), left_size) == 0;
+
38 }
+
39 
+
40 void AppendNalu(const Nalu& nalu,
+
41  int nalu_length_size,
+
42  bool escape_data,
+
43  BufferWriter* buffer_writer) {
+
44  if (escape_data) {
+
45  EscapeNalByteSequence(nalu.data(), nalu.header_size() + nalu.payload_size(),
+
46  buffer_writer);
+
47  } else {
+
48  buffer_writer->AppendArray(nalu.data(),
+
49  nalu.header_size() + nalu.payload_size());
+
50  }
+
51 }
+
52 
+
53 void AddAccessUnitDelimiter(BufferWriter* buffer_writer) {
+
54  buffer_writer->AppendInt(static_cast<uint8_t>(Nalu::H264_AUD));
+
55  // For now, primary_pic_type is 7 which is "anything".
+
56  buffer_writer->AppendInt(kAccessUnitDelimiterRbspAnyPrimaryPicType);
+
57 }
+
58 
+
59 } // namespace
+
60 
+
61 void EscapeNalByteSequence(const uint8_t* input,
+
62  size_t input_size,
+
63  BufferWriter* output_writer) {
+
64  // Keep track of consecutive zeros that it has seen (not including the current
+
65  // byte), so that the algorithm doesn't need to go back to check the same
+
66  // bytes.
+
67  int consecutive_zero_count = 0;
+
68  for (size_t i = 0; i < input_size; ++i) {
+
69  if (consecutive_zero_count <= 1) {
+
70  output_writer->AppendInt(input[i]);
+
71  } else if (consecutive_zero_count == 2) {
+
72  if (input[i] == 0 || input[i] == 1 || input[i] == 2 || input[i] == 3) {
+
73  // Must be escaped.
+
74  output_writer->AppendInt(kEmulationPreventionByte);
+
75  }
+
76 
+
77  output_writer->AppendInt(input[i]);
+
78  // Note that input[i] can be 0.
+
79  // 00 00 00 00 00 00 should become
+
80  // 00 00 03 00 00 03 00 00 03
+
81  // So consecutive_zero_count is reset here and incremented below if
+
82  // input[i] is 0.
+
83  consecutive_zero_count = 0;
+
84  }
+
85 
+
86  consecutive_zero_count = input[i] == 0 ? consecutive_zero_count + 1 : 0;
+
87  }
+
88 
+
89  // ISO 14496-10 Section 7.4.1.1 mentions that if the last byte is 0 (which
+
90  // only happens if RBSP has cabac_zero_word), 0x03 must be appended.
+
91  if (consecutive_zero_count > 0) {
+
92  DCHECK_GT(input_size, 0u);
+
93  DCHECK_EQ(input[input_size - 1], 0u);
+
94  output_writer->AppendInt(kEmulationPreventionByte);
+
95  }
+
96 }
+
97 
+
98 // This functions creates a new subsample entry (|clear_bytes|, |cipher_bytes|)
+
99 // and appends it to |subsamples|. It splits the oversized (64KB) clear_bytes
+
100 // into smaller ones.
+
101 void AppendSubsamples(uint32_t clear_bytes,
+
102  uint32_t cipher_bytes,
+
103  std::vector<SubsampleEntry>* subsamples) {
+
104  while (clear_bytes > UINT16_MAX) {
+
105  subsamples->emplace_back(UINT16_MAX, 0);
+
106  clear_bytes -= UINT16_MAX;
+
107  }
+
108  subsamples->emplace_back(clear_bytes, cipher_bytes);
+
109 }
+
110 
+
111 // TODO(hmchen): Wrap methods of processing subsamples into a separate class,
+
112 // e.g., SubsampleReader.
+
113 // This function finds the range of the subsamples corresponding a NAL unit
+
114 // size. If a subsample crosses the boundary of two NAL units, it is split into
+
115 // smaller subsamples. Each call processes one NAL unit and it assumes the input
+
116 // NAL unit is already aligned with subsamples->at(start_subsample_id).
+
117 //
+
118 // An example of calling multiple times on each NAL unit is as follow:
+
119 //
+
120 // Input:
+
121 //
+
122 // Nalu 0 Nalu 1 Nalu 2
+
123 // | | |
+
124 // v v v
+
125 // | clear | cipher | clear | clear | clear | cipher |
+
126 //
+
127 // | Subsample 0 | Subsample 1 |
+
128 //
+
129 // Output:
+
130 //
+
131 // | Subsample 0 | Subsample 1 | Subsample 2 | Subsample 3 |
+
132 //
+
133 // Nalu 0: start_subsample_id = 0, next_subsample_id = 2
+
134 // Nalu 1: start_subsample_id = 2, next_subsample_id = 3
+
135 // Nalu 2: start_subsample_id = 3, next_subsample_id = 4
+
136 bool AlignSubsamplesWithNalu(size_t nalu_size,
+
137  size_t start_subsample_id,
+
138  std::vector<SubsampleEntry>* subsamples,
+
139  size_t* next_subsample_id) {
+
140  DCHECK(subsamples && !subsamples->empty());
+
141  size_t subsample_id = start_subsample_id;
+
142  size_t nalu_size_remain = nalu_size;
+
143  size_t subsample_bytes = 0;
+
144  while (subsample_id < subsamples->size()) {
+
145  subsample_bytes = subsamples->at(subsample_id).clear_bytes +
+
146  subsamples->at(subsample_id).cipher_bytes;
+
147  if (nalu_size_remain <= subsample_bytes) {
+
148  break;
+
149  }
+
150  nalu_size_remain -= subsample_bytes;
+
151  subsample_id++;
+
152  }
+
153 
+
154  if (subsample_id == subsamples->size()) {
+
155  DCHECK_GT(nalu_size_remain, 0u);
+
156  LOG(ERROR)
+
157  << "Total size of NAL unit is larger than the size of subsamples.";
+
158  return false;
+
159  }
+
160 
+
161  if (nalu_size_remain == subsample_bytes) {
+
162  *next_subsample_id = subsample_id + 1;
+
163  return true;
+
164  }
+
165 
+
166  DCHECK_GT(subsample_bytes, nalu_size_remain);
+
167  size_t clear_bytes = subsamples->at(subsample_id).clear_bytes;
+
168  size_t new_clear_bytes = 0;
+
169  size_t new_cipher_bytes = 0;
+
170  if (nalu_size_remain < clear_bytes) {
+
171  new_clear_bytes = nalu_size_remain;
+
172  } else {
+
173  new_clear_bytes = clear_bytes;
+
174  new_cipher_bytes = nalu_size_remain - clear_bytes;
+
175  }
+
176  subsamples->insert(subsamples->begin() + subsample_id,
+
177  SubsampleEntry(static_cast<uint16_t>(new_clear_bytes),
+
178  static_cast<uint32_t>(new_cipher_bytes)));
+
179  subsample_id++;
+
180  subsamples->at(subsample_id).clear_bytes -=
+
181  static_cast<uint16_t>(new_clear_bytes);
+
182  subsamples->at(subsample_id).cipher_bytes -=
+
183  static_cast<uint32_t>(new_cipher_bytes);
+
184  *next_subsample_id = subsample_id;
+
185  return true;
+
186 }
+
187 
+
188 // This function tries to merge clear-only into clear+cipher subsamples. This
+
189 // merge makes sure the clear_bytes will not exceed the clear size limits
+
190 // (2^16 bytes).
+
191 std::vector<SubsampleEntry> MergeSubsamples(
+
192  const std::vector<SubsampleEntry>& subsamples) {
+
193  std::vector<SubsampleEntry> new_subsamples;
+
194  uint32_t clear_bytes = 0;
+
195  for (size_t i = 0; i < subsamples.size(); ++i) {
+
196  clear_bytes += subsamples[i].clear_bytes;
+
197  // Add new subsample(s).
+
198  if (subsamples[i].cipher_bytes > 0 || i == subsamples.size() - 1) {
+
199  AppendSubsamples(clear_bytes, subsamples[i].cipher_bytes,
+
200  &new_subsamples);
+
201  clear_bytes = 0;
+
202  }
+
203  }
+
204  return new_subsamples;
+
205 }
+
206 
+
207 NalUnitToByteStreamConverter::NalUnitToByteStreamConverter()
+
208  : nalu_length_size_(0) {}
+
209 NalUnitToByteStreamConverter::~NalUnitToByteStreamConverter() {}
+
210 
+
211 bool NalUnitToByteStreamConverter::Initialize(
+
212  const uint8_t* decoder_configuration_data,
+
213  size_t decoder_configuration_data_size) {
+
214  if (!decoder_configuration_data || decoder_configuration_data_size == 0) {
+
215  LOG(ERROR) << "Decoder conguration is empty.";
+
216  return false;
+
217  }
+
218 
+
219  if (!decoder_config_.Parse(std::vector<uint8_t>(
+
220  decoder_configuration_data,
+
221  decoder_configuration_data + decoder_configuration_data_size))) {
+
222  return false;
+
223  }
+
224 
+
225  if (decoder_config_.nalu_count() < 2) {
+
226  LOG(ERROR) << "Cannot find SPS or PPS.";
+
227  return false;
+
228  }
+
229 
+
230  nalu_length_size_ = decoder_config_.nalu_length_size();
+
231 
+
232  BufferWriter buffer_writer(decoder_configuration_data_size);
+
233  bool found_sps = false;
+
234  bool found_pps = false;
+
235  for (uint32_t i = 0; i < decoder_config_.nalu_count(); ++i) {
+
236  const Nalu& nalu = decoder_config_.nalu(i);
+
237  if (nalu.type() == Nalu::H264NaluType::H264_SPS) {
+
238  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
+
239  AppendNalu(nalu, nalu_length_size_, !kEscapeData, &buffer_writer);
+
240  found_sps = true;
+
241  } else if (nalu.type() == Nalu::H264NaluType::H264_PPS) {
+
242  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
+
243  AppendNalu(nalu, nalu_length_size_, !kEscapeData, &buffer_writer);
+
244  found_pps = true;
+
245  } else if (nalu.type() == Nalu::H264NaluType::H264_SPSExtension) {
+
246  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
+
247  AppendNalu(nalu, nalu_length_size_, !kEscapeData, &buffer_writer);
+
248  }
+
249  }
+
250  if (!found_sps || !found_pps) {
+
251  LOG(ERROR) << "Failed to find SPS or PPS.";
+
252  return false;
+
253  }
+
254 
+
255  buffer_writer.SwapBuffer(&decoder_configuration_in_byte_stream_);
+
256  return true;
+
257 }
+
258 
+
259 bool NalUnitToByteStreamConverter::ConvertUnitToByteStream(
+
260  const uint8_t* sample,
+
261  size_t sample_size,
+
262  bool is_key_frame,
+
263  std::vector<uint8_t>* output) {
+
264  return ConvertUnitToByteStreamWithSubsamples(
+
265  sample, sample_size, is_key_frame, false, output,
+
266  nullptr); // Skip subsample update.
+
267 }
+
268 
+
269 // This ignores all AUD, SPS, and PPS in the sample. Instead uses the data
+
270 // parsed in Initialize(). However, if the SPS and PPS are different to
+
271 // those parsed in Initialized(), they are kept.
+
272 bool NalUnitToByteStreamConverter::ConvertUnitToByteStreamWithSubsamples(
+
273  const uint8_t* sample,
+
274  size_t sample_size,
+
275  bool is_key_frame,
+
276  bool escape_encrypted_nalu,
+
277  std::vector<uint8_t>* output,
+
278  std::vector<SubsampleEntry>* subsamples) {
+
279  if (!sample || sample_size == 0) {
+
280  LOG(WARNING) << "Sample is empty.";
+
281  return true;
+
282  }
+
283 
+
284  std::vector<SubsampleEntry> temp_subsamples;
+
285 
+
286  BufferWriter buffer_writer(sample_size);
+
287  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
+
288  AddAccessUnitDelimiter(&buffer_writer);
+
289  if (is_key_frame)
+
290  buffer_writer.AppendVector(decoder_configuration_in_byte_stream_);
+
291 
+
292  if (subsamples && !subsamples->empty()) {
+
293  // The inserted part in buffer_writer is all clear. Add a corresponding
+
294  // all-clear subsample.
+
295  AppendSubsamples(static_cast<uint32_t>(buffer_writer.Size()), 0u,
+
296  &temp_subsamples);
+
297  }
+
298 
+
299  NaluReader nalu_reader(Nalu::kH264, nalu_length_size_, sample, sample_size);
+
300  Nalu nalu;
+
301  NaluReader::Result result = nalu_reader.Advance(&nalu);
+
302 
+
303  size_t start_subsample_id = 0;
+
304  size_t next_subsample_id = 0;
+
305  while (result == NaluReader::kOk) {
+
306  const size_t old_nalu_size =
+
307  nalu_length_size_ + nalu.header_size() + nalu.payload_size();
+
308  if (subsamples && !subsamples->empty()) {
+
309  if (!AlignSubsamplesWithNalu(old_nalu_size, start_subsample_id,
+
310  subsamples, &next_subsample_id)) {
+
311  return false;
+
312  }
+
313  }
+
314  switch (nalu.type()) {
+
315  case Nalu::H264_AUD:
+
316  break;
+
317  case Nalu::H264_SPS:
+
318  FALLTHROUGH_INTENDED;
+
319  case Nalu::H264_SPSExtension:
+
320  FALLTHROUGH_INTENDED;
+
321  case Nalu::H264_PPS: {
+
322  // Also write this SPS/PPS if it is not the same as SPS/PPS in decoder
+
323  // configuration, which is already written.
+
324  //
+
325  // For more information see:
+
326  // - github.com/google/shaka-packager/issues/327
+
327  // - ISO/IEC 14496-15 5.4.5 Sync Sample
+
328  //
+
329  // TODO(kqyang): Parse sample data to figure out which SPS/PPS the
+
330  // sample actually uses and include that only.
+
331  bool new_decoder_config = true;
+
332  for (size_t i = 0; i < decoder_config_.nalu_count(); ++i) {
+
333  if (IsNaluEqual(decoder_config_.nalu(i), nalu)) {
+
334  new_decoder_config = false;
+
335  break;
+
336  }
+
337  }
+
338  if (!new_decoder_config)
+
339  break;
+
340  FALLTHROUGH_INTENDED;
+
341  }
+
342  default:
+
343  bool escape_data = false;
+
344  if (subsamples && !subsamples->empty()) {
+
345  if (escape_encrypted_nalu) {
+
346  for (size_t i = start_subsample_id; i < next_subsample_id; ++i) {
+
347  if (subsamples->at(i).cipher_bytes != 0) {
+
348  escape_data = true;
+
349  break;
+
350  }
+
351  }
+
352  }
+
353  }
+
354  buffer_writer.AppendArray(kNaluStartCode, arraysize(kNaluStartCode));
+
355  AppendNalu(nalu, nalu_length_size_, escape_data, &buffer_writer);
+
356 
+
357  if (subsamples && !subsamples->empty()) {
+
358  temp_subsamples.emplace_back(
+
359  static_cast<uint16_t>(arraysize(kNaluStartCode)), 0u);
+
360  // Update the first subsample of each NAL unit, which replaces NAL
+
361  // unit length field with start code. Note that if the escape_data is
+
362  // true, the total data size and the cipher_bytes may be changed.
+
363  // However, since the escape_data for encrypted nalu is only used in
+
364  // Sample-AES, which means the subsample is not really used,
+
365  // inaccurate subsamples should not be a big deal.
+
366  if (subsamples->at(start_subsample_id).clear_bytes <
+
367  nalu_length_size_) {
+
368  LOG(ERROR) << "Clear bytes ("
+
369  << subsamples->at(start_subsample_id).clear_bytes
+
370  << ") in start subsample of NAL unit is less than NAL "
+
371  "unit length size ("
+
372  << nalu_length_size_
+
373  << "). The NAL unit length size is (partially) "
+
374  "encrypted. In that case, it cannot be "
+
375  "converted to byte stream.";
+
376  return false;
+
377  }
+
378  subsamples->at(start_subsample_id).clear_bytes -= nalu_length_size_;
+
379  temp_subsamples.insert(temp_subsamples.end(),
+
380  subsamples->begin() + start_subsample_id,
+
381  subsamples->begin() + next_subsample_id);
+
382  }
+
383  break;
+
384  }
+
385 
+
386  start_subsample_id = next_subsample_id;
+
387  result = nalu_reader.Advance(&nalu);
+
388  }
+
389 
+
390  DCHECK_NE(result, NaluReader::kOk);
+
391  if (result != NaluReader::kEOStream) {
+
392  LOG(ERROR) << "Stopped reading before end of stream.";
+
393  return false;
+
394  }
+
395 
+
396  buffer_writer.SwapBuffer(output);
+
397  if (subsamples && !subsamples->empty()) {
+
398  if (next_subsample_id < subsamples->size()) {
+
399  LOG(ERROR)
+
400  << "The total size of NAL unit is shorter than the subsample size.";
+
401  return false;
+
402  }
+
403  // This function may modify the new_subsamples. But since it creates a
+
404  // merged verion and assign to the output subsamples, the input one is no
+
405  // longer used.
+
406  *subsamples = MergeSubsamples(temp_subsamples);
+
407  }
+
408  return true;
+
409 }
+
410 
+
411 } // namespace media
+
412 } // namespace shaka
+ + +
Result Advance(Nalu *nalu)
Definition: nalu_reader.cc:241
+ +
int type() const
Definition: nalu_reader.h:113
+
uint64_t header_size() const
The size of the header, e.g. 1 for H.264.
Definition: nalu_reader.h:100
+
uint64_t payload_size() const
Size of this Nalu minus header_size().
Definition: nalu_reader.h:102
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d4d/file_8h_source.html b/docs/d2/d4d/file_8h_source.html index 0201f4b44c..8df23392d7 100644 --- a/docs/d2/d4d/file_8h_source.html +++ b/docs/d2/d4d/file_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/file.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
file.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_FILE_FILE_H_
8 #define PACKAGER_FILE_FILE_H_
9 
10 #include <stdint.h>
11 
12 #include <string>
13 
14 #include "packager/base/macros.h"
15 #include "packager/file/public/buffer_callback_params.h"
16 
17 namespace shaka {
18 
19 extern const char* kCallbackFilePrefix;
20 extern const char* kLocalFilePrefix;
21 extern const char* kMemoryFilePrefix;
22 extern const char* kUdpFilePrefix;
23 const int64_t kWholeFile = -1;
24 
26 class File {
27  public:
34  static File* Open(const char* file_name, const char* mode);
35 
42  static File* OpenWithNoBuffering(const char* file_name, const char* mode);
43 
47  static bool Delete(const char* file_name);
48 
54  virtual bool Close() = 0;
55 
62  virtual int64_t Read(void* buffer, uint64_t length) = 0;
63 
68  virtual int64_t Write(const void* buffer, uint64_t length) = 0;
69 
72  virtual int64_t Size() = 0;
73 
79  virtual bool Flush() = 0;
80 
84  virtual bool Seek(uint64_t position) = 0;
85 
90  virtual bool Tell(uint64_t* position) = 0;
91 
94  const std::string& file_name() const { return file_name_; }
95 
96  // ************************************************************
97  // * Static Methods: File-on-the-filesystem status
98  // ************************************************************
99 
102  static int64_t GetFileSize(const char* file_name);
103 
108  static bool ReadFileToString(const char* file_name, std::string* contents);
109 
114  static bool WriteStringToFile(const char* file_name,
115  const std::string& contents);
116 
121  static bool WriteFileAtomically(const char* file_name,
122  const std::string& contents);
123 
130  static bool Copy(const char* from_file_name, const char* to_file_name);
131 
136  static int64_t CopyFile(File* source, File* destination);
137 
143  static int64_t CopyFile(File* source, File* destination, int64_t max_copy);
144 
147  static bool IsLocalRegularFile(const char* file_name);
148 
155  static std::string MakeCallbackFileName(
156  const BufferCallbackParams& callback_params,
157  const std::string& name);
158 
165  static bool ParseCallbackFileName(
166  const std::string& callback_file_name,
167  const BufferCallbackParams** callback_params,
168  std::string* name);
169 
170  protected:
171  explicit File(const std::string& file_name) : file_name_(file_name) {}
174  virtual ~File() {}
175 
177  virtual bool Open() = 0;
178 
179  private:
180  friend class ThreadedIoFile;
181 
182  // This is a file factory method, it creates a proper file, e.g.
183  // LocalFile, MemFile based on prefix.
184  static File* Create(const char* file_name, const char* mode);
185 
186  static File* CreateInternalFile(const char* file_name, const char* mode);
187 
188  // Note that the file type prefix has been stripped off.
189  std::string file_name_;
190 
191  DISALLOW_COPY_AND_ASSIGN(File);
192 };
193 
194 } // namespace shaka
195 
196 #endif // PACKAGER_FILE_FILE_H_
virtual int64_t Write(const void *buffer, uint64_t length)=0
-
static bool Delete(const char *file_name)
Definition: file.cc:198
-
Define an abstract file interface.
Definition: file.h:26
-
static bool IsLocalRegularFile(const char *file_name)
Definition: file.cc:354
-
static bool Copy(const char *from_file_name, const char *to_file_name)
Definition: file.cc:281
-
static int64_t CopyFile(File *source, File *destination)
Definition: file.cc:316
-
static bool ReadFileToString(const char *file_name, std::string *contents)
Definition: file.cc:216
-
virtual int64_t Read(void *buffer, uint64_t length)=0
-
const std::string & file_name() const
Definition: file.h:94
-
Declaration of class which implements a thread-safe circular buffer.
-
All the methods that are virtual are virtual for mocking.
-
static int64_t GetFileSize(const char *file_name)
Definition: file.cc:207
-
virtual bool Tell(uint64_t *position)=0
-
virtual bool Close()=0
-
virtual bool Flush()=0
-
virtual int64_t Size()=0
-
static bool WriteStringToFile(const char *file_name, const std::string &contents)
Definition: file.cc:234
-
virtual bool Seek(uint64_t position)=0
-
static std::string MakeCallbackFileName(const BufferCallbackParams &callback_params, const std::string &name)
Definition: file.cc:379
-
static File * OpenWithNoBuffering(const char *file_name, const char *mode)
Definition: file.cc:187
-
virtual ~File()
Definition: file.h:174
-
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:262
-
static bool ParseCallbackFileName(const std::string &callback_file_name, const BufferCallbackParams **callback_params, std::string *name)
Definition: file.cc:389
-
virtual bool Open()=0
Internal open. Should not be used directly.
-
Buffer callback params.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_FILE_FILE_H_
+
8 #define PACKAGER_FILE_FILE_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <string>
+
13 
+
14 #include "packager/base/macros.h"
+
15 #include "packager/file/public/buffer_callback_params.h"
+
16 
+
17 namespace shaka {
+
18 
+
19 extern const char* kCallbackFilePrefix;
+
20 extern const char* kLocalFilePrefix;
+
21 extern const char* kMemoryFilePrefix;
+
22 extern const char* kUdpFilePrefix;
+
23 extern const char* kHttpFilePrefix;
+
24 const int64_t kWholeFile = -1;
+
25 
+
27 class File {
+
28  public:
+
35  static File* Open(const char* file_name, const char* mode);
+
36 
+
43  static File* OpenWithNoBuffering(const char* file_name, const char* mode);
+
44 
+
48  static bool Delete(const char* file_name);
+
49 
+
55  virtual bool Close() = 0;
+
56 
+
63  virtual int64_t Read(void* buffer, uint64_t length) = 0;
+
64 
+
69  virtual int64_t Write(const void* buffer, uint64_t length) = 0;
+
70 
+
73  virtual int64_t Size() = 0;
+
74 
+
80  virtual bool Flush() = 0;
+
81 
+
85  virtual bool Seek(uint64_t position) = 0;
+
86 
+
91  virtual bool Tell(uint64_t* position) = 0;
+
92 
+
95  const std::string& file_name() const { return file_name_; }
+
96 
+
97  // ************************************************************
+
98  // * Static Methods: File-on-the-filesystem status
+
99  // ************************************************************
+
100 
+
103  static int64_t GetFileSize(const char* file_name);
+
104 
+
109  static bool ReadFileToString(const char* file_name, std::string* contents);
+
110 
+
115  static bool WriteStringToFile(const char* file_name,
+
116  const std::string& contents);
+
117 
+
122  static bool WriteFileAtomically(const char* file_name,
+
123  const std::string& contents);
+
124 
+
131  static bool Copy(const char* from_file_name, const char* to_file_name);
+
132 
+
137  static int64_t CopyFile(File* source, File* destination);
+
138 
+
144  static int64_t CopyFile(File* source, File* destination, int64_t max_copy);
+
145 
+
148  static bool IsLocalRegularFile(const char* file_name);
+
149 
+
156  static std::string MakeCallbackFileName(
+
157  const BufferCallbackParams& callback_params,
+
158  const std::string& name);
+
159 
+
166  static bool ParseCallbackFileName(
+
167  const std::string& callback_file_name,
+
168  const BufferCallbackParams** callback_params,
+
169  std::string* name);
+
170 
+
171  protected:
+
172  explicit File(const std::string& file_name) : file_name_(file_name) {}
+
175  virtual ~File() {}
+
176 
+
178  virtual bool Open() = 0;
+
179 
+
180  private:
+
181  friend class ThreadedIoFile;
+
182 
+
183  // This is a file factory method, it creates a proper file, e.g.
+
184  // LocalFile, MemFile based on prefix.
+
185  static File* Create(const char* file_name, const char* mode);
+
186 
+
187  static File* CreateInternalFile(const char* file_name, const char* mode);
+
188 
+
189  // Note that the file type prefix has been stripped off.
+
190  std::string file_name_;
+
191 
+
192  DISALLOW_COPY_AND_ASSIGN(File);
+
193 };
+
194 
+
195 } // namespace shaka
+
196 
+
197 #endif // PACKAGER_FILE_FILE_H_
+
Define an abstract file interface.
Definition: file.h:27
+
virtual bool Tell(uint64_t *position)=0
+
static File * OpenWithNoBuffering(const char *file_name, const char *mode)
Definition: file.cc:201
+
static bool Delete(const char *file_name)
Definition: file.cc:212
+
static bool WriteStringToFile(const char *file_name, const std::string &contents)
Definition: file.cc:248
+
virtual bool Seek(uint64_t position)=0
+
const std::string & file_name() const
Definition: file.h:95
+
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:277
+
virtual bool Flush()=0
+
virtual bool Open()=0
Internal open. Should not be used directly.
+
virtual int64_t Read(void *buffer, uint64_t length)=0
+
static std::string MakeCallbackFileName(const BufferCallbackParams &callback_params, const std::string &name)
Definition: file.cc:399
+
static int64_t CopyFile(File *source, File *destination)
Definition: file.cc:333
+
virtual int64_t Write(const void *buffer, uint64_t length)=0
+
static bool IsLocalRegularFile(const char *file_name)
Definition: file.cc:374
+
virtual ~File()
Definition: file.h:175
+
virtual bool Close()=0
+
static int64_t GetFileSize(const char *file_name)
Definition: file.cc:221
+
static bool ReadFileToString(const char *file_name, std::string *contents)
Definition: file.cc:230
+
static bool ParseCallbackFileName(const std::string &callback_file_name, const BufferCallbackParams **callback_params, std::string *name)
Definition: file.cc:409
+
virtual int64_t Size()=0
+
static bool Copy(const char *from_file_name, const char *to_file_name)
Definition: file.cc:297
+
Declaration of class which implements a thread-safe circular buffer.
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d2/d4f/structshaka_1_1Element-members.html b/docs/d2/d4f/structshaka_1_1Element-members.html index 74eac81c30..01a18ef24c 100644 --- a/docs/d2/d4f/structshaka_1_1Element-members.html +++ b/docs/d2/d4f/structshaka_1_1Element-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d51/classshaka_1_1MockMpdNotifier-members.html b/docs/d2/d51/classshaka_1_1MockMpdNotifier-members.html index 696a3e79a5..bf32087424 100644 --- a/docs/d2/d51/classshaka_1_1MockMpdNotifier-members.html +++ b/docs/d2/d51/classshaka_1_1MockMpdNotifier-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
dash_profile() constshaka::MpdNotifierinline Flush()=0shaka::MpdNotifierpure virtual - Init()=0shaka::MpdNotifierpure virtual - MOCK_METHOD0(Init, bool()) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier - MOCK_METHOD0(Flush, bool()) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier - MOCK_METHOD2(NotifyNewContainer, bool(const MediaInfo &media_info, uint32_t *container_id)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier - MOCK_METHOD2(NotifySampleDuration, bool(uint32_t container_id, uint32_t sample_duration)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier - MOCK_METHOD2(NotifyCueEvent, bool(uint32_t container_id, uint64_t timestamp)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier - MOCK_METHOD2(NotifyMediaInfoUpdate, bool(uint32_t container_id, const MediaInfo &media_info)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier - MOCK_METHOD4(NotifyNewSegment, bool(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier - MOCK_METHOD4(NotifyEncryptionUpdate, bool(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier - MockMpdNotifier(const MpdOptions &mpd_options) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifierexplicit - mpd_type() constshaka::MpdNotifierinline - MpdNotifier(const MpdOptions &mpd_options) (defined in shaka::MpdNotifier)shaka::MpdNotifierinlineexplicit - NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0shaka::MpdNotifierpure virtual - NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0shaka::MpdNotifierpure virtual - NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0shaka::MpdNotifierpure virtual - NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0shaka::MpdNotifierpure virtual - NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0shaka::MpdNotifierpure virtual - NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0shaka::MpdNotifierpure virtual - ~MockMpdNotifier() (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifiervirtual - ~MpdNotifier() (defined in shaka::MpdNotifier)shaka::MpdNotifierinlinevirtual + include_mspr_pro() constshaka::MpdNotifierinline + Init()=0shaka::MpdNotifierpure virtual + MOCK_METHOD0(Init, bool()) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier + MOCK_METHOD0(Flush, bool()) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier + MOCK_METHOD2(NotifyNewContainer, bool(const MediaInfo &media_info, uint32_t *container_id)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier + MOCK_METHOD2(NotifySampleDuration, bool(uint32_t container_id, uint32_t sample_duration)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier + MOCK_METHOD2(NotifyCueEvent, bool(uint32_t container_id, uint64_t timestamp)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier + MOCK_METHOD2(NotifyMediaInfoUpdate, bool(uint32_t container_id, const MediaInfo &media_info)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier + MOCK_METHOD4(NotifyNewSegment, bool(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier + MOCK_METHOD4(NotifyEncryptionUpdate, bool(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifier + MockMpdNotifier(const MpdOptions &mpd_options) (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifierexplicit + mpd_type() constshaka::MpdNotifierinline + MpdNotifier(const MpdOptions &mpd_options) (defined in shaka::MpdNotifier)shaka::MpdNotifierinlineexplicit + NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0shaka::MpdNotifierpure virtual + NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0shaka::MpdNotifierpure virtual + NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0shaka::MpdNotifierpure virtual + NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0shaka::MpdNotifierpure virtual + NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0shaka::MpdNotifierpure virtual + NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0shaka::MpdNotifierpure virtual + ~MockMpdNotifier() (defined in shaka::MockMpdNotifier)shaka::MockMpdNotifiervirtual + ~MpdNotifier() (defined in shaka::MpdNotifier)shaka::MpdNotifierinlinevirtual
diff --git a/docs/d2/d57/master__playlist_8h_source.html b/docs/d2/d57/master__playlist_8h_source.html index b8a330de65..5b98694a64 100644 --- a/docs/d2/d57/master__playlist_8h_source.html +++ b/docs/d2/d57/master__playlist_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/master_playlist.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
master_playlist.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_HLS_BASE_MASTER_PLAYLIST_H_
8 #define PACKAGER_HLS_BASE_MASTER_PLAYLIST_H_
9 
10 #include <list>
11 #include <string>
12 
13 namespace shaka {
14 namespace hls {
15 
16 class MediaPlaylist;
17 
21  public:
27  MasterPlaylist(const std::string& file_name,
28  const std::string& default_audio_language,
29  const std::string& default_text_language);
30  virtual ~MasterPlaylist();
31 
41  virtual bool WriteMasterPlaylist(const std::string& base_url,
42  const std::string& output_dir,
43  const std::list<MediaPlaylist*>& playlists);
44 
45  private:
46  MasterPlaylist(const MasterPlaylist&) = delete;
47  MasterPlaylist& operator=(const MasterPlaylist&) = delete;
48 
49  std::string written_playlist_;
50  const std::string file_name_;
51  const std::string default_audio_language_;
52  const std::string default_text_language_;
53 };
54 
55 } // namespace hls
56 } // namespace shaka
57 
58 #endif // PACKAGER_HLS_BASE_MASTER_PLAYLIST_H_
-
All the methods that are virtual are virtual for mocking.
-
virtual bool WriteMasterPlaylist(const std::string &base_url, const std::string &output_dir, const std::list< MediaPlaylist *> &playlists)
-
MasterPlaylist(const std::string &file_name, const std::string &default_audio_language, const std::string &default_text_language)
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_HLS_BASE_MASTER_PLAYLIST_H_
+
8 #define PACKAGER_HLS_BASE_MASTER_PLAYLIST_H_
+
9 
+
10 #include <list>
+
11 #include <string>
+
12 
+
13 namespace shaka {
+
14 namespace hls {
+
15 
+
16 class MediaPlaylist;
+
17 
+ +
21  public:
+
27  MasterPlaylist(const std::string& file_name,
+
28  const std::string& default_audio_language,
+
29  const std::string& default_text_language,
+
30  const bool is_independent_segments);
+
31  virtual ~MasterPlaylist();
+
32 
+
42  virtual bool WriteMasterPlaylist(const std::string& base_url,
+
43  const std::string& output_dir,
+
44  const std::list<MediaPlaylist*>& playlists);
+
45 
+
46  private:
+
47  MasterPlaylist(const MasterPlaylist&) = delete;
+
48  MasterPlaylist& operator=(const MasterPlaylist&) = delete;
+
49 
+
50  std::string written_playlist_;
+
51  const std::string file_name_;
+
52  const std::string default_audio_language_;
+
53  const std::string default_text_language_;
+
54  bool is_independent_segments_;
+
55 };
+
56 
+
57 } // namespace hls
+
58 } // namespace shaka
+
59 
+
60 #endif // PACKAGER_HLS_BASE_MASTER_PLAYLIST_H_
+ +
MasterPlaylist(const std::string &file_name, const std::string &default_audio_language, const std::string &default_text_language, const bool is_independent_segments)
+
virtual bool WriteMasterPlaylist(const std::string &base_url, const std::string &output_dir, const std::list< MediaPlaylist * > &playlists)
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d59/structshaka_1_1media_1_1H264SliceHeader.html b/docs/d2/d59/structshaka_1_1media_1_1H264SliceHeader.html index 09f66658f6..89e82638d6 100644 --- a/docs/d2/d59/structshaka_1_1media_1_1H264SliceHeader.html +++ b/docs/d2/d59/structshaka_1_1media_1_1H264SliceHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264SliceHeader Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */

Public Types

-enum  { kRefListSize = 32, -kRefListModSize = kRefListSize +enum  { kRefListSize = 32 +, kRefListModSize = kRefListSize }   enum  Type {
-  kPSlice = 0, -kBSlice = 1, -kISlice = 2, -kSPSlice = 3, -
+  kPSlice = 0 +, kBSlice = 1 +, kISlice = 2 +, kSPSlice = 3 +,
  kSISlice = 4
} @@ -232,7 +235,7 @@ int slice_beta_offset_div2

Detailed Description

-

Definition at line 146 of file h264_parser.h.

+

Definition at line 142 of file h264_parser.h.


The documentation for this struct was generated from the following files:
diff --git a/docs/d2/d5b/classshaka_1_1media_1_1KeySource-members.html b/docs/d2/d5b/classshaka_1_1media_1_1KeySource-members.html index 23efeda2c9..5aaffd2049 100644 --- a/docs/d2/d5b/classshaka_1_1media_1_1KeySource-members.html +++ b/docs/d2/d5b/classshaka_1_1media_1_1KeySource-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key)=0shaka::media::KeySourcepure virtual GetKey(const std::string &stream_label, EncryptionKey *key)=0shaka::media::KeySourcepure virtual GetKey(const std::vector< uint8_t > &key_id, EncryptionKey *key)=0shaka::media::KeySourcepure virtual - KeySource(int protection_systems_flags, FourCC protection_scheme) (defined in shaka::media::KeySource)shaka::media::KeySource - UpdateProtectionSystemInfo(EncryptionKeyMap *encryption_key_map)shaka::media::KeySourceprotected - ~KeySource() (defined in shaka::media::KeySource)shaka::media::KeySourcevirtual + KeySource() (defined in shaka::media::KeySource)shaka::media::KeySource + ~KeySource() (defined in shaka::media::KeySource)shaka::media::KeySourcevirtual
diff --git a/docs/d2/d5c/classshaka_1_1SimpleMpdNotifier-members.html b/docs/d2/d5c/classshaka_1_1SimpleMpdNotifier-members.html index 43f7c4a39e..75b0d2444e 100644 --- a/docs/d2/d5c/classshaka_1_1SimpleMpdNotifier-members.html +++ b/docs/d2/d5c/classshaka_1_1SimpleMpdNotifier-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
dash_profile() constshaka::MpdNotifierinline Flush() overrideshaka::SimpleMpdNotifiervirtual - Init() overrideshaka::SimpleMpdNotifiervirtual - mpd_type() constshaka::MpdNotifierinline - MpdNotifier(const MpdOptions &mpd_options) (defined in shaka::MpdNotifier)shaka::MpdNotifierinlineexplicit - NotifyCueEvent(uint32_t container_id, uint64_t timestamp) overrideshaka::SimpleMpdNotifiervirtual - NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh) overrideshaka::SimpleMpdNotifiervirtual - NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info) overrideshaka::SimpleMpdNotifiervirtual - NotifyNewContainer(const MediaInfo &media_info, uint32_t *id) overrideshaka::SimpleMpdNotifiervirtual - NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size) overrideshaka::SimpleMpdNotifiervirtual - NotifySampleDuration(uint32_t container_id, uint32_t sample_duration) overrideshaka::SimpleMpdNotifiervirtual - SimpleMpdNotifier(const MpdOptions &mpd_options) (defined in shaka::SimpleMpdNotifier)shaka::SimpleMpdNotifierexplicit - SimpleMpdNotifierTest (defined in shaka::SimpleMpdNotifier)shaka::SimpleMpdNotifierfriend - ~MpdNotifier() (defined in shaka::MpdNotifier)shaka::MpdNotifierinlinevirtual - ~SimpleMpdNotifier() override (defined in shaka::SimpleMpdNotifier)shaka::SimpleMpdNotifier + include_mspr_pro() constshaka::MpdNotifierinline + Init() overrideshaka::SimpleMpdNotifiervirtual + mpd_type() constshaka::MpdNotifierinline + MpdNotifier(const MpdOptions &mpd_options) (defined in shaka::MpdNotifier)shaka::MpdNotifierinlineexplicit + NotifyCueEvent(uint32_t container_id, uint64_t timestamp) overrideshaka::SimpleMpdNotifiervirtual + NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh) overrideshaka::SimpleMpdNotifiervirtual + NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info) overrideshaka::SimpleMpdNotifiervirtual + NotifyNewContainer(const MediaInfo &media_info, uint32_t *id) overrideshaka::SimpleMpdNotifiervirtual + NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size) overrideshaka::SimpleMpdNotifiervirtual + NotifySampleDuration(uint32_t container_id, uint32_t sample_duration) overrideshaka::SimpleMpdNotifiervirtual + SimpleMpdNotifier(const MpdOptions &mpd_options) (defined in shaka::SimpleMpdNotifier)shaka::SimpleMpdNotifierexplicit + SimpleMpdNotifierTest (defined in shaka::SimpleMpdNotifier)shaka::SimpleMpdNotifierfriend + ~MpdNotifier() (defined in shaka::MpdNotifier)shaka::MpdNotifierinlinevirtual + ~SimpleMpdNotifier() override (defined in shaka::SimpleMpdNotifier)shaka::SimpleMpdNotifier
diff --git a/docs/d2/d61/structshaka_1_1media_1_1H264ModificationOfPicNum-members.html b/docs/d2/d61/structshaka_1_1media_1_1H264ModificationOfPicNum-members.html index 4bd0bbe3bb..ee9891ff96 100644 --- a/docs/d2/d61/structshaka_1_1media_1_1H264ModificationOfPicNum-members.html +++ b/docs/d2/d61/structshaka_1_1media_1_1H264ModificationOfPicNum-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d2/d62/simple__mpd__notifier_8h_source.html b/docs/d2/d62/simple__mpd__notifier_8h_source.html index 0674dc08cb..a126195e0a 100644 --- a/docs/d2/d62/simple__mpd__notifier_8h_source.html +++ b/docs/d2/d62/simple__mpd__notifier_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/simple_mpd_notifier.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
simple_mpd_notifier.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
8 #define MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "packager/base/synchronization/lock.h"
16 #include "packager/mpd/base/mpd_notifier.h"
17 #include "packager/mpd/base/mpd_notifier_util.h"
18 
19 namespace shaka {
20 
21 class AdaptationSet;
22 class MpdBuilder;
23 class Representation;
24 
25 struct MpdOptions;
26 
30  public:
31  explicit SimpleMpdNotifier(const MpdOptions& mpd_options);
32  ~SimpleMpdNotifier() override;
33 
37  bool Init() override;
38  bool NotifyNewContainer(const MediaInfo& media_info, uint32_t* id) override;
39  bool NotifySampleDuration(uint32_t container_id,
40  uint32_t sample_duration) override;
41  bool NotifyNewSegment(uint32_t container_id,
42  uint64_t start_time,
43  uint64_t duration,
44  uint64_t size) override;
45  bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override;
46  bool NotifyEncryptionUpdate(uint32_t container_id,
47  const std::string& drm_uuid,
48  const std::vector<uint8_t>& new_key_id,
49  const std::vector<uint8_t>& new_pssh) override;
50  bool NotifyMediaInfoUpdate(uint32_t container_id,
51  const MediaInfo& media_info) override;
52  bool Flush() override;
54 
55  private:
56  SimpleMpdNotifier(const SimpleMpdNotifier&) = delete;
57  SimpleMpdNotifier& operator=(const SimpleMpdNotifier&) = delete;
58 
59  friend class SimpleMpdNotifierTest;
60 
61  // Testing only method. Returns a pointer to MpdBuilder.
62  MpdBuilder* MpdBuilderForTesting() const { return mpd_builder_.get(); }
63 
64  // Testing only method. Sets mpd_builder_.
65  void SetMpdBuilderForTesting(std::unique_ptr<MpdBuilder> mpd_builder) {
66  mpd_builder_ = std::move(mpd_builder);
67  }
68 
69  // MPD output path.
70  std::string output_path_;
71  std::unique_ptr<MpdBuilder> mpd_builder_;
72  bool content_protection_in_adaptation_set_ = true;
73  base::Lock lock_;
74 
75  uint32_t next_adaptation_set_id_ = 0;
76  // Maps Representation ID to Representation.
77  std::map<uint32_t, Representation*> representation_map_;
78  // Maps Representation ID to AdaptationSet. This is for updating the PSSH.
79  std::map<uint32_t, AdaptationSet*> representation_id_to_adaptation_set_;
80 };
81 
82 } // namespace shaka
83 
84 #endif // MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
-
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:37
-
All the methods that are virtual are virtual for mocking.
-
bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override
- - -
bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration) override
- -
bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh) override
-
bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info) override
-
bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size) override
-
Defines Mpd Options.
Definition: mpd_options.h:25
-
bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *id) override
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
+
8 #define MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
+
9 
+
10 #include <map>
+
11 #include <memory>
+
12 #include <string>
+
13 #include <vector>
+
14 
+
15 #include "packager/base/synchronization/lock.h"
+
16 #include "packager/mpd/base/mpd_notifier.h"
+
17 #include "packager/mpd/base/mpd_notifier_util.h"
+
18 
+
19 namespace shaka {
+
20 
+
21 class AdaptationSet;
+
22 class MpdBuilder;
+
23 class Representation;
+
24 
+
25 struct MpdOptions;
+
26 
+ +
30  public:
+
31  explicit SimpleMpdNotifier(const MpdOptions& mpd_options);
+
32  ~SimpleMpdNotifier() override;
+
33 
+
37  bool Init() override;
+
38  bool NotifyNewContainer(const MediaInfo& media_info, uint32_t* id) override;
+
39  bool NotifySampleDuration(uint32_t container_id,
+
40  uint32_t sample_duration) override;
+
41  bool NotifyNewSegment(uint32_t container_id,
+
42  uint64_t start_time,
+
43  uint64_t duration,
+
44  uint64_t size) override;
+
45  bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override;
+
46  bool NotifyEncryptionUpdate(uint32_t container_id,
+
47  const std::string& drm_uuid,
+
48  const std::vector<uint8_t>& new_key_id,
+
49  const std::vector<uint8_t>& new_pssh) override;
+
50  bool NotifyMediaInfoUpdate(uint32_t container_id,
+
51  const MediaInfo& media_info) override;
+
52  bool Flush() override;
+
54 
+
55  private:
+
56  SimpleMpdNotifier(const SimpleMpdNotifier&) = delete;
+
57  SimpleMpdNotifier& operator=(const SimpleMpdNotifier&) = delete;
+
58 
+
59  friend class SimpleMpdNotifierTest;
+
60 
+
61  // Testing only method. Returns a pointer to MpdBuilder.
+
62  MpdBuilder* MpdBuilderForTesting() const { return mpd_builder_.get(); }
+
63 
+
64  // Testing only method. Sets mpd_builder_.
+
65  void SetMpdBuilderForTesting(std::unique_ptr<MpdBuilder> mpd_builder) {
+
66  mpd_builder_ = std::move(mpd_builder);
+
67  }
+
68 
+
69  // MPD output path.
+
70  std::string output_path_;
+
71  std::unique_ptr<MpdBuilder> mpd_builder_;
+
72  bool content_protection_in_adaptation_set_ = true;
+
73  base::Lock lock_;
+
74 
+
75  uint32_t next_adaptation_set_id_ = 0;
+
76  // Maps Representation ID to Representation.
+
77  std::map<uint32_t, Representation*> representation_map_;
+
78  // Maps Representation ID to AdaptationSet. This is for updating the PSSH.
+
79  std::map<uint32_t, AdaptationSet*> representation_id_to_adaptation_set_;
+
80 };
+
81 
+
82 } // namespace shaka
+
83 
+
84 #endif // MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
+
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:36
+ + +
bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override
+
bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *id) override
+ +
bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info) override
+
bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size) override
+ +
bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration) override
+
bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh) override
+
All the methods that are virtual are virtual for mocking.
+
Defines Mpd Options.
Definition: mpd_options.h:25
diff --git a/docs/d2/d62/structshaka_1_1media_1_1mp4_1_1Movie-members.html b/docs/d2/d62/structshaka_1_1media_1_1mp4_1_1Movie-members.html index d029b11b71..5dbe32deff 100644 --- a/docs/d2/d62/structshaka_1_1media_1_1mp4_1_1Movie-members.html +++ b/docs/d2/d62/structshaka_1_1media_1_1mp4_1_1Movie-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d6a/classshaka_1_1media_1_1AesCryptor-members.html b/docs/d2/d6a/classshaka_1_1media_1_1AesCryptor-members.html index e22fa6d78f..f3d65a37d2 100644 --- a/docs/d2/d6a/classshaka_1_1media_1_1AesCryptor-members.html +++ b/docs/d2/d6a/classshaka_1_1media_1_1AesCryptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d2/d70/structshaka_1_1media_1_1mp4_1_1SchemeInfo.html b/docs/d2/d70/structshaka_1_1media_1_1mp4_1_1SchemeInfo.html index 74b54e8475..4a06ae370b 100644 --- a/docs/d2/d70/structshaka_1_1media_1_1mp4_1_1SchemeInfo.html +++ b/docs/d2/d70/structshaka_1_1media_1_1mp4_1_1SchemeInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SchemeInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 160 of file box_definitions.h.

+

Definition at line 161 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 484 of file box_definitions.cc.

+

Definition at line 496 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d2/d71/classshaka_1_1media_1_1CombinedMuxerListener-members.html b/docs/d2/d71/classshaka_1_1media_1_1CombinedMuxerListener-members.html index 0cd176fc17..46c5ea3d0f 100644 --- a/docs/d2/d71/classshaka_1_1media_1_1CombinedMuxerListener-members.html +++ b/docs/d2/d71/classshaka_1_1media_1_1CombinedMuxerListener-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
kContainerText enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener kContainerUnknown enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener kContainerWebM enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener - MuxerListener()=default (defined in shaka::media::MuxerListener)shaka::media::MuxerListenerprotected + LimitNumOfMuxerListners(size_t num)shaka::media::CombinedMuxerListenerinlineprotected + MuxerListener()=default (defined in shaka::media::MuxerListener)shaka::media::MuxerListenerprotected + MuxerListenerAt(size_t index)shaka::media::CombinedMuxerListenerinlineprotected OnCueEvent(int64_t timestamp, const std::string &cue_data) overrideshaka::media::CombinedMuxerListenervirtual OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) overrideshaka::media::CombinedMuxerListenervirtual OnEncryptionStart() overrideshaka::media::CombinedMuxerListenervirtual @@ -91,9 +96,7 @@ $(function() {
diff --git a/docs/d2/d76/structshaka_1_1media_1_1JobManager_1_1JobEntry.html b/docs/d2/d76/structshaka_1_1media_1_1JobManager_1_1JobEntry.html new file mode 100644 index 0000000000..eb1d3730a8 --- /dev/null +++ b/docs/d2/d76/structshaka_1_1media_1_1JobManager_1_1JobEntry.html @@ -0,0 +1,97 @@ + + + + + + + +Shaka Packager SDK: shaka::media::JobManager::JobEntry Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::JobManager::JobEntry Struct Reference
+
+
+ + + + + + +

+Public Attributes

+std::string name
 
+std::shared_ptr< OriginHandlerworker
 
+

Detailed Description

+
+

Definition at line 90 of file job_manager.h.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/docs/d2/d7b/simple__mpd__notifier_8cc_source.html b/docs/d2/d7b/simple__mpd__notifier_8cc_source.html index ebc4ddb8df..aed0a03206 100644 --- a/docs/d2/d7b/simple__mpd__notifier_8cc_source.html +++ b/docs/d2/d7b/simple__mpd__notifier_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/simple_mpd_notifier.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
simple_mpd_notifier.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/mpd/base/simple_mpd_notifier.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/base/stl_util.h"
11 #include "packager/mpd/base/adaptation_set.h"
12 #include "packager/mpd/base/mpd_builder.h"
13 #include "packager/mpd/base/mpd_notifier_util.h"
14 #include "packager/mpd/base/mpd_utils.h"
15 #include "packager/mpd/base/period.h"
16 #include "packager/mpd/base/representation.h"
17 
18 namespace shaka {
19 
20 SimpleMpdNotifier::SimpleMpdNotifier(const MpdOptions& mpd_options)
21  : MpdNotifier(mpd_options),
22  output_path_(mpd_options.mpd_params.mpd_output),
23  mpd_builder_(new MpdBuilder(mpd_options)),
24  content_protection_in_adaptation_set_(
25  mpd_options.mpd_params.generate_dash_if_iop_compliant_mpd) {
26  for (const std::string& base_url : mpd_options.mpd_params.base_urls)
27  mpd_builder_->AddBaseUrl(base_url);
28 }
29 
30 SimpleMpdNotifier::~SimpleMpdNotifier() {}
31 
33  return true;
34 }
35 
36 bool SimpleMpdNotifier::NotifyNewContainer(const MediaInfo& media_info,
37  uint32_t* container_id) {
38  DCHECK(container_id);
39 
40  ContentType content_type = GetContentType(media_info);
41  if (content_type == kContentTypeUnknown)
42  return false;
43 
44  MediaInfo adjusted_media_info(media_info);
45  MpdBuilder::MakePathsRelativeToMpd(output_path_, &adjusted_media_info);
46 
47  base::AutoLock auto_lock(lock_);
48  const double kPeriodStartTimeSeconds = 0.0;
49  Period* period = mpd_builder_->GetOrCreatePeriod(kPeriodStartTimeSeconds);
50  DCHECK(period);
51  AdaptationSet* adaptation_set = period->GetOrCreateAdaptationSet(
52  media_info, content_protection_in_adaptation_set_);
53  DCHECK(adaptation_set);
54  if (!adaptation_set->has_id())
55  adaptation_set->set_id(next_adaptation_set_id_++);
56  Representation* representation =
57  adaptation_set->AddRepresentation(adjusted_media_info);
58  if (!representation)
59  return false;
60 
61  *container_id = representation->id();
62  if (content_protection_in_adaptation_set_) {
63  // ContentProtection elements are already added to AdaptationSet above.
64  // Use RepresentationId to AdaptationSet map to update ContentProtection
65  // in AdaptationSet in NotifyEncryptionUpdate.
66  representation_id_to_adaptation_set_[representation->id()] = adaptation_set;
67  } else {
68  AddContentProtectionElements(media_info, representation);
69  }
70  representation_map_[representation->id()] = representation;
71  return true;
72 }
73 
74 bool SimpleMpdNotifier::NotifySampleDuration(uint32_t container_id,
75  uint32_t sample_duration) {
76  base::AutoLock auto_lock(lock_);
77  auto it = representation_map_.find(container_id);
78  if (it == representation_map_.end()) {
79  LOG(ERROR) << "Unexpected container_id: " << container_id;
80  return false;
81  }
82  it->second->SetSampleDuration(sample_duration);
83  return true;
84 }
85 
86 bool SimpleMpdNotifier::NotifyNewSegment(uint32_t container_id,
87  uint64_t start_time,
88  uint64_t duration,
89  uint64_t size) {
90  base::AutoLock auto_lock(lock_);
91  auto it = representation_map_.find(container_id);
92  if (it == representation_map_.end()) {
93  LOG(ERROR) << "Unexpected container_id: " << container_id;
94  return false;
95  }
96  it->second->AddNewSegment(start_time, duration, size);
97  return true;
98 }
99 
100 bool SimpleMpdNotifier::NotifyCueEvent(uint32_t container_id,
101  uint64_t timestamp) {
102  base::AutoLock auto_lock(lock_);
103  auto it = representation_map_.find(container_id);
104  if (it == representation_map_.end()) {
105  LOG(ERROR) << "Unexpected container_id: " << container_id;
106  return false;
107  }
108  Representation* original_representation = it->second;
109  AdaptationSet* original_adaptation_set =
110  representation_id_to_adaptation_set_[container_id];
111 
112  const MediaInfo& media_info = original_representation->GetMediaInfo();
113  const double period_start_time_seconds =
114  static_cast<double>(timestamp) / media_info.reference_time_scale();
115 
116  Period* period = mpd_builder_->GetOrCreatePeriod(period_start_time_seconds);
117  DCHECK(period);
118  AdaptationSet* adaptation_set = period->GetOrCreateAdaptationSet(
119  media_info, content_protection_in_adaptation_set_);
120  DCHECK(adaptation_set);
121  if (!adaptation_set->has_id()) {
122  adaptation_set->set_id(original_adaptation_set->id());
123  } else {
124  DCHECK_EQ(adaptation_set->id(), original_adaptation_set->id());
125  }
126 
127  Representation* representation =
128  adaptation_set->CopyRepresentation(*original_representation);
129  if (!representation)
130  return false;
131 
132  if (content_protection_in_adaptation_set_) {
133  // ContentProtection elements are already added to AdaptationSet above.
134  // Use RepresentationId to AdaptationSet map to update ContentProtection
135  // in AdaptationSet in NotifyEncryptionUpdate.
136  representation_id_to_adaptation_set_[representation->id()] = adaptation_set;
137  } else {
138  AddContentProtectionElements(media_info, representation);
139  }
140  representation_map_[representation->id()] = representation;
141  return true;
142 }
143 
145  uint32_t container_id,
146  const std::string& drm_uuid,
147  const std::vector<uint8_t>& new_key_id,
148  const std::vector<uint8_t>& new_pssh) {
149  base::AutoLock auto_lock(lock_);
150  auto it = representation_map_.find(container_id);
151  if (it == representation_map_.end()) {
152  LOG(ERROR) << "Unexpected container_id: " << container_id;
153  return false;
154  }
155 
156  if (content_protection_in_adaptation_set_) {
157  AdaptationSet* adaptation_set_for_representation =
158  representation_id_to_adaptation_set_[it->second->id()];
159  adaptation_set_for_representation->UpdateContentProtectionPssh(
160  drm_uuid, Uint8VectorToBase64(new_pssh));
161  } else {
162  it->second->UpdateContentProtectionPssh(drm_uuid,
163  Uint8VectorToBase64(new_pssh));
164  }
165  return true;
166 }
167 
168 bool SimpleMpdNotifier::NotifyMediaInfoUpdate(uint32_t container_id,
169  const MediaInfo& media_info) {
170  base::AutoLock auto_lock(lock_);
171  auto it = representation_map_.find(container_id);
172  if (it == representation_map_.end()) {
173  LOG(ERROR) << "Unexpected container_id: " << container_id;
174  return false;
175  }
176 
177  MediaInfo adjusted_media_info(media_info);
178  MpdBuilder::MakePathsRelativeToMpd(output_path_, &adjusted_media_info);
179 
180  it->second->set_media_info(adjusted_media_info);
181  return true;
182 }
183 
185  base::AutoLock auto_lock(lock_);
186  return WriteMpdToFile(output_path_, mpd_builder_.get());
187 }
188 
189 } // namespace shaka
-
virtual const MediaInfo & GetMediaInfo() const
- -
virtual AdaptationSet * GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)
Definition: period.cc:74
- -
virtual Representation * AddRepresentation(const MediaInfo &media_info)
-
uint32_t id() const
-
All the methods that are virtual are virtual for mocking.
-
virtual Representation * CopyRepresentation(const Representation &representation)
-
bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override
-
void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
Definition: mpd_utils.cc:436
-
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
- -
std::string Uint8VectorToBase64(const std::vector< uint8_t > &input)
Converts uint8 vector into base64 encoded string.
-
bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration) override
-
bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh) override
-
static void MakePathsRelativeToMpd(const std::string &mpd_path, MediaInfo *media_info)
Definition: mpd_builder.cc:420
-
bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info) override
- -
ContentType GetContentType(const MediaInfo &media_info)
-
bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size) override
-
bool WriteMpdToFile(const std::string &output_path, MpdBuilder *mpd_builder)
-
void set_id(uint32_t id)
-
bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *id) override
- +
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/mpd/base/simple_mpd_notifier.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/base/stl_util.h"
+
11 #include "packager/mpd/base/adaptation_set.h"
+
12 #include "packager/mpd/base/mpd_builder.h"
+
13 #include "packager/mpd/base/mpd_notifier_util.h"
+
14 #include "packager/mpd/base/mpd_utils.h"
+
15 #include "packager/mpd/base/period.h"
+
16 #include "packager/mpd/base/representation.h"
+
17 
+
18 namespace shaka {
+
19 
+
20 SimpleMpdNotifier::SimpleMpdNotifier(const MpdOptions& mpd_options)
+
21  : MpdNotifier(mpd_options),
+
22  output_path_(mpd_options.mpd_params.mpd_output),
+
23  mpd_builder_(new MpdBuilder(mpd_options)),
+
24  content_protection_in_adaptation_set_(
+
25  mpd_options.mpd_params.generate_dash_if_iop_compliant_mpd) {
+
26  for (const std::string& base_url : mpd_options.mpd_params.base_urls)
+
27  mpd_builder_->AddBaseUrl(base_url);
+
28 }
+
29 
+
30 SimpleMpdNotifier::~SimpleMpdNotifier() {}
+
31 
+
32 bool SimpleMpdNotifier::Init() {
+
33  return true;
+
34 }
+
35 
+
36 bool SimpleMpdNotifier::NotifyNewContainer(const MediaInfo& media_info,
+
37  uint32_t* container_id) {
+
38  DCHECK(container_id);
+
39 
+
40  ContentType content_type = GetContentType(media_info);
+
41  if (content_type == kContentTypeUnknown)
+
42  return false;
+
43 
+
44  MediaInfo adjusted_media_info(media_info);
+
45  MpdBuilder::MakePathsRelativeToMpd(output_path_, &adjusted_media_info);
+
46 
+
47  base::AutoLock auto_lock(lock_);
+
48  const double kPeriodStartTimeSeconds = 0.0;
+
49  Period* period = mpd_builder_->GetOrCreatePeriod(kPeriodStartTimeSeconds);
+
50  DCHECK(period);
+
51  AdaptationSet* adaptation_set = period->GetOrCreateAdaptationSet(
+
52  media_info, content_protection_in_adaptation_set_);
+
53  DCHECK(adaptation_set);
+
54  if (!adaptation_set->has_id())
+
55  adaptation_set->set_id(next_adaptation_set_id_++);
+
56  Representation* representation =
+
57  adaptation_set->AddRepresentation(adjusted_media_info);
+
58  if (!representation)
+
59  return false;
+
60 
+
61  *container_id = representation->id();
+
62  if (content_protection_in_adaptation_set_) {
+
63  // ContentProtection elements are already added to AdaptationSet above.
+
64  // Use RepresentationId to AdaptationSet map to update ContentProtection
+
65  // in AdaptationSet in NotifyEncryptionUpdate.
+
66  representation_id_to_adaptation_set_[representation->id()] = adaptation_set;
+
67  } else {
+
68  AddContentProtectionElements(media_info, representation);
+
69  }
+
70  representation_map_[representation->id()] = representation;
+
71  return true;
+
72 }
+
73 
+
74 bool SimpleMpdNotifier::NotifySampleDuration(uint32_t container_id,
+
75  uint32_t sample_duration) {
+
76  base::AutoLock auto_lock(lock_);
+
77  auto it = representation_map_.find(container_id);
+
78  if (it == representation_map_.end()) {
+
79  LOG(ERROR) << "Unexpected container_id: " << container_id;
+
80  return false;
+
81  }
+
82  it->second->SetSampleDuration(sample_duration);
+
83  return true;
+
84 }
+
85 
+
86 bool SimpleMpdNotifier::NotifyNewSegment(uint32_t container_id,
+
87  uint64_t start_time,
+
88  uint64_t duration,
+
89  uint64_t size) {
+
90  base::AutoLock auto_lock(lock_);
+
91  auto it = representation_map_.find(container_id);
+
92  if (it == representation_map_.end()) {
+
93  LOG(ERROR) << "Unexpected container_id: " << container_id;
+
94  return false;
+
95  }
+
96  it->second->AddNewSegment(start_time, duration, size);
+
97  return true;
+
98 }
+
99 
+
100 bool SimpleMpdNotifier::NotifyCueEvent(uint32_t container_id,
+
101  uint64_t timestamp) {
+
102  base::AutoLock auto_lock(lock_);
+
103  auto it = representation_map_.find(container_id);
+
104  if (it == representation_map_.end()) {
+
105  LOG(ERROR) << "Unexpected container_id: " << container_id;
+
106  return false;
+
107  }
+
108  Representation* original_representation = it->second;
+
109  AdaptationSet* original_adaptation_set =
+
110  representation_id_to_adaptation_set_[container_id];
+
111 
+
112  const MediaInfo& media_info = original_representation->GetMediaInfo();
+
113  const double period_start_time_seconds =
+
114  static_cast<double>(timestamp) / media_info.reference_time_scale();
+
115 
+
116  Period* period = mpd_builder_->GetOrCreatePeriod(period_start_time_seconds);
+
117  DCHECK(period);
+
118  AdaptationSet* adaptation_set = period->GetOrCreateAdaptationSet(
+
119  media_info, content_protection_in_adaptation_set_);
+
120  DCHECK(adaptation_set);
+
121  if (!adaptation_set->has_id()) {
+
122  adaptation_set->set_id(original_adaptation_set->id());
+
123  } else {
+
124  DCHECK_EQ(adaptation_set->id(), original_adaptation_set->id());
+
125  }
+
126 
+
127  Representation* representation =
+
128  adaptation_set->CopyRepresentation(*original_representation);
+
129  if (!representation)
+
130  return false;
+
131 
+
132  if (content_protection_in_adaptation_set_) {
+
133  // ContentProtection elements are already added to AdaptationSet above.
+
134  // Use RepresentationId to AdaptationSet map to update ContentProtection
+
135  // in AdaptationSet in NotifyEncryptionUpdate.
+
136  representation_id_to_adaptation_set_[representation->id()] = adaptation_set;
+
137  } else {
+
138  AddContentProtectionElements(media_info, representation);
+
139  }
+
140  representation_map_[representation->id()] = representation;
+
141  return true;
+
142 }
+
143 
+
144 bool SimpleMpdNotifier::NotifyEncryptionUpdate(
+
145  uint32_t container_id,
+
146  const std::string& drm_uuid,
+
147  const std::vector<uint8_t>& new_key_id,
+
148  const std::vector<uint8_t>& new_pssh) {
+
149  base::AutoLock auto_lock(lock_);
+
150  auto it = representation_map_.find(container_id);
+
151  if (it == representation_map_.end()) {
+
152  LOG(ERROR) << "Unexpected container_id: " << container_id;
+
153  return false;
+
154  }
+
155 
+
156  if (content_protection_in_adaptation_set_) {
+
157  AdaptationSet* adaptation_set_for_representation =
+
158  representation_id_to_adaptation_set_[it->second->id()];
+
159  adaptation_set_for_representation->UpdateContentProtectionPssh(
+
160  drm_uuid, Uint8VectorToBase64(new_pssh));
+
161  } else {
+
162  it->second->UpdateContentProtectionPssh(drm_uuid,
+
163  Uint8VectorToBase64(new_pssh));
+
164  }
+
165  return true;
+
166 }
+
167 
+
168 bool SimpleMpdNotifier::NotifyMediaInfoUpdate(uint32_t container_id,
+
169  const MediaInfo& media_info) {
+
170  base::AutoLock auto_lock(lock_);
+
171  auto it = representation_map_.find(container_id);
+
172  if (it == representation_map_.end()) {
+
173  LOG(ERROR) << "Unexpected container_id: " << container_id;
+
174  return false;
+
175  }
+
176 
+
177  MediaInfo adjusted_media_info(media_info);
+
178  MpdBuilder::MakePathsRelativeToMpd(output_path_, &adjusted_media_info);
+
179 
+
180  it->second->set_media_info(adjusted_media_info);
+
181  return true;
+
182 }
+
183 
+
184 bool SimpleMpdNotifier::Flush() {
+
185  base::AutoLock auto_lock(lock_);
+
186  return WriteMpdToFile(output_path_, mpd_builder_.get());
+
187 }
+
188 
+
189 } // namespace shaka
+ +
virtual Representation * AddRepresentation(const MediaInfo &media_info)
+
virtual Representation * CopyRepresentation(const Representation &representation)
+ +
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
+
void set_id(uint32_t id)
+ +
virtual AdaptationSet * GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)
Definition: period.cc:74
+ +
virtual const MediaInfo & GetMediaInfo() const
+
uint32_t id() const
+
All the methods that are virtual are virtual for mocking.
+
std::string Uint8VectorToBase64(const std::vector< uint8_t > &input)
Converts uint8 vector into base64 encoded string.
+
ContentType GetContentType(const MediaInfo &media_info)
+
bool WriteMpdToFile(const std::string &output_path, MpdBuilder *mpd_builder)
+
void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
Definition: mpd_utils.cc:473
diff --git a/docs/d2/d7b/structshaka_1_1StreamDescriptor.html b/docs/d2/d7b/structshaka_1_1StreamDescriptor.html index 7c064fbe33..821f3dc212 100644 --- a/docs/d2/d7b/structshaka_1_1StreamDescriptor.html +++ b/docs/d2/d7b/structshaka_1_1StreamDescriptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::StreamDescriptor Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
  std::string language   +int32_t cc_index = -1 +  std::string hls_name   std::string hls_group_id @@ -119,11 +124,19 @@ std::vector< std::string > dash_roles  Optional for DASH output. It defines Role elements of the stream.
  + +bool dash_only = false + Set to true to indicate that the stream is for dash only.
+  + +bool hls_only = false + Set to true to indicate that the stream is for hls only.

Detailed Description

Defines a single input/output stream.

-

Definition at line 73 of file packager.h.

+

Definition at line 76 of file packager.h.

Member Data Documentation

◆ bandwidth

@@ -138,7 +151,24 @@ std::vector< std::string > 

Optional user-specified content bit rate for the stream, in bits/sec. If specified, this value is propagated to the $Bandwidth$ template parameter for segment names. If not specified, its value may be estimated.

-

Definition at line 105 of file packager.h.

+

Definition at line 108 of file packager.h.

+ +
+ + +

◆ cc_index

+ +
+
+ + + + +
int32_t shaka::StreamDescriptor::cc_index = -1
+
+

Optional value for the index of the sub-stream to use. For some text formats, there are multiple "channels" in a single stream. This allows selecting only one channel.

+ +

Definition at line 115 of file packager.h.

@@ -155,7 +185,7 @@ std::vector< std::string > 

Specifies a custom DRM stream label, which can be a DRM label defined by the DRM system. Typically values include AUDIO, SD, HD, UHD1, UHD2. If not provided, the DRM stream label is derived from stream type (video, audio), resolutions etc.

-

Definition at line 97 of file packager.h.

+

Definition at line 100 of file packager.h.

@@ -172,7 +202,7 @@ std::vector< std::string > 

Optional for HLS output. It defines the CHARACTERISTICS attribute of the stream.

-

Definition at line 125 of file packager.h.

+

Definition at line 132 of file packager.h.

@@ -189,7 +219,7 @@ std::vector< std::string > 

Required for audio when outputting HLS. It defines the group ID for the output stream. This is used as the GROUP-ID attribute for EXT-X-MEDIA.

-

Definition at line 116 of file packager.h.

+

Definition at line 123 of file packager.h.

@@ -206,7 +236,7 @@ std::vector< std::string > 

Optional for HLS output. It defines the name of the I-Frames only playlist for the stream. For Video only. Usually ends with .m3u8.

-

Definition at line 122 of file packager.h.

+

Definition at line 129 of file packager.h.

@@ -223,7 +253,7 @@ std::vector< std::string > 

Required for audio when outputting HLS. It defines the name of the output stream, which is not necessarily the same as output. This is used as the NAME attribute for EXT-X-MEDIA.

-

Definition at line 113 of file packager.h.

+

Definition at line 120 of file packager.h.

@@ -240,7 +270,7 @@ std::vector< std::string > 

Required for HLS output. It defines the name of the playlist for the stream. Usually ends with .m3u8.

-

Definition at line 119 of file packager.h.

+

Definition at line 126 of file packager.h.

@@ -257,7 +287,7 @@ std::vector< std::string > 

Optional value which contains a user-specified language tag. If specified, this value overrides any language metadata in the input stream.

-

Definition at line 108 of file packager.h.

+

Definition at line 111 of file packager.h.

@@ -274,7 +304,7 @@ std::vector< std::string > 

Specifies output file path or init segment path (if segment template is specified). Can be empty for self initialization media segments.

-

Definition at line 83 of file packager.h.

+

Definition at line 86 of file packager.h.

@@ -291,7 +321,7 @@ std::vector< std::string > 

Optional value which specifies output container format, e.g. "mp4". If not specified, will detect from output / segment template name.

-

Definition at line 89 of file packager.h.

+

Definition at line 92 of file packager.h.

@@ -308,7 +338,7 @@ std::vector< std::string > 

If set to true, the stream will not be encrypted. This is useful, e.g. to encrypt only video streams.

-

Definition at line 92 of file packager.h.

+

Definition at line 95 of file packager.h.

@@ -325,7 +355,7 @@ std::vector< std::string > 

Stream selector, can be audio, video, text or a zero based stream index. Required.

-

Definition at line 79 of file packager.h.

+

Definition at line 82 of file packager.h.

@@ -342,7 +372,7 @@ std::vector< std::string > 

If set to a non-zero value, will generate a trick play / trick mode stream with frames sampled from the key frames in the original stream. trick_play_factor defines the sampling rate.

-

Definition at line 101 of file packager.h.

+

Definition at line 104 of file packager.h.

@@ -352,9 +382,7 @@ std::vector< std::string >  diff --git a/docs/d2/d7e/aac__audio__specific__config_8h_source.html b/docs/d2/d7e/aac__audio__specific__config_8h_source.html index b529b3d77b..e2e54f0db1 100644 --- a/docs/d2/d7e/aac__audio__specific__config_8h_source.html +++ b/docs/d2/d7e/aac__audio__specific__config_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/aac_audio_specific_config.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
aac_audio_specific_config.h
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_CODECS_AAC_AUDIO_SPECIFIC_CONFIG_H_
6 #define PACKAGER_MEDIA_CODECS_AAC_AUDIO_SPECIFIC_CONFIG_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <vector>
12 
13 namespace shaka {
14 namespace media {
15 
16 class BitReader;
17 
18 // Methods are virtual for mocking.
24  public:
25  // Audio Object Types specified in ISO 14496-3 (2005), Table 1.3
26  enum AudioObjectType {
27  AOT_NULL = 0,
28  AOT_AAC_MAIN = 1, // Main
29  AOT_AAC_LC = 2, // Low Complexity
30  AOT_AAC_SSR = 3, // Scalable Sample Rate
31  AOT_AAC_LTP = 4, // Long Term Prediction
32  AOT_SBR = 5, // Spectral Band Replication
33  AOT_AAC_SCALABLE = 6, // Scalable
34  AOT_TWINVQ = 7, // Twin Vector Quantizer
35  AOT_CELP = 8, // Code Excited Linear Prediction
36  AOT_HVXC = 9, // Harmonic Vector eXcitation Coding
37  AOT_TTSI = 12, // Text-To-Speech Interface
38  AOT_MAINSYNTH = 13, // Main Synthesis
39  AOT_WAVESYNTH = 14, // Wavetable Synthesis
40  AOT_MIDI = 15, // General MIDI
41  AOT_SAFX = 16, // Algorithmic Synthesis and Audio Effects
42  AOT_ER_AAC_LC = 17, // Error Resilient Low Complexity
43  AOT_ER_AAC_LTP = 19, // Error Resilient Long Term Prediction
44  AOT_ER_AAC_SCALABLE = 20, // Error Resilient Scalable
45  AOT_ER_TWINVQ = 21, // Error Resilient Twin Vector Quantizer
46  AOT_ER_BSAC = 22, // Error Resilient Bit-Sliced Arithmetic Coding
47  AOT_ER_AAC_LD = 23, // Error Resilient Low Delay
48  AOT_ER_CELP = 24, // Error Resilient Code Excited Linear
49  // Prediction
50  AOT_ER_HVXC = 25, // Error Resilient Harmonic Vector eXcitation
51  // Coding
52  AOT_ER_HILN = 26, // Error Resilient Harmonic and Individual Lines
53  // plus Noise
54  AOT_ER_PARAM = 27, // Error Resilient Parametric
55  AOT_SSC = 28, // SinuSoidal Coding
56  AOT_PS = 29, // Parametric Stereo
57  AOT_SURROUND = 30, // MPEG Surround
58  AOT_ESCAPE = 31, // Escape Value
59  AOT_L1 = 32, // Layer 1
60  AOT_L2 = 33, // Layer 2
61  AOT_L3 = 34, // Layer 3
62  AOT_DST = 35, // Direct Stream Transfer
63  AOT_ALS = 36, // Audio LosslesS
64  AOT_SLS = 37, // Scalable LosslesS
65  AOT_SLS_NON_CORE = 38, // Scalable LosslesS (non core)
66  AOT_ER_AAC_ELD = 39, // Error Resilient Enhanced Low Delay
67  AOT_SMR_SIMPLE = 40, // Symbolic Music Representation Simple
68  AOT_SMR_MAIN = 41, // Symbolic Music Representation Main
69  AOT_USAC_NOSBR = 42, // Unified Speech and Audio Coding (no SBR)
70  AOT_SAOC = 43, // Spatial Audio Object Coding
71  AOT_LD_SURROUND = 44, // Low Delay MPEG Surround
72  AOT_USAC = 45, // Unified Speech and Audio Coding
73  };
74 
76  virtual ~AACAudioSpecificConfig();
77 
84  virtual bool Parse(const std::vector<uint8_t>& data);
85 
92  virtual bool ConvertToADTS(const uint8_t* data,
93  size_t data_size,
94  std::vector<uint8_t>* audio_frame) const;
95 
98  AudioObjectType GetAudioObjectType() const;
99 
102  uint32_t GetSamplesPerSecond() const;
103 
106  uint8_t GetNumChannels() const;
107 
109  static const size_t kADTSHeaderSize = 7;
110 
112  bool sbr_present() const { return sbr_present_; }
114  void set_sbr_present(bool sbr_present) { sbr_present_ = sbr_present; }
115 
116  private:
117  bool ParseDecoderGASpecificConfig(BitReader* bit_reader);
118  bool SkipErrorSpecificConfig() const;
119  // Parse GASpecificConfig. Calls |ParseProgramConfigElement| if
120  // |channel_config_| == 0.
121  bool ParseGASpecificConfig(BitReader* bit_reader);
122  // Parse program_config_element(). |num_channels_| will be updated.
123  bool ParseProgramConfigElement(BitReader* bit_reader);
124 
125  // The following variables store the AAC specific configuration information
126  // that are used to generate the ADTS header.
127  AudioObjectType audio_object_type_ = AOT_NULL;
128  uint8_t frequency_index_ = 0;
129  uint8_t channel_config_ = 0;
130  // Is Spectral Band Replication (SBR) available?
131  bool sbr_present_ = false;
132  // Is Parametric Stereo available?
133  bool ps_present_ = false;
134 
135  // The following variables store audio configuration information.
136  // They are based on the AAC specific configuration but can be overridden
137  // by extensions in elementary stream descriptor.
138  uint32_t frequency_ = 0;
139  uint32_t extension_frequency_ = 0;
140  uint8_t num_channels_ = 0;
141 };
142 
143 } // namespace media
144 } // namespace shaka
145 
146 #endif // PACKAGER_MEDIA_CODECS_AAC_AUDIO_SPECIFIC_CONFIG_H_
-
A class to read bit streams.
Definition: bit_reader.h:17
- - -
void set_sbr_present(bool sbr_present)
Indicate whether SBR is present in the stream.
-
virtual bool Parse(const std::vector< uint8_t > &data)
-
All the methods that are virtual are virtual for mocking.
- -
static const size_t kADTSHeaderSize
Size in bytes of the ADTS header added by ConvertEsdsToADTS().
- -
virtual bool ConvertToADTS(const uint8_t *data, size_t data_size, std::vector< uint8_t > *audio_frame) const
+
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_CODECS_AAC_AUDIO_SPECIFIC_CONFIG_H_
+
6 #define PACKAGER_MEDIA_CODECS_AAC_AUDIO_SPECIFIC_CONFIG_H_
+
7 
+
8 #include <stddef.h>
+
9 #include <stdint.h>
+
10 
+
11 #include <vector>
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
16 class BitReader;
+
17 
+
18 // Methods are virtual for mocking.
+ +
24  public:
+
25  // Audio Object Types specified in ISO 14496-3 (2005), Table 1.3
+
26  enum AudioObjectType {
+
27  AOT_NULL = 0,
+
28  AOT_AAC_MAIN = 1, // Main
+
29  AOT_AAC_LC = 2, // Low Complexity
+
30  AOT_AAC_SSR = 3, // Scalable Sample Rate
+
31  AOT_AAC_LTP = 4, // Long Term Prediction
+
32  AOT_SBR = 5, // Spectral Band Replication
+
33  AOT_AAC_SCALABLE = 6, // Scalable
+
34  AOT_TWINVQ = 7, // Twin Vector Quantizer
+
35  AOT_CELP = 8, // Code Excited Linear Prediction
+
36  AOT_HVXC = 9, // Harmonic Vector eXcitation Coding
+
37  AOT_TTSI = 12, // Text-To-Speech Interface
+
38  AOT_MAINSYNTH = 13, // Main Synthesis
+
39  AOT_WAVESYNTH = 14, // Wavetable Synthesis
+
40  AOT_MIDI = 15, // General MIDI
+
41  AOT_SAFX = 16, // Algorithmic Synthesis and Audio Effects
+
42  AOT_ER_AAC_LC = 17, // Error Resilient Low Complexity
+
43  AOT_ER_AAC_LTP = 19, // Error Resilient Long Term Prediction
+
44  AOT_ER_AAC_SCALABLE = 20, // Error Resilient Scalable
+
45  AOT_ER_TWINVQ = 21, // Error Resilient Twin Vector Quantizer
+
46  AOT_ER_BSAC = 22, // Error Resilient Bit-Sliced Arithmetic Coding
+
47  AOT_ER_AAC_LD = 23, // Error Resilient Low Delay
+
48  AOT_ER_CELP = 24, // Error Resilient Code Excited Linear
+
49  // Prediction
+
50  AOT_ER_HVXC = 25, // Error Resilient Harmonic Vector eXcitation
+
51  // Coding
+
52  AOT_ER_HILN = 26, // Error Resilient Harmonic and Individual Lines
+
53  // plus Noise
+
54  AOT_ER_PARAM = 27, // Error Resilient Parametric
+
55  AOT_SSC = 28, // SinuSoidal Coding
+
56  AOT_PS = 29, // Parametric Stereo
+
57  AOT_SURROUND = 30, // MPEG Surround
+
58  AOT_ESCAPE = 31, // Escape Value
+
59  AOT_L1 = 32, // Layer 1
+
60  AOT_L2 = 33, // Layer 2
+
61  AOT_L3 = 34, // Layer 3
+
62  AOT_DST = 35, // Direct Stream Transfer
+
63  AOT_ALS = 36, // Audio LosslesS
+
64  AOT_SLS = 37, // Scalable LosslesS
+
65  AOT_SLS_NON_CORE = 38, // Scalable LosslesS (non core)
+
66  AOT_ER_AAC_ELD = 39, // Error Resilient Enhanced Low Delay
+
67  AOT_SMR_SIMPLE = 40, // Symbolic Music Representation Simple
+
68  AOT_SMR_MAIN = 41, // Symbolic Music Representation Main
+
69  AOT_USAC_NOSBR = 42, // Unified Speech and Audio Coding (no SBR)
+
70  AOT_SAOC = 43, // Spatial Audio Object Coding
+
71  AOT_LD_SURROUND = 44, // Low Delay MPEG Surround
+
72  AOT_USAC = 45, // Unified Speech and Audio Coding
+
73  };
+
74 
+ +
76  virtual ~AACAudioSpecificConfig();
+
77 
+
84  virtual bool Parse(const std::vector<uint8_t>& data);
+
85 
+
92  virtual bool ConvertToADTS(const uint8_t* data,
+
93  size_t data_size,
+
94  std::vector<uint8_t>* audio_frame) const;
+
95 
+
98  AudioObjectType GetAudioObjectType() const;
+
99 
+
102  uint32_t GetSamplesPerSecond() const;
+
103 
+
106  uint8_t GetNumChannels() const;
+
107 
+
109  static const size_t kADTSHeaderSize = 7;
+
110 
+
112  bool sbr_present() const { return sbr_present_; }
+
114  void set_sbr_present(bool sbr_present) { sbr_present_ = sbr_present; }
+
115 
+
116  private:
+
117  bool ParseDecoderGASpecificConfig(BitReader* bit_reader);
+
118  bool SkipErrorSpecificConfig() const;
+
119  // Parse GASpecificConfig. Calls |ParseProgramConfigElement| if
+
120  // |channel_config_| == 0.
+
121  bool ParseGASpecificConfig(BitReader* bit_reader);
+
122  // Parse program_config_element(). |num_channels_| will be updated.
+
123  bool ParseProgramConfigElement(BitReader* bit_reader);
+
124 
+
125  // The following variables store the AAC specific configuration information
+
126  // that are used to generate the ADTS header.
+
127  AudioObjectType audio_object_type_ = AOT_NULL;
+
128  uint8_t frequency_index_ = 0;
+
129  uint8_t channel_config_ = 0;
+
130  // Is Spectral Band Replication (SBR) available?
+
131  bool sbr_present_ = false;
+
132  // Is Parametric Stereo available?
+
133  bool ps_present_ = false;
+
134 
+
135  // The following variables store audio configuration information.
+
136  // They are based on the AAC specific configuration but can be overridden
+
137  // by extensions in elementary stream descriptor.
+
138  uint32_t frequency_ = 0;
+
139  uint32_t extension_frequency_ = 0;
+
140  uint8_t num_channels_ = 0;
+
141 };
+
142 
+
143 } // namespace media
+
144 } // namespace shaka
+
145 
+
146 #endif // PACKAGER_MEDIA_CODECS_AAC_AUDIO_SPECIFIC_CONFIG_H_
+ +
static const size_t kADTSHeaderSize
Size in bytes of the ADTS header added by ConvertEsdsToADTS().
+
virtual bool ConvertToADTS(const uint8_t *data, size_t data_size, std::vector< uint8_t > *audio_frame) const
+
virtual bool Parse(const std::vector< uint8_t > &data)
+ + +
void set_sbr_present(bool sbr_present)
Indicate whether SBR is present in the stream.
+ + +
A class to read bit streams.
Definition: bit_reader.h:17
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/d7f/structshaka_1_1media_1_1mp4_1_1CuePayloadBox.html b/docs/d2/d7f/structshaka_1_1media_1_1mp4_1_1CuePayloadBox.html index 7a16c8906c..e27a661f61 100644 --- a/docs/d2/d7f/structshaka_1_1media_1_1mp4_1_1CuePayloadBox.html +++ b/docs/d2/d7f/structshaka_1_1media_1_1mp4_1_1CuePayloadBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CuePayloadBox Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 828 of file box_definitions.h.

+

Definition at line 846 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2795 of file box_definitions.cc.

+

Definition at line 2899 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d2/d82/structshaka_1_1BufferCallbackParams-members.html b/docs/d2/d82/structshaka_1_1BufferCallbackParams-members.html index 0dba299712..31939ce3b4 100644 --- a/docs/d2/d82/structshaka_1_1BufferCallbackParams-members.html +++ b/docs/d2/d82/structshaka_1_1BufferCallbackParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d2/d8a/hls__notify__muxer__listener_8h_source.html b/docs/d2/d8a/hls__notify__muxer__listener_8h_source.html index 6a63acf1af..63b2724fc3 100644 --- a/docs/d2/d8a/hls__notify__muxer__listener_8h_source.html +++ b/docs/d2/d8a/hls__notify__muxer__listener_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/hls_notify_muxer_listener.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
hls_notify_muxer_listener.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_EVENT_HLS_NOTIFY_MUXER_LISTENER_H_
8 #define PACKAGER_MEDIA_EVENT_HLS_NOTIFY_MUXER_LISTENER_H_
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "packager/base/optional.h"
15 #include "packager/media/event/event_info.h"
16 #include "packager/media/event/muxer_listener.h"
17 #include "packager/mpd/base/media_info.pb.h"
18 
19 namespace shaka {
20 
21 namespace hls {
22 class HlsNotifier;
23 } // namespace hls
24 
25 namespace media {
26 
29  public:
43  HlsNotifyMuxerListener(const std::string& playlist_name,
44  bool iframes_only,
45  const std::string& ext_x_media_name,
46  const std::string& ext_x_media_group_id,
47  const std::vector<std::string>& characteristics,
48  hls::HlsNotifier* hls_notifier);
49  ~HlsNotifyMuxerListener() override;
50 
53  void OnEncryptionInfoReady(bool is_initial_encryption_info,
54  FourCC protection_scheme,
55  const std::vector<uint8_t>& key_id,
56  const std::vector<uint8_t>& iv,
57  const std::vector<ProtectionSystemSpecificInfo>&
58  key_system_info) override;
59  void OnEncryptionStart() override;
60  void OnMediaStart(const MuxerOptions& muxer_options,
61  const StreamInfo& stream_info,
62  uint32_t time_scale,
63  ContainerType container_type) override;
64  void OnSampleDurationReady(uint32_t sample_duration) override;
65  void OnMediaEnd(const MediaRanges& media_ranges,
66  float duration_seconds) override;
67  void OnNewSegment(const std::string& file_name,
68  int64_t start_time,
69  int64_t duration,
70  uint64_t segment_file_size) override;
71  void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size);
72  void OnCueEvent(int64_t timestamp, const std::string& cue_data) override;
74 
75  private:
77  HlsNotifyMuxerListener& operator=(const HlsNotifyMuxerListener&) = delete;
78 
79  bool NotifyNewStream();
80 
81  const std::string playlist_name_;
82  const bool iframes_only_;
83  const std::string ext_x_media_name_;
84  const std::string ext_x_media_group_id_;
85  const std::vector<std::string> characteristics_;
86  hls::HlsNotifier* const hls_notifier_;
87  base::Optional<uint32_t> stream_id_;
88 
89  bool must_notify_encryption_start_ = false;
90  // Cached encryption info before OnMediaStart() is called.
91  std::vector<uint8_t> next_key_id_;
92  std::vector<uint8_t> next_iv_;
93  std::vector<ProtectionSystemSpecificInfo> next_key_system_infos_;
94  FourCC protection_scheme_ = FOURCC_NULL;
95 
96  // MediaInfo passed to Notifier::OnNewStream(). Mainly for single segment
97  // playlists.
98  std::unique_ptr<MediaInfo> media_info_;
99  // Even information for delayed function calls (NotifyNewSegment and
100  // NotifyCueEvent) after NotifyNewStream is called in OnMediaEnd. Only needed
101  // for on-demand as the functions are called immediately in live mode.
102  std::vector<EventInfo> event_info_;
103 };
104 
105 } // namespace media
106 } // namespace shaka
107 #endif // PACKAGER_MEDIA_EVENT_HLS_NOTIFY_MUXER_LISTENER_H_
Abstract class holds stream information.
Definition: stream_info.h:62
-
MuxerListener that uses HlsNotifier.
-
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
- - - +
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_EVENT_HLS_NOTIFY_MUXER_LISTENER_H_
+
8 #define PACKAGER_MEDIA_EVENT_HLS_NOTIFY_MUXER_LISTENER_H_
+
9 
+
10 #include <memory>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/base/optional.h"
+
15 #include "packager/media/event/event_info.h"
+
16 #include "packager/media/event/muxer_listener.h"
+
17 #include "packager/mpd/base/media_info.pb.h"
+
18 
+
19 namespace shaka {
+
20 
+
21 namespace hls {
+
22 class HlsNotifier;
+
23 } // namespace hls
+
24 
+
25 namespace media {
+
26 
+ +
29  public:
+
43  HlsNotifyMuxerListener(const std::string& playlist_name,
+
44  bool iframes_only,
+
45  const std::string& ext_x_media_name,
+
46  const std::string& ext_x_media_group_id,
+
47  const std::vector<std::string>& characteristics,
+
48  hls::HlsNotifier* hls_notifier);
+
49  ~HlsNotifyMuxerListener() override;
+
50 
+
53  void OnEncryptionInfoReady(bool is_initial_encryption_info,
+
54  FourCC protection_scheme,
+
55  const std::vector<uint8_t>& key_id,
+
56  const std::vector<uint8_t>& iv,
+
57  const std::vector<ProtectionSystemSpecificInfo>&
+
58  key_system_info) override;
+
59  void OnEncryptionStart() override;
+
60  void OnMediaStart(const MuxerOptions& muxer_options,
+
61  const StreamInfo& stream_info,
+
62  uint32_t time_scale,
+
63  ContainerType container_type) override;
+
64  void OnSampleDurationReady(uint32_t sample_duration) override;
+
65  void OnMediaEnd(const MediaRanges& media_ranges,
+
66  float duration_seconds) override;
+
67  void OnNewSegment(const std::string& file_name,
+
68  int64_t start_time,
+
69  int64_t duration,
+
70  uint64_t segment_file_size) override;
+
71  void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size);
+
72  void OnCueEvent(int64_t timestamp, const std::string& cue_data) override;
+
74 
+
75  private:
+ +
77  HlsNotifyMuxerListener& operator=(const HlsNotifyMuxerListener&) = delete;
+
78 
+
79  bool NotifyNewStream();
+
80 
+
81  const std::string playlist_name_;
+
82  const bool iframes_only_;
+
83  const std::string ext_x_media_name_;
+
84  const std::string ext_x_media_group_id_;
+
85  const std::vector<std::string> characteristics_;
+
86  hls::HlsNotifier* const hls_notifier_;
+
87  base::Optional<uint32_t> stream_id_;
+
88 
+
89  bool must_notify_encryption_start_ = false;
+
90  // Cached encryption info before OnMediaStart() is called.
+
91  std::vector<uint8_t> next_key_id_;
+
92  std::vector<uint8_t> next_iv_;
+
93  std::vector<ProtectionSystemSpecificInfo> next_key_system_infos_;
+
94  FourCC protection_scheme_ = FOURCC_NULL;
+
95 
+
96  // MediaInfo passed to Notifier::OnNewStream(). Mainly for single segment
+
97  // playlists.
+
98  std::unique_ptr<MediaInfo> media_info_;
+
99  // Even information for delayed function calls (NotifyNewSegment and
+
100  // NotifyCueEvent) after NotifyNewStream is called in OnMediaEnd. Only needed
+
101  // for on-demand as the functions are called immediately in live mode.
+
102  std::vector<EventInfo> event_info_;
+
103 };
+
104 
+
105 } // namespace media
+
106 } // namespace shaka
+
107 #endif // PACKAGER_MEDIA_EVENT_HLS_NOTIFY_MUXER_LISTENER_H_
+ +
MuxerListener that uses HlsNotifier.
+ +
void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
+
void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
+
void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
+
void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
+
void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
+
void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
+
HlsNotifyMuxerListener(const std::string &playlist_name, bool iframes_only, const std::string &ext_x_media_name, const std::string &ext_x_media_group_id, const std::vector< std::string > &characteristics, hls::HlsNotifier *hls_notifier)
+
void OnSampleDurationReady(uint32_t sample_duration) override
+ +
Abstract class holds stream information.
Definition: stream_info.h:65
+
All the methods that are virtual are virtual for mocking.
+ +
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
diff --git a/docs/d2/d91/structshaka_1_1media_1_1mp4_1_1CuePayloadBox-members.html b/docs/d2/d91/structshaka_1_1media_1_1mp4_1_1CuePayloadBox-members.html index ee72fb4b38..e4df02fd0d 100644 --- a/docs/d2/d91/structshaka_1_1media_1_1mp4_1_1CuePayloadBox-members.html +++ b/docs/d2/d91/structshaka_1_1media_1_1mp4_1_1CuePayloadBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d92/box__reader_8h_source.html b/docs/d2/d92/box__reader_8h_source.html index ee874bf047..99f0072be3 100644 --- a/docs/d2/d92/box__reader_8h_source.html +++ b/docs/d2/d92/box__reader_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/box_reader.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
box_reader.h
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
6 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
7 
8 #include <map>
9 #include <memory>
10 #include <vector>
11 
12 #include "packager/base/compiler_specific.h"
13 #include "packager/base/logging.h"
14 #include "packager/media/base/buffer_reader.h"
15 #include "packager/media/base/fourccs.h"
16 #include "packager/media/base/rcheck.h"
17 
18 namespace shaka {
19 namespace media {
20 namespace mp4 {
21 
22 struct Box;
23 
25 class BoxReader : public BufferReader {
26  public:
27  ~BoxReader();
28 
39  static BoxReader* ReadBox(const uint8_t* buf,
40  const size_t buf_size,
41  bool* err);
42 
52  static bool StartBox(const uint8_t* buf,
53  const size_t buf_size,
54  FourCC* type,
55  uint64_t* box_size,
56  bool* err) WARN_UNUSED_RESULT;
57 
62  bool ScanChildren() WARN_UNUSED_RESULT;
63 
65  bool ChildExist(Box* child) WARN_UNUSED_RESULT;
66 
70  bool ReadChild(Box* child) WARN_UNUSED_RESULT;
71 
74  bool TryReadChild(Box* child) WARN_UNUSED_RESULT;
75 
78  template <typename T>
79  bool ReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
80 
83  template <typename T>
84  bool TryReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
85 
89  template <typename T>
90  bool ReadAllChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
91 
92  bool ReadFourCC(FourCC* fourcc) {
93  uint32_t val;
94  if (!Read4(&val))
95  return false;
96  *fourcc = static_cast<FourCC>(val);
97  return true;
98  }
99 
100  FourCC type() const { return type_; }
101 
102  private:
103  BoxReader(const uint8_t* buf, size_t size);
104 
105  // Must be called immediately after init. If the return is false, this
106  // indicates that the box header and its contents were not available in the
107  // stream or were nonsensical, and that the box must not be used further. In
108  // this case, if |*err| is false, the problem was simply a lack of data, and
109  // should only be an error condition if some higher-level component knows that
110  // no more data is coming (i.e. EOS or end of containing box). If |*err| is
111  // true, the error is unrecoverable and the stream should be aborted.
112  bool ReadHeader(bool* err);
113 
114  FourCC type_;
115 
116  typedef std::multimap<FourCC, std::unique_ptr<BoxReader>> ChildMap;
117 
118  // The set of child box FourCCs and their corresponding buffer readers. Only
119  // valid if scanned_ is true.
120  ChildMap children_;
121  bool scanned_;
122 
123  DISALLOW_COPY_AND_ASSIGN(BoxReader);
124 };
125 
126 // Template definitions.
127 template <typename T>
128 bool BoxReader::ReadChildren(std::vector<T>* children) {
129  RCHECK(TryReadChildren(children) && !children->empty());
130  return true;
131 }
132 
133 template <typename T>
134 bool BoxReader::TryReadChildren(std::vector<T>* children) {
135  DCHECK(scanned_);
136  DCHECK(children->empty());
137 
138  children->resize(1);
139  FourCC child_type = (*children)[0].BoxType();
140 
141  ChildMap::iterator start_itr = children_.lower_bound(child_type);
142  ChildMap::iterator end_itr = children_.upper_bound(child_type);
143  children->resize(std::distance(start_itr, end_itr));
144  typename std::vector<T>::iterator child_itr = children->begin();
145  for (ChildMap::iterator itr = start_itr; itr != end_itr; ++itr) {
146  RCHECK(child_itr->Parse(itr->second.get()));
147  ++child_itr;
148  }
149  children_.erase(start_itr, end_itr);
150 
151  DVLOG(2) << "Found " << children->size() << " " << FourCCToString(child_type)
152  << " boxes.";
153  return true;
154 }
155 
156 template <typename T>
157 bool BoxReader::ReadAllChildren(std::vector<T>* children) {
158  DCHECK(!scanned_);
159  scanned_ = true;
160 
161  while (pos() < size()) {
162  BoxReader child_reader(&data()[pos()], size() - pos());
163  bool err;
164  if (!child_reader.ReadHeader(&err))
165  return false;
166 
167  T child;
168  RCHECK(child.Parse(&child_reader));
169  children->push_back(child);
170  RCHECK(SkipBytes(child_reader.size()));
171  }
172 
173  return true;
174 }
175 
176 } // namespace mp4
177 } // namespace media
178 } // namespace shaka
179 
180 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
bool TryReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:134
-
bool ReadAllChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:157
-
All the methods that are virtual are virtual for mocking.
-
bool ScanChildren() WARN_UNUSED_RESULT
Definition: box_reader.cc:67
-
bool ReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:128
- -
bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
-
Class for reading MP4 boxes.
Definition: box_reader.h:25
-
bool ReadChild(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:90
- -
bool TryReadChild(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:106
-
static bool StartBox(const uint8_t *buf, const size_t buf_size, FourCC *type, uint64_t *box_size, bool *err) WARN_UNUSED_RESULT
Definition: box_reader.cc:54
-
bool ChildExist(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:102
-
static BoxReader * ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)
Definition: box_reader.cc:36
+
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
+
6 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
+
7 
+
8 #include <map>
+
9 #include <memory>
+
10 #include <vector>
+
11 
+
12 #include "packager/base/compiler_specific.h"
+
13 #include "packager/base/logging.h"
+
14 #include "packager/media/base/buffer_reader.h"
+
15 #include "packager/media/base/fourccs.h"
+
16 #include "packager/media/base/rcheck.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 namespace mp4 {
+
21 
+
22 struct Box;
+
23 
+
25 class BoxReader : public BufferReader {
+
26  public:
+
27  ~BoxReader();
+
28 
+
39  static BoxReader* ReadBox(const uint8_t* buf,
+
40  const size_t buf_size,
+
41  bool* err);
+
42 
+
52  static bool StartBox(const uint8_t* buf,
+
53  const size_t buf_size,
+
54  FourCC* type,
+
55  uint64_t* box_size,
+
56  bool* err) WARN_UNUSED_RESULT;
+
57 
+
62  bool ScanChildren() WARN_UNUSED_RESULT;
+
63 
+
65  bool ChildExist(Box* child) WARN_UNUSED_RESULT;
+
66 
+
70  bool ReadChild(Box* child) WARN_UNUSED_RESULT;
+
71 
+
74  bool TryReadChild(Box* child) WARN_UNUSED_RESULT;
+
75 
+
78  template <typename T>
+
79  bool ReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
+
80 
+
83  template <typename T>
+
84  bool TryReadChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
+
85 
+
89  template <typename T>
+
90  bool ReadAllChildren(std::vector<T>* children) WARN_UNUSED_RESULT;
+
91 
+
92  bool ReadFourCC(FourCC* fourcc) {
+
93  uint32_t val;
+
94  if (!Read4(&val))
+
95  return false;
+
96  *fourcc = static_cast<FourCC>(val);
+
97  return true;
+
98  }
+
99 
+
100  FourCC type() const { return type_; }
+
101 
+
102  private:
+
103  BoxReader(const uint8_t* buf, size_t size);
+
104 
+
105  // Must be called immediately after init. If the return is false, this
+
106  // indicates that the box header and its contents were not available in the
+
107  // stream or were nonsensical, and that the box must not be used further. In
+
108  // this case, if |*err| is false, the problem was simply a lack of data, and
+
109  // should only be an error condition if some higher-level component knows that
+
110  // no more data is coming (i.e. EOS or end of containing box). If |*err| is
+
111  // true, the error is unrecoverable and the stream should be aborted.
+
112  bool ReadHeader(bool* err);
+
113 
+
114  FourCC type_;
+
115 
+
116  typedef std::multimap<FourCC, std::unique_ptr<BoxReader>> ChildMap;
+
117 
+
118  // The set of child box FourCCs and their corresponding buffer readers. Only
+
119  // valid if scanned_ is true.
+
120  ChildMap children_;
+
121  bool scanned_;
+
122 
+
123  DISALLOW_COPY_AND_ASSIGN(BoxReader);
+
124 };
+
125 
+
126 // Template definitions.
+
127 template <typename T>
+
128 bool BoxReader::ReadChildren(std::vector<T>* children) {
+
129  RCHECK(TryReadChildren(children) && !children->empty());
+
130  return true;
+
131 }
+
132 
+
133 template <typename T>
+
134 bool BoxReader::TryReadChildren(std::vector<T>* children) {
+
135  DCHECK(scanned_);
+
136  DCHECK(children->empty());
+
137 
+
138  children->resize(1);
+
139  FourCC child_type = (*children)[0].BoxType();
+
140 
+
141  ChildMap::iterator start_itr = children_.lower_bound(child_type);
+
142  ChildMap::iterator end_itr = children_.upper_bound(child_type);
+
143  children->resize(std::distance(start_itr, end_itr));
+
144  typename std::vector<T>::iterator child_itr = children->begin();
+
145  for (ChildMap::iterator itr = start_itr; itr != end_itr; ++itr) {
+
146  RCHECK(child_itr->Parse(itr->second.get()));
+
147  ++child_itr;
+
148  }
+
149  children_.erase(start_itr, end_itr);
+
150 
+
151  DVLOG(2) << "Found " << children->size() << " " << FourCCToString(child_type)
+
152  << " boxes.";
+
153  return true;
+
154 }
+
155 
+
156 template <typename T>
+
157 bool BoxReader::ReadAllChildren(std::vector<T>* children) {
+
158  DCHECK(!scanned_);
+
159  scanned_ = true;
+
160 
+
161  while (pos() < size()) {
+
162  BoxReader child_reader(&data()[pos()], size() - pos());
+
163  bool err;
+
164  if (!child_reader.ReadHeader(&err))
+
165  return false;
+
166 
+
167  T child;
+
168  RCHECK(child.Parse(&child_reader));
+
169  children->push_back(child);
+
170  RCHECK(SkipBytes(child_reader.size()));
+
171  }
+
172 
+
173  return true;
+
174 }
+
175 
+
176 } // namespace mp4
+
177 } // namespace media
+
178 } // namespace shaka
+
179 
+
180 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_READER_H_
+ +
bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
+
Class for reading MP4 boxes.
Definition: box_reader.h:25
+
bool TryReadChild(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:106
+
bool TryReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:134
+
bool ReadChild(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:90
+
static bool StartBox(const uint8_t *buf, const size_t buf_size, FourCC *type, uint64_t *box_size, bool *err) WARN_UNUSED_RESULT
Definition: box_reader.cc:54
+
bool ReadAllChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:157
+
bool ChildExist(Box *child) WARN_UNUSED_RESULT
Definition: box_reader.cc:102
+
bool ScanChildren() WARN_UNUSED_RESULT
Definition: box_reader.cc:67
+
static BoxReader * ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)
Definition: box_reader.cc:36
+
bool ReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
Definition: box_reader.h:128
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d2/d93/classshaka_1_1media_1_1mp2t_1_1PesPacket.html b/docs/d2/d93/classshaka_1_1media_1_1mp2t_1_1PesPacket.html index 4a3da8ca5a..3c66bb4a56 100644 --- a/docs/d2/d93/classshaka_1_1media_1_1mp2t_1_1PesPacket.html +++ b/docs/d2/d93/classshaka_1_1media_1_1mp2t_1_1PesPacket.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::PesPacket Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/d9d/structshaka_1_1FileCloser-members.html b/docs/d2/d9d/structshaka_1_1FileCloser-members.html index 16041f5ab2..eeb8de697c 100644 --- a/docs/d2/d9d/structshaka_1_1FileCloser-members.html +++ b/docs/d2/d9d/structshaka_1_1FileCloser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/da0/classshaka_1_1media_1_1TrickPlayHandler-members.html b/docs/d2/da0/classshaka_1_1media_1_1TrickPlayHandler-members.html index d23151313f..a749c0134b 100644 --- a/docs/d2/da0/classshaka_1_1media_1_1TrickPlayHandler-members.html +++ b/docs/d2/da0/classshaka_1_1media_1_1TrickPlayHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
This is the complete list of members for shaka::media::TrickPlayHandler, including all inherited members.

- + @@ -94,9 +97,7 @@ $(function() {
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
diff --git a/docs/d2/da6/threaded__io__file_8h_source.html b/docs/d2/da6/threaded__io__file_8h_source.html index adc24e0dfb..2ac83b440a 100644 --- a/docs/d2/da6/threaded__io__file_8h_source.html +++ b/docs/d2/da6/threaded__io__file_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/threaded_io_file.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
threaded_io_file.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_FILE_THREADED_IO_FILE_H_
8 #define PACKAGER_FILE_THREADED_IO_FILE_H_
9 
10 #include <atomic>
11 #include <memory>
12 #include "packager/base/synchronization/waitable_event.h"
13 #include "packager/file/file.h"
14 #include "packager/file/file_closer.h"
15 #include "packager/file/io_cache.h"
16 
17 namespace shaka {
18 
20 class ThreadedIoFile : public File {
21  public:
22  enum Mode { kInputMode, kOutputMode };
23 
24  ThreadedIoFile(std::unique_ptr<File, FileCloser> internal_file,
25  Mode mode,
26  uint64_t io_cache_size,
27  uint64_t io_block_size);
28 
31  bool Close() override;
32  int64_t Read(void* buffer, uint64_t length) override;
33  int64_t Write(const void* buffer, uint64_t length) override;
34  int64_t Size() override;
35  bool Flush() override;
36  bool Seek(uint64_t position) override;
37  bool Tell(uint64_t* position) override;
39 
40  protected:
41  ~ThreadedIoFile() override;
42 
43  bool Open() override;
44 
45  private:
46  // Internal task handler implementation. Will dispatch to either
47  // |RunInInputMode| or |RunInOutputMode| depending on |mode_|.
48  void TaskHandler();
49  void RunInInputMode();
50  void RunInOutputMode();
51 
52  std::unique_ptr<File, FileCloser> internal_file_;
53  const Mode mode_;
54  IoCache cache_;
55  std::vector<uint8_t> io_buffer_;
56  uint64_t position_;
57  uint64_t size_;
58  std::atomic<bool> eof_;
59  bool flushing_;
60  base::WaitableEvent flush_complete_event_;
61  std::atomic<int32_t> internal_file_error_;
62  // Signalled when thread task exits.
63  base::WaitableEvent task_exit_event_;
64 
65  DISALLOW_COPY_AND_ASSIGN(ThreadedIoFile);
66 };
67 
68 } // namespace shaka
69 
70 #endif // PACKAGER_FILE_THREADED_IO_FILE_H
Declaration of class which implements a thread-safe circular buffer.
Definition: io_cache.h:19
-
int64_t Size() override
-
Define an abstract file interface.
Definition: file.h:26
-
int64_t Write(const void *buffer, uint64_t length) override
- -
Declaration of class which implements a thread-safe circular buffer.
-
All the methods that are virtual are virtual for mocking.
-
bool Open() override
Internal open. Should not be used directly.
-
bool Seek(uint64_t position) override
- -
bool Tell(uint64_t *position) override
-
int64_t Read(void *buffer, uint64_t length) override
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_FILE_THREADED_IO_FILE_H_
+
8 #define PACKAGER_FILE_THREADED_IO_FILE_H_
+
9 
+
10 #include <atomic>
+
11 #include <memory>
+
12 #include "packager/base/synchronization/waitable_event.h"
+
13 #include "packager/file/file.h"
+
14 #include "packager/file/file_closer.h"
+
15 #include "packager/file/io_cache.h"
+
16 
+
17 namespace shaka {
+
18 
+
20 class ThreadedIoFile : public File {
+
21  public:
+
22  enum Mode { kInputMode, kOutputMode };
+
23 
+
24  ThreadedIoFile(std::unique_ptr<File, FileCloser> internal_file,
+
25  Mode mode,
+
26  uint64_t io_cache_size,
+
27  uint64_t io_block_size);
+
28 
+
31  bool Close() override;
+
32  int64_t Read(void* buffer, uint64_t length) override;
+
33  int64_t Write(const void* buffer, uint64_t length) override;
+
34  int64_t Size() override;
+
35  bool Flush() override;
+
36  bool Seek(uint64_t position) override;
+
37  bool Tell(uint64_t* position) override;
+
39 
+
40  protected:
+
41  ~ThreadedIoFile() override;
+
42 
+
43  bool Open() override;
+
44 
+
45  private:
+
46  // Internal task handler implementation. Will dispatch to either
+
47  // |RunInInputMode| or |RunInOutputMode| depending on |mode_|.
+
48  void TaskHandler();
+
49  void RunInInputMode();
+
50  void RunInOutputMode();
+
51 
+
52  std::unique_ptr<File, FileCloser> internal_file_;
+
53  const Mode mode_;
+
54  IoCache cache_;
+
55  std::vector<uint8_t> io_buffer_;
+
56  uint64_t position_;
+
57  uint64_t size_;
+
58  std::atomic<bool> eof_;
+
59  bool flushing_;
+
60  base::WaitableEvent flush_complete_event_;
+
61  std::atomic<int32_t> internal_file_error_;
+
62  // Signalled when thread task exits.
+
63  base::WaitableEvent task_exit_event_;
+
64 
+
65  DISALLOW_COPY_AND_ASSIGN(ThreadedIoFile);
+
66 };
+
67 
+
68 } // namespace shaka
+
69 
+
70 #endif // PACKAGER_FILE_THREADED_IO_FILE_H
+
Define an abstract file interface.
Definition: file.h:27
+
Declaration of class which implements a thread-safe circular buffer.
Definition: io_cache.h:19
+
Declaration of class which implements a thread-safe circular buffer.
+ +
bool Open() override
Internal open. Should not be used directly.
+
bool Tell(uint64_t *position) override
+ +
bool Seek(uint64_t position) override
+
int64_t Write(const void *buffer, uint64_t length) override
+
int64_t Size() override
+
int64_t Read(void *buffer, uint64_t length) override
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/da8/mp4_2segmenter_8cc_source.html b/docs/d2/da8/mp4_2segmenter_8cc_source.html index 90bcd2f1c6..c4d6774723 100644 --- a/docs/d2/da8/mp4_2segmenter_8cc_source.html +++ b/docs/d2/da8/mp4_2segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/segmenter.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
segmenter.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp4/segmenter.h"
8 
9 #include <algorithm>
10 
11 #include "packager/base/logging.h"
12 #include "packager/media/base/buffer_writer.h"
13 #include "packager/media/base/id3_tag.h"
14 #include "packager/media/base/media_sample.h"
15 #include "packager/media/base/muxer_options.h"
16 #include "packager/media/base/muxer_util.h"
17 #include "packager/media/base/stream_info.h"
18 #include "packager/media/chunking/chunking_handler.h"
19 #include "packager/media/event/progress_listener.h"
20 #include "packager/media/formats/mp4/box_definitions.h"
21 #include "packager/media/formats/mp4/fragmenter.h"
22 #include "packager/media/formats/mp4/key_frame_info.h"
23 #include "packager/version/version.h"
24 
25 namespace shaka {
26 namespace media {
27 namespace mp4 {
28 
29 namespace {
30 
31 uint64_t Rescale(uint64_t time_in_old_scale,
32  uint32_t old_scale,
33  uint32_t new_scale) {
34  return static_cast<double>(time_in_old_scale) / old_scale * new_scale;
35 }
36 
37 } // namespace
38 
39 Segmenter::Segmenter(const MuxerOptions& options,
40  std::unique_ptr<FileType> ftyp,
41  std::unique_ptr<Movie> moov)
42  : options_(options),
43  ftyp_(std::move(ftyp)),
44  moov_(std::move(moov)),
45  moof_(new MovieFragment()),
46  fragment_buffer_(new BufferWriter()),
47  sidx_(new SegmentIndex()) {}
48 
49 Segmenter::~Segmenter() {}
50 
52  const std::vector<std::shared_ptr<const StreamInfo>>& streams,
53  MuxerListener* muxer_listener,
54  ProgressListener* progress_listener) {
55  DCHECK_LT(0u, streams.size());
56  muxer_listener_ = muxer_listener;
57  progress_listener_ = progress_listener;
58  moof_->header.sequence_number = 0;
59 
60  moof_->tracks.resize(streams.size());
61  fragmenters_.resize(streams.size());
62  stream_durations_.resize(streams.size());
63 
64  for (uint32_t i = 0; i < streams.size(); ++i) {
65  moof_->tracks[i].header.track_id = i + 1;
66  if (streams[i]->stream_type() == kStreamVideo) {
67  // Use the first video stream as the reference stream (which is 1-based).
68  if (sidx_->reference_id == 0)
69  sidx_->reference_id = i + 1;
70  }
71 
72  const EditList& edit_list = moov_->tracks[i].edit.list;
73  int64_t edit_list_offset = 0;
74  if (edit_list.edits.size() > 0) {
75  DCHECK_EQ(edit_list.edits.size(), 1u);
76  edit_list_offset = edit_list.edits.front().media_time;
77  }
78 
79  fragmenters_[i].reset(
80  new Fragmenter(streams[i], &moof_->tracks[i], edit_list_offset));
81  }
82 
83  // Choose the first stream if there is no VIDEO.
84  if (sidx_->reference_id == 0)
85  sidx_->reference_id = 1;
86  sidx_->timescale = streams[GetReferenceStreamId()]->time_scale();
87 
88  // Use media duration as progress target.
89  progress_target_ = streams[GetReferenceStreamId()]->duration();
90 
91  // Use the reference stream's time scale as movie time scale.
92  moov_->header.timescale = sidx_->timescale;
93  moof_->header.sequence_number = 1;
94 
95  // Fill in version information.
96  const std::string version = GetPackagerVersion();
97  if (!version.empty()) {
98  moov_->metadata.handler.handler_type = FOURCC_ID32;
99  moov_->metadata.id3v2.language.code = "eng";
100 
101  Id3Tag id3_tag;
102  id3_tag.AddPrivateFrame(GetPackagerProjectUrl(), version);
103  CHECK(id3_tag.WriteToVector(&moov_->metadata.id3v2.id3v2_data));
104  }
105  return DoInitialize();
106 }
107 
109  // Set movie duration. Note that the duration in mvhd, tkhd, mdhd should not
110  // be touched, i.e. kept at 0. The updated moov box will be written to output
111  // file for VOD and static live case only.
112  moov_->extends.header.fragment_duration = 0;
113  for (size_t i = 0; i < stream_durations_.size(); ++i) {
114  uint64_t duration =
115  Rescale(stream_durations_[i], moov_->tracks[i].media.header.timescale,
116  moov_->header.timescale);
117  if (duration > moov_->extends.header.fragment_duration)
118  moov_->extends.header.fragment_duration = duration;
119  }
120  return DoFinalize();
121 }
122 
123 Status Segmenter::AddSample(size_t stream_id, const MediaSample& sample) {
124  // Set default sample duration if it has not been set yet.
125  if (moov_->extends.tracks[stream_id].default_sample_duration == 0) {
126  moov_->extends.tracks[stream_id].default_sample_duration =
127  sample.duration();
128  }
129 
130  DCHECK_LT(stream_id, fragmenters_.size());
131  Fragmenter* fragmenter = fragmenters_[stream_id].get();
132  if (fragmenter->fragment_finalized()) {
133  return Status(error::FRAGMENT_FINALIZED,
134  "Current fragment is finalized already.");
135  }
136 
137  Status status = fragmenter->AddSample(sample);
138  if (!status.ok())
139  return status;
140 
141  if (sample_duration_ == 0)
142  sample_duration_ = sample.duration();
143  stream_durations_[stream_id] += sample.duration();
144  return Status::OK;
145 }
146 
148  const SegmentInfo& segment_info) {
149  if (segment_info.key_rotation_encryption_config) {
150  FinalizeFragmentForKeyRotation(
151  stream_id, segment_info.is_encrypted,
152  *segment_info.key_rotation_encryption_config);
153  }
154 
155  DCHECK_LT(stream_id, fragmenters_.size());
156  Fragmenter* fragmenter = fragmenters_[stream_id].get();
157  DCHECK(fragmenter);
158  Status status = fragmenter->FinalizeFragment();
159  if (!status.ok())
160  return status;
161 
162  // Check if all tracks are ready for fragmentation.
163  for (const std::unique_ptr<Fragmenter>& fragmenter : fragmenters_) {
164  if (!fragmenter->fragment_finalized())
165  return Status::OK;
166  }
167 
168  MediaData mdat;
169  // Data offset relative to 'moof': moof size + mdat header size.
170  // The code will also update box sizes for moof_ and its child boxes.
171  uint64_t data_offset = moof_->ComputeSize() + mdat.HeaderSize();
172  // 'traf' should follow 'mfhd' moof header box.
173  uint64_t next_traf_position = moof_->HeaderSize() + moof_->header.box_size();
174  for (size_t i = 0; i < moof_->tracks.size(); ++i) {
175  TrackFragment& traf = moof_->tracks[i];
176  if (traf.auxiliary_offset.offsets.size() > 0) {
177  DCHECK_EQ(traf.auxiliary_offset.offsets.size(), 1u);
178  DCHECK(!traf.sample_encryption.sample_encryption_entries.empty());
179 
180  next_traf_position += traf.box_size();
181  // SampleEncryption 'senc' box should be the last box in 'traf'.
182  // |auxiliary_offset| should point to the data of SampleEncryption.
183  traf.auxiliary_offset.offsets[0] =
184  next_traf_position - traf.sample_encryption.box_size() +
185  traf.sample_encryption.HeaderSize() +
186  sizeof(uint32_t); // for sample count field in 'senc'
187  }
188  traf.runs[0].data_offset = data_offset + mdat.data_size;
189  mdat.data_size += static_cast<uint32_t>(fragmenters_[i]->data()->Size());
190  }
191 
192  // Generate segment reference.
193  sidx_->references.resize(sidx_->references.size() + 1);
194  fragmenters_[GetReferenceStreamId()]->GenerateSegmentReference(
195  &sidx_->references[sidx_->references.size() - 1]);
196  sidx_->references[sidx_->references.size() - 1].referenced_size =
197  data_offset + mdat.data_size;
198 
199  const uint64_t moof_start_offset = fragment_buffer_->Size();
200 
201  // Write the fragment to buffer.
202  moof_->Write(fragment_buffer_.get());
203  mdat.WriteHeader(fragment_buffer_.get());
204 
205  bool first_key_frame = true;
206  for (const std::unique_ptr<Fragmenter>& fragmenter : fragmenters_) {
207  // https://goo.gl/xcFus6 6. Trick play requirements
208  // 6.10. If using fMP4, I-frame segments must include the 'moof' header
209  // associated with the I-frame. It also implies that only the first key
210  // frame can be included.
211  if (!fragmenter->key_frame_infos().empty() && first_key_frame) {
212  const KeyFrameInfo& key_frame_info =
213  fragmenter->key_frame_infos().front();
214  first_key_frame = false;
215  key_frame_infos_.push_back(
216  {key_frame_info.timestamp, moof_start_offset,
217  fragment_buffer_->Size() - moof_start_offset + key_frame_info.size});
218  }
219  fragment_buffer_->AppendBuffer(*fragmenter->data());
220  }
221 
222  // Increase sequence_number for next fragment.
223  ++moof_->header.sequence_number;
224 
225  for (std::unique_ptr<Fragmenter>& fragmenter : fragmenters_)
226  fragmenter->ClearFragmentFinalized();
227  if (!segment_info.is_subsegment) {
228  Status status = DoFinalizeSegment();
229  // Reset segment information to initial state.
230  sidx_->references.clear();
231  key_frame_infos_.clear();
232  return status;
233  }
234  return Status::OK;
235 }
236 
237 uint32_t Segmenter::GetReferenceTimeScale() const {
238  return moov_->header.timescale;
239 }
240 
241 double Segmenter::GetDuration() const {
242  uint64_t duration = moov_->extends.header.fragment_duration;
243  if (duration == 0) {
244  // Handling the case where this is not properly initialized.
245  return 0.0;
246  }
247  return static_cast<double>(duration) / moov_->header.timescale;
248 }
249 
250 void Segmenter::UpdateProgress(uint64_t progress) {
251  accumulated_progress_ += progress;
252 
253  if (!progress_listener_) return;
254  if (progress_target_ == 0) return;
255  // It might happen that accumulated progress exceeds progress_target due to
256  // computation errors, e.g. rounding error. Cap it so it never reports > 100%
257  // progress.
258  if (accumulated_progress_ >= progress_target_) {
259  progress_listener_->OnProgress(1.0);
260  } else {
261  progress_listener_->OnProgress(static_cast<double>(accumulated_progress_) /
262  progress_target_);
263  }
264 }
265 
266 void Segmenter::SetComplete() {
267  if (!progress_listener_) return;
268  progress_listener_->OnProgress(1.0);
269 }
270 
271 uint32_t Segmenter::GetReferenceStreamId() {
272  DCHECK(sidx_);
273  return sidx_->reference_id - 1;
274 }
275 
276 void Segmenter::FinalizeFragmentForKeyRotation(
277  size_t stream_id,
278  bool fragment_encrypted,
279  const EncryptionConfig& encryption_config) {
280  if (options_.mp4_params.include_pssh_in_stream) {
281  moof_->pssh.clear();
282  const auto& key_system_info = encryption_config.key_system_info;
283  for (const ProtectionSystemSpecificInfo& system : key_system_info) {
284  if (system.psshs.empty())
285  continue;
287  pssh.raw_box = system.psshs;
288  moof_->pssh.push_back(pssh);
289  }
290  } else {
291  LOG(WARNING)
292  << "Key rotation and no pssh in stream may not work well together.";
293  }
294 
295  // Skip the following steps if the current fragment is not going to be
296  // encrypted. 'pssh' box needs to be included in the fragment, which is
297  // performed above, regardless of whether the fragment is encrypted. This is
298  // necessary for two reasons: 1) Requesting keys before reaching encrypted
299  // content avoids playback delay due to license requests; 2) In Chrome, CDM
300  // must be initialized before starting the playback and CDM can only be
301  // initialized with a valid 'pssh'.
302  if (!fragment_encrypted)
303  return;
304 
305  DCHECK_LT(stream_id, moof_->tracks.size());
306  TrackFragment& traf = moof_->tracks[stream_id];
307  traf.sample_group_descriptions.resize(traf.sample_group_descriptions.size() +
308  1);
309  SampleGroupDescription& sample_group_description =
310  traf.sample_group_descriptions.back();
311  sample_group_description.grouping_type = FOURCC_seig;
312 
313  sample_group_description.cenc_sample_encryption_info_entries.resize(1);
314  CencSampleEncryptionInfoEntry& sample_group_entry =
315  sample_group_description.cenc_sample_encryption_info_entries.back();
316  sample_group_entry.is_protected = 1;
317  sample_group_entry.per_sample_iv_size = encryption_config.per_sample_iv_size;
318  sample_group_entry.constant_iv = encryption_config.constant_iv;
319  sample_group_entry.crypt_byte_block = encryption_config.crypt_byte_block;
320  sample_group_entry.skip_byte_block = encryption_config.skip_byte_block;
321  sample_group_entry.key_id = encryption_config.key_id;
322 }
323 
324 } // namespace mp4
325 } // namespace media
326 } // namespace shaka
-
uint32_t HeaderSize() const final
Definition: box.cc:75
- -
virtual bool WriteToVector(std::vector< uint8_t > *output)
Definition: id3_tag.cc:67
- -
STL namespace.
-
virtual void AddPrivateFrame(const std::string &owner, const std::string &data)
Definition: id3_tag.cc:49
-
All the methods that are virtual are virtual for mocking.
-
Status AddSample(const MediaSample &sample)
Definition: segmenter.cc:159
-
virtual Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration_timestamp, bool is_subsegment)=0
Finalize the (sub)segment.
Definition: segmenter.cc:195
- - -
uint32_t ComputeSize()
Definition: box.cc:50
-
This class listens to progress updates events.
- -
Status Initialize(const StreamInfo &info, ProgressListener *progress_listener, MuxerListener *muxer_listener)
Definition: segmenter.cc:78
-
Tracks key frame information.
-
uint32_t box_size()
Definition: box.h:55
-
virtual uint32_t HeaderSize() const
Definition: box.cc:55
- - -
Class to hold a media sample.
Definition: media_sample.h:22
- - - - -
void UpdateProgress(uint64_t progress)
Update segmentation progress using ProgressListener.
Definition: segmenter.cc:270
- -
void WriteHeader(BufferWriter *writer)
Definition: box.cc:38
- +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp4/segmenter.h"
+
8 
+
9 #include <algorithm>
+
10 
+
11 #include "packager/base/logging.h"
+
12 #include "packager/media/base/buffer_writer.h"
+
13 #include "packager/media/base/id3_tag.h"
+
14 #include "packager/media/base/media_sample.h"
+
15 #include "packager/media/base/muxer_options.h"
+
16 #include "packager/media/base/muxer_util.h"
+
17 #include "packager/media/base/stream_info.h"
+
18 #include "packager/media/chunking/chunking_handler.h"
+
19 #include "packager/media/event/progress_listener.h"
+
20 #include "packager/media/formats/mp4/box_definitions.h"
+
21 #include "packager/media/formats/mp4/fragmenter.h"
+
22 #include "packager/media/formats/mp4/key_frame_info.h"
+
23 #include "packager/version/version.h"
+
24 
+
25 namespace shaka {
+
26 namespace media {
+
27 namespace mp4 {
+
28 
+
29 namespace {
+
30 
+
31 uint64_t Rescale(uint64_t time_in_old_scale,
+
32  uint32_t old_scale,
+
33  uint32_t new_scale) {
+
34  return static_cast<double>(time_in_old_scale) / old_scale * new_scale;
+
35 }
+
36 
+
37 } // namespace
+
38 
+
39 Segmenter::Segmenter(const MuxerOptions& options,
+
40  std::unique_ptr<FileType> ftyp,
+
41  std::unique_ptr<Movie> moov)
+
42  : options_(options),
+
43  ftyp_(std::move(ftyp)),
+
44  moov_(std::move(moov)),
+
45  moof_(new MovieFragment()),
+
46  fragment_buffer_(new BufferWriter()),
+
47  sidx_(new SegmentIndex()) {}
+
48 
+
49 Segmenter::~Segmenter() {}
+
50 
+
51 Status Segmenter::Initialize(
+
52  const std::vector<std::shared_ptr<const StreamInfo>>& streams,
+
53  MuxerListener* muxer_listener,
+
54  ProgressListener* progress_listener) {
+
55  DCHECK_LT(0u, streams.size());
+
56  muxer_listener_ = muxer_listener;
+
57  progress_listener_ = progress_listener;
+
58  moof_->header.sequence_number = 0;
+
59 
+
60  moof_->tracks.resize(streams.size());
+
61  fragmenters_.resize(streams.size());
+
62  stream_durations_.resize(streams.size());
+
63 
+
64  for (uint32_t i = 0; i < streams.size(); ++i) {
+
65  moof_->tracks[i].header.track_id = i + 1;
+
66  if (streams[i]->stream_type() == kStreamVideo) {
+
67  // Use the first video stream as the reference stream (which is 1-based).
+
68  if (sidx_->reference_id == 0)
+
69  sidx_->reference_id = i + 1;
+
70  }
+
71 
+
72  const EditList& edit_list = moov_->tracks[i].edit.list;
+
73  int64_t edit_list_offset = 0;
+
74  if (edit_list.edits.size() > 0) {
+
75  DCHECK_EQ(edit_list.edits.size(), 1u);
+
76  edit_list_offset = edit_list.edits.front().media_time;
+
77  }
+
78 
+
79  fragmenters_[i].reset(
+
80  new Fragmenter(streams[i], &moof_->tracks[i], edit_list_offset));
+
81  }
+
82 
+
83  // Choose the first stream if there is no VIDEO.
+
84  if (sidx_->reference_id == 0)
+
85  sidx_->reference_id = 1;
+
86  sidx_->timescale = streams[GetReferenceStreamId()]->time_scale();
+
87 
+
88  // Use media duration as progress target.
+
89  progress_target_ = streams[GetReferenceStreamId()]->duration();
+
90 
+
91  // Use the reference stream's time scale as movie time scale.
+
92  moov_->header.timescale = sidx_->timescale;
+
93  moof_->header.sequence_number = 1;
+
94 
+
95  // Fill in version information.
+
96  const std::string version = GetPackagerVersion();
+
97  if (!version.empty()) {
+
98  moov_->metadata.handler.handler_type = FOURCC_ID32;
+
99  moov_->metadata.id3v2.language.code = "eng";
+
100 
+
101  Id3Tag id3_tag;
+
102  id3_tag.AddPrivateFrame(GetPackagerProjectUrl(), version);
+
103  CHECK(id3_tag.WriteToVector(&moov_->metadata.id3v2.id3v2_data));
+
104  }
+
105  return DoInitialize();
+
106 }
+
107 
+
108 Status Segmenter::Finalize() {
+
109  // Set movie duration. Note that the duration in mvhd, tkhd, mdhd should not
+
110  // be touched, i.e. kept at 0. The updated moov box will be written to output
+
111  // file for VOD and static live case only.
+
112  moov_->extends.header.fragment_duration = 0;
+
113  for (size_t i = 0; i < stream_durations_.size(); ++i) {
+
114  uint64_t duration =
+
115  Rescale(stream_durations_[i], moov_->tracks[i].media.header.timescale,
+
116  moov_->header.timescale);
+
117  if (duration > moov_->extends.header.fragment_duration)
+
118  moov_->extends.header.fragment_duration = duration;
+
119  }
+
120  return DoFinalize();
+
121 }
+
122 
+
123 Status Segmenter::AddSample(size_t stream_id, const MediaSample& sample) {
+
124  // Set default sample duration if it has not been set yet.
+
125  if (moov_->extends.tracks[stream_id].default_sample_duration == 0) {
+
126  moov_->extends.tracks[stream_id].default_sample_duration =
+
127  sample.duration();
+
128  }
+
129 
+
130  DCHECK_LT(stream_id, fragmenters_.size());
+
131  Fragmenter* fragmenter = fragmenters_[stream_id].get();
+
132  if (fragmenter->fragment_finalized()) {
+
133  return Status(error::FRAGMENT_FINALIZED,
+
134  "Current fragment is finalized already.");
+
135  }
+
136 
+
137  Status status = fragmenter->AddSample(sample);
+
138  if (!status.ok())
+
139  return status;
+
140 
+
141  if (sample_duration_ == 0)
+
142  sample_duration_ = sample.duration();
+
143  stream_durations_[stream_id] += sample.duration();
+
144  return Status::OK;
+
145 }
+
146 
+
147 Status Segmenter::FinalizeSegment(size_t stream_id,
+
148  const SegmentInfo& segment_info) {
+
149  if (segment_info.key_rotation_encryption_config) {
+
150  FinalizeFragmentForKeyRotation(
+
151  stream_id, segment_info.is_encrypted,
+
152  *segment_info.key_rotation_encryption_config);
+
153  }
+
154 
+
155  DCHECK_LT(stream_id, fragmenters_.size());
+
156  Fragmenter* fragmenter = fragmenters_[stream_id].get();
+
157  DCHECK(fragmenter);
+
158  Status status = fragmenter->FinalizeFragment();
+
159  if (!status.ok())
+
160  return status;
+
161 
+
162  // Check if all tracks are ready for fragmentation.
+
163  for (const std::unique_ptr<Fragmenter>& fragmenter : fragmenters_) {
+
164  if (!fragmenter->fragment_finalized())
+
165  return Status::OK;
+
166  }
+
167 
+
168  MediaData mdat;
+
169  // Data offset relative to 'moof': moof size + mdat header size.
+
170  // The code will also update box sizes for moof_ and its child boxes.
+
171  uint64_t data_offset = moof_->ComputeSize() + mdat.HeaderSize();
+
172  // 'traf' should follow 'mfhd' moof header box.
+
173  uint64_t next_traf_position = moof_->HeaderSize() + moof_->header.box_size();
+
174  for (size_t i = 0; i < moof_->tracks.size(); ++i) {
+
175  TrackFragment& traf = moof_->tracks[i];
+
176  if (traf.auxiliary_offset.offsets.size() > 0) {
+
177  DCHECK_EQ(traf.auxiliary_offset.offsets.size(), 1u);
+
178  DCHECK(!traf.sample_encryption.sample_encryption_entries.empty());
+
179 
+
180  next_traf_position += traf.box_size();
+
181  // SampleEncryption 'senc' box should be the last box in 'traf'.
+
182  // |auxiliary_offset| should point to the data of SampleEncryption.
+
183  traf.auxiliary_offset.offsets[0] =
+
184  next_traf_position - traf.sample_encryption.box_size() +
+
185  traf.sample_encryption.HeaderSize() +
+
186  sizeof(uint32_t); // for sample count field in 'senc'
+
187  }
+
188  traf.runs[0].data_offset = data_offset + mdat.data_size;
+
189  mdat.data_size += static_cast<uint32_t>(fragmenters_[i]->data()->Size());
+
190  }
+
191 
+
192  // Generate segment reference.
+
193  sidx_->references.resize(sidx_->references.size() + 1);
+
194  fragmenters_[GetReferenceStreamId()]->GenerateSegmentReference(
+
195  &sidx_->references[sidx_->references.size() - 1]);
+
196  sidx_->references[sidx_->references.size() - 1].referenced_size =
+
197  data_offset + mdat.data_size;
+
198 
+
199  const uint64_t moof_start_offset = fragment_buffer_->Size();
+
200 
+
201  // Write the fragment to buffer.
+
202  moof_->Write(fragment_buffer_.get());
+
203  mdat.WriteHeader(fragment_buffer_.get());
+
204 
+
205  bool first_key_frame = true;
+
206  for (const std::unique_ptr<Fragmenter>& fragmenter : fragmenters_) {
+
207  // https://goo.gl/xcFus6 6. Trick play requirements
+
208  // 6.10. If using fMP4, I-frame segments must include the 'moof' header
+
209  // associated with the I-frame. It also implies that only the first key
+
210  // frame can be included.
+
211  if (!fragmenter->key_frame_infos().empty() && first_key_frame) {
+
212  const KeyFrameInfo& key_frame_info =
+
213  fragmenter->key_frame_infos().front();
+
214  first_key_frame = false;
+
215  key_frame_infos_.push_back(
+
216  {key_frame_info.timestamp, moof_start_offset,
+
217  fragment_buffer_->Size() - moof_start_offset + key_frame_info.size});
+
218  }
+
219  fragment_buffer_->AppendBuffer(*fragmenter->data());
+
220  }
+
221 
+
222  // Increase sequence_number for next fragment.
+
223  ++moof_->header.sequence_number;
+
224 
+
225  for (std::unique_ptr<Fragmenter>& fragmenter : fragmenters_)
+
226  fragmenter->ClearFragmentFinalized();
+
227  if (!segment_info.is_subsegment) {
+
228  Status status = DoFinalizeSegment();
+
229  // Reset segment information to initial state.
+
230  sidx_->references.clear();
+
231  key_frame_infos_.clear();
+
232  return status;
+
233  }
+
234  return Status::OK;
+
235 }
+
236 
+
237 uint32_t Segmenter::GetReferenceTimeScale() const {
+
238  return moov_->header.timescale;
+
239 }
+
240 
+
241 double Segmenter::GetDuration() const {
+
242  uint64_t duration = moov_->extends.header.fragment_duration;
+
243  if (duration == 0) {
+
244  // Handling the case where this is not properly initialized.
+
245  return 0.0;
+
246  }
+
247  return static_cast<double>(duration) / moov_->header.timescale;
+
248 }
+
249 
+
250 void Segmenter::UpdateProgress(uint64_t progress) {
+
251  accumulated_progress_ += progress;
+
252 
+
253  if (!progress_listener_) return;
+
254  if (progress_target_ == 0) return;
+
255  // It might happen that accumulated progress exceeds progress_target due to
+
256  // computation errors, e.g. rounding error. Cap it so it never reports > 100%
+
257  // progress.
+
258  if (accumulated_progress_ >= progress_target_) {
+
259  progress_listener_->OnProgress(1.0);
+
260  } else {
+
261  progress_listener_->OnProgress(static_cast<double>(accumulated_progress_) /
+
262  progress_target_);
+
263  }
+
264 }
+
265 
+
266 void Segmenter::SetComplete() {
+
267  if (!progress_listener_) return;
+
268  progress_listener_->OnProgress(1.0);
+
269 }
+
270 
+
271 uint32_t Segmenter::GetReferenceStreamId() {
+
272  DCHECK(sidx_);
+
273  return sidx_->reference_id - 1;
+
274 }
+
275 
+
276 void Segmenter::FinalizeFragmentForKeyRotation(
+
277  size_t stream_id,
+
278  bool fragment_encrypted,
+
279  const EncryptionConfig& encryption_config) {
+
280  if (options_.mp4_params.include_pssh_in_stream) {
+
281  moof_->pssh.clear();
+
282  const auto& key_system_info = encryption_config.key_system_info;
+
283  for (const ProtectionSystemSpecificInfo& system : key_system_info) {
+
284  if (system.psshs.empty())
+
285  continue;
+
286  ProtectionSystemSpecificHeader pssh;
+
287  pssh.raw_box = system.psshs;
+
288  moof_->pssh.push_back(pssh);
+
289  }
+
290  } else {
+
291  LOG(WARNING)
+
292  << "Key rotation and no pssh in stream may not work well together.";
+
293  }
+
294 
+
295  // Skip the following steps if the current fragment is not going to be
+
296  // encrypted. 'pssh' box needs to be included in the fragment, which is
+
297  // performed above, regardless of whether the fragment is encrypted. This is
+
298  // necessary for two reasons: 1) Requesting keys before reaching encrypted
+
299  // content avoids playback delay due to license requests; 2) In Chrome, CDM
+
300  // must be initialized before starting the playback and CDM can only be
+
301  // initialized with a valid 'pssh'.
+
302  if (!fragment_encrypted)
+
303  return;
+
304 
+
305  DCHECK_LT(stream_id, moof_->tracks.size());
+
306  TrackFragment& traf = moof_->tracks[stream_id];
+
307  traf.sample_group_descriptions.resize(traf.sample_group_descriptions.size() +
+
308  1);
+
309  SampleGroupDescription& sample_group_description =
+
310  traf.sample_group_descriptions.back();
+
311  sample_group_description.grouping_type = FOURCC_seig;
+
312 
+
313  sample_group_description.cenc_sample_encryption_info_entries.resize(1);
+
314  CencSampleEncryptionInfoEntry& sample_group_entry =
+
315  sample_group_description.cenc_sample_encryption_info_entries.back();
+
316  sample_group_entry.is_protected = 1;
+
317  sample_group_entry.per_sample_iv_size = encryption_config.per_sample_iv_size;
+
318  sample_group_entry.constant_iv = encryption_config.constant_iv;
+
319  sample_group_entry.crypt_byte_block = encryption_config.crypt_byte_block;
+
320  sample_group_entry.skip_byte_block = encryption_config.skip_byte_block;
+
321  sample_group_entry.key_id = encryption_config.key_id;
+
322 }
+
323 
+
324 } // namespace mp4
+
325 } // namespace media
+
326 } // namespace shaka
+ + +
virtual void AddPrivateFrame(const std::string &owner, const std::string &data)
Definition: id3_tag.cc:49
+
virtual bool WriteToVector(std::vector< uint8_t > *output)
Definition: id3_tag.cc:67
+
Class to hold a media sample.
Definition: media_sample.h:22
+ +
This class listens to progress updates events.
+ +
Status AddSample(const MediaSample &sample)
Definition: fragmenter.cc:65
+
Status FinalizeFragment()
Finalize and optimize the fragment.
Definition: fragmenter.cc:159
+
All the methods that are virtual are virtual for mocking.
+ + + +
virtual uint32_t HeaderSize() const
Definition: box.cc:55
+
void WriteHeader(BufferWriter *writer)
Definition: box.cc:38
+
uint32_t ComputeSize()
Definition: box.cc:50
+
uint32_t box_size()
Definition: box.h:55
+ +
uint32_t HeaderSize() const final
Definition: box.cc:75
+
Tracks key frame information.
+ +
diff --git a/docs/d2/da9/classshaka_1_1media_1_1BufferWriter-members.html b/docs/d2/da9/classshaka_1_1media_1_1BufferWriter-members.html index eebee206f4..ceb815fe3c 100644 --- a/docs/d2/da9/classshaka_1_1media_1_1BufferWriter-members.html +++ b/docs/d2/da9/classshaka_1_1media_1_1BufferWriter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/dae/classshaka_1_1MockAdaptationSet-members.html b/docs/d2/dae/classshaka_1_1MockAdaptationSet-members.html index cc271fd45d..31e3f0f6e0 100644 --- a/docs/d2/dae/classshaka_1_1MockAdaptationSet-members.html +++ b/docs/d2/dae/classshaka_1_1MockAdaptationSet-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
AddRepresentation(const MediaInfo &media_info)shaka::AdaptationSetvirtual AddRole(Role role)shaka::AdaptationSetvirtual AddTrickPlayReference(const AdaptationSet *adaptation_set)shaka::AdaptationSetvirtual - CopyRepresentation(const Representation &representation)shaka::AdaptationSetvirtual - ForceSetSegmentAlignment(bool segment_alignment)shaka::AdaptationSetvirtual - GetRepresentations() const (defined in shaka::AdaptationSet)shaka::AdaptationSet - GetXml()shaka::AdaptationSet - has_id() constshaka::AdaptationSetinline - id() const (defined in shaka::AdaptationSet)shaka::AdaptationSetinline - IsVideo() constshaka::AdaptationSet - kRoleAlternate enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleCaption enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleCommentary enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleDub enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleMain enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleSubtitle enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleSupplementary enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleUnknown enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - MOCK_METHOD1(AddRepresentation, Representation *(const MediaInfo &media_info)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - MOCK_METHOD1(CopyRepresentation, Representation *(const Representation &representation)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - MOCK_METHOD1(AddContentProtectionElement, void(const ContentProtectionElement &element)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - MOCK_METHOD1(AddRole, void(AdaptationSet::Role role)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - MOCK_METHOD1(ForceSetSegmentAlignment, void(bool segment_alignment)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - MOCK_METHOD1(AddAdaptationSetSwitching, void(const AdaptationSet *adaptation_set)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - MOCK_METHOD1(AddTrickPlayReference, void(const AdaptationSet *adaptation_set)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - MOCK_METHOD2(UpdateContentProtectionPssh, void(const std::string &drm_uuid, const std::string &pssh)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - MockAdaptationSet() (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet - OnNewSegmentForRepresentation(uint32_t representation_id, uint64_t start_time, uint64_t duration)shaka::AdaptationSet - OnSetFrameRateForRepresentation(uint32_t representation_id, uint32_t frame_duration, uint32_t timescale)shaka::AdaptationSet - Role enum name (defined in shaka::AdaptationSet)shaka::AdaptationSet + codec() constshaka::AdaptationSetinline + CopyRepresentation(const Representation &representation)shaka::AdaptationSetvirtual + ForceSetSegmentAlignment(bool segment_alignment)shaka::AdaptationSetvirtual + GetRepresentations() const (defined in shaka::AdaptationSet)shaka::AdaptationSet + GetXml()shaka::AdaptationSet + has_id() constshaka::AdaptationSetinline + id() const (defined in shaka::AdaptationSet)shaka::AdaptationSetinline + IsVideo() constshaka::AdaptationSet + kRoleAlternate enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleCaption enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleCommentary enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleDub enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleMain enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleSubtitle enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleSupplementary enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleUnknown enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + MOCK_METHOD1(AddRepresentation, Representation *(const MediaInfo &media_info)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + MOCK_METHOD1(CopyRepresentation, Representation *(const Representation &representation)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + MOCK_METHOD1(AddContentProtectionElement, void(const ContentProtectionElement &element)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + MOCK_METHOD1(AddRole, void(AdaptationSet::Role role)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + MOCK_METHOD1(ForceSetSegmentAlignment, void(bool segment_alignment)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + MOCK_METHOD1(AddAdaptationSetSwitching, void(const AdaptationSet *adaptation_set)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + MOCK_METHOD1(AddTrickPlayReference, void(const AdaptationSet *adaptation_set)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + MOCK_METHOD2(UpdateContentProtectionPssh, void(const std::string &drm_uuid, const std::string &pssh)) (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + MockAdaptationSet() (defined in shaka::MockAdaptationSet)shaka::MockAdaptationSet + OnNewSegmentForRepresentation(uint32_t representation_id, uint64_t start_time, uint64_t duration)shaka::AdaptationSet + OnSetFrameRateForRepresentation(uint32_t representation_id, uint32_t frame_duration, uint32_t timescale)shaka::AdaptationSet + Role enum name (defined in shaka::AdaptationSet)shaka::AdaptationSet + set_codec(const std::string &codec)shaka::AdaptationSetinline set_id(uint32_t id)shaka::AdaptationSetinline UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)shaka::AdaptationSetvirtual ~AdaptationSet() (defined in shaka::AdaptationSet)shaka::AdaptationSetvirtual @@ -110,9 +115,7 @@ $(function() {
diff --git a/docs/d2/dae/webm__muxer_8cc_source.html b/docs/d2/dae/webm__muxer_8cc_source.html index 70c292cce5..e9be4841fe 100644 --- a/docs/d2/dae/webm__muxer_8cc_source.html +++ b/docs/d2/dae/webm__muxer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_muxer.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webm_muxer.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webm/webm_muxer.h"
8 
9 #include "packager/media/base/fourccs.h"
10 #include "packager/media/base/media_sample.h"
11 #include "packager/media/base/stream_info.h"
12 #include "packager/media/formats/webm/mkv_writer.h"
13 #include "packager/media/formats/webm/multi_segment_segmenter.h"
14 #include "packager/media/formats/webm/single_segment_segmenter.h"
15 #include "packager/media/formats/webm/two_pass_single_segment_segmenter.h"
16 
17 namespace shaka {
18 namespace media {
19 namespace webm {
20 
21 WebMMuxer::WebMMuxer(const MuxerOptions& options) : Muxer(options) {}
22 WebMMuxer::~WebMMuxer() {}
23 
24 Status WebMMuxer::InitializeMuxer() {
25  CHECK_EQ(streams().size(), 1U);
26 
27  if (streams()[0]->is_encrypted() &&
28  streams()[0]->encryption_config().protection_scheme != FOURCC_cenc) {
29  LOG(ERROR) << "WebM does not support protection scheme other than 'cenc'.";
30  return Status(error::INVALID_ARGUMENT,
31  "WebM does not support protection scheme other than 'cenc'.");
32  }
33 
34  if (!options().segment_template.empty()) {
35  segmenter_.reset(new MultiSegmentSegmenter(options()));
36  } else {
37  segmenter_.reset(new TwoPassSingleSegmentSegmenter(options()));
38  }
39 
40  Status initialized = segmenter_->Initialize(
41  *streams()[0], progress_listener(), muxer_listener());
42  if (!initialized.ok())
43  return initialized;
44 
45  FireOnMediaStartEvent();
46  return Status::OK;
47 }
48 
49 Status WebMMuxer::Finalize() {
50  DCHECK(segmenter_);
51  Status segmenter_finalized = segmenter_->Finalize();
52 
53  if (!segmenter_finalized.ok())
54  return segmenter_finalized;
55 
56  FireOnMediaEndEvent();
57  LOG(INFO) << "WEBM file '" << options().output_file_name << "' finalized.";
58  return Status::OK;
59 }
60 
61 Status WebMMuxer::AddSample(size_t stream_id, const MediaSample& sample) {
62  DCHECK(segmenter_);
63  DCHECK_EQ(stream_id, 0u);
64  if (sample.pts() < 0) {
65  LOG(ERROR) << "Seeing negative timestamp " << sample.pts();
66  return Status(error::MUXER_FAILURE, "Unsupported negative timestamp.");
67  }
68  return segmenter_->AddSample(sample);
69 }
70 
71 Status WebMMuxer::FinalizeSegment(size_t stream_id,
72  const SegmentInfo& segment_info) {
73  DCHECK(segmenter_);
74  DCHECK_EQ(stream_id, 0u);
75 
76  if (segment_info.key_rotation_encryption_config) {
77  NOTIMPLEMENTED() << "Key rotation is not implemented for WebM.";
78  return Status(error::UNIMPLEMENTED,
79  "Key rotation is not implemented for WebM");
80  }
81  return segmenter_->FinalizeSegment(segment_info.start_timestamp,
82  segment_info.duration,
83  segment_info.is_subsegment);
84 }
85 
86 void WebMMuxer::FireOnMediaStartEvent() {
87  if (!muxer_listener())
88  return;
89 
90  DCHECK(!streams().empty()) << "Media started without a stream.";
91 
92  const uint32_t timescale = streams().front()->time_scale();
93  muxer_listener()->OnMediaStart(options(), *streams().front(), timescale,
94  MuxerListener::kContainerWebM);
95 }
96 
97 void WebMMuxer::FireOnMediaEndEvent() {
98  if (!muxer_listener())
99  return;
100 
101  MuxerListener::MediaRanges media_range;
102 
103  uint64_t init_range_start = 0;
104  uint64_t init_range_end = 0;
105  const bool has_init_range =
106  segmenter_->GetInitRangeStartAndEnd(&init_range_start, &init_range_end);
107  if (has_init_range) {
108  Range r;
109  r.start = init_range_start;
110  r.end = init_range_end;
111  media_range.init_range = r;
112  }
113 
114  uint64_t index_range_start = 0;
115  uint64_t index_range_end = 0;
116  const bool has_index_range = segmenter_->GetIndexRangeStartAndEnd(
117  &index_range_start, &index_range_end);
118  if (has_index_range) {
119  Range r;
120  r.start = index_range_start;
121  r.end = index_range_end;
122  media_range.index_range = r;
123  }
124 
125  media_range.subsegment_ranges = segmenter_->GetSegmentRanges();
126 
127  const float duration_seconds = segmenter_->GetDurationInSeconds();
128  muxer_listener()->OnMediaEnd(media_range, duration_seconds);
129 }
130 
131 } // namespace webm
132 } // namespace media
133 } // namespace shaka
base::Optional< Range > init_range
Range of the initialization section of a segment.
- -
base::Optional< Range > index_range
Range of the index section of a segment.
- - -
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
- - -
virtual void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds)=0
-
Class to hold a media sample.
Definition: media_sample.h:22
- -
virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
- - - -
WebMMuxer(const MuxerOptions &options)
Create a WebMMuxer object from MuxerOptions.
Definition: webm_muxer.cc:21
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/webm/webm_muxer.h"
+
8 
+
9 #include "packager/media/base/fourccs.h"
+
10 #include "packager/media/base/media_sample.h"
+
11 #include "packager/media/base/stream_info.h"
+
12 #include "packager/media/formats/webm/mkv_writer.h"
+
13 #include "packager/media/formats/webm/multi_segment_segmenter.h"
+
14 #include "packager/media/formats/webm/single_segment_segmenter.h"
+
15 #include "packager/media/formats/webm/two_pass_single_segment_segmenter.h"
+
16 
+
17 namespace shaka {
+
18 namespace media {
+
19 namespace webm {
+
20 
+
21 WebMMuxer::WebMMuxer(const MuxerOptions& options) : Muxer(options) {}
+
22 WebMMuxer::~WebMMuxer() {}
+
23 
+
24 Status WebMMuxer::InitializeMuxer() {
+
25  CHECK_EQ(streams().size(), 1U);
+
26 
+
27  if (streams()[0]->is_encrypted() &&
+
28  streams()[0]->encryption_config().protection_scheme != FOURCC_cenc) {
+
29  LOG(ERROR) << "WebM does not support protection scheme other than 'cenc'.";
+
30  return Status(error::INVALID_ARGUMENT,
+
31  "WebM does not support protection scheme other than 'cenc'.");
+
32  }
+
33 
+
34  if (!options().segment_template.empty()) {
+
35  segmenter_.reset(new MultiSegmentSegmenter(options()));
+
36  } else {
+
37  segmenter_.reset(new TwoPassSingleSegmentSegmenter(options()));
+
38  }
+
39 
+
40  Status initialized = segmenter_->Initialize(
+
41  *streams()[0], progress_listener(), muxer_listener());
+
42  if (!initialized.ok())
+
43  return initialized;
+
44 
+
45  FireOnMediaStartEvent();
+
46  return Status::OK;
+
47 }
+
48 
+
49 Status WebMMuxer::Finalize() {
+
50  if (!segmenter_)
+
51  return Status::OK;
+
52  Status segmenter_finalized = segmenter_->Finalize();
+
53 
+
54  if (!segmenter_finalized.ok())
+
55  return segmenter_finalized;
+
56 
+
57  FireOnMediaEndEvent();
+
58  LOG(INFO) << "WEBM file '" << options().output_file_name << "' finalized.";
+
59  return Status::OK;
+
60 }
+
61 
+
62 Status WebMMuxer::AddMediaSample(size_t stream_id, const MediaSample& sample) {
+
63  DCHECK(segmenter_);
+
64  DCHECK_EQ(stream_id, 0u);
+
65  if (sample.pts() < 0) {
+
66  LOG(ERROR) << "Seeing negative timestamp " << sample.pts();
+
67  return Status(error::MUXER_FAILURE, "Unsupported negative timestamp.");
+
68  }
+
69  return segmenter_->AddSample(sample);
+
70 }
+
71 
+
72 Status WebMMuxer::FinalizeSegment(size_t stream_id,
+
73  const SegmentInfo& segment_info) {
+
74  DCHECK(segmenter_);
+
75  DCHECK_EQ(stream_id, 0u);
+
76 
+
77  if (segment_info.key_rotation_encryption_config) {
+
78  NOTIMPLEMENTED() << "Key rotation is not implemented for WebM.";
+
79  return Status(error::UNIMPLEMENTED,
+
80  "Key rotation is not implemented for WebM");
+
81  }
+
82  return segmenter_->FinalizeSegment(segment_info.start_timestamp,
+
83  segment_info.duration,
+
84  segment_info.is_subsegment);
+
85 }
+
86 
+
87 void WebMMuxer::FireOnMediaStartEvent() {
+
88  if (!muxer_listener())
+
89  return;
+
90 
+
91  DCHECK(!streams().empty()) << "Media started without a stream.";
+
92 
+
93  const uint32_t timescale = streams().front()->time_scale();
+
94  muxer_listener()->OnMediaStart(options(), *streams().front(), timescale,
+
95  MuxerListener::kContainerWebM);
+
96 }
+
97 
+
98 void WebMMuxer::FireOnMediaEndEvent() {
+
99  if (!muxer_listener())
+
100  return;
+
101 
+
102  MuxerListener::MediaRanges media_range;
+
103 
+
104  uint64_t init_range_start = 0;
+
105  uint64_t init_range_end = 0;
+
106  const bool has_init_range =
+
107  segmenter_->GetInitRangeStartAndEnd(&init_range_start, &init_range_end);
+
108  if (has_init_range) {
+
109  Range r;
+
110  r.start = init_range_start;
+
111  r.end = init_range_end;
+
112  media_range.init_range = r;
+
113  }
+
114 
+
115  uint64_t index_range_start = 0;
+
116  uint64_t index_range_end = 0;
+
117  const bool has_index_range = segmenter_->GetIndexRangeStartAndEnd(
+
118  &index_range_start, &index_range_end);
+
119  if (has_index_range) {
+
120  Range r;
+
121  r.start = index_range_start;
+
122  r.end = index_range_end;
+
123  media_range.index_range = r;
+
124  }
+
125 
+
126  media_range.subsegment_ranges = segmenter_->GetSegmentRanges();
+
127 
+
128  const float duration_seconds = segmenter_->GetDurationInSeconds();
+
129  muxer_listener()->OnMediaEnd(media_range, duration_seconds);
+
130 }
+
131 
+
132 } // namespace webm
+
133 } // namespace media
+
134 } // namespace shaka
+ +
virtual void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds)=0
+
virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
+ +
WebMMuxer(const MuxerOptions &options)
Create a WebMMuxer object from MuxerOptions.
Definition: webm_muxer.cc:21
+
All the methods that are virtual are virtual for mocking.
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+
diff --git a/docs/d2/db1/master__playlist_8cc_source.html b/docs/d2/db1/master__playlist_8cc_source.html index d969579c60..d1657c3eb8 100644 --- a/docs/d2/db1/master__playlist_8cc_source.html +++ b/docs/d2/db1/master__playlist_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/master_playlist.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
master_playlist.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/hls/base/master_playlist.h"
8 
9 #include <algorithm> // std::max
10 
11 #include <inttypes.h>
12 
13 #include "packager/base/files/file_path.h"
14 #include "packager/base/strings/string_number_conversions.h"
15 #include "packager/base/strings/string_util.h"
16 #include "packager/base/strings/stringprintf.h"
17 #include "packager/file/file.h"
18 #include "packager/hls/base/media_playlist.h"
19 #include "packager/hls/base/tag.h"
20 #include "packager/version/version.h"
21 
22 namespace shaka {
23 namespace hls {
24 namespace {
25 const char* kDefaultAudioGroupId = "default-audio-group";
26 const char* kDefaultSubtitleGroupId = "default-text-group";
27 const char* kUnexpectedGroupId = "unexpected-group";
28 
29 void AppendVersionString(std::string* content) {
30  const std::string version = GetPackagerVersion();
31  if (version.empty())
32  return;
33  base::StringAppendF(content, "## Generated with %s version %s\n",
34  GetPackagerProjectUrl().c_str(), version.c_str());
35 }
36 
37 // This structure roughly maps to the Variant stream in HLS specification.
38 // Each variant specifies zero or one audio group and zero or one text group.
39 struct Variant {
40  std::set<std::string> audio_codecs;
41  std::set<std::string> text_codecs;
42  const std::string* audio_group_id = nullptr;
43  const std::string* text_group_id = nullptr;
44  // The bitrates should be the sum of audio bitrate and text bitrate.
45  // However, given the contraints and assumptions, it makes sense to exclude
46  // text bitrate out of the calculation:
47  // - Text streams usually have a very small negligible bitrate.
48  // - Text does not have constant bitrates. To avoid fluctuation, an arbitrary
49  // value is assigned to the text bitrates in the parser. It does not make
50  // sense to take that text bitrate into account here.
51  uint64_t max_audio_bitrate = 0;
52  uint64_t avg_audio_bitrate = 0;
53 };
54 
55 uint64_t GetMaximumMaxBitrate(const std::list<const MediaPlaylist*> playlists) {
56  uint64_t max = 0;
57  for (const auto& playlist : playlists) {
58  max = std::max(max, playlist->MaxBitrate());
59  }
60  return max;
61 }
62 
63 uint64_t GetMaximumAvgBitrate(const std::list<const MediaPlaylist*> playlists) {
64  uint64_t max = 0;
65  for (const auto& playlist : playlists) {
66  max = std::max(max, playlist->AvgBitrate());
67  }
68  return max;
69 }
70 
71 std::set<std::string> GetGroupCodecString(
72  const std::list<const MediaPlaylist*>& group) {
73  std::set<std::string> codecs;
74 
75  for (const MediaPlaylist* playlist : group) {
76  codecs.insert(playlist->codec());
77  }
78 
79  // To support some older players, we cannot include "wvtt" in the codec
80  // string. As per HLS guidelines, "wvtt" is optional. When it is included, it
81  // can cause playback errors on some Apple produces. Excluding it allows
82  // playback on all Apple products. See
83  // https://github.com/google/shaka-packager/issues/402 for all details.
84  auto wvtt = codecs.find("wvtt");
85  if (wvtt != codecs.end()) {
86  codecs.erase(wvtt);
87  }
88 
89  return codecs;
90 }
91 
92 std::list<Variant> AudioGroupsToVariants(
93  const std::map<std::string, std::list<const MediaPlaylist*>>& groups) {
94  std::list<Variant> variants;
95 
96  for (const auto& group : groups) {
97  Variant variant;
98  variant.audio_group_id = &group.first;
99  variant.max_audio_bitrate = GetMaximumMaxBitrate(group.second);
100  variant.avg_audio_bitrate = GetMaximumAvgBitrate(group.second);
101  variant.audio_codecs = GetGroupCodecString(group.second);
102 
103  variants.push_back(variant);
104  }
105 
106  // Make sure we return at least one variant so create a null variant if there
107  // are no variants.
108  if (variants.empty()) {
109  variants.emplace_back();
110  }
111 
112  return variants;
113 }
114 
115 const char* GetGroupId(const MediaPlaylist& playlist) {
116  const std::string& group_id = playlist.group_id();
117 
118  if (!group_id.empty()) {
119  return group_id.c_str();
120  }
121 
122  switch (playlist.stream_type()) {
123  case MediaPlaylist::MediaPlaylistStreamType::kAudio:
124  return kDefaultAudioGroupId;
125 
126  case MediaPlaylist::MediaPlaylistStreamType::kSubtitle:
127  return kDefaultSubtitleGroupId;
128 
129  default:
130  return kUnexpectedGroupId;
131  }
132 }
133 
134 std::list<Variant> SubtitleGroupsToVariants(
135  const std::map<std::string, std::list<const MediaPlaylist*>>& groups) {
136  std::list<Variant> variants;
137 
138  for (const auto& group : groups) {
139  Variant variant;
140  variant.text_group_id = &group.first;
141  variant.text_codecs = GetGroupCodecString(group.second);
142 
143  variants.push_back(variant);
144  }
145 
146  // Make sure we return at least one variant so create a null variant if there
147  // are no variants.
148  if (variants.empty()) {
149  variants.emplace_back();
150  }
151 
152  return variants;
153 }
154 
155 std::list<Variant> BuildVariants(
156  const std::map<std::string, std::list<const MediaPlaylist*>>& audio_groups,
157  const std::map<std::string, std::list<const MediaPlaylist*>>&
158  subtitle_groups) {
159  std::list<Variant> audio_variants = AudioGroupsToVariants(audio_groups);
160  std::list<Variant> subtitle_variants =
161  SubtitleGroupsToVariants(subtitle_groups);
162 
163  DCHECK_GE(audio_variants.size(), 1u);
164  DCHECK_GE(subtitle_variants.size(), 1u);
165 
166  std::list<Variant> merged;
167 
168  for (const auto& audio_variant : audio_variants) {
169  for (const auto& subtitle_variant : subtitle_variants) {
170  Variant variant;
171  variant.audio_codecs = audio_variant.audio_codecs;
172  variant.text_codecs = subtitle_variant.text_codecs;
173  variant.audio_group_id = audio_variant.audio_group_id;
174  variant.text_group_id = subtitle_variant.text_group_id;
175  variant.max_audio_bitrate = audio_variant.max_audio_bitrate;
176  variant.avg_audio_bitrate = audio_variant.avg_audio_bitrate;
177 
178  merged.push_back(variant);
179  }
180  }
181 
182  DCHECK_GE(merged.size(), 1u);
183 
184  return merged;
185 }
186 
187 void BuildStreamInfTag(const MediaPlaylist& playlist,
188  const Variant& variant,
189  const std::string& base_url,
190  std::string* out) {
191  DCHECK(out);
192 
193  std::string tag_name;
194  switch (playlist.stream_type()) {
195  case MediaPlaylist::MediaPlaylistStreamType::kAudio:
196  case MediaPlaylist::MediaPlaylistStreamType::kVideo:
197  tag_name = "#EXT-X-STREAM-INF";
198  break;
199  case MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly:
200  tag_name = "#EXT-X-I-FRAME-STREAM-INF";
201  break;
202  default:
203  NOTREACHED() << "Cannot build STREAM-INFO tag for type "
204  << static_cast<int>(playlist.stream_type());
205  break;
206  }
207  Tag tag(tag_name, out);
208 
209  tag.AddNumber("BANDWIDTH", playlist.MaxBitrate() + variant.max_audio_bitrate);
210  tag.AddNumber("AVERAGE-BANDWIDTH",
211  playlist.AvgBitrate() + variant.avg_audio_bitrate);
212 
213  std::vector<std::string> all_codecs;
214  all_codecs.push_back(playlist.codec());
215  all_codecs.insert(all_codecs.end(), variant.audio_codecs.begin(),
216  variant.audio_codecs.end());
217  all_codecs.insert(all_codecs.end(), variant.text_codecs.begin(),
218  variant.text_codecs.end());
219  tag.AddQuotedString("CODECS", base::JoinString(all_codecs, ","));
220 
221  uint32_t width;
222  uint32_t height;
223  if (playlist.GetDisplayResolution(&width, &height)) {
224  tag.AddNumberPair("RESOLUTION", width, 'x', height);
225 
226  // Right now the frame-rate returned may not be accurate in some scenarios.
227  // TODO(kqyang): Fix frame-rate computation.
228  const double frame_rate = playlist.GetFrameRate();
229  if (frame_rate > 0)
230  tag.AddFloat("FRAME-RATE", frame_rate);
231 
232  const std::string video_range = playlist.GetVideoRange();
233  if (!video_range.empty())
234  tag.AddString("VIDEO-RANGE", video_range);
235  }
236 
237  if (variant.audio_group_id) {
238  tag.AddQuotedString("AUDIO", *variant.audio_group_id);
239  }
240 
241  if (variant.text_group_id) {
242  tag.AddQuotedString("SUBTITLES", *variant.text_group_id);
243  }
244 
245  if (playlist.stream_type() ==
246  MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly) {
247  tag.AddQuotedString("URI", base_url + playlist.file_name());
248  out->append("\n");
249  } else {
250  base::StringAppendF(out, "\n%s%s\n", base_url.c_str(),
251  playlist.file_name().c_str());
252  }
253 }
254 
255 // Need to pass in |group_id| as it may have changed to a new default when
256 // grouped with other playlists.
257 void BuildMediaTag(const MediaPlaylist& playlist,
258  const std::string& group_id,
259  bool is_default,
260  bool is_autoselect,
261  const std::string& base_url,
262  std::string* out) {
263  // Tag attribures should follow the order as defined in
264  // https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-3.5
265 
266  Tag tag("#EXT-X-MEDIA", out);
267 
268  // We should only be making media tags for audio and text.
269  switch (playlist.stream_type()) {
270  case MediaPlaylist::MediaPlaylistStreamType::kAudio:
271  tag.AddString("TYPE", "AUDIO");
272  break;
273 
274  case MediaPlaylist::MediaPlaylistStreamType::kSubtitle:
275  tag.AddString("TYPE", "SUBTITLES");
276  break;
277 
278  default:
279  NOTREACHED() << "Cannot build media tag for type "
280  << static_cast<int>(playlist.stream_type());
281  break;
282  }
283 
284  tag.AddQuotedString("URI", base_url + playlist.file_name());
285  tag.AddQuotedString("GROUP-ID", group_id);
286 
287  const std::string& language = playlist.language();
288  if (!language.empty()) {
289  tag.AddQuotedString("LANGUAGE", language);
290  }
291 
292  tag.AddQuotedString("NAME", playlist.name());
293 
294  if (is_default) {
295  tag.AddString("DEFAULT", "YES");
296  }
297 
298  if (is_autoselect) {
299  tag.AddString("AUTOSELECT", "YES");
300  }
301 
302  const std::vector<std::string>& characteristics = playlist.characteristics();
303  if (!characteristics.empty()) {
304  tag.AddQuotedString("CHARACTERISTICS",
305  base::JoinString(characteristics, ","));
306  }
307 
308  const MediaPlaylist::MediaPlaylistStreamType kAudio =
309  MediaPlaylist::MediaPlaylistStreamType::kAudio;
310  if (playlist.stream_type() == kAudio) {
311  std::string channel_string = std::to_string(playlist.GetNumChannels());
312  tag.AddQuotedString("CHANNELS", channel_string);
313  }
314 
315  out->append("\n");
316 }
317 
318 void BuildMediaTags(
319  const std::map<std::string, std::list<const MediaPlaylist*>>& groups,
320  const std::string& default_language,
321  const std::string& base_url,
322  std::string* out) {
323  for (const auto& group : groups) {
324  const std::string& group_id = group.first;
325  const auto& playlists = group.second;
326 
327  // Tracks the language of the playlist in this group.
328  // According to HLS spec: https://goo.gl/MiqjNd 4.3.4.1.1. Rendition Groups
329  // - A Group MUST NOT have more than one member with a DEFAULT attribute of
330  // YES.
331  // - Each EXT-X-MEDIA tag with an AUTOSELECT=YES attribute SHOULD have a
332  // combination of LANGUAGE[RFC5646], ASSOC-LANGUAGE, FORCED, and
333  // CHARACTERISTICS attributes that is distinct from those of other
334  // AUTOSELECT=YES members of its Group.
335  // We tag the first rendition encountered with a particular language with
336  // 'AUTOSELECT'; it is tagged with 'DEFAULT' too if the language matches
337  // |default_language_|.
338  std::set<std::string> languages;
339 
340  for (const auto& playlist : playlists) {
341  bool is_default = false;
342  bool is_autoselect = false;
343 
344  const std::string language = playlist->language();
345  if (languages.find(language) == languages.end()) {
346  is_default = !language.empty() && language == default_language;
347  is_autoselect = true;
348 
349  languages.insert(language);
350  }
351 
352  BuildMediaTag(*playlist, group_id, is_default, is_autoselect, base_url,
353  out);
354  }
355  }
356 }
357 
358 void AppendPlaylists(const std::string& default_audio_language,
359  const std::string& default_text_language,
360  const std::string& base_url,
361  const std::list<MediaPlaylist*>& playlists,
362  std::string* content) {
363  std::map<std::string, std::list<const MediaPlaylist*>> audio_playlist_groups;
364  std::map<std::string, std::list<const MediaPlaylist*>>
365  subtitle_playlist_groups;
366  std::list<const MediaPlaylist*> video_playlists;
367  std::list<const MediaPlaylist*> iframe_playlists;
368  for (const MediaPlaylist* playlist : playlists) {
369  switch (playlist->stream_type()) {
370  case MediaPlaylist::MediaPlaylistStreamType::kAudio:
371  audio_playlist_groups[GetGroupId(*playlist)].push_back(playlist);
372  break;
373  case MediaPlaylist::MediaPlaylistStreamType::kVideo:
374  video_playlists.push_back(playlist);
375  break;
376  case MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly:
377  iframe_playlists.push_back(playlist);
378  break;
379  case MediaPlaylist::MediaPlaylistStreamType::kSubtitle:
380  subtitle_playlist_groups[GetGroupId(*playlist)].push_back(playlist);
381  break;
382  default:
383  NOTIMPLEMENTED() << static_cast<int>(playlist->stream_type())
384  << " not handled.";
385  }
386  }
387 
388  if (!audio_playlist_groups.empty()) {
389  content->append("\n");
390  BuildMediaTags(audio_playlist_groups, default_audio_language, base_url,
391  content);
392  }
393 
394  if (!subtitle_playlist_groups.empty()) {
395  content->append("\n");
396  BuildMediaTags(subtitle_playlist_groups, default_text_language, base_url,
397  content);
398  }
399 
400  std::list<Variant> variants =
401  BuildVariants(audio_playlist_groups, subtitle_playlist_groups);
402  for (const auto& variant : variants) {
403  if (video_playlists.empty())
404  break;
405  content->append("\n");
406  for (const auto& playlist : video_playlists) {
407  BuildStreamInfTag(*playlist, variant, base_url, content);
408  }
409  }
410 
411  if (!iframe_playlists.empty()) {
412  content->append("\n");
413  for (const auto& playlist : iframe_playlists) {
414  // I-Frame playlists do not have variant. Just use the default.
415  BuildStreamInfTag(*playlist, Variant(), base_url, content);
416  }
417  }
418 
419  // Generate audio-only master playlist when there are no videos and subtitles.
420  if (!audio_playlist_groups.empty() && video_playlists.empty() &&
421  subtitle_playlist_groups.empty()) {
422  content->append("\n");
423  for (const auto& playlist_group : audio_playlist_groups) {
424  Variant variant;
425  // Populate |audio_group_id|, which will be propagated to "AUDIO" field.
426  // Leaving other fields, e.g. xxx_audio_bitrate in |Variant|, as
427  // null/empty/zero intentionally as the information is already available
428  // in audio |playlist|.
429  variant.audio_group_id = &playlist_group.first;
430  for (const auto& playlist : playlist_group.second) {
431  BuildStreamInfTag(*playlist, variant, base_url, content);
432  }
433  }
434  }
435 }
436 
437 } // namespace
438 
439 MasterPlaylist::MasterPlaylist(const std::string& file_name,
440  const std::string& default_audio_language,
441  const std::string& default_text_language)
442  : file_name_(file_name),
443  default_audio_language_(default_audio_language),
444  default_text_language_(default_text_language) {}
445 
446 MasterPlaylist::~MasterPlaylist() {}
447 
449  const std::string& base_url,
450  const std::string& output_dir,
451  const std::list<MediaPlaylist*>& playlists) {
452  std::string content = "#EXTM3U\n";
453  AppendVersionString(&content);
454  AppendPlaylists(default_audio_language_, default_text_language_, base_url,
455  playlists, &content);
456 
457  // Skip if the playlist is already written.
458  if (content == written_playlist_)
459  return true;
460 
461  std::string file_path =
462  base::FilePath::FromUTF8Unsafe(output_dir)
463  .Append(base::FilePath::FromUTF8Unsafe(file_name_))
464  .AsUTF8Unsafe();
465  if (!File::WriteFileAtomically(file_path.c_str(), content)) {
466  LOG(ERROR) << "Failed to write master playlist to: " << file_path;
467  return false;
468  }
469  written_playlist_ = content;
470  return true;
471 }
472 
473 } // namespace hls
474 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:262
-
virtual bool WriteMasterPlaylist(const std::string &base_url, const std::string &output_dir, const std::list< MediaPlaylist *> &playlists)
-
MasterPlaylist(const std::string &file_name, const std::string &default_audio_language, const std::string &default_text_language)
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/hls/base/master_playlist.h"
+
8 
+
9 #include <algorithm> // std::max
+
10 
+
11 #include <inttypes.h>
+
12 
+
13 #include "packager/base/files/file_path.h"
+
14 #include "packager/base/strings/string_number_conversions.h"
+
15 #include "packager/base/strings/string_util.h"
+
16 #include "packager/base/strings/stringprintf.h"
+
17 #include "packager/file/file.h"
+
18 #include "packager/hls/base/media_playlist.h"
+
19 #include "packager/hls/base/tag.h"
+
20 #include "packager/version/version.h"
+
21 
+
22 namespace shaka {
+
23 namespace hls {
+
24 namespace {
+
25 const char* kDefaultAudioGroupId = "default-audio-group";
+
26 const char* kDefaultSubtitleGroupId = "default-text-group";
+
27 const char* kUnexpectedGroupId = "unexpected-group";
+
28 
+
29 void AppendVersionString(std::string* content) {
+
30  const std::string version = GetPackagerVersion();
+
31  if (version.empty())
+
32  return;
+
33  base::StringAppendF(content, "## Generated with %s version %s\n",
+
34  GetPackagerProjectUrl().c_str(), version.c_str());
+
35 }
+
36 
+
37 // This structure roughly maps to the Variant stream in HLS specification.
+
38 // Each variant specifies zero or one audio group and zero or one text group.
+
39 struct Variant {
+
40  std::set<std::string> audio_codecs;
+
41  std::set<std::string> text_codecs;
+
42  const std::string* audio_group_id = nullptr;
+
43  const std::string* text_group_id = nullptr;
+
44  // The bitrates should be the sum of audio bitrate and text bitrate.
+
45  // However, given the constraints and assumptions, it makes sense to exclude
+
46  // text bitrate out of the calculation:
+
47  // - Text streams usually have a very small negligible bitrate.
+
48  // - Text does not have constant bitrates. To avoid fluctuation, an arbitrary
+
49  // value is assigned to the text bitrates in the parser. It does not make
+
50  // sense to take that text bitrate into account here.
+
51  uint64_t max_audio_bitrate = 0;
+
52  uint64_t avg_audio_bitrate = 0;
+
53 };
+
54 
+
55 uint64_t GetMaximumMaxBitrate(const std::list<const MediaPlaylist*> playlists) {
+
56  uint64_t max = 0;
+
57  for (const auto& playlist : playlists) {
+
58  max = std::max(max, playlist->MaxBitrate());
+
59  }
+
60  return max;
+
61 }
+
62 
+
63 uint64_t GetMaximumAvgBitrate(const std::list<const MediaPlaylist*> playlists) {
+
64  uint64_t max = 0;
+
65  for (const auto& playlist : playlists) {
+
66  max = std::max(max, playlist->AvgBitrate());
+
67  }
+
68  return max;
+
69 }
+
70 
+
71 std::set<std::string> GetGroupCodecString(
+
72  const std::list<const MediaPlaylist*>& group) {
+
73  std::set<std::string> codecs;
+
74 
+
75  for (const MediaPlaylist* playlist : group) {
+
76  codecs.insert(playlist->codec());
+
77  }
+
78 
+
79  // To support some older players, we cannot include "wvtt" in the codec
+
80  // string. As per HLS guidelines, "wvtt" is optional. When it is included, it
+
81  // can cause playback errors on some Apple produces. Excluding it allows
+
82  // playback on all Apple products. See
+
83  // https://github.com/google/shaka-packager/issues/402 for all details.
+
84  auto wvtt = codecs.find("wvtt");
+
85  if (wvtt != codecs.end()) {
+
86  codecs.erase(wvtt);
+
87  }
+
88  // TTML is specified using 'stpp.ttml.im1t'; see section 5.10 of
+
89  // https://developer.apple.com/documentation/http_live_streaming/hls_authoring_specification_for_apple_devices
+
90  auto ttml = codecs.find("ttml");
+
91  if (ttml != codecs.end()) {
+
92  codecs.erase(ttml);
+
93  codecs.insert("stpp.ttml.im1t");
+
94  }
+
95 
+
96  return codecs;
+
97 }
+
98 
+
99 std::list<Variant> AudioGroupsToVariants(
+
100  const std::map<std::string, std::list<const MediaPlaylist*>>& groups) {
+
101  std::list<Variant> variants;
+
102 
+
103  for (const auto& group : groups) {
+
104  Variant variant;
+
105  variant.audio_group_id = &group.first;
+
106  variant.max_audio_bitrate = GetMaximumMaxBitrate(group.second);
+
107  variant.avg_audio_bitrate = GetMaximumAvgBitrate(group.second);
+
108  variant.audio_codecs = GetGroupCodecString(group.second);
+
109 
+
110  variants.push_back(variant);
+
111  }
+
112 
+
113  // Make sure we return at least one variant so create a null variant if there
+
114  // are no variants.
+
115  if (variants.empty()) {
+
116  variants.emplace_back();
+
117  }
+
118 
+
119  return variants;
+
120 }
+
121 
+
122 const char* GetGroupId(const MediaPlaylist& playlist) {
+
123  const std::string& group_id = playlist.group_id();
+
124 
+
125  if (!group_id.empty()) {
+
126  return group_id.c_str();
+
127  }
+
128 
+
129  switch (playlist.stream_type()) {
+
130  case MediaPlaylist::MediaPlaylistStreamType::kAudio:
+
131  return kDefaultAudioGroupId;
+
132 
+
133  case MediaPlaylist::MediaPlaylistStreamType::kSubtitle:
+
134  return kDefaultSubtitleGroupId;
+
135 
+
136  default:
+
137  return kUnexpectedGroupId;
+
138  }
+
139 }
+
140 
+
141 std::list<Variant> SubtitleGroupsToVariants(
+
142  const std::map<std::string, std::list<const MediaPlaylist*>>& groups) {
+
143  std::list<Variant> variants;
+
144 
+
145  for (const auto& group : groups) {
+
146  Variant variant;
+
147  variant.text_group_id = &group.first;
+
148  variant.text_codecs = GetGroupCodecString(group.second);
+
149 
+
150  variants.push_back(variant);
+
151  }
+
152 
+
153  // Make sure we return at least one variant so create a null variant if there
+
154  // are no variants.
+
155  if (variants.empty()) {
+
156  variants.emplace_back();
+
157  }
+
158 
+
159  return variants;
+
160 }
+
161 
+
162 std::list<Variant> BuildVariants(
+
163  const std::map<std::string, std::list<const MediaPlaylist*>>& audio_groups,
+
164  const std::map<std::string, std::list<const MediaPlaylist*>>&
+
165  subtitle_groups) {
+
166  std::list<Variant> audio_variants = AudioGroupsToVariants(audio_groups);
+
167  std::list<Variant> subtitle_variants =
+
168  SubtitleGroupsToVariants(subtitle_groups);
+
169 
+
170  DCHECK_GE(audio_variants.size(), 1u);
+
171  DCHECK_GE(subtitle_variants.size(), 1u);
+
172 
+
173  std::list<Variant> merged;
+
174 
+
175  for (const auto& audio_variant : audio_variants) {
+
176  for (const auto& subtitle_variant : subtitle_variants) {
+
177  Variant variant;
+
178  variant.audio_codecs = audio_variant.audio_codecs;
+
179  variant.text_codecs = subtitle_variant.text_codecs;
+
180  variant.audio_group_id = audio_variant.audio_group_id;
+
181  variant.text_group_id = subtitle_variant.text_group_id;
+
182  variant.max_audio_bitrate = audio_variant.max_audio_bitrate;
+
183  variant.avg_audio_bitrate = audio_variant.avg_audio_bitrate;
+
184 
+
185  merged.push_back(variant);
+
186  }
+
187  }
+
188 
+
189  DCHECK_GE(merged.size(), 1u);
+
190 
+
191  return merged;
+
192 }
+
193 
+
194 void BuildStreamInfTag(const MediaPlaylist& playlist,
+
195  const Variant& variant,
+
196  const std::string& base_url,
+
197  std::string* out) {
+
198  DCHECK(out);
+
199 
+
200  std::string tag_name;
+
201  switch (playlist.stream_type()) {
+
202  case MediaPlaylist::MediaPlaylistStreamType::kAudio:
+
203  case MediaPlaylist::MediaPlaylistStreamType::kVideo:
+
204  tag_name = "#EXT-X-STREAM-INF";
+
205  break;
+
206  case MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly:
+
207  tag_name = "#EXT-X-I-FRAME-STREAM-INF";
+
208  break;
+
209  default:
+
210  NOTREACHED() << "Cannot build STREAM-INFO tag for type "
+
211  << static_cast<int>(playlist.stream_type());
+
212  break;
+
213  }
+
214  Tag tag(tag_name, out);
+
215 
+
216  tag.AddNumber("BANDWIDTH", playlist.MaxBitrate() + variant.max_audio_bitrate);
+
217  tag.AddNumber("AVERAGE-BANDWIDTH",
+
218  playlist.AvgBitrate() + variant.avg_audio_bitrate);
+
219 
+
220  std::vector<std::string> all_codecs;
+
221  all_codecs.push_back(playlist.codec());
+
222  all_codecs.insert(all_codecs.end(), variant.audio_codecs.begin(),
+
223  variant.audio_codecs.end());
+
224  all_codecs.insert(all_codecs.end(), variant.text_codecs.begin(),
+
225  variant.text_codecs.end());
+
226  tag.AddQuotedString("CODECS", base::JoinString(all_codecs, ","));
+
227 
+
228  uint32_t width;
+
229  uint32_t height;
+
230  if (playlist.GetDisplayResolution(&width, &height)) {
+
231  tag.AddNumberPair("RESOLUTION", width, 'x', height);
+
232 
+
233  // Right now the frame-rate returned may not be accurate in some scenarios.
+
234  // TODO(kqyang): Fix frame-rate computation.
+
235  const bool is_iframe_playlist =
+
236  playlist.stream_type() ==
+
237  MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly;
+
238  if (!is_iframe_playlist) {
+
239  const double frame_rate = playlist.GetFrameRate();
+
240  if (frame_rate > 0)
+
241  tag.AddFloat("FRAME-RATE", frame_rate);
+
242  }
+
243 
+
244  const std::string video_range = playlist.GetVideoRange();
+
245  if (!video_range.empty())
+
246  tag.AddString("VIDEO-RANGE", video_range);
+
247  }
+
248 
+
249  if (variant.audio_group_id) {
+
250  tag.AddQuotedString("AUDIO", *variant.audio_group_id);
+
251  }
+
252 
+
253  if (variant.text_group_id) {
+
254  tag.AddQuotedString("SUBTITLES", *variant.text_group_id);
+
255  }
+
256 
+
257  // Since CEA captions in Shaka Packager are only an input format, but not
+
258  // supported as output, the HLS output should always indicate that there are
+
259  // no captions. Explicitly signaling a lack of captions in HLS keeps Safari
+
260  // from assuming captions and showing a text track that doesn't exist.
+
261  // https://github.com/google/shaka-packager/issues/922#issuecomment-804304019
+
262  tag.AddString("CLOSED-CAPTIONS", "NONE");
+
263 
+
264  if (playlist.stream_type() ==
+
265  MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly) {
+
266  tag.AddQuotedString("URI", base_url + playlist.file_name());
+
267  out->append("\n");
+
268  } else {
+
269  base::StringAppendF(out, "\n%s%s\n", base_url.c_str(),
+
270  playlist.file_name().c_str());
+
271  }
+
272 }
+
273 
+
274 // Need to pass in |group_id| as it may have changed to a new default when
+
275 // grouped with other playlists.
+
276 void BuildMediaTag(const MediaPlaylist& playlist,
+
277  const std::string& group_id,
+
278  bool is_default,
+
279  bool is_autoselect,
+
280  const std::string& base_url,
+
281  std::string* out) {
+
282  // Tag attributes should follow the order as defined in
+
283  // https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-3.5
+
284 
+
285  Tag tag("#EXT-X-MEDIA", out);
+
286 
+
287  // We should only be making media tags for audio and text.
+
288  switch (playlist.stream_type()) {
+
289  case MediaPlaylist::MediaPlaylistStreamType::kAudio:
+
290  tag.AddString("TYPE", "AUDIO");
+
291  break;
+
292 
+
293  case MediaPlaylist::MediaPlaylistStreamType::kSubtitle:
+
294  tag.AddString("TYPE", "SUBTITLES");
+
295  break;
+
296 
+
297  default:
+
298  NOTREACHED() << "Cannot build media tag for type "
+
299  << static_cast<int>(playlist.stream_type());
+
300  break;
+
301  }
+
302 
+
303  tag.AddQuotedString("URI", base_url + playlist.file_name());
+
304  tag.AddQuotedString("GROUP-ID", group_id);
+
305 
+
306  const std::string& language = playlist.language();
+
307  if (!language.empty()) {
+
308  tag.AddQuotedString("LANGUAGE", language);
+
309  }
+
310 
+
311  tag.AddQuotedString("NAME", playlist.name());
+
312 
+
313  if (is_default) {
+
314  tag.AddString("DEFAULT", "YES");
+
315  }
+
316 
+
317  if (is_autoselect) {
+
318  tag.AddString("AUTOSELECT", "YES");
+
319  }
+
320 
+
321  const std::vector<std::string>& characteristics = playlist.characteristics();
+
322  if (!characteristics.empty()) {
+
323  tag.AddQuotedString("CHARACTERISTICS",
+
324  base::JoinString(characteristics, ","));
+
325  }
+
326 
+
327  const MediaPlaylist::MediaPlaylistStreamType kAudio =
+
328  MediaPlaylist::MediaPlaylistStreamType::kAudio;
+
329  if (playlist.stream_type() == kAudio) {
+
330  if (playlist.GetEC3JocComplexity() != 0) {
+
331  // HLS Authoring Specification for Apple Devices Appendices documents how
+
332  // to handle Dolby Digital Plus JOC content.
+
333  // https://developer.apple.com/documentation/http_live_streaming/hls_authoring_specification_for_apple_devices/hls_authoring_specification_for_apple_devices_appendices
+
334  std::string channel_string =
+
335  std::to_string(playlist.GetEC3JocComplexity()) + "/JOC";
+
336  tag.AddQuotedString("CHANNELS", channel_string);
+
337  } else if (playlist.GetAC4ImsFlag() || playlist.GetAC4CbiFlag()) {
+
338  // Dolby has qualified using IMSA to present AC4 immersive audio (IMS and
+
339  // CBI without object-based audio) for Dolby internal use only. IMSA is
+
340  // not included in any publicly-available specifications as of June, 2020.
+
341  std::string channel_string =
+
342  std::to_string(playlist.GetNumChannels()) + "/IMSA";
+
343  tag.AddQuotedString("CHANNELS", channel_string);
+
344  } else {
+
345  // According to HLS spec:
+
346  // https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis 4.4.6.1.
+
347  // CHANNELS is a quoted-string that specifies an ordered,
+
348  // slash-separated ("/") list of parameters. The first parameter is a
+
349  // count of audio channels, and the second parameter identifies the
+
350  // encoding of object-based audio used by the Rendition.
+
351  std::string channel_string = std::to_string(playlist.GetNumChannels());
+
352  tag.AddQuotedString("CHANNELS", channel_string);
+
353  }
+
354  }
+
355  out->append("\n");
+
356 }
+
357 
+
358 void BuildMediaTags(
+
359  const std::map<std::string, std::list<const MediaPlaylist*>>& groups,
+
360  const std::string& default_language,
+
361  const std::string& base_url,
+
362  std::string* out) {
+
363  for (const auto& group : groups) {
+
364  const std::string& group_id = group.first;
+
365  const auto& playlists = group.second;
+
366 
+
367  // Tracks the language of the playlist in this group.
+
368  // According to HLS spec: https://goo.gl/MiqjNd 4.3.4.1.1. Rendition Groups
+
369  // - A Group MUST NOT have more than one member with a DEFAULT attribute of
+
370  // YES.
+
371  // - Each EXT-X-MEDIA tag with an AUTOSELECT=YES attribute SHOULD have a
+
372  // combination of LANGUAGE[RFC5646], ASSOC-LANGUAGE, FORCED, and
+
373  // CHARACTERISTICS attributes that is distinct from those of other
+
374  // AUTOSELECT=YES members of its Group.
+
375  // We tag the first rendition encountered with a particular language with
+
376  // 'AUTOSELECT'; it is tagged with 'DEFAULT' too if the language matches
+
377  // |default_language_|.
+
378  std::set<std::string> languages;
+
379 
+
380  for (const auto& playlist : playlists) {
+
381  bool is_default = false;
+
382  bool is_autoselect = false;
+
383 
+
384  if (playlist->is_dvs()) {
+
385  // According to HLS Authoring Specification for Apple Devices
+
386  // https://developer.apple.com/documentation/http_live_streaming/hls_authoring_specification_for_apple_devices#overview
+
387  // section 2.13 If you provide DVS, the AUTOSELECT attribute MUST have
+
388  // a value of "YES".
+
389  is_autoselect = true;
+
390  } else {
+
391  const std::string language = playlist->language();
+
392  if (languages.find(language) == languages.end()) {
+
393  is_default = !language.empty() && language == default_language;
+
394  is_autoselect = true;
+
395 
+
396  languages.insert(language);
+
397  }
+
398  }
+
399 
+
400  BuildMediaTag(*playlist, group_id, is_default, is_autoselect, base_url,
+
401  out);
+
402  }
+
403  }
+
404 }
+
405 
+
406 void AppendPlaylists(const std::string& default_audio_language,
+
407  const std::string& default_text_language,
+
408  const std::string& base_url,
+
409  const std::list<MediaPlaylist*>& playlists,
+
410  std::string* content) {
+
411  std::map<std::string, std::list<const MediaPlaylist*>> audio_playlist_groups;
+
412  std::map<std::string, std::list<const MediaPlaylist*>>
+
413  subtitle_playlist_groups;
+
414  std::list<const MediaPlaylist*> video_playlists;
+
415  std::list<const MediaPlaylist*> iframe_playlists;
+
416  for (const MediaPlaylist* playlist : playlists) {
+
417  switch (playlist->stream_type()) {
+
418  case MediaPlaylist::MediaPlaylistStreamType::kAudio:
+
419  audio_playlist_groups[GetGroupId(*playlist)].push_back(playlist);
+
420  break;
+
421  case MediaPlaylist::MediaPlaylistStreamType::kVideo:
+
422  video_playlists.push_back(playlist);
+
423  break;
+
424  case MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly:
+
425  iframe_playlists.push_back(playlist);
+
426  break;
+
427  case MediaPlaylist::MediaPlaylistStreamType::kSubtitle:
+
428  subtitle_playlist_groups[GetGroupId(*playlist)].push_back(playlist);
+
429  break;
+
430  default:
+
431  NOTIMPLEMENTED() << static_cast<int>(playlist->stream_type())
+
432  << " not handled.";
+
433  }
+
434  }
+
435 
+
436  if (!audio_playlist_groups.empty()) {
+
437  content->append("\n");
+
438  BuildMediaTags(audio_playlist_groups, default_audio_language, base_url,
+
439  content);
+
440  }
+
441 
+
442  if (!subtitle_playlist_groups.empty()) {
+
443  content->append("\n");
+
444  BuildMediaTags(subtitle_playlist_groups, default_text_language, base_url,
+
445  content);
+
446  }
+
447 
+
448  std::list<Variant> variants =
+
449  BuildVariants(audio_playlist_groups, subtitle_playlist_groups);
+
450  for (const auto& variant : variants) {
+
451  if (video_playlists.empty())
+
452  break;
+
453  content->append("\n");
+
454  for (const auto& playlist : video_playlists) {
+
455  BuildStreamInfTag(*playlist, variant, base_url, content);
+
456  }
+
457  }
+
458 
+
459  if (!iframe_playlists.empty()) {
+
460  content->append("\n");
+
461  for (const auto& playlist : iframe_playlists) {
+
462  // I-Frame playlists do not have variant. Just use the default.
+
463  BuildStreamInfTag(*playlist, Variant(), base_url, content);
+
464  }
+
465  }
+
466 
+
467  // Generate audio-only master playlist when there are no videos and subtitles.
+
468  if (!audio_playlist_groups.empty() && video_playlists.empty() &&
+
469  subtitle_playlist_groups.empty()) {
+
470  content->append("\n");
+
471  for (const auto& playlist_group : audio_playlist_groups) {
+
472  Variant variant;
+
473  // Populate |audio_group_id|, which will be propagated to "AUDIO" field.
+
474  // Leaving other fields, e.g. xxx_audio_bitrate in |Variant|, as
+
475  // null/empty/zero intentionally as the information is already available
+
476  // in audio |playlist|.
+
477  variant.audio_group_id = &playlist_group.first;
+
478  for (const auto& playlist : playlist_group.second) {
+
479  BuildStreamInfTag(*playlist, variant, base_url, content);
+
480  }
+
481  }
+
482  }
+
483 }
+
484 
+
485 } // namespace
+
486 
+
487 MasterPlaylist::MasterPlaylist(const std::string& file_name,
+
488  const std::string& default_audio_language,
+
489  const std::string& default_text_language,
+
490  bool is_independent_segments)
+
491  : file_name_(file_name),
+
492  default_audio_language_(default_audio_language),
+
493  default_text_language_(default_text_language),
+
494  is_independent_segments_(is_independent_segments) {}
+
495 
+
496 MasterPlaylist::~MasterPlaylist() {}
+
497 
+ +
499  const std::string& base_url,
+
500  const std::string& output_dir,
+
501  const std::list<MediaPlaylist*>& playlists) {
+
502  std::string content = "#EXTM3U\n";
+
503  AppendVersionString(&content);
+
504 
+
505  if (is_independent_segments_) {
+
506  content.append("\n#EXT-X-INDEPENDENT-SEGMENTS\n");
+
507  }
+
508  AppendPlaylists(default_audio_language_, default_text_language_, base_url,
+
509  playlists, &content);
+
510 
+
511  // Skip if the playlist is already written.
+
512  if (content == written_playlist_)
+
513  return true;
+
514 
+
515  std::string file_path =
+
516  base::FilePath::FromUTF8Unsafe(output_dir)
+
517  .Append(base::FilePath::FromUTF8Unsafe(file_name_))
+
518  .AsUTF8Unsafe();
+
519  if (!File::WriteFileAtomically(file_path.c_str(), content)) {
+
520  LOG(ERROR) << "Failed to write master playlist to: " << file_path;
+
521  return false;
+
522  }
+
523  written_playlist_ = content;
+
524  return true;
+
525 }
+
526 
+
527 } // namespace hls
+
528 } // namespace shaka
+
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:277
+
MasterPlaylist(const std::string &file_name, const std::string &default_audio_language, const std::string &default_text_language, const bool is_independent_segments)
+
virtual bool WriteMasterPlaylist(const std::string &base_url, const std::string &output_dir, const std::list< MediaPlaylist * > &playlists)
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/db1/structshaka_1_1media_1_1mp4_1_1SampleToGroup-members.html b/docs/d2/db1/structshaka_1_1media_1_1mp4_1_1SampleToGroup-members.html index 9f54a32539..f9ed62a3da 100644 --- a/docs/d2/db1/structshaka_1_1media_1_1mp4_1_1SampleToGroup-members.html +++ b/docs/d2/db1/structshaka_1_1media_1_1mp4_1_1SampleToGroup-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/db6/structshaka_1_1media_1_1mp4_1_1FileType-members.html b/docs/d2/db6/structshaka_1_1media_1_1mp4_1_1FileType-members.html index 7bcf673be0..289620a49e 100644 --- a/docs/d2/db6/structshaka_1_1media_1_1mp4_1_1FileType-members.html +++ b/docs/d2/db6/structshaka_1_1media_1_1mp4_1_1FileType-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d2/db8/structshaka_1_1media_1_1mp4_1_1CueSourceIDBox-members.html b/docs/d2/db8/structshaka_1_1media_1_1mp4_1_1CueSourceIDBox-members.html index ea94566e1d..b3233b6b4e 100644 --- a/docs/d2/db8/structshaka_1_1media_1_1mp4_1_1CueSourceIDBox-members.html +++ b/docs/d2/db8/structshaka_1_1media_1_1mp4_1_1CueSourceIDBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d2/dba/classshaka_1_1media_1_1SegmentTestBase.html b/docs/d2/dba/classshaka_1_1media_1_1SegmentTestBase.html index d2a1c42ad5..900c5526fc 100644 --- a/docs/d2/dba/classshaka_1_1media_1_1SegmentTestBase.html +++ b/docs/d2/dba/classshaka_1_1media_1_1SegmentTestBase.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SegmentTestBase Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
- - - +

@@ -88,12 +89,12 @@ Classes

- -

Public Types

enum  KeyFrameFlag { kKeyFrame, -kNotKeyFrame +
enum  KeyFrameFlag { kKeyFrame +, kNotKeyFrame }
 
enum  SideDataFlag { kGenerateSideData, -kNoSideData +
enum  SideDataFlag { kGenerateSideData +, kNoSideData }
 
@@ -159,9 +160,7 @@ bool 
single_segment_ diff --git a/docs/d2/dba/classshaka_1_1media_1_1SegmentTestBase.png b/docs/d2/dba/classshaka_1_1media_1_1SegmentTestBase.png index 4dc3c2812aec82ca6f86ae5fbc27e782b0f349a9..8c4ab78dfc9470af1744b9910155cec0dea2446a 100644 GIT binary patch delta 622 zcmV-!0+Idm1iuB4Tz^hUL_t(|0qvdL(&``#MOSXz@BhX}TZHga^{Yh=Gt98HrAb(% zA-%=SY+7NGG^rN7B#qIcm!vWJn!a?u-?t-%E+NT{Zx`=CFG)?+&j!RNga=KiwWm)4SWR)3e!hts(KyrnO!CF!iL z%DumNpZhoMNs>NNuewiD$CdLx(C0lTbeU(;MK4KXwCE*ijPCSiX0r;Qqiz7xYHIr1ZD#zb>F@9p>VhW8+Gio*Ni^7$Fi$)S;TOE#Y>JEZLHpKF6isJ_wyBfwpuuJ z&jh-fa4%su$qKAGHkH+pb1bMGqkNLhr-l5fZ6w9-sLp-)t~0YktJZXNK%13Q^|!L_ zU)LF!8)wbBujxyxk1FSnbzfCZ%6z=Z1GIXMziD=+%-J2@y65a?+=Ypy+~_#~UDacq z-_U1O1#ppml>65oe1KE>UF85=twj$oMvER`jKUYe%xp&e1K>b%xtN2*J^%m!07*qo IM6N<$f@JMMcmMzZ delta 546 zcmV+-0^R+;1@i=uTz>*dL_t(|0qvdLj_V){2FEx3-v5nH^9Lr-ZqIH~3&|3b-KGWx zW9ThrX48U6(xjxlB*l>Sk`%)&_WOk($+bJObXV^CQRlPYH(+^odm%}G4}Zg4WDhiLef6pSi{K+EZ-%M%>mrvl?5V5${rcB<7qY|;!|ERRsJ8Pq zTbZi~U;i!k?!BL=*l**m-S!U0mvtRmfb$*p*{3V3a8c*ZHQtGWxz>+e*V@?E?xpPd zT%N{oe@>fRGCG)j(D`KF*S&w=**CN8hwezAs|mLWTYpGXVBN9lqF!|_1+{6MziHmr ziTtS@B*m|&&;5C?o3NKrqu1R59ac_vzn$y;eVu{1Hmv*J{v7pD<@{&eca>8!Up}-0 zjP4x&VR$n&o!#N>@0{(7yJ1Qx5AGa*Te)MN@7On01#l5x%KiHve1Ko^y~+W&nzRRq kA?*QT*c*Ql%* + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::media::TextChunker, including all inherited members.

- + @@ -94,9 +97,7 @@ $(function() {
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
diff --git a/docs/d2/dbc/av1__parser_8cc_source.html b/docs/d2/dbc/av1__parser_8cc_source.html index d6ff54dec0..ddb2d4da66 100644 --- a/docs/d2/dbc/av1__parser_8cc_source.html +++ b/docs/d2/dbc/av1__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/av1_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
av1_parser.cc
-
1 // Copyright 2018 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/av1_parser.h"
8 
9 #include <algorithm>
10 
11 #include "packager/base/logging.h"
12 #include "packager/media/base/bit_reader.h"
13 #include "packager/media/base/rcheck.h"
14 
15 namespace shaka {
16 namespace media {
17 namespace {
18 
19 // 3. Symbols and abbreviated terms.
20 enum MotionType {
21  IDENTITY = 0,
22  TRANSLATION,
23  ROTZOOM,
24  AFFINE,
25 };
26 
27 const int kSelectScreenContentTools = 2;
28 const int kSelectIntegerMv = 2;
29 const int kPrimaryRefNone = 7;
30 const int kNumRefFrames = 8;
31 const int kAllFrames = (1 << kNumRefFrames) - 1;
32 
33 // 6.2.2. OBU header semantics.
34 enum ObuType {
35  OBU_SEQUENCE_HEADER = 1,
36  OBU_TEMPORAL_DELIMITER,
37  OBU_FRAME_HEADER,
38  OBU_TILE_GROUP,
39  OBU_METADATA,
40  OBU_FRAME,
41  OBU_REDUNDENT_FRAME_HEADER,
42  OBU_TILE_LIST,
43  // Reserved types between OBU_TILE_LIST and OBU_PADDING.
44  OBU_PADDING = 15,
45 };
46 
47 // 6.4.2. Color config semantics.
48 enum ColorPrimaries {
49  CP_BT_709 = 1,
50  CP_UNSPECIFIED = 2,
51  // We are not interested in the others.
52 };
53 enum TransferCharacteristics {
54  TC_UNSPECIFIED = 2,
55  TC_SRGB = 13,
56  // We are not interested in the others.
57 };
58 enum MatrixCoefficients {
59  MC_IDENTITY = 0,
60  MC_UNSPECIFIED = 2,
61  // We are not interested in the others.
62 };
63 enum ChromaSamplePosition {
64  CSP_UNKNOWN = 0,
65  CSP_VERTICAL,
66  CSP_COLOCATED,
67  CSP_RESERVED,
68 };
69 
70 // 6.8.2. Uncompressed header semantics.
71 enum FrameType {
72  KEY_FRAME = 0,
73  INTER_FRAME,
74  INTRA_ONLY_FRAME,
75  SWITCH_FRAME,
76 };
77 
78 // 6.10.24. Ref frames semantics.
79 enum RefFrameName {
80  INTRA_FRAME = 0,
81  LAST_FRAME,
82  LAST2_FRAME,
83  LAST3_FRAME,
84  GOLDEN_FRAME,
85  BWDREF_FRAME,
86  ALTREF2_FRAME,
87  ALTREF_FRAME,
88 };
89 
90 // 4.7. Mathematical functions.
91 int Clip3(int min_value, int max_value, int value) {
92  if (value < min_value)
93  return min_value;
94  if (value > max_value)
95  return max_value;
96  return value;
97 }
98 
99 // 4.7. Mathematical functions. The FloorLog2(x) function is defined to be the
100 // floor of the base 2 logarithm of the input x.
101 int FloorLog2(int x) {
102  int s = 0;
103  while (x != 0) {
104  x = x >> 1;
105  s++;
106  }
107  return s - 1;
108 }
109 
110 // 4.10.3. uvlc(). This is a modified form of Exponential-Golomb coding.
111 bool ReadUvlc(BitReader* reader, uint32_t* val) {
112  // Count the number of contiguous zero bits.
113  int leading_zeros = 0;
114  while (true) {
115  bool done = false;
116  RCHECK(reader->ReadBits(1, &done));
117  if (done)
118  break;
119  leading_zeros++;
120  }
121 
122  if (leading_zeros >= 32) {
123  *val = (1ull << 32) - 1;
124  return true;
125  }
126 
127  int value = 0;
128  if (leading_zeros > 0)
129  RCHECK(reader->ReadBits(leading_zeros, &value));
130 
131  *val = value + (1 << leading_zeros) - 1;
132  return true;
133 }
134 
135 // 4.10.4. le(n). Unsigned little-endian n-byte number appearing directly in the
136 // bitstream.
137 bool ReadLe(int n, BitReader* reader, size_t* val) {
138  size_t t = 0;
139  for (int i = 0; i < n; i++) {
140  size_t byte = 0;
141  RCHECK(reader->ReadBits(8, &byte));
142  t += (byte << (i * 8));
143  }
144  *val = t;
145  return true;
146 }
147 
148 // 4.10.5. leb128(). Unsigned integer represented by a variable number of
149 // little-endian bytes.
150 bool ReadLeb128(BitReader* reader, size_t* size) {
151  size_t value = 0;
152  for (int i = 0; i < 8; i++) {
153  size_t leb128_byte = 0;
154  RCHECK(reader->ReadBits(8, &leb128_byte));
155  value |= (leb128_byte & 0x7f) << (i * 7);
156  if (!(leb128_byte & 0x80))
157  break;
158  }
159  // It is a requirement of bitstream conformance that the value returned from
160  // the leb128 parsing process is less than or equal to (1<<32) - 1.
161  RCHECK(value <= ((1ull << 32) - 1));
162  *size = value;
163  return true;
164 }
165 
166 // 4.10.6. su(n). Signed integer converted from an n bits unsigned integer in
167 // the bitstream.
168 bool ReadSu(int n, BitReader* reader, int* value) {
169  RCHECK(reader->ReadBits(n, value));
170  int sign_mask = 1 << (n - 1);
171  if (*value & sign_mask)
172  *value = *value - 2 * sign_mask;
173  return true;
174 }
175 
176 // 4.10.7. ns(n). Unsigned encoded integer with maximum number of values in n
177 // (i.e. output in range 0..n-1).
178 bool ReadNs(int n, BitReader* reader, int* value) {
179  const int w = FloorLog2(n) + 1;
180  const int m = (1 << w) - n;
181  RCHECK(reader->ReadBits(w - 1, value));
182  if (*value < m)
183  return true;
184  int extra_bit = 0;
185  RCHECK(reader->ReadBits(1, &extra_bit));
186  *value = (*value << 1) - m + extra_bit;
187  return true;
188 }
189 
190 // 5.9.16. Tile size calculation function: returns the smallest value for k such
191 // that blk_size << k is greater than or equal to target.
192 int TileLog2(int blk_size, int target) {
193  int k = 0;
194  for (k = 0; (blk_size << k) < target; k++)
195  continue;
196  return k;
197 }
198 
199 // See 7.8. Set frame refs process.
200 int FindLatestBackward(int shifted_order_hints[],
201  bool used_frame[],
202  int cur_frame_hint) {
203  int ref = -1;
204  int latest_order_hint = 0;
205  for (int i = 0; i < kNumRefFrames; i++) {
206  const int hint = shifted_order_hints[i];
207  if (!used_frame[i] && hint >= cur_frame_hint &&
208  (ref < 0 || hint >= latest_order_hint)) {
209  ref = i;
210  latest_order_hint = hint;
211  }
212  }
213  return ref;
214 }
215 
216 // See 7.8. Set frame refs process.
217 int FindEarliestBackward(int shifted_order_hints[],
218  bool used_frame[],
219  int cur_frame_hint) {
220  int ref = -1;
221  int earliest_order_hint = 0;
222  for (int i = 0; i < kNumRefFrames; i++) {
223  const int hint = shifted_order_hints[i];
224  if (!used_frame[i] && hint >= cur_frame_hint &&
225  (ref < 0 || hint < earliest_order_hint)) {
226  ref = i;
227  earliest_order_hint = hint;
228  }
229  }
230  return ref;
231 }
232 
233 // See 7.8. Set frame refs process.
234 int FindLatestForward(int shifted_order_hints[],
235  bool used_frame[],
236  int cur_frame_hint) {
237  int ref = -1;
238  int latest_order_hint = 0;
239  for (int i = 0; i < kNumRefFrames; i++) {
240  const int hint = shifted_order_hints[i];
241  if (!used_frame[i] && hint < cur_frame_hint &&
242  (ref < 0 || hint >= latest_order_hint)) {
243  ref = i;
244  latest_order_hint = hint;
245  }
246  }
247  return ref;
248 }
249 
250 } // namespace
251 
252 AV1Parser::AV1Parser() = default;
253 AV1Parser::~AV1Parser() = default;
254 
255 bool AV1Parser::Parse(const uint8_t* data,
256  size_t data_size,
257  std::vector<Tile>* tiles) {
258  tiles->clear();
259 
260  BitReader reader(data, data_size);
261  while (reader.bits_available() > 0) {
262  if (!ParseOpenBitstreamUnit(&reader, tiles))
263  return false;
264  }
265  return true;
266 }
267 
268 // 5.3.1. General OBU syntax.
269 bool AV1Parser::ParseOpenBitstreamUnit(BitReader* reader,
270  std::vector<Tile>* tiles) {
271  ObuHeader obu_header;
272  RCHECK(ParseObuHeader(reader, &obu_header));
273 
274  size_t obu_size = 0;
275  if (obu_header.obu_has_size_field)
276  RCHECK(ReadLeb128(reader, &obu_size));
277  else
278  obu_size = reader->bits_available() / 8;
279 
280  VLOG(4) << "OBU " << obu_header.obu_type << " size " << obu_size;
281 
282  const size_t start_position = reader->bit_position();
283  switch (obu_header.obu_type) {
284  case OBU_SEQUENCE_HEADER:
285  RCHECK(ParseSequenceHeaderObu(reader));
286  break;
287  case OBU_FRAME_HEADER:
288  case OBU_REDUNDENT_FRAME_HEADER:
289  RCHECK(ParseFrameHeaderObu(obu_header, reader));
290  break;
291  case OBU_TILE_GROUP:
292  RCHECK(ParseTileGroupObu(obu_size, reader, tiles));
293  break;
294  case OBU_FRAME:
295  RCHECK(ParseFrameObu(obu_header, obu_size, reader, tiles));
296  break;
297  default:
298  // Skip all OBUs we are not interested.
299  RCHECK(reader->SkipBits(obu_size * 8));
300  break;
301  }
302 
303  const size_t current_position = reader->bit_position();
304  const size_t payload_bits = current_position - start_position;
305  if (obu_header.obu_type == OBU_TILE_GROUP ||
306  obu_header.obu_type == OBU_FRAME) {
307  RCHECK(payload_bits == obu_size * 8);
308  } else if (obu_size > 0) {
309  RCHECK(payload_bits <= obu_size * 8);
310  RCHECK(ParseTrailingBits(obu_size * 8 - payload_bits, reader));
311  }
312  return true;
313 }
314 
315 // 5.3.2. OBU header syntax.
316 bool AV1Parser::ParseObuHeader(BitReader* reader, ObuHeader* obu_header) {
317  int obu_forbidden_bit = 0;
318  RCHECK(reader->ReadBits(1, &obu_forbidden_bit));
319  RCHECK(obu_forbidden_bit == 0);
320  RCHECK(reader->ReadBits(4, &obu_header->obu_type));
321  bool obu_extension_flag = false;
322  RCHECK(reader->ReadBits(1, &obu_extension_flag));
323  RCHECK(reader->ReadBits(1, &obu_header->obu_has_size_field));
324  RCHECK(reader->SkipBits(1)); // Skip obu_reserved_1bit.
325 
326  if (obu_extension_flag)
327  RCHECK(ParseObuExtensionHeader(reader, &obu_header->extension_header));
328 
329  return true;
330 }
331 
332 // 5.3.3. OBU extension header syntax.
333 bool AV1Parser::ParseObuExtensionHeader(
334  BitReader* reader,
335  ObuExtensionHeader* obu_extension_header) {
336  RCHECK(reader->ReadBits(3, &obu_extension_header->temporal_id));
337  RCHECK(reader->ReadBits(2, &obu_extension_header->spatial_id));
338  RCHECK(reader->SkipBits(3)); // Skip extension_header_reserved_3bits.
339  return true;
340 }
341 
342 // 5.3.4. Trailing bits syntax.
343 bool AV1Parser::ParseTrailingBits(size_t nb_bits, BitReader* reader) {
344  int trailing_one_bit = 0;
345  RCHECK(reader->ReadBits(1, &trailing_one_bit));
346  RCHECK(trailing_one_bit == 1);
347  nb_bits--;
348  while (nb_bits > 0) {
349  int trailing_zero_bit = 0;
350  RCHECK(reader->ReadBits(1, &trailing_zero_bit));
351  RCHECK(trailing_zero_bit == 0);
352  nb_bits--;
353  }
354  return true;
355 }
356 
357 bool AV1Parser::ByteAlignment(BitReader* reader) {
358  while (reader->bit_position() & 7) {
359  int zero_bit = 0;
360  RCHECK(reader->ReadBits(1, &zero_bit));
361  RCHECK(zero_bit == 0);
362  }
363  return true;
364 }
365 
366 // 5.5.1. General sequence header OBU syntax.
367 bool AV1Parser::ParseSequenceHeaderObu(BitReader* reader) {
368  RCHECK(reader->ReadBits(3, &sequence_header_.seq_profile));
369  // Skip still_picture.
370  RCHECK(reader->SkipBits(1));
371 
372  RCHECK(reader->ReadBits(1, &sequence_header_.reduced_still_picture_header));
373  if (sequence_header_.reduced_still_picture_header) {
374  sequence_header_.decoder_model_info_present_flag = false;
375  sequence_header_.operating_points_cnt_minus_1 = 0;
376  sequence_header_.operating_point_idc[0] = 0;
377  // Skip seq_level_idx[0].
378  RCHECK(reader->SkipBits(5));
379  sequence_header_.decoder_model_present_for_this_op[0] = false;
380  } else {
381  bool timing_info_present_flag = false;
382  RCHECK(reader->ReadBits(1, &timing_info_present_flag));
383 
384  bool decoder_model_info_present_flag = false;
385  if (timing_info_present_flag) {
386  RCHECK(ParseTimingInfo(reader));
387  RCHECK(reader->ReadBits(1, &decoder_model_info_present_flag));
388  if (decoder_model_info_present_flag)
389  RCHECK(ParseDecoderModelInfo(reader));
390  }
391  sequence_header_.decoder_model_info_present_flag =
392  decoder_model_info_present_flag;
393 
394  bool initial_display_delay_present_flag = false;
395  RCHECK(reader->ReadBits(1, &initial_display_delay_present_flag));
396 
397  RCHECK(reader->ReadBits(5, &sequence_header_.operating_points_cnt_minus_1));
398  for (int i = 0; i <= sequence_header_.operating_points_cnt_minus_1; i++) {
399  RCHECK(reader->ReadBits(12, &sequence_header_.operating_point_idc[i]));
400  int seq_level_idx_i = 0;
401  RCHECK(reader->ReadBits(5, &seq_level_idx_i));
402  if (seq_level_idx_i > 7) {
403  // Skip seq_tier[i].
404  RCHECK(reader->SkipBits(1));
405  }
406 
407  if (sequence_header_.decoder_model_info_present_flag) {
408  RCHECK(reader->ReadBits(
409  1, &sequence_header_.decoder_model_present_for_this_op[i]));
410  if (sequence_header_.decoder_model_present_for_this_op[i]) {
411  RCHECK(SkipOperatingParametersInfo(reader));
412  }
413  } else {
414  sequence_header_.decoder_model_present_for_this_op[i] = false;
415  }
416 
417  if (initial_display_delay_present_flag) {
418  // Skip initial_display_delay_present_for_this_op[i],
419  // initial_display_delay_minus_1[i].
420  RCHECK(reader->SkipBitsConditional(true, 4));
421  }
422  }
423  }
424 
425  RCHECK(reader->ReadBits(4, &sequence_header_.frame_width_bits_minus_1));
426  RCHECK(reader->ReadBits(4, &sequence_header_.frame_height_bits_minus_1));
427  RCHECK(reader->ReadBits(sequence_header_.frame_width_bits_minus_1 + 1,
428  &sequence_header_.max_frame_width_minus_1));
429  RCHECK(reader->ReadBits(sequence_header_.frame_height_bits_minus_1 + 1,
430  &sequence_header_.max_frame_height_minus_1));
431 
432  if (sequence_header_.reduced_still_picture_header) {
433  sequence_header_.frame_id_numbers_present_flag = false;
434  } else {
435  RCHECK(
436  reader->ReadBits(1, &sequence_header_.frame_id_numbers_present_flag));
437  }
438  if (sequence_header_.frame_id_numbers_present_flag) {
439  RCHECK(
440  reader->ReadBits(4, &sequence_header_.delta_frame_id_length_minus_2));
441  RCHECK(reader->ReadBits(
442  3, &sequence_header_.additional_frame_id_length_minus_1));
443  }
444 
445  RCHECK(reader->ReadBits(1, &sequence_header_.use_128x128_superblock));
446  // Skip enable_filter_intra, enable_intra_edge_filter.
447  RCHECK(reader->SkipBits(1 + 1));
448 
449  if (sequence_header_.reduced_still_picture_header) {
450  sequence_header_.enable_warped_motion = false;
451  sequence_header_.enable_order_hint = false;
452  sequence_header_.enable_ref_frame_mvs = false;
453  sequence_header_.order_hint_bits = 0;
454  sequence_header_.seq_force_screen_content_tools = kSelectScreenContentTools;
455  sequence_header_.seq_force_integer_mv = kSelectIntegerMv;
456  } else {
457  // Skip enable_interintra_compound, enable_masked_compound,
458  RCHECK(reader->SkipBits(1 + 1));
459 
460  RCHECK(reader->ReadBits(1, &sequence_header_.enable_warped_motion));
461  RCHECK(reader->SkipBits(1)); // Skip enable_dual_filter.
462  RCHECK(reader->ReadBits(1, &sequence_header_.enable_order_hint));
463  if (sequence_header_.enable_order_hint) {
464  // Skip enable_jnt_comp.
465  RCHECK(reader->SkipBits(1));
466  RCHECK(reader->ReadBits(1, &sequence_header_.enable_ref_frame_mvs));
467  } else {
468  sequence_header_.enable_ref_frame_mvs = false;
469  }
470 
471  bool seq_choose_screen_content_tools = false;
472  RCHECK(reader->ReadBits(1, &seq_choose_screen_content_tools));
473 
474  if (seq_choose_screen_content_tools) {
475  sequence_header_.seq_force_screen_content_tools =
476  kSelectScreenContentTools;
477  } else {
478  RCHECK(reader->ReadBits(
479  1, &sequence_header_.seq_force_screen_content_tools));
480  }
481 
482  if (sequence_header_.seq_force_screen_content_tools > 0) {
483  bool seq_choose_integer_mv = false;
484  RCHECK(reader->ReadBits(1, &seq_choose_integer_mv));
485  if (seq_choose_integer_mv)
486  sequence_header_.seq_force_integer_mv = kSelectIntegerMv;
487  else
488  RCHECK(reader->ReadBits(1, &sequence_header_.seq_force_integer_mv));
489  } else {
490  sequence_header_.seq_force_integer_mv = kSelectIntegerMv;
491  }
492 
493  if (sequence_header_.enable_order_hint) {
494  int order_hint_bits_minus_1 = 0;
495  RCHECK(reader->ReadBits(3, &order_hint_bits_minus_1));
496  sequence_header_.order_hint_bits = order_hint_bits_minus_1 + 1;
497  } else {
498  sequence_header_.order_hint_bits = 0;
499  }
500  }
501 
502  RCHECK(reader->ReadBits(1, &sequence_header_.enable_superres));
503  RCHECK(reader->ReadBits(1, &sequence_header_.enable_cdef));
504  RCHECK(reader->ReadBits(1, &sequence_header_.enable_restoration));
505  RCHECK(ParseColorConfig(reader));
506  RCHECK(reader->ReadBits(1, &sequence_header_.film_grain_params_present));
507  return true;
508 }
509 
510 // 5.5.2. Color config syntax.
511 bool AV1Parser::ParseColorConfig(BitReader* reader) {
512  ColorConfig& color_config = sequence_header_.color_config;
513 
514  bool high_bitdepth = false;
515  RCHECK(reader->ReadBits(1, &high_bitdepth));
516  if (sequence_header_.seq_profile == 2 && high_bitdepth) {
517  bool twelve_bit = false;
518  RCHECK(reader->ReadBits(1, &twelve_bit));
519  color_config.bit_depth = twelve_bit ? 12 : 10;
520  } else if (sequence_header_.seq_profile <= 2) {
521  color_config.bit_depth = high_bitdepth ? 10 : 8;
522  }
523 
524  if (sequence_header_.seq_profile == 1)
525  color_config.mono_chrome = 0;
526  else
527  RCHECK(reader->ReadBits(1, &color_config.mono_chrome));
528  color_config.num_planes = color_config.mono_chrome ? 1 : 3;
529 
530  bool color_description_present_flag = false;
531  RCHECK(reader->ReadBits(1, &color_description_present_flag));
532 
533  if (color_description_present_flag) {
534  RCHECK(reader->ReadBits(8, &color_config.color_primaries));
535  RCHECK(reader->ReadBits(8, &color_config.transfer_chracteristics));
536  RCHECK(reader->ReadBits(8, &color_config.matrix_coefficients));
537  } else {
538  color_config.color_primaries = CP_UNSPECIFIED;
539  color_config.transfer_chracteristics = TC_UNSPECIFIED;
540  color_config.matrix_coefficients = MC_UNSPECIFIED;
541  }
542 
543  if (color_config.mono_chrome) {
544  RCHECK(reader->ReadBits(1, &color_config.color_range));
545  color_config.subsampling_x = true;
546  color_config.subsampling_y = true;
547  color_config.chroma_sampling_position = CSP_UNKNOWN;
548  color_config.separate_uv_delta_q = false;
549  return true;
550  } else if (color_config.color_primaries == CP_BT_709 &&
551  color_config.transfer_chracteristics == TC_SRGB &&
552  color_config.matrix_coefficients == MC_IDENTITY) {
553  color_config.color_range = true;
554  color_config.subsampling_x = false;
555  color_config.subsampling_y = false;
556  } else {
557  RCHECK(reader->ReadBits(1, &color_config.color_range));
558  if (sequence_header_.seq_profile == 0) {
559  color_config.subsampling_x = true;
560  color_config.subsampling_y = true;
561  } else if (sequence_header_.seq_profile == 1) {
562  color_config.subsampling_x = false;
563  color_config.subsampling_y = false;
564  } else {
565  if (color_config.bit_depth == 12) {
566  RCHECK(reader->ReadBits(1, &color_config.subsampling_x));
567  if (color_config.subsampling_x)
568  RCHECK(reader->ReadBits(1, &color_config.subsampling_y));
569  else
570  color_config.subsampling_y = false;
571  } else {
572  color_config.subsampling_x = true;
573  color_config.subsampling_y = false;
574  }
575  }
576 
577  if (color_config.subsampling_x && color_config.subsampling_y)
578  RCHECK(reader->ReadBits(2, &color_config.chroma_sampling_position));
579  }
580 
581  RCHECK(reader->ReadBits(1, &color_config.separate_uv_delta_q));
582  return true;
583 }
584 
585 // 5.5.3.Timing info syntax.
586 bool AV1Parser::ParseTimingInfo(BitReader* reader) {
587  // Skip num_units_in_display_tick, time_scale.
588  RCHECK(reader->SkipBits(32 + 32));
589  bool equal_picture_interval = false;
590  RCHECK(reader->ReadBits(1, &equal_picture_interval));
591  sequence_header_.timing_info.equal_picture_interval = equal_picture_interval;
592  if (equal_picture_interval) {
593  uint32_t num_ticks_per_picture_minus_1 = 0;
594  RCHECK(ReadUvlc(reader, &num_ticks_per_picture_minus_1));
595  }
596  return true;
597 }
598 
599 // 5.5.4. Decoder model info syntax.
600 bool AV1Parser::ParseDecoderModelInfo(BitReader* reader) {
601  DecoderModelInfo& decoder_model_info = sequence_header_.decoder_model_info;
602 
603  RCHECK(reader->ReadBits(5, &decoder_model_info.buffer_delay_length_minus_1));
604  // Skip num_units_in_decoding_tick.
605  RCHECK(reader->SkipBits(32));
606  RCHECK(reader->ReadBits(
607  5, &decoder_model_info.buffer_removal_time_length_minus_1));
608  RCHECK(reader->ReadBits(
609  5, &decoder_model_info.frame_presentation_time_length_minus_1));
610  return true;
611 }
612 
613 // 5.5.5. Operating parameters info syntax.
614 bool AV1Parser::SkipOperatingParametersInfo(BitReader* reader) {
615  const int n =
616  sequence_header_.decoder_model_info.buffer_delay_length_minus_1 + 1;
617  // Skip decoder_buffer_delay[op], encoder_buffer_delay[op],
618  // low_delay_mode_flag[op].
619  RCHECK(reader->SkipBits(n + n + 1));
620  return true;
621 }
622 
623 // 5.9.1. General frame header OBU syntax.
624 bool AV1Parser::ParseFrameHeaderObu(const ObuHeader& obu_header,
625  BitReader* reader) {
626  if (frame_header_.seen_frame_header)
627  return true;
628 
629  frame_header_.seen_frame_header = true;
630  RCHECK(ParseUncompressedHeader(obu_header, reader));
631  if (frame_header_.show_existing_frame) {
632  DecodeFrameWrapup();
633  frame_header_.seen_frame_header = false;
634  } else {
635  frame_header_.seen_frame_header = true;
636  }
637  return true;
638 }
639 
640 // 5.9.2. Uncompressed header syntax.
641 bool AV1Parser::ParseUncompressedHeader(const ObuHeader& obu_header,
642  BitReader* reader) {
643  int id_len = 0;
644  if (sequence_header_.frame_id_numbers_present_flag) {
645  id_len = sequence_header_.additional_frame_id_length_minus_1 + 1 +
646  sequence_header_.delta_frame_id_length_minus_2 + 2;
647  }
648 
649  bool frame_is_intra = false;
650  bool show_frame = false;
651  bool showable_frame = false;
652  bool error_resilient_mode = false;
653 
654  if (sequence_header_.reduced_still_picture_header) {
655  frame_header_.show_existing_frame = false;
656  frame_header_.frame_type = KEY_FRAME;
657  frame_is_intra = true;
658  show_frame = true;
659  showable_frame = false;
660  } else {
661  RCHECK(reader->ReadBits(1, &frame_header_.show_existing_frame));
662  if (frame_header_.show_existing_frame) {
663  RCHECK(reader->ReadBits(3, &frame_header_.frame_to_show_map_idx));
664  if (sequence_header_.decoder_model_info_present_flag &&
665  !sequence_header_.timing_info.equal_picture_interval) {
666  RCHECK(SkipTemporalPointInfo(reader));
667  }
668  frame_header_.refresh_frame_flags = 0;
669  if (sequence_header_.frame_id_numbers_present_flag) {
670  // Skip display_frame_id.
671  RCHECK(reader->SkipBits(id_len));
672  }
673  frame_header_.frame_type =
674  reference_frames_[frame_header_.frame_to_show_map_idx].frame_type;
675  if (frame_header_.frame_type == KEY_FRAME) {
676  frame_header_.refresh_frame_flags = kAllFrames;
677  }
678  return true;
679  }
680 
681  RCHECK(reader->ReadBits(2, &frame_header_.frame_type));
682  frame_is_intra = frame_header_.frame_type == INTRA_ONLY_FRAME ||
683  frame_header_.frame_type == KEY_FRAME;
684  RCHECK(reader->ReadBits(1, &show_frame));
685  if (show_frame && sequence_header_.decoder_model_info_present_flag &&
686  !sequence_header_.timing_info.equal_picture_interval) {
687  RCHECK(SkipTemporalPointInfo(reader));
688  }
689  if (show_frame)
690  showable_frame = frame_header_.frame_type != KEY_FRAME;
691  else
692  RCHECK(reader->ReadBits(1, &showable_frame));
693 
694  if (frame_header_.frame_type == SWITCH_FRAME ||
695  (frame_header_.frame_type == KEY_FRAME && show_frame)) {
696  error_resilient_mode = true;
697  } else {
698  RCHECK(reader->ReadBits(1, &error_resilient_mode));
699  }
700  }
701 
702  if (frame_header_.frame_type == KEY_FRAME && show_frame) {
703  for (int i = 0; i < kNumRefFrames; i++) {
704  reference_frames_[i].order_hint = 0;
705  }
706  }
707 
708  bool disable_cdf_update = false;
709  RCHECK(reader->ReadBits(1, &disable_cdf_update));
710 
711  bool allow_screen_content_tools = false;
712  if (sequence_header_.seq_force_screen_content_tools ==
713  kSelectScreenContentTools) {
714  RCHECK(reader->ReadBits(1, &allow_screen_content_tools));
715  } else {
716  allow_screen_content_tools =
717  sequence_header_.seq_force_screen_content_tools != 0;
718  }
719 
720  int force_integer_mv = 0;
721  if (allow_screen_content_tools) {
722  if (sequence_header_.seq_force_integer_mv == kSelectIntegerMv)
723  RCHECK(reader->ReadBits(1, &force_integer_mv));
724  else
725  force_integer_mv = sequence_header_.seq_force_integer_mv;
726  }
727  if (frame_is_intra)
728  force_integer_mv = 1;
729 
730  if (sequence_header_.frame_id_numbers_present_flag) {
731  // Skip current_frame_id.
732  RCHECK(reader->SkipBits(id_len));
733  }
734 
735  bool frame_size_override_flag = false;
736  if (frame_header_.frame_type == SWITCH_FRAME)
737  frame_size_override_flag = true;
738  else if (sequence_header_.reduced_still_picture_header)
739  frame_size_override_flag = false;
740  else
741  RCHECK(reader->ReadBits(1, &frame_size_override_flag));
742 
743  RCHECK(reader->ReadBits(sequence_header_.order_hint_bits,
744  &frame_header_.order_hint));
745  int primary_ref_frame = 0;
746  if (frame_is_intra || error_resilient_mode) {
747  primary_ref_frame = kPrimaryRefNone;
748  } else {
749  RCHECK(reader->ReadBits(3, &primary_ref_frame));
750  }
751  if (sequence_header_.decoder_model_info_present_flag) {
752  bool buffer_removal_time_present_flag = false;
753  RCHECK(reader->ReadBits(1, &buffer_removal_time_present_flag));
754  if (buffer_removal_time_present_flag) {
755  for (int op_num = 0;
756  op_num <= sequence_header_.operating_points_cnt_minus_1; op_num++) {
757  if (sequence_header_.decoder_model_present_for_this_op[op_num]) {
758  const int op_pt_idc = sequence_header_.operating_point_idc[op_num];
759  const int in_temporal_layer =
760  (op_pt_idc >> obu_header.extension_header.temporal_id) & 1;
761  const int in_spatial_layer =
762  (op_pt_idc >> (obu_header.extension_header.spatial_id + 8)) & 1;
763  if (op_pt_idc == 0 || (in_temporal_layer && in_spatial_layer)) {
764  // Skip buffer_removal_time[ opNum ].
765  RCHECK(reader->SkipBits(sequence_header_.decoder_model_info
766  .buffer_removal_time_length_minus_1 +
767  1));
768  }
769  }
770  }
771  }
772  }
773 
774  bool allow_high_precision_mv = false;
775  bool allow_intrabc = false;
776 
777  if (frame_header_.frame_type == SWITCH_FRAME ||
778  (frame_header_.frame_type == KEY_FRAME && show_frame)) {
779  frame_header_.refresh_frame_flags = kAllFrames;
780  } else {
781  RCHECK(reader->ReadBits(8, &frame_header_.refresh_frame_flags));
782  }
783  if (!frame_is_intra || frame_header_.refresh_frame_flags != kAllFrames) {
784  if (error_resilient_mode && sequence_header_.enable_order_hint) {
785  for (int i = 0; i < kNumRefFrames; i++) {
786  // Skip ref_order_hint[ i ].
787  RCHECK(reader->SkipBits(sequence_header_.order_hint_bits));
788  }
789  }
790  }
791 
792  if (frame_is_intra) {
793  RCHECK(ParseFrameSize(frame_size_override_flag, reader));
794  RCHECK(ParseRenderSize(reader));
795  if (allow_screen_content_tools &&
796  frame_header_.upscaled_width == frame_header_.frame_width)
797  RCHECK(reader->ReadBits(1, &allow_intrabc));
798  } else {
799  bool frame_refs_short_signaling = false;
800  if (sequence_header_.enable_order_hint) {
801  RCHECK(reader->ReadBits(1, &frame_refs_short_signaling));
802  if (frame_refs_short_signaling) {
803  int last_frame_idx = 0;
804  RCHECK(reader->ReadBits(3, &last_frame_idx));
805  int gold_frame_idx = 0;
806  RCHECK(reader->ReadBits(3, &gold_frame_idx));
807  RCHECK(SetFrameRefs(last_frame_idx, gold_frame_idx));
808  }
809  }
810  for (int i = 0; i < kRefsPerFrame; i++) {
811  if (!frame_refs_short_signaling)
812  RCHECK(reader->ReadBits(3, &frame_header_.ref_frame_idx[i]));
813  if (sequence_header_.frame_id_numbers_present_flag) {
814  // Skip delta_frame_id_minus_1.
815  RCHECK(reader->SkipBits(sequence_header_.delta_frame_id_length_minus_2 +
816  2));
817  }
818  }
819  if (frame_size_override_flag && !error_resilient_mode) {
820  RCHECK(ParseFrameSizeWithRefs(frame_size_override_flag, reader));
821  } else {
822  RCHECK(ParseFrameSize(frame_size_override_flag, reader));
823  RCHECK(ParseRenderSize(reader));
824  }
825 
826  if (force_integer_mv)
827  allow_high_precision_mv = false;
828  else
829  RCHECK(reader->ReadBits(1, &allow_high_precision_mv));
830 
831  RCHECK(SkipInterpolationFilter(reader));
832  // Skip is_motion_mode_switchable.
833  RCHECK(reader->SkipBits(1));
834  if (!error_resilient_mode && sequence_header_.enable_ref_frame_mvs) {
835  // Skip use_ref_frame_mvs.
836  RCHECK(reader->SkipBits(1));
837  }
838  }
839 
840  if (!sequence_header_.reduced_still_picture_header && !disable_cdf_update) {
841  // Skip disable_frame_end_update_cdf.
842  RCHECK(reader->SkipBits(1));
843  }
844 
845  RCHECK(ParseTileInfo(reader));
846  RCHECK(ParseQuantizationParams(reader));
847  RCHECK(ParseSegmentationParams(primary_ref_frame, reader));
848 
849  bool delta_q_present = false;
850  RCHECK(SkipDeltaQParams(reader, &delta_q_present));
851  RCHECK(SkipDeltaLfParams(delta_q_present, allow_intrabc, reader));
852 
853  const auto& quantization_params = frame_header_.quantization_params;
854  bool coded_lossless = true;
855  for (int segment_id = 0; segment_id < kMaxSegments; segment_id++) {
856  const int qindex = GetQIndex(true, segment_id);
857  const bool lossless = qindex == 0 && quantization_params.delta_qydc == 0 &&
858  quantization_params.delta_quac == 0 &&
859  quantization_params.delta_qudc == 0 &&
860  quantization_params.delta_qvac == 0 &&
861  quantization_params.delta_qvdc == 0;
862  if (!lossless)
863  coded_lossless = false;
864  }
865  const bool all_lossless = coded_lossless && (frame_header_.frame_width ==
866  frame_header_.upscaled_width);
867 
868  RCHECK(ParseLoopFilterParams(coded_lossless, allow_intrabc, reader));
869  RCHECK(ParseCdefParams(coded_lossless, allow_intrabc, reader));
870  RCHECK(ParseLrParams(all_lossless, allow_intrabc, reader));
871  RCHECK(SkipTxMode(coded_lossless, reader));
872  bool reference_select = false;
873  RCHECK(ParseFrameReferenceMode(frame_is_intra, reader, &reference_select));
874  RCHECK(SkipSkipModeParams(frame_is_intra, reference_select, reader));
875 
876  bool allow_warped_motion = false;
877  if (frame_is_intra || error_resilient_mode ||
878  !sequence_header_.enable_warped_motion) {
879  allow_warped_motion = false;
880  } else {
881  RCHECK(reader->ReadBits(1, &allow_warped_motion));
882  }
883  // Skip reduced_tx_set.
884  RCHECK(reader->SkipBits(1));
885 
886  RCHECK(
887  SkipGlobalMotionParams(frame_is_intra, allow_high_precision_mv, reader));
888  RCHECK(SkipFilmGrainParams(show_frame, showable_frame, reader));
889  return true;
890 }
891 
892 // 5.9.3. Get relative distance function.
893 int AV1Parser::GetRelativeDist(int a, int b) {
894  if (!sequence_header_.enable_order_hint)
895  return 0;
896  int diff = a - b;
897  const int m = 1 << (sequence_header_.order_hint_bits - 1);
898  diff = (diff & (m - 1)) - (diff & m);
899  return diff;
900 }
901 
902 // 5.9.5. Frame size syntax.
903 bool AV1Parser::ParseFrameSize(bool frame_size_override_flag,
904  BitReader* reader) {
905  if (frame_size_override_flag) {
906  int frame_width_minus_1 = 0;
907  RCHECK(reader->ReadBits(sequence_header_.frame_width_bits_minus_1 + 1,
908  &frame_width_minus_1));
909  int frame_height_minus_1 = 0;
910  RCHECK(reader->ReadBits(sequence_header_.frame_height_bits_minus_1 + 1,
911  &frame_height_minus_1));
912  frame_header_.frame_width = frame_width_minus_1 + 1;
913  frame_header_.frame_height = frame_height_minus_1 + 1;
914  } else {
915  frame_header_.frame_width = sequence_header_.max_frame_width_minus_1 + 1;
916  frame_header_.frame_height = sequence_header_.max_frame_height_minus_1 + 1;
917  }
918  RCHECK(ParseSuperresParams(reader));
919  ComputeImageSize();
920  return true;
921 }
922 
923 // 5.9.6. Render size syntax.
924 bool AV1Parser::ParseRenderSize(BitReader* reader) {
925  bool render_and_frame_size_different = false;
926  RCHECK(reader->ReadBits(1, &render_and_frame_size_different));
927  if (render_and_frame_size_different) {
928  int render_width_minus_1 = 0;
929  RCHECK(reader->ReadBits(16, &render_width_minus_1));
930  int render_height_minus_1 = 0;
931  RCHECK(reader->ReadBits(16, &render_height_minus_1));
932  frame_header_.render_width = render_width_minus_1 + 1;
933  frame_header_.render_height = render_height_minus_1 + 1;
934  } else {
935  frame_header_.render_width = frame_header_.upscaled_width;
936  frame_header_.render_height = frame_header_.frame_height;
937  }
938  return true;
939 }
940 
941 // 5.9.7. Frame size with refs syntax.
942 bool AV1Parser::ParseFrameSizeWithRefs(bool frame_size_override_flag,
943  BitReader* reader) {
944  bool found_ref = false;
945  for (int i = 0; i < kRefsPerFrame; i++) {
946  RCHECK(reader->ReadBits(1, &found_ref));
947  if (found_ref) {
948  const ReferenceFrame& reference_frame =
949  reference_frames_[frame_header_.ref_frame_idx[i]];
950  frame_header_.upscaled_width = reference_frame.upscaled_width;
951  frame_header_.frame_width = frame_header_.upscaled_width;
952  frame_header_.frame_height = reference_frame.frame_height;
953  frame_header_.render_width = reference_frame.render_width;
954  frame_header_.render_height = reference_frame.render_height;
955  break;
956  }
957  }
958  if (!found_ref) {
959  RCHECK(ParseFrameSize(frame_size_override_flag, reader));
960  RCHECK(ParseRenderSize(reader));
961  } else {
962  RCHECK(ParseSuperresParams(reader));
963  ComputeImageSize();
964  }
965  return true;
966 }
967 
968 // 5.9.8. Superres params syntax.
969 bool AV1Parser::ParseSuperresParams(BitReader* reader) {
970  const int kSuperresNum = 8;
971  const int kSuperresDenomMin = 9;
972  const int kSuperresDenomBits = 3;
973 
974  bool use_superres = false;
975  if (sequence_header_.enable_superres)
976  RCHECK(reader->ReadBits(1, &use_superres));
977 
978  int superres_denom = 0;
979  if (use_superres) {
980  int coded_denom = 0;
981  RCHECK(reader->ReadBits(kSuperresDenomBits, &coded_denom));
982  superres_denom = coded_denom + kSuperresDenomMin;
983  } else {
984  superres_denom = kSuperresNum;
985  }
986 
987  const int upscaled_width = frame_header_.frame_width;
988  frame_header_.upscaled_width =
989  (upscaled_width * kSuperresNum + superres_denom / 2) / superres_denom;
990  return true;
991 }
992 
993 // 5.9.9. Compute image size function.
994 void AV1Parser::ComputeImageSize() {
995  frame_header_.mi_cols = 2 * ((frame_header_.frame_width + 7) >> 3);
996  frame_header_.mi_rows = 2 * ((frame_header_.frame_height + 7) >> 3);
997 }
998 
999 // 5.9.10. Interpolation filter syntax.
1000 bool AV1Parser::SkipInterpolationFilter(BitReader* reader) {
1001  // SKip is_filter_switchable, interpolation_filter.
1002  RCHECK(reader->SkipBitsConditional(false, 2));
1003  return true;
1004 }
1005 
1006 // 5.9.11. Loop filter parms syntax.
1007 bool AV1Parser::ParseLoopFilterParams(bool coded_lossless,
1008  bool allow_intrabc,
1009  BitReader* reader) {
1010  if (coded_lossless || allow_intrabc)
1011  return true;
1012 
1013  int loop_filter_level[] = {0, 0};
1014  RCHECK(reader->ReadBits(6, &loop_filter_level[0]));
1015  RCHECK(reader->ReadBits(6, &loop_filter_level[1]));
1016  if (sequence_header_.color_config.num_planes > 1) {
1017  if (loop_filter_level[0] || loop_filter_level[1]) {
1018  // Skip loop_filter_level[2], loop_filter_level[3].
1019  RCHECK(reader->SkipBits(6 + 6));
1020  }
1021  }
1022  // Skip loop_filter_sharpness.
1023  RCHECK(reader->SkipBits(3));
1024  bool loop_filter_delta_enabled = false;
1025  RCHECK(reader->ReadBits(1, &loop_filter_delta_enabled));
1026  if (loop_filter_delta_enabled) {
1027  bool loop_filter_delta_update = false;
1028  RCHECK(reader->ReadBits(1, &loop_filter_delta_update));
1029  if (loop_filter_delta_update) {
1030  const int kTotalRefsPerFrame = 8;
1031  for (int i = 0; i < kTotalRefsPerFrame; i++) {
1032  // Skip update_ref_delta, loop_filter_ref_delta[ i ].
1033  RCHECK(reader->SkipBitsConditional(true, 1 + 6));
1034  }
1035  for (int i = 0; i < 2; i++) {
1036  // Skip update_mode_delta, loop_filter_mode_delta[ i ].
1037  RCHECK(reader->SkipBitsConditional(true, 1 + 6));
1038  }
1039  }
1040  }
1041  return true;
1042 }
1043 
1044 // 5.9.12. Quantization params syntax.
1045 bool AV1Parser::ParseQuantizationParams(BitReader* reader) {
1046  QuantizationParams& quantization_params = frame_header_.quantization_params;
1047 
1048  RCHECK(reader->ReadBits(8, &quantization_params.base_q_idx));
1049  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_qydc));
1050 
1051  const ColorConfig& color_config = sequence_header_.color_config;
1052  if (color_config.num_planes > 1) {
1053  bool diff_uv_delta = false;
1054  if (color_config.separate_uv_delta_q)
1055  RCHECK(reader->ReadBits(1, &diff_uv_delta));
1056  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_qudc));
1057  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_quac));
1058  if (diff_uv_delta) {
1059  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_qvdc));
1060  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_qvac));
1061  } else {
1062  quantization_params.delta_qvdc = quantization_params.delta_qudc;
1063  quantization_params.delta_qvac = quantization_params.delta_quac;
1064  }
1065  } else {
1066  quantization_params.delta_qudc = 0;
1067  quantization_params.delta_quac = 0;
1068  quantization_params.delta_qvdc = 0;
1069  quantization_params.delta_qvac = 0;
1070  }
1071  bool using_qmatrix = false;
1072  RCHECK(reader->ReadBits(1, &using_qmatrix));
1073  if (using_qmatrix) {
1074  // Skip qm_y, qm_u.
1075  RCHECK(reader->SkipBits(4 + 4));
1076  if (color_config.separate_uv_delta_q) {
1077  // Skip qm_v.
1078  RCHECK(reader->SkipBits(4));
1079  }
1080  }
1081  return true;
1082 }
1083 
1084 // 5.9.13. Delta quantizer syntax.
1085 bool AV1Parser::ReadDeltaQ(BitReader* reader, int* delta_q) {
1086  bool delta_coded = false;
1087  RCHECK(reader->ReadBits(1, &delta_coded));
1088  if (delta_coded)
1089  RCHECK(ReadSu(1 + 6, reader, delta_q));
1090  else
1091  *delta_q = 0;
1092  return true;
1093 }
1094 
1095 // 5.9.14. Segmentation params syntax.
1096 bool AV1Parser::ParseSegmentationParams(int primary_ref_frame,
1097  BitReader* reader) {
1098  SegmentationParams& segmentation_params = frame_header_.segmentation_params;
1099 
1100  RCHECK(reader->ReadBits(1, &segmentation_params.segmentation_enabled));
1101  if (segmentation_params.segmentation_enabled) {
1102  bool segmentation_update_data = false;
1103  if (primary_ref_frame == kPrimaryRefNone) {
1104  segmentation_update_data = true;
1105  } else {
1106  // Skip segmentation_update_map, segmentation_temporal_update.
1107  RCHECK(reader->SkipBitsConditional(true, 1));
1108  RCHECK(reader->ReadBits(1, &segmentation_update_data));
1109  }
1110  if (segmentation_update_data) {
1111  static const int kSegmentationFeatureBits[kSegLvlMax] = {8, 6, 6, 6,
1112  6, 3, 0, 0};
1113  static const int kSegmentationFeatureSigned[kSegLvlMax] = {1, 1, 1, 1,
1114  1, 0, 0, 0};
1115  const int kMaxLoopFilter = 63;
1116  static const int kSegmentationFeatureMax[kSegLvlMax] = {255,
1117  kMaxLoopFilter,
1118  kMaxLoopFilter,
1119  kMaxLoopFilter,
1120  kMaxLoopFilter,
1121  7,
1122  0,
1123  0};
1124 
1125  for (int i = 0; i < kMaxSegments; i++) {
1126  for (int j = 0; j < kSegLvlMax; j++) {
1127  bool feature_enabled = false;
1128  RCHECK(reader->ReadBits(1, &feature_enabled));
1129  segmentation_params.feature_enabled[i][j] = feature_enabled;
1130  int clipped_value = 0;
1131  if (feature_enabled) {
1132  const int bits_to_read = kSegmentationFeatureBits[j];
1133  const int limit = kSegmentationFeatureMax[j];
1134  if (kSegmentationFeatureSigned[j]) {
1135  int feature_value = 0;
1136  RCHECK(ReadSu(1 + bits_to_read, reader, &feature_value));
1137  clipped_value = Clip3(-limit, limit, feature_value);
1138  } else {
1139  int feature_value = 0;
1140  RCHECK(reader->ReadBits(bits_to_read, &feature_value));
1141  clipped_value = Clip3(0, limit, feature_value);
1142  }
1143  }
1144  segmentation_params.feature_data[i][j] = clipped_value;
1145  }
1146  }
1147  }
1148  } else {
1149  for (int i = 0; i < kMaxSegments; i++) {
1150  for (int j = 0; j < kSegLvlMax; j++) {
1151  segmentation_params.feature_enabled[i][j] = false;
1152  segmentation_params.feature_data[i][j] = 0;
1153  }
1154  }
1155  }
1156  return true;
1157 }
1158 
1159 // 5.9.15. Tile info syntax.
1160 bool AV1Parser::ParseTileInfo(BitReader* reader) {
1161  const int kMaxTileWidth = 4096;
1162  const int kMaxTileArea = 4096 * 2304;
1163  const int kMaxTileRows = 64;
1164  const int kMaxTileCols = 64;
1165 
1166  TileInfo& tile_info = frame_header_.tile_info;
1167 
1168  const int sb_cols = sequence_header_.use_128x128_superblock
1169  ? ((frame_header_.mi_cols + 31) >> 5)
1170  : ((frame_header_.mi_cols + 15) >> 4);
1171  const int sb_rows = sequence_header_.use_128x128_superblock
1172  ? ((frame_header_.mi_rows + 31) >> 5)
1173  : ((frame_header_.mi_rows + 15) >> 4);
1174  const int sb_shift = sequence_header_.use_128x128_superblock ? 5 : 4;
1175  const int sb_size = sb_shift + 2;
1176  const int max_tile_width_sb = kMaxTileWidth >> sb_size;
1177  int max_tile_area_sb = kMaxTileArea >> (2 * sb_size);
1178  const int min_log2_tile_cols = TileLog2(max_tile_width_sb, sb_cols);
1179  const int max_log2_tile_cols = TileLog2(1, std::min(sb_cols, kMaxTileCols));
1180  const int max_log2_tile_rows = TileLog2(1, std::min(sb_rows, kMaxTileRows));
1181  const int min_log2_tiles = std::max(
1182  min_log2_tile_cols, TileLog2(max_tile_area_sb, sb_rows * sb_cols));
1183 
1184  bool uniform_tile_spacing_flag = false;
1185  RCHECK(reader->ReadBits(1, &uniform_tile_spacing_flag));
1186  if (uniform_tile_spacing_flag) {
1187  tile_info.tile_cols_log2 = min_log2_tile_cols;
1188  while (tile_info.tile_cols_log2 < max_log2_tile_cols) {
1189  bool increment_tile_cols_log2 = false;
1190  RCHECK(reader->ReadBits(1, &increment_tile_cols_log2));
1191  if (increment_tile_cols_log2)
1192  tile_info.tile_cols_log2++;
1193  else
1194  break;
1195  }
1196  const int tile_width_sb = (sb_cols + (1 << tile_info.tile_cols_log2) - 1) >>
1197  tile_info.tile_cols_log2;
1198  int i = 0;
1199  for (int start_sb = 0; start_sb < sb_cols; start_sb += tile_width_sb) {
1200  i += 1;
1201  }
1202  tile_info.tile_cols = i;
1203 
1204  const int min_log2_tile_rows =
1205  std::max(min_log2_tiles - tile_info.tile_cols_log2, 0);
1206  tile_info.tile_rows_log2 = min_log2_tile_rows;
1207  while (tile_info.tile_rows_log2 < max_log2_tile_rows) {
1208  bool increment_tile_rows_log2 = false;
1209  RCHECK(reader->ReadBits(1, &increment_tile_rows_log2));
1210  if (increment_tile_rows_log2)
1211  tile_info.tile_rows_log2++;
1212  else
1213  break;
1214  }
1215  const int tile_height_sb =
1216  (sb_rows + (1 << tile_info.tile_rows_log2) - 1) >>
1217  tile_info.tile_rows_log2;
1218  i = 0;
1219  for (int start_sb = 0; start_sb < sb_rows; start_sb += tile_height_sb) {
1220  i += 1;
1221  }
1222  tile_info.tile_rows = i;
1223  } else {
1224  int widest_tile_sb = 0;
1225  int start_sb = 0;
1226  int i = 0;
1227  for (; start_sb < sb_cols; i++) {
1228  const int max_width = std::min(sb_cols - start_sb, max_tile_width_sb);
1229  int width_in_sbs_minus_1 = 0;
1230  RCHECK(ReadNs(max_width, reader, &width_in_sbs_minus_1));
1231  const int size_sb = width_in_sbs_minus_1 + 1;
1232  widest_tile_sb = std::max(size_sb, widest_tile_sb);
1233  start_sb += size_sb;
1234  }
1235  tile_info.tile_cols = i;
1236  tile_info.tile_cols_log2 = TileLog2(1, tile_info.tile_cols);
1237 
1238  if (min_log2_tiles > 0)
1239  max_tile_area_sb = (sb_rows * sb_cols) >> (min_log2_tiles + 1);
1240  else
1241  max_tile_area_sb = sb_rows * sb_cols;
1242  const int max_tile_height_sb =
1243  std::max(max_tile_area_sb / widest_tile_sb, 1);
1244 
1245  start_sb = 0;
1246  i = 0;
1247  for (; start_sb < sb_rows; i++) {
1248  const int max_height = std::min(sb_rows - start_sb, max_tile_height_sb);
1249  int height_in_sbs_minus_1 = 0;
1250  RCHECK(ReadNs(max_height, reader, &height_in_sbs_minus_1));
1251  const int size_sb = height_in_sbs_minus_1 + 1;
1252  start_sb += size_sb;
1253  }
1254  tile_info.tile_rows = i;
1255  tile_info.tile_rows_log2 = TileLog2(1, tile_info.tile_rows);
1256  }
1257  if (tile_info.tile_cols_log2 > 0 || tile_info.tile_rows_log2 > 0) {
1258  // Skip context_update_tile_id.
1259  RCHECK(
1260  reader->SkipBits(tile_info.tile_rows_log2 + tile_info.tile_cols_log2));
1261  int tile_size_bytes_minus_1 = 0;
1262  RCHECK(reader->ReadBits(2, &tile_size_bytes_minus_1));
1263  tile_info.tile_size_bytes = tile_size_bytes_minus_1 + 1;
1264  }
1265  return true;
1266 }
1267 
1268 // 5.9.17. Quantizer index delta parameters syntax.
1269 bool AV1Parser::SkipDeltaQParams(BitReader* reader, bool* delta_q_present) {
1270  *delta_q_present = false;
1271  if (frame_header_.quantization_params.base_q_idx > 0)
1272  RCHECK(reader->ReadBits(1, delta_q_present));
1273  if (*delta_q_present) {
1274  // Skip delta_q_res.
1275  RCHECK(reader->SkipBits(2));
1276  }
1277  return true;
1278 }
1279 
1280 // 5.9.18. Loop filter delta parameters syntax.
1281 bool AV1Parser::SkipDeltaLfParams(bool delta_q_present,
1282  bool allow_intrabc,
1283  BitReader* reader) {
1284  bool delta_lf_present = false;
1285  if (delta_q_present) {
1286  if (!allow_intrabc)
1287  RCHECK(reader->ReadBits(1, &delta_lf_present));
1288  if (delta_lf_present) {
1289  // Skip delta_lf_res, delta_lf_multi.
1290  RCHECK(reader->SkipBits(2 + 1));
1291  }
1292  }
1293  return true;
1294 }
1295 
1296 // 5.9.19. CDEF params syntax.
1297 bool AV1Parser::ParseCdefParams(bool coded_lossless,
1298  bool allow_intrabc,
1299  BitReader* reader) {
1300  if (coded_lossless || allow_intrabc || !sequence_header_.enable_cdef)
1301  return true;
1302 
1303  // Skip cdef_damping_minus_3.
1304  RCHECK(reader->SkipBits(2));
1305  int cdef_bits = 0;
1306  RCHECK(reader->ReadBits(2, &cdef_bits));
1307  for (int i = 0; i < (1 << cdef_bits); i++) {
1308  // Skip cdef_y_pri_strength[i], Skip cdef_y_sec_strength[i].
1309  RCHECK(reader->SkipBits(4 + 2));
1310  if (sequence_header_.color_config.num_planes > 1) {
1311  // Skip cdef_uv_pri_strength[i], Skip cdef_uv_sec_strength[i].
1312  RCHECK(reader->SkipBits(4 + 2));
1313  }
1314  }
1315  return true;
1316 }
1317 
1318 // 5.9.20. Loop restoration params syntax.
1319 bool AV1Parser::ParseLrParams(bool all_lossless,
1320  bool allow_intrabc,
1321  BitReader* reader) {
1322  if (all_lossless || allow_intrabc || !sequence_header_.enable_restoration)
1323  return true;
1324 
1325  enum FrameRestorationType {
1326  RESTORE_NONE = 0,
1327  RESTORE_SWITCHABLE = 3,
1328  RESTORE_WIENER = 1,
1329  RESTORE_SGRPROJ = 2,
1330  };
1331  static const int kRemapLrType[4] = {RESTORE_NONE, RESTORE_SWITCHABLE,
1332  RESTORE_WIENER, RESTORE_SGRPROJ};
1333  bool uses_lr = false;
1334  bool uses_chroma_lr = false;
1335  for (int i = 0; i < sequence_header_.color_config.num_planes; i++) {
1336  int lr_type = 0;
1337  RCHECK(reader->ReadBits(2, &lr_type));
1338  const int frame_restoration_type = kRemapLrType[lr_type];
1339  if (frame_restoration_type != RESTORE_NONE) {
1340  uses_lr = true;
1341  if (i > 0)
1342  uses_chroma_lr = true;
1343  }
1344  }
1345 
1346  if (uses_lr) {
1347  if (sequence_header_.use_128x128_superblock) {
1348  // Skip lr_unit_shift.
1349  RCHECK(reader->SkipBits(1));
1350  } else {
1351  // Skip lr_unit_shift, lr_unit_extra_shift.
1352  RCHECK(reader->SkipBitsConditional(true, 1));
1353  }
1354  if (sequence_header_.color_config.subsampling_x &&
1355  sequence_header_.color_config.subsampling_y && uses_chroma_lr) {
1356  // Skip lr_uv_shift.
1357  RCHECK(reader->SkipBits(1));
1358  }
1359  }
1360  return true;
1361 }
1362 
1363 // 5.9.21. TX mode syntax.
1364 bool AV1Parser::SkipTxMode(bool coded_lossless, BitReader* reader) {
1365  if (!coded_lossless) {
1366  // Skip tx_mode_select.
1367  RCHECK(reader->SkipBits(1));
1368  }
1369  return true;
1370 }
1371 
1372 // 5.9.22. Skip mode params syntax.
1373 bool AV1Parser::SkipSkipModeParams(bool frame_is_intra,
1374  bool reference_select,
1375  BitReader* reader) {
1376  bool skip_mode_allowed = false;
1377  if (frame_is_intra || !reference_select ||
1378  !sequence_header_.enable_order_hint) {
1379  skip_mode_allowed = false;
1380  } else {
1381  int forward_idx = -1;
1382  int forward_hint = 0;
1383  int backward_idx = -1;
1384  int backward_hint = 0;
1385  for (int i = 0; i < kRefsPerFrame; i++) {
1386  const int ref_hint =
1387  reference_frames_[frame_header_.ref_frame_idx[i]].order_hint;
1388  if (GetRelativeDist(ref_hint, frame_header_.order_hint) < 0) {
1389  if (forward_idx < 0 || GetRelativeDist(ref_hint, forward_hint) > 0) {
1390  forward_idx = i;
1391  forward_hint = ref_hint;
1392  }
1393  } else if (GetRelativeDist(ref_hint, frame_header_.order_hint) > 0) {
1394  if (backward_idx < 0 || GetRelativeDist(ref_hint, backward_hint) < 0) {
1395  backward_idx = i;
1396  backward_hint = ref_hint;
1397  }
1398  }
1399  }
1400  if (forward_idx < 0) {
1401  skip_mode_allowed = false;
1402  } else if (backward_idx >= 0) {
1403  skip_mode_allowed = true;
1404  } else {
1405  int second_forward_idx = -1;
1406  int second_forward_hint = 0;
1407  for (int i = 0; i < kRefsPerFrame; i++) {
1408  const int ref_hint =
1409  reference_frames_[frame_header_.ref_frame_idx[i]].order_hint;
1410  if (GetRelativeDist(ref_hint, forward_hint) < 0) {
1411  if (second_forward_idx < 0 ||
1412  GetRelativeDist(ref_hint, second_forward_hint) > 0) {
1413  second_forward_idx = i;
1414  second_forward_hint = ref_hint;
1415  }
1416  }
1417  }
1418  skip_mode_allowed = second_forward_idx >= 0;
1419  }
1420  }
1421 
1422  if (skip_mode_allowed) {
1423  // Skip skip_mode_present.
1424  RCHECK(reader->SkipBits(1));
1425  }
1426  return true;
1427 }
1428 
1429 // 5.9.23. Frame reference mode syntax.
1430 bool AV1Parser::ParseFrameReferenceMode(bool frame_is_intra,
1431  BitReader* reader,
1432  bool* reference_select) {
1433  if (frame_is_intra)
1434  *reference_select = false;
1435  else
1436  RCHECK(reader->ReadBits(1, reference_select));
1437  return true;
1438 }
1439 
1440 // 5.9.24. Global motion params syntax.
1441 bool AV1Parser::SkipGlobalMotionParams(bool frame_is_intra,
1442  bool allow_high_precision_mv,
1443  BitReader* reader) {
1444  if (frame_is_intra)
1445  return true;
1446 
1447  for (int ref = LAST_FRAME; ref <= ALTREF_FRAME; ref++) {
1448  int type = 0;
1449 
1450  bool is_global = false;
1451  RCHECK(reader->ReadBits(1, &is_global));
1452  if (is_global) {
1453  bool is_rot_zoom = false;
1454  RCHECK(reader->ReadBits(1, &is_rot_zoom));
1455  if (is_rot_zoom) {
1456  type = ROTZOOM;
1457  } else {
1458  bool is_translation = false;
1459  RCHECK(reader->ReadBits(1, &is_translation));
1460  type = is_translation ? TRANSLATION : AFFINE;
1461  }
1462  } else {
1463  type = IDENTITY;
1464  }
1465 
1466  if (type >= ROTZOOM) {
1467  RCHECK(SkipGlobalParam(type, ref, 2, allow_high_precision_mv, reader));
1468  RCHECK(SkipGlobalParam(type, ref, 3, allow_high_precision_mv, reader));
1469  if (type == AFFINE) {
1470  RCHECK(SkipGlobalParam(type, ref, 4, allow_high_precision_mv, reader));
1471  RCHECK(SkipGlobalParam(type, ref, 5, allow_high_precision_mv, reader));
1472  }
1473  }
1474  if (type >= TRANSLATION) {
1475  RCHECK(SkipGlobalParam(type, ref, 0, allow_high_precision_mv, reader));
1476  RCHECK(SkipGlobalParam(type, ref, 1, allow_high_precision_mv, reader));
1477  }
1478  }
1479  return true;
1480 }
1481 
1482 // 5.9.25. Global param syntax.
1483 bool AV1Parser::SkipGlobalParam(int type,
1484  int ref,
1485  int idx,
1486  bool allow_high_precision_mv,
1487  BitReader* reader) {
1488  const int kGmAbsTransBits = 12;
1489  const int kGmAbsTransOnlyBits = 9;
1490  const int kGmAbsAlphaBits = 12;
1491 
1492  int abs_bits = kGmAbsAlphaBits;
1493  if (idx < 2) {
1494  if (type == TRANSLATION) {
1495  abs_bits = kGmAbsTransOnlyBits - (allow_high_precision_mv ? 0 : 1);
1496  } else {
1497  abs_bits = kGmAbsTransBits;
1498  }
1499  }
1500  const int mx = 1 << abs_bits;
1501  RCHECK(SkipDecodeSignedSubexpWithRef(-mx, mx + 1, reader));
1502  return true;
1503 }
1504 
1505 // 5.9.26. Decode signed subexp with ref syntax.
1506 bool AV1Parser::SkipDecodeSignedSubexpWithRef(int low,
1507  int high,
1508  BitReader* reader) {
1509  RCHECK(SkipDecodeUnsignedSubexpWithRef(high - low, reader));
1510  return true;
1511 }
1512 
1513 // 5.9.27. Decode unsigned subbexp with ref syntax.
1514 bool AV1Parser::SkipDecodeUnsignedSubexpWithRef(int mx, BitReader* reader) {
1515  RCHECK(SkipDecodeSubexp(mx, reader));
1516  return true;
1517 }
1518 
1519 // 5.9.28. Decode subexp syntax.
1520 bool AV1Parser::SkipDecodeSubexp(int num_syms, BitReader* reader) {
1521  int i = 0;
1522  int mk = 0;
1523  int k = 3;
1524  while (true) {
1525  const int b2 = i ? (k + i - 1) : k;
1526  const int a = 1 << b2;
1527  if (num_syms <= mk + 3 * a) {
1528  int subexp_final_bits = 0;
1529  RCHECK(ReadNs(num_syms - mk, reader, &subexp_final_bits));
1530  return true;
1531  } else {
1532  bool subexp_more_bits = false;
1533  RCHECK(reader->ReadBits(1, &subexp_more_bits));
1534  if (subexp_more_bits) {
1535  i++;
1536  mk += a;
1537  } else {
1538  // Skip subexp_bits.
1539  RCHECK(reader->SkipBits(b2));
1540  return true;
1541  }
1542  }
1543  }
1544  return true;
1545 }
1546 
1547 // 5.9.30. Film grain params syntax.
1548 bool AV1Parser::SkipFilmGrainParams(bool show_frame,
1549  bool showable_frame,
1550  BitReader* reader) {
1551  if (!sequence_header_.film_grain_params_present ||
1552  (!show_frame && !showable_frame)) {
1553  return true;
1554  }
1555 
1556  bool apply_grain = false;
1557  RCHECK(reader->ReadBits(1, &apply_grain));
1558  if (!apply_grain)
1559  return true;
1560 
1561  // Skip grain_seed.
1562  RCHECK(reader->SkipBits(16));
1563  bool update_grain = true;
1564  if (frame_header_.frame_type == INTER_FRAME)
1565  RCHECK(reader->ReadBits(1, &update_grain));
1566  if (!update_grain) {
1567  // Skip film_grain_params_ref_idx.
1568  RCHECK(reader->SkipBits(3));
1569  return true;
1570  }
1571 
1572  int num_y_points = 0;
1573  RCHECK(reader->ReadBits(4, &num_y_points));
1574  // Skip point_y_value, point_y_scaling.
1575  RCHECK(reader->SkipBits((8 + 8) * num_y_points));
1576 
1577  const ColorConfig& color_config = sequence_header_.color_config;
1578  bool chroma_scaling_from_luma = false;
1579  if (!color_config.mono_chrome)
1580  RCHECK(reader->ReadBits(1, &chroma_scaling_from_luma));
1581  int num_cb_points = 0;
1582  int num_cr_points = 0;
1583  if (color_config.mono_chrome || chroma_scaling_from_luma ||
1584  (color_config.subsampling_x && color_config.subsampling_y &&
1585  num_y_points == 0)) {
1586  num_cb_points = 0;
1587  num_cr_points = 0;
1588  } else {
1589  RCHECK(reader->ReadBits(4, &num_cb_points));
1590  // Skip point_cb_value, point_cb_scaling.
1591  RCHECK(reader->SkipBits((8 + 8) * num_cb_points));
1592  RCHECK(reader->ReadBits(4, &num_cr_points));
1593  // Skip point_cr_value, point_cr_scaling.
1594  RCHECK(reader->SkipBits((8 + 8) * num_cr_points));
1595  }
1596 
1597  // Skip grain_scaling_minus_8.
1598  RCHECK(reader->SkipBits(2));
1599  int ar_coeff_lag = 0;
1600  RCHECK(reader->ReadBits(2, &ar_coeff_lag));
1601  const int num_pos_luma = 2 * ar_coeff_lag * (ar_coeff_lag + 1);
1602  int num_pos_chroma = num_pos_luma;
1603  if (num_y_points) {
1604  num_pos_chroma = num_pos_luma + 1;
1605  // Skip ar_coeffs_y_plus_128.
1606  RCHECK(reader->SkipBits(8 * num_pos_luma));
1607  }
1608  if (chroma_scaling_from_luma || num_cb_points) {
1609  // Skip ar_coeffs_cb_plus_128.
1610  RCHECK(reader->SkipBits(8 * num_pos_chroma));
1611  }
1612  if (chroma_scaling_from_luma || num_cr_points) {
1613  // Skip ar_coeffs_cb_plus_128.
1614  RCHECK(reader->SkipBits(8 * num_pos_chroma));
1615  }
1616 
1617  // Skip ar_coeff_shift_minus_6, grain_scale_shift.
1618  RCHECK(reader->SkipBits(2 + 2));
1619  if (num_cb_points) {
1620  // Skip cb_mult, cb_luma_mult, cb_offset.
1621  RCHECK(reader->SkipBits(8 + 8 + 9));
1622  }
1623  if (num_cr_points) {
1624  // Skip cr_mult, cr_luma_mult, cr_offset.
1625  RCHECK(reader->SkipBits(8 + 8 + 9));
1626  }
1627  // Skip overlap_flag, clip_restricted_range.
1628  RCHECK(reader->SkipBits(1 + 1));
1629  return true;
1630 }
1631 
1632 // 5.9.31. Temporal point info syntax.
1633 bool AV1Parser::SkipTemporalPointInfo(BitReader* reader) {
1634  const int frame_presentation_time_length =
1635  sequence_header_.decoder_model_info
1636  .frame_presentation_time_length_minus_1 +
1637  1;
1638  // Skip frame_presentation_time.
1639  RCHECK(reader->SkipBits(frame_presentation_time_length));
1640  return true;
1641 }
1642 
1643 // 5.10. Frame OBU syntax.
1644 bool AV1Parser::ParseFrameObu(const ObuHeader& obu_header,
1645  size_t size,
1646  BitReader* reader,
1647  std::vector<Tile>* tiles) {
1648  const size_t start_bit_pos = reader->bit_position();
1649  RCHECK(ParseFrameHeaderObu(obu_header, reader));
1650  RCHECK(ByteAlignment(reader));
1651  const size_t end_bit_pos = reader->bit_position();
1652  const size_t header_bytes = (end_bit_pos - start_bit_pos) / 8;
1653  RCHECK(ParseTileGroupObu(size - header_bytes, reader, tiles));
1654  return true;
1655 }
1656 
1657 // 5.11.1. General tile group OBU syntax.
1658 bool AV1Parser::ParseTileGroupObu(size_t size,
1659  BitReader* reader,
1660  std::vector<Tile>* tiles) {
1661  const TileInfo& tile_info = frame_header_.tile_info;
1662  const size_t start_bit_pos = reader->bit_position();
1663 
1664  const int num_tiles = tile_info.tile_cols * tile_info.tile_rows;
1665  bool tile_start_and_end_present_flag = false;
1666  if (num_tiles > 1)
1667  RCHECK(reader->ReadBits(1, &tile_start_and_end_present_flag));
1668 
1669  int tg_start = 0;
1670  int tg_end = num_tiles - 1;
1671  if (num_tiles > 1 && tile_start_and_end_present_flag) {
1672  const int tile_bits = tile_info.tile_cols_log2 + tile_info.tile_rows_log2;
1673  RCHECK(reader->ReadBits(tile_bits, &tg_start));
1674  RCHECK(reader->ReadBits(tile_bits, &tg_end));
1675  }
1676  RCHECK(ByteAlignment(reader));
1677 
1678  const size_t end_bit_pos = reader->bit_position();
1679  const size_t header_bytes = (end_bit_pos - start_bit_pos) / 8;
1680  size -= header_bytes;
1681 
1682  for (int tile_num = tg_start; tile_num <= tg_end; tile_num++) {
1683  const bool last_tile = tile_num == tg_end;
1684  size_t tile_size = size;
1685  if (!last_tile) {
1686  size_t tile_size_minus_1 = 0;
1687  RCHECK(ReadLe(tile_info.tile_size_bytes, reader, &tile_size_minus_1));
1688  tile_size = tile_size_minus_1 + 1;
1689  size -= tile_size + tile_info.tile_size_bytes;
1690  }
1691  tiles->push_back({reader->bit_position() / 8, tile_size});
1692  RCHECK(reader->SkipBits(tile_size * 8)); // Skip the tile.
1693  }
1694 
1695  if (tg_end == num_tiles - 1) {
1696  DecodeFrameWrapup();
1697  frame_header_.seen_frame_header = false;
1698  }
1699  return true;
1700 }
1701 
1702 // 5.11.14. Segmentation feature active function.
1703 bool AV1Parser::SegFeatureActiveIdx(int idx, int feature) {
1704  const SegmentationParams& segmentation_params =
1705  frame_header_.segmentation_params;
1706  return segmentation_params.segmentation_enabled &&
1707  segmentation_params.feature_enabled[idx][feature];
1708 }
1709 
1710 // 7.4. Decode frame wrapup process.
1711 void AV1Parser::DecodeFrameWrapup() {
1712  const int refresh_frame_flags = frame_header_.refresh_frame_flags;
1713  if (frame_header_.show_existing_frame &&
1714  frame_header_.frame_type == KEY_FRAME) {
1715  // 7.21. Reference frame loading process.
1716  const ReferenceFrame& reference_frame =
1717  reference_frames_[frame_header_.frame_to_show_map_idx];
1718 
1719  frame_header_.upscaled_width = reference_frame.upscaled_width;
1720  frame_header_.frame_width = reference_frame.frame_width;
1721  frame_header_.frame_height = reference_frame.frame_height;
1722  frame_header_.render_width = reference_frame.render_width;
1723  frame_header_.render_height = reference_frame.render_height;
1724  frame_header_.mi_cols = reference_frame.mi_cols;
1725  frame_header_.mi_rows = reference_frame.mi_rows;
1726 
1727  ColorConfig& color_config = sequence_header_.color_config;
1728  color_config.subsampling_x = reference_frame.subsampling_x;
1729  color_config.subsampling_y = reference_frame.subsampling_y;
1730  color_config.bit_depth = reference_frame.bit_depth;
1731 
1732  frame_header_.order_hint = reference_frame.order_hint;
1733  }
1734  // 7.20. Reference frame update process.
1735  for (int i = 0; i <= kNumRefFrames - 1; i++) {
1736  if ((refresh_frame_flags >> i) & 1) {
1737  ReferenceFrame& reference_frame = reference_frames_[i];
1738 
1739  reference_frame.upscaled_width = frame_header_.upscaled_width;
1740  reference_frame.frame_width = frame_header_.frame_width;
1741  reference_frame.frame_height = frame_header_.frame_height;
1742  reference_frame.render_width = frame_header_.render_width;
1743  reference_frame.render_height = frame_header_.render_height;
1744  reference_frame.mi_cols = frame_header_.mi_cols;
1745  reference_frame.mi_rows = frame_header_.mi_rows;
1746  reference_frame.frame_type = frame_header_.frame_type;
1747 
1748  const ColorConfig& color_config = sequence_header_.color_config;
1749  reference_frame.subsampling_x = color_config.subsampling_x;
1750  reference_frame.subsampling_y = color_config.subsampling_y;
1751  reference_frame.bit_depth = color_config.bit_depth;
1752 
1753  reference_frame.order_hint = frame_header_.order_hint;
1754  }
1755  }
1756 }
1757 
1758 // 7.8. Set frame refs process.
1759 bool AV1Parser::SetFrameRefs(int last_frame_idx, int gold_frame_idx) {
1760  for (int i = 0; i < kRefsPerFrame; i++)
1761  frame_header_.ref_frame_idx[i] = -1;
1762  frame_header_.ref_frame_idx[LAST_FRAME - LAST_FRAME] = last_frame_idx;
1763  frame_header_.ref_frame_idx[GOLDEN_FRAME - LAST_FRAME] = gold_frame_idx;
1764 
1765  bool used_frame[kNumRefFrames] = {};
1766  used_frame[last_frame_idx] = true;
1767  used_frame[gold_frame_idx] = true;
1768 
1769  const int cur_frame_hint = 1 << (sequence_header_.order_hint_bits - 1);
1770 
1771  // An array containing the expected output order shifted such that the
1772  // current frame has hint equal to |cur_frame_hint| is prepared.
1773  int shifted_order_hints[kNumRefFrames];
1774  for (int i = 0; i < kNumRefFrames; i++) {
1775  shifted_order_hints[i] =
1776  cur_frame_hint + GetRelativeDist(reference_frames_[i].order_hint,
1777  frame_header_.order_hint);
1778  }
1779 
1780  const int last_order_hint = shifted_order_hints[last_frame_idx];
1781  RCHECK(last_order_hint < cur_frame_hint);
1782  const int gold_order_hint = shifted_order_hints[gold_frame_idx];
1783  RCHECK(gold_order_hint < cur_frame_hint);
1784 
1785  // The ALTREF_FRAME reference is set to be a backward reference to the frame
1786  // with highest output order.
1787  int ref = FindLatestBackward(shifted_order_hints, used_frame, cur_frame_hint);
1788  if (ref >= 0) {
1789  frame_header_.ref_frame_idx[ALTREF_FRAME - LAST_FRAME] = ref;
1790  used_frame[ref] = true;
1791  }
1792 
1793  // The BWDREF_FRAME reference is set to be a backward reference to the cloest
1794  // frame.
1795  ref = FindEarliestBackward(shifted_order_hints, used_frame, cur_frame_hint);
1796  if (ref >= 0) {
1797  frame_header_.ref_frame_idx[BWDREF_FRAME - LAST_FRAME] = ref;
1798  used_frame[ref] = true;
1799  }
1800 
1801  // The ALTREF2_FRAME reference is set to the next closest backward reference.
1802  ref = FindEarliestBackward(shifted_order_hints, used_frame, cur_frame_hint);
1803  if (ref >= 0) {
1804  frame_header_.ref_frame_idx[ALTREF2_FRAME - LAST_FRAME] = ref;
1805  used_frame[ref] = true;
1806  }
1807 
1808  // The remaining references are set to be forward references in
1809  // anti-chronological order.
1810  static const int kRefFrameList[] = {
1811  LAST2_FRAME, LAST3_FRAME, BWDREF_FRAME, ALTREF2_FRAME, ALTREF_FRAME,
1812  };
1813  static_assert(arraysize(kRefFrameList) == kRefsPerFrame - 2,
1814  "Unexpected kRefFrameList size.");
1815  for (const int ref_frame : kRefFrameList) {
1816  if (frame_header_.ref_frame_idx[ref_frame - LAST_FRAME] < 0) {
1817  ref = FindLatestForward(shifted_order_hints, used_frame, cur_frame_hint);
1818  if (ref >= 0) {
1819  frame_header_.ref_frame_idx[ref_frame - LAST_FRAME] = ref;
1820  used_frame[ref] = true;
1821  }
1822  }
1823  }
1824 
1825  // Finally, any remaining references are set to the reference frame with
1826  // smallest output order.
1827  ref = -1;
1828  int earliest_order_hint = 0;
1829  for (int i = 0; i < kNumRefFrames; i++) {
1830  const int hint = shifted_order_hints[i];
1831  if (ref < 0 || hint < earliest_order_hint) {
1832  ref = i;
1833  earliest_order_hint = hint;
1834  }
1835  }
1836  for (int i = 0; i < kRefsPerFrame; i++) {
1837  if (frame_header_.ref_frame_idx[i] < 0) {
1838  frame_header_.ref_frame_idx[i] = ref;
1839  }
1840  }
1841 
1842  return true;
1843 }
1844 
1845 // 7.12.2. Dequantization functions. The function returns the quantizer index
1846 // for the current block.
1847 int AV1Parser::GetQIndex(bool ignore_delta_q, int segment_id) {
1848  // We do not have use case for ignore_delta_q false case.
1849  CHECK(ignore_delta_q) << "ignoreDeltaQ equal to 0 is not supported.";
1850 
1851  const int base_q_idx = frame_header_.quantization_params.base_q_idx;
1852 
1853  const int kSegLvlAltQ = 0;
1854  if (SegFeatureActiveIdx(segment_id, kSegLvlAltQ)) {
1855  const int data =
1856  frame_header_.segmentation_params.feature_data[segment_id][kSegLvlAltQ];
1857  const int qindex = base_q_idx + data;
1858  return Clip3(0, 255, qindex);
1859  } else {
1860  return base_q_idx;
1861  }
1862 }
1863 
1864 } // namespace media
1865 } // namespace shaka
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:35
-
A class to read bit streams.
Definition: bit_reader.h:17
-
bool SkipBitsConditional(bool condition, size_t num_bits)
Definition: bit_reader.h:69
-
All the methods that are virtual are virtual for mocking.
-
size_t bit_position() const
Definition: bit_reader.h:94
-
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
-
size_t bits_available() const
Definition: bit_reader.h:89
-
virtual bool Parse(const uint8_t *data, size_t data_size, std::vector< Tile > *tiles)
Definition: av1_parser.cc:255
+
1 // Copyright 2018 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/av1_parser.h"
+
8 
+
9 #include <algorithm>
+
10 
+
11 #include "packager/base/logging.h"
+
12 #include "packager/media/base/bit_reader.h"
+
13 #include "packager/media/base/rcheck.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 namespace {
+
18 
+
19 // 3. Symbols and abbreviated terms.
+
20 enum MotionType {
+
21  IDENTITY = 0,
+
22  TRANSLATION,
+
23  ROTZOOM,
+
24  AFFINE,
+
25 };
+
26 
+
27 const int kSelectScreenContentTools = 2;
+
28 const int kSelectIntegerMv = 2;
+
29 const int kPrimaryRefNone = 7;
+
30 const int kNumRefFrames = 8;
+
31 const int kAllFrames = (1 << kNumRefFrames) - 1;
+
32 
+
33 // 6.2.2. OBU header semantics.
+
34 enum ObuType {
+
35  OBU_SEQUENCE_HEADER = 1,
+
36  OBU_TEMPORAL_DELIMITER,
+
37  OBU_FRAME_HEADER,
+
38  OBU_TILE_GROUP,
+
39  OBU_METADATA,
+
40  OBU_FRAME,
+
41  OBU_REDUNDENT_FRAME_HEADER,
+
42  OBU_TILE_LIST,
+
43  // Reserved types between OBU_TILE_LIST and OBU_PADDING.
+
44  OBU_PADDING = 15,
+
45 };
+
46 
+
47 // 6.4.2. Color config semantics.
+
48 enum ColorPrimaries {
+
49  CP_BT_709 = 1,
+
50  CP_UNSPECIFIED = 2,
+
51  // We are not interested in the others.
+
52 };
+
53 enum TransferCharacteristics {
+
54  TC_UNSPECIFIED = 2,
+
55  TC_SRGB = 13,
+
56  // We are not interested in the others.
+
57 };
+
58 enum MatrixCoefficients {
+
59  MC_IDENTITY = 0,
+
60  MC_UNSPECIFIED = 2,
+
61  // We are not interested in the others.
+
62 };
+
63 enum ChromaSamplePosition {
+
64  CSP_UNKNOWN = 0,
+
65  CSP_VERTICAL,
+
66  CSP_COLOCATED,
+
67  CSP_RESERVED,
+
68 };
+
69 
+
70 // 6.8.2. Uncompressed header semantics.
+
71 enum FrameType {
+
72  KEY_FRAME = 0,
+
73  INTER_FRAME,
+
74  INTRA_ONLY_FRAME,
+
75  SWITCH_FRAME,
+
76 };
+
77 
+
78 // 6.10.24. Ref frames semantics.
+
79 enum RefFrameName {
+
80  INTRA_FRAME = 0,
+
81  LAST_FRAME,
+
82  LAST2_FRAME,
+
83  LAST3_FRAME,
+
84  GOLDEN_FRAME,
+
85  BWDREF_FRAME,
+
86  ALTREF2_FRAME,
+
87  ALTREF_FRAME,
+
88 };
+
89 
+
90 // 4.7. Mathematical functions.
+
91 int Clip3(int min_value, int max_value, int value) {
+
92  if (value < min_value)
+
93  return min_value;
+
94  if (value > max_value)
+
95  return max_value;
+
96  return value;
+
97 }
+
98 
+
99 // 4.7. Mathematical functions. The FloorLog2(x) function is defined to be the
+
100 // floor of the base 2 logarithm of the input x.
+
101 int FloorLog2(int x) {
+
102  int s = 0;
+
103  while (x != 0) {
+
104  x = x >> 1;
+
105  s++;
+
106  }
+
107  return s - 1;
+
108 }
+
109 
+
110 // 4.10.3. uvlc(). This is a modified form of Exponential-Golomb coding.
+
111 bool ReadUvlc(BitReader* reader, uint32_t* val) {
+
112  // Count the number of contiguous zero bits.
+
113  int leading_zeros = 0;
+
114  while (true) {
+
115  bool done = false;
+
116  RCHECK(reader->ReadBits(1, &done));
+
117  if (done)
+
118  break;
+
119  leading_zeros++;
+
120  }
+
121 
+
122  if (leading_zeros >= 32) {
+
123  *val = (1ull << 32) - 1;
+
124  return true;
+
125  }
+
126 
+
127  int value = 0;
+
128  if (leading_zeros > 0)
+
129  RCHECK(reader->ReadBits(leading_zeros, &value));
+
130 
+
131  *val = value + (1 << leading_zeros) - 1;
+
132  return true;
+
133 }
+
134 
+
135 // 4.10.4. le(n). Unsigned little-endian n-byte number appearing directly in the
+
136 // bitstream.
+
137 bool ReadLe(int n, BitReader* reader, size_t* val) {
+
138  size_t t = 0;
+
139  for (int i = 0; i < n; i++) {
+
140  size_t byte = 0;
+
141  RCHECK(reader->ReadBits(8, &byte));
+
142  t += (byte << (i * 8));
+
143  }
+
144  *val = t;
+
145  return true;
+
146 }
+
147 
+
148 // 4.10.5. leb128(). Unsigned integer represented by a variable number of
+
149 // little-endian bytes.
+
150 bool ReadLeb128(BitReader* reader, size_t* size) {
+
151  size_t value = 0;
+
152  for (int i = 0; i < 8; i++) {
+
153  size_t leb128_byte = 0;
+
154  RCHECK(reader->ReadBits(8, &leb128_byte));
+
155  value |= (leb128_byte & 0x7f) << (i * 7);
+
156  if (!(leb128_byte & 0x80))
+
157  break;
+
158  }
+
159  // It is a requirement of bitstream conformance that the value returned from
+
160  // the leb128 parsing process is less than or equal to (1<<32) - 1.
+
161  RCHECK(value <= ((1ull << 32) - 1));
+
162  *size = value;
+
163  return true;
+
164 }
+
165 
+
166 // 4.10.6. su(n). Signed integer converted from an n bits unsigned integer in
+
167 // the bitstream.
+
168 bool ReadSu(int n, BitReader* reader, int* value) {
+
169  RCHECK(reader->ReadBits(n, value));
+
170  int sign_mask = 1 << (n - 1);
+
171  if (*value & sign_mask)
+
172  *value = *value - 2 * sign_mask;
+
173  return true;
+
174 }
+
175 
+
176 // 4.10.7. ns(n). Unsigned encoded integer with maximum number of values in n
+
177 // (i.e. output in range 0..n-1).
+
178 bool ReadNs(int n, BitReader* reader, int* value) {
+
179  const int w = FloorLog2(n) + 1;
+
180  const int m = (1 << w) - n;
+
181  RCHECK(reader->ReadBits(w - 1, value));
+
182  if (*value < m)
+
183  return true;
+
184  int extra_bit = 0;
+
185  RCHECK(reader->ReadBits(1, &extra_bit));
+
186  *value = (*value << 1) - m + extra_bit;
+
187  return true;
+
188 }
+
189 
+
190 // 5.9.16. Tile size calculation function: returns the smallest value for k such
+
191 // that blk_size << k is greater than or equal to target.
+
192 int TileLog2(int blk_size, int target) {
+
193  int k = 0;
+
194  for (k = 0; (blk_size << k) < target; k++)
+
195  continue;
+
196  return k;
+
197 }
+
198 
+
199 // See 7.8. Set frame refs process.
+
200 int FindLatestBackward(int shifted_order_hints[],
+
201  bool used_frame[],
+
202  int cur_frame_hint) {
+
203  int ref = -1;
+
204  int latest_order_hint = 0;
+
205  for (int i = 0; i < kNumRefFrames; i++) {
+
206  const int hint = shifted_order_hints[i];
+
207  if (!used_frame[i] && hint >= cur_frame_hint &&
+
208  (ref < 0 || hint >= latest_order_hint)) {
+
209  ref = i;
+
210  latest_order_hint = hint;
+
211  }
+
212  }
+
213  return ref;
+
214 }
+
215 
+
216 // See 7.8. Set frame refs process.
+
217 int FindEarliestBackward(int shifted_order_hints[],
+
218  bool used_frame[],
+
219  int cur_frame_hint) {
+
220  int ref = -1;
+
221  int earliest_order_hint = 0;
+
222  for (int i = 0; i < kNumRefFrames; i++) {
+
223  const int hint = shifted_order_hints[i];
+
224  if (!used_frame[i] && hint >= cur_frame_hint &&
+
225  (ref < 0 || hint < earliest_order_hint)) {
+
226  ref = i;
+
227  earliest_order_hint = hint;
+
228  }
+
229  }
+
230  return ref;
+
231 }
+
232 
+
233 // See 7.8. Set frame refs process.
+
234 int FindLatestForward(int shifted_order_hints[],
+
235  bool used_frame[],
+
236  int cur_frame_hint) {
+
237  int ref = -1;
+
238  int latest_order_hint = 0;
+
239  for (int i = 0; i < kNumRefFrames; i++) {
+
240  const int hint = shifted_order_hints[i];
+
241  if (!used_frame[i] && hint < cur_frame_hint &&
+
242  (ref < 0 || hint >= latest_order_hint)) {
+
243  ref = i;
+
244  latest_order_hint = hint;
+
245  }
+
246  }
+
247  return ref;
+
248 }
+
249 
+
250 } // namespace
+
251 
+
252 AV1Parser::AV1Parser() = default;
+
253 AV1Parser::~AV1Parser() = default;
+
254 
+
255 bool AV1Parser::Parse(const uint8_t* data,
+
256  size_t data_size,
+
257  std::vector<Tile>* tiles) {
+
258  tiles->clear();
+
259 
+
260  BitReader reader(data, data_size);
+
261  while (reader.bits_available() > 0) {
+
262  if (!ParseOpenBitstreamUnit(&reader, tiles))
+
263  return false;
+
264  }
+
265  return true;
+
266 }
+
267 
+
268 // 5.3.1. General OBU syntax.
+
269 bool AV1Parser::ParseOpenBitstreamUnit(BitReader* reader,
+
270  std::vector<Tile>* tiles) {
+
271  ObuHeader obu_header;
+
272  RCHECK(ParseObuHeader(reader, &obu_header));
+
273 
+
274  size_t obu_size = 0;
+
275  if (obu_header.obu_has_size_field)
+
276  RCHECK(ReadLeb128(reader, &obu_size));
+
277  else
+
278  obu_size = reader->bits_available() / 8;
+
279 
+
280  VLOG(4) << "OBU " << obu_header.obu_type << " size " << obu_size;
+
281 
+
282  const size_t start_position = reader->bit_position();
+
283  switch (obu_header.obu_type) {
+
284  case OBU_SEQUENCE_HEADER:
+
285  RCHECK(ParseSequenceHeaderObu(reader));
+
286  break;
+
287  case OBU_FRAME_HEADER:
+
288  case OBU_REDUNDENT_FRAME_HEADER:
+
289  RCHECK(ParseFrameHeaderObu(obu_header, reader));
+
290  break;
+
291  case OBU_TILE_GROUP:
+
292  RCHECK(ParseTileGroupObu(obu_size, reader, tiles));
+
293  break;
+
294  case OBU_FRAME:
+
295  RCHECK(ParseFrameObu(obu_header, obu_size, reader, tiles));
+
296  break;
+
297  default:
+
298  // Skip all OBUs we are not interested.
+
299  RCHECK(reader->SkipBits(obu_size * 8));
+
300  break;
+
301  }
+
302 
+
303  const size_t current_position = reader->bit_position();
+
304  const size_t payload_bits = current_position - start_position;
+
305  if (obu_header.obu_type == OBU_TILE_GROUP ||
+
306  obu_header.obu_type == OBU_FRAME) {
+
307  RCHECK(payload_bits == obu_size * 8);
+
308  } else if (obu_size > 0) {
+
309  RCHECK(payload_bits <= obu_size * 8);
+
310  RCHECK(ParseTrailingBits(obu_size * 8 - payload_bits, reader));
+
311  }
+
312  return true;
+
313 }
+
314 
+
315 // 5.3.2. OBU header syntax.
+
316 bool AV1Parser::ParseObuHeader(BitReader* reader, ObuHeader* obu_header) {
+
317  int obu_forbidden_bit = 0;
+
318  RCHECK(reader->ReadBits(1, &obu_forbidden_bit));
+
319  RCHECK(obu_forbidden_bit == 0);
+
320  RCHECK(reader->ReadBits(4, &obu_header->obu_type));
+
321  bool obu_extension_flag = false;
+
322  RCHECK(reader->ReadBits(1, &obu_extension_flag));
+
323  RCHECK(reader->ReadBits(1, &obu_header->obu_has_size_field));
+
324  RCHECK(reader->SkipBits(1)); // Skip obu_reserved_1bit.
+
325 
+
326  if (obu_extension_flag)
+
327  RCHECK(ParseObuExtensionHeader(reader, &obu_header->extension_header));
+
328 
+
329  return true;
+
330 }
+
331 
+
332 // 5.3.3. OBU extension header syntax.
+
333 bool AV1Parser::ParseObuExtensionHeader(
+
334  BitReader* reader,
+
335  ObuExtensionHeader* obu_extension_header) {
+
336  RCHECK(reader->ReadBits(3, &obu_extension_header->temporal_id));
+
337  RCHECK(reader->ReadBits(2, &obu_extension_header->spatial_id));
+
338  RCHECK(reader->SkipBits(3)); // Skip extension_header_reserved_3bits.
+
339  return true;
+
340 }
+
341 
+
342 // 5.3.4. Trailing bits syntax.
+
343 bool AV1Parser::ParseTrailingBits(size_t nb_bits, BitReader* reader) {
+
344  int trailing_one_bit = 0;
+
345  RCHECK(reader->ReadBits(1, &trailing_one_bit));
+
346  RCHECK(trailing_one_bit == 1);
+
347  nb_bits--;
+
348  while (nb_bits > 0) {
+
349  int trailing_zero_bit = 0;
+
350  RCHECK(reader->ReadBits(1, &trailing_zero_bit));
+
351  RCHECK(trailing_zero_bit == 0);
+
352  nb_bits--;
+
353  }
+
354  return true;
+
355 }
+
356 
+
357 bool AV1Parser::ByteAlignment(BitReader* reader) {
+
358  while (reader->bit_position() & 7) {
+
359  int zero_bit = 0;
+
360  RCHECK(reader->ReadBits(1, &zero_bit));
+
361  RCHECK(zero_bit == 0);
+
362  }
+
363  return true;
+
364 }
+
365 
+
366 // 5.5.1. General sequence header OBU syntax.
+
367 bool AV1Parser::ParseSequenceHeaderObu(BitReader* reader) {
+
368  RCHECK(reader->ReadBits(3, &sequence_header_.seq_profile));
+
369  // Skip still_picture.
+
370  RCHECK(reader->SkipBits(1));
+
371 
+
372  RCHECK(reader->ReadBits(1, &sequence_header_.reduced_still_picture_header));
+
373  if (sequence_header_.reduced_still_picture_header) {
+
374  sequence_header_.decoder_model_info_present_flag = false;
+
375  sequence_header_.operating_points_cnt_minus_1 = 0;
+
376  sequence_header_.operating_point_idc[0] = 0;
+
377  // Skip seq_level_idx[0].
+
378  RCHECK(reader->SkipBits(5));
+
379  sequence_header_.decoder_model_present_for_this_op[0] = false;
+
380  } else {
+
381  bool timing_info_present_flag = false;
+
382  RCHECK(reader->ReadBits(1, &timing_info_present_flag));
+
383 
+
384  bool decoder_model_info_present_flag = false;
+
385  if (timing_info_present_flag) {
+
386  RCHECK(ParseTimingInfo(reader));
+
387  RCHECK(reader->ReadBits(1, &decoder_model_info_present_flag));
+
388  if (decoder_model_info_present_flag)
+
389  RCHECK(ParseDecoderModelInfo(reader));
+
390  }
+
391  sequence_header_.decoder_model_info_present_flag =
+
392  decoder_model_info_present_flag;
+
393 
+
394  bool initial_display_delay_present_flag = false;
+
395  RCHECK(reader->ReadBits(1, &initial_display_delay_present_flag));
+
396 
+
397  RCHECK(reader->ReadBits(5, &sequence_header_.operating_points_cnt_minus_1));
+
398  for (int i = 0; i <= sequence_header_.operating_points_cnt_minus_1; i++) {
+
399  RCHECK(reader->ReadBits(12, &sequence_header_.operating_point_idc[i]));
+
400  int seq_level_idx_i = 0;
+
401  RCHECK(reader->ReadBits(5, &seq_level_idx_i));
+
402  if (seq_level_idx_i > 7) {
+
403  // Skip seq_tier[i].
+
404  RCHECK(reader->SkipBits(1));
+
405  }
+
406 
+
407  if (sequence_header_.decoder_model_info_present_flag) {
+
408  RCHECK(reader->ReadBits(
+
409  1, &sequence_header_.decoder_model_present_for_this_op[i]));
+
410  if (sequence_header_.decoder_model_present_for_this_op[i]) {
+
411  RCHECK(SkipOperatingParametersInfo(reader));
+
412  }
+
413  } else {
+
414  sequence_header_.decoder_model_present_for_this_op[i] = false;
+
415  }
+
416 
+
417  if (initial_display_delay_present_flag) {
+
418  // Skip initial_display_delay_present_for_this_op[i],
+
419  // initial_display_delay_minus_1[i].
+
420  RCHECK(reader->SkipBitsConditional(true, 4));
+
421  }
+
422  }
+
423  }
+
424 
+
425  RCHECK(reader->ReadBits(4, &sequence_header_.frame_width_bits_minus_1));
+
426  RCHECK(reader->ReadBits(4, &sequence_header_.frame_height_bits_minus_1));
+
427  RCHECK(reader->ReadBits(sequence_header_.frame_width_bits_minus_1 + 1,
+
428  &sequence_header_.max_frame_width_minus_1));
+
429  RCHECK(reader->ReadBits(sequence_header_.frame_height_bits_minus_1 + 1,
+
430  &sequence_header_.max_frame_height_minus_1));
+
431 
+
432  if (sequence_header_.reduced_still_picture_header) {
+
433  sequence_header_.frame_id_numbers_present_flag = false;
+
434  } else {
+
435  RCHECK(
+
436  reader->ReadBits(1, &sequence_header_.frame_id_numbers_present_flag));
+
437  }
+
438  if (sequence_header_.frame_id_numbers_present_flag) {
+
439  RCHECK(
+
440  reader->ReadBits(4, &sequence_header_.delta_frame_id_length_minus_2));
+
441  RCHECK(reader->ReadBits(
+
442  3, &sequence_header_.additional_frame_id_length_minus_1));
+
443  }
+
444 
+
445  RCHECK(reader->ReadBits(1, &sequence_header_.use_128x128_superblock));
+
446  // Skip enable_filter_intra, enable_intra_edge_filter.
+
447  RCHECK(reader->SkipBits(1 + 1));
+
448 
+
449  if (sequence_header_.reduced_still_picture_header) {
+
450  sequence_header_.enable_warped_motion = false;
+
451  sequence_header_.enable_order_hint = false;
+
452  sequence_header_.enable_ref_frame_mvs = false;
+
453  sequence_header_.order_hint_bits = 0;
+
454  sequence_header_.seq_force_screen_content_tools = kSelectScreenContentTools;
+
455  sequence_header_.seq_force_integer_mv = kSelectIntegerMv;
+
456  } else {
+
457  // Skip enable_interintra_compound, enable_masked_compound,
+
458  RCHECK(reader->SkipBits(1 + 1));
+
459 
+
460  RCHECK(reader->ReadBits(1, &sequence_header_.enable_warped_motion));
+
461  RCHECK(reader->SkipBits(1)); // Skip enable_dual_filter.
+
462  RCHECK(reader->ReadBits(1, &sequence_header_.enable_order_hint));
+
463  if (sequence_header_.enable_order_hint) {
+
464  // Skip enable_jnt_comp.
+
465  RCHECK(reader->SkipBits(1));
+
466  RCHECK(reader->ReadBits(1, &sequence_header_.enable_ref_frame_mvs));
+
467  } else {
+
468  sequence_header_.enable_ref_frame_mvs = false;
+
469  }
+
470 
+
471  bool seq_choose_screen_content_tools = false;
+
472  RCHECK(reader->ReadBits(1, &seq_choose_screen_content_tools));
+
473 
+
474  if (seq_choose_screen_content_tools) {
+
475  sequence_header_.seq_force_screen_content_tools =
+
476  kSelectScreenContentTools;
+
477  } else {
+
478  RCHECK(reader->ReadBits(
+
479  1, &sequence_header_.seq_force_screen_content_tools));
+
480  }
+
481 
+
482  if (sequence_header_.seq_force_screen_content_tools > 0) {
+
483  bool seq_choose_integer_mv = false;
+
484  RCHECK(reader->ReadBits(1, &seq_choose_integer_mv));
+
485  if (seq_choose_integer_mv)
+
486  sequence_header_.seq_force_integer_mv = kSelectIntegerMv;
+
487  else
+
488  RCHECK(reader->ReadBits(1, &sequence_header_.seq_force_integer_mv));
+
489  } else {
+
490  sequence_header_.seq_force_integer_mv = kSelectIntegerMv;
+
491  }
+
492 
+
493  if (sequence_header_.enable_order_hint) {
+
494  int order_hint_bits_minus_1 = 0;
+
495  RCHECK(reader->ReadBits(3, &order_hint_bits_minus_1));
+
496  sequence_header_.order_hint_bits = order_hint_bits_minus_1 + 1;
+
497  } else {
+
498  sequence_header_.order_hint_bits = 0;
+
499  }
+
500  }
+
501 
+
502  RCHECK(reader->ReadBits(1, &sequence_header_.enable_superres));
+
503  RCHECK(reader->ReadBits(1, &sequence_header_.enable_cdef));
+
504  RCHECK(reader->ReadBits(1, &sequence_header_.enable_restoration));
+
505  RCHECK(ParseColorConfig(reader));
+
506  RCHECK(reader->ReadBits(1, &sequence_header_.film_grain_params_present));
+
507  return true;
+
508 }
+
509 
+
510 // 5.5.2. Color config syntax.
+
511 bool AV1Parser::ParseColorConfig(BitReader* reader) {
+
512  ColorConfig& color_config = sequence_header_.color_config;
+
513 
+
514  bool high_bitdepth = false;
+
515  RCHECK(reader->ReadBits(1, &high_bitdepth));
+
516  if (sequence_header_.seq_profile == 2 && high_bitdepth) {
+
517  bool twelve_bit = false;
+
518  RCHECK(reader->ReadBits(1, &twelve_bit));
+
519  color_config.bit_depth = twelve_bit ? 12 : 10;
+
520  } else if (sequence_header_.seq_profile <= 2) {
+
521  color_config.bit_depth = high_bitdepth ? 10 : 8;
+
522  }
+
523 
+
524  if (sequence_header_.seq_profile == 1)
+
525  color_config.mono_chrome = 0;
+
526  else
+
527  RCHECK(reader->ReadBits(1, &color_config.mono_chrome));
+
528  color_config.num_planes = color_config.mono_chrome ? 1 : 3;
+
529 
+
530  bool color_description_present_flag = false;
+
531  RCHECK(reader->ReadBits(1, &color_description_present_flag));
+
532 
+
533  if (color_description_present_flag) {
+
534  RCHECK(reader->ReadBits(8, &color_config.color_primaries));
+
535  RCHECK(reader->ReadBits(8, &color_config.transfer_chracteristics));
+
536  RCHECK(reader->ReadBits(8, &color_config.matrix_coefficients));
+
537  } else {
+
538  color_config.color_primaries = CP_UNSPECIFIED;
+
539  color_config.transfer_chracteristics = TC_UNSPECIFIED;
+
540  color_config.matrix_coefficients = MC_UNSPECIFIED;
+
541  }
+
542 
+
543  if (color_config.mono_chrome) {
+
544  RCHECK(reader->ReadBits(1, &color_config.color_range));
+
545  color_config.subsampling_x = true;
+
546  color_config.subsampling_y = true;
+
547  color_config.chroma_sampling_position = CSP_UNKNOWN;
+
548  color_config.separate_uv_delta_q = false;
+
549  return true;
+
550  } else if (color_config.color_primaries == CP_BT_709 &&
+
551  color_config.transfer_chracteristics == TC_SRGB &&
+
552  color_config.matrix_coefficients == MC_IDENTITY) {
+
553  color_config.color_range = true;
+
554  color_config.subsampling_x = false;
+
555  color_config.subsampling_y = false;
+
556  } else {
+
557  RCHECK(reader->ReadBits(1, &color_config.color_range));
+
558  if (sequence_header_.seq_profile == 0) {
+
559  color_config.subsampling_x = true;
+
560  color_config.subsampling_y = true;
+
561  } else if (sequence_header_.seq_profile == 1) {
+
562  color_config.subsampling_x = false;
+
563  color_config.subsampling_y = false;
+
564  } else {
+
565  if (color_config.bit_depth == 12) {
+
566  RCHECK(reader->ReadBits(1, &color_config.subsampling_x));
+
567  if (color_config.subsampling_x)
+
568  RCHECK(reader->ReadBits(1, &color_config.subsampling_y));
+
569  else
+
570  color_config.subsampling_y = false;
+
571  } else {
+
572  color_config.subsampling_x = true;
+
573  color_config.subsampling_y = false;
+
574  }
+
575  }
+
576 
+
577  if (color_config.subsampling_x && color_config.subsampling_y)
+
578  RCHECK(reader->ReadBits(2, &color_config.chroma_sampling_position));
+
579  }
+
580 
+
581  RCHECK(reader->ReadBits(1, &color_config.separate_uv_delta_q));
+
582  return true;
+
583 }
+
584 
+
585 // 5.5.3.Timing info syntax.
+
586 bool AV1Parser::ParseTimingInfo(BitReader* reader) {
+
587  // Skip num_units_in_display_tick, time_scale.
+
588  RCHECK(reader->SkipBits(32 + 32));
+
589  bool equal_picture_interval = false;
+
590  RCHECK(reader->ReadBits(1, &equal_picture_interval));
+
591  sequence_header_.timing_info.equal_picture_interval = equal_picture_interval;
+
592  if (equal_picture_interval) {
+
593  uint32_t num_ticks_per_picture_minus_1 = 0;
+
594  RCHECK(ReadUvlc(reader, &num_ticks_per_picture_minus_1));
+
595  }
+
596  return true;
+
597 }
+
598 
+
599 // 5.5.4. Decoder model info syntax.
+
600 bool AV1Parser::ParseDecoderModelInfo(BitReader* reader) {
+
601  DecoderModelInfo& decoder_model_info = sequence_header_.decoder_model_info;
+
602 
+
603  RCHECK(reader->ReadBits(5, &decoder_model_info.buffer_delay_length_minus_1));
+
604  // Skip num_units_in_decoding_tick.
+
605  RCHECK(reader->SkipBits(32));
+
606  RCHECK(reader->ReadBits(
+
607  5, &decoder_model_info.buffer_removal_time_length_minus_1));
+
608  RCHECK(reader->ReadBits(
+
609  5, &decoder_model_info.frame_presentation_time_length_minus_1));
+
610  return true;
+
611 }
+
612 
+
613 // 5.5.5. Operating parameters info syntax.
+
614 bool AV1Parser::SkipOperatingParametersInfo(BitReader* reader) {
+
615  const int n =
+
616  sequence_header_.decoder_model_info.buffer_delay_length_minus_1 + 1;
+
617  // Skip decoder_buffer_delay[op], encoder_buffer_delay[op],
+
618  // low_delay_mode_flag[op].
+
619  RCHECK(reader->SkipBits(n + n + 1));
+
620  return true;
+
621 }
+
622 
+
623 // 5.9.1. General frame header OBU syntax.
+
624 bool AV1Parser::ParseFrameHeaderObu(const ObuHeader& obu_header,
+
625  BitReader* reader) {
+
626  if (frame_header_.seen_frame_header)
+
627  return true;
+
628 
+
629  frame_header_.seen_frame_header = true;
+
630  RCHECK(ParseUncompressedHeader(obu_header, reader));
+
631  if (frame_header_.show_existing_frame) {
+
632  DecodeFrameWrapup();
+
633  frame_header_.seen_frame_header = false;
+
634  } else {
+
635  frame_header_.seen_frame_header = true;
+
636  }
+
637  return true;
+
638 }
+
639 
+
640 // 5.9.2. Uncompressed header syntax.
+
641 bool AV1Parser::ParseUncompressedHeader(const ObuHeader& obu_header,
+
642  BitReader* reader) {
+
643  int id_len = 0;
+
644  if (sequence_header_.frame_id_numbers_present_flag) {
+
645  id_len = sequence_header_.additional_frame_id_length_minus_1 + 1 +
+
646  sequence_header_.delta_frame_id_length_minus_2 + 2;
+
647  }
+
648 
+
649  bool frame_is_intra = false;
+
650  bool show_frame = false;
+
651  bool showable_frame = false;
+
652  bool error_resilient_mode = false;
+
653 
+
654  if (sequence_header_.reduced_still_picture_header) {
+
655  frame_header_.show_existing_frame = false;
+
656  frame_header_.frame_type = KEY_FRAME;
+
657  frame_is_intra = true;
+
658  show_frame = true;
+
659  showable_frame = false;
+
660  } else {
+
661  RCHECK(reader->ReadBits(1, &frame_header_.show_existing_frame));
+
662  if (frame_header_.show_existing_frame) {
+
663  RCHECK(reader->ReadBits(3, &frame_header_.frame_to_show_map_idx));
+
664  if (sequence_header_.decoder_model_info_present_flag &&
+
665  !sequence_header_.timing_info.equal_picture_interval) {
+
666  RCHECK(SkipTemporalPointInfo(reader));
+
667  }
+
668  frame_header_.refresh_frame_flags = 0;
+
669  if (sequence_header_.frame_id_numbers_present_flag) {
+
670  // Skip display_frame_id.
+
671  RCHECK(reader->SkipBits(id_len));
+
672  }
+
673  frame_header_.frame_type =
+
674  reference_frames_[frame_header_.frame_to_show_map_idx].frame_type;
+
675  if (frame_header_.frame_type == KEY_FRAME) {
+
676  frame_header_.refresh_frame_flags = kAllFrames;
+
677  }
+
678  return true;
+
679  }
+
680 
+
681  RCHECK(reader->ReadBits(2, &frame_header_.frame_type));
+
682  frame_is_intra = frame_header_.frame_type == INTRA_ONLY_FRAME ||
+
683  frame_header_.frame_type == KEY_FRAME;
+
684  RCHECK(reader->ReadBits(1, &show_frame));
+
685  if (show_frame && sequence_header_.decoder_model_info_present_flag &&
+
686  !sequence_header_.timing_info.equal_picture_interval) {
+
687  RCHECK(SkipTemporalPointInfo(reader));
+
688  }
+
689  if (show_frame)
+
690  showable_frame = frame_header_.frame_type != KEY_FRAME;
+
691  else
+
692  RCHECK(reader->ReadBits(1, &showable_frame));
+
693 
+
694  if (frame_header_.frame_type == SWITCH_FRAME ||
+
695  (frame_header_.frame_type == KEY_FRAME && show_frame)) {
+
696  error_resilient_mode = true;
+
697  } else {
+
698  RCHECK(reader->ReadBits(1, &error_resilient_mode));
+
699  }
+
700  }
+
701 
+
702  if (frame_header_.frame_type == KEY_FRAME && show_frame) {
+
703  for (int i = 0; i < kNumRefFrames; i++) {
+
704  reference_frames_[i].order_hint = 0;
+
705  }
+
706  }
+
707 
+
708  bool disable_cdf_update = false;
+
709  RCHECK(reader->ReadBits(1, &disable_cdf_update));
+
710 
+
711  bool allow_screen_content_tools = false;
+
712  if (sequence_header_.seq_force_screen_content_tools ==
+
713  kSelectScreenContentTools) {
+
714  RCHECK(reader->ReadBits(1, &allow_screen_content_tools));
+
715  } else {
+
716  allow_screen_content_tools =
+
717  sequence_header_.seq_force_screen_content_tools != 0;
+
718  }
+
719 
+
720  int force_integer_mv = 0;
+
721  if (allow_screen_content_tools) {
+
722  if (sequence_header_.seq_force_integer_mv == kSelectIntegerMv)
+
723  RCHECK(reader->ReadBits(1, &force_integer_mv));
+
724  else
+
725  force_integer_mv = sequence_header_.seq_force_integer_mv;
+
726  }
+
727  if (frame_is_intra)
+
728  force_integer_mv = 1;
+
729 
+
730  if (sequence_header_.frame_id_numbers_present_flag) {
+
731  // Skip current_frame_id.
+
732  RCHECK(reader->SkipBits(id_len));
+
733  }
+
734 
+
735  bool frame_size_override_flag = false;
+
736  if (frame_header_.frame_type == SWITCH_FRAME)
+
737  frame_size_override_flag = true;
+
738  else if (sequence_header_.reduced_still_picture_header)
+
739  frame_size_override_flag = false;
+
740  else
+
741  RCHECK(reader->ReadBits(1, &frame_size_override_flag));
+
742 
+
743  RCHECK(reader->ReadBits(sequence_header_.order_hint_bits,
+
744  &frame_header_.order_hint));
+
745  int primary_ref_frame = 0;
+
746  if (frame_is_intra || error_resilient_mode) {
+
747  primary_ref_frame = kPrimaryRefNone;
+
748  } else {
+
749  RCHECK(reader->ReadBits(3, &primary_ref_frame));
+
750  }
+
751  if (sequence_header_.decoder_model_info_present_flag) {
+
752  bool buffer_removal_time_present_flag = false;
+
753  RCHECK(reader->ReadBits(1, &buffer_removal_time_present_flag));
+
754  if (buffer_removal_time_present_flag) {
+
755  for (int op_num = 0;
+
756  op_num <= sequence_header_.operating_points_cnt_minus_1; op_num++) {
+
757  if (sequence_header_.decoder_model_present_for_this_op[op_num]) {
+
758  const int op_pt_idc = sequence_header_.operating_point_idc[op_num];
+
759  const int in_temporal_layer =
+
760  (op_pt_idc >> obu_header.extension_header.temporal_id) & 1;
+
761  const int in_spatial_layer =
+
762  (op_pt_idc >> (obu_header.extension_header.spatial_id + 8)) & 1;
+
763  if (op_pt_idc == 0 || (in_temporal_layer && in_spatial_layer)) {
+
764  // Skip buffer_removal_time[ opNum ].
+
765  RCHECK(reader->SkipBits(sequence_header_.decoder_model_info
+
766  .buffer_removal_time_length_minus_1 +
+
767  1));
+
768  }
+
769  }
+
770  }
+
771  }
+
772  }
+
773 
+
774  bool allow_high_precision_mv = false;
+
775  bool allow_intrabc = false;
+
776 
+
777  if (frame_header_.frame_type == SWITCH_FRAME ||
+
778  (frame_header_.frame_type == KEY_FRAME && show_frame)) {
+
779  frame_header_.refresh_frame_flags = kAllFrames;
+
780  } else {
+
781  RCHECK(reader->ReadBits(8, &frame_header_.refresh_frame_flags));
+
782  }
+
783  if (!frame_is_intra || frame_header_.refresh_frame_flags != kAllFrames) {
+
784  if (error_resilient_mode && sequence_header_.enable_order_hint) {
+
785  for (int i = 0; i < kNumRefFrames; i++) {
+
786  // Skip ref_order_hint[ i ].
+
787  RCHECK(reader->SkipBits(sequence_header_.order_hint_bits));
+
788  }
+
789  }
+
790  }
+
791 
+
792  if (frame_is_intra) {
+
793  RCHECK(ParseFrameSize(frame_size_override_flag, reader));
+
794  RCHECK(ParseRenderSize(reader));
+
795  if (allow_screen_content_tools &&
+
796  frame_header_.upscaled_width == frame_header_.frame_width)
+
797  RCHECK(reader->ReadBits(1, &allow_intrabc));
+
798  } else {
+
799  bool frame_refs_short_signaling = false;
+
800  if (sequence_header_.enable_order_hint) {
+
801  RCHECK(reader->ReadBits(1, &frame_refs_short_signaling));
+
802  if (frame_refs_short_signaling) {
+
803  int last_frame_idx = 0;
+
804  RCHECK(reader->ReadBits(3, &last_frame_idx));
+
805  int gold_frame_idx = 0;
+
806  RCHECK(reader->ReadBits(3, &gold_frame_idx));
+
807  RCHECK(SetFrameRefs(last_frame_idx, gold_frame_idx));
+
808  }
+
809  }
+
810  for (int i = 0; i < kRefsPerFrame; i++) {
+
811  if (!frame_refs_short_signaling)
+
812  RCHECK(reader->ReadBits(3, &frame_header_.ref_frame_idx[i]));
+
813  if (sequence_header_.frame_id_numbers_present_flag) {
+
814  // Skip delta_frame_id_minus_1.
+
815  RCHECK(reader->SkipBits(sequence_header_.delta_frame_id_length_minus_2 +
+
816  2));
+
817  }
+
818  }
+
819  if (frame_size_override_flag && !error_resilient_mode) {
+
820  RCHECK(ParseFrameSizeWithRefs(frame_size_override_flag, reader));
+
821  } else {
+
822  RCHECK(ParseFrameSize(frame_size_override_flag, reader));
+
823  RCHECK(ParseRenderSize(reader));
+
824  }
+
825 
+
826  if (force_integer_mv)
+
827  allow_high_precision_mv = false;
+
828  else
+
829  RCHECK(reader->ReadBits(1, &allow_high_precision_mv));
+
830 
+
831  RCHECK(SkipInterpolationFilter(reader));
+
832  // Skip is_motion_mode_switchable.
+
833  RCHECK(reader->SkipBits(1));
+
834  if (!error_resilient_mode && sequence_header_.enable_ref_frame_mvs) {
+
835  // Skip use_ref_frame_mvs.
+
836  RCHECK(reader->SkipBits(1));
+
837  }
+
838  }
+
839 
+
840  if (!sequence_header_.reduced_still_picture_header && !disable_cdf_update) {
+
841  // Skip disable_frame_end_update_cdf.
+
842  RCHECK(reader->SkipBits(1));
+
843  }
+
844 
+
845  RCHECK(ParseTileInfo(reader));
+
846  RCHECK(ParseQuantizationParams(reader));
+
847  RCHECK(ParseSegmentationParams(primary_ref_frame, reader));
+
848 
+
849  bool delta_q_present = false;
+
850  RCHECK(SkipDeltaQParams(reader, &delta_q_present));
+
851  RCHECK(SkipDeltaLfParams(delta_q_present, allow_intrabc, reader));
+
852 
+
853  const auto& quantization_params = frame_header_.quantization_params;
+
854  bool coded_lossless = true;
+
855  for (int segment_id = 0; segment_id < kMaxSegments; segment_id++) {
+
856  const int qindex = GetQIndex(true, segment_id);
+
857  const bool lossless = qindex == 0 && quantization_params.delta_qydc == 0 &&
+
858  quantization_params.delta_quac == 0 &&
+
859  quantization_params.delta_qudc == 0 &&
+
860  quantization_params.delta_qvac == 0 &&
+
861  quantization_params.delta_qvdc == 0;
+
862  if (!lossless)
+
863  coded_lossless = false;
+
864  }
+
865  const bool all_lossless = coded_lossless && (frame_header_.frame_width ==
+
866  frame_header_.upscaled_width);
+
867 
+
868  RCHECK(ParseLoopFilterParams(coded_lossless, allow_intrabc, reader));
+
869  RCHECK(ParseCdefParams(coded_lossless, allow_intrabc, reader));
+
870  RCHECK(ParseLrParams(all_lossless, allow_intrabc, reader));
+
871  RCHECK(SkipTxMode(coded_lossless, reader));
+
872  bool reference_select = false;
+
873  RCHECK(ParseFrameReferenceMode(frame_is_intra, reader, &reference_select));
+
874  RCHECK(SkipSkipModeParams(frame_is_intra, reference_select, reader));
+
875 
+
876  bool allow_warped_motion = false;
+
877  if (frame_is_intra || error_resilient_mode ||
+
878  !sequence_header_.enable_warped_motion) {
+
879  allow_warped_motion = false;
+
880  } else {
+
881  RCHECK(reader->ReadBits(1, &allow_warped_motion));
+
882  }
+
883  // Skip reduced_tx_set.
+
884  RCHECK(reader->SkipBits(1));
+
885 
+
886  RCHECK(
+
887  SkipGlobalMotionParams(frame_is_intra, allow_high_precision_mv, reader));
+
888  RCHECK(SkipFilmGrainParams(show_frame, showable_frame, reader));
+
889  return true;
+
890 }
+
891 
+
892 // 5.9.3. Get relative distance function.
+
893 int AV1Parser::GetRelativeDist(int a, int b) {
+
894  if (!sequence_header_.enable_order_hint)
+
895  return 0;
+
896  int diff = a - b;
+
897  const int m = 1 << (sequence_header_.order_hint_bits - 1);
+
898  diff = (diff & (m - 1)) - (diff & m);
+
899  return diff;
+
900 }
+
901 
+
902 // 5.9.5. Frame size syntax.
+
903 bool AV1Parser::ParseFrameSize(bool frame_size_override_flag,
+
904  BitReader* reader) {
+
905  if (frame_size_override_flag) {
+
906  int frame_width_minus_1 = 0;
+
907  RCHECK(reader->ReadBits(sequence_header_.frame_width_bits_minus_1 + 1,
+
908  &frame_width_minus_1));
+
909  int frame_height_minus_1 = 0;
+
910  RCHECK(reader->ReadBits(sequence_header_.frame_height_bits_minus_1 + 1,
+
911  &frame_height_minus_1));
+
912  frame_header_.frame_width = frame_width_minus_1 + 1;
+
913  frame_header_.frame_height = frame_height_minus_1 + 1;
+
914  } else {
+
915  frame_header_.frame_width = sequence_header_.max_frame_width_minus_1 + 1;
+
916  frame_header_.frame_height = sequence_header_.max_frame_height_minus_1 + 1;
+
917  }
+
918  RCHECK(ParseSuperresParams(reader));
+
919  ComputeImageSize();
+
920  return true;
+
921 }
+
922 
+
923 // 5.9.6. Render size syntax.
+
924 bool AV1Parser::ParseRenderSize(BitReader* reader) {
+
925  bool render_and_frame_size_different = false;
+
926  RCHECK(reader->ReadBits(1, &render_and_frame_size_different));
+
927  if (render_and_frame_size_different) {
+
928  int render_width_minus_1 = 0;
+
929  RCHECK(reader->ReadBits(16, &render_width_minus_1));
+
930  int render_height_minus_1 = 0;
+
931  RCHECK(reader->ReadBits(16, &render_height_minus_1));
+
932  frame_header_.render_width = render_width_minus_1 + 1;
+
933  frame_header_.render_height = render_height_minus_1 + 1;
+
934  } else {
+
935  frame_header_.render_width = frame_header_.upscaled_width;
+
936  frame_header_.render_height = frame_header_.frame_height;
+
937  }
+
938  return true;
+
939 }
+
940 
+
941 // 5.9.7. Frame size with refs syntax.
+
942 bool AV1Parser::ParseFrameSizeWithRefs(bool frame_size_override_flag,
+
943  BitReader* reader) {
+
944  bool found_ref = false;
+
945  for (int i = 0; i < kRefsPerFrame; i++) {
+
946  RCHECK(reader->ReadBits(1, &found_ref));
+
947  if (found_ref) {
+
948  const ReferenceFrame& reference_frame =
+
949  reference_frames_[frame_header_.ref_frame_idx[i]];
+
950  frame_header_.upscaled_width = reference_frame.upscaled_width;
+
951  frame_header_.frame_width = frame_header_.upscaled_width;
+
952  frame_header_.frame_height = reference_frame.frame_height;
+
953  frame_header_.render_width = reference_frame.render_width;
+
954  frame_header_.render_height = reference_frame.render_height;
+
955  break;
+
956  }
+
957  }
+
958  if (!found_ref) {
+
959  RCHECK(ParseFrameSize(frame_size_override_flag, reader));
+
960  RCHECK(ParseRenderSize(reader));
+
961  } else {
+
962  RCHECK(ParseSuperresParams(reader));
+
963  ComputeImageSize();
+
964  }
+
965  return true;
+
966 }
+
967 
+
968 // 5.9.8. Superres params syntax.
+
969 bool AV1Parser::ParseSuperresParams(BitReader* reader) {
+
970  const int kSuperresNum = 8;
+
971  const int kSuperresDenomMin = 9;
+
972  const int kSuperresDenomBits = 3;
+
973 
+
974  bool use_superres = false;
+
975  if (sequence_header_.enable_superres)
+
976  RCHECK(reader->ReadBits(1, &use_superres));
+
977 
+
978  int superres_denom = 0;
+
979  if (use_superres) {
+
980  int coded_denom = 0;
+
981  RCHECK(reader->ReadBits(kSuperresDenomBits, &coded_denom));
+
982  superres_denom = coded_denom + kSuperresDenomMin;
+
983  } else {
+
984  superres_denom = kSuperresNum;
+
985  }
+
986 
+
987  const int upscaled_width = frame_header_.frame_width;
+
988  frame_header_.upscaled_width =
+
989  (upscaled_width * kSuperresNum + superres_denom / 2) / superres_denom;
+
990  return true;
+
991 }
+
992 
+
993 // 5.9.9. Compute image size function.
+
994 void AV1Parser::ComputeImageSize() {
+
995  frame_header_.mi_cols = 2 * ((frame_header_.frame_width + 7) >> 3);
+
996  frame_header_.mi_rows = 2 * ((frame_header_.frame_height + 7) >> 3);
+
997 }
+
998 
+
999 // 5.9.10. Interpolation filter syntax.
+
1000 bool AV1Parser::SkipInterpolationFilter(BitReader* reader) {
+
1001  // SKip is_filter_switchable, interpolation_filter.
+
1002  RCHECK(reader->SkipBitsConditional(false, 2));
+
1003  return true;
+
1004 }
+
1005 
+
1006 // 5.9.11. Loop filter parms syntax.
+
1007 bool AV1Parser::ParseLoopFilterParams(bool coded_lossless,
+
1008  bool allow_intrabc,
+
1009  BitReader* reader) {
+
1010  if (coded_lossless || allow_intrabc)
+
1011  return true;
+
1012 
+
1013  int loop_filter_level[] = {0, 0};
+
1014  RCHECK(reader->ReadBits(6, &loop_filter_level[0]));
+
1015  RCHECK(reader->ReadBits(6, &loop_filter_level[1]));
+
1016  if (sequence_header_.color_config.num_planes > 1) {
+
1017  if (loop_filter_level[0] || loop_filter_level[1]) {
+
1018  // Skip loop_filter_level[2], loop_filter_level[3].
+
1019  RCHECK(reader->SkipBits(6 + 6));
+
1020  }
+
1021  }
+
1022  // Skip loop_filter_sharpness.
+
1023  RCHECK(reader->SkipBits(3));
+
1024  bool loop_filter_delta_enabled = false;
+
1025  RCHECK(reader->ReadBits(1, &loop_filter_delta_enabled));
+
1026  if (loop_filter_delta_enabled) {
+
1027  bool loop_filter_delta_update = false;
+
1028  RCHECK(reader->ReadBits(1, &loop_filter_delta_update));
+
1029  if (loop_filter_delta_update) {
+
1030  const int kTotalRefsPerFrame = 8;
+
1031  for (int i = 0; i < kTotalRefsPerFrame; i++) {
+
1032  // Skip update_ref_delta, loop_filter_ref_delta[ i ].
+
1033  RCHECK(reader->SkipBitsConditional(true, 1 + 6));
+
1034  }
+
1035  for (int i = 0; i < 2; i++) {
+
1036  // Skip update_mode_delta, loop_filter_mode_delta[ i ].
+
1037  RCHECK(reader->SkipBitsConditional(true, 1 + 6));
+
1038  }
+
1039  }
+
1040  }
+
1041  return true;
+
1042 }
+
1043 
+
1044 // 5.9.12. Quantization params syntax.
+
1045 bool AV1Parser::ParseQuantizationParams(BitReader* reader) {
+
1046  QuantizationParams& quantization_params = frame_header_.quantization_params;
+
1047 
+
1048  RCHECK(reader->ReadBits(8, &quantization_params.base_q_idx));
+
1049  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_qydc));
+
1050 
+
1051  const ColorConfig& color_config = sequence_header_.color_config;
+
1052  if (color_config.num_planes > 1) {
+
1053  bool diff_uv_delta = false;
+
1054  if (color_config.separate_uv_delta_q)
+
1055  RCHECK(reader->ReadBits(1, &diff_uv_delta));
+
1056  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_qudc));
+
1057  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_quac));
+
1058  if (diff_uv_delta) {
+
1059  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_qvdc));
+
1060  RCHECK(ReadDeltaQ(reader, &quantization_params.delta_qvac));
+
1061  } else {
+
1062  quantization_params.delta_qvdc = quantization_params.delta_qudc;
+
1063  quantization_params.delta_qvac = quantization_params.delta_quac;
+
1064  }
+
1065  } else {
+
1066  quantization_params.delta_qudc = 0;
+
1067  quantization_params.delta_quac = 0;
+
1068  quantization_params.delta_qvdc = 0;
+
1069  quantization_params.delta_qvac = 0;
+
1070  }
+
1071  bool using_qmatrix = false;
+
1072  RCHECK(reader->ReadBits(1, &using_qmatrix));
+
1073  if (using_qmatrix) {
+
1074  // Skip qm_y, qm_u.
+
1075  RCHECK(reader->SkipBits(4 + 4));
+
1076  if (color_config.separate_uv_delta_q) {
+
1077  // Skip qm_v.
+
1078  RCHECK(reader->SkipBits(4));
+
1079  }
+
1080  }
+
1081  return true;
+
1082 }
+
1083 
+
1084 // 5.9.13. Delta quantizer syntax.
+
1085 bool AV1Parser::ReadDeltaQ(BitReader* reader, int* delta_q) {
+
1086  bool delta_coded = false;
+
1087  RCHECK(reader->ReadBits(1, &delta_coded));
+
1088  if (delta_coded)
+
1089  RCHECK(ReadSu(1 + 6, reader, delta_q));
+
1090  else
+
1091  *delta_q = 0;
+
1092  return true;
+
1093 }
+
1094 
+
1095 // 5.9.14. Segmentation params syntax.
+
1096 bool AV1Parser::ParseSegmentationParams(int primary_ref_frame,
+
1097  BitReader* reader) {
+
1098  SegmentationParams& segmentation_params = frame_header_.segmentation_params;
+
1099 
+
1100  RCHECK(reader->ReadBits(1, &segmentation_params.segmentation_enabled));
+
1101  if (segmentation_params.segmentation_enabled) {
+
1102  bool segmentation_update_data = false;
+
1103  if (primary_ref_frame == kPrimaryRefNone) {
+
1104  segmentation_update_data = true;
+
1105  } else {
+
1106  // Skip segmentation_update_map, segmentation_temporal_update.
+
1107  RCHECK(reader->SkipBitsConditional(true, 1));
+
1108  RCHECK(reader->ReadBits(1, &segmentation_update_data));
+
1109  }
+
1110  if (segmentation_update_data) {
+
1111  static const int kSegmentationFeatureBits[kSegLvlMax] = {8, 6, 6, 6,
+
1112  6, 3, 0, 0};
+
1113  static const int kSegmentationFeatureSigned[kSegLvlMax] = {1, 1, 1, 1,
+
1114  1, 0, 0, 0};
+
1115  const int kMaxLoopFilter = 63;
+
1116  static const int kSegmentationFeatureMax[kSegLvlMax] = {255,
+
1117  kMaxLoopFilter,
+
1118  kMaxLoopFilter,
+
1119  kMaxLoopFilter,
+
1120  kMaxLoopFilter,
+
1121  7,
+
1122  0,
+
1123  0};
+
1124 
+
1125  for (int i = 0; i < kMaxSegments; i++) {
+
1126  for (int j = 0; j < kSegLvlMax; j++) {
+
1127  bool feature_enabled = false;
+
1128  RCHECK(reader->ReadBits(1, &feature_enabled));
+
1129  segmentation_params.feature_enabled[i][j] = feature_enabled;
+
1130  int clipped_value = 0;
+
1131  if (feature_enabled) {
+
1132  const int bits_to_read = kSegmentationFeatureBits[j];
+
1133  const int limit = kSegmentationFeatureMax[j];
+
1134  if (kSegmentationFeatureSigned[j]) {
+
1135  int feature_value = 0;
+
1136  RCHECK(ReadSu(1 + bits_to_read, reader, &feature_value));
+
1137  clipped_value = Clip3(-limit, limit, feature_value);
+
1138  } else {
+
1139  int feature_value = 0;
+
1140  RCHECK(reader->ReadBits(bits_to_read, &feature_value));
+
1141  clipped_value = Clip3(0, limit, feature_value);
+
1142  }
+
1143  }
+
1144  segmentation_params.feature_data[i][j] = clipped_value;
+
1145  }
+
1146  }
+
1147  }
+
1148  } else {
+
1149  for (int i = 0; i < kMaxSegments; i++) {
+
1150  for (int j = 0; j < kSegLvlMax; j++) {
+
1151  segmentation_params.feature_enabled[i][j] = false;
+
1152  segmentation_params.feature_data[i][j] = 0;
+
1153  }
+
1154  }
+
1155  }
+
1156  return true;
+
1157 }
+
1158 
+
1159 // 5.9.15. Tile info syntax.
+
1160 bool AV1Parser::ParseTileInfo(BitReader* reader) {
+
1161  const int kMaxTileWidth = 4096;
+
1162  const int kMaxTileArea = 4096 * 2304;
+
1163  const int kMaxTileRows = 64;
+
1164  const int kMaxTileCols = 64;
+
1165 
+
1166  TileInfo& tile_info = frame_header_.tile_info;
+
1167 
+
1168  const int sb_cols = sequence_header_.use_128x128_superblock
+
1169  ? ((frame_header_.mi_cols + 31) >> 5)
+
1170  : ((frame_header_.mi_cols + 15) >> 4);
+
1171  const int sb_rows = sequence_header_.use_128x128_superblock
+
1172  ? ((frame_header_.mi_rows + 31) >> 5)
+
1173  : ((frame_header_.mi_rows + 15) >> 4);
+
1174  const int sb_shift = sequence_header_.use_128x128_superblock ? 5 : 4;
+
1175  const int sb_size = sb_shift + 2;
+
1176  const int max_tile_width_sb = kMaxTileWidth >> sb_size;
+
1177  int max_tile_area_sb = kMaxTileArea >> (2 * sb_size);
+
1178  const int min_log2_tile_cols = TileLog2(max_tile_width_sb, sb_cols);
+
1179  const int max_log2_tile_cols = TileLog2(1, std::min(sb_cols, kMaxTileCols));
+
1180  const int max_log2_tile_rows = TileLog2(1, std::min(sb_rows, kMaxTileRows));
+
1181  const int min_log2_tiles = std::max(
+
1182  min_log2_tile_cols, TileLog2(max_tile_area_sb, sb_rows * sb_cols));
+
1183 
+
1184  bool uniform_tile_spacing_flag = false;
+
1185  RCHECK(reader->ReadBits(1, &uniform_tile_spacing_flag));
+
1186  if (uniform_tile_spacing_flag) {
+
1187  tile_info.tile_cols_log2 = min_log2_tile_cols;
+
1188  while (tile_info.tile_cols_log2 < max_log2_tile_cols) {
+
1189  bool increment_tile_cols_log2 = false;
+
1190  RCHECK(reader->ReadBits(1, &increment_tile_cols_log2));
+
1191  if (increment_tile_cols_log2)
+
1192  tile_info.tile_cols_log2++;
+
1193  else
+
1194  break;
+
1195  }
+
1196  const int tile_width_sb = (sb_cols + (1 << tile_info.tile_cols_log2) - 1) >>
+
1197  tile_info.tile_cols_log2;
+
1198  int i = 0;
+
1199  for (int start_sb = 0; start_sb < sb_cols; start_sb += tile_width_sb) {
+
1200  i += 1;
+
1201  }
+
1202  tile_info.tile_cols = i;
+
1203 
+
1204  const int min_log2_tile_rows =
+
1205  std::max(min_log2_tiles - tile_info.tile_cols_log2, 0);
+
1206  tile_info.tile_rows_log2 = min_log2_tile_rows;
+
1207  while (tile_info.tile_rows_log2 < max_log2_tile_rows) {
+
1208  bool increment_tile_rows_log2 = false;
+
1209  RCHECK(reader->ReadBits(1, &increment_tile_rows_log2));
+
1210  if (increment_tile_rows_log2)
+
1211  tile_info.tile_rows_log2++;
+
1212  else
+
1213  break;
+
1214  }
+
1215  const int tile_height_sb =
+
1216  (sb_rows + (1 << tile_info.tile_rows_log2) - 1) >>
+
1217  tile_info.tile_rows_log2;
+
1218  i = 0;
+
1219  for (int start_sb = 0; start_sb < sb_rows; start_sb += tile_height_sb) {
+
1220  i += 1;
+
1221  }
+
1222  tile_info.tile_rows = i;
+
1223  } else {
+
1224  int widest_tile_sb = 0;
+
1225  int start_sb = 0;
+
1226  int i = 0;
+
1227  for (; start_sb < sb_cols; i++) {
+
1228  const int max_width = std::min(sb_cols - start_sb, max_tile_width_sb);
+
1229  int width_in_sbs_minus_1 = 0;
+
1230  RCHECK(ReadNs(max_width, reader, &width_in_sbs_minus_1));
+
1231  const int size_sb = width_in_sbs_minus_1 + 1;
+
1232  widest_tile_sb = std::max(size_sb, widest_tile_sb);
+
1233  start_sb += size_sb;
+
1234  }
+
1235  tile_info.tile_cols = i;
+
1236  tile_info.tile_cols_log2 = TileLog2(1, tile_info.tile_cols);
+
1237 
+
1238  if (min_log2_tiles > 0)
+
1239  max_tile_area_sb = (sb_rows * sb_cols) >> (min_log2_tiles + 1);
+
1240  else
+
1241  max_tile_area_sb = sb_rows * sb_cols;
+
1242  const int max_tile_height_sb =
+
1243  std::max(max_tile_area_sb / widest_tile_sb, 1);
+
1244 
+
1245  start_sb = 0;
+
1246  i = 0;
+
1247  for (; start_sb < sb_rows; i++) {
+
1248  const int max_height = std::min(sb_rows - start_sb, max_tile_height_sb);
+
1249  int height_in_sbs_minus_1 = 0;
+
1250  RCHECK(ReadNs(max_height, reader, &height_in_sbs_minus_1));
+
1251  const int size_sb = height_in_sbs_minus_1 + 1;
+
1252  start_sb += size_sb;
+
1253  }
+
1254  tile_info.tile_rows = i;
+
1255  tile_info.tile_rows_log2 = TileLog2(1, tile_info.tile_rows);
+
1256  }
+
1257  if (tile_info.tile_cols_log2 > 0 || tile_info.tile_rows_log2 > 0) {
+
1258  // Skip context_update_tile_id.
+
1259  RCHECK(
+
1260  reader->SkipBits(tile_info.tile_rows_log2 + tile_info.tile_cols_log2));
+
1261  int tile_size_bytes_minus_1 = 0;
+
1262  RCHECK(reader->ReadBits(2, &tile_size_bytes_minus_1));
+
1263  tile_info.tile_size_bytes = tile_size_bytes_minus_1 + 1;
+
1264  }
+
1265  return true;
+
1266 }
+
1267 
+
1268 // 5.9.17. Quantizer index delta parameters syntax.
+
1269 bool AV1Parser::SkipDeltaQParams(BitReader* reader, bool* delta_q_present) {
+
1270  *delta_q_present = false;
+
1271  if (frame_header_.quantization_params.base_q_idx > 0)
+
1272  RCHECK(reader->ReadBits(1, delta_q_present));
+
1273  if (*delta_q_present) {
+
1274  // Skip delta_q_res.
+
1275  RCHECK(reader->SkipBits(2));
+
1276  }
+
1277  return true;
+
1278 }
+
1279 
+
1280 // 5.9.18. Loop filter delta parameters syntax.
+
1281 bool AV1Parser::SkipDeltaLfParams(bool delta_q_present,
+
1282  bool allow_intrabc,
+
1283  BitReader* reader) {
+
1284  bool delta_lf_present = false;
+
1285  if (delta_q_present) {
+
1286  if (!allow_intrabc)
+
1287  RCHECK(reader->ReadBits(1, &delta_lf_present));
+
1288  if (delta_lf_present) {
+
1289  // Skip delta_lf_res, delta_lf_multi.
+
1290  RCHECK(reader->SkipBits(2 + 1));
+
1291  }
+
1292  }
+
1293  return true;
+
1294 }
+
1295 
+
1296 // 5.9.19. CDEF params syntax.
+
1297 bool AV1Parser::ParseCdefParams(bool coded_lossless,
+
1298  bool allow_intrabc,
+
1299  BitReader* reader) {
+
1300  if (coded_lossless || allow_intrabc || !sequence_header_.enable_cdef)
+
1301  return true;
+
1302 
+
1303  // Skip cdef_damping_minus_3.
+
1304  RCHECK(reader->SkipBits(2));
+
1305  int cdef_bits = 0;
+
1306  RCHECK(reader->ReadBits(2, &cdef_bits));
+
1307  for (int i = 0; i < (1 << cdef_bits); i++) {
+
1308  // Skip cdef_y_pri_strength[i], Skip cdef_y_sec_strength[i].
+
1309  RCHECK(reader->SkipBits(4 + 2));
+
1310  if (sequence_header_.color_config.num_planes > 1) {
+
1311  // Skip cdef_uv_pri_strength[i], Skip cdef_uv_sec_strength[i].
+
1312  RCHECK(reader->SkipBits(4 + 2));
+
1313  }
+
1314  }
+
1315  return true;
+
1316 }
+
1317 
+
1318 // 5.9.20. Loop restoration params syntax.
+
1319 bool AV1Parser::ParseLrParams(bool all_lossless,
+
1320  bool allow_intrabc,
+
1321  BitReader* reader) {
+
1322  if (all_lossless || allow_intrabc || !sequence_header_.enable_restoration)
+
1323  return true;
+
1324 
+
1325  enum FrameRestorationType {
+
1326  RESTORE_NONE = 0,
+
1327  RESTORE_SWITCHABLE = 3,
+
1328  RESTORE_WIENER = 1,
+
1329  RESTORE_SGRPROJ = 2,
+
1330  };
+
1331  static const int kRemapLrType[4] = {RESTORE_NONE, RESTORE_SWITCHABLE,
+
1332  RESTORE_WIENER, RESTORE_SGRPROJ};
+
1333  bool uses_lr = false;
+
1334  bool uses_chroma_lr = false;
+
1335  for (int i = 0; i < sequence_header_.color_config.num_planes; i++) {
+
1336  int lr_type = 0;
+
1337  RCHECK(reader->ReadBits(2, &lr_type));
+
1338  const int frame_restoration_type = kRemapLrType[lr_type];
+
1339  if (frame_restoration_type != RESTORE_NONE) {
+
1340  uses_lr = true;
+
1341  if (i > 0)
+
1342  uses_chroma_lr = true;
+
1343  }
+
1344  }
+
1345 
+
1346  if (uses_lr) {
+
1347  if (sequence_header_.use_128x128_superblock) {
+
1348  // Skip lr_unit_shift.
+
1349  RCHECK(reader->SkipBits(1));
+
1350  } else {
+
1351  // Skip lr_unit_shift, lr_unit_extra_shift.
+
1352  RCHECK(reader->SkipBitsConditional(true, 1));
+
1353  }
+
1354  if (sequence_header_.color_config.subsampling_x &&
+
1355  sequence_header_.color_config.subsampling_y && uses_chroma_lr) {
+
1356  // Skip lr_uv_shift.
+
1357  RCHECK(reader->SkipBits(1));
+
1358  }
+
1359  }
+
1360  return true;
+
1361 }
+
1362 
+
1363 // 5.9.21. TX mode syntax.
+
1364 bool AV1Parser::SkipTxMode(bool coded_lossless, BitReader* reader) {
+
1365  if (!coded_lossless) {
+
1366  // Skip tx_mode_select.
+
1367  RCHECK(reader->SkipBits(1));
+
1368  }
+
1369  return true;
+
1370 }
+
1371 
+
1372 // 5.9.22. Skip mode params syntax.
+
1373 bool AV1Parser::SkipSkipModeParams(bool frame_is_intra,
+
1374  bool reference_select,
+
1375  BitReader* reader) {
+
1376  bool skip_mode_allowed = false;
+
1377  if (frame_is_intra || !reference_select ||
+
1378  !sequence_header_.enable_order_hint) {
+
1379  skip_mode_allowed = false;
+
1380  } else {
+
1381  int forward_idx = -1;
+
1382  int forward_hint = 0;
+
1383  int backward_idx = -1;
+
1384  int backward_hint = 0;
+
1385  for (int i = 0; i < kRefsPerFrame; i++) {
+
1386  const int ref_hint =
+
1387  reference_frames_[frame_header_.ref_frame_idx[i]].order_hint;
+
1388  if (GetRelativeDist(ref_hint, frame_header_.order_hint) < 0) {
+
1389  if (forward_idx < 0 || GetRelativeDist(ref_hint, forward_hint) > 0) {
+
1390  forward_idx = i;
+
1391  forward_hint = ref_hint;
+
1392  }
+
1393  } else if (GetRelativeDist(ref_hint, frame_header_.order_hint) > 0) {
+
1394  if (backward_idx < 0 || GetRelativeDist(ref_hint, backward_hint) < 0) {
+
1395  backward_idx = i;
+
1396  backward_hint = ref_hint;
+
1397  }
+
1398  }
+
1399  }
+
1400  if (forward_idx < 0) {
+
1401  skip_mode_allowed = false;
+
1402  } else if (backward_idx >= 0) {
+
1403  skip_mode_allowed = true;
+
1404  } else {
+
1405  int second_forward_idx = -1;
+
1406  int second_forward_hint = 0;
+
1407  for (int i = 0; i < kRefsPerFrame; i++) {
+
1408  const int ref_hint =
+
1409  reference_frames_[frame_header_.ref_frame_idx[i]].order_hint;
+
1410  if (GetRelativeDist(ref_hint, forward_hint) < 0) {
+
1411  if (second_forward_idx < 0 ||
+
1412  GetRelativeDist(ref_hint, second_forward_hint) > 0) {
+
1413  second_forward_idx = i;
+
1414  second_forward_hint = ref_hint;
+
1415  }
+
1416  }
+
1417  }
+
1418  skip_mode_allowed = second_forward_idx >= 0;
+
1419  }
+
1420  }
+
1421 
+
1422  if (skip_mode_allowed) {
+
1423  // Skip skip_mode_present.
+
1424  RCHECK(reader->SkipBits(1));
+
1425  }
+
1426  return true;
+
1427 }
+
1428 
+
1429 // 5.9.23. Frame reference mode syntax.
+
1430 bool AV1Parser::ParseFrameReferenceMode(bool frame_is_intra,
+
1431  BitReader* reader,
+
1432  bool* reference_select) {
+
1433  if (frame_is_intra)
+
1434  *reference_select = false;
+
1435  else
+
1436  RCHECK(reader->ReadBits(1, reference_select));
+
1437  return true;
+
1438 }
+
1439 
+
1440 // 5.9.24. Global motion params syntax.
+
1441 bool AV1Parser::SkipGlobalMotionParams(bool frame_is_intra,
+
1442  bool allow_high_precision_mv,
+
1443  BitReader* reader) {
+
1444  if (frame_is_intra)
+
1445  return true;
+
1446 
+
1447  for (int ref = LAST_FRAME; ref <= ALTREF_FRAME; ref++) {
+
1448  int type = 0;
+
1449 
+
1450  bool is_global = false;
+
1451  RCHECK(reader->ReadBits(1, &is_global));
+
1452  if (is_global) {
+
1453  bool is_rot_zoom = false;
+
1454  RCHECK(reader->ReadBits(1, &is_rot_zoom));
+
1455  if (is_rot_zoom) {
+
1456  type = ROTZOOM;
+
1457  } else {
+
1458  bool is_translation = false;
+
1459  RCHECK(reader->ReadBits(1, &is_translation));
+
1460  type = is_translation ? TRANSLATION : AFFINE;
+
1461  }
+
1462  } else {
+
1463  type = IDENTITY;
+
1464  }
+
1465 
+
1466  if (type >= ROTZOOM) {
+
1467  RCHECK(SkipGlobalParam(type, ref, 2, allow_high_precision_mv, reader));
+
1468  RCHECK(SkipGlobalParam(type, ref, 3, allow_high_precision_mv, reader));
+
1469  if (type == AFFINE) {
+
1470  RCHECK(SkipGlobalParam(type, ref, 4, allow_high_precision_mv, reader));
+
1471  RCHECK(SkipGlobalParam(type, ref, 5, allow_high_precision_mv, reader));
+
1472  }
+
1473  }
+
1474  if (type >= TRANSLATION) {
+
1475  RCHECK(SkipGlobalParam(type, ref, 0, allow_high_precision_mv, reader));
+
1476  RCHECK(SkipGlobalParam(type, ref, 1, allow_high_precision_mv, reader));
+
1477  }
+
1478  }
+
1479  return true;
+
1480 }
+
1481 
+
1482 // 5.9.25. Global param syntax.
+
1483 bool AV1Parser::SkipGlobalParam(int type,
+
1484  int ref,
+
1485  int idx,
+
1486  bool allow_high_precision_mv,
+
1487  BitReader* reader) {
+
1488  const int kGmAbsTransBits = 12;
+
1489  const int kGmAbsTransOnlyBits = 9;
+
1490  const int kGmAbsAlphaBits = 12;
+
1491 
+
1492  int abs_bits = kGmAbsAlphaBits;
+
1493  if (idx < 2) {
+
1494  if (type == TRANSLATION) {
+
1495  abs_bits = kGmAbsTransOnlyBits - (allow_high_precision_mv ? 0 : 1);
+
1496  } else {
+
1497  abs_bits = kGmAbsTransBits;
+
1498  }
+
1499  }
+
1500  const int mx = 1 << abs_bits;
+
1501  RCHECK(SkipDecodeSignedSubexpWithRef(-mx, mx + 1, reader));
+
1502  return true;
+
1503 }
+
1504 
+
1505 // 5.9.26. Decode signed subexp with ref syntax.
+
1506 bool AV1Parser::SkipDecodeSignedSubexpWithRef(int low,
+
1507  int high,
+
1508  BitReader* reader) {
+
1509  RCHECK(SkipDecodeUnsignedSubexpWithRef(high - low, reader));
+
1510  return true;
+
1511 }
+
1512 
+
1513 // 5.9.27. Decode unsigned subbexp with ref syntax.
+
1514 bool AV1Parser::SkipDecodeUnsignedSubexpWithRef(int mx, BitReader* reader) {
+
1515  RCHECK(SkipDecodeSubexp(mx, reader));
+
1516  return true;
+
1517 }
+
1518 
+
1519 // 5.9.28. Decode subexp syntax.
+
1520 bool AV1Parser::SkipDecodeSubexp(int num_syms, BitReader* reader) {
+
1521  int i = 0;
+
1522  int mk = 0;
+
1523  int k = 3;
+
1524  while (true) {
+
1525  const int b2 = i ? (k + i - 1) : k;
+
1526  const int a = 1 << b2;
+
1527  if (num_syms <= mk + 3 * a) {
+
1528  int subexp_final_bits = 0;
+
1529  RCHECK(ReadNs(num_syms - mk, reader, &subexp_final_bits));
+
1530  return true;
+
1531  } else {
+
1532  bool subexp_more_bits = false;
+
1533  RCHECK(reader->ReadBits(1, &subexp_more_bits));
+
1534  if (subexp_more_bits) {
+
1535  i++;
+
1536  mk += a;
+
1537  } else {
+
1538  // Skip subexp_bits.
+
1539  RCHECK(reader->SkipBits(b2));
+
1540  return true;
+
1541  }
+
1542  }
+
1543  }
+
1544  return true;
+
1545 }
+
1546 
+
1547 // 5.9.30. Film grain params syntax.
+
1548 bool AV1Parser::SkipFilmGrainParams(bool show_frame,
+
1549  bool showable_frame,
+
1550  BitReader* reader) {
+
1551  if (!sequence_header_.film_grain_params_present ||
+
1552  (!show_frame && !showable_frame)) {
+
1553  return true;
+
1554  }
+
1555 
+
1556  bool apply_grain = false;
+
1557  RCHECK(reader->ReadBits(1, &apply_grain));
+
1558  if (!apply_grain)
+
1559  return true;
+
1560 
+
1561  // Skip grain_seed.
+
1562  RCHECK(reader->SkipBits(16));
+
1563  bool update_grain = true;
+
1564  if (frame_header_.frame_type == INTER_FRAME)
+
1565  RCHECK(reader->ReadBits(1, &update_grain));
+
1566  if (!update_grain) {
+
1567  // Skip film_grain_params_ref_idx.
+
1568  RCHECK(reader->SkipBits(3));
+
1569  return true;
+
1570  }
+
1571 
+
1572  int num_y_points = 0;
+
1573  RCHECK(reader->ReadBits(4, &num_y_points));
+
1574  // Skip point_y_value, point_y_scaling.
+
1575  RCHECK(reader->SkipBits((8 + 8) * num_y_points));
+
1576 
+
1577  const ColorConfig& color_config = sequence_header_.color_config;
+
1578  bool chroma_scaling_from_luma = false;
+
1579  if (!color_config.mono_chrome)
+
1580  RCHECK(reader->ReadBits(1, &chroma_scaling_from_luma));
+
1581  int num_cb_points = 0;
+
1582  int num_cr_points = 0;
+
1583  if (color_config.mono_chrome || chroma_scaling_from_luma ||
+
1584  (color_config.subsampling_x && color_config.subsampling_y &&
+
1585  num_y_points == 0)) {
+
1586  num_cb_points = 0;
+
1587  num_cr_points = 0;
+
1588  } else {
+
1589  RCHECK(reader->ReadBits(4, &num_cb_points));
+
1590  // Skip point_cb_value, point_cb_scaling.
+
1591  RCHECK(reader->SkipBits((8 + 8) * num_cb_points));
+
1592  RCHECK(reader->ReadBits(4, &num_cr_points));
+
1593  // Skip point_cr_value, point_cr_scaling.
+
1594  RCHECK(reader->SkipBits((8 + 8) * num_cr_points));
+
1595  }
+
1596 
+
1597  // Skip grain_scaling_minus_8.
+
1598  RCHECK(reader->SkipBits(2));
+
1599  int ar_coeff_lag = 0;
+
1600  RCHECK(reader->ReadBits(2, &ar_coeff_lag));
+
1601  const int num_pos_luma = 2 * ar_coeff_lag * (ar_coeff_lag + 1);
+
1602  int num_pos_chroma = num_pos_luma;
+
1603  if (num_y_points) {
+
1604  num_pos_chroma = num_pos_luma + 1;
+
1605  // Skip ar_coeffs_y_plus_128.
+
1606  RCHECK(reader->SkipBits(8 * num_pos_luma));
+
1607  }
+
1608  if (chroma_scaling_from_luma || num_cb_points) {
+
1609  // Skip ar_coeffs_cb_plus_128.
+
1610  RCHECK(reader->SkipBits(8 * num_pos_chroma));
+
1611  }
+
1612  if (chroma_scaling_from_luma || num_cr_points) {
+
1613  // Skip ar_coeffs_cb_plus_128.
+
1614  RCHECK(reader->SkipBits(8 * num_pos_chroma));
+
1615  }
+
1616 
+
1617  // Skip ar_coeff_shift_minus_6, grain_scale_shift.
+
1618  RCHECK(reader->SkipBits(2 + 2));
+
1619  if (num_cb_points) {
+
1620  // Skip cb_mult, cb_luma_mult, cb_offset.
+
1621  RCHECK(reader->SkipBits(8 + 8 + 9));
+
1622  }
+
1623  if (num_cr_points) {
+
1624  // Skip cr_mult, cr_luma_mult, cr_offset.
+
1625  RCHECK(reader->SkipBits(8 + 8 + 9));
+
1626  }
+
1627  // Skip overlap_flag, clip_restricted_range.
+
1628  RCHECK(reader->SkipBits(1 + 1));
+
1629  return true;
+
1630 }
+
1631 
+
1632 // 5.9.31. Temporal point info syntax.
+
1633 bool AV1Parser::SkipTemporalPointInfo(BitReader* reader) {
+
1634  const int frame_presentation_time_length =
+
1635  sequence_header_.decoder_model_info
+
1636  .frame_presentation_time_length_minus_1 +
+
1637  1;
+
1638  // Skip frame_presentation_time.
+
1639  RCHECK(reader->SkipBits(frame_presentation_time_length));
+
1640  return true;
+
1641 }
+
1642 
+
1643 // 5.10. Frame OBU syntax.
+
1644 bool AV1Parser::ParseFrameObu(const ObuHeader& obu_header,
+
1645  size_t size,
+
1646  BitReader* reader,
+
1647  std::vector<Tile>* tiles) {
+
1648  const size_t start_bit_pos = reader->bit_position();
+
1649  RCHECK(ParseFrameHeaderObu(obu_header, reader));
+
1650  RCHECK(ByteAlignment(reader));
+
1651  const size_t end_bit_pos = reader->bit_position();
+
1652  const size_t header_bytes = (end_bit_pos - start_bit_pos) / 8;
+
1653  RCHECK(ParseTileGroupObu(size - header_bytes, reader, tiles));
+
1654  return true;
+
1655 }
+
1656 
+
1657 // 5.11.1. General tile group OBU syntax.
+
1658 bool AV1Parser::ParseTileGroupObu(size_t size,
+
1659  BitReader* reader,
+
1660  std::vector<Tile>* tiles) {
+
1661  const TileInfo& tile_info = frame_header_.tile_info;
+
1662  const size_t start_bit_pos = reader->bit_position();
+
1663 
+
1664  const int num_tiles = tile_info.tile_cols * tile_info.tile_rows;
+
1665  bool tile_start_and_end_present_flag = false;
+
1666  if (num_tiles > 1)
+
1667  RCHECK(reader->ReadBits(1, &tile_start_and_end_present_flag));
+
1668 
+
1669  int tg_start = 0;
+
1670  int tg_end = num_tiles - 1;
+
1671  if (num_tiles > 1 && tile_start_and_end_present_flag) {
+
1672  const int tile_bits = tile_info.tile_cols_log2 + tile_info.tile_rows_log2;
+
1673  RCHECK(reader->ReadBits(tile_bits, &tg_start));
+
1674  RCHECK(reader->ReadBits(tile_bits, &tg_end));
+
1675  }
+
1676  RCHECK(ByteAlignment(reader));
+
1677 
+
1678  const size_t end_bit_pos = reader->bit_position();
+
1679  const size_t header_bytes = (end_bit_pos - start_bit_pos) / 8;
+
1680  size -= header_bytes;
+
1681 
+
1682  for (int tile_num = tg_start; tile_num <= tg_end; tile_num++) {
+
1683  const bool last_tile = tile_num == tg_end;
+
1684  size_t tile_size = size;
+
1685  if (!last_tile) {
+
1686  size_t tile_size_minus_1 = 0;
+
1687  RCHECK(ReadLe(tile_info.tile_size_bytes, reader, &tile_size_minus_1));
+
1688  tile_size = tile_size_minus_1 + 1;
+
1689  size -= tile_size + tile_info.tile_size_bytes;
+
1690  }
+
1691  tiles->push_back({reader->bit_position() / 8, tile_size});
+
1692  RCHECK(reader->SkipBits(tile_size * 8)); // Skip the tile.
+
1693  }
+
1694 
+
1695  if (tg_end == num_tiles - 1) {
+
1696  DecodeFrameWrapup();
+
1697  frame_header_.seen_frame_header = false;
+
1698  }
+
1699  return true;
+
1700 }
+
1701 
+
1702 // 5.11.14. Segmentation feature active function.
+
1703 bool AV1Parser::SegFeatureActiveIdx(int idx, int feature) {
+
1704  const SegmentationParams& segmentation_params =
+
1705  frame_header_.segmentation_params;
+
1706  return segmentation_params.segmentation_enabled &&
+
1707  segmentation_params.feature_enabled[idx][feature];
+
1708 }
+
1709 
+
1710 // 7.4. Decode frame wrapup process.
+
1711 void AV1Parser::DecodeFrameWrapup() {
+
1712  const int refresh_frame_flags = frame_header_.refresh_frame_flags;
+
1713  if (frame_header_.show_existing_frame &&
+
1714  frame_header_.frame_type == KEY_FRAME) {
+
1715  // 7.21. Reference frame loading process.
+
1716  const ReferenceFrame& reference_frame =
+
1717  reference_frames_[frame_header_.frame_to_show_map_idx];
+
1718 
+
1719  frame_header_.upscaled_width = reference_frame.upscaled_width;
+
1720  frame_header_.frame_width = reference_frame.frame_width;
+
1721  frame_header_.frame_height = reference_frame.frame_height;
+
1722  frame_header_.render_width = reference_frame.render_width;
+
1723  frame_header_.render_height = reference_frame.render_height;
+
1724  frame_header_.mi_cols = reference_frame.mi_cols;
+
1725  frame_header_.mi_rows = reference_frame.mi_rows;
+
1726 
+
1727  ColorConfig& color_config = sequence_header_.color_config;
+
1728  color_config.subsampling_x = reference_frame.subsampling_x;
+
1729  color_config.subsampling_y = reference_frame.subsampling_y;
+
1730  color_config.bit_depth = reference_frame.bit_depth;
+
1731 
+
1732  frame_header_.order_hint = reference_frame.order_hint;
+
1733  }
+
1734  // 7.20. Reference frame update process.
+
1735  for (int i = 0; i <= kNumRefFrames - 1; i++) {
+
1736  if ((refresh_frame_flags >> i) & 1) {
+
1737  ReferenceFrame& reference_frame = reference_frames_[i];
+
1738 
+
1739  reference_frame.upscaled_width = frame_header_.upscaled_width;
+
1740  reference_frame.frame_width = frame_header_.frame_width;
+
1741  reference_frame.frame_height = frame_header_.frame_height;
+
1742  reference_frame.render_width = frame_header_.render_width;
+
1743  reference_frame.render_height = frame_header_.render_height;
+
1744  reference_frame.mi_cols = frame_header_.mi_cols;
+
1745  reference_frame.mi_rows = frame_header_.mi_rows;
+
1746  reference_frame.frame_type = frame_header_.frame_type;
+
1747 
+
1748  const ColorConfig& color_config = sequence_header_.color_config;
+
1749  reference_frame.subsampling_x = color_config.subsampling_x;
+
1750  reference_frame.subsampling_y = color_config.subsampling_y;
+
1751  reference_frame.bit_depth = color_config.bit_depth;
+
1752 
+
1753  reference_frame.order_hint = frame_header_.order_hint;
+
1754  }
+
1755  }
+
1756 }
+
1757 
+
1758 // 7.8. Set frame refs process.
+
1759 bool AV1Parser::SetFrameRefs(int last_frame_idx, int gold_frame_idx) {
+
1760  for (int i = 0; i < kRefsPerFrame; i++)
+
1761  frame_header_.ref_frame_idx[i] = -1;
+
1762  frame_header_.ref_frame_idx[LAST_FRAME - LAST_FRAME] = last_frame_idx;
+
1763  frame_header_.ref_frame_idx[GOLDEN_FRAME - LAST_FRAME] = gold_frame_idx;
+
1764 
+
1765  bool used_frame[kNumRefFrames] = {};
+
1766  used_frame[last_frame_idx] = true;
+
1767  used_frame[gold_frame_idx] = true;
+
1768 
+
1769  const int cur_frame_hint = 1 << (sequence_header_.order_hint_bits - 1);
+
1770 
+
1771  // An array containing the expected output order shifted such that the
+
1772  // current frame has hint equal to |cur_frame_hint| is prepared.
+
1773  int shifted_order_hints[kNumRefFrames];
+
1774  for (int i = 0; i < kNumRefFrames; i++) {
+
1775  shifted_order_hints[i] =
+
1776  cur_frame_hint + GetRelativeDist(reference_frames_[i].order_hint,
+
1777  frame_header_.order_hint);
+
1778  }
+
1779 
+
1780  const int last_order_hint = shifted_order_hints[last_frame_idx];
+
1781  RCHECK(last_order_hint < cur_frame_hint);
+
1782  const int gold_order_hint = shifted_order_hints[gold_frame_idx];
+
1783  RCHECK(gold_order_hint < cur_frame_hint);
+
1784 
+
1785  // The ALTREF_FRAME reference is set to be a backward reference to the frame
+
1786  // with highest output order.
+
1787  int ref = FindLatestBackward(shifted_order_hints, used_frame, cur_frame_hint);
+
1788  if (ref >= 0) {
+
1789  frame_header_.ref_frame_idx[ALTREF_FRAME - LAST_FRAME] = ref;
+
1790  used_frame[ref] = true;
+
1791  }
+
1792 
+
1793  // The BWDREF_FRAME reference is set to be a backward reference to the cloest
+
1794  // frame.
+
1795  ref = FindEarliestBackward(shifted_order_hints, used_frame, cur_frame_hint);
+
1796  if (ref >= 0) {
+
1797  frame_header_.ref_frame_idx[BWDREF_FRAME - LAST_FRAME] = ref;
+
1798  used_frame[ref] = true;
+
1799  }
+
1800 
+
1801  // The ALTREF2_FRAME reference is set to the next closest backward reference.
+
1802  ref = FindEarliestBackward(shifted_order_hints, used_frame, cur_frame_hint);
+
1803  if (ref >= 0) {
+
1804  frame_header_.ref_frame_idx[ALTREF2_FRAME - LAST_FRAME] = ref;
+
1805  used_frame[ref] = true;
+
1806  }
+
1807 
+
1808  // The remaining references are set to be forward references in
+
1809  // anti-chronological order.
+
1810  static const int kRefFrameList[] = {
+
1811  LAST2_FRAME, LAST3_FRAME, BWDREF_FRAME, ALTREF2_FRAME, ALTREF_FRAME,
+
1812  };
+
1813  static_assert(arraysize(kRefFrameList) == kRefsPerFrame - 2,
+
1814  "Unexpected kRefFrameList size.");
+
1815  for (const int ref_frame : kRefFrameList) {
+
1816  if (frame_header_.ref_frame_idx[ref_frame - LAST_FRAME] < 0) {
+
1817  ref = FindLatestForward(shifted_order_hints, used_frame, cur_frame_hint);
+
1818  if (ref >= 0) {
+
1819  frame_header_.ref_frame_idx[ref_frame - LAST_FRAME] = ref;
+
1820  used_frame[ref] = true;
+
1821  }
+
1822  }
+
1823  }
+
1824 
+
1825  // Finally, any remaining references are set to the reference frame with
+
1826  // smallest output order.
+
1827  ref = -1;
+
1828  int earliest_order_hint = 0;
+
1829  for (int i = 0; i < kNumRefFrames; i++) {
+
1830  const int hint = shifted_order_hints[i];
+
1831  if (ref < 0 || hint < earliest_order_hint) {
+
1832  ref = i;
+
1833  earliest_order_hint = hint;
+
1834  }
+
1835  }
+
1836  for (int i = 0; i < kRefsPerFrame; i++) {
+
1837  if (frame_header_.ref_frame_idx[i] < 0) {
+
1838  frame_header_.ref_frame_idx[i] = ref;
+
1839  }
+
1840  }
+
1841 
+
1842  return true;
+
1843 }
+
1844 
+
1845 // 7.12.2. Dequantization functions. The function returns the quantizer index
+
1846 // for the current block.
+
1847 int AV1Parser::GetQIndex(bool ignore_delta_q, int segment_id) {
+
1848  // We do not have use case for ignore_delta_q false case.
+
1849  CHECK(ignore_delta_q) << "ignoreDeltaQ equal to 0 is not supported.";
+
1850 
+
1851  const int base_q_idx = frame_header_.quantization_params.base_q_idx;
+
1852 
+
1853  const int kSegLvlAltQ = 0;
+
1854  if (SegFeatureActiveIdx(segment_id, kSegLvlAltQ)) {
+
1855  const int data =
+
1856  frame_header_.segmentation_params.feature_data[segment_id][kSegLvlAltQ];
+
1857  const int qindex = base_q_idx + data;
+
1858  return Clip3(0, 255, qindex);
+
1859  } else {
+
1860  return base_q_idx;
+
1861  }
+
1862 }
+
1863 
+
1864 } // namespace media
+
1865 } // namespace shaka
+
virtual bool Parse(const uint8_t *data, size_t data_size, std::vector< Tile > *tiles)
Definition: av1_parser.cc:255
+
A class to read bit streams.
Definition: bit_reader.h:17
+
size_t bit_position() const
Definition: bit_reader.h:94
+
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
+
size_t bits_available() const
Definition: bit_reader.h:89
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/dbf/status__macros_8h_source.html b/docs/d2/dbf/status__macros_8h_source.html index bc67fbd5be..6956bd3541 100644 --- a/docs/d2/dbf/status__macros_8h_source.html +++ b/docs/d2/dbf/status__macros_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/status_macros.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
status_macros.h
-
1 // Copyright 2018 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_STATUS_MACROS_H_
8 #define PACKAGER_STATUS_MACROS_H_
9 
10 #include "packager/status.h"
11 
12 // Evaluates an expression that produces a `Status`. If the status is not
13 // ok, returns it from the current function.
14 #define RETURN_IF_ERROR(expr) \
15  do { \
16  /* Using _status below to avoid capture problems if expr is "status". */ \
17  shaka::Status _status = (expr); \
18  if (!_status.ok()) \
19  return _status; \
20  } while (0)
21 
22 // TODO(kqyang): Support build Status and update Status message through "<<".
23 
24 #endif // PACKAGER_STATUS_MACROS_H_
+
1 // Copyright 2018 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_STATUS_MACROS_H_
+
8 #define PACKAGER_STATUS_MACROS_H_
+
9 
+
10 #include "packager/status.h"
+
11 
+
12 // Evaluates an expression that produces a `Status`. If the status is not
+
13 // ok, returns it from the current function.
+
14 #define RETURN_IF_ERROR(expr) \
+
15  do { \
+
16  /* Using _status below to avoid capture problems if expr is "status". */ \
+
17  shaka::Status _status = (expr); \
+
18  if (!_status.ok()) \
+
19  return _status; \
+
20  } while (0)
+
21 
+
22 // TODO(kqyang): Support build Status and update Status message through "<<".
+
23 
+
24 #endif // PACKAGER_STATUS_MACROS_H_
+
diff --git a/docs/d2/dc3/structshaka_1_1media_1_1mp4_1_1Track-members.html b/docs/d2/dc3/structshaka_1_1media_1_1mp4_1_1Track-members.html index 5b128bbde1..c78dbeb627 100644 --- a/docs/d2/dc3/structshaka_1_1media_1_1mp4_1_1Track-members.html +++ b/docs/d2/dc3/structshaka_1_1media_1_1mp4_1_1Track-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d2/dc7/media__handler__test__base_8cc_source.html b/docs/d2/dc7/media__handler__test__base_8cc_source.html index b8a58bd8e9..12d0d43a37 100644 --- a/docs/d2/dc7/media__handler__test__base_8cc_source.html +++ b/docs/d2/dc7/media__handler__test__base_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/media_handler_test_base.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
media_handler_test_base.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/media_handler_test_base.h"
8 
9 #include "packager/media/base/audio_stream_info.h"
10 #include "packager/media/base/text_stream_info.h"
11 #include "packager/media/base/video_stream_info.h"
12 #include "packager/status_test_util.h"
13 
14 namespace {
15 
16 const int kTrackId = 1;
17 const uint64_t kDuration = 10000;
18 const char kCodecString[] = "codec string";
19 const uint8_t kSampleBits = 1;
20 const uint8_t kNumChannels = 2;
21 const uint32_t kSamplingFrequency = 48000;
22 const uint64_t kSeekPrerollNs = 12345;
23 const uint64_t kCodecDelayNs = 56789;
24 const uint32_t kMaxBitrate = 13579;
25 const uint32_t kAvgBitrate = 13000;
26 const char kLanguage[] = "eng";
27 const uint16_t kWidth = 10u;
28 const uint16_t kHeight = 20u;
29 const uint32_t kPixelWidth = 2u;
30 const uint32_t kPixelHeight = 3u;
31 const uint8_t kTransferCharacteristics = 0;
32 const int16_t kTrickPlayFactor = 0;
33 const uint8_t kNaluLengthSize = 1u;
34 const bool kEncrypted = true;
35 
36 // Use H264 code config.
37 const uint8_t kCodecConfig[]{
38  // clang-format off
39  // Header
40  0x01, 0x64, 0x00, 0x1e, 0xff,
41  // SPS count (ignore top three bits)
42  0xe1,
43  // SPS
44  0x00, 0x19, // Size
45  0x67, 0x64, 0x00, 0x1e, 0xac, 0xd9, 0x40, 0xa0, 0x2f, 0xf9, 0x70, 0x11,
46  0x00, 0x00, 0x03, 0x03, 0xe9, 0x00, 0x00, 0xea, 0x60, 0x0f, 0x16, 0x2d,
47  0x96,
48  // PPS count
49  0x01,
50  // PPS
51  0x00, 0x06, // Size
52  0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
53  // clang-format on
54 };
55 
56 // Mock data, we don't really care about what is inside.
57 const uint8_t kData[]{
58  0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
59 };
60 
61 } // namespace
62 
63 namespace shaka {
64 namespace media {
65 
66 std::string BoolToString(bool value) {
67  return value ? "true" : "false";
68 }
69 
70 bool TryMatchStreamDataType(const StreamDataType& actual,
71  const StreamDataType& expected,
72  ::testing::MatchResultListener* listener) {
73  if (actual != expected) {
74  std::string expected_as_string = StreamDataTypeToString(expected);
75  std::string actual_as_string = StreamDataTypeToString(actual);
76 
77  *listener << "which is " << actual_as_string << " (expected "
78  << expected_as_string << ")";
79  return false;
80  }
81 
82  return true;
83 }
84 
85 bool TryMatchStreamType(const StreamType& actual,
86  const StreamType& expected,
87  ::testing::MatchResultListener* listener) {
88  if (actual != expected) {
89  std::string expected_as_string = StreamTypeToString(expected);
90  std::string actual_as_string = StreamTypeToString(actual);
91 
92  *listener << "which is " << actual_as_string << " (expected "
93  << expected_as_string << ")";
94  return false;
95  }
96 
97  return true;
98 }
99 
100 std::string ToPrettyString(const std::string& str) {
101  std::string out;
102 
103  // Opening quotation.
104  out.push_back('"');
105 
106  for (char c : str) {
107  if (isspace(c)) {
108  // Make all white space characters spaces to avoid print issues in
109  // the terminal.
110  out.push_back(' ');
111  } else if (isalnum(c)) {
112  // If the character is alpha-numeric, then print it as is. Just using
113  // these characters, it should be enough to understand the string.
114  out.push_back(c);
115  } else {
116  // Replace all other characters with '.'. This is to avoid print issues
117  // (e.g. \n) or readability issues (e.g. ").
118  out.push_back('.');
119  }
120  }
121 
122  // Closing quotation.
123  out.push_back('"');
124 
125  return out;
126 }
127 
128 bool FakeInputMediaHandler::ValidateOutputStreamIndex(size_t index) const {
129  return true;
130 }
131 
132 Status FakeInputMediaHandler::InitializeInternal() {
133  return Status::OK;
134 }
135 
136 Status FakeInputMediaHandler::Process(std::unique_ptr<StreamData> stream_data) {
137  return Status(error::INTERNAL_ERROR,
138  "FakeInputMediaHandler should never be a downstream handler.");
139 }
140 
141 Status MockOutputMediaHandler::InitializeInternal() {
142  return Status::OK;
143 }
144 
145 Status MockOutputMediaHandler::Process(
146  std::unique_ptr<StreamData> stream_data) {
147  OnProcess(stream_data.get());
148  return Status::OK;
149 }
150 
151 Status MockOutputMediaHandler::OnFlushRequest(size_t index) {
152  OnFlush(index);
153  return Status::OK;
154 }
155 
156 Status CachingMediaHandler::InitializeInternal() {
157  return Status::OK;
158 }
159 
160 Status CachingMediaHandler::Process(std::unique_ptr<StreamData> stream_data) {
161  stream_data_vector_.push_back(std::move(stream_data));
162  return Status::OK;
163 }
164 
165 Status CachingMediaHandler::OnFlushRequest(size_t input_stream_index) {
166  return Status::OK;
167 }
168 
169 bool CachingMediaHandler::ValidateOutputStreamIndex(size_t stream_index) const {
170  return true;
171 }
172 
173 bool MediaHandlerTestBase::IsVideoCodec(Codec codec) const {
174  return codec >= kCodecVideo && codec < kCodecVideoMaxPlusOne;
175 }
176 
177 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetVideoStreamInfo(
178  uint32_t time_scale) const {
179  return GetVideoStreamInfo(time_scale, kCodecVP9, kWidth, kHeight);
180 }
181 
182 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetVideoStreamInfo(
183  uint32_t time_scale,
184  uint32_t width,
185  uint64_t height) const {
186  return GetVideoStreamInfo(time_scale, kCodecVP9, width, height);
187 }
188 
189 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetVideoStreamInfo(
190  uint32_t time_scale,
191  Codec codec) const {
192  return GetVideoStreamInfo(time_scale, codec, kWidth, kHeight);
193 }
194 
195 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetVideoStreamInfo(
196  uint32_t time_scale,
197  Codec codec,
198  uint32_t width,
199  uint64_t height) const {
200  return std::unique_ptr<VideoStreamInfo>(new VideoStreamInfo(
201  kTrackId, time_scale, kDuration, codec, H26xStreamFormat::kUnSpecified,
202  kCodecString, kCodecConfig, sizeof(kCodecConfig), width, height,
203  kPixelWidth, kPixelHeight, kTransferCharacteristics, kTrickPlayFactor,
204  kNaluLengthSize, kLanguage, !kEncrypted));
205 }
206 
207 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetAudioStreamInfo(
208  uint32_t time_scale) const {
209  return GetAudioStreamInfo(time_scale, kCodecAAC);
210 }
211 
212 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetAudioStreamInfo(
213  uint32_t time_scale,
214  Codec codec) const {
215  return std::unique_ptr<AudioStreamInfo>(new AudioStreamInfo(
216  kTrackId, time_scale, kDuration, codec, kCodecString, kCodecConfig,
217  sizeof(kCodecConfig), kSampleBits, kNumChannels, kSamplingFrequency,
218  kSeekPrerollNs, kCodecDelayNs, kMaxBitrate, kAvgBitrate, kLanguage,
219  !kEncrypted));
220 }
221 
222 std::shared_ptr<MediaSample> MediaHandlerTestBase::GetMediaSample(
223  int64_t timestamp,
224  int64_t duration,
225  bool is_keyframe) const {
226  return GetMediaSample(timestamp, duration, is_keyframe, kData, sizeof(kData));
227 }
228 
229 std::shared_ptr<MediaSample> MediaHandlerTestBase::GetMediaSample(
230  int64_t timestamp,
231  int64_t duration,
232  bool is_keyframe,
233  const uint8_t* data,
234  size_t data_length) const {
235  std::shared_ptr<MediaSample> sample =
236  MediaSample::CopyFrom(data, data_length, nullptr, 0, is_keyframe);
237  sample->set_dts(timestamp);
238  sample->set_pts(timestamp);
239  sample->set_duration(duration);
240 
241  return sample;
242 }
243 
244 std::unique_ptr<SegmentInfo> MediaHandlerTestBase::GetSegmentInfo(
245  int64_t start_timestamp,
246  int64_t duration,
247  bool is_subsegment) const {
248  std::unique_ptr<SegmentInfo> info(new SegmentInfo);
249  info->start_timestamp = start_timestamp;
250  info->duration = duration;
251  info->is_subsegment = is_subsegment;
252 
253  return info;
254 }
255 
256 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetTextStreamInfo(
257  uint32_t timescale) const {
258  // None of this information is actually used by the text out handler.
259  // The stream info is just needed to signal the start of the stream.
260  return std::unique_ptr<StreamInfo>(
261  new TextStreamInfo(0, timescale, 0, kUnknownCodec, "", "", 0, 0, ""));
262 }
263 
264 std::unique_ptr<TextSample> MediaHandlerTestBase::GetTextSample(
265  const std::string& id,
266  int64_t start,
267  int64_t end,
268  const std::string& payload) const {
269  std::unique_ptr<TextSample> sample(new TextSample);
270  sample->set_id(id);
271  sample->SetTime(start, end);
272  sample->AppendPayload(payload);
273 
274  return sample;
275 }
276 
277 std::unique_ptr<CueEvent> MediaHandlerTestBase::GetCueEvent(
278  double time_in_seconds) const {
279  std::unique_ptr<CueEvent> event(new CueEvent);
280  event->time_in_seconds = time_in_seconds;
281 
282  return event;
283 }
284 
285 Status MediaHandlerTestBase::SetUpAndInitializeGraph(
286  std::shared_ptr<MediaHandler> handler,
287  size_t input_count,
288  size_t output_count) {
289  DCHECK(handler);
290  DCHECK_EQ(nullptr, handler_);
291  DCHECK(inputs_.empty());
292  DCHECK(outputs_.empty());
293 
294  handler_ = std::move(handler);
295 
296  Status status;
297 
298  // Add and connect all the requested inputs.
299  for (size_t i = 0; i < input_count; i++) {
300  inputs_.emplace_back(new FakeInputMediaHandler);
301  }
302 
303  for (auto& input : inputs_) {
304  status.Update(input->AddHandler(handler_));
305  }
306 
307  if (!status.ok()) {
308  return status;
309  }
310 
311  // Add and connect all the requested outputs.
312  for (size_t i = 0; i < output_count; i++) {
313  outputs_.emplace_back(new testing::NiceMock<MockOutputMediaHandler>);
314  }
315 
316  for (auto& output : outputs_) {
317  status.Update(handler_->AddHandler(output));
318  }
319 
320  if (!status.ok()) {
321  return status;
322  }
323 
324  // Initialize the graph.
325  for (auto& input : inputs_) {
326  status.Update(input->Initialize());
327  }
328 
329  // In the case that there are no inputs, the start of the graph
330  // is at |handler_| so it needs to be initialized or else the graph
331  // won't be initialized.
332  if (inputs_.empty()) {
333  status.Update(handler_->Initialize());
334  }
335 
336  return status;
337 }
338 
339 FakeInputMediaHandler* MediaHandlerTestBase::Input(size_t index) {
340  DCHECK_LT(index, inputs_.size());
341  return inputs_[index].get();
342 }
343 
344 MockOutputMediaHandler* MediaHandlerTestBase::Output(size_t index) {
345  DCHECK_LT(index, outputs_.size());
346  return outputs_[index].get();
347 }
348 
349 MediaHandlerGraphTestBase::MediaHandlerGraphTestBase()
350  : next_handler_(new CachingMediaHandler),
351  some_handler_(new CachingMediaHandler) {}
352 
354  size_t num_inputs,
355  size_t num_outputs,
356  std::shared_ptr<MediaHandler> handler) {
357  // Input handler is not really used anywhere else except to validate number of
358  // allowed inputs for the handler to be tested.
359  auto input_handler = std::make_shared<CachingMediaHandler>();
360  for (size_t i = 0; i < num_inputs; ++i)
361  ASSERT_OK(input_handler->SetHandler(i, handler));
362  // All outputs are routed to |next_handler_|.
363  for (size_t i = 0; i < num_outputs; ++i)
364  ASSERT_OK(handler->SetHandler(i, next_handler_));
365 }
366 
367 const std::vector<std::unique_ptr<StreamData>>&
369  return next_handler_->Cache();
370 }
371 
373  next_handler_->Clear();
374 }
375 
376 } // namespace media
377 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
void ClearOutputStreamDataVector()
Clear the output stream data vector.
-
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
Definition: media_sample.cc:42
-
const std::vector< std::unique_ptr< StreamData > > & GetOutputStreamDataVector() const
-
void SetUpGraph(size_t num_inputs, size_t num_outputs, std::shared_ptr< MediaHandler > handler)
Setup a graph using |handler| with |num_inputs| and |num_outputs|.
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/media_handler_test_base.h"
+
8 
+
9 #include "packager/media/base/audio_stream_info.h"
+
10 #include "packager/media/base/text_stream_info.h"
+
11 #include "packager/media/base/video_stream_info.h"
+
12 #include "packager/status_test_util.h"
+
13 
+
14 namespace {
+
15 
+
16 const int kTrackId = 1;
+
17 const uint64_t kDuration = 10000;
+
18 const char kCodecString[] = "codec string";
+
19 const uint8_t kSampleBits = 1;
+
20 const uint8_t kNumChannels = 2;
+
21 const uint32_t kSamplingFrequency = 48000;
+
22 const uint64_t kSeekPrerollNs = 12345;
+
23 const uint64_t kCodecDelayNs = 56789;
+
24 const uint32_t kMaxBitrate = 13579;
+
25 const uint32_t kAvgBitrate = 13000;
+
26 const char kLanguage[] = "eng";
+
27 const uint16_t kWidth = 10u;
+
28 const uint16_t kHeight = 20u;
+
29 const uint32_t kPixelWidth = 2u;
+
30 const uint32_t kPixelHeight = 3u;
+
31 const uint8_t kTransferCharacteristics = 0;
+
32 const int16_t kTrickPlayFactor = 0;
+
33 const uint8_t kNaluLengthSize = 1u;
+
34 const bool kEncrypted = true;
+
35 
+
36 // Use H264 code config.
+
37 const uint8_t kCodecConfig[]{
+
38  // clang-format off
+
39  // Header
+
40  0x01, 0x64, 0x00, 0x1e, 0xff,
+
41  // SPS count (ignore top three bits)
+
42  0xe1,
+
43  // SPS
+
44  0x00, 0x19, // Size
+
45  0x67, 0x64, 0x00, 0x1e, 0xac, 0xd9, 0x40, 0xa0, 0x2f, 0xf9, 0x70, 0x11,
+
46  0x00, 0x00, 0x03, 0x03, 0xe9, 0x00, 0x00, 0xea, 0x60, 0x0f, 0x16, 0x2d,
+
47  0x96,
+
48  // PPS count
+
49  0x01,
+
50  // PPS
+
51  0x00, 0x06, // Size
+
52  0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0,
+
53  // clang-format on
+
54 };
+
55 
+
56 // Mock data, we don't really care about what is inside.
+
57 const uint8_t kData[]{
+
58  0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+
59 };
+
60 
+
61 } // namespace
+
62 
+
63 namespace shaka {
+
64 namespace media {
+
65 
+
66 std::string BoolToString(bool value) {
+
67  return value ? "true" : "false";
+
68 }
+
69 
+
70 bool TryMatchStreamDataType(const StreamDataType& actual,
+
71  const StreamDataType& expected,
+
72  ::testing::MatchResultListener* listener) {
+
73  if (actual != expected) {
+
74  std::string expected_as_string = StreamDataTypeToString(expected);
+
75  std::string actual_as_string = StreamDataTypeToString(actual);
+
76 
+
77  *listener << "which is " << actual_as_string << " (expected "
+
78  << expected_as_string << ")";
+
79  return false;
+
80  }
+
81 
+
82  return true;
+
83 }
+
84 
+
85 bool TryMatchStreamType(const StreamType& actual,
+
86  const StreamType& expected,
+
87  ::testing::MatchResultListener* listener) {
+
88  if (actual != expected) {
+
89  std::string expected_as_string = StreamTypeToString(expected);
+
90  std::string actual_as_string = StreamTypeToString(actual);
+
91 
+
92  *listener << "which is " << actual_as_string << " (expected "
+
93  << expected_as_string << ")";
+
94  return false;
+
95  }
+
96 
+
97  return true;
+
98 }
+
99 
+
100 std::string ToPrettyString(const std::string& str) {
+
101  std::string out;
+
102 
+
103  // Opening quotation.
+
104  out.push_back('"');
+
105 
+
106  for (char c : str) {
+
107  if (isspace(c)) {
+
108  // Make all white space characters spaces to avoid print issues in
+
109  // the terminal.
+
110  out.push_back(' ');
+
111  } else if (isalnum(c)) {
+
112  // If the character is alpha-numeric, then print it as is. Just using
+
113  // these characters, it should be enough to understand the string.
+
114  out.push_back(c);
+
115  } else {
+
116  // Replace all other characters with '.'. This is to avoid print issues
+
117  // (e.g. \n) or readability issues (e.g. ").
+
118  out.push_back('.');
+
119  }
+
120  }
+
121 
+
122  // Closing quotation.
+
123  out.push_back('"');
+
124 
+
125  return out;
+
126 }
+
127 
+
128 bool FakeInputMediaHandler::ValidateOutputStreamIndex(size_t index) const {
+
129  return true;
+
130 }
+
131 
+
132 Status FakeInputMediaHandler::InitializeInternal() {
+
133  return Status::OK;
+
134 }
+
135 
+
136 Status FakeInputMediaHandler::Process(std::unique_ptr<StreamData> stream_data) {
+
137  return Status(error::INTERNAL_ERROR,
+
138  "FakeInputMediaHandler should never be a downstream handler.");
+
139 }
+
140 
+
141 Status MockOutputMediaHandler::InitializeInternal() {
+
142  return Status::OK;
+
143 }
+
144 
+
145 Status MockOutputMediaHandler::Process(
+
146  std::unique_ptr<StreamData> stream_data) {
+
147  OnProcess(stream_data.get());
+
148  return Status::OK;
+
149 }
+
150 
+
151 Status MockOutputMediaHandler::OnFlushRequest(size_t index) {
+
152  OnFlush(index);
+
153  return Status::OK;
+
154 }
+
155 
+
156 Status CachingMediaHandler::InitializeInternal() {
+
157  return Status::OK;
+
158 }
+
159 
+
160 Status CachingMediaHandler::Process(std::unique_ptr<StreamData> stream_data) {
+
161  stream_data_vector_.push_back(std::move(stream_data));
+
162  return Status::OK;
+
163 }
+
164 
+
165 Status CachingMediaHandler::OnFlushRequest(size_t input_stream_index) {
+
166  return Status::OK;
+
167 }
+
168 
+
169 bool CachingMediaHandler::ValidateOutputStreamIndex(size_t stream_index) const {
+
170  return true;
+
171 }
+
172 
+
173 bool MediaHandlerTestBase::IsVideoCodec(Codec codec) const {
+
174  return codec >= kCodecVideo && codec < kCodecVideoMaxPlusOne;
+
175 }
+
176 
+
177 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetVideoStreamInfo(
+
178  uint32_t time_scale) const {
+
179  return GetVideoStreamInfo(time_scale, kCodecVP9, kWidth, kHeight);
+
180 }
+
181 
+
182 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetVideoStreamInfo(
+
183  uint32_t time_scale,
+
184  uint32_t width,
+
185  uint64_t height) const {
+
186  return GetVideoStreamInfo(time_scale, kCodecVP9, width, height);
+
187 }
+
188 
+
189 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetVideoStreamInfo(
+
190  uint32_t time_scale,
+
191  Codec codec) const {
+
192  return GetVideoStreamInfo(time_scale, codec, kWidth, kHeight);
+
193 }
+
194 
+
195 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetVideoStreamInfo(
+
196  uint32_t time_scale,
+
197  Codec codec,
+
198  uint32_t width,
+
199  uint64_t height) const {
+
200  return std::unique_ptr<VideoStreamInfo>(new VideoStreamInfo(
+
201  kTrackId, time_scale, kDuration, codec, H26xStreamFormat::kUnSpecified,
+
202  kCodecString, kCodecConfig, sizeof(kCodecConfig), width, height,
+
203  kPixelWidth, kPixelHeight, kTransferCharacteristics, kTrickPlayFactor,
+
204  kNaluLengthSize, kLanguage, !kEncrypted));
+
205 }
+
206 
+
207 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetAudioStreamInfo(
+
208  uint32_t time_scale) const {
+
209  return GetAudioStreamInfo(time_scale, kCodecAAC);
+
210 }
+
211 
+
212 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetAudioStreamInfo(
+
213  uint32_t time_scale,
+
214  Codec codec) const {
+
215  return std::unique_ptr<AudioStreamInfo>(new AudioStreamInfo(
+
216  kTrackId, time_scale, kDuration, codec, kCodecString, kCodecConfig,
+
217  sizeof(kCodecConfig), kSampleBits, kNumChannels, kSamplingFrequency,
+
218  kSeekPrerollNs, kCodecDelayNs, kMaxBitrate, kAvgBitrate, kLanguage,
+
219  !kEncrypted));
+
220 }
+
221 
+
222 std::shared_ptr<MediaSample> MediaHandlerTestBase::GetMediaSample(
+
223  int64_t timestamp,
+
224  int64_t duration,
+
225  bool is_keyframe) const {
+
226  return GetMediaSample(timestamp, duration, is_keyframe, kData, sizeof(kData));
+
227 }
+
228 
+
229 std::shared_ptr<MediaSample> MediaHandlerTestBase::GetMediaSample(
+
230  int64_t timestamp,
+
231  int64_t duration,
+
232  bool is_keyframe,
+
233  const uint8_t* data,
+
234  size_t data_length) const {
+
235  std::shared_ptr<MediaSample> sample =
+
236  MediaSample::CopyFrom(data, data_length, nullptr, 0, is_keyframe);
+
237  sample->set_dts(timestamp);
+
238  sample->set_pts(timestamp);
+
239  sample->set_duration(duration);
+
240 
+
241  return sample;
+
242 }
+
243 
+
244 std::unique_ptr<SegmentInfo> MediaHandlerTestBase::GetSegmentInfo(
+
245  int64_t start_timestamp,
+
246  int64_t duration,
+
247  bool is_subsegment) const {
+
248  std::unique_ptr<SegmentInfo> info(new SegmentInfo);
+
249  info->start_timestamp = start_timestamp;
+
250  info->duration = duration;
+
251  info->is_subsegment = is_subsegment;
+
252 
+
253  return info;
+
254 }
+
255 
+
256 std::unique_ptr<StreamInfo> MediaHandlerTestBase::GetTextStreamInfo(
+
257  uint32_t timescale) const {
+
258  // None of this information is actually used by the text out handler.
+
259  // The stream info is just needed to signal the start of the stream.
+
260  return std::unique_ptr<StreamInfo>(
+
261  new TextStreamInfo(0, timescale, 0, kUnknownCodec, "", "", 0, 0, ""));
+
262 }
+
263 
+
264 std::unique_ptr<TextSample> MediaHandlerTestBase::GetTextSample(
+
265  const std::string& id,
+
266  int64_t start,
+
267  int64_t end,
+
268  const std::string& payload) const {
+
269  return std::unique_ptr<TextSample>{
+
270  new TextSample(id, start, end, {}, TextFragment{{}, payload})};
+
271 }
+
272 
+
273 std::unique_ptr<CueEvent> MediaHandlerTestBase::GetCueEvent(
+
274  double time_in_seconds) const {
+
275  std::unique_ptr<CueEvent> event(new CueEvent);
+
276  event->time_in_seconds = time_in_seconds;
+
277 
+
278  return event;
+
279 }
+
280 
+
281 Status MediaHandlerTestBase::SetUpAndInitializeGraph(
+
282  std::shared_ptr<MediaHandler> handler,
+
283  size_t input_count,
+
284  size_t output_count) {
+
285  DCHECK(handler);
+
286  DCHECK_EQ(nullptr, handler_);
+
287  DCHECK(inputs_.empty());
+
288  DCHECK(outputs_.empty());
+
289 
+
290  handler_ = std::move(handler);
+
291 
+
292  Status status;
+
293 
+
294  // Add and connect all the requested inputs.
+
295  for (size_t i = 0; i < input_count; i++) {
+
296  inputs_.emplace_back(new FakeInputMediaHandler);
+
297  }
+
298 
+
299  for (auto& input : inputs_) {
+
300  status.Update(input->AddHandler(handler_));
+
301  }
+
302 
+
303  if (!status.ok()) {
+
304  return status;
+
305  }
+
306 
+
307  // Add and connect all the requested outputs.
+
308  for (size_t i = 0; i < output_count; i++) {
+
309  outputs_.emplace_back(new testing::NiceMock<MockOutputMediaHandler>);
+
310  }
+
311 
+
312  for (auto& output : outputs_) {
+
313  status.Update(handler_->AddHandler(output));
+
314  }
+
315 
+
316  if (!status.ok()) {
+
317  return status;
+
318  }
+
319 
+
320  // Initialize the graph.
+
321  for (auto& input : inputs_) {
+
322  status.Update(input->Initialize());
+
323  }
+
324 
+
325  // In the case that there are no inputs, the start of the graph
+
326  // is at |handler_| so it needs to be initialized or else the graph
+
327  // won't be initialized.
+
328  if (inputs_.empty()) {
+
329  status.Update(handler_->Initialize());
+
330  }
+
331 
+
332  return status;
+
333 }
+
334 
+
335 FakeInputMediaHandler* MediaHandlerTestBase::Input(size_t index) {
+
336  DCHECK_LT(index, inputs_.size());
+
337  return inputs_[index].get();
+
338 }
+
339 
+
340 MockOutputMediaHandler* MediaHandlerTestBase::Output(size_t index) {
+
341  DCHECK_LT(index, outputs_.size());
+
342  return outputs_[index].get();
+
343 }
+
344 
+
345 MediaHandlerGraphTestBase::MediaHandlerGraphTestBase()
+
346  : next_handler_(new CachingMediaHandler),
+
347  some_handler_(new CachingMediaHandler) {}
+
348 
+
349 void MediaHandlerGraphTestBase::SetUpGraph(
+
350  size_t num_inputs,
+
351  size_t num_outputs,
+
352  std::shared_ptr<MediaHandler> handler) {
+
353  // Input handler is not really used anywhere else except to validate number of
+
354  // allowed inputs for the handler to be tested.
+
355  auto input_handler = std::make_shared<CachingMediaHandler>();
+
356  for (size_t i = 0; i < num_inputs; ++i)
+
357  ASSERT_OK(input_handler->SetHandler(i, handler));
+
358  // All outputs are routed to |next_handler_|.
+
359  for (size_t i = 0; i < num_outputs; ++i)
+
360  ASSERT_OK(handler->SetHandler(i, next_handler_));
+
361 }
+
362 
+
363 const std::vector<std::unique_ptr<StreamData>>&
+
364 MediaHandlerGraphTestBase::GetOutputStreamDataVector() const {
+
365  return next_handler_->Cache();
+
366 }
+
367 
+
368 void MediaHandlerGraphTestBase::ClearOutputStreamDataVector() {
+
369  next_handler_->Clear();
+
370 }
+
371 
+
372 } // namespace media
+
373 } // namespace shaka
+
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
Definition: media_sample.cc:42
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/dc7/structshaka_1_1MpdOptions-members.html b/docs/d2/dc7/structshaka_1_1MpdOptions-members.html index 4d64832fab..26ac004bda 100644 --- a/docs/d2/dc7/structshaka_1_1MpdOptions-members.html +++ b/docs/d2/dc7/structshaka_1_1MpdOptions-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/dcd/program__map__table__writer_8h_source.html b/docs/d2/dcd/program__map__table__writer_8h_source.html index ca1aceb998..91f97dd16e 100644 --- a/docs/d2/dcd/program__map__table__writer_8h_source.html +++ b/docs/d2/dcd/program__map__table__writer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/program_map_table_writer.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
program_map_table_writer.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_PROGRAM_MAP_TABLE_WRITER_H_
8 #define PACKAGER_MEDIA_FORMATS_MP2T_PROGRAM_MAP_TABLE_WRITER_H_
9 
10 #include <stdint.h>
11 
12 #include <vector>
13 
14 #include "packager/media/base/buffer_writer.h"
15 // TODO(kqyang): Move codec to codec.h.
16 #include "packager/media/base/stream_info.h"
17 #include "packager/media/formats/mp2t/continuity_counter.h"
18 
19 namespace shaka {
20 namespace media {
21 
22 class BufferWriter;
23 
24 namespace mp2t {
25 
28  public:
29  explicit ProgramMapTableWriter(Codec codec);
30  virtual ~ProgramMapTableWriter() = default;
31 
33  // Virtual for testing.
34  virtual bool EncryptedSegmentPmt(BufferWriter* writer);
35 
37  // Virtual for testing.
38  virtual bool ClearSegmentPmt(BufferWriter* writer);
39 
40  // The pid can be 13 bits long but 8 bits is sufficient for this library.
41  // This is the minimum PID that can be used for PMT.
42  static const uint8_t kPmtPid = 0x20;
43 
44  // This is arbitrary number that is not reserved by the spec.
45  static const uint8_t kElementaryPid = 0x50;
46 
47  protected:
49  Codec codec() const { return codec_; }
50 
51  private:
53  ProgramMapTableWriter& operator=(const ProgramMapTableWriter&) = delete;
54 
55  // Writes descriptors for PMT (only needed for encrypted PMT).
56  virtual bool WriteDescriptors(BufferWriter* writer) const = 0;
57 
58  const Codec codec_;
59  ContinuityCounter continuity_counter_;
60  BufferWriter clear_pmt_;
61  BufferWriter encrypted_pmt_;
62 };
63 
66  public:
67  explicit VideoProgramMapTableWriter(Codec codec);
68  ~VideoProgramMapTableWriter() override = default;
69 
70  private:
73  delete;
74 
75  bool WriteDescriptors(BufferWriter* writer) const override;
76 };
77 
80  public:
82  const std::vector<uint8_t>& audio_specific_config);
83  ~AudioProgramMapTableWriter() override = default;
84 
85  private:
88  delete;
89 
90  // Writers descriptors for PMT (only needed for encrypted PMT).
91  bool WriteDescriptors(BufferWriter* descriptors) const override;
92 
93  const std::vector<uint8_t> audio_specific_config_;
94 };
95 
96 } // namespace mp2t
97 } // namespace media
98 } // namespace shaka
99 
100 #endif // PACKAGER_MEDIA_FORMATS_MP2T_PROGRAM_MAP_TABLE_WRITER_H_
ProgramMapTableWriter for video codecs.
-
All the methods that are virtual are virtual for mocking.
- - -
ProgramMapTableWriter for video codecs.
-
virtual bool ClearSegmentPmt(BufferWriter *writer)
Writes TS packets with PMT for clear segments.
- -
virtual bool EncryptedSegmentPmt(BufferWriter *writer)
Writes TS packets with PMT for encrypted segments.
-
Puts PMT into TS packets and writes them to buffer.
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_PROGRAM_MAP_TABLE_WRITER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_MP2T_PROGRAM_MAP_TABLE_WRITER_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <vector>
+
13 
+
14 #include "packager/media/base/buffer_writer.h"
+
15 // TODO(kqyang): Move codec to codec.h.
+
16 #include "packager/media/base/stream_info.h"
+
17 #include "packager/media/formats/mp2t/continuity_counter.h"
+
18 
+
19 namespace shaka {
+
20 namespace media {
+
21 
+
22 class BufferWriter;
+
23 
+
24 namespace mp2t {
+
25 
+ +
28  public:
+
29  explicit ProgramMapTableWriter(Codec codec);
+
30  virtual ~ProgramMapTableWriter() = default;
+
31 
+
33  // Virtual for testing.
+
34  virtual bool EncryptedSegmentPmt(BufferWriter* writer);
+
35 
+
37  // Virtual for testing.
+
38  virtual bool ClearSegmentPmt(BufferWriter* writer);
+
39 
+
40  // The pid can be 13 bits long but 8 bits is sufficient for this library.
+
41  // This is the minimum PID that can be used for PMT.
+
42  static const uint8_t kPmtPid = 0x20;
+
43 
+
44  // This is arbitrary number that is not reserved by the spec.
+
45  static const uint8_t kElementaryPid = 0x50;
+
46 
+
47  protected:
+
49  Codec codec() const { return codec_; }
+
50 
+
51  private:
+ +
53  ProgramMapTableWriter& operator=(const ProgramMapTableWriter&) = delete;
+
54 
+
55  // Writes descriptors for PMT (only needed for encrypted PMT).
+
56  virtual bool WriteDescriptors(BufferWriter* writer) const = 0;
+
57 
+
58  const Codec codec_;
+
59  ContinuityCounter continuity_counter_;
+
60  BufferWriter clear_pmt_;
+
61  BufferWriter encrypted_pmt_;
+
62 };
+
63 
+ +
66  public:
+
67  explicit VideoProgramMapTableWriter(Codec codec);
+
68  ~VideoProgramMapTableWriter() override = default;
+
69 
+
70  private:
+ + +
73  delete;
+
74 
+
75  bool WriteDescriptors(BufferWriter* writer) const override;
+
76 };
+
77 
+ +
80  public:
+ +
82  const std::vector<uint8_t>& audio_specific_config);
+
83  ~AudioProgramMapTableWriter() override = default;
+
84 
+
85  private:
+ + +
88  delete;
+
89 
+
90  // Writers descriptors for PMT (only needed for encrypted PMT).
+
91  bool WriteDescriptors(BufferWriter* descriptors) const override;
+
92 
+
93  const std::vector<uint8_t> audio_specific_config_;
+
94 };
+
95 
+
96 } // namespace mp2t
+
97 } // namespace media
+
98 } // namespace shaka
+
99 
+
100 #endif // PACKAGER_MEDIA_FORMATS_MP2T_PROGRAM_MAP_TABLE_WRITER_H_
+ +
ProgramMapTableWriter for video codecs.
+ +
Puts PMT into TS packets and writes them to buffer.
+
virtual bool EncryptedSegmentPmt(BufferWriter *writer)
Writes TS packets with PMT for encrypted segments.
+
virtual bool ClearSegmentPmt(BufferWriter *writer)
Writes TS packets with PMT for clear segments.
+ +
ProgramMapTableWriter for video codecs.
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/dcd/structshaka_1_1media_1_1mp4_1_1EditList-members.html b/docs/d2/dcd/structshaka_1_1media_1_1mp4_1_1EditList-members.html index 81d93601ca..51587da7d6 100644 --- a/docs/d2/dcd/structshaka_1_1media_1_1mp4_1_1EditList-members.html +++ b/docs/d2/dcd/structshaka_1_1media_1_1mp4_1_1EditList-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/dcd/tag_8h_source.html b/docs/d2/dcd/tag_8h_source.html index d23e7bc20b..df82128f2f 100644 --- a/docs/d2/dcd/tag_8h_source.html +++ b/docs/d2/dcd/tag_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/tag.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
tag.h
-
1 // Copyright 2018 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_HLS_BASE_TAG_H_
8 #define PACKAGER_HLS_BASE_TAG_H_
9 
10 #include <string>
11 
12 namespace shaka {
13 namespace hls {
14 
17 class Tag {
18  public:
19  Tag(const std::string& name, std::string* buffer);
20 
22  void AddString(const std::string& key, const std::string& value);
23 
25  void AddQuotedString(const std::string& key, const std::string& value);
26 
28  void AddNumber(const std::string& key, uint64_t value);
29 
31  void AddFloat(const std::string& key, float value);
32 
34  void AddNumberPair(const std::string& key,
35  uint64_t number1,
36  char separator,
37  uint64_t number2);
38 
40  void AddQuotedNumberPair(const std::string& key,
41  uint64_t number1,
42  char separator,
43  uint64_t number2);
44 
45  private:
46  Tag(const Tag&) = delete;
47  Tag& operator=(const Tag&) = delete;
48 
49  std::string* const buffer_;
50  size_t fields = 0;
51 
52  void NextField();
53 };
54 
55 } // namespace hls
56 } // namespace shaka
57 
58 #endif // PACKAGER_HLS_BASE_TAG_H_
All the methods that are virtual are virtual for mocking.
-
void AddQuotedString(const std::string &key, const std::string &value)
Add a quoted string value to the argument list.
Definition: tag.cc:25
- -
void AddString(const std::string &key, const std::string &value)
Add a non-quoted string value to the argument list.
Definition: tag.cc:20
-
void AddNumber(const std::string &key, uint64_t value)
Add a non-quoted numeric value to the argument list.
Definition: tag.cc:30
-
void AddFloat(const std::string &key, float value)
Add a non-quoted float value to the argument list.
Definition: tag.cc:35
-
void AddQuotedNumberPair(const std::string &key, uint64_t number1, char separator, uint64_t number2)
Add a quoted pair of numbers with a symbol separating them.
Definition: tag.cc:49
-
void AddNumberPair(const std::string &key, uint64_t number1, char separator, uint64_t number2)
Add a pair of numbers with a symbol separating them.
Definition: tag.cc:40
+
1 // Copyright 2018 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_HLS_BASE_TAG_H_
+
8 #define PACKAGER_HLS_BASE_TAG_H_
+
9 
+
10 #include <string>
+
11 
+
12 namespace shaka {
+
13 namespace hls {
+
14 
+
17 class Tag {
+
18  public:
+
19  Tag(const std::string& name, std::string* buffer);
+
20 
+
22  void AddString(const std::string& key, const std::string& value);
+
23 
+
25  void AddQuotedString(const std::string& key, const std::string& value);
+
26 
+
28  void AddNumber(const std::string& key, uint64_t value);
+
29 
+
31  void AddFloat(const std::string& key, float value);
+
32 
+
34  void AddNumberPair(const std::string& key,
+
35  uint64_t number1,
+
36  char separator,
+
37  uint64_t number2);
+
38 
+
40  void AddQuotedNumberPair(const std::string& key,
+
41  uint64_t number1,
+
42  char separator,
+
43  uint64_t number2);
+
44 
+
45  private:
+
46  Tag(const Tag&) = delete;
+
47  Tag& operator=(const Tag&) = delete;
+
48 
+
49  std::string* const buffer_;
+
50  size_t fields = 0;
+
51 
+
52  void NextField();
+
53 };
+
54 
+
55 } // namespace hls
+
56 } // namespace shaka
+
57 
+
58 #endif // PACKAGER_HLS_BASE_TAG_H_
+ +
void AddQuotedString(const std::string &key, const std::string &value)
Add a quoted string value to the argument list.
Definition: tag.cc:25
+
void AddFloat(const std::string &key, float value)
Add a non-quoted float value to the argument list.
Definition: tag.cc:35
+
void AddQuotedNumberPair(const std::string &key, uint64_t number1, char separator, uint64_t number2)
Add a quoted pair of numbers with a symbol separating them.
Definition: tag.cc:49
+
void AddNumberPair(const std::string &key, uint64_t number1, char separator, uint64_t number2)
Add a pair of numbers with a symbol separating them.
Definition: tag.cc:40
+
void AddNumber(const std::string &key, uint64_t value)
Add a non-quoted numeric value to the argument list.
Definition: tag.cc:30
+
void AddString(const std::string &key, const std::string &value)
Add a non-quoted string value to the argument list.
Definition: tag.cc:20
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/dce/structshaka_1_1WidevineSigner-members.html b/docs/d2/dce/structshaka_1_1WidevineSigner-members.html index 911f7a0b11..b5432bd0ed 100644 --- a/docs/d2/dce/structshaka_1_1WidevineSigner-members.html +++ b/docs/d2/dce/structshaka_1_1WidevineSigner-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/dd5/classshaka_1_1media_1_1webm_1_1MultiSegmentSegmenter.html b/docs/d2/dd5/classshaka_1_1media_1_1webm_1_1MultiSegmentSegmenter.html index cca6d3fa77..498b720af7 100644 --- a/docs/d2/dd5/classshaka_1_1media_1_1webm_1_1MultiSegmentSegmenter.html +++ b/docs/d2/dd5/classshaka_1_1media_1_1webm_1_1MultiSegmentSegmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::webm::MultiSegmentSegmenter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::webm::Segmenter - -
+ + @@ -139,7 +142,7 @@ uint64_t  - + @@ -172,7 +175,7 @@ uint64_t 

Public Member Functions

 
void UpdateProgress (uint64_t progress)
 Update segmentation progress using ProgressListener.
 Update segmentation progress using ProgressListener.
 
void set_progress_target (uint64_t target)
duration () c

Detailed Description

An implementation of a Segmenter for a multi-segment. Since this does not use seeking, it does not matter if the underlying files support seeking.

-

Definition at line 24 of file multi_segment_segmenter.h.

+

Definition at line 25 of file multi_segment_segmenter.h.

Member Function Documentation

◆ GetIndexRangeStartAndEnd()

@@ -211,7 +214,7 @@ uint64_t 
duration () c

Implements shaka::media::webm::Segmenter.

-

Definition at line 55 of file multi_segment_segmenter.cc.

+

Definition at line 66 of file multi_segment_segmenter.cc.

@@ -252,7 +255,7 @@ uint64_t 
duration () c

Implements shaka::media::webm::Segmenter.

-

Definition at line 50 of file multi_segment_segmenter.cc.

+

Definition at line 61 of file multi_segment_segmenter.cc.

@@ -263,9 +266,7 @@ uint64_t 
duration () c diff --git a/docs/d2/dd6/mkv__writer_8h_source.html b/docs/d2/dd6/mkv__writer_8h_source.html index 7d1c6bbb0b..7d90e42949 100644 --- a/docs/d2/dd6/mkv__writer_8h_source.html +++ b/docs/d2/dd6/mkv__writer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/mkv_writer.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mkv_writer.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_MKV_WRITER_H_
8 #define PACKAGER_MEDIA_FORMATS_WEBM_MKV_WRITER_H_
9 
10 #include <memory>
11 #include <string>
12 
13 #include "packager/file/file_closer.h"
14 #include "packager/status.h"
15 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
16 
17 namespace shaka {
18 namespace media {
19 
21 class MkvWriter : public mkvmuxer::IMkvWriter {
22  public:
23  MkvWriter();
24  ~MkvWriter() override;
25 
30  Status Open(const std::string& name);
32  Status Close();
33 
36  mkvmuxer::int32 Write(const void* buf, mkvmuxer::uint32 len) override;
39  mkvmuxer::int64 Position() const override;
42  mkvmuxer::int32 Position(mkvmuxer::int64 position) override;
44  bool Seekable() const override;
50  void ElementStartNotify(mkvmuxer::uint64 element_id,
51  mkvmuxer::int64 position) override;
52 
55  int64_t WriteFromFile(File* source);
59  int64_t WriteFromFile(File* source, int64_t max_copy);
60 
61  File* file() { return file_.get(); }
62 
63  private:
64  std::unique_ptr<File, FileCloser> file_;
65  // Keep track of the position and whether we can seek.
66  mkvmuxer::int64 position_;
67  bool seekable_;
68 
69  DISALLOW_COPY_AND_ASSIGN(MkvWriter);
70 };
71 
72 } // namespace media
73 } // namespace shaka
74 
75 #endif // PACKAGER_MEDIA_FORMATS_WEBM_MKV_WRITER_H_
Define an abstract file interface.
Definition: file.h:26
-
All the methods that are virtual are virtual for mocking.
-
int64_t WriteFromFile(File *source)
Definition: mkv_writer.cc:59
- -
void ElementStartNotify(mkvmuxer::uint64 element_id, mkvmuxer::int64 position) override
Definition: mkv_writer.cc:93
-
mkvmuxer::int64 Position() const override
Definition: mkv_writer.cc:74
-
An implementation of IMkvWriter using our File type.
Definition: mkv_writer.h:21
-
bool Seekable() const override
Definition: mkv_writer.cc:89
-
Status Open(const std::string &name)
Definition: mkv_writer.cc:16
-
Status Close()
Closes the file. MUST call Open before calling any other methods.
Definition: mkv_writer.cc:29
-
mkvmuxer::int32 Write(const void *buf, mkvmuxer::uint32 len) override
Definition: mkv_writer.cc:40
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_MKV_WRITER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_WEBM_MKV_WRITER_H_
+
9 
+
10 #include <memory>
+
11 #include <string>
+
12 
+
13 #include "packager/file/file_closer.h"
+
14 #include "packager/status.h"
+
15 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
+
16 
+
17 namespace shaka {
+
18 namespace media {
+
19 
+
21 class MkvWriter : public mkvmuxer::IMkvWriter {
+
22  public:
+
23  MkvWriter();
+
24  ~MkvWriter() override;
+
25 
+
30  Status Open(const std::string& name);
+
32  Status Close();
+
33 
+
36  mkvmuxer::int32 Write(const void* buf, mkvmuxer::uint32 len) override;
+
39  mkvmuxer::int64 Position() const override;
+
42  mkvmuxer::int32 Position(mkvmuxer::int64 position) override;
+
44  bool Seekable() const override;
+
50  void ElementStartNotify(mkvmuxer::uint64 element_id,
+
51  mkvmuxer::int64 position) override;
+
52 
+
55  int64_t WriteFromFile(File* source);
+
59  int64_t WriteFromFile(File* source, int64_t max_copy);
+
60 
+
61  File* file() { return file_.get(); }
+
62 
+
63  private:
+
64  std::unique_ptr<File, FileCloser> file_;
+
65  // Keep track of the position and whether we can seek.
+
66  mkvmuxer::int64 position_;
+
67  bool seekable_;
+
68 
+
69  DISALLOW_COPY_AND_ASSIGN(MkvWriter);
+
70 };
+
71 
+
72 } // namespace media
+
73 } // namespace shaka
+
74 
+
75 #endif // PACKAGER_MEDIA_FORMATS_WEBM_MKV_WRITER_H_
+
Define an abstract file interface.
Definition: file.h:27
+ +
An implementation of IMkvWriter using our File type.
Definition: mkv_writer.h:21
+
mkvmuxer::int32 Write(const void *buf, mkvmuxer::uint32 len) override
Definition: mkv_writer.cc:40
+
mkvmuxer::int64 Position() const override
Definition: mkv_writer.cc:74
+
void ElementStartNotify(mkvmuxer::uint64 element_id, mkvmuxer::int64 position) override
Definition: mkv_writer.cc:93
+
bool Seekable() const override
Definition: mkv_writer.cc:89
+
Status Open(const std::string &name)
Definition: mkv_writer.cc:16
+
int64_t WriteFromFile(File *source)
Definition: mkv_writer.cc:59
+
Status Close()
Closes the file. MUST call Open before calling any other methods.
Definition: mkv_writer.cc:29
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/dd7/structshaka_1_1RawKeyParams-members.html b/docs/d2/dd7/structshaka_1_1RawKeyParams-members.html index 0d39cc9e98..37fd8d89db 100644 --- a/docs/d2/dd7/structshaka_1_1RawKeyParams-members.html +++ b/docs/d2/dd7/structshaka_1_1RawKeyParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d2/dd8/classshaka_1_1media_1_1ChunkingHandler-members.html b/docs/d2/dd8/classshaka_1_1media_1_1ChunkingHandler-members.html index baea8fcc0e..ddd5317adf 100644 --- a/docs/d2/dd8/classshaka_1_1media_1_1ChunkingHandler-members.html +++ b/docs/d2/dd8/classshaka_1_1media_1_1ChunkingHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
This is the complete list of members for shaka::media::ChunkingHandler, including all inherited members.

- + @@ -99,9 +102,7 @@ $(function() {
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
ChunkingHandler(const ChunkingParams &chunking_params) (defined in shaka::media::ChunkingHandler)shaka::media::ChunkingHandlerexplicit
ChunkingHandlerTest (defined in shaka::media::ChunkingHandler)shaka::media::ChunkingHandlerfriend
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
diff --git a/docs/d2/ddb/classshaka_1_1media_1_1WebMMediaParser.html b/docs/d2/ddb/classshaka_1_1media_1_1WebMMediaParser.html index 90a24a8830..17c9c27d45 100644 --- a/docs/d2/ddb/classshaka_1_1media_1_1WebMMediaParser.html +++ b/docs/d2/ddb/classshaka_1_1media_1_1WebMMediaParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMMediaParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::MediaParser - -
+ + - - + + @@ -93,8 +96,10 @@ Additional Inherited Members - - + + + +

Public Member Functions

MediaParser implementation overrides.
void Init (const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
 
void Init (const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
 
bool Flush () override WARN_UNUSED_RESULT
 
bool Parse (const uint8_t *buf, int size) override WARN_UNUSED_RESULT
- Public Types inherited from shaka::media::MediaParser
typedef base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
 
typedef base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
 
typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
 
typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
 

Detailed Description

@@ -126,12 +131,12 @@ Additional Inherited Members

Implements shaka::media::MediaParser.

-

Definition at line 43 of file webm_media_parser.cc.

+

Definition at line 44 of file webm_media_parser.cc.

- -

◆ Init()

+ +

◆ Init()

@@ -148,8 +153,14 @@ Additional Inherited Members - const NewSampleCB &  - new_sample_cb, + const NewMediaSampleCB &  + new_media_sample_cb, + + + + + const NewTextSampleCB &  + new_text_sample_cb, @@ -172,12 +183,14 @@ Additional Inherited Members

Initialize the parser with necessary callbacks. Must be called before any data is passed to Parse().

Parameters
- + + +
init_cbwill be called once enough data has been parsed to determine the initial stream configurations.
new_sample_cbwill be called each time a new media sample is available from the parser. May be NULL, and caller retains ownership.
new_media_sample_cbwill be called each time a new media sample is available from the parser.
new_text_sample_cbwill be called each time a new text sample is available from the parser.
decryption_key_sourcethe key source to decrypt the frames. May be NULL, and caller retains ownership.
-

Implements shaka::media::MediaParser.

+

Implements shaka::media::MediaParser.

Definition at line 28 of file webm_media_parser.cc.

@@ -220,7 +233,7 @@ Additional Inherited Members

Implements shaka::media::MediaParser.

-

Definition at line 56 of file webm_media_parser.cc.

+

Definition at line 57 of file webm_media_parser.cc.

@@ -231,9 +244,7 @@ Additional Inherited Members diff --git a/docs/d2/ddc/hls__audio__util_8h_source.html b/docs/d2/ddc/hls__audio__util_8h_source.html index cd454198e6..7eda1c5594 100644 --- a/docs/d2/ddc/hls__audio__util_8h_source.html +++ b/docs/d2/ddc/hls__audio__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/hls_audio_util.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
hls_audio_util.h
-
1 // Copyright 2018 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
8 #define PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
9 
10 #include "packager/media/base/stream_info.h"
11 
12 namespace shaka {
13 namespace media {
14 
15 class BufferWriter;
16 
21 bool WriteAudioSetupInformation(Codec codec,
22  const uint8_t* audio_specific_config,
23  size_t audio_specific_config_size,
24  BufferWriter* audio_setup_information);
25 
26 } // namespace media
27 } // namespace shaka
28 
29 #endif // PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2018 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
+
8 #define PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
+
9 
+
10 #include "packager/media/base/stream_info.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+
15 class BufferWriter;
+
16 
+
21 bool WriteAudioSetupInformation(Codec codec,
+
22  const uint8_t* audio_specific_config,
+
23  size_t audio_specific_config_size,
+
24  BufferWriter* audio_setup_information);
+
25 
+
26 } // namespace media
+
27 } // namespace shaka
+
28 
+
29 #endif // PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d2/de1/dvb__image_8h_source.html b/docs/d2/de1/dvb__image_8h_source.html new file mode 100644 index 0000000000..6b338ae1be --- /dev/null +++ b/docs/d2/de1/dvb__image_8h_source.html @@ -0,0 +1,194 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/dvb/dvb_image.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
dvb_image.h
+
+
+
1 // Copyright 2020 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_DVB_DVB_IMAGE_H_
+
8 #define PACKAGER_MEDIA_DVB_DVB_IMAGE_H_
+
9 
+
10 #include <memory>
+
11 #include <type_traits>
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
16 struct RgbaColor {
+
17  uint8_t r;
+
18  uint8_t g;
+
19  uint8_t b;
+
20  uint8_t a;
+
21 
+
22  bool operator==(const RgbaColor& other) const {
+
23  return r == other.r && g == other.g && b == other.b && a == other.a;
+
24  }
+
25  bool operator!=(const RgbaColor& other) const { return !(*this == other); }
+
26 };
+
27 // To avoid copying, we pass an RgbaColor array as a uint8_t* pointer to libpng
+
28 // for RGBA.
+
29 static_assert(std::is_pod<RgbaColor>::value, "RgbaColor must be POD");
+
30 static_assert(sizeof(RgbaColor) == 4, "RgbaColor not packed correctly");
+
31 
+
32 enum class BitDepth : uint8_t {
+
33  k2Bit,
+
34  k4Bit,
+
35  k8Bit,
+
36 };
+
37 
+ +
48  public:
+ + +
51 
+
52  DvbImageColorSpace(const DvbImageColorSpace&) = delete;
+
53  DvbImageColorSpace& operator=(const DvbImageColorSpace&) = delete;
+
54 
+
55  RgbaColor GetColor(BitDepth bit_depth, uint8_t entry_id) const;
+
56 
+
57  void SetColor(BitDepth bit_depth, uint8_t entry_id, RgbaColor color);
+
59  void Set2To4BitDepthMap(const uint8_t* map);
+
61  void Set2To8BitDepthMap(const uint8_t* map);
+
63  void Set4To8BitDepthMap(const uint8_t* map);
+
64 
+
65  private:
+
66  RgbaColor GetColorRaw(BitDepth bit_depth, uint8_t entry_id) const;
+
67 
+
68  // These hold the colors for each entry ID. Each value is initialized to the
+
69  // special value kNoColor meaning there isn't a value present.
+
70  RgbaColor color_map_2_[4];
+
71  RgbaColor color_map_4_[16];
+
72  RgbaColor color_map_8_[256];
+
73  // See ETSI EN 300 743 Sections 10.4, 10.5, 10.6 for defaults.
+
74  uint8_t bit_depth_2_to_4_[4] = {0x0, 0x7, 0x8, 0xf};
+
75  uint8_t bit_depth_2_to_8_[4] = {0x0, 0x77, 0x88, 0xff};
+
76  uint8_t bit_depth_4_to_8_[16] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+
77  0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
+
78  0xcc, 0xdd, 0xee, 0xff};
+
79 };
+
80 
+ +
90  public:
+
91  DvbImageBuilder(const DvbImageColorSpace* color_space,
+
92  const RgbaColor& default_color,
+
93  uint16_t max_width,
+
94  uint16_t max_height);
+
95  ~DvbImageBuilder();
+
96 
+
97  DvbImageBuilder(const DvbImageBuilder&) = delete;
+
98  DvbImageBuilder& operator=(const DvbImageBuilder&) = delete;
+
99 
+
100  uint16_t max_width() const { return max_width_; }
+
101  uint16_t max_height() const { return max_height_; }
+
102 
+
103  bool AddPixel(BitDepth bit_depth, uint8_t byte_code, bool is_top_rows);
+
104  void NewRow(bool is_top_rows);
+
106  void MirrorToBottomRows();
+
107 
+
117  bool GetPixels(const RgbaColor** pixels,
+
118  uint16_t* width,
+
119  uint16_t* height) const;
+
120 
+
121  private:
+
122  struct Position {
+
123  uint16_t x, y;
+
124  };
+
125 
+
126  const std::unique_ptr<RgbaColor[]> pixels_;
+
127  const DvbImageColorSpace* const color_space_;
+
128  Position top_pos_, bottom_pos_;
+
129  const uint16_t max_width_;
+
130  const uint16_t max_height_;
+
131  uint16_t width_;
+
132 };
+
133 
+
134 } // namespace media
+
135 } // namespace shaka
+
136 
+
137 #endif // PACKAGER_MEDIA_DVB_DVB_IMAGE_H_
+ +
bool GetPixels(const RgbaColor **pixels, uint16_t *width, uint16_t *height) const
Definition: dvb_image.cc:244
+
void MirrorToBottomRows()
Copies the top-rows to the bottom rows.
Definition: dvb_image.cc:232
+ +
void Set4To8BitDepthMap(const uint8_t *map)
Must pass a 16-element array; elements are copied over.
Definition: dvb_image.cc:175
+
void Set2To8BitDepthMap(const uint8_t *map)
Must pass a 4-element array; elements are copied over.
Definition: dvb_image.cc:171
+
void Set2To4BitDepthMap(const uint8_t *map)
Must pass a 4-element array; elements are copied over.
Definition: dvb_image.cc:167
+
All the methods that are virtual are virtual for mocking.
+ +
+ + + + diff --git a/docs/d2/de1/webvtt__timestamp_8h_source.html b/docs/d2/de1/webvtt__timestamp_8h_source.html deleted file mode 100644 index 74060a9d42..0000000000 --- a/docs/d2/de1/webvtt__timestamp_8h_source.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - -Shaka Packager SDK: packager/media/formats/webvtt/webvtt_timestamp.h Source File - - - - - - - - - -
-
- - - - - - -
-
Shaka Packager SDK -
-
-
- - - - - - - - -
-
- - -
- -
- - -
-
-
-
webvtt_timestamp.h
-
-
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_TIMESTAMP_H_
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_TIMESTAMP_H_
9 
10 #include <stdint.h>
11 
12 #include <string>
13 
14 #include "packager/base/strings/string_piece.h"
15 
16 namespace shaka {
17 namespace media {
18 // Parse a timestamp into milliseconds using the two patterns defined by WebVtt:
19 // LONG : ##:##:##.### (long can have 2 or more hour digits)
20 // SHORT : ##:##:###
21 bool WebVttTimestampToMs(const base::StringPiece& source, uint64_t* out);
22 
23 // Create a long form timestamp encoded as a string.
24 std::string MsToWebVttTimestamp(uint64_t ms);
25 } // namespace media
26 } // namespace shaka
27 
28 #endif // PACKAGER_MEDIA_FORMATS_WEBVTT_TIMESTAMP_H_
All the methods that are virtual are virtual for mocking.
-
- - - - diff --git a/docs/d2/de3/classshaka_1_1media_1_1mp2t_1_1TsSectionPmt.html b/docs/d2/de3/classshaka_1_1media_1_1mp2t_1_1TsSectionPmt.html index 6310f909f8..70c4d7f1cb 100644 --- a/docs/d2/de3/classshaka_1_1media_1_1mp2t_1_1TsSectionPmt.html +++ b/docs/d2/de3/classshaka_1_1media_1_1mp2t_1_1TsSectionPmt.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::TsSectionPmt Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::mp2t::TsSectionPsi shaka::media::mp2t::TsSection - -
+ + - - + + @@ -113,16 +116,16 @@ void  - - + +

Public Types

-typedef base::Callback< void(int, int)> RegisterPesCb
 
+typedef base::Callback< void(int, TsStreamType, const uint8_t *, size_t)> RegisterPesCb
 
- Public Types inherited from shaka::media::mp2t::TsSection
enum  SpecialPid {
-  kPidPat = 0x0, -kPidCat = 0x1, -kPidTsdt = 0x2, -kPidNullPacket = 0x1fff, -
+  kPidPat = 0x0 +, kPidCat = 0x1 +, kPidTsdt = 0x2 +, kPidNullPacket = 0x1fff +,
  kPidMax = 0x1fff
}
ResetPsiSection (
bool Parse (bool payload_unit_start_indicator, const uint8_t *buf, int size) override
 
-void Flush () override
 
+bool Flush () override
 
void Reset () override
 

Detailed Description

-

Definition at line 16 of file ts_section_pmt.h.

+

Definition at line 17 of file ts_section_pmt.h.


The documentation for this class was generated from the following files:
  • packager/media/formats/mp2t/ts_section_pmt.h
  • packager/media/formats/mp2t/ts_section_pmt.cc
  • @@ -130,9 +133,7 @@ void Reset () override diff --git a/docs/d2/de6/packager__main_8cc_source.html b/docs/d2/de6/packager__main_8cc_source.html index 23f3ec7b5d..19735c17dc 100644 --- a/docs/d2/de6/packager__main_8cc_source.html +++ b/docs/d2/de6/packager__main_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/packager_main.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    packager_main.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include <gflags/gflags.h>
    8 #include <iostream>
    9 
    10 #include "packager/app/ad_cue_generator_flags.h"
    11 #include "packager/app/crypto_flags.h"
    12 #include "packager/app/hls_flags.h"
    13 #include "packager/app/manifest_flags.h"
    14 #include "packager/app/mpd_flags.h"
    15 #include "packager/app/muxer_flags.h"
    16 #include "packager/app/packager_util.h"
    17 #include "packager/app/playready_key_encryption_flags.h"
    18 #include "packager/app/protection_system_flags.h"
    19 #include "packager/app/raw_key_encryption_flags.h"
    20 #include "packager/app/stream_descriptor.h"
    21 #include "packager/app/vlog_flags.h"
    22 #include "packager/app/widevine_encryption_flags.h"
    23 #include "packager/base/command_line.h"
    24 #include "packager/base/logging.h"
    25 #include "packager/base/optional.h"
    26 #include "packager/base/strings/string_number_conversions.h"
    27 #include "packager/base/strings/string_split.h"
    28 #include "packager/base/strings/string_util.h"
    29 #include "packager/base/strings/stringprintf.h"
    30 #include "packager/file/file.h"
    31 #include "packager/packager.h"
    32 #include "packager/tools/license_notice.h"
    33 
    34 #if defined(OS_WIN)
    35 #include <codecvt>
    36 #include <functional>
    37 #include <locale>
    38 #endif // defined(OS_WIN)
    39 
    40 DEFINE_bool(dump_stream_info, false, "Dump demuxed stream info.");
    41 DEFINE_bool(licenses, false, "Dump licenses.");
    42 DEFINE_bool(quiet, false, "When enabled, LOG(INFO) output is suppressed.");
    43 DEFINE_bool(use_fake_clock_for_muxer,
    44  false,
    45  "Set to true to use a fake clock for muxer. With this flag set, "
    46  "creation time and modification time in outputs are set to 0. "
    47  "Should only be used for testing.");
    48 DEFINE_string(test_packager_version,
    49  "",
    50  "Packager version for testing. Should be used for testing only.");
    51 
    52 namespace shaka {
    53 namespace {
    54 
    55 const char kUsage[] =
    56  "%s [flags] <stream_descriptor> ...\n\n"
    57  " stream_descriptor consists of comma separated field_name/value pairs:\n"
    58  " field_name=value,[field_name=value,]...\n"
    59  " Supported field names are as follows (names in parenthesis are alias):\n"
    60  " - input (in): Required input/source media file path or network stream\n"
    61  " URL.\n"
    62  " - stream_selector (stream): Required field with value 'audio',\n"
    63  " 'video', 'text', or stream number (zero based).\n"
    64  " - output (out,init_segment): Required output file (single file) or\n"
    65  " initialization file path (multiple file).\n"
    66  " - segment_template (segment): Optional value which specifies the\n"
    67  " naming pattern for the segment files, and that the stream should be\n"
    68  " split into multiple files. Its presence should be consistent across\n"
    69  " streams.\n"
    70  " - bandwidth (bw): Optional value which contains a user-specified\n"
    71  " maximum bit rate for the stream, in bits/sec. If specified, this\n"
    72  " value is propagated to (HLS) EXT-X-STREAM-INF:BANDWIDTH or (DASH)\n"
    73  " Representation@bandwidth and the $Bandwidth$ template parameter for\n"
    74  " segment names. If not specified, the bandwidth value is estimated\n"
    75  " from content bitrate. Note that it only affects the generated\n"
    76  " manifests/playlists; it has no effect on the media content itself.\n"
    77  " - language (lang): Optional value which contains a user-specified\n"
    78  " language tag. If specified, this value overrides any language\n"
    79  " metadata in the input stream.\n"
    80  " - output_format (format): Optional value which specifies the format\n"
    81  " of the output files (MP4 or WebM). If not specified, it will be\n"
    82  " derived from the file extension of the output file.\n"
    83  " - skip_encryption=0|1: Optional. Defaults to 0 if not specified. If\n"
    84  " it is set to 1, no encryption of the stream will be made.\n"
    85  " - drm_label: Optional value for custom DRM label, which defines the\n"
    86  " encryption key applied to the stream. Typical values include AUDIO,\n"
    87  " SD, HD, UHD1, UHD2. For raw key, it should be a label defined in\n"
    88  " --keys. If not provided, the DRM label is derived from stream type\n"
    89  " (video, audio), resolution, etc.\n"
    90  " Note that it is case sensitive.\n"
    91  " - trick_play_factor (tpf): Optional value which specifies the trick\n"
    92  " play, a.k.a. trick mode, stream sampling rate among key frames.\n"
    93  " If specified, the output is a trick play stream.\n"
    94  " - hls_name: Used for HLS audio to set the NAME attribute for\n"
    95  " EXT-X-MEDIA. Defaults to the base of the playlist name.\n"
    96  " - hls_group_id: Used for HLS audio to set the GROUP-ID attribute for\n"
    97  " EXT-X-MEDIA. Defaults to 'audio' if not specified.\n"
    98  " - playlist_name: The HLS playlist file to create. Usually ends with\n"
    99  " '.m3u8', and is relative to --hls_master_playlist_output. If\n"
    100  " unspecified, defaults to something of the form 'stream_0.m3u8',\n"
    101  " 'stream_1.m3u8', 'stream_2.m3u8', etc.\n"
    102  " - iframe_playlist_name: The optional HLS I-Frames only playlist file\n"
    103  " to create. Usually ends with '.m3u8', and is relative to\n"
    104  " hls_master_playlist_output. Should only be set for video streams. If\n"
    105  " unspecified, no I-Frames only playlist is created.\n"
    106  " - hls_characteristics (charcs): Optional colon/semicolon separated\n"
    107  " list of values for the CHARACTERISTICS attribute for EXT-X-MEDIA.\n"
    108  " See CHARACTERISTICS attribute in http://bit.ly/2OOUkdB for details.\n"
    109  " - dash_accessibilities (accessibilities): Optional semicolon separated\n"
    110  " list of values for DASH Accessibility elements. The value should be\n"
    111  " in the format: scheme_id_uri=value.\n"
    112  " - dash_roles (roles): Optional semicolon separated list of values for\n"
    113  " DASH Role elements. The value should be one of: caption, subtitle,\n"
    114  " main, alternate, supplementary, commentary and dub. See DASH\n"
    115  " (ISO/IEC 23009-1) specification for details.\n";
    116 
    117 // Labels for parameters in RawKey key info.
    118 const char kDrmLabelLabel[] = "label";
    119 const char kKeyIdLabel[] = "key_id";
    120 const char kKeyLabel[] = "key";
    121 
    122 enum ExitStatus {
    123  kSuccess = 0,
    124  kArgumentValidationFailed,
    125  kPackagingFailed,
    126  kInternalError,
    127 };
    128 
    129 bool GetWidevineSigner(WidevineSigner* signer) {
    130  signer->signer_name = FLAGS_signer;
    131  if (!FLAGS_aes_signing_key_bytes.empty()) {
    132  signer->signing_key_type = WidevineSigner::SigningKeyType::kAes;
    133  signer->aes.key = FLAGS_aes_signing_key_bytes;
    134  signer->aes.iv = FLAGS_aes_signing_iv_bytes;
    135  } else if (!FLAGS_rsa_signing_key_path.empty()) {
    136  signer->signing_key_type = WidevineSigner::SigningKeyType::kRsa;
    137  if (!File::ReadFileToString(FLAGS_rsa_signing_key_path.c_str(),
    138  &signer->rsa.key)) {
    139  LOG(ERROR) << "Failed to read from '" << FLAGS_rsa_signing_key_path
    140  << "'.";
    141  return false;
    142  }
    143  }
    144  return true;
    145 }
    146 
    147 bool GetHlsPlaylistType(const std::string& playlist_type,
    148  HlsPlaylistType* playlist_type_enum) {
    149  if (base::ToUpperASCII(playlist_type) == "VOD") {
    150  *playlist_type_enum = HlsPlaylistType::kVod;
    151  } else if (base::ToUpperASCII(playlist_type) == "LIVE") {
    152  *playlist_type_enum = HlsPlaylistType::kLive;
    153  } else if (base::ToUpperASCII(playlist_type) == "EVENT") {
    154  *playlist_type_enum = HlsPlaylistType::kEvent;
    155  } else {
    156  LOG(ERROR) << "Unrecognized playlist type " << playlist_type;
    157  return false;
    158  }
    159  return true;
    160 }
    161 
    162 bool GetProtectionScheme(uint32_t* protection_scheme) {
    163  if (FLAGS_protection_scheme == "cenc") {
    164  *protection_scheme = EncryptionParams::kProtectionSchemeCenc;
    165  return true;
    166  }
    167  if (FLAGS_protection_scheme == "cbc1") {
    168  *protection_scheme = EncryptionParams::kProtectionSchemeCbc1;
    169  return true;
    170  }
    171  if (FLAGS_protection_scheme == "cbcs") {
    172  *protection_scheme = EncryptionParams::kProtectionSchemeCbcs;
    173  return true;
    174  }
    175  if (FLAGS_protection_scheme == "cens") {
    176  *protection_scheme = EncryptionParams::kProtectionSchemeCens;
    177  return true;
    178  }
    179  LOG(ERROR) << "Unrecognized protection_scheme " << FLAGS_protection_scheme;
    180  return false;
    181 }
    182 
    183 bool ParseKeys(const std::string& keys, RawKeyParams* raw_key) {
    184  for (const std::string& key_data : base::SplitString(
    185  keys, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
    186  base::StringPairs string_pairs;
    187  base::SplitStringIntoKeyValuePairs(key_data, '=', ':', &string_pairs);
    188 
    189  std::map<std::string, std::string> value_map;
    190  for (const auto& string_pair : string_pairs)
    191  value_map[string_pair.first] = string_pair.second;
    192  const std::string drm_label = value_map[kDrmLabelLabel];
    193  if (raw_key->key_map.find(drm_label) != raw_key->key_map.end()) {
    194  LOG(ERROR) << "Seeing duplicated DRM label '" << drm_label << "'.";
    195  return false;
    196  }
    197  auto& key_info = raw_key->key_map[drm_label];
    198  if (value_map[kKeyIdLabel].empty() ||
    199  !base::HexStringToBytes(value_map[kKeyIdLabel], &key_info.key_id)) {
    200  LOG(ERROR) << "Empty key id or invalid hex string for key id: "
    201  << value_map[kKeyIdLabel];
    202  return false;
    203  }
    204  if (value_map[kKeyLabel].empty() ||
    205  !base::HexStringToBytes(value_map[kKeyLabel], &key_info.key)) {
    206  LOG(ERROR) << "Empty key or invalid hex string for key: "
    207  << value_map[kKeyLabel];
    208  return false;
    209  }
    210  }
    211  return true;
    212 }
    213 
    214 bool GetRawKeyParams(RawKeyParams* raw_key) {
    215  raw_key->iv = FLAGS_iv_bytes;
    216  raw_key->pssh = FLAGS_pssh_bytes;
    217  if (!FLAGS_keys.empty()) {
    218  if (!ParseKeys(FLAGS_keys, raw_key)) {
    219  LOG(ERROR) << "Failed to parse --keys " << FLAGS_keys;
    220  return false;
    221  }
    222  } else {
    223  // An empty StreamLabel specifies the default key info.
    224  RawKeyParams::KeyInfo& key_info = raw_key->key_map[""];
    225  key_info.key_id = FLAGS_key_id_bytes;
    226  key_info.key = FLAGS_key_bytes;
    227  }
    228  return true;
    229 }
    230 
    231 bool ParseAdCues(const std::string& ad_cues, std::vector<Cuepoint>* cuepoints) {
    232  // Track if optional field is supplied consistently across all cue points.
    233  size_t duration_count = 0;
    234 
    235  for (const std::string& ad_cue : base::SplitString(
    236  ad_cues, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
    237  Cuepoint cuepoint;
    238  auto split_ad_cue = base::SplitString(ad_cue, ",", base::TRIM_WHITESPACE,
    239  base::SPLIT_WANT_NONEMPTY);
    240  if (split_ad_cue.size() > 2) {
    241  LOG(ERROR) << "Failed to parse --ad_cues " << ad_cues
    242  << " Each ad cue must contain no more than 2 components.";
    243  }
    244  if (!base::StringToDouble(split_ad_cue.front(),
    245  &cuepoint.start_time_in_seconds)) {
    246  LOG(ERROR) << "Failed to parse --ad_cues " << ad_cues
    247  << " Start time component must be of type double.";
    248  return false;
    249  }
    250  if (split_ad_cue.size() > 1) {
    251  duration_count++;
    252  if (!base::StringToDouble(split_ad_cue[1],
    253  &cuepoint.duration_in_seconds)) {
    254  LOG(ERROR) << "Failed to parse --ad_cues " << ad_cues
    255  << " Duration component must be of type double.";
    256  return false;
    257  }
    258  }
    259  cuepoints->push_back(cuepoint);
    260  }
    261 
    262  if (duration_count > 0 && duration_count != cuepoints->size()) {
    263  LOG(ERROR) << "Failed to parse --ad_cues " << ad_cues
    264  << " Duration component is optional. However if it is supplied,"
    265  << " it must be supplied consistently across all cuepoints.";
    266  return false;
    267  }
    268  return true;
    269 }
    270 
    271 bool ParseProtectionSystems(
    272  const std::string& protection_systems_str,
    273  std::vector<EncryptionParams::ProtectionSystem>* protection_systems) {
    274  protection_systems->clear();
    275 
    276  std::map<std::string, EncryptionParams::ProtectionSystem> mapping = {
    277  {"common", EncryptionParams::ProtectionSystem::kCommonSystem},
    278  {"commonsystem", EncryptionParams::ProtectionSystem::kCommonSystem},
    279  {"fairplay", EncryptionParams::ProtectionSystem::kFairPlay},
    280  {"marlin", EncryptionParams::ProtectionSystem::kMarlin},
    281  {"playready", EncryptionParams::ProtectionSystem::kPlayReady},
    282  {"widevine", EncryptionParams::ProtectionSystem::kWidevine},
    283  };
    284 
    285  for (const std::string& protection_system :
    286  base::SplitString(base::ToLowerASCII(protection_systems_str), ",",
    287  base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
    288  auto iter = mapping.find(protection_system);
    289  if (iter == mapping.end()) {
    290  LOG(ERROR) << "Seeing unrecognized protection system: "
    291  << protection_system;
    292  return false;
    293  }
    294  protection_systems->push_back(iter->second);
    295  }
    296  return true;
    297 }
    298 
    299 base::Optional<PackagingParams> GetPackagingParams() {
    300  PackagingParams packaging_params;
    301 
    302  packaging_params.temp_dir = FLAGS_temp_dir;
    303 
    304  AdCueGeneratorParams& ad_cue_generator_params =
    305  packaging_params.ad_cue_generator_params;
    306  if (!ParseAdCues(FLAGS_ad_cues, &ad_cue_generator_params.cue_points)) {
    307  return base::nullopt;
    308  }
    309 
    310  ChunkingParams& chunking_params = packaging_params.chunking_params;
    311  chunking_params.segment_duration_in_seconds = FLAGS_segment_duration;
    312  chunking_params.subsegment_duration_in_seconds = FLAGS_fragment_duration;
    313  chunking_params.segment_sap_aligned = FLAGS_segment_sap_aligned;
    314  chunking_params.subsegment_sap_aligned = FLAGS_fragment_sap_aligned;
    315 
    316  int num_key_providers = 0;
    317  EncryptionParams& encryption_params = packaging_params.encryption_params;
    318  if (FLAGS_enable_widevine_encryption) {
    319  encryption_params.key_provider = KeyProvider::kWidevine;
    320  ++num_key_providers;
    321  }
    322  if (FLAGS_enable_playready_encryption) {
    323  encryption_params.key_provider = KeyProvider::kPlayReady;
    324  ++num_key_providers;
    325  }
    326  if (FLAGS_enable_raw_key_encryption) {
    327  encryption_params.key_provider = KeyProvider::kRawKey;
    328  ++num_key_providers;
    329  }
    330  if (num_key_providers > 1) {
    331  LOG(ERROR) << "Only one of --enable_widevine_encryption, "
    332  "--enable_playready_encryption, "
    333  "--enable_raw_key_encryption can be enabled.";
    334  return base::nullopt;
    335  }
    336 
    337  if (!ParseProtectionSystems(FLAGS_protection_systems,
    338  &encryption_params.protection_systems)) {
    339  return base::nullopt;
    340  }
    341 
    342  if (encryption_params.key_provider != KeyProvider::kNone) {
    343  encryption_params.clear_lead_in_seconds = FLAGS_clear_lead;
    344  if (!GetProtectionScheme(&encryption_params.protection_scheme))
    345  return base::nullopt;
    346  encryption_params.crypto_period_duration_in_seconds =
    347  FLAGS_crypto_period_duration;
    348  encryption_params.vp9_subsample_encryption = FLAGS_vp9_subsample_encryption;
    349  encryption_params.stream_label_func = std::bind(
    350  &Packager::DefaultStreamLabelFunction, FLAGS_max_sd_pixels,
    351  FLAGS_max_hd_pixels, FLAGS_max_uhd1_pixels, std::placeholders::_1);
    352  }
    353  switch (encryption_params.key_provider) {
    354  case KeyProvider::kWidevine: {
    355  WidevineEncryptionParams& widevine = encryption_params.widevine;
    356  widevine.key_server_url = FLAGS_key_server_url;
    357 
    358  widevine.content_id = FLAGS_content_id_bytes;
    359  widevine.policy = FLAGS_policy;
    360  widevine.group_id = FLAGS_group_id_bytes;
    361  widevine.enable_entitlement_license = FLAGS_enable_entitlement_license;
    362  if (!GetWidevineSigner(&widevine.signer))
    363  return base::nullopt;
    364  break;
    365  }
    366  case KeyProvider::kPlayReady: {
    367  PlayReadyEncryptionParams& playready = encryption_params.playready;
    368  playready.key_server_url = FLAGS_playready_server_url;
    369  playready.program_identifier = FLAGS_program_identifier;
    370  playready.ca_file = FLAGS_ca_file;
    371  playready.client_cert_file = FLAGS_client_cert_file;
    372  playready.client_cert_private_key_file =
    373  FLAGS_client_cert_private_key_file;
    374  playready.client_cert_private_key_password =
    375  FLAGS_client_cert_private_key_password;
    376  break;
    377  }
    378  case KeyProvider::kRawKey: {
    379  if (!GetRawKeyParams(&encryption_params.raw_key))
    380  return base::nullopt;
    381  break;
    382  }
    383  case KeyProvider::kNone:
    384  break;
    385  }
    386 
    387  num_key_providers = 0;
    388  DecryptionParams& decryption_params = packaging_params.decryption_params;
    389  if (FLAGS_enable_widevine_decryption) {
    390  decryption_params.key_provider = KeyProvider::kWidevine;
    391  ++num_key_providers;
    392  }
    393  if (FLAGS_enable_raw_key_decryption) {
    394  decryption_params.key_provider = KeyProvider::kRawKey;
    395  ++num_key_providers;
    396  }
    397  if (num_key_providers > 1) {
    398  LOG(ERROR) << "Only one of --enable_widevine_decryption, "
    399  "--enable_raw_key_decryption can be enabled.";
    400  return base::nullopt;
    401  }
    402  switch (decryption_params.key_provider) {
    403  case KeyProvider::kWidevine: {
    404  WidevineDecryptionParams& widevine = decryption_params.widevine;
    405  widevine.key_server_url = FLAGS_key_server_url;
    406  if (!GetWidevineSigner(&widevine.signer))
    407  return base::nullopt;
    408  break;
    409  }
    410  case KeyProvider::kRawKey: {
    411  if (!GetRawKeyParams(&decryption_params.raw_key))
    412  return base::nullopt;
    413  break;
    414  }
    415  case KeyProvider::kPlayReady:
    416  case KeyProvider::kNone:
    417  break;
    418  }
    419 
    420  Mp4OutputParams& mp4_params = packaging_params.mp4_output_params;
    421  mp4_params.generate_sidx_in_media_segments =
    422  FLAGS_generate_sidx_in_media_segments;
    423  mp4_params.include_pssh_in_stream = FLAGS_mp4_include_pssh_in_stream;
    424 
    425  packaging_params.transport_stream_timestamp_offset_ms =
    426  FLAGS_transport_stream_timestamp_offset_ms;
    427 
    428  packaging_params.output_media_info = FLAGS_output_media_info;
    429 
    430  MpdParams& mpd_params = packaging_params.mpd_params;
    431  mpd_params.mpd_output = FLAGS_mpd_output;
    432  mpd_params.base_urls = base::SplitString(
    433  FLAGS_base_urls, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    434  mpd_params.min_buffer_time = FLAGS_min_buffer_time;
    435  mpd_params.minimum_update_period = FLAGS_minimum_update_period;
    436  mpd_params.suggested_presentation_delay = FLAGS_suggested_presentation_delay;
    437  mpd_params.time_shift_buffer_depth = FLAGS_time_shift_buffer_depth;
    438  mpd_params.preserved_segments_outside_live_window =
    439  FLAGS_preserved_segments_outside_live_window;
    440 
    441  if (!FLAGS_utc_timings.empty()) {
    442  base::StringPairs pairs;
    443  if (!base::SplitStringIntoKeyValuePairs(FLAGS_utc_timings, '=', ',',
    444  &pairs)) {
    445  LOG(ERROR) << "Invalid --utc_timings scheme_id_uri/value pairs.";
    446  return base::nullopt;
    447  }
    448  for (const auto& string_pair : pairs) {
    449  mpd_params.utc_timings.push_back({string_pair.first, string_pair.second});
    450  }
    451  }
    452 
    453  mpd_params.default_language = FLAGS_default_language;
    454  mpd_params.default_text_language = FLAGS_default_text_language;
    455  mpd_params.generate_static_live_mpd = FLAGS_generate_static_live_mpd;
    456  mpd_params.generate_dash_if_iop_compliant_mpd =
    457  FLAGS_generate_dash_if_iop_compliant_mpd;
    458  mpd_params.allow_approximate_segment_timeline =
    459  FLAGS_allow_approximate_segment_timeline;
    460 
    461  HlsParams& hls_params = packaging_params.hls_params;
    462  if (!GetHlsPlaylistType(FLAGS_hls_playlist_type, &hls_params.playlist_type)) {
    463  return base::nullopt;
    464  }
    465  hls_params.master_playlist_output = FLAGS_hls_master_playlist_output;
    466  hls_params.base_url = FLAGS_hls_base_url;
    467  hls_params.key_uri = FLAGS_hls_key_uri;
    468  hls_params.time_shift_buffer_depth = FLAGS_time_shift_buffer_depth;
    469  hls_params.preserved_segments_outside_live_window =
    470  FLAGS_preserved_segments_outside_live_window;
    471  hls_params.default_language = FLAGS_default_language;
    472  hls_params.default_text_language = FLAGS_default_text_language;
    473 
    474  TestParams& test_params = packaging_params.test_params;
    475  test_params.dump_stream_info = FLAGS_dump_stream_info;
    476  test_params.inject_fake_clock = FLAGS_use_fake_clock_for_muxer;
    477  if (!FLAGS_test_packager_version.empty())
    478  test_params.injected_library_version = FLAGS_test_packager_version;
    479 
    480  return packaging_params;
    481 }
    482 
    483 int PackagerMain(int argc, char** argv) {
    484  // Needed to enable VLOG/DVLOG through --vmodule or --v.
    485  base::CommandLine::Init(argc, argv);
    486 
    487  // Set up logging.
    488  logging::LoggingSettings log_settings;
    489  log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
    490  CHECK(logging::InitLogging(log_settings));
    491 
    492  google::SetVersionString(shaka::Packager::GetLibraryVersion());
    493  google::SetUsageMessage(base::StringPrintf(kUsage, argv[0]));
    494  google::ParseCommandLineFlags(&argc, &argv, true);
    495  if (FLAGS_licenses) {
    496  for (const char* line : kLicenseNotice)
    497  std::cout << line << std::endl;
    498  return kSuccess;
    499  }
    500  if (argc < 2) {
    501  google::ShowUsageWithFlags("Usage");
    502  return kSuccess;
    503  }
    504  if (FLAGS_quiet)
    505  logging::SetMinLogLevel(logging::LOG_WARNING);
    506 
    509  return kArgumentValidationFailed;
    510  }
    511 
    512  base::Optional<PackagingParams> packaging_params = GetPackagingParams();
    513  if (!packaging_params)
    514  return kArgumentValidationFailed;
    515 
    516  std::vector<StreamDescriptor> stream_descriptors;
    517  for (int i = 1; i < argc; ++i) {
    518  base::Optional<StreamDescriptor> stream_descriptor =
    519  ParseStreamDescriptor(argv[i]);
    520  if (!stream_descriptor)
    521  return kArgumentValidationFailed;
    522  stream_descriptors.push_back(stream_descriptor.value());
    523  }
    524  Packager packager;
    525  Status status =
    526  packager.Initialize(packaging_params.value(), stream_descriptors);
    527  if (!status.ok()) {
    528  LOG(ERROR) << "Failed to initialize packager: " << status.ToString();
    529  return kArgumentValidationFailed;
    530  }
    531  status = packager.Run();
    532  if (!status.ok()) {
    533  LOG(ERROR) << "Packaging Error: " << status.ToString();
    534  return kPackagingFailed;
    535  }
    536  if (!FLAGS_quiet)
    537  printf("Packaging completed successfully.\n");
    538  return kSuccess;
    539 }
    540 
    541 } // namespace
    542 } // namespace shaka
    543 
    544 #if defined(OS_WIN)
    545 // Windows wmain, which converts wide character arguments to UTF-8.
    546 int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) {
    547  std::unique_ptr<char* [], std::function<void(char**)>> utf8_argv(
    548  new char*[argc], [argc](char** utf8_args) {
    549  // TODO(tinskip): This leaks, but if this code is enabled, it crashes.
    550  // Figure out why. I suspect gflags does something funny with the
    551  // argument array.
    552  // for (int idx = 0; idx < argc; ++idx)
    553  // delete[] utf8_args[idx];
    554  delete[] utf8_args;
    555  });
    556  std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    557  for (int idx = 0; idx < argc; ++idx) {
    558  std::string utf8_arg(converter.to_bytes(argv[idx]));
    559  utf8_arg += '\0';
    560  utf8_argv[idx] = new char[utf8_arg.size()];
    561  memcpy(utf8_argv[idx], &utf8_arg[0], utf8_arg.size());
    562  }
    563  return shaka::PackagerMain(argc, utf8_argv.get());
    564 }
    565 #else
    566 int main(int argc, char** argv) {
    567  return shaka::PackagerMain(argc, argv);
    568 }
    569 #endif // defined(OS_WIN)
    static std::string DefaultStreamLabelFunction(int max_sd_pixels, int max_hd_pixels, int max_uhd1_pixels, const EncryptionParams::EncryptedStreamAttributes &stream_attributes)
    Definition: packager.cc:1033
    -
    HlsPlaylistType
    Definition: hls_params.h:16
    -
    base::Optional< StreamDescriptor > ParseStreamDescriptor(const std::string &descriptor_string)
    -
    static bool ReadFileToString(const char *file_name, std::string *contents)
    Definition: file.cc:216
    -
    bool ValidateRawKeyCryptoFlags()
    -
    bool ValidateWidevineCryptoFlags()
    -
    All the methods that are virtual are virtual for mocking.
    -
    static std::string GetLibraryVersion()
    Definition: packager.cc:1029
    -
    static constexpr uint32_t kProtectionSchemeCenc
    The protection scheme: "cenc", "cens", "cbc1", "cbcs".
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include <gflags/gflags.h>
    +
    8 #include <iostream>
    +
    9 
    +
    10 #include "packager/app/ad_cue_generator_flags.h"
    +
    11 #include "packager/app/crypto_flags.h"
    +
    12 #include "packager/app/hls_flags.h"
    +
    13 #include "packager/app/manifest_flags.h"
    +
    14 #include "packager/app/mpd_flags.h"
    +
    15 #include "packager/app/muxer_flags.h"
    +
    16 #include "packager/app/packager_util.h"
    +
    17 #include "packager/app/playready_key_encryption_flags.h"
    +
    18 #include "packager/app/protection_system_flags.h"
    +
    19 #include "packager/app/raw_key_encryption_flags.h"
    +
    20 #include "packager/app/stream_descriptor.h"
    +
    21 #include "packager/app/vlog_flags.h"
    +
    22 #include "packager/app/widevine_encryption_flags.h"
    +
    23 #include "packager/base/command_line.h"
    +
    24 #include "packager/base/logging.h"
    +
    25 #include "packager/base/optional.h"
    +
    26 #include "packager/base/strings/string_number_conversions.h"
    +
    27 #include "packager/base/strings/string_split.h"
    +
    28 #include "packager/base/strings/string_util.h"
    +
    29 #include "packager/base/strings/stringprintf.h"
    +
    30 #include "packager/file/file.h"
    +
    31 #include "packager/packager.h"
    +
    32 #include "packager/tools/license_notice.h"
    +
    33 
    +
    34 #if defined(OS_WIN)
    +
    35 #include <codecvt>
    +
    36 #include <functional>
    +
    37 #include <locale>
    +
    38 #endif // defined(OS_WIN)
    +
    39 
    +
    40 DEFINE_bool(dump_stream_info, false, "Dump demuxed stream info.");
    +
    41 DEFINE_bool(licenses, false, "Dump licenses.");
    +
    42 DEFINE_bool(quiet, false, "When enabled, LOG(INFO) output is suppressed.");
    +
    43 DEFINE_bool(use_fake_clock_for_muxer,
    +
    44  false,
    +
    45  "Set to true to use a fake clock for muxer. With this flag set, "
    +
    46  "creation time and modification time in outputs are set to 0. "
    +
    47  "Should only be used for testing.");
    +
    48 DEFINE_string(test_packager_version,
    +
    49  "",
    +
    50  "Packager version for testing. Should be used for testing only.");
    +
    51 DEFINE_bool(single_threaded,
    +
    52  false,
    +
    53  "If enabled, only use one thread when generating content.");
    +
    54 
    +
    55 namespace shaka {
    +
    56 namespace {
    +
    57 
    +
    58 const char kUsage[] =
    +
    59  "%s [flags] <stream_descriptor> ...\n\n"
    +
    60  " stream_descriptor consists of comma separated field_name/value pairs:\n"
    +
    61  " field_name=value,[field_name=value,]...\n"
    +
    62  " Supported field names are as follows (names in parenthesis are alias):\n"
    +
    63  " - input (in): Required input/source media file path or network stream\n"
    +
    64  " URL.\n"
    +
    65  " - stream_selector (stream): Required field with value 'audio',\n"
    +
    66  " 'video', 'text', or stream number (zero based).\n"
    +
    67  " - output (out,init_segment): Required output file (single file) or\n"
    +
    68  " initialization file path (multiple file).\n"
    +
    69  " - segment_template (segment): Optional value which specifies the\n"
    +
    70  " naming pattern for the segment files, and that the stream should be\n"
    +
    71  " split into multiple files. Its presence should be consistent across\n"
    +
    72  " streams.\n"
    +
    73  " - bandwidth (bw): Optional value which contains a user-specified\n"
    +
    74  " maximum bit rate for the stream, in bits/sec. If specified, this\n"
    +
    75  " value is propagated to (HLS) EXT-X-STREAM-INF:BANDWIDTH or (DASH)\n"
    +
    76  " Representation@bandwidth and the $Bandwidth$ template parameter for\n"
    +
    77  " segment names. If not specified, the bandwidth value is estimated\n"
    +
    78  " from content bitrate. Note that it only affects the generated\n"
    +
    79  " manifests/playlists; it has no effect on the media content itself.\n"
    +
    80  " - language (lang): Optional value which contains a user-specified\n"
    +
    81  " language tag. If specified, this value overrides any language\n"
    +
    82  " metadata in the input stream.\n"
    +
    83  " - output_format (format): Optional value which specifies the format\n"
    +
    84  " of the output files (MP4 or WebM). If not specified, it will be\n"
    +
    85  " derived from the file extension of the output file.\n"
    +
    86  " - skip_encryption=0|1: Optional. Defaults to 0 if not specified. If\n"
    +
    87  " it is set to 1, no encryption of the stream will be made.\n"
    +
    88  " - drm_label: Optional value for custom DRM label, which defines the\n"
    +
    89  " encryption key applied to the stream. Typical values include AUDIO,\n"
    +
    90  " SD, HD, UHD1, UHD2. For raw key, it should be a label defined in\n"
    +
    91  " --keys. If not provided, the DRM label is derived from stream type\n"
    +
    92  " (video, audio), resolution, etc.\n"
    +
    93  " Note that it is case sensitive.\n"
    +
    94  " - trick_play_factor (tpf): Optional value which specifies the trick\n"
    +
    95  " play, a.k.a. trick mode, stream sampling rate among key frames.\n"
    +
    96  " If specified, the output is a trick play stream.\n"
    +
    97  " - hls_name: Used for HLS audio to set the NAME attribute for\n"
    +
    98  " EXT-X-MEDIA. Defaults to the base of the playlist name.\n"
    +
    99  " - hls_group_id: Used for HLS audio to set the GROUP-ID attribute for\n"
    +
    100  " EXT-X-MEDIA. Defaults to 'audio' if not specified.\n"
    +
    101  " - playlist_name: The HLS playlist file to create. Usually ends with\n"
    +
    102  " '.m3u8', and is relative to --hls_master_playlist_output. If\n"
    +
    103  " unspecified, defaults to something of the form 'stream_0.m3u8',\n"
    +
    104  " 'stream_1.m3u8', 'stream_2.m3u8', etc.\n"
    +
    105  " - iframe_playlist_name: The optional HLS I-Frames only playlist file\n"
    +
    106  " to create. Usually ends with '.m3u8', and is relative to\n"
    +
    107  " hls_master_playlist_output. Should only be set for video streams. If\n"
    +
    108  " unspecified, no I-Frames only playlist is created.\n"
    +
    109  " - hls_characteristics (charcs): Optional colon/semicolon separated\n"
    +
    110  " list of values for the CHARACTERISTICS attribute for EXT-X-MEDIA.\n"
    +
    111  " See CHARACTERISTICS attribute in http://bit.ly/2OOUkdB for details.\n"
    +
    112  " - dash_accessibilities (accessibilities): Optional semicolon separated\n"
    +
    113  " list of values for DASH Accessibility elements. The value should be\n"
    +
    114  " in the format: scheme_id_uri=value.\n"
    +
    115  " - dash_roles (roles): Optional semicolon separated list of values for\n"
    +
    116  " DASH Role elements. The value should be one of: caption, subtitle,\n"
    +
    117  " main, alternate, supplementary, commentary and dub. See DASH\n"
    +
    118  " (ISO/IEC 23009-1) specification for details.\n";
    +
    119 
    +
    120 // Labels for parameters in RawKey key info.
    +
    121 const char kDrmLabelLabel[] = "label";
    +
    122 const char kKeyIdLabel[] = "key_id";
    +
    123 const char kKeyLabel[] = "key";
    +
    124 const char kKeyIvLabel[] = "iv";
    +
    125 
    +
    126 enum ExitStatus {
    +
    127  kSuccess = 0,
    +
    128  kArgumentValidationFailed,
    +
    129  kPackagingFailed,
    +
    130  kInternalError,
    +
    131 };
    +
    132 
    +
    133 bool GetWidevineSigner(WidevineSigner* signer) {
    +
    134  signer->signer_name = FLAGS_signer;
    +
    135  if (!FLAGS_aes_signing_key_bytes.empty()) {
    +
    136  signer->signing_key_type = WidevineSigner::SigningKeyType::kAes;
    +
    137  signer->aes.key = FLAGS_aes_signing_key_bytes;
    +
    138  signer->aes.iv = FLAGS_aes_signing_iv_bytes;
    +
    139  } else if (!FLAGS_rsa_signing_key_path.empty()) {
    +
    140  signer->signing_key_type = WidevineSigner::SigningKeyType::kRsa;
    +
    141  if (!File::ReadFileToString(FLAGS_rsa_signing_key_path.c_str(),
    +
    142  &signer->rsa.key)) {
    +
    143  LOG(ERROR) << "Failed to read from '" << FLAGS_rsa_signing_key_path
    +
    144  << "'.";
    +
    145  return false;
    +
    146  }
    +
    147  }
    +
    148  return true;
    +
    149 }
    +
    150 
    +
    151 bool GetHlsPlaylistType(const std::string& playlist_type,
    +
    152  HlsPlaylistType* playlist_type_enum) {
    +
    153  if (base::ToUpperASCII(playlist_type) == "VOD") {
    +
    154  *playlist_type_enum = HlsPlaylistType::kVod;
    +
    155  } else if (base::ToUpperASCII(playlist_type) == "LIVE") {
    +
    156  *playlist_type_enum = HlsPlaylistType::kLive;
    +
    157  } else if (base::ToUpperASCII(playlist_type) == "EVENT") {
    +
    158  *playlist_type_enum = HlsPlaylistType::kEvent;
    +
    159  } else {
    +
    160  LOG(ERROR) << "Unrecognized playlist type " << playlist_type;
    +
    161  return false;
    +
    162  }
    +
    163  return true;
    +
    164 }
    +
    165 
    +
    166 bool GetProtectionScheme(uint32_t* protection_scheme) {
    +
    167  if (FLAGS_protection_scheme == "cenc") {
    +
    168  *protection_scheme = EncryptionParams::kProtectionSchemeCenc;
    +
    169  return true;
    +
    170  }
    +
    171  if (FLAGS_protection_scheme == "cbc1") {
    +
    172  *protection_scheme = EncryptionParams::kProtectionSchemeCbc1;
    +
    173  return true;
    +
    174  }
    +
    175  if (FLAGS_protection_scheme == "cbcs") {
    +
    176  *protection_scheme = EncryptionParams::kProtectionSchemeCbcs;
    +
    177  return true;
    +
    178  }
    +
    179  if (FLAGS_protection_scheme == "cens") {
    +
    180  *protection_scheme = EncryptionParams::kProtectionSchemeCens;
    +
    181  return true;
    +
    182  }
    +
    183  LOG(ERROR) << "Unrecognized protection_scheme " << FLAGS_protection_scheme;
    +
    184  return false;
    +
    185 }
    +
    186 
    +
    187 bool ParseKeys(const std::string& keys, RawKeyParams* raw_key) {
    +
    188  for (const std::string& key_data : base::SplitString(
    +
    189  keys, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
    +
    190  base::StringPairs string_pairs;
    +
    191  base::SplitStringIntoKeyValuePairs(key_data, '=', ':', &string_pairs);
    +
    192 
    +
    193  std::map<std::string, std::string> value_map;
    +
    194  for (const auto& string_pair : string_pairs)
    +
    195  value_map[string_pair.first] = string_pair.second;
    +
    196  const std::string drm_label = value_map[kDrmLabelLabel];
    +
    197  if (raw_key->key_map.find(drm_label) != raw_key->key_map.end()) {
    +
    198  LOG(ERROR) << "Seeing duplicated DRM label '" << drm_label << "'.";
    +
    199  return false;
    +
    200  }
    +
    201  auto& key_info = raw_key->key_map[drm_label];
    +
    202  if (value_map[kKeyIdLabel].empty() ||
    +
    203  !base::HexStringToBytes(value_map[kKeyIdLabel], &key_info.key_id)) {
    +
    204  LOG(ERROR) << "Empty key id or invalid hex string for key id: "
    +
    205  << value_map[kKeyIdLabel];
    +
    206  return false;
    +
    207  }
    +
    208  if (value_map[kKeyLabel].empty() ||
    +
    209  !base::HexStringToBytes(value_map[kKeyLabel], &key_info.key)) {
    +
    210  LOG(ERROR) << "Empty key or invalid hex string for key: "
    +
    211  << value_map[kKeyLabel];
    +
    212  return false;
    +
    213  }
    +
    214  if (!value_map[kKeyIvLabel].empty()) {
    +
    215  if (!raw_key->iv.empty()) {
    +
    216  LOG(ERROR) << "IV already specified with --iv";
    +
    217  return false;
    +
    218  }
    +
    219  if (!base::HexStringToBytes(value_map[kKeyIvLabel], &key_info.iv)) {
    +
    220  LOG(ERROR) << "Empty IV or invalid hex string for IV: "
    +
    221  << value_map[kKeyIvLabel];
    +
    222  return false;
    +
    223  }
    +
    224  }
    +
    225  }
    +
    226  return true;
    +
    227 }
    +
    228 
    +
    229 bool GetRawKeyParams(RawKeyParams* raw_key) {
    +
    230  raw_key->iv = FLAGS_iv_bytes;
    +
    231  raw_key->pssh = FLAGS_pssh_bytes;
    +
    232  if (!FLAGS_keys.empty()) {
    +
    233  if (!ParseKeys(FLAGS_keys, raw_key)) {
    +
    234  LOG(ERROR) << "Failed to parse --keys " << FLAGS_keys;
    +
    235  return false;
    +
    236  }
    +
    237  } else {
    +
    238  // An empty StreamLabel specifies the default key info.
    +
    239  RawKeyParams::KeyInfo& key_info = raw_key->key_map[""];
    +
    240  key_info.key_id = FLAGS_key_id_bytes;
    +
    241  key_info.key = FLAGS_key_bytes;
    +
    242  }
    +
    243  return true;
    +
    244 }
    +
    245 
    +
    246 bool ParseAdCues(const std::string& ad_cues, std::vector<Cuepoint>* cuepoints) {
    +
    247  // Track if optional field is supplied consistently across all cue points.
    +
    248  size_t duration_count = 0;
    +
    249 
    +
    250  for (const std::string& ad_cue : base::SplitString(
    +
    251  ad_cues, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
    +
    252  Cuepoint cuepoint;
    +
    253  auto split_ad_cue = base::SplitString(ad_cue, ",", base::TRIM_WHITESPACE,
    +
    254  base::SPLIT_WANT_NONEMPTY);
    +
    255  if (split_ad_cue.size() > 2) {
    +
    256  LOG(ERROR) << "Failed to parse --ad_cues " << ad_cues
    +
    257  << " Each ad cue must contain no more than 2 components.";
    +
    258  }
    +
    259  if (!base::StringToDouble(split_ad_cue.front(),
    +
    260  &cuepoint.start_time_in_seconds)) {
    +
    261  LOG(ERROR) << "Failed to parse --ad_cues " << ad_cues
    +
    262  << " Start time component must be of type double.";
    +
    263  return false;
    +
    264  }
    +
    265  if (split_ad_cue.size() > 1) {
    +
    266  duration_count++;
    +
    267  if (!base::StringToDouble(split_ad_cue[1],
    +
    268  &cuepoint.duration_in_seconds)) {
    +
    269  LOG(ERROR) << "Failed to parse --ad_cues " << ad_cues
    +
    270  << " Duration component must be of type double.";
    +
    271  return false;
    +
    272  }
    +
    273  }
    +
    274  cuepoints->push_back(cuepoint);
    +
    275  }
    +
    276 
    +
    277  if (duration_count > 0 && duration_count != cuepoints->size()) {
    +
    278  LOG(ERROR) << "Failed to parse --ad_cues " << ad_cues
    +
    279  << " Duration component is optional. However if it is supplied,"
    +
    280  << " it must be supplied consistently across all cuepoints.";
    +
    281  return false;
    +
    282  }
    +
    283  return true;
    +
    284 }
    +
    285 
    +
    286 bool ParseProtectionSystems(const std::string& protection_systems_str,
    +
    287  ProtectionSystem* protection_systems) {
    +
    288  *protection_systems = ProtectionSystem::kNone;
    +
    289 
    +
    290  std::map<std::string, ProtectionSystem> mapping = {
    +
    291  {"common", ProtectionSystem::kCommon},
    +
    292  {"commonsystem", ProtectionSystem::kCommon},
    +
    293  {"fairplay", ProtectionSystem::kFairPlay},
    +
    294  {"marlin", ProtectionSystem::kMarlin},
    +
    295  {"playready", ProtectionSystem::kPlayReady},
    +
    296  {"widevine", ProtectionSystem::kWidevine},
    +
    297  };
    +
    298 
    +
    299  for (const std::string& protection_system :
    +
    300  base::SplitString(base::ToLowerASCII(protection_systems_str), ",",
    +
    301  base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
    +
    302  auto iter = mapping.find(protection_system);
    +
    303  if (iter == mapping.end()) {
    +
    304  LOG(ERROR) << "Seeing unrecognized protection system: "
    +
    305  << protection_system;
    +
    306  return false;
    +
    307  }
    +
    308  *protection_systems |= iter->second;
    +
    309  }
    +
    310  return true;
    +
    311 }
    +
    312 
    +
    313 base::Optional<PackagingParams> GetPackagingParams() {
    +
    314  PackagingParams packaging_params;
    +
    315 
    +
    316  packaging_params.temp_dir = FLAGS_temp_dir;
    +
    317  packaging_params.single_threaded = FLAGS_single_threaded;
    +
    318 
    +
    319  AdCueGeneratorParams& ad_cue_generator_params =
    +
    320  packaging_params.ad_cue_generator_params;
    +
    321  if (!ParseAdCues(FLAGS_ad_cues, &ad_cue_generator_params.cue_points)) {
    +
    322  return base::nullopt;
    +
    323  }
    +
    324 
    +
    325  ChunkingParams& chunking_params = packaging_params.chunking_params;
    +
    326  chunking_params.segment_duration_in_seconds = FLAGS_segment_duration;
    +
    327  chunking_params.subsegment_duration_in_seconds = FLAGS_fragment_duration;
    +
    328  chunking_params.segment_sap_aligned = FLAGS_segment_sap_aligned;
    +
    329  chunking_params.subsegment_sap_aligned = FLAGS_fragment_sap_aligned;
    +
    330 
    +
    331  int num_key_providers = 0;
    +
    332  EncryptionParams& encryption_params = packaging_params.encryption_params;
    +
    333  if (FLAGS_enable_widevine_encryption) {
    +
    334  encryption_params.key_provider = KeyProvider::kWidevine;
    +
    335  ++num_key_providers;
    +
    336  }
    +
    337  if (FLAGS_enable_playready_encryption) {
    +
    338  encryption_params.key_provider = KeyProvider::kPlayReady;
    +
    339  ++num_key_providers;
    +
    340  }
    +
    341  if (FLAGS_enable_raw_key_encryption) {
    +
    342  encryption_params.key_provider = KeyProvider::kRawKey;
    +
    343  ++num_key_providers;
    +
    344  }
    +
    345  if (num_key_providers > 1) {
    +
    346  LOG(ERROR) << "Only one of --enable_widevine_encryption, "
    +
    347  "--enable_playready_encryption, "
    +
    348  "--enable_raw_key_encryption can be enabled.";
    +
    349  return base::nullopt;
    +
    350  }
    +
    351 
    +
    352  if (!ParseProtectionSystems(FLAGS_protection_systems,
    +
    353  &encryption_params.protection_systems)) {
    +
    354  return base::nullopt;
    +
    355  }
    +
    356 
    +
    357  if (encryption_params.key_provider != KeyProvider::kNone) {
    +
    358  encryption_params.clear_lead_in_seconds = FLAGS_clear_lead;
    +
    359  if (!GetProtectionScheme(&encryption_params.protection_scheme))
    +
    360  return base::nullopt;
    +
    361  encryption_params.crypt_byte_block = FLAGS_crypt_byte_block;
    +
    362  encryption_params.skip_byte_block = FLAGS_skip_byte_block;
    +
    363 
    +
    364  encryption_params.crypto_period_duration_in_seconds =
    +
    365  FLAGS_crypto_period_duration;
    +
    366  encryption_params.vp9_subsample_encryption = FLAGS_vp9_subsample_encryption;
    +
    367  encryption_params.stream_label_func = std::bind(
    +
    368  &Packager::DefaultStreamLabelFunction, FLAGS_max_sd_pixels,
    +
    369  FLAGS_max_hd_pixels, FLAGS_max_uhd1_pixels, std::placeholders::_1);
    +
    370  encryption_params.playready_extra_header_data =
    +
    371  FLAGS_playready_extra_header_data;
    +
    372  }
    +
    373  switch (encryption_params.key_provider) {
    +
    374  case KeyProvider::kWidevine: {
    +
    375  WidevineEncryptionParams& widevine = encryption_params.widevine;
    +
    376  widevine.key_server_url = FLAGS_key_server_url;
    +
    377 
    +
    378  widevine.content_id = FLAGS_content_id_bytes;
    +
    379  widevine.policy = FLAGS_policy;
    +
    380  widevine.group_id = FLAGS_group_id_bytes;
    +
    381  widevine.enable_entitlement_license = FLAGS_enable_entitlement_license;
    +
    382  if (!GetWidevineSigner(&widevine.signer))
    +
    383  return base::nullopt;
    +
    384  break;
    +
    385  }
    +
    386  case KeyProvider::kPlayReady: {
    +
    387  PlayReadyEncryptionParams& playready = encryption_params.playready;
    +
    388  playready.key_server_url = FLAGS_playready_server_url;
    +
    389  playready.program_identifier = FLAGS_program_identifier;
    +
    390  break;
    +
    391  }
    +
    392  case KeyProvider::kRawKey: {
    +
    393  if (!GetRawKeyParams(&encryption_params.raw_key))
    +
    394  return base::nullopt;
    +
    395  break;
    +
    396  }
    +
    397  case KeyProvider::kNone:
    +
    398  break;
    +
    399  }
    +
    400 
    +
    401  num_key_providers = 0;
    +
    402  DecryptionParams& decryption_params = packaging_params.decryption_params;
    +
    403  if (FLAGS_enable_widevine_decryption) {
    +
    404  decryption_params.key_provider = KeyProvider::kWidevine;
    +
    405  ++num_key_providers;
    +
    406  }
    +
    407  if (FLAGS_enable_raw_key_decryption) {
    +
    408  decryption_params.key_provider = KeyProvider::kRawKey;
    +
    409  ++num_key_providers;
    +
    410  }
    +
    411  if (num_key_providers > 1) {
    +
    412  LOG(ERROR) << "Only one of --enable_widevine_decryption, "
    +
    413  "--enable_raw_key_decryption can be enabled.";
    +
    414  return base::nullopt;
    +
    415  }
    +
    416  switch (decryption_params.key_provider) {
    +
    417  case KeyProvider::kWidevine: {
    +
    418  WidevineDecryptionParams& widevine = decryption_params.widevine;
    +
    419  widevine.key_server_url = FLAGS_key_server_url;
    +
    420  if (!GetWidevineSigner(&widevine.signer))
    +
    421  return base::nullopt;
    +
    422  break;
    +
    423  }
    +
    424  case KeyProvider::kRawKey: {
    +
    425  if (!GetRawKeyParams(&decryption_params.raw_key))
    +
    426  return base::nullopt;
    +
    427  break;
    +
    428  }
    +
    429  case KeyProvider::kPlayReady:
    +
    430  case KeyProvider::kNone:
    +
    431  break;
    +
    432  }
    +
    433 
    +
    434  Mp4OutputParams& mp4_params = packaging_params.mp4_output_params;
    +
    435  mp4_params.generate_sidx_in_media_segments =
    +
    436  FLAGS_generate_sidx_in_media_segments;
    +
    437  mp4_params.include_pssh_in_stream = FLAGS_mp4_include_pssh_in_stream;
    +
    438 
    +
    439  packaging_params.transport_stream_timestamp_offset_ms =
    +
    440  FLAGS_transport_stream_timestamp_offset_ms;
    +
    441 
    +
    442  packaging_params.output_media_info = FLAGS_output_media_info;
    +
    443 
    +
    444  MpdParams& mpd_params = packaging_params.mpd_params;
    +
    445  mpd_params.mpd_output = FLAGS_mpd_output;
    +
    446  mpd_params.base_urls = base::SplitString(
    +
    447  FLAGS_base_urls, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    +
    448  mpd_params.min_buffer_time = FLAGS_min_buffer_time;
    +
    449  mpd_params.minimum_update_period = FLAGS_minimum_update_period;
    +
    450  mpd_params.suggested_presentation_delay = FLAGS_suggested_presentation_delay;
    +
    451  mpd_params.time_shift_buffer_depth = FLAGS_time_shift_buffer_depth;
    +
    452  mpd_params.preserved_segments_outside_live_window =
    +
    453  FLAGS_preserved_segments_outside_live_window;
    +
    454 
    +
    455  if (!FLAGS_utc_timings.empty()) {
    +
    456  base::StringPairs pairs;
    +
    457  if (!base::SplitStringIntoKeyValuePairs(FLAGS_utc_timings, '=', ',',
    +
    458  &pairs)) {
    +
    459  LOG(ERROR) << "Invalid --utc_timings scheme_id_uri/value pairs.";
    +
    460  return base::nullopt;
    +
    461  }
    +
    462  for (const auto& string_pair : pairs) {
    +
    463  mpd_params.utc_timings.push_back({string_pair.first, string_pair.second});
    +
    464  }
    +
    465  }
    +
    466 
    +
    467  mpd_params.default_language = FLAGS_default_language;
    +
    468  mpd_params.default_text_language = FLAGS_default_text_language;
    +
    469  mpd_params.generate_static_live_mpd = FLAGS_generate_static_live_mpd;
    +
    470  mpd_params.generate_dash_if_iop_compliant_mpd =
    +
    471  FLAGS_generate_dash_if_iop_compliant_mpd;
    +
    472  mpd_params.allow_approximate_segment_timeline =
    +
    473  FLAGS_allow_approximate_segment_timeline;
    +
    474  mpd_params.allow_codec_switching = FLAGS_allow_codec_switching;
    +
    475  mpd_params.include_mspr_pro = FLAGS_include_mspr_pro_for_playready;
    +
    476 
    +
    477  HlsParams& hls_params = packaging_params.hls_params;
    +
    478  if (!GetHlsPlaylistType(FLAGS_hls_playlist_type, &hls_params.playlist_type)) {
    +
    479  return base::nullopt;
    +
    480  }
    +
    481  hls_params.master_playlist_output = FLAGS_hls_master_playlist_output;
    +
    482  hls_params.base_url = FLAGS_hls_base_url;
    +
    483  hls_params.key_uri = FLAGS_hls_key_uri;
    +
    484  hls_params.time_shift_buffer_depth = FLAGS_time_shift_buffer_depth;
    +
    485  hls_params.preserved_segments_outside_live_window =
    +
    486  FLAGS_preserved_segments_outside_live_window;
    +
    487  hls_params.default_language = FLAGS_default_language;
    +
    488  hls_params.default_text_language = FLAGS_default_text_language;
    +
    489  hls_params.media_sequence_number = FLAGS_hls_media_sequence_number;
    +
    490 
    +
    491  TestParams& test_params = packaging_params.test_params;
    +
    492  test_params.dump_stream_info = FLAGS_dump_stream_info;
    +
    493  test_params.inject_fake_clock = FLAGS_use_fake_clock_for_muxer;
    +
    494  if (!FLAGS_test_packager_version.empty())
    +
    495  test_params.injected_library_version = FLAGS_test_packager_version;
    +
    496 
    +
    497  return packaging_params;
    +
    498 }
    +
    499 
    +
    500 int PackagerMain(int argc, char** argv) {
    +
    501  // Needed to enable VLOG/DVLOG through --vmodule or --v.
    +
    502  base::CommandLine::Init(argc, argv);
    +
    503 
    +
    504  // Set up logging.
    +
    505  logging::LoggingSettings log_settings;
    +
    506  log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
    +
    507  CHECK(logging::InitLogging(log_settings));
    +
    508 
    +
    509  google::SetVersionString(shaka::Packager::GetLibraryVersion());
    +
    510  google::SetUsageMessage(base::StringPrintf(kUsage, argv[0]));
    +
    511  google::ParseCommandLineFlags(&argc, &argv, true);
    +
    512  if (FLAGS_licenses) {
    +
    513  for (const char* line : kLicenseNotice)
    +
    514  std::cout << line << std::endl;
    +
    515  return kSuccess;
    +
    516  }
    +
    517  if (argc < 2) {
    +
    518  google::ShowUsageWithFlags("Usage");
    +
    519  return kSuccess;
    +
    520  }
    +
    521  if (FLAGS_quiet)
    +
    522  logging::SetMinLogLevel(logging::LOG_WARNING);
    +
    523 
    + + +
    526  return kArgumentValidationFailed;
    +
    527  }
    +
    528 
    +
    529  base::Optional<PackagingParams> packaging_params = GetPackagingParams();
    +
    530  if (!packaging_params)
    +
    531  return kArgumentValidationFailed;
    +
    532 
    +
    533  std::vector<StreamDescriptor> stream_descriptors;
    +
    534  for (int i = 1; i < argc; ++i) {
    +
    535  base::Optional<StreamDescriptor> stream_descriptor =
    +
    536  ParseStreamDescriptor(argv[i]);
    +
    537  if (!stream_descriptor)
    +
    538  return kArgumentValidationFailed;
    +
    539  stream_descriptors.push_back(stream_descriptor.value());
    +
    540  }
    +
    541  Packager packager;
    +
    542  Status status =
    +
    543  packager.Initialize(packaging_params.value(), stream_descriptors);
    +
    544  if (!status.ok()) {
    +
    545  LOG(ERROR) << "Failed to initialize packager: " << status.ToString();
    +
    546  return kArgumentValidationFailed;
    +
    547  }
    +
    548  status = packager.Run();
    +
    549  if (!status.ok()) {
    +
    550  LOG(ERROR) << "Packaging Error: " << status.ToString();
    +
    551  return kPackagingFailed;
    +
    552  }
    +
    553  if (!FLAGS_quiet)
    +
    554  printf("Packaging completed successfully.\n");
    +
    555  return kSuccess;
    +
    556 }
    +
    557 
    +
    558 } // namespace
    +
    559 } // namespace shaka
    +
    560 
    +
    561 #if defined(OS_WIN)
    +
    562 // Windows wmain, which converts wide character arguments to UTF-8.
    +
    563 int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) {
    +
    564  std::unique_ptr<char* [], std::function<void(char**)>> utf8_argv(
    +
    565  new char*[argc], [argc](char** utf8_args) {
    +
    566  // TODO(tinskip): This leaks, but if this code is enabled, it crashes.
    +
    567  // Figure out why. I suspect gflags does something funny with the
    +
    568  // argument array.
    +
    569  // for (int idx = 0; idx < argc; ++idx)
    +
    570  // delete[] utf8_args[idx];
    +
    571  delete[] utf8_args;
    +
    572  });
    +
    573  std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    +
    574  for (int idx = 0; idx < argc; ++idx) {
    +
    575  std::string utf8_arg(converter.to_bytes(argv[idx]));
    +
    576  utf8_arg += '\0';
    +
    577  utf8_argv[idx] = new char[utf8_arg.size()];
    +
    578  memcpy(utf8_argv[idx], &utf8_arg[0], utf8_arg.size());
    +
    579  }
    +
    580  return shaka::PackagerMain(argc, utf8_argv.get());
    +
    581 }
    +
    582 #else
    +
    583 int main(int argc, char** argv) {
    +
    584  return shaka::PackagerMain(argc, argv);
    +
    585 }
    +
    586 #endif // defined(OS_WIN)
    +
    static bool ReadFileToString(const char *file_name, std::string *contents)
    Definition: file.cc:230
    +
    static std::string DefaultStreamLabelFunction(int max_sd_pixels, int max_hd_pixels, int max_uhd1_pixels, const EncryptionParams::EncryptedStreamAttributes &stream_attributes)
    Definition: packager.cc:982
    +
    static std::string GetLibraryVersion()
    Definition: packager.cc:978
    +
    All the methods that are virtual are virtual for mocking.
    + +
    base::Optional< StreamDescriptor > ParseStreamDescriptor(const std::string &descriptor_string)
    +
    ProtectionSystem
    Definition: crypto_params.h:31
    +
    @ kCommon
    The common key system from EME: https://goo.gl/s8RIhr.
    +
    bool ValidateRawKeyCryptoFlags()
    +
    HlsPlaylistType
    Definition: hls_params.h:16
    +
    bool ValidateWidevineCryptoFlags()
    +
    static constexpr uint32_t kProtectionSchemeCenc
    The protection scheme: "cenc", "cens", "cbc1", "cbcs".
    diff --git a/docs/d2/de7/classshaka_1_1media_1_1TextStreamInfo-members.html b/docs/d2/de7/classshaka_1_1media_1_1TextStreamInfo-members.html index 8122026f30..d074ef56ce 100644 --- a/docs/d2/de7/classshaka_1_1media_1_1TextStreamInfo-members.html +++ b/docs/d2/de7/classshaka_1_1media_1_1TextStreamInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::TextStreamInfo, including all inherited members.

    + + - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + + + - + @@ -101,9 +110,7 @@ $(function() {
    AddRegion(const std::string &id, const TextRegion &region) (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    AddSubStream(uint16_t index, TextSubStreamInfo info) (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    Clone() const overrideshaka::media::TextStreamInfovirtual
    codec() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    codec_config() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    codec_string() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    duration() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    encryption_config() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    has_clear_lead() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    height() const (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    is_encrypted() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    IsValidConfig() const overrideshaka::media::TextStreamInfovirtual
    language() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    css_styles() const (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    duration() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    encryption_config() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    has_clear_lead() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    height() const (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    is_encrypted() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    IsValidConfig() const overrideshaka::media::TextStreamInfovirtual
    language() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    regions() const (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    set_codec(Codec codec) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_codec_config(const std::vector< uint8_t > &data) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_codec_string(const std::string &codec_string) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_duration(uint64_t duration) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_encryption_config(const EncryptionConfig &encryption_config) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_has_clear_lead(bool has_clear_lead) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_is_encrypted(bool is_encrypted) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_language(const std::string &language) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    stream_type() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    StreamInfo()=default (defined in shaka::media::StreamInfo)shaka::media::StreamInfo
    StreamInfo(StreamType stream_type, int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const uint8_t *codec_config, size_t codec_config_size, const std::string &language, bool is_encrypted) (defined in shaka::media::StreamInfo)shaka::media::StreamInfo
    set_css_styles(const std::string &styles) (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    set_duration(uint64_t duration) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_encryption_config(const EncryptionConfig &encryption_config) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_has_clear_lead(bool has_clear_lead) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_is_encrypted(bool is_encrypted) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    set_language(const std::string &language) (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    stream_type() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    StreamInfo()=default (defined in shaka::media::StreamInfo)shaka::media::StreamInfo
    StreamInfo(StreamType stream_type, int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const uint8_t *codec_config, size_t codec_config_size, const std::string &language, bool is_encrypted) (defined in shaka::media::StreamInfo)shaka::media::StreamInfo
    sub_streams() const (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    TextStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const std::string &codec_config, uint16_t width, uint16_t height, const std::string &language)shaka::media::TextStreamInfo
    time_scale() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    ToString() constshaka::media::StreamInfovirtual
    ToString() const overrideshaka::media::TextStreamInfovirtual
    track_id() const (defined in shaka::media::StreamInfo)shaka::media::StreamInfoinline
    width() const (defined in shaka::media::TextStreamInfo)shaka::media::TextStreamInfoinline
    ~StreamInfo() (defined in shaka::media::StreamInfo)shaka::media::StreamInfovirtual
    diff --git a/docs/d2/de7/structshaka_1_1media_1_1mp4_1_1Edit-members.html b/docs/d2/de7/structshaka_1_1media_1_1mp4_1_1Edit-members.html index 97d9179dc2..2d932a90cb 100644 --- a/docs/d2/de7/structshaka_1_1media_1_1mp4_1_1Edit-members.html +++ b/docs/d2/de7/structshaka_1_1media_1_1mp4_1_1Edit-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d2/de9/media__handler_8cc_source.html b/docs/d2/de9/media__handler_8cc_source.html index d9c08eb3fd..75d9f12036 100644 --- a/docs/d2/de9/media__handler_8cc_source.html +++ b/docs/d2/de9/media__handler_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/media_handler.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    media_handler.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/media_handler.h"
    8 
    9 #include "packager/status_macros.h"
    10 
    11 namespace shaka {
    12 namespace media {
    13 
    14 std::string StreamDataTypeToString(StreamDataType type) {
    15  switch (type) {
    16  case StreamDataType::kStreamInfo:
    17  return "stream info";
    18  case StreamDataType::kMediaSample:
    19  return "media sample";
    20  case StreamDataType::kTextSample:
    21  return "text sample";
    22  case StreamDataType::kSegmentInfo:
    23  return "segment info";
    24  case StreamDataType::kScte35Event:
    25  return "scte35 event";
    26  case StreamDataType::kCueEvent:
    27  return "cue event";
    28  case StreamDataType::kUnknown:
    29  return "unknown";
    30  }
    31  return "unknown";
    32 }
    33 
    34 Status MediaHandler::SetHandler(size_t output_stream_index,
    35  std::shared_ptr<MediaHandler> handler) {
    36  if (output_handlers_.find(output_stream_index) != output_handlers_.end()) {
    37  return Status(error::ALREADY_EXISTS,
    38  "The handler at the specified index already exists.");
    39  }
    40  output_handlers_[output_stream_index] =
    41  std::make_pair(handler, handler->num_input_streams_++);
    42  next_output_stream_index_ = output_stream_index + 1;
    43  return Status::OK;
    44 }
    45 
    47  if (initialized_)
    48  return Status::OK;
    49  Status status = InitializeInternal();
    50  if (!status.ok())
    51  return status;
    52  for (auto& pair : output_handlers_) {
    53  if (!ValidateOutputStreamIndex(pair.first))
    54  return Status(error::INVALID_ARGUMENT, "Invalid output stream index");
    55  status = pair.second.first->Initialize();
    56  if (!status.ok())
    57  return status;
    58  }
    59  initialized_ = true;
    60  return Status::OK;
    61 }
    62 
    63 Status MediaHandler::Chain(
    64  std::initializer_list<std::shared_ptr<MediaHandler>> list) {
    65  std::shared_ptr<MediaHandler> previous;
    66 
    67  for (auto& next : list) {
    68  // Skip null entries.
    69  if (!next) {
    70  continue;
    71  }
    72 
    73  if (previous) {
    74  RETURN_IF_ERROR(previous->AddHandler(next));
    75  }
    76 
    77  previous = std::move(next);
    78  }
    79 
    80  return Status::OK;
    81 }
    82 
    83 Status MediaHandler::OnFlushRequest(size_t input_stream_index) {
    84  // The default implementation treats the output stream index to be identical
    85  // to the input stream index, which is true for most handlers.
    86  const size_t output_stream_index = input_stream_index;
    87  return FlushDownstream(output_stream_index);
    88 }
    89 
    90 bool MediaHandler::ValidateOutputStreamIndex(size_t stream_index) const {
    91  return stream_index < num_input_streams_;
    92 }
    93 
    94 Status MediaHandler::Dispatch(std::unique_ptr<StreamData> stream_data) const {
    95  size_t output_stream_index = stream_data->stream_index;
    96  auto handler_it = output_handlers_.find(output_stream_index);
    97  if (handler_it == output_handlers_.end()) {
    98  return Status(error::NOT_FOUND,
    99  "No output handler exist at the specified index.");
    100  }
    101  stream_data->stream_index = handler_it->second.second;
    102  return handler_it->second.first->Process(std::move(stream_data));
    103 }
    104 
    105 Status MediaHandler::FlushDownstream(size_t output_stream_index) {
    106  auto handler_it = output_handlers_.find(output_stream_index);
    107  if (handler_it == output_handlers_.end()) {
    108  return Status(error::NOT_FOUND,
    109  "No output handler exist at the specified index.");
    110  }
    111  return handler_it->second.first->OnFlushRequest(handler_it->second.second);
    112 }
    113 
    115  for (const auto& pair : output_handlers_) {
    116  Status status = pair.second.first->OnFlushRequest(pair.second.second);
    117  if (!status.ok()) {
    118  return status;
    119  }
    120  }
    121  return Status::OK;
    122 }
    123 } // namespace media
    124 } // namespace shaka
    virtual bool ValidateOutputStreamIndex(size_t stream_index) const
    Validate if the stream at the specified index actually exists.
    -
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    -
    virtual Status InitializeInternal()=0
    -
    virtual Status OnFlushRequest(size_t input_stream_index)
    Event handler for flush request at the specific input stream index.
    -
    All the methods that are virtual are virtual for mocking.
    - -
    Status FlushAllDownstreams()
    Flush all connected downstream handlers.
    -
    Status FlushDownstream(size_t output_stream_index)
    Flush the downstream connected at the specified output stream index.
    -
    Status SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
    Connect downstream handler at the specified output stream index.
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/media_handler.h"
    +
    8 
    +
    9 #include "packager/status_macros.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 namespace media {
    +
    13 
    +
    14 std::string StreamDataTypeToString(StreamDataType type) {
    +
    15  switch (type) {
    +
    16  case StreamDataType::kStreamInfo:
    +
    17  return "stream info";
    +
    18  case StreamDataType::kMediaSample:
    +
    19  return "media sample";
    +
    20  case StreamDataType::kTextSample:
    +
    21  return "text sample";
    +
    22  case StreamDataType::kSegmentInfo:
    +
    23  return "segment info";
    +
    24  case StreamDataType::kScte35Event:
    +
    25  return "scte35 event";
    +
    26  case StreamDataType::kCueEvent:
    +
    27  return "cue event";
    +
    28  case StreamDataType::kUnknown:
    +
    29  return "unknown";
    +
    30  }
    +
    31  return "unknown";
    +
    32 }
    +
    33 
    +
    34 Status MediaHandler::SetHandler(size_t output_stream_index,
    +
    35  std::shared_ptr<MediaHandler> handler) {
    +
    36  if (output_handlers_.find(output_stream_index) != output_handlers_.end()) {
    +
    37  return Status(error::ALREADY_EXISTS,
    +
    38  "The handler at the specified index already exists.");
    +
    39  }
    +
    40  output_handlers_[output_stream_index] =
    +
    41  std::make_pair(handler, handler->num_input_streams_++);
    +
    42  next_output_stream_index_ = output_stream_index + 1;
    +
    43  return Status::OK;
    +
    44 }
    +
    45 
    + +
    47  if (initialized_)
    +
    48  return Status::OK;
    +
    49  Status status = InitializeInternal();
    +
    50  if (!status.ok())
    +
    51  return status;
    +
    52  for (auto& pair : output_handlers_) {
    +
    53  if (!ValidateOutputStreamIndex(pair.first))
    +
    54  return Status(error::INVALID_ARGUMENT, "Invalid output stream index");
    +
    55  status = pair.second.first->Initialize();
    +
    56  if (!status.ok())
    +
    57  return status;
    +
    58  }
    +
    59  initialized_ = true;
    +
    60  return Status::OK;
    +
    61 }
    +
    62 
    +
    63 Status MediaHandler::Chain(
    +
    64  const std::vector<std::shared_ptr<MediaHandler>>& list) {
    +
    65  std::shared_ptr<MediaHandler> previous;
    +
    66 
    +
    67  for (const auto& next : list) {
    +
    68  // Skip null entries.
    +
    69  if (!next) {
    +
    70  continue;
    +
    71  }
    +
    72 
    +
    73  if (previous) {
    +
    74  RETURN_IF_ERROR(previous->AddHandler(next));
    +
    75  }
    +
    76 
    +
    77  previous = std::move(next);
    +
    78  }
    +
    79 
    +
    80  return Status::OK;
    +
    81 }
    +
    82 
    +
    83 Status MediaHandler::OnFlushRequest(size_t input_stream_index) {
    +
    84  // The default implementation treats the output stream index to be identical
    +
    85  // to the input stream index, which is true for most handlers.
    +
    86  const size_t output_stream_index = input_stream_index;
    +
    87  return FlushDownstream(output_stream_index);
    +
    88 }
    +
    89 
    +
    90 bool MediaHandler::ValidateOutputStreamIndex(size_t stream_index) const {
    +
    91  return stream_index < num_input_streams_;
    +
    92 }
    +
    93 
    +
    94 Status MediaHandler::Dispatch(std::unique_ptr<StreamData> stream_data) const {
    +
    95  size_t output_stream_index = stream_data->stream_index;
    +
    96  auto handler_it = output_handlers_.find(output_stream_index);
    +
    97  if (handler_it == output_handlers_.end()) {
    +
    98  return Status(error::NOT_FOUND,
    +
    99  "No output handler exist at the specified index.");
    +
    100  }
    +
    101  stream_data->stream_index = handler_it->second.second;
    +
    102  return handler_it->second.first->Process(std::move(stream_data));
    +
    103 }
    +
    104 
    +
    105 Status MediaHandler::FlushDownstream(size_t output_stream_index) {
    +
    106  auto handler_it = output_handlers_.find(output_stream_index);
    +
    107  if (handler_it == output_handlers_.end()) {
    +
    108  return Status(error::NOT_FOUND,
    +
    109  "No output handler exist at the specified index.");
    +
    110  }
    +
    111  return handler_it->second.first->OnFlushRequest(handler_it->second.second);
    +
    112 }
    +
    113 
    + +
    115  for (const auto& pair : output_handlers_) {
    +
    116  Status status = pair.second.first->OnFlushRequest(pair.second.second);
    +
    117  if (!status.ok()) {
    +
    118  return status;
    +
    119  }
    +
    120  }
    +
    121  return Status::OK;
    +
    122 }
    +
    123 } // namespace media
    +
    124 } // namespace shaka
    + +
    virtual Status InitializeInternal()=0
    +
    Status SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
    Connect downstream handler at the specified output stream index.
    +
    virtual Status OnFlushRequest(size_t input_stream_index)
    Event handler for flush request at the specific input stream index.
    +
    Status FlushAllDownstreams()
    Flush all connected downstream handlers.
    +
    virtual bool ValidateOutputStreamIndex(size_t stream_index) const
    Validate if the stream at the specified index actually exists.
    +
    Status FlushDownstream(size_t output_stream_index)
    Flush the downstream connected at the specified output stream index.
    + +
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d2/de9/mock__muxer__listener_8h_source.html b/docs/d2/de9/mock__muxer__listener_8h_source.html index 249eb27d38..63a6b03998 100644 --- a/docs/d2/de9/mock__muxer__listener_8h_source.html +++ b/docs/d2/de9/mock__muxer__listener_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/mock_muxer_listener.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mock_muxer_listener.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_EVENT_MOCK_MUXER_LISTENER_H_
    8 #define PACKAGER_MEDIA_EVENT_MOCK_MUXER_LISTENER_H_
    9 
    10 #include <gmock/gmock.h>
    11 
    12 #include "packager/media/base/muxer_options.h"
    13 #include "packager/media/base/protection_system_specific_info.h"
    14 #include "packager/media/base/stream_info.h"
    15 #include "packager/media/event/muxer_listener.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    21  public:
    23  ~MockMuxerListener() override;
    24 
    25  MOCK_METHOD5(
    27  void(bool is_initial_encryption_info,
    28  FourCC protection_scheme,
    29  const std::vector<uint8_t>& key_id,
    30  const std::vector<uint8_t>& iv,
    31  const std::vector<ProtectionSystemSpecificInfo>& key_system_info));
    32 
    33  MOCK_METHOD0(OnEncryptionStart, void());
    34 
    35  MOCK_METHOD4(OnMediaStart,
    36  void(const MuxerOptions& muxer_options,
    37  const StreamInfo& stream_info,
    38  uint32_t time_scale,
    39  ContainerType container_type));
    40 
    41  MOCK_METHOD1(OnSampleDurationReady, void(uint32_t sample_duration));
    42 
    43  MOCK_METHOD9(OnMediaEndMock,
    44  void(bool has_init_range,
    45  uint64_t init_range_start,
    46  uint64_t init_range_end,
    47  bool has_index_range,
    48  uint64_t index_range_start,
    49  uint64_t index_range_end,
    50  bool has_subsegment_ranges,
    51  const std::vector<Range> subsegment_ranges,
    52  float duration_seconds));
    53 
    54  // Windows 32 bit cannot mock MediaRanges because it has Optionals that use
    55  // memory alignment of 8 bytes. The compiler fails if it is mocked.
    56  void OnMediaEnd(const MediaRanges& range,
    57  float duration_seconds) override;
    58 
    59  MOCK_METHOD4(OnNewSegment,
    60  void(const std::string& segment_name,
    61  int64_t start_time,
    62  int64_t duration,
    63  uint64_t segment_file_size));
    64 
    65  MOCK_METHOD3(OnKeyFrame,
    66  void(int64_t timestamp,
    67  uint64_t start_byte_offset,
    68  uint64_t size));
    69 
    70  MOCK_METHOD2(OnCueEvent,
    71  void(int64_t timestamp, const std::string& cue_data));
    72 };
    73 
    74 } // namespace media
    75 } // namespace shaka
    76 
    77 #endif // PACKAGER_MEDIA_EVENT_MOCK_MUXER_LISTENER_H_
    virtual void OnCueEvent(int64_t timestamp, const std::string &cue_data)=0
    -
    virtual void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info)=0
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    virtual void OnSampleDurationReady(uint32_t sample_duration)=0
    - -
    virtual void OnEncryptionStart()=0
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
    -
    virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
    -
    void OnMediaEnd(const MediaRanges &range, float duration_seconds) override
    - -
    virtual void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_EVENT_MOCK_MUXER_LISTENER_H_
    +
    8 #define PACKAGER_MEDIA_EVENT_MOCK_MUXER_LISTENER_H_
    +
    9 
    +
    10 #include <gmock/gmock.h>
    +
    11 
    +
    12 #include "packager/media/base/muxer_options.h"
    +
    13 #include "packager/media/base/protection_system_specific_info.h"
    +
    14 #include "packager/media/base/stream_info.h"
    +
    15 #include "packager/media/event/muxer_listener.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    + +
    21  public:
    + +
    23  ~MockMuxerListener() override;
    +
    24 
    +
    25  MOCK_METHOD5(
    + +
    27  void(bool is_initial_encryption_info,
    +
    28  FourCC protection_scheme,
    +
    29  const std::vector<uint8_t>& key_id,
    +
    30  const std::vector<uint8_t>& iv,
    +
    31  const std::vector<ProtectionSystemSpecificInfo>& key_system_info));
    +
    32 
    +
    33  MOCK_METHOD0(OnEncryptionStart, void());
    +
    34 
    +
    35  MOCK_METHOD4(OnMediaStart,
    +
    36  void(const MuxerOptions& muxer_options,
    +
    37  const StreamInfo& stream_info,
    +
    38  uint32_t time_scale,
    +
    39  ContainerType container_type));
    +
    40 
    +
    41  MOCK_METHOD1(OnSampleDurationReady, void(uint32_t sample_duration));
    +
    42 
    +
    43  MOCK_METHOD9(OnMediaEndMock,
    +
    44  void(bool has_init_range,
    +
    45  uint64_t init_range_start,
    +
    46  uint64_t init_range_end,
    +
    47  bool has_index_range,
    +
    48  uint64_t index_range_start,
    +
    49  uint64_t index_range_end,
    +
    50  bool has_subsegment_ranges,
    +
    51  const std::vector<Range> subsegment_ranges,
    +
    52  float duration_seconds));
    +
    53 
    +
    54  // Windows 32 bit cannot mock MediaRanges because it has Optionals that use
    +
    55  // memory alignment of 8 bytes. The compiler fails if it is mocked.
    +
    56  void OnMediaEnd(const MediaRanges& range,
    +
    57  float duration_seconds) override;
    +
    58 
    +
    59  MOCK_METHOD4(OnNewSegment,
    +
    60  void(const std::string& segment_name,
    +
    61  int64_t start_time,
    +
    62  int64_t duration,
    +
    63  uint64_t segment_file_size));
    +
    64 
    +
    65  MOCK_METHOD3(OnKeyFrame,
    +
    66  void(int64_t timestamp,
    +
    67  uint64_t start_byte_offset,
    +
    68  uint64_t size));
    +
    69 
    +
    70  MOCK_METHOD2(OnCueEvent,
    +
    71  void(int64_t timestamp, const std::string& cue_data));
    +
    72 };
    +
    73 
    +
    74 } // namespace media
    +
    75 } // namespace shaka
    +
    76 
    +
    77 #endif // PACKAGER_MEDIA_EVENT_MOCK_MUXER_LISTENER_H_
    + +
    void OnMediaEnd(const MediaRanges &range, float duration_seconds) override
    + +
    virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
    +
    virtual void OnEncryptionStart()=0
    +
    virtual void OnCueEvent(int64_t timestamp, const std::string &cue_data)=0
    +
    virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
    +
    virtual void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info)=0
    +
    virtual void OnSampleDurationReady(uint32_t sample_duration)=0
    +
    virtual void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    + +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/d2/deb/es__parser_8h_source.html b/docs/d2/deb/es__parser_8h_source.html index 792f778b92..72a0d1c69a 100644 --- a/docs/d2/deb/es__parser_8h_source.html +++ b/docs/d2/deb/es__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    es_parser.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H_
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H_
    7 
    8 #include <stdint.h>
    9 
    10 #include "packager/base/callback.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    15 class MediaSample;
    16 class StreamInfo;
    17 
    18 namespace mp2t {
    19 
    20 class EsParser {
    21  public:
    22  typedef base::Callback<void(const std::shared_ptr<StreamInfo>&)>
    23  NewStreamInfoCB;
    24  typedef base::Callback<void(uint32_t, const std::shared_ptr<MediaSample>&)>
    25  EmitSampleCB;
    26 
    27  EsParser(uint32_t pid) : pid_(pid) {}
    28  virtual ~EsParser() {}
    29 
    30  // ES parsing.
    31  // Should use kNoTimestamp when a timestamp is not valid.
    32  virtual bool Parse(const uint8_t* buf,
    33  int size,
    34  int64_t pts,
    35  int64_t dts) = 0;
    36 
    37  // Flush any pending buffer.
    38  virtual void Flush() = 0;
    39 
    40  // Reset the state of the ES parser.
    41  virtual void Reset() = 0;
    42 
    43  uint32_t pid() { return pid_; }
    44 
    45  private:
    46  uint32_t pid_;
    47 };
    48 
    49 } // namespace mp2t
    50 } // namespace media
    51 } // namespace shaka
    52 
    53 #endif
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 
    +
    10 #include "packager/base/callback.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    15 class MediaSample;
    +
    16 class StreamInfo;
    +
    17 class TextSample;
    +
    18 
    +
    19 namespace mp2t {
    +
    20 
    +
    21 class EsParser {
    +
    22  public:
    +
    23  typedef base::Callback<void(std::shared_ptr<StreamInfo>)> NewStreamInfoCB;
    +
    24  typedef base::Callback<void(std::shared_ptr<MediaSample>)> EmitSampleCB;
    +
    25  typedef base::Callback<void(std::shared_ptr<TextSample>)> EmitTextSampleCB;
    +
    26 
    +
    27  EsParser(uint32_t pid) : pid_(pid) {}
    +
    28  virtual ~EsParser() {}
    +
    29 
    +
    30  // ES parsing.
    +
    31  // Should use kNoTimestamp when a timestamp is not valid.
    +
    32  virtual bool Parse(const uint8_t* buf,
    +
    33  int size,
    +
    34  int64_t pts,
    +
    35  int64_t dts) = 0;
    +
    36 
    +
    37  // Flush any pending buffer.
    +
    38  virtual bool Flush() = 0;
    +
    39 
    +
    40  // Reset the state of the ES parser.
    +
    41  virtual void Reset() = 0;
    +
    42 
    +
    43  uint32_t pid() { return pid_; }
    +
    44 
    +
    45  private:
    +
    46  uint32_t pid_;
    +
    47 };
    +
    48 
    +
    49 } // namespace mp2t
    +
    50 } // namespace media
    +
    51 } // namespace shaka
    +
    52 
    +
    53 #endif
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d2/dee/classshaka_1_1media_1_1mp2t_1_1TsSectionPes-members.html b/docs/d2/dee/classshaka_1_1media_1_1mp2t_1_1TsSectionPes-members.html index e984bb2bb4..34974e52f5 100644 --- a/docs/d2/dee/classshaka_1_1media_1_1mp2t_1_1TsSectionPes-members.html +++ b/docs/d2/dee/classshaka_1_1media_1_1mp2t_1_1TsSectionPes-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d2/dee/pes__packet__generator_8cc_source.html b/docs/d2/dee/pes__packet__generator_8cc_source.html index 8dda238df0..a655a04912 100644 --- a/docs/d2/dee/pes__packet__generator_8cc_source.html +++ b/docs/d2/dee/pes__packet__generator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/pes_packet_generator.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    pes_packet_generator.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp2t/pes_packet_generator.h"
    8 
    9 #include <algorithm>
    10 #include <cstring>
    11 #include <memory>
    12 
    13 #include "packager/media/base/audio_stream_info.h"
    14 #include "packager/media/base/buffer_writer.h"
    15 #include "packager/media/base/media_sample.h"
    16 #include "packager/media/base/video_stream_info.h"
    17 #include "packager/media/codecs/aac_audio_specific_config.h"
    18 #include "packager/media/codecs/nal_unit_to_byte_stream_converter.h"
    19 #include "packager/media/codecs/nalu_reader.h"
    20 #include "packager/media/formats/mp2t/pes_packet.h"
    21 
    22 namespace shaka {
    23 namespace media {
    24 namespace mp2t {
    25 
    26 namespace {
    27 const uint8_t kVideoStreamId = 0xE0;
    28 const uint8_t kAacAudioStreamId = 0xC0;
    29 const uint8_t kAc3AudioStreamId = 0xBD; // AC3 uses private stream 1 id.
    30 const double kTsTimescale = 90000.0;
    31 } // namespace
    32 
    34  uint32_t transport_stream_timestamp_offset)
    35  : transport_stream_timestamp_offset_(transport_stream_timestamp_offset) {}
    36 
    37 PesPacketGenerator::~PesPacketGenerator() {}
    38 
    39 bool PesPacketGenerator::Initialize(const StreamInfo& stream_info) {
    40  pes_packets_.clear();
    41  stream_type_ = stream_info.stream_type();
    42 
    43  if (stream_type_ == kStreamVideo) {
    44  const VideoStreamInfo& video_stream_info =
    45  static_cast<const VideoStreamInfo&>(stream_info);
    46  if (video_stream_info.codec() != Codec::kCodecH264) {
    47  NOTIMPLEMENTED() << "Video codec " << video_stream_info.codec()
    48  << " is not supported.";
    49  return false;
    50  }
    51  timescale_scale_ = kTsTimescale / video_stream_info.time_scale();
    52  converter_.reset(new NalUnitToByteStreamConverter());
    53  return converter_->Initialize(video_stream_info.codec_config().data(),
    54  video_stream_info.codec_config().size());
    55  }
    56  if (stream_type_ == kStreamAudio) {
    57  const AudioStreamInfo& audio_stream_info =
    58  static_cast<const AudioStreamInfo&>(stream_info);
    59  timescale_scale_ = kTsTimescale / audio_stream_info.time_scale();
    60  if (audio_stream_info.codec() == Codec::kCodecAAC) {
    61  audio_stream_id_ = kAacAudioStreamId;
    62  adts_converter_.reset(new AACAudioSpecificConfig());
    63  return adts_converter_->Parse(audio_stream_info.codec_config());
    64  }
    65  if (audio_stream_info.codec() == Codec::kCodecAC3 ||
    66  audio_stream_info.codec() == Codec::kCodecEAC3) {
    67  audio_stream_id_ = kAc3AudioStreamId;
    68  // No converter needed for AC3 and E-AC3.
    69  return true;
    70  }
    71  NOTIMPLEMENTED() << "Audio codec " << audio_stream_info.codec()
    72  << " is not supported yet.";
    73  return false;
    74  }
    75 
    76  NOTIMPLEMENTED() << "Stream type: " << stream_type_ << " not implemented.";
    77  return false;
    78 }
    79 
    81  if (!current_processing_pes_)
    82  current_processing_pes_.reset(new PesPacket());
    83 
    84  const int64_t pts =
    85  sample.pts() * timescale_scale_ + transport_stream_timestamp_offset_;
    86  const int64_t dts =
    87  sample.dts() * timescale_scale_ + transport_stream_timestamp_offset_;
    88 
    89  if (pts < 0 || dts < 0) {
    90  LOG(ERROR) << "Seeing negative timestamp (" << pts << "," << dts << ")"
    91  << " after applying offset "
    92  << transport_stream_timestamp_offset_
    93  << ". Please check if it is expected. Adjust "
    94  "--transport_stream_timestamp_offset_ms if needed.";
    95  return false;
    96  }
    97 
    98  current_processing_pes_->set_is_key_frame(sample.is_key_frame());
    99  current_processing_pes_->set_pts(pts);
    100  current_processing_pes_->set_dts(dts);
    101  if (stream_type_ == kStreamVideo) {
    102  DCHECK(converter_);
    103  std::vector<SubsampleEntry> subsamples;
    104  if (sample.decrypt_config())
    105  subsamples = sample.decrypt_config()->subsamples();
    106  const bool kEscapeEncryptedNalu = true;
    107  std::vector<uint8_t> byte_stream;
    108  if (!converter_->ConvertUnitToByteStreamWithSubsamples(
    109  sample.data(), sample.data_size(), sample.is_key_frame(),
    110  kEscapeEncryptedNalu, &byte_stream, &subsamples)) {
    111  LOG(ERROR) << "Failed to convert sample to byte stream.";
    112  return false;
    113  }
    114 
    115  current_processing_pes_->mutable_data()->swap(byte_stream);
    116  current_processing_pes_->set_stream_id(kVideoStreamId);
    117  pes_packets_.push_back(std::move(current_processing_pes_));
    118  return true;
    119  }
    120  DCHECK_EQ(stream_type_, kStreamAudio);
    121 
    122  std::vector<uint8_t> audio_frame;
    123 
    124  // AAC is carried in ADTS.
    125  if (adts_converter_) {
    126  if (!adts_converter_->ConvertToADTS(sample.data(), sample.data_size(),
    127  &audio_frame))
    128  return false;
    129  } else {
    130  audio_frame.assign(sample.data(), sample.data() + sample.data_size());
    131  }
    132 
    133  // TODO(rkuriowa): Put multiple samples in the PES packet to reduce # of PES
    134  // packets.
    135  current_processing_pes_->mutable_data()->swap(audio_frame);
    136  current_processing_pes_->set_stream_id(audio_stream_id_);
    137  pes_packets_.push_back(std::move(current_processing_pes_));
    138  return true;
    139 }
    140 
    142  return pes_packets_.size();
    143 }
    144 
    145 std::unique_ptr<PesPacket> PesPacketGenerator::GetNextPesPacket() {
    146  DCHECK(!pes_packets_.empty());
    147  std::unique_ptr<PesPacket> pes = std::move(pes_packets_.front());
    148  pes_packets_.pop_front();
    149  return pes;
    150 }
    151 
    153  return true;
    154 }
    155 
    156 } // namespace mp2t
    157 } // namespace media
    158 } // namespace shaka
    Abstract class holds stream information.
    Definition: stream_info.h:62
    - -
    virtual bool PushSample(const MediaSample &sample)
    -
    virtual std::unique_ptr< PesPacket > GetNextPesPacket()
    - -
    All the methods that are virtual are virtual for mocking.
    - -
    virtual bool Initialize(const StreamInfo &stream)
    -
    PesPacketGenerator(uint32_t transport_stream_timestamp_offset)
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    -
    Class that carries PES packet information.
    Definition: pes_packet.h:20
    -
    Holds video stream information.
    -
    Holds audio stream information.
    - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/pes_packet_generator.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 #include <cstring>
    +
    11 #include <memory>
    +
    12 
    +
    13 #include "packager/media/base/audio_stream_info.h"
    +
    14 #include "packager/media/base/buffer_writer.h"
    +
    15 #include "packager/media/base/media_sample.h"
    +
    16 #include "packager/media/base/video_stream_info.h"
    +
    17 #include "packager/media/codecs/aac_audio_specific_config.h"
    +
    18 #include "packager/media/codecs/nal_unit_to_byte_stream_converter.h"
    +
    19 #include "packager/media/codecs/nalu_reader.h"
    +
    20 #include "packager/media/formats/mp2t/pes_packet.h"
    +
    21 
    +
    22 namespace shaka {
    +
    23 namespace media {
    +
    24 namespace mp2t {
    +
    25 
    +
    26 namespace {
    +
    27 const uint8_t kVideoStreamId = 0xE0;
    +
    28 const uint8_t kAacAudioStreamId = 0xC0;
    +
    29 const uint8_t kAc3AudioStreamId = 0xBD; // AC3 uses private stream 1 id.
    +
    30 const double kTsTimescale = 90000.0;
    +
    31 } // namespace
    +
    32 
    + +
    34  uint32_t transport_stream_timestamp_offset)
    +
    35  : transport_stream_timestamp_offset_(transport_stream_timestamp_offset) {}
    +
    36 
    +
    37 PesPacketGenerator::~PesPacketGenerator() {}
    +
    38 
    +
    39 bool PesPacketGenerator::Initialize(const StreamInfo& stream_info) {
    +
    40  pes_packets_.clear();
    +
    41  stream_type_ = stream_info.stream_type();
    +
    42 
    +
    43  if (stream_type_ == kStreamVideo) {
    +
    44  const VideoStreamInfo& video_stream_info =
    +
    45  static_cast<const VideoStreamInfo&>(stream_info);
    +
    46  if (video_stream_info.codec() != Codec::kCodecH264) {
    +
    47  NOTIMPLEMENTED() << "Video codec " << video_stream_info.codec()
    +
    48  << " is not supported.";
    +
    49  return false;
    +
    50  }
    +
    51  timescale_scale_ = kTsTimescale / video_stream_info.time_scale();
    +
    52  converter_.reset(new NalUnitToByteStreamConverter());
    +
    53  return converter_->Initialize(video_stream_info.codec_config().data(),
    +
    54  video_stream_info.codec_config().size());
    +
    55  }
    +
    56  if (stream_type_ == kStreamAudio) {
    +
    57  const AudioStreamInfo& audio_stream_info =
    +
    58  static_cast<const AudioStreamInfo&>(stream_info);
    +
    59  timescale_scale_ = kTsTimescale / audio_stream_info.time_scale();
    +
    60  if (audio_stream_info.codec() == Codec::kCodecAAC) {
    +
    61  audio_stream_id_ = kAacAudioStreamId;
    +
    62  adts_converter_.reset(new AACAudioSpecificConfig());
    +
    63  return adts_converter_->Parse(audio_stream_info.codec_config());
    +
    64  }
    +
    65  if (audio_stream_info.codec() == Codec::kCodecAC3 ||
    +
    66  audio_stream_info.codec() == Codec::kCodecEAC3 ||
    +
    67  audio_stream_info.codec() == Codec::kCodecMP3) {
    +
    68  audio_stream_id_ = kAc3AudioStreamId;
    +
    69  // No converter needed for AC3, E-AC3 and MP3.
    +
    70  return true;
    +
    71  }
    +
    72  NOTIMPLEMENTED() << "Audio codec " << audio_stream_info.codec()
    +
    73  << " is not supported yet.";
    +
    74  return false;
    +
    75  }
    +
    76 
    +
    77  NOTIMPLEMENTED() << "Stream type: " << stream_type_ << " not implemented.";
    +
    78  return false;
    +
    79 }
    +
    80 
    + +
    82  if (!current_processing_pes_)
    +
    83  current_processing_pes_.reset(new PesPacket());
    +
    84 
    +
    85  const int64_t pts =
    +
    86  sample.pts() * timescale_scale_ + transport_stream_timestamp_offset_;
    +
    87  const int64_t dts =
    +
    88  sample.dts() * timescale_scale_ + transport_stream_timestamp_offset_;
    +
    89 
    +
    90  if (pts < 0 || dts < 0) {
    +
    91  LOG(ERROR) << "Seeing negative timestamp (" << pts << "," << dts << ")"
    +
    92  << " after applying offset "
    +
    93  << transport_stream_timestamp_offset_
    +
    94  << ". Please check if it is expected. Adjust "
    +
    95  "--transport_stream_timestamp_offset_ms if needed.";
    +
    96  return false;
    +
    97  }
    +
    98 
    +
    99  current_processing_pes_->set_is_key_frame(sample.is_key_frame());
    +
    100  current_processing_pes_->set_pts(pts);
    +
    101  current_processing_pes_->set_dts(dts);
    +
    102  if (stream_type_ == kStreamVideo) {
    +
    103  DCHECK(converter_);
    +
    104  std::vector<SubsampleEntry> subsamples;
    +
    105  if (sample.decrypt_config())
    +
    106  subsamples = sample.decrypt_config()->subsamples();
    +
    107  const bool kEscapeEncryptedNalu = true;
    +
    108  std::vector<uint8_t> byte_stream;
    +
    109  if (!converter_->ConvertUnitToByteStreamWithSubsamples(
    +
    110  sample.data(), sample.data_size(), sample.is_key_frame(),
    +
    111  kEscapeEncryptedNalu, &byte_stream, &subsamples)) {
    +
    112  LOG(ERROR) << "Failed to convert sample to byte stream.";
    +
    113  return false;
    +
    114  }
    +
    115 
    +
    116  current_processing_pes_->mutable_data()->swap(byte_stream);
    +
    117  current_processing_pes_->set_stream_id(kVideoStreamId);
    +
    118  pes_packets_.push_back(std::move(current_processing_pes_));
    +
    119  return true;
    +
    120  }
    +
    121  DCHECK_EQ(stream_type_, kStreamAudio);
    +
    122 
    +
    123  std::vector<uint8_t> audio_frame;
    +
    124 
    +
    125  // AAC is carried in ADTS.
    +
    126  if (adts_converter_) {
    +
    127  if (!adts_converter_->ConvertToADTS(sample.data(), sample.data_size(),
    +
    128  &audio_frame))
    +
    129  return false;
    +
    130  } else {
    +
    131  audio_frame.assign(sample.data(), sample.data() + sample.data_size());
    +
    132  }
    +
    133 
    +
    134  // TODO(rkuriowa): Put multiple samples in the PES packet to reduce # of PES
    +
    135  // packets.
    +
    136  current_processing_pes_->mutable_data()->swap(audio_frame);
    +
    137  current_processing_pes_->set_stream_id(audio_stream_id_);
    +
    138  pes_packets_.push_back(std::move(current_processing_pes_));
    +
    139  return true;
    +
    140 }
    +
    141 
    + +
    143  return pes_packets_.size();
    +
    144 }
    +
    145 
    +
    146 std::unique_ptr<PesPacket> PesPacketGenerator::GetNextPesPacket() {
    +
    147  DCHECK(!pes_packets_.empty());
    +
    148  std::unique_ptr<PesPacket> pes = std::move(pes_packets_.front());
    +
    149  pes_packets_.pop_front();
    +
    150  return pes;
    +
    151 }
    +
    152 
    + +
    154  return true;
    +
    155 }
    +
    156 
    +
    157 } // namespace mp2t
    +
    158 } // namespace media
    +
    159 } // namespace shaka
    + +
    Holds audio stream information.
    +
    Class to hold a media sample.
    Definition: media_sample.h:22
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    Holds video stream information.
    + + +
    virtual bool PushSample(const MediaSample &sample)
    +
    PesPacketGenerator(uint32_t transport_stream_timestamp_offset)
    +
    virtual bool Initialize(const StreamInfo &stream)
    +
    virtual std::unique_ptr< PesPacket > GetNextPesPacket()
    +
    Class that carries PES packet information.
    Definition: pes_packet.h:20
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d2/def/webvtt__muxer_8cc_source.html b/docs/d2/def/webvtt__muxer_8cc_source.html new file mode 100644 index 0000000000..ab40e9a7bc --- /dev/null +++ b/docs/d2/def/webvtt__muxer_8cc_source.html @@ -0,0 +1,145 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/webvtt/webvtt_muxer.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    webvtt_muxer.cc
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webvtt/webvtt_muxer.h"
    +
    8 
    +
    9 #include "packager/file/file.h"
    +
    10 #include "packager/file/file_closer.h"
    +
    11 #include "packager/media/formats/webvtt/webvtt_utils.h"
    +
    12 #include "packager/status_macros.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 namespace webvtt {
    +
    17 
    +
    18 WebVttMuxer::WebVttMuxer(const MuxerOptions& options) : TextMuxer(options) {}
    +
    19 WebVttMuxer::~WebVttMuxer() {}
    +
    20 
    +
    21 Status WebVttMuxer::InitializeStream(TextStreamInfo* stream) {
    +
    22  stream->set_codec(kCodecWebVtt);
    +
    23  stream->set_codec_string("wvtt");
    +
    24 
    +
    25  const std::string preamble = WebVttGetPreamble(*stream);
    +
    26  buffer_.reset(new WebVttFileBuffer(
    +
    27  options().transport_stream_timestamp_offset_ms, preamble));
    +
    28  return Status::OK;
    +
    29 }
    +
    30 
    +
    31 Status WebVttMuxer::AddTextSampleInternal(const TextSample& sample) {
    +
    32  if (sample.id().find('\n') != std::string::npos) {
    +
    33  return Status(error::MUXER_FAILURE, "Text id cannot contain newlines");
    +
    34  }
    +
    35 
    +
    36  buffer_->Append(sample);
    +
    37  return Status::OK;
    +
    38 }
    +
    39 
    +
    40 Status WebVttMuxer::WriteToFile(const std::string& filename, uint64_t* size) {
    +
    41  // Write everything to the file before telling the manifest so that the
    +
    42  // file will exist on disk.
    +
    43  std::unique_ptr<File, FileCloser> file(File::Open(filename.c_str(), "w"));
    +
    44  if (!file) {
    +
    45  return Status(error::FILE_FAILURE, "Failed to open " + filename);
    +
    46  }
    +
    47 
    +
    48  buffer_->WriteTo(file.get(), size);
    +
    49  buffer_->Reset();
    +
    50  if (!file.release()->Close()) {
    +
    51  return Status(error::FILE_FAILURE, "Failed to close " + filename);
    +
    52  }
    +
    53 
    +
    54  return Status::OK;
    +
    55 }
    +
    56 
    +
    57 } // namespace webvtt
    +
    58 } // namespace media
    +
    59 } // namespace shaka
    +
    virtual bool Open()=0
    Internal open. Should not be used directly.
    + + + + +
    WebVttMuxer(const MuxerOptions &options)
    Create a WebMMuxer object from MuxerOptions.
    Definition: webvtt_muxer.cc:18
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    + + + + diff --git a/docs/d2/df7/structshaka_1_1media_1_1mp4_1_1AC4Specific-members.html b/docs/d2/df7/structshaka_1_1media_1_1mp4_1_1AC4Specific-members.html new file mode 100644 index 0000000000..ee05393409 --- /dev/null +++ b/docs/d2/df7/structshaka_1_1media_1_1mp4_1_1AC4Specific-members.html @@ -0,0 +1,94 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::mp4::AC4Specific Member List
    +
    +
    + +

    This is the complete list of members for shaka::media::mp4::AC4Specific, including all inherited members.

    + + + + + + + + + + + + + + +
    AC4Specific() (defined in shaka::media::mp4::AC4Specific)shaka::media::mp4::AC4Specific
    Box() (defined in shaka::media::mp4::Box)shaka::media::mp4::Box
    box_size()shaka::media::mp4::Boxinline
    BoxType() const overrideshaka::media::mp4::AC4Specificvirtual
    ComputeSize()shaka::media::mp4::Box
    data (defined in shaka::media::mp4::AC4Specific)shaka::media::mp4::AC4Specific
    HeaderSize() constshaka::media::mp4::Boxvirtual
    Parse(BoxReader *reader)shaka::media::mp4::Box
    ReadWriteHeaderInternal(BoxBuffer *buffer)shaka::media::mp4::Boxprotectedvirtual
    Write(BufferWriter *writer)shaka::media::mp4::Box
    WriteHeader(BufferWriter *writer)shaka::media::mp4::Box
    ~ AC4Specific() override (defined in shaka::media::mp4::AC4Specific)shaka::media::mp4::AC4Specific
    ~Box() (defined in shaka::media::mp4::Box)shaka::media::mp4::Boxvirtual
    + + + + diff --git a/docs/d2/df8/classshaka_1_1media_1_1SegmentTestBase_1_1ClusterParser.html b/docs/d2/df8/classshaka_1_1media_1_1SegmentTestBase_1_1ClusterParser.html index 66d11130e1..c714c46800 100644 --- a/docs/d2/df8/classshaka_1_1media_1_1SegmentTestBase_1_1ClusterParser.html +++ b/docs/d2/df8/classshaka_1_1media_1_1SegmentTestBase_1_1ClusterParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SegmentTestBase::ClusterParser Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::WebMParserClient - -
    + + @@ -107,9 +110,7 @@ size_t 

    Public Member Functions

    cluster_count ( diff --git a/docs/d2/dfc/classshaka_1_1media_1_1MkvWriter-members.html b/docs/d2/dfc/classshaka_1_1media_1_1MkvWriter-members.html index 701f060ce1..acff56f58b 100644 --- a/docs/d2/dfc/classshaka_1_1media_1_1MkvWriter-members.html +++ b/docs/d2/dfc/classshaka_1_1media_1_1MkvWriter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d2/dfd/adts__header_8h_source.html b/docs/d2/dfd/adts__header_8h_source.html index 9be0711860..56b8a3fb27 100644 --- a/docs/d2/dfd/adts__header_8h_source.html +++ b/docs/d2/dfd/adts__header_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/adts_header.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    adts_header.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ADTS_HEADER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_ADTS_HEADER_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <vector>
    13 
    14 #include "packager/media/formats/mp2t/audio_header.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 namespace mp2t {
    19 
    22 class AdtsHeader : public AudioHeader {
    23  public:
    24  AdtsHeader() = default;
    25  ~AdtsHeader() override = default;
    26 
    29  bool IsSyncWord(const uint8_t* buf) const override;
    30  size_t GetMinFrameSize() const override;
    31  size_t GetSamplesPerFrame() const override;
    32  bool Parse(const uint8_t* adts_frame, size_t adts_frame_size) override;
    33  size_t GetHeaderSize() const override;
    34  size_t GetFrameSize() const override;
    35  size_t GetFrameSizeWithoutParsing(const uint8_t* data,
    36  size_t num_bytes) const override;
    37  void GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const override;
    38  uint8_t GetObjectType() const override;
    39  uint32_t GetSamplingFrequency() const override;
    40  uint8_t GetNumChannels() const override;
    42 
    43  private:
    44  AdtsHeader(const AdtsHeader&) = delete;
    45  AdtsHeader& operator=(const AdtsHeader&) = delete;
    46 
    47  uint8_t protection_absent_ = 0;
    48  uint16_t frame_size_ = 0;
    49  uint8_t profile_ = 0;
    50  uint8_t sampling_frequency_index_ = 0;
    51  uint8_t channel_configuration_ = 0;
    52 };
    53 
    54 } // namespace mp2t
    55 } // namespace media
    56 } // namespace shaka
    57 
    58 #endif // PACKAGER_MEDIA_FORMATS_MP2T_ADTS_HEADER_H_
    size_t GetHeaderSize() const override
    Definition: adts_header.cc:82
    -
    uint8_t GetObjectType() const override
    Definition: adts_header.cc:108
    -
    All the methods that are virtual are virtual for mocking.
    -
    size_t GetSamplesPerFrame() const override
    Definition: adts_header.cc:41
    -
    size_t GetMinFrameSize() const override
    Definition: adts_header.cc:37
    -
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: adts_header.cc:33
    -
    uint8_t GetNumChannels() const override
    Definition: adts_header.cc:117
    -
    uint32_t GetSamplingFrequency() const override
    Definition: adts_header.cc:112
    -
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: adts_header.cc:98
    -
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    Definition: adts_header.cc:91
    - -
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: adts_header.cc:46
    - -
    size_t GetFrameSize() const override
    Definition: adts_header.cc:87
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ADTS_HEADER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_ADTS_HEADER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/media/formats/mp2t/audio_header.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 namespace mp2t {
    +
    19 
    +
    22 class AdtsHeader : public AudioHeader {
    +
    23  public:
    +
    24  AdtsHeader() = default;
    +
    25  ~AdtsHeader() override = default;
    +
    26 
    +
    29  bool IsSyncWord(const uint8_t* buf) const override;
    +
    30  size_t GetMinFrameSize() const override;
    +
    31  size_t GetSamplesPerFrame() const override;
    +
    32  bool Parse(const uint8_t* adts_frame, size_t adts_frame_size) override;
    +
    33  size_t GetHeaderSize() const override;
    +
    34  size_t GetFrameSize() const override;
    +
    35  size_t GetFrameSizeWithoutParsing(const uint8_t* data,
    +
    36  size_t num_bytes) const override;
    +
    37  void GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const override;
    +
    38  uint8_t GetObjectType() const override;
    +
    39  uint32_t GetSamplingFrequency() const override;
    +
    40  uint8_t GetNumChannels() const override;
    +
    42 
    +
    43  private:
    +
    44  AdtsHeader(const AdtsHeader&) = delete;
    +
    45  AdtsHeader& operator=(const AdtsHeader&) = delete;
    +
    46 
    +
    47  uint8_t protection_absent_ = 0;
    +
    48  uint16_t frame_size_ = 0;
    +
    49  uint8_t profile_ = 0;
    +
    50  uint8_t sampling_frequency_index_ = 0;
    +
    51  uint8_t channel_configuration_ = 0;
    +
    52 };
    +
    53 
    +
    54 } // namespace mp2t
    +
    55 } // namespace media
    +
    56 } // namespace shaka
    +
    57 
    +
    58 #endif // PACKAGER_MEDIA_FORMATS_MP2T_ADTS_HEADER_H_
    + +
    size_t GetSamplesPerFrame() const override
    Definition: adts_header.cc:41
    +
    uint8_t GetNumChannels() const override
    Definition: adts_header.cc:117
    +
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: adts_header.cc:98
    +
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    Definition: adts_header.cc:91
    +
    size_t GetHeaderSize() const override
    Definition: adts_header.cc:82
    +
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: adts_header.cc:33
    +
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: adts_header.cc:46
    +
    size_t GetMinFrameSize() const override
    Definition: adts_header.cc:37
    +
    uint8_t GetObjectType() const override
    Definition: adts_header.cc:108
    +
    size_t GetFrameSize() const override
    Definition: adts_header.cc:87
    +
    uint32_t GetSamplingFrequency() const override
    Definition: adts_header.cc:112
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/d03/structshaka_1_1media_1_1OnNewSegmentParameters-members.html b/docs/d3/d03/structshaka_1_1media_1_1OnNewSegmentParameters-members.html index c987142302..8b577dad38 100644 --- a/docs/d3/d03/structshaka_1_1media_1_1OnNewSegmentParameters-members.html +++ b/docs/d3/d03/structshaka_1_1media_1_1OnNewSegmentParameters-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d3/d07/classshaka_1_1media_1_1mp4_1_1BoxReader-members.html b/docs/d3/d07/classshaka_1_1media_1_1mp4_1_1BoxReader-members.html index 99409724f4..8a785c6ea3 100644 --- a/docs/d3/d07/classshaka_1_1media_1_1mp4_1_1BoxReader-members.html +++ b/docs/d3/d07/classshaka_1_1media_1_1mp4_1_1BoxReader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)shaka::media::mp4::BoxReaderstatic ReadChild(Box *child) WARN_UNUSED_RESULTshaka::media::mp4::BoxReader ReadChildren(std::vector< T > *children) WARN_UNUSED_RESULTshaka::media::mp4::BoxReader - ReadFourCC(FourCC *fourcc) (defined in shaka::media::mp4::BoxReader)shaka::media::mp4::BoxReaderinline - ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULTshaka::media::BufferReader - ReadNBytesInto8s(int64_t *v, size_t num_bytes) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader - ReadToString(std::string *str, size_t size) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader - ReadToVector(std::vector< uint8_t > *t, size_t count) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader - ScanChildren() WARN_UNUSED_RESULTshaka::media::mp4::BoxReader - set_size(size_t size) (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline - size() const (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline - SkipBytes(size_t num_bytes) WARN_UNUSED_RESULTshaka::media::BufferReader - StartBox(const uint8_t *buf, const size_t buf_size, FourCC *type, uint64_t *box_size, bool *err) WARN_UNUSED_RESULTshaka::media::mp4::BoxReaderstatic - TryReadChild(Box *child) WARN_UNUSED_RESULTshaka::media::mp4::BoxReader - TryReadChildren(std::vector< T > *children) WARN_UNUSED_RESULTshaka::media::mp4::BoxReader - type() const (defined in shaka::media::mp4::BoxReader)shaka::media::mp4::BoxReaderinline - ~BoxReader() (defined in shaka::media::mp4::BoxReader)shaka::media::mp4::BoxReader - ~BufferReader() (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline + ReadCString(std::string *str) WARN_UNUSED_RESULTshaka::media::BufferReader + ReadFourCC(FourCC *fourcc) (defined in shaka::media::mp4::BoxReader)shaka::media::mp4::BoxReaderinline + ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULTshaka::media::BufferReader + ReadNBytesInto8s(int64_t *v, size_t num_bytes) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader + ReadToString(std::string *str, size_t size) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader + ReadToVector(std::vector< uint8_t > *t, size_t count) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader + ScanChildren() WARN_UNUSED_RESULTshaka::media::mp4::BoxReader + set_size(size_t size) (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline + size() const (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline + SkipBytes(size_t num_bytes) WARN_UNUSED_RESULTshaka::media::BufferReader + StartBox(const uint8_t *buf, const size_t buf_size, FourCC *type, uint64_t *box_size, bool *err) WARN_UNUSED_RESULTshaka::media::mp4::BoxReaderstatic + TryReadChild(Box *child) WARN_UNUSED_RESULTshaka::media::mp4::BoxReader + TryReadChildren(std::vector< T > *children) WARN_UNUSED_RESULTshaka::media::mp4::BoxReader + type() const (defined in shaka::media::mp4::BoxReader)shaka::media::mp4::BoxReaderinline + ~BoxReader() (defined in shaka::media::mp4::BoxReader)shaka::media::mp4::BoxReader + ~BufferReader() (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline
    diff --git a/docs/d3/d07/mpd__params_8h_source.html b/docs/d3/d07/mpd__params_8h_source.html index 554387fe7a..da577956a7 100644 --- a/docs/d3/d07/mpd__params_8h_source.html +++ b/docs/d3/d07/mpd__params_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/public/mpd_params.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    mpd_params.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MPD_PUBLIC_MPD_PARAMS_H_
    8 #define PACKAGER_MPD_PUBLIC_MPD_PARAMS_H_
    9 
    10 #include <string>
    11 #include <vector>
    12 
    13 namespace shaka {
    14 
    16 struct MpdParams {
    18  std::string mpd_output;
    21  std::vector<std::string> base_urls;
    27  double min_buffer_time = 2.0;
    35  static constexpr double kSuggestedPresentationDelayNotSet = 0;
    36  double suggested_presentation_delay = kSuggestedPresentationDelayNotSet;
    48  struct UtcTiming {
    49  std::string scheme_id_uri;
    50  std::string value;
    51  };
    52  std::vector<UtcTiming> utc_timings;
    58  std::string default_language;
    61  std::string default_text_language;
    83 };
    84 
    85 } // namespace shaka
    86 
    87 #endif // PACKAGER_MPD_PUBLIC_MPD_PARAMS_H_
    DASH MPD related parameters.
    Definition: mpd_params.h:16
    -
    double min_buffer_time
    Definition: mpd_params.h:27
    -
    UTCTimings. For dynamic MPD only.
    Definition: mpd_params.h:48
    -
    std::string default_language
    Definition: mpd_params.h:58
    -
    size_t preserved_segments_outside_live_window
    Definition: mpd_params.h:46
    -
    bool generate_dash_if_iop_compliant_mpd
    Try to generate DASH-IF IOP compliant MPD.
    Definition: mpd_params.h:66
    -
    bool generate_static_live_mpd
    Definition: mpd_params.h:64
    -
    All the methods that are virtual are virtual for mocking.
    -
    static constexpr double kSuggestedPresentationDelayNotSet
    Definition: mpd_params.h:35
    -
    std::string mpd_output
    MPD output file path.
    Definition: mpd_params.h:18
    -
    std::vector< std::string > base_urls
    Definition: mpd_params.h:21
    -
    double target_segment_duration
    Definition: mpd_params.h:82
    -
    double minimum_update_period
    Definition: mpd_params.h:30
    -
    double time_shift_buffer_depth
    Definition: mpd_params.h:39
    -
    bool allow_approximate_segment_timeline
    Definition: mpd_params.h:76
    -
    std::string default_text_language
    Definition: mpd_params.h:61
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MPD_PUBLIC_MPD_PARAMS_H_
    +
    8 #define PACKAGER_MPD_PUBLIC_MPD_PARAMS_H_
    +
    9 
    +
    10 #include <string>
    +
    11 #include <vector>
    +
    12 
    +
    13 namespace shaka {
    +
    14 
    +
    16 struct MpdParams {
    +
    18  std::string mpd_output;
    +
    21  std::vector<std::string> base_urls;
    +
    27  double min_buffer_time = 2.0;
    + +
    35  static constexpr double kSuggestedPresentationDelayNotSet = 0;
    +
    36  double suggested_presentation_delay = kSuggestedPresentationDelayNotSet;
    + + +
    48  struct UtcTiming {
    +
    49  std::string scheme_id_uri;
    +
    50  std::string value;
    +
    51  };
    +
    52  std::vector<UtcTiming> utc_timings;
    +
    58  std::string default_language;
    +
    61  std::string default_text_language;
    + + + + +
    85  bool allow_codec_switching = false;
    +
    89  bool include_mspr_pro = true;
    +
    90 };
    +
    91 
    +
    92 } // namespace shaka
    +
    93 
    +
    94 #endif // PACKAGER_MPD_PUBLIC_MPD_PARAMS_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    UTCTimings. For dynamic MPD only.
    Definition: mpd_params.h:48
    +
    DASH MPD related parameters.
    Definition: mpd_params.h:16
    +
    bool include_mspr_pro
    Definition: mpd_params.h:89
    +
    static constexpr double kSuggestedPresentationDelayNotSet
    Definition: mpd_params.h:35
    +
    double minimum_update_period
    Definition: mpd_params.h:30
    +
    bool allow_codec_switching
    Definition: mpd_params.h:85
    +
    std::string default_language
    Definition: mpd_params.h:58
    +
    size_t preserved_segments_outside_live_window
    Definition: mpd_params.h:46
    +
    double target_segment_duration
    Definition: mpd_params.h:82
    +
    double time_shift_buffer_depth
    Definition: mpd_params.h:39
    +
    std::vector< std::string > base_urls
    Definition: mpd_params.h:21
    +
    bool generate_dash_if_iop_compliant_mpd
    Try to generate DASH-IF IOP compliant MPD.
    Definition: mpd_params.h:66
    +
    std::string mpd_output
    MPD output file path.
    Definition: mpd_params.h:18
    +
    bool generate_static_live_mpd
    Definition: mpd_params.h:64
    +
    std::string default_text_language
    Definition: mpd_params.h:61
    +
    double min_buffer_time
    Definition: mpd_params.h:27
    +
    bool allow_approximate_segment_timeline
    Definition: mpd_params.h:76
    diff --git a/docs/d3/d09/classshaka_1_1media_1_1mp4_1_1SyncSampleIterator-members.html b/docs/d3/d09/classshaka_1_1media_1_1mp4_1_1SyncSampleIterator-members.html index c75b5ec04b..894fd748eb 100644 --- a/docs/d3/d09/classshaka_1_1media_1_1mp4_1_1SyncSampleIterator-members.html +++ b/docs/d3/d09/classshaka_1_1media_1_1mp4_1_1SyncSampleIterator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d3/d0a/classshaka_1_1media_1_1MediaParser.html b/docs/d3/d0a/classshaka_1_1media_1_1MediaParser.html index 38df8b9389..7db849f1bb 100644 --- a/docs/d3/d0a/classshaka_1_1media_1_1MediaParser.html +++ b/docs/d3/d0a/classshaka_1_1media_1_1MediaParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MediaParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::media::mp2t::Mp2tMediaParser -shaka::media::mp4::MP4MediaParser -shaka::media::WebMMediaParser -shaka::media::wvm::WvmMediaParser - -
    +shaka::media::WebMMediaParser +shaka::media::WebVttParser +shaka::media::mp2t::Mp2tMediaParser +shaka::media::mp4::MP4MediaParser +shaka::media::wvm::WvmMediaParser + + - - + + + +

    Public Types

    typedef base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
     
    typedef base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
     
    typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
     
    typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
     
    - - + + @@ -101,7 +107,7 @@ Public Member Functions

    Public Member Functions

    virtual void Init (const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source)=0
     
    virtual void Init (const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source)=0
     
    virtual bool Flush () WARN_UNUSED_RESULT=0
     
    virtual bool Parse (const uint8_t *buf, int size) WARN_UNUSED_RESULT=0

    Detailed Description

    -

    Definition at line 24 of file media_parser.h.

    +

    Definition at line 25 of file media_parser.h.

    Member Typedef Documentation

    ◆ InitCB

    @@ -121,18 +127,18 @@ Public Member Functions -

    Definition at line 34 of file media_parser.h.

    +

    Definition at line 35 of file media_parser.h.

    - -

    ◆ NewSampleCB

    + +

    ◆ NewMediaSampleCB

    - +
    typedef base::Callback<bool(uint32_t track_id, const std::shared_ptr<MediaSample>& media_sample)> shaka::media::MediaParser::NewSampleCBtypedef base::Callback<bool(uint32_t track_id, std::shared_ptr<MediaSample> media_sample)> shaka::media::MediaParser::NewMediaSampleCB
    @@ -145,7 +151,31 @@ Public Member Functions
    Returns
    true if the sample is accepted, false if something was wrong with the sample and a parsing error should be signaled.
    -

    Definition at line 43 of file media_parser.h.

    +

    Definition at line 44 of file media_parser.h.

    + +
    +
    + +

    ◆ NewTextSampleCB

    + +
    +
    + + + + +
    typedef base::Callback<bool(uint32_t track_id, std::shared_ptr<TextSample> text_sample)> shaka::media::MediaParser::NewTextSampleCB
    +
    +

    Called when a new text sample has been parsed.

    Parameters
    + + + +
    track_idis the track id of the new sample.
    text_sampleis the new text sample.
    +
    +
    +
    Returns
    true if the sample is accepted, false if something was wrong with the sample and a parsing error should be signaled.
    + +

    Definition at line 53 of file media_parser.h.

    @@ -174,12 +204,12 @@ Public Member Functions

    Flush data currently in the parser and put the parser in a state where it can receive data for a new seek point.

    Returns
    true if successful, false otherwise.
    -

    Implemented in shaka::media::wvm::WvmMediaParser, shaka::media::mp4::MP4MediaParser, shaka::media::mp2t::Mp2tMediaParser, and shaka::media::WebMMediaParser.

    +

    Implemented in shaka::media::wvm::WvmMediaParser, shaka::media::WebMMediaParser, shaka::media::mp4::MP4MediaParser, shaka::media::mp2t::Mp2tMediaParser, and shaka::media::WebVttParser.

    - -

    ◆ Init()

    + +

    ◆ Init()

    @@ -196,8 +226,14 @@ Public Member Functions - const NewSampleCB &  - new_sample_cb, + const NewMediaSampleCB &  + new_media_sample_cb, + + + + + const NewTextSampleCB &  + new_text_sample_cb, @@ -220,12 +256,14 @@ Public Member Functions

    Initialize the parser with necessary callbacks. Must be called before any data is passed to Parse().

    Parameters
    - + + +
    init_cbwill be called once enough data has been parsed to determine the initial stream configurations.
    new_sample_cbwill be called each time a new media sample is available from the parser. May be NULL, and caller retains ownership.
    new_media_sample_cbwill be called each time a new media sample is available from the parser.
    new_text_sample_cbwill be called each time a new text sample is available from the parser.
    decryption_key_sourcethe key source to decrypt the frames. May be NULL, and caller retains ownership.
    -

    Implemented in shaka::media::wvm::WvmMediaParser, shaka::media::mp4::MP4MediaParser, shaka::media::mp2t::Mp2tMediaParser, and shaka::media::WebMMediaParser.

    +

    Implemented in shaka::media::wvm::WvmMediaParser, shaka::media::WebVttParser, shaka::media::WebMMediaParser, shaka::media::mp4::MP4MediaParser, and shaka::media::mp2t::Mp2tMediaParser.

    @@ -264,7 +302,7 @@ Public Member Functions @@ -274,9 +312,7 @@ Public Member Functions diff --git a/docs/d3/d0a/classshaka_1_1media_1_1MediaParser.png b/docs/d3/d0a/classshaka_1_1media_1_1MediaParser.png index babf7146149f1a8f60bff8cbb19f8b7ae2d42cd7..7b30527294c4c3f605d70cf3df782ffeaee075d7 100644 GIT binary patch literal 1981 zcma)7c~Fzr77s!Q294GMWJ$m`1f_t+qK}w>V)`HwSsD}tv;iD90+uy^tg%Va$E#q8 z0S1I51z8>-q6k6Ah7^2&KqwD`gg`BuNWxNqu$p&+?ewqCygT#Vd+wQgf9IUvIp=;E zWS>(z;pT7%1hSLl;dTZB(PILcY@iEf;bC`wu$Yp){Mo zW(-?_tpV+f&shjKq#XmDevS|b%!}kk@Vlv_Qq07Z;CH*f#XPVRYpl6HVf9Qn$6#m8 zybn~fza?HPFD(_5C5KbM*s;Tid{Rez_lZ9hX8^bT1$zd;*alXQP6E(FktD5_cgy;7 z7(oYW6otlA|9o{CYqjBU(SM}Js{H{bC1q2hd5F}58qHhaB!mE@e{(gu?wB)Ix$lRV z-9}_dHc6eo+%c7|qQ>%t+j_TL*&qf5bn++Y1Ff4K%dJdO#Fv5W zIOH>jjg>X(ZLT;eQNPz#>+%Ls^gLHyN?&Ll_$<@G97gdpZ>{d)?Cq(~o9da$`$}be z^Yo{{e^Z=ma%?+iop2se@REa}p`Q8PtfHj0y+^o|e+qB)wO#6b>kFq;7{zs|3x9dD zkI%u(yS-;0dluxZRyF9Y_?VlKgQA$cT(rnU*uwSWo51cVr; z*=^rS6!H(nS%S^qv_}yo+91f1C+u(k9~*z<`>!3GPl&=7`Ls>b@W$o+(|(0M<^334 z{YmbdzuVj1b%UnsR1jZy_>oOBVs`I12~E$g;2nkxc$j9u;nuzgh7Q>7F*efYnQyoD zC0s&x5)MO*jflmJ7Z5+|OK3X)fiuwOF}5IXg`u^G*|xA2h!znJ*Cl6ur$yW|vCs6D z7LjlXQkktqBo-s}bjbkG&Q`#r7L@7Yy!(%$JfKBo)T9H(w1Tqfog2=Ca%z+o6fp4c-Iu&LQfJC@|1^7jBglG>HBiU$O@)0K>G4^+OxI{}& zu~q{(Hl)1Xr*RXq)y%d4zG3%~U88SY7MJd$F$+whC42q1pJWRqAtaNR=cU4*(H)E~ z&(SVCO5m>?QmC>-2gAzmRJGS@{w188zb3^_rktQBYraDji&_Za%JK!lq4rp3xxJ#L z=K$vMfG&!CB|1e;aE0eyiB_t3=*0HZm?A`vadUhE9cI%JJLK2>uqb$=Fm4JbXlAm; zp&VSOtO8Ukwzez5p`q@41Q)8d9KO(ZFg*0sNR+faL`~+ee^5p|MpN&}kTkE^_4fj$ zv8y4#r!i&=C*z|zNx@cgTzUQT%E9_(MV1H~wyv4Oy^EpG;f4*HuJRAt*oWF>W|PDvv$E6;nRb^j1({l$dT2-dTy4xWvpTJV_t$ z-hmIUQU*iSAEPhVu7=MQiG`ubHl$?1IFA`Kn$#Gv=Gnq>$Qrq;IMO}l^g3T^0n)*j z_azW1@gX^}!V=}NJIzm1J$rEDx0$b@>qM1vg?%54{%GL&tG*3vp2Zj!`Rt2;;K~_i zKu$OUzh8Zu8Klj?V%}sLH7R)}7IrX3DN|%-i7@XIyKhVg9{n5p>TQ~o5<8;)PYu(= zqN9xYk^bKrrlo%JpdP<$Lbz8RzVM`Sec{LIy_NjA{nV^HB#k^r)dcw2+*uAL=z4rd9f-u>-tmUJ2WCpPGP`(9$)OJIoKKo_nI77V8p*e^ zTb_yFmqcbZ)iWAU&$^Jao$<2mO%uGAtIaANs(2a2Mqi#U09A{bsO8a3eobKKqg}@& zpyWJQE@M^&P4!3bk3TL4UATS*v?%|qwoh$A*^AiVk_t>$Aa99t6^#ZO$V(?$NNAWz>T9QtJ3o@BT(VDR?uoSFSTY!uG7G V2%gw~z`(y2LUQ+UtNAj7@juhfoc#a* literal 1696 zcmb7FeKgZ+9A8nUTUt>ZM5UWbEVpKrBAO#dhVm;~CDq+Dd5Pt13%72mD{pnnH8-S_ zmtU+G+F~;zR`^|sDa>204b8mFrdjMhoOA!W|Je-p|qI5_Cjj`^n5m>1c#B=VILQbMgz`u%a&xtqy3p~Gus2#aqMIlhhRoRB*35>Y>H8ScstI;fU~2S;%YM8y>l z>pqSeVvs`Zsjs?0Ia*aVS*W|nAtl3Z49apOinJ@rZQWw615HVl1(otk0rZaB?B42g zd7HJr?w&iFm^ylqcEPspLr#0CU&n7ud5wFJsU(z`z_p4dwEc=Q7bKB*xX&=c*_(VY zSk1e?>$7#EnIZAzM>Xrzl${xF!vO)WBIfuB(J8I0%gBYW3dw0CxkiyvZu*OW;DH{$ z#4C##E6a3y#S)iTv+kEPDSQysVbCG1A&JBgza6AXGY9HKjZaPHMD2_gc0(jfQPXuz zkp5+3y?x)-1uCwD_AImnV6o|q|AVc=v=JjTAblHU9#<_;@4Y)`V6!$l3pjqzJ|j>irtbjZFu)xP_V?lV^qu}Ce=i@kzbv9f5MbGIj{1S}~#Ux6?XuiguxbC1=rDR9F<=q9jQ+<7- z`~uXyyw7n`*#>_@Y)MEw?g?zxn$LW3IEbI^M9*iGG9jG$;**Xy-Fte~ZN>1+4`xN> zL1H&#EdTO@sP>u@&DbRaOSz+^u0L~ht2CyX5RNo2Z^f&LG~2#l#*vCy@)s9Aeq^+T zL_IBt@=%>b9$4VZc7_&~yYdsMvdoZWc;e16x}4a$R+<EWhOL}AZLX9~$XS=~Fa zCg%`A!IagS)=$cVosHzOS+X3YqsoaHe&hlBdn!4}>E+Y@-f|sPcA-jXIJ5iPh|{;)rbo=);Akr6D38omqATw2a`(07(!cHE zd$*(n?>o<=h-4hpD4t}meBdpyr=~~DEmgX!e2^;^9Bzc)r#IcW-rC%;n1>z%Cyz(? zJqra43gv$j2M4!?_x9sg77D0#I*sj-e5=zop|+D}1bpnsM=bB2T)9+91f-p^z-L%p zpYEciGCZ%!W}FLHukyvk=@(&@98_jfGPguhpUgfH$@#$Td0za7;+`V0c*)5xuT3aY z(jyzLI2?g4Gv)H%J%u9tq%)$1D|?}I8M7+; zgD%E37s0Bs?%3_wB_sT^>=Z@f?frqv8CJoba>Y7zdm*W6n$2|dRPlmj#xZPq6(!s8 zjE1rDnk*~C9Z`>WQDtc{M@nI8e0!V-raClR!SI}aw)7JWS4M}X!LaMMvq0sVl=v-y zKv6#7AmNH7ONz4;OFUr#*-Dc*2}Ky%o4DJAg8Ef64F)bSk5!zv)tz3c7S{|?T1 z0f;4lEF%f?`Ln-fw3*%r7|Ia4=+*9+a=$u{Z!{=MbfpDkMa~7^3ChidNMJdix%v;G CXIFp# diff --git a/docs/d3/d0c/classshaka_1_1media_1_1mp2t_1_1AdtsHeader.html b/docs/d3/d0c/classshaka_1_1media_1_1mp2t_1_1AdtsHeader.html index 94ec36f358..380606955f 100644 --- a/docs/d3/d0c/classshaka_1_1media_1_1mp2t_1_1AdtsHeader.html +++ b/docs/d3/d0c/classshaka_1_1media_1_1mp2t_1_1AdtsHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::AdtsHeader Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp2t::AudioHeader - -
    + + @@ -491,9 +494,7 @@ Public Member Functions diff --git a/docs/d3/d12/classshaka_1_1media_1_1LibcryptoThreading-members.html b/docs/d3/d12/classshaka_1_1media_1_1LibcryptoThreading-members.html index 7938fcfe28..344c907a16 100644 --- a/docs/d3/d12/classshaka_1_1media_1_1LibcryptoThreading-members.html +++ b/docs/d3/d12/classshaka_1_1media_1_1LibcryptoThreading-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    diff --git a/docs/d3/d12/structshaka_1_1media_1_1mp4_1_1FlacSpecific-members.html b/docs/d3/d12/structshaka_1_1media_1_1mp4_1_1FlacSpecific-members.html index 58ab11eb18..49fbc86968 100644 --- a/docs/d3/d12/structshaka_1_1media_1_1mp4_1_1FlacSpecific-members.html +++ b/docs/d3/d12/structshaka_1_1media_1_1mp4_1_1FlacSpecific-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d3/d18/classshaka_1_1media_1_1mp2t_1_1TsSectionPat-members.html b/docs/d3/d18/classshaka_1_1media_1_1mp2t_1_1TsSectionPat-members.html index 0f8e415f1d..6ba5f8157f 100644 --- a/docs/d3/d18/classshaka_1_1media_1_1mp2t_1_1TsSectionPat-members.html +++ b/docs/d3/d18/classshaka_1_1media_1_1mp2t_1_1TsSectionPat-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d3/d19/io__cache_8h_source.html b/docs/d3/d19/io__cache_8h_source.html index a04586eb0c..0d66152668 100644 --- a/docs/d3/d19/io__cache_8h_source.html +++ b/docs/d3/d19/io__cache_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/io_cache.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    io_cache.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_FILE_IO_CACHE_H_
    8 #define PACKAGER_FILE_IO_CACHE_H_
    9 
    10 #include <stdint.h>
    11 #include <vector>
    12 #include "packager/base/macros.h"
    13 #include "packager/base/synchronization/lock.h"
    14 #include "packager/base/synchronization/waitable_event.h"
    15 
    16 namespace shaka {
    17 
    19 class IoCache {
    20  public:
    21  explicit IoCache(uint64_t cache_size);
    22  ~IoCache();
    23 
    30  uint64_t Read(void* buffer, uint64_t size);
    31 
    39  uint64_t Write(const void* buffer, uint64_t size);
    40 
    42  void Clear();
    43 
    46  void Close();
    47 
    49  bool closed() { return closed_; }
    50 
    52  void Reopen();
    53 
    56  uint64_t BytesCached();
    57 
    60  uint64_t BytesFree();
    61 
    64 
    65  private:
    66  uint64_t BytesCachedInternal();
    67  uint64_t BytesFreeInternal();
    68 
    69  const uint64_t cache_size_;
    70  base::Lock lock_;
    71  base::WaitableEvent read_event_;
    72  base::WaitableEvent write_event_;
    73  std::vector<uint8_t> circular_buffer_;
    74  const uint8_t* end_ptr_;
    75  uint8_t* r_ptr_;
    76  uint8_t* w_ptr_;
    77  bool closed_;
    78 
    79  DISALLOW_COPY_AND_ASSIGN(IoCache);
    80 };
    81 
    82 } // namespace shaka
    83 
    84 #endif // PACKAGER_FILE_IO_CACHE_H
    Declaration of class which implements a thread-safe circular buffer.
    Definition: io_cache.h:19
    -
    void Reopen()
    Reopens the cache. Any data still in the cache will be lost.
    Definition: io_cache.cc:119
    -
    void Clear()
    Empties the cache.
    Definition: io_cache.cc:105
    -
    void Close()
    Definition: io_cache.cc:112
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool closed()
    Definition: io_cache.h:49
    -
    uint64_t Write(const void *buffer, uint64_t size)
    Definition: io_cache.cc:66
    -
    void WaitUntilEmptyOrClosed()
    Waits until the cache is empty or has been closed.
    Definition: io_cache.cc:148
    -
    uint64_t Read(void *buffer, uint64_t size)
    Definition: io_cache.cc:38
    -
    uint64_t BytesFree()
    Definition: io_cache.cc:133
    -
    uint64_t BytesCached()
    Definition: io_cache.cc:128
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_FILE_IO_CACHE_H_
    +
    8 #define PACKAGER_FILE_IO_CACHE_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <vector>
    +
    12 #include "packager/base/macros.h"
    +
    13 #include "packager/base/synchronization/lock.h"
    +
    14 #include "packager/base/synchronization/waitable_event.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 
    +
    19 class IoCache {
    +
    20  public:
    +
    21  explicit IoCache(uint64_t cache_size);
    +
    22  ~IoCache();
    +
    23 
    +
    30  uint64_t Read(void* buffer, uint64_t size);
    +
    31 
    +
    39  uint64_t Write(const void* buffer, uint64_t size);
    +
    40 
    +
    42  void Clear();
    +
    43 
    +
    46  void Close();
    +
    47 
    +
    49  bool closed() { return closed_; }
    +
    50 
    +
    52  void Reopen();
    +
    53 
    +
    56  uint64_t BytesCached();
    +
    57 
    +
    60  uint64_t BytesFree();
    +
    61 
    + +
    64 
    +
    65  private:
    +
    66  uint64_t BytesCachedInternal();
    +
    67  uint64_t BytesFreeInternal();
    +
    68 
    +
    69  const uint64_t cache_size_;
    +
    70  base::Lock lock_;
    +
    71  base::WaitableEvent read_event_;
    +
    72  base::WaitableEvent write_event_;
    +
    73  std::vector<uint8_t> circular_buffer_;
    +
    74  const uint8_t* end_ptr_;
    +
    75  uint8_t* r_ptr_;
    +
    76  uint8_t* w_ptr_;
    +
    77  bool closed_;
    +
    78 
    +
    79  DISALLOW_COPY_AND_ASSIGN(IoCache);
    +
    80 };
    +
    81 
    +
    82 } // namespace shaka
    +
    83 
    +
    84 #endif // PACKAGER_FILE_IO_CACHE_H
    +
    Declaration of class which implements a thread-safe circular buffer.
    Definition: io_cache.h:19
    +
    void Clear()
    Empties the cache.
    Definition: io_cache.cc:105
    +
    void Close()
    Definition: io_cache.cc:112
    +
    uint64_t Write(const void *buffer, uint64_t size)
    Definition: io_cache.cc:66
    +
    bool closed()
    Definition: io_cache.h:49
    +
    uint64_t BytesFree()
    Definition: io_cache.cc:133
    +
    uint64_t Read(void *buffer, uint64_t size)
    Definition: io_cache.cc:38
    +
    uint64_t BytesCached()
    Definition: io_cache.cc:128
    +
    void WaitUntilEmptyOrClosed()
    Waits until the cache is empty or has been closed.
    Definition: io_cache.cc:148
    +
    void Reopen()
    Reopens the cache. Any data still in the cache will be lost.
    Definition: io_cache.cc:119
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/d1a/classshaka_1_1media_1_1Replicator.html b/docs/d3/d1a/classshaka_1_1media_1_1Replicator.html index d6f262bc57..6fe8830e7b 100644 --- a/docs/d3/d1a/classshaka_1_1media_1_1Replicator.html +++ b/docs/d3/d1a/classshaka_1_1media_1_1Replicator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::Replicator Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::MediaHandler - -
    + + @@ -98,9 +101,9 @@ bool  - - + + @@ -160,9 +163,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/d3/d1e/classshaka_1_1media_1_1FakeInputMediaHandler.html b/docs/d3/d1e/classshaka_1_1media_1_1FakeInputMediaHandler.html index 7ff5d60333..77fd091076 100644 --- a/docs/d3/d1e/classshaka_1_1media_1_1FakeInputMediaHandler.html +++ b/docs/d3/d1e/classshaka_1_1media_1_1FakeInputMediaHandler.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::FakeInputMediaHandler Class Reference @@ -29,18 +29,21 @@

    Additional Inherited Members

     Validate if the handler is connected to its upstream handler.
     
    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    Status Dispatch (std::unique_ptr< StreamData > stream_data) const
     
    - + +/* @license-end */
    shaka::media::FakeInputMediaHandler Class Reference
    @@ -75,11 +79,21 @@ Inheritance diagram for shaka::media::FakeInputMediaHandler:
    shaka::media::MediaHandler - -
    + + - + + + + + + + + + @@ -95,10 +109,13 @@ Additional Inherited Members bool  +

    -Additional Inherited Members

    +Public Member Functions

    Status Dispatch (std::unique_ptr< StreamData > stream_data) const
     
    +Status FlushAllDownstreams ()
     Flush all connected downstream handlers.
     
    +Status FlushDownstream (size_t output_stream_index)
     Flush the downstream connected at the specified output stream index.
     
    - Public Member Functions inherited from shaka::media::MediaHandler
    Status SetHandler (size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
    IsConnected ()
     Validate if the handler is connected to its upstream handler.
     
    + - - + + @@ -153,17 +170,33 @@ const std::map< size_t, std::pair< std::shared_ptr<

    Detailed Description

    -

    Definition at line 250 of file media_handler_test_base.h.

    -

    The documentation for this class was generated from the following files:

    +Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    virtual Status OnFlushRequest (size_t input_stream_index)
    + + + +
    Status shaka::media::MediaHandler::Dispatch
    +
    +

    Dispatch the stream data to downstream handlers. Note that stream_data.stream_index should be the output stream index.

    + +

    Definition at line 196 of file media_handler.cc.

    + +
    + +
    The documentation for this class was generated from the following files: diff --git a/docs/d3/d35/video__slice__header__parser_8cc_source.html b/docs/d3/d35/video__slice__header__parser_8cc_source.html index dc49aead95..aead183874 100644 --- a/docs/d3/d35/video__slice__header__parser_8cc_source.html +++ b/docs/d3/d35/video__slice__header__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/video_slice_header_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    video_slice_header_parser.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/video_slice_header_parser.h"
    8 
    9 #include "packager/media/base/rcheck.h"
    10 #include "packager/media/codecs/avc_decoder_configuration_record.h"
    11 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 namespace {
    17 
    18 size_t NumBitsToNumBytes(size_t size_in_bits) {
    19  // Round-up division.
    20  return (size_in_bits + 7) >> 3;
    21 }
    22 
    23 } // namespace
    24 
    25 H264VideoSliceHeaderParser::H264VideoSliceHeaderParser() {}
    26 H264VideoSliceHeaderParser::~H264VideoSliceHeaderParser() {}
    27 
    29  const std::vector<uint8_t>& decoder_configuration) {
    31  RCHECK(config.Parse(decoder_configuration));
    32 
    33  for (size_t i = 0; i < config.nalu_count(); i++) {
    34  int id;
    35  const Nalu& nalu = config.nalu(i);
    36  if (nalu.type() == Nalu::H264_SPS) {
    37  RCHECK(parser_.ParseSps(nalu, &id) == H264Parser::kOk);
    38  } else {
    39  DCHECK_EQ(Nalu::H264_PPS, nalu.type());
    40  RCHECK(parser_.ParsePps(nalu, &id) == H264Parser::kOk);
    41  }
    42  }
    43 
    44  return true;
    45 }
    46 
    48  int id;
    49  switch (nalu.type()) {
    50  case Nalu::H264_SPS:
    51  return parser_.ParseSps(nalu, &id) == H264Parser::kOk;
    52  case Nalu::H264_PPS:
    53  return parser_.ParsePps(nalu, &id) == H264Parser::kOk;
    54  default:
    55  return true;
    56  }
    57 }
    58 
    60  DCHECK(nalu.is_video_slice());
    61  H264SliceHeader slice_header;
    62  if (parser_.ParseSliceHeader(nalu, &slice_header) != H264Parser::kOk)
    63  return -1;
    64 
    65  return NumBitsToNumBytes(slice_header.header_bit_size);
    66 }
    67 
    68 H265VideoSliceHeaderParser::H265VideoSliceHeaderParser() {}
    69 H265VideoSliceHeaderParser::~H265VideoSliceHeaderParser() {}
    70 
    72  const std::vector<uint8_t>& decoder_configuration) {
    73  int id;
    75  RCHECK(hevc_config.Parse(decoder_configuration));
    76 
    77  for (size_t i = 0; i < hevc_config.nalu_count(); i++) {
    78  const Nalu& nalu = hevc_config.nalu(i);
    79  if (nalu.type() == Nalu::H265_SPS) {
    80  RCHECK(parser_.ParseSps(nalu, &id) == H265Parser::kOk);
    81  } else if (nalu.type() == Nalu::H265_PPS) {
    82  RCHECK(parser_.ParsePps(nalu, &id) == H265Parser::kOk);
    83  } else if (nalu.type() == Nalu::H265_VPS) {
    84  // Ignore since it does not affect video slice header parsing.
    85  } else {
    86  VLOG(1) << "Ignoring decoder configuration Nalu of unknown type "
    87  << nalu.type();
    88  }
    89  }
    90 
    91  return true;
    92 }
    93 
    95  int id;
    96  switch (nalu.type()) {
    97  case Nalu::H265_SPS:
    98  return parser_.ParseSps(nalu, &id) == H265Parser::kOk;
    99  case Nalu::H265_PPS:
    100  return parser_.ParsePps(nalu, &id) == H265Parser::kOk;
    101  case Nalu::H265_VPS:
    102  // Ignore since it does not affect video slice header parsing.
    103  return true;
    104  default:
    105  return true;
    106  }
    107 }
    108 
    110  DCHECK(nalu.is_video_slice());
    111  H265SliceHeader slice_header;
    112  if (parser_.ParseSliceHeader(nalu, &slice_header) != H265Parser::kOk)
    113  return -1;
    114 
    115  return NumBitsToNumBytes(slice_header.header_bit_size);
    116 }
    117 
    118 } // namespace media
    119 } // namespace shaka
    120 
    bool is_video_slice() const
    Slice data partition NALs are not considered as slice NALs.
    Definition: nalu_reader.h:117
    - - - -
    All the methods that are virtual are virtual for mocking.
    -
    int64_t GetHeaderSize(const Nalu &nalu) override
    Gets the header size of the given NALU. Returns < 0 on error.
    -
    int64_t GetHeaderSize(const Nalu &nalu) override
    Gets the header size of the given NALU. Returns < 0 on error.
    - - -
    bool Parse(const std::vector< uint8_t > &data)
    -
    bool Initialize(const std::vector< uint8_t > &decoder_configuration) override
    - -
    Class for parsing HEVC decoder configuration record.
    -
    int type() const
    Definition: nalu_reader.h:113
    -
    Class for parsing AVC decoder configuration record.
    -
    bool Initialize(const std::vector< uint8_t > &decoder_configuration) override
    - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/video_slice_header_parser.h"
    +
    8 
    +
    9 #include "packager/media/base/rcheck.h"
    +
    10 #include "packager/media/codecs/avc_decoder_configuration_record.h"
    +
    11 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 namespace {
    +
    17 
    +
    18 size_t NumBitsToNumBytes(size_t size_in_bits) {
    +
    19  // Round-up division.
    +
    20  return (size_in_bits + 7) >> 3;
    +
    21 }
    +
    22 
    +
    23 } // namespace
    +
    24 
    +
    25 H264VideoSliceHeaderParser::H264VideoSliceHeaderParser() {}
    +
    26 H264VideoSliceHeaderParser::~H264VideoSliceHeaderParser() {}
    +
    27 
    + +
    29  const std::vector<uint8_t>& decoder_configuration) {
    + +
    31  RCHECK(config.Parse(decoder_configuration));
    +
    32 
    +
    33  for (size_t i = 0; i < config.nalu_count(); i++) {
    +
    34  int id;
    +
    35  const Nalu& nalu = config.nalu(i);
    +
    36  if (nalu.type() == Nalu::H264_SPS) {
    +
    37  RCHECK(parser_.ParseSps(nalu, &id) == H264Parser::kOk);
    +
    38  } else if (nalu.type() == Nalu::H264_PPS) {
    +
    39  RCHECK(parser_.ParsePps(nalu, &id) == H264Parser::kOk);
    +
    40  }
    +
    41  }
    +
    42 
    +
    43  return true;
    +
    44 }
    +
    45 
    + +
    47  int id;
    +
    48  switch (nalu.type()) {
    +
    49  case Nalu::H264_SPS:
    +
    50  return parser_.ParseSps(nalu, &id) == H264Parser::kOk;
    +
    51  case Nalu::H264_PPS:
    +
    52  return parser_.ParsePps(nalu, &id) == H264Parser::kOk;
    +
    53  default:
    +
    54  return true;
    +
    55  }
    +
    56 }
    +
    57 
    + +
    59  DCHECK(nalu.is_video_slice());
    +
    60  H264SliceHeader slice_header;
    +
    61  if (parser_.ParseSliceHeader(nalu, &slice_header) != H264Parser::kOk)
    +
    62  return -1;
    +
    63 
    +
    64  return NumBitsToNumBytes(slice_header.header_bit_size);
    +
    65 }
    +
    66 
    +
    67 H265VideoSliceHeaderParser::H265VideoSliceHeaderParser() {}
    +
    68 H265VideoSliceHeaderParser::~H265VideoSliceHeaderParser() {}
    +
    69 
    + +
    71  const std::vector<uint8_t>& decoder_configuration) {
    +
    72  int id;
    + +
    74  RCHECK(hevc_config.Parse(decoder_configuration));
    +
    75 
    +
    76  for (size_t i = 0; i < hevc_config.nalu_count(); i++) {
    +
    77  const Nalu& nalu = hevc_config.nalu(i);
    +
    78  if (nalu.type() == Nalu::H265_SPS) {
    +
    79  RCHECK(parser_.ParseSps(nalu, &id) == H265Parser::kOk);
    +
    80  } else if (nalu.type() == Nalu::H265_PPS) {
    +
    81  RCHECK(parser_.ParsePps(nalu, &id) == H265Parser::kOk);
    +
    82  } else if (nalu.type() == Nalu::H265_VPS) {
    +
    83  // Ignore since it does not affect video slice header parsing.
    +
    84  } else {
    +
    85  VLOG(1) << "Ignoring decoder configuration Nalu of unknown type "
    +
    86  << nalu.type();
    +
    87  }
    +
    88  }
    +
    89 
    +
    90  return true;
    +
    91 }
    +
    92 
    + +
    94  int id;
    +
    95  switch (nalu.type()) {
    +
    96  case Nalu::H265_SPS:
    +
    97  return parser_.ParseSps(nalu, &id) == H265Parser::kOk;
    +
    98  case Nalu::H265_PPS:
    +
    99  return parser_.ParsePps(nalu, &id) == H265Parser::kOk;
    +
    100  case Nalu::H265_VPS:
    +
    101  // Ignore since it does not affect video slice header parsing.
    +
    102  return true;
    +
    103  default:
    +
    104  return true;
    +
    105  }
    +
    106 }
    +
    107 
    + +
    109  DCHECK(nalu.is_video_slice());
    +
    110  H265SliceHeader slice_header;
    +
    111  if (parser_.ParseSliceHeader(nalu, &slice_header) != H265Parser::kOk)
    +
    112  return -1;
    +
    113 
    +
    114  return NumBitsToNumBytes(slice_header.header_bit_size);
    +
    115 }
    +
    116 
    +
    117 } // namespace media
    +
    118 } // namespace shaka
    +
    119 
    +
    Class for parsing AVC decoder configuration record.
    +
    bool Parse(const std::vector< uint8_t > &data)
    + + + +
    bool Initialize(const std::vector< uint8_t > &decoder_configuration) override
    +
    int64_t GetHeaderSize(const Nalu &nalu) override
    Gets the header size of the given NALU. Returns < 0 on error.
    +
    Result ParseSps(const Nalu &nalu, int *sps_id)
    Definition: h265_parser.cc:509
    +
    Result ParsePps(const Nalu &nalu, int *pps_id)
    Definition: h265_parser.cc:401
    +
    Result ParseSliceHeader(const Nalu &nalu, H265SliceHeader *slice_header)
    Definition: h265_parser.cc:183
    +
    int64_t GetHeaderSize(const Nalu &nalu) override
    Gets the header size of the given NALU. Returns < 0 on error.
    +
    bool Initialize(const std::vector< uint8_t > &decoder_configuration) override
    + +
    Class for parsing HEVC decoder configuration record.
    + +
    bool is_video_slice() const
    Slice data partition NALs are not considered as slice NALs.
    Definition: nalu_reader.h:117
    +
    int type() const
    Definition: nalu_reader.h:113
    +
    All the methods that are virtual are virtual for mocking.
    + +
    diff --git a/docs/d3/d48/packager_8cc_source.html b/docs/d3/d48/packager_8cc_source.html index 809004aa64..8e45e7b751 100644 --- a/docs/d3/d48/packager_8cc_source.html +++ b/docs/d3/d48/packager_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/packager.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    packager.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/packager.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/app/job_manager.h"
    12 #include "packager/app/libcrypto_threading.h"
    13 #include "packager/app/muxer_factory.h"
    14 #include "packager/app/packager_util.h"
    15 #include "packager/app/stream_descriptor.h"
    16 #include "packager/base/at_exit.h"
    17 #include "packager/base/files/file_path.h"
    18 #include "packager/base/logging.h"
    19 #include "packager/base/optional.h"
    20 #include "packager/base/path_service.h"
    21 #include "packager/base/strings/string_util.h"
    22 #include "packager/base/strings/stringprintf.h"
    23 #include "packager/base/threading/simple_thread.h"
    24 #include "packager/base/time/clock.h"
    25 #include "packager/file/file.h"
    26 #include "packager/hls/base/hls_notifier.h"
    27 #include "packager/hls/base/simple_hls_notifier.h"
    28 #include "packager/media/base/container_names.h"
    29 #include "packager/media/base/fourccs.h"
    30 #include "packager/media/base/key_source.h"
    31 #include "packager/media/base/language_utils.h"
    32 #include "packager/media/base/muxer.h"
    33 #include "packager/media/base/muxer_options.h"
    34 #include "packager/media/base/muxer_util.h"
    35 #include "packager/media/chunking/chunking_handler.h"
    36 #include "packager/media/chunking/cue_alignment_handler.h"
    37 #include "packager/media/chunking/text_chunker.h"
    38 #include "packager/media/crypto/encryption_handler.h"
    39 #include "packager/media/demuxer/demuxer.h"
    40 #include "packager/media/event/muxer_listener_factory.h"
    41 #include "packager/media/event/vod_media_info_dump_muxer_listener.h"
    42 #include "packager/media/formats/webvtt/text_padder.h"
    43 #include "packager/media/formats/webvtt/text_readers.h"
    44 #include "packager/media/formats/webvtt/webvtt_parser.h"
    45 #include "packager/media/formats/webvtt/webvtt_text_output_handler.h"
    46 #include "packager/media/formats/webvtt/webvtt_to_mp4_handler.h"
    47 #include "packager/media/replicator/replicator.h"
    48 #include "packager/media/trick_play/trick_play_handler.h"
    49 #include "packager/mpd/base/media_info.pb.h"
    50 #include "packager/mpd/base/mpd_builder.h"
    51 #include "packager/mpd/base/simple_mpd_notifier.h"
    52 #include "packager/status_macros.h"
    53 #include "packager/version/version.h"
    54 
    55 namespace shaka {
    56 
    57 // TODO(kqyang): Clean up namespaces.
    58 using media::Demuxer;
    59 using media::JobManager;
    60 using media::KeySource;
    61 using media::MuxerOptions;
    62 using media::SyncPointQueue;
    63 
    64 namespace media {
    65 namespace {
    66 
    67 const char kMediaInfoSuffix[] = ".media_info";
    68 
    69 const int64_t kDefaultTextZeroBiasMs = 10 * 60 * 1000; // 10 minutes
    70 
    71 MuxerOptions CreateMuxerOptions(const StreamDescriptor& stream,
    72  const PackagingParams& params) {
    73  MuxerOptions options;
    74 
    75  options.mp4_params = params.mp4_output_params;
    76  options.transport_stream_timestamp_offset_ms =
    77  params.transport_stream_timestamp_offset_ms;
    78  options.temp_dir = params.temp_dir;
    79  options.bandwidth = stream.bandwidth;
    80  options.output_file_name = stream.output;
    81  options.segment_template = stream.segment_template;
    82 
    83  return options;
    84 }
    85 
    86 MuxerListenerFactory::StreamData ToMuxerListenerData(
    87  const StreamDescriptor& stream) {
    88  MuxerListenerFactory::StreamData data;
    89  data.media_info_output = stream.output;
    90 
    91  data.hls_group_id = stream.hls_group_id;
    92  data.hls_name = stream.hls_name;
    93  data.hls_playlist_name = stream.hls_playlist_name;
    94  data.hls_iframe_playlist_name = stream.hls_iframe_playlist_name;
    95  data.hls_characteristics = stream.hls_characteristics;
    96 
    97  data.dash_accessiblities = stream.dash_accessiblities;
    98  data.dash_roles = stream.dash_roles;
    99  return data;
    100 };
    101 
    102 // TODO(rkuroiwa): Write TTML and WebVTT parser (demuxing) for a better check
    103 // and for supporting live/segmenting (muxing). With a demuxer and a muxer,
    104 // CreateAllJobs() shouldn't treat text as a special case.
    105 bool DetermineTextFileCodec(const std::string& file, std::string* out) {
    106  CHECK(out);
    107 
    108  std::string content;
    109  if (!File::ReadFileToString(file.c_str(), &content)) {
    110  LOG(ERROR) << "Failed to open file " << file
    111  << " to determine file format.";
    112  return false;
    113  }
    114 
    115  const uint8_t* content_data =
    116  reinterpret_cast<const uint8_t*>(content.data());
    117  MediaContainerName container_name =
    118  DetermineContainer(content_data, content.size());
    119 
    120  if (container_name == CONTAINER_WEBVTT) {
    121  *out = "wvtt";
    122  return true;
    123  }
    124 
    125  if (container_name == CONTAINER_TTML) {
    126  *out = "ttml";
    127  return true;
    128  }
    129 
    130  return false;
    131 }
    132 
    133 MediaContainerName GetOutputFormat(const StreamDescriptor& descriptor) {
    134  if (!descriptor.output_format.empty()) {
    135  MediaContainerName format =
    136  DetermineContainerFromFormatName(descriptor.output_format);
    137  if (format == CONTAINER_UNKNOWN) {
    138  LOG(ERROR) << "Unable to determine output format from '"
    139  << descriptor.output_format << "'.";
    140  }
    141  return format;
    142  }
    143 
    144  base::Optional<MediaContainerName> format_from_output;
    145  base::Optional<MediaContainerName> format_from_segment;
    146  if (!descriptor.output.empty()) {
    147  format_from_output = DetermineContainerFromFileName(descriptor.output);
    148  if (format_from_output.value() == CONTAINER_UNKNOWN) {
    149  LOG(ERROR) << "Unable to determine output format from '"
    150  << descriptor.output << "'.";
    151  }
    152  }
    153  if (!descriptor.segment_template.empty()) {
    154  format_from_segment =
    155  DetermineContainerFromFileName(descriptor.segment_template);
    156  if (format_from_segment.value() == CONTAINER_UNKNOWN) {
    157  LOG(ERROR) << "Unable to determine output format from '"
    158  << descriptor.segment_template << "'.";
    159  }
    160  }
    161 
    162  if (format_from_output && format_from_segment) {
    163  if (format_from_output.value() != format_from_segment.value()) {
    164  LOG(ERROR) << "Output format determined from '" << descriptor.output
    165  << "' differs from output format determined from '"
    166  << descriptor.segment_template << "'.";
    167  return CONTAINER_UNKNOWN;
    168  }
    169  }
    170 
    171  if (format_from_output)
    172  return format_from_output.value();
    173  if (format_from_segment)
    174  return format_from_segment.value();
    175  return CONTAINER_UNKNOWN;
    176 }
    177 
    178 Status ValidateStreamDescriptor(bool dump_stream_info,
    179  const StreamDescriptor& stream) {
    180  if (stream.input.empty()) {
    181  return Status(error::INVALID_ARGUMENT, "Stream input not specified.");
    182  }
    183 
    184  // The only time a stream can have no outputs, is when dump stream info is
    185  // set.
    186  if (dump_stream_info && stream.output.empty() &&
    187  stream.segment_template.empty()) {
    188  return Status::OK;
    189  }
    190 
    191  if (stream.output.empty() && stream.segment_template.empty()) {
    192  return Status(error::INVALID_ARGUMENT,
    193  "Streams must specify 'output' or 'segment template'.");
    194  }
    195 
    196  // Whenever there is output, a stream must be selected.
    197  if (stream.stream_selector.empty()) {
    198  return Status(error::INVALID_ARGUMENT,
    199  "Stream stream_selector not specified.");
    200  }
    201 
    202  // If a segment template is provided, it must be valid.
    203  if (stream.segment_template.length()) {
    204  RETURN_IF_ERROR(ValidateSegmentTemplate(stream.segment_template));
    205  }
    206 
    207  // There are some specifics that must be checked based on which format
    208  // we are writing to.
    209  const MediaContainerName output_format = GetOutputFormat(stream);
    210 
    211  if (output_format == CONTAINER_UNKNOWN) {
    212  return Status(error::INVALID_ARGUMENT, "Unsupported output format.");
    213  }
    214  if (output_format == MediaContainerName::CONTAINER_MPEG2TS) {
    215  if (stream.segment_template.empty()) {
    216  return Status(
    217  error::INVALID_ARGUMENT,
    218  "Please specify 'segment_template'. Single file TS output is "
    219  "not supported.");
    220  }
    221 
    222  // Right now the init segment is saved in |output| for multi-segment
    223  // content. However, for TS all segments must be self-initializing so
    224  // there cannot be an init segment.
    225  if (stream.output.length()) {
    226  return Status(error::INVALID_ARGUMENT,
    227  "All TS segments must be self-initializing. Stream "
    228  "descriptors 'output' or 'init_segment' are not allowed.");
    229  }
    230  } else if (output_format == CONTAINER_WEBVTT ||
    231  output_format == CONTAINER_AAC || output_format == CONTAINER_AC3 ||
    232  output_format == CONTAINER_EAC3) {
    233  // There is no need for an init segment when outputting because there is no
    234  // initialization data.
    235  if (stream.segment_template.length() && stream.output.length()) {
    236  return Status(
    237  error::INVALID_ARGUMENT,
    238  "Segmented WebVTT or PackedAudio output cannot have an init segment. "
    239  "Do not specify stream descriptors 'output' or 'init_segment' when "
    240  "using 'segment_template'.");
    241  }
    242  } else {
    243  // For any other format, if there is a segment template, there must be an
    244  // init segment provided.
    245  if (stream.segment_template.length() && stream.output.empty()) {
    246  return Status(error::INVALID_ARGUMENT,
    247  "Please specify 'init_segment'. All non-TS multi-segment "
    248  "content must provide an init segment.");
    249  }
    250  }
    251 
    252  if (stream.output.find('$') != std::string::npos) {
    253  if (output_format == CONTAINER_WEBVTT) {
    254  return Status(
    255  error::UNIMPLEMENTED,
    256  "WebVTT output with one file per Representation per Period "
    257  "is not supported yet. Please use fMP4 instead. If that needs to be "
    258  "supported, please file a feature request on GitHub.");
    259  }
    260  // "$" is only allowed if the output file name is a template, which is
    261  // used to support one file per Representation per Period when there are
    262  // Ad Cues.
    263  RETURN_IF_ERROR(ValidateSegmentTemplate(stream.output));
    264  }
    265 
    266  return Status::OK;
    267 }
    268 
    269 Status ValidateParams(const PackagingParams& packaging_params,
    270  const std::vector<StreamDescriptor>& stream_descriptors) {
    271  if (!packaging_params.chunking_params.segment_sap_aligned &&
    272  packaging_params.chunking_params.subsegment_sap_aligned) {
    273  return Status(error::INVALID_ARGUMENT,
    274  "Setting segment_sap_aligned to false but "
    275  "subsegment_sap_aligned to true is not allowed.");
    276  }
    277 
    278  if (stream_descriptors.empty()) {
    279  return Status(error::INVALID_ARGUMENT,
    280  "Stream descriptors cannot be empty.");
    281  }
    282 
    283  // On demand profile generates single file segment while live profile
    284  // generates multiple segments specified using segment template.
    285  const bool on_demand_dash_profile =
    286  stream_descriptors.begin()->segment_template.empty();
    287  std::set<std::string> outputs;
    288  std::set<std::string> segment_templates;
    289  for (const auto& descriptor : stream_descriptors) {
    290  if (on_demand_dash_profile != descriptor.segment_template.empty()) {
    291  return Status(error::INVALID_ARGUMENT,
    292  "Inconsistent stream descriptor specification: "
    293  "segment_template should be specified for none or all "
    294  "stream descriptors.");
    295  }
    296 
    297  RETURN_IF_ERROR(ValidateStreamDescriptor(
    298  packaging_params.test_params.dump_stream_info, descriptor));
    299 
    300  if (base::StartsWith(descriptor.input, "udp://",
    301  base::CompareCase::SENSITIVE)) {
    302  const HlsParams& hls_params = packaging_params.hls_params;
    303  if (!hls_params.master_playlist_output.empty() &&
    304  hls_params.playlist_type == HlsPlaylistType::kVod) {
    305  LOG(WARNING)
    306  << "Seeing UDP input with HLS Playlist Type set to VOD. The "
    307  "playlists will only be generated when UDP socket is closed. "
    308  "If you want to do live packaging, --hls_playlist_type needs to "
    309  "be set to LIVE.";
    310  }
    311  // Skip the check for DASH as DASH defaults to 'dynamic' MPD when segment
    312  // template is provided.
    313  }
    314 
    315  if (!descriptor.output.empty()) {
    316  if (outputs.find(descriptor.output) != outputs.end()) {
    317  return Status(
    318  error::INVALID_ARGUMENT,
    319  "Seeing duplicated outputs '" + descriptor.output +
    320  "' in stream descriptors. Every output must be unique.");
    321  }
    322  outputs.insert(descriptor.output);
    323  }
    324  if (!descriptor.segment_template.empty()) {
    325  if (segment_templates.find(descriptor.segment_template) !=
    326  segment_templates.end()) {
    327  return Status(error::INVALID_ARGUMENT,
    328  "Seeing duplicated segment templates '" +
    329  descriptor.segment_template +
    330  "' in stream descriptors. Every segment template "
    331  "must be unique.");
    332  }
    333  segment_templates.insert(descriptor.segment_template);
    334  }
    335  }
    336 
    337  if (packaging_params.output_media_info && !on_demand_dash_profile) {
    338  // TODO(rkuroiwa, kqyang): Support partial media info dump for live.
    339  return Status(error::UNIMPLEMENTED,
    340  "--output_media_info is only supported for on-demand profile "
    341  "(not using segment_template).");
    342  }
    343 
    344  return Status::OK;
    345 }
    346 
    347 bool StreamDescriptorCompareFn(const StreamDescriptor& a,
    348  const StreamDescriptor& b) {
    349  // This function is used by std::sort() to sort the stream descriptors.
    350  // Note that std::sort() need a comparator that return true iff the first
    351  // argument is strictly lower than the second one. That is: must return false
    352  // when they are equal. The requirement is enforced in gcc/g++ but not in
    353  // clang.
    354  if (a.input == b.input) {
    355  if (a.stream_selector == b.stream_selector) {
    356  // The MPD notifier requires that the main track comes first, so make
    357  // sure that happens.
    358  return a.trick_play_factor < b.trick_play_factor;
    359  }
    360  return a.stream_selector < b.stream_selector;
    361  }
    362 
    363  return a.input < b.input;
    364 }
    365 
    366 // A fake clock that always return time 0 (epoch). Should only be used for
    367 // testing.
    368 class FakeClock : public base::Clock {
    369  public:
    370  base::Time Now() override { return base::Time(); }
    371 };
    372 
    373 bool StreamInfoToTextMediaInfo(const StreamDescriptor& stream_descriptor,
    374  MediaInfo* text_media_info) {
    375  std::string codec;
    376  if (!DetermineTextFileCodec(stream_descriptor.input, &codec)) {
    377  LOG(ERROR) << "Failed to determine the text file format for "
    378  << stream_descriptor.input;
    379  return false;
    380  }
    381 
    382  MediaInfo::TextInfo* text_info = text_media_info->mutable_text_info();
    383  text_info->set_codec(codec);
    384 
    385  const std::string& language = stream_descriptor.language;
    386  if (!language.empty()) {
    387  text_info->set_language(language);
    388  }
    389 
    390  text_media_info->set_media_file_name(stream_descriptor.output);
    391  text_media_info->set_container_type(MediaInfo::CONTAINER_TEXT);
    392 
    393  if (stream_descriptor.bandwidth != 0) {
    394  text_media_info->set_bandwidth(stream_descriptor.bandwidth);
    395  } else {
    396  // Text files are usually small and since the input is one file; there's no
    397  // way for the player to do ranged requests. So set this value to something
    398  // reasonable.
    399  const int kDefaultTextBandwidth = 256;
    400  text_media_info->set_bandwidth(kDefaultTextBandwidth);
    401  }
    402 
    403  return true;
    404 }
    405 
    409 Status CreateDemuxer(const StreamDescriptor& stream,
    410  const PackagingParams& packaging_params,
    411  std::shared_ptr<Demuxer>* new_demuxer) {
    412  std::shared_ptr<Demuxer> demuxer = std::make_shared<Demuxer>(stream.input);
    413  demuxer->set_dump_stream_info(packaging_params.test_params.dump_stream_info);
    414 
    415  if (packaging_params.decryption_params.key_provider != KeyProvider::kNone) {
    416  std::unique_ptr<KeySource> decryption_key_source(
    417  CreateDecryptionKeySource(packaging_params.decryption_params));
    418  if (!decryption_key_source) {
    419  return Status(
    420  error::INVALID_ARGUMENT,
    421  "Must define decryption key source when defining key provider");
    422  }
    423  demuxer->SetKeySource(std::move(decryption_key_source));
    424  }
    425 
    426  *new_demuxer = std::move(demuxer);
    427  return Status::OK;
    428 }
    429 
    430 std::shared_ptr<MediaHandler> CreateEncryptionHandler(
    431  const PackagingParams& packaging_params,
    432  const StreamDescriptor& stream,
    433  KeySource* key_source) {
    434  if (stream.skip_encryption) {
    435  return nullptr;
    436  }
    437 
    438  if (!key_source) {
    439  return nullptr;
    440  }
    441 
    442  // Make a copy so that we can modify it for this specific stream.
    443  EncryptionParams encryption_params = packaging_params.encryption_params;
    444 
    445  // Use Sample AES in MPEG2TS.
    446  // TODO(kqyang): Consider adding a new flag to enable Sample AES as we
    447  // will support CENC in TS in the future.
    448  if (GetOutputFormat(stream) == CONTAINER_MPEG2TS ||
    449  GetOutputFormat(stream) == CONTAINER_AAC ||
    450  GetOutputFormat(stream) == CONTAINER_AC3 ||
    451  GetOutputFormat(stream) == CONTAINER_EAC3) {
    452  VLOG(1) << "Use Apple Sample AES encryption for MPEG2TS or Packed Audio.";
    453  encryption_params.protection_scheme = kAppleSampleAesProtectionScheme;
    454  }
    455 
    456  if (!stream.drm_label.empty()) {
    457  const std::string& drm_label = stream.drm_label;
    458  encryption_params.stream_label_func =
    459  [drm_label](const EncryptionParams::EncryptedStreamAttributes&) {
    460  return drm_label;
    461  };
    462  } else if (!encryption_params.stream_label_func) {
    463  const int kDefaultMaxSdPixels = 768 * 576;
    464  const int kDefaultMaxHdPixels = 1920 * 1080;
    465  const int kDefaultMaxUhd1Pixels = 4096 * 2160;
    466  encryption_params.stream_label_func = std::bind(
    467  &Packager::DefaultStreamLabelFunction, kDefaultMaxSdPixels,
    468  kDefaultMaxHdPixels, kDefaultMaxUhd1Pixels, std::placeholders::_1);
    469  }
    470 
    471  return std::make_shared<EncryptionHandler>(encryption_params, key_source);
    472 }
    473 
    474 std::unique_ptr<TextChunker> CreateTextChunker(
    475  const ChunkingParams& chunking_params) {
    476  const float segment_length_in_seconds =
    477  chunking_params.segment_duration_in_seconds;
    478  return std::unique_ptr<TextChunker>(
    479  new TextChunker(segment_length_in_seconds));
    480 }
    481 
    482 Status CreateHlsTextJob(const StreamDescriptor& stream,
    483  const PackagingParams& packaging_params,
    484  std::unique_ptr<MuxerListener> muxer_listener,
    485  SyncPointQueue* sync_points,
    486  JobManager* job_manager) {
    487  DCHECK(muxer_listener);
    488  DCHECK(job_manager);
    489 
    490  if (stream.segment_template.empty()) {
    491  return Status(error::INVALID_ARGUMENT,
    492  "Cannot output text (" + stream.input +
    493  ") to HLS with no segment template");
    494  }
    495 
    496  // Text files are usually small and since the input is one file;
    497  // there's no way for the player to do ranged requests. So set this
    498  // value to something reasonable if it is missing.
    499  MuxerOptions muxer_options = CreateMuxerOptions(stream, packaging_params);
    500  muxer_options.bandwidth = stream.bandwidth ? stream.bandwidth : 256;
    501 
    502  auto output = std::make_shared<WebVttTextOutputHandler>(
    503  muxer_options, std::move(muxer_listener));
    504 
    505  std::unique_ptr<FileReader> reader;
    506  RETURN_IF_ERROR(FileReader::Open(stream.input, &reader));
    507 
    508  auto parser =
    509  std::make_shared<WebVttParser>(std::move(reader), stream.language);
    510  auto padder = std::make_shared<TextPadder>(kDefaultTextZeroBiasMs);
    511  auto cue_aligner = sync_points
    512  ? std::make_shared<CueAlignmentHandler>(sync_points)
    513  : nullptr;
    514  auto chunker = CreateTextChunker(packaging_params.chunking_params);
    515 
    516  job_manager->Add("Segmented Text Job", parser);
    517 
    518  return MediaHandler::Chain({std::move(parser), std::move(padder),
    519  std::move(cue_aligner), std::move(chunker),
    520  std::move(output)});
    521 }
    522 
    523 Status CreateWebVttToMp4TextJob(const StreamDescriptor& stream,
    524  const PackagingParams& packaging_params,
    525  std::unique_ptr<MuxerListener> muxer_listener,
    526  SyncPointQueue* sync_points,
    527  MuxerFactory* muxer_factory,
    528  std::shared_ptr<OriginHandler>* root) {
    529  std::unique_ptr<FileReader> reader;
    530  RETURN_IF_ERROR(FileReader::Open(stream.input, &reader));
    531 
    532  auto parser =
    533  std::make_shared<WebVttParser>(std::move(reader), stream.language);
    534  auto padder = std::make_shared<TextPadder>(kDefaultTextZeroBiasMs);
    535 
    536  auto text_to_mp4 = std::make_shared<WebVttToMp4Handler>();
    537  auto muxer = muxer_factory->CreateMuxer(GetOutputFormat(stream), stream);
    538  muxer->SetMuxerListener(std::move(muxer_listener));
    539 
    540  // Optional Cue Alignment Handler
    541  std::shared_ptr<MediaHandler> cue_aligner;
    542  if (sync_points) {
    543  cue_aligner = std::make_shared<CueAlignmentHandler>(sync_points);
    544  }
    545 
    546  std::shared_ptr<MediaHandler> chunker =
    547  CreateTextChunker(packaging_params.chunking_params);
    548 
    549  *root = parser;
    550 
    551  return MediaHandler::Chain({std::move(parser), std::move(padder),
    552  std::move(cue_aligner), std::move(chunker),
    553  std::move(text_to_mp4), std::move(muxer)});
    554 }
    555 
    556 Status CreateTextJobs(
    557  const std::vector<std::reference_wrapper<const StreamDescriptor>>& streams,
    558  const PackagingParams& packaging_params,
    559  SyncPointQueue* sync_points,
    560  MuxerListenerFactory* muxer_listener_factory,
    561  MuxerFactory* muxer_factory,
    562  MpdNotifier* mpd_notifier,
    563  JobManager* job_manager) {
    564  DCHECK(muxer_listener_factory);
    565  DCHECK(job_manager);
    566  for (const StreamDescriptor& stream : streams) {
    567  // There are currently options:
    568  // TEXT TTML --> TEXT TTML [ supported ], for DASH only.
    569  // TEXT WEBVTT --> TEXT WEBVTT [ supported ]
    570  // TEXT WEBVTT --> MP4 WEBVTT [ supported ]
    571  // MP4 WEBVTT --> MP4 WEBVTT [ unsupported ]
    572  // MP4 WEBVTT --> TEXT WEBVTT [ unsupported ]
    573  const auto input_container = DetermineContainerFromFileName(stream.input);
    574  const auto output_container = GetOutputFormat(stream);
    575 
    576  if (input_container != CONTAINER_WEBVTT &&
    577  input_container != CONTAINER_TTML) {
    578  return Status(error::INVALID_ARGUMENT,
    579  "Text output format is not support for " + stream.input);
    580  }
    581 
    582  if (output_container == CONTAINER_MOV) {
    583  if (input_container == CONTAINER_TTML) {
    584  return Status(error::INVALID_ARGUMENT,
    585  "TTML in MP4 is not supported yet. Please follow "
    586  "https://github.com/google/shaka-packager/issues/87 for "
    587  "the updates.");
    588  }
    589 
    590  std::unique_ptr<MuxerListener> muxer_listener =
    591  muxer_listener_factory->CreateListener(ToMuxerListenerData(stream));
    592 
    593  std::shared_ptr<OriginHandler> root;
    594  RETURN_IF_ERROR(CreateWebVttToMp4TextJob(
    595  stream, packaging_params, std::move(muxer_listener), sync_points,
    596  muxer_factory, &root));
    597 
    598  job_manager->Add("MP4 text job", std::move(root));
    599  } else {
    600  std::unique_ptr<MuxerListener> hls_listener =
    601  muxer_listener_factory->CreateHlsListener(
    602  ToMuxerListenerData(stream));
    603 
    604  // Check input to ensure that output is possible.
    605  if (hls_listener) {
    606  if (input_container == CONTAINER_TTML) {
    607  return Status(error::INVALID_ARGUMENT,
    608  "HLS does not support TTML in xml format.");
    609  }
    610  if (stream.segment_template.empty() || !stream.output.empty()) {
    611  return Status(error::INVALID_ARGUMENT,
    612  "segment_template needs to be specified for HLS text "
    613  "output. Single file output is not supported yet.");
    614  }
    615  }
    616 
    617  if (mpd_notifier && !stream.segment_template.empty()) {
    618  return Status(error::INVALID_ARGUMENT,
    619  "Cannot create text output for MPD with segment output.");
    620  }
    621 
    622  // If we are outputting to HLS, then create the HLS test pipeline that
    623  // will create segmented text output.
    624  if (hls_listener) {
    625  RETURN_IF_ERROR(CreateHlsTextJob(stream, packaging_params,
    626  std::move(hls_listener), sync_points,
    627  job_manager));
    628  }
    629 
    630  if (!stream.output.empty()) {
    631  if (!File::Copy(stream.input.c_str(), stream.output.c_str())) {
    632  std::string error;
    633  base::StringAppendF(
    634  &error, "Failed to copy the input file (%s) to output file (%s).",
    635  stream.input.c_str(), stream.output.c_str());
    636  return Status(error::FILE_FAILURE, error);
    637  }
    638 
    639  MediaInfo text_media_info;
    640  if (!StreamInfoToTextMediaInfo(stream, &text_media_info)) {
    641  return Status(error::INVALID_ARGUMENT,
    642  "Could not create media info for stream.");
    643  }
    644 
    645  // If we are outputting to MPD, just add the input to the outputted
    646  // manifest.
    647  if (mpd_notifier) {
    648  uint32_t unused;
    649  if (mpd_notifier->NotifyNewContainer(text_media_info, &unused)) {
    650  mpd_notifier->Flush();
    651  } else {
    652  return Status(error::PARSER_FAILURE,
    653  "Failed to process text file " + stream.input);
    654  }
    655  }
    656 
    657  if (packaging_params.output_media_info) {
    659  text_media_info, stream.output + kMediaInfoSuffix);
    660  }
    661  }
    662  }
    663  }
    664 
    665  return Status::OK;
    666 }
    667 
    668 Status CreateAudioVideoJobs(
    669  const std::vector<std::reference_wrapper<const StreamDescriptor>>& streams,
    670  const PackagingParams& packaging_params,
    671  KeySource* encryption_key_source,
    672  SyncPointQueue* sync_points,
    673  MuxerListenerFactory* muxer_listener_factory,
    674  MuxerFactory* muxer_factory,
    675  JobManager* job_manager) {
    676  DCHECK(muxer_listener_factory);
    677  DCHECK(muxer_factory);
    678  DCHECK(job_manager);
    679  // Store all the demuxers in a map so that we can look up a stream's demuxer.
    680  // This is step one in making this part of the pipeline less dependant on
    681  // order.
    682  std::map<std::string, std::shared_ptr<Demuxer>> sources;
    683  std::map<std::string, std::shared_ptr<MediaHandler>> cue_aligners;
    684 
    685  for (const StreamDescriptor& stream : streams) {
    686  bool seen_input_before = sources.find(stream.input) != sources.end();
    687  if (seen_input_before) {
    688  continue;
    689  }
    690 
    691  RETURN_IF_ERROR(
    692  CreateDemuxer(stream, packaging_params, &sources[stream.input]));
    693  cue_aligners[stream.input] =
    694  sync_points ? std::make_shared<CueAlignmentHandler>(sync_points)
    695  : nullptr;
    696  }
    697 
    698  for (auto& source : sources) {
    699  job_manager->Add("RemuxJob", source.second);
    700  }
    701 
    702  // Replicators are shared among all streams with the same input and stream
    703  // selector.
    704  std::shared_ptr<MediaHandler> replicator;
    705 
    706  std::string previous_input;
    707  std::string previous_selector;
    708 
    709  for (const StreamDescriptor& stream : streams) {
    710  // Get the demuxer for this stream.
    711  auto& demuxer = sources[stream.input];
    712  auto& cue_aligner = cue_aligners[stream.input];
    713 
    714  const bool new_input_file = stream.input != previous_input;
    715  const bool new_stream =
    716  new_input_file || previous_selector != stream.stream_selector;
    717  previous_input = stream.input;
    718  previous_selector = stream.stream_selector;
    719 
    720  // If the stream has no output, then there is no reason setting-up the rest
    721  // of the pipeline.
    722  if (stream.output.empty() && stream.segment_template.empty()) {
    723  continue;
    724  }
    725 
    726  // Just because it is a different stream descriptor does not mean it is a
    727  // new stream. Multiple stream descriptors may have the same stream but
    728  // only differ by trick play factor.
    729  if (new_stream) {
    730  if (!stream.language.empty()) {
    731  demuxer->SetLanguageOverride(stream.stream_selector, stream.language);
    732  }
    733 
    734  replicator = std::make_shared<Replicator>();
    735  auto chunker =
    736  std::make_shared<ChunkingHandler>(packaging_params.chunking_params);
    737  auto encryptor = CreateEncryptionHandler(packaging_params, stream,
    738  encryption_key_source);
    739 
    740  // TODO(vaage) : Create a nicer way to connect handlers to demuxers.
    741  if (sync_points) {
    742  RETURN_IF_ERROR(
    743  MediaHandler::Chain({cue_aligner, chunker, encryptor, replicator}));
    744  RETURN_IF_ERROR(
    745  demuxer->SetHandler(stream.stream_selector, cue_aligner));
    746  } else {
    747  RETURN_IF_ERROR(MediaHandler::Chain({chunker, encryptor, replicator}));
    748  RETURN_IF_ERROR(demuxer->SetHandler(stream.stream_selector, chunker));
    749  }
    750  }
    751 
    752  // Create the muxer (output) for this track.
    753  std::shared_ptr<Muxer> muxer =
    754  muxer_factory->CreateMuxer(GetOutputFormat(stream), stream);
    755  if (!muxer) {
    756  return Status(error::INVALID_ARGUMENT, "Failed to create muxer for " +
    757  stream.input + ":" +
    758  stream.stream_selector);
    759  }
    760 
    761  std::unique_ptr<MuxerListener> muxer_listener =
    762  muxer_listener_factory->CreateListener(ToMuxerListenerData(stream));
    763  muxer->SetMuxerListener(std::move(muxer_listener));
    764 
    765  // Trick play is optional.
    766  std::shared_ptr<MediaHandler> trick_play =
    767  stream.trick_play_factor
    768  ? std::make_shared<TrickPlayHandler>(stream.trick_play_factor)
    769  : nullptr;
    770 
    771  RETURN_IF_ERROR(MediaHandler::Chain({replicator, trick_play, muxer}));
    772  }
    773 
    774  return Status::OK;
    775 }
    776 
    777 Status CreateAllJobs(const std::vector<StreamDescriptor>& stream_descriptors,
    778  const PackagingParams& packaging_params,
    779  MpdNotifier* mpd_notifier,
    780  KeySource* encryption_key_source,
    781  SyncPointQueue* sync_points,
    782  MuxerListenerFactory* muxer_listener_factory,
    783  MuxerFactory* muxer_factory,
    784  JobManager* job_manager) {
    785  DCHECK(muxer_factory);
    786  DCHECK(muxer_listener_factory);
    787  DCHECK(job_manager);
    788 
    789  // Group all streams based on which pipeline they will use.
    790  std::vector<std::reference_wrapper<const StreamDescriptor>> text_streams;
    791  std::vector<std::reference_wrapper<const StreamDescriptor>>
    792  audio_video_streams;
    793 
    794  bool has_transport_audio_video_streams = false;
    795  bool has_non_transport_audio_video_streams = false;
    796 
    797  for (const StreamDescriptor& stream : stream_descriptors) {
    798  // TODO: Find a better way to determine what stream type a stream
    799  // descriptor is as |stream_selector| may use an index. This would
    800  // also allow us to use a simpler audio pipeline.
    801  if (stream.stream_selector == "text") {
    802  text_streams.push_back(stream);
    803  } else {
    804  audio_video_streams.push_back(stream);
    805 
    806  switch (GetOutputFormat(stream)) {
    807  case CONTAINER_MPEG2TS:
    808  case CONTAINER_AAC:
    809  case CONTAINER_AC3:
    810  case CONTAINER_EAC3:
    811  has_transport_audio_video_streams = true;
    812  break;
    813  default:
    814  has_non_transport_audio_video_streams = true;
    815  break;
    816  }
    817  }
    818  }
    819 
    820  // Audio/Video streams need to be in sorted order so that demuxers and trick
    821  // play handlers get setup correctly.
    822  std::sort(audio_video_streams.begin(), audio_video_streams.end(),
    823  media::StreamDescriptorCompareFn);
    824 
    825  if (!text_streams.empty()) {
    826  PackagingParams text_packaging_params = packaging_params;
    827  if (text_packaging_params.transport_stream_timestamp_offset_ms > 0) {
    828  if (has_transport_audio_video_streams &&
    829  has_non_transport_audio_video_streams) {
    830  LOG(WARNING) << "There may be problems mixing transport streams and "
    831  "non-transport streams. For example, the subtitles may "
    832  "be out of sync with non-transport streams.";
    833  } else if (has_non_transport_audio_video_streams) {
    834  // Don't insert the X-TIMESTAMP-MAP in WebVTT if there is no transport
    835  // stream.
    836  text_packaging_params.transport_stream_timestamp_offset_ms = 0;
    837  }
    838  }
    839 
    840  RETURN_IF_ERROR(CreateTextJobs(text_streams, text_packaging_params,
    841  sync_points, muxer_listener_factory,
    842  muxer_factory, mpd_notifier, job_manager));
    843  }
    844 
    845  RETURN_IF_ERROR(CreateAudioVideoJobs(
    846  audio_video_streams, packaging_params, encryption_key_source, sync_points,
    847  muxer_listener_factory, muxer_factory, job_manager));
    848 
    849  // Initialize processing graph.
    850  return job_manager->InitializeJobs();
    851 }
    852 
    853 } // namespace
    854 } // namespace media
    855 
    856 struct Packager::PackagerInternal {
    857  media::FakeClock fake_clock;
    858  std::unique_ptr<KeySource> encryption_key_source;
    859  std::unique_ptr<MpdNotifier> mpd_notifier;
    860  std::unique_ptr<hls::HlsNotifier> hls_notifier;
    861  BufferCallbackParams buffer_callback_params;
    862  std::unique_ptr<media::JobManager> job_manager;
    863 };
    864 
    865 Packager::Packager() {}
    866 
    867 Packager::~Packager() {}
    868 
    870  const PackagingParams& packaging_params,
    871  const std::vector<StreamDescriptor>& stream_descriptors) {
    872  // Needed by base::WorkedPool used in ThreadedIoFile.
    873  static base::AtExitManager exit;
    874  static media::LibcryptoThreading libcrypto_threading;
    875 
    876  if (internal_)
    877  return Status(error::INVALID_ARGUMENT, "Already initialized.");
    878 
    879  RETURN_IF_ERROR(media::ValidateParams(packaging_params, stream_descriptors));
    880 
    881  if (!packaging_params.test_params.injected_library_version.empty()) {
    882  SetPackagerVersionForTesting(
    883  packaging_params.test_params.injected_library_version);
    884  }
    885 
    886  std::unique_ptr<PackagerInternal> internal(new PackagerInternal);
    887 
    888  // Create encryption key source if needed.
    889  if (packaging_params.encryption_params.key_provider != KeyProvider::kNone) {
    890  internal->encryption_key_source = CreateEncryptionKeySource(
    891  static_cast<media::FourCC>(
    892  packaging_params.encryption_params.protection_scheme),
    893  packaging_params.encryption_params);
    894  if (!internal->encryption_key_source)
    895  return Status(error::INVALID_ARGUMENT, "Failed to create key source.");
    896  }
    897 
    898  // Update MPD output and HLS output if needed.
    899  MpdParams mpd_params = packaging_params.mpd_params;
    900  HlsParams hls_params = packaging_params.hls_params;
    901 
    902  // |target_segment_duration| is needed for bandwidth estimation and also for
    903  // DASH approximate segment timeline.
    904  const double target_segment_duration =
    906  mpd_params.target_segment_duration = target_segment_duration;
    907  hls_params.target_segment_duration = target_segment_duration;
    908 
    909  // Store callback params to make it available during packaging.
    910  internal->buffer_callback_params = packaging_params.buffer_callback_params;
    911  if (internal->buffer_callback_params.write_func) {
    913  internal->buffer_callback_params, mpd_params.mpd_output);
    915  internal->buffer_callback_params, hls_params.master_playlist_output);
    916  }
    917 
    918  // Both DASH and HLS require language to follow RFC5646
    919  // (https://tools.ietf.org/html/rfc5646), which requires the language to be
    920  // in the shortest form.
    921  mpd_params.default_language =
    923  mpd_params.default_text_language =
    925  hls_params.default_language =
    927  hls_params.default_text_language =
    929 
    930  if (!mpd_params.mpd_output.empty()) {
    931  const bool on_demand_dash_profile =
    932  stream_descriptors.begin()->segment_template.empty();
    933  const MpdOptions mpd_options =
    934  media::GetMpdOptions(on_demand_dash_profile, mpd_params);
    935  internal->mpd_notifier.reset(new SimpleMpdNotifier(mpd_options));
    936  if (!internal->mpd_notifier->Init()) {
    937  LOG(ERROR) << "MpdNotifier failed to initialize.";
    938  return Status(error::INVALID_ARGUMENT,
    939  "Failed to initialize MpdNotifier.");
    940  }
    941  }
    942 
    943  if (!hls_params.master_playlist_output.empty()) {
    944  internal->hls_notifier.reset(new hls::SimpleHlsNotifier(hls_params));
    945  }
    946 
    947  std::unique_ptr<SyncPointQueue> sync_points;
    948  if (!packaging_params.ad_cue_generator_params.cue_points.empty()) {
    949  sync_points.reset(
    950  new SyncPointQueue(packaging_params.ad_cue_generator_params));
    951  }
    952  internal->job_manager.reset(new JobManager(std::move(sync_points)));
    953 
    954  std::vector<StreamDescriptor> streams_for_jobs;
    955 
    956  for (const StreamDescriptor& descriptor : stream_descriptors) {
    957  // We may need to overwrite some values, so make a copy first.
    958  StreamDescriptor copy = descriptor;
    959 
    960  if (internal->buffer_callback_params.read_func) {
    961  copy.input = File::MakeCallbackFileName(internal->buffer_callback_params,
    962  descriptor.input);
    963  }
    964 
    965  if (internal->buffer_callback_params.write_func) {
    966  copy.output = File::MakeCallbackFileName(internal->buffer_callback_params,
    967  descriptor.output);
    969  internal->buffer_callback_params, descriptor.segment_template);
    970  }
    971 
    972  // Update language to ISO_639_2 code if set.
    973  if (!copy.language.empty()) {
    974  copy.language = LanguageToISO_639_2(descriptor.language);
    975  if (copy.language == "und") {
    976  return Status(
    977  error::INVALID_ARGUMENT,
    978  "Unknown/invalid language specified: " + descriptor.language);
    979  }
    980  }
    981 
    982  streams_for_jobs.push_back(copy);
    983  }
    984 
    985  media::MuxerFactory muxer_factory(packaging_params);
    986  if (packaging_params.test_params.inject_fake_clock) {
    987  muxer_factory.OverrideClock(&internal->fake_clock);
    988  }
    989 
    990  media::MuxerListenerFactory muxer_listener_factory(
    991  packaging_params.output_media_info, internal->mpd_notifier.get(),
    992  internal->hls_notifier.get());
    993 
    994  RETURN_IF_ERROR(media::CreateAllJobs(
    995  streams_for_jobs, packaging_params, internal->mpd_notifier.get(),
    996  internal->encryption_key_source.get(),
    997  internal->job_manager->sync_points(), &muxer_listener_factory,
    998  &muxer_factory, internal->job_manager.get()));
    999 
    1000  internal_ = std::move(internal);
    1001  return Status::OK;
    1002 }
    1003 
    1005  if (!internal_)
    1006  return Status(error::INVALID_ARGUMENT, "Not yet initialized.");
    1007 
    1008  RETURN_IF_ERROR(internal_->job_manager->RunJobs());
    1009 
    1010  if (internal_->hls_notifier) {
    1011  if (!internal_->hls_notifier->Flush())
    1012  return Status(error::INVALID_ARGUMENT, "Failed to flush Hls.");
    1013  }
    1014  if (internal_->mpd_notifier) {
    1015  if (!internal_->mpd_notifier->Flush())
    1016  return Status(error::INVALID_ARGUMENT, "Failed to flush Mpd.");
    1017  }
    1018  return Status::OK;
    1019 }
    1020 
    1022  if (!internal_) {
    1023  LOG(INFO) << "Not yet initialized. Return directly.";
    1024  return;
    1025  }
    1026  internal_->job_manager->CancelJobs();
    1027 }
    1028 
    1030  return GetPackagerVersion();
    1031 }
    1032 
    1034  int max_sd_pixels,
    1035  int max_hd_pixels,
    1036  int max_uhd1_pixels,
    1037  const EncryptionParams::EncryptedStreamAttributes& stream_attributes) {
    1038  if (stream_attributes.stream_type ==
    1039  EncryptionParams::EncryptedStreamAttributes::kAudio)
    1040  return "AUDIO";
    1041  if (stream_attributes.stream_type ==
    1042  EncryptionParams::EncryptedStreamAttributes::kVideo) {
    1043  const int pixels = stream_attributes.oneof.video.width *
    1044  stream_attributes.oneof.video.height;
    1045  if (pixels <= max_sd_pixels)
    1046  return "SD";
    1047  if (pixels <= max_hd_pixels)
    1048  return "HD";
    1049  if (pixels <= max_uhd1_pixels)
    1050  return "UHD1";
    1051  return "UHD2";
    1052  }
    1053  return "";
    1054 }
    1055 
    1056 } // namespace shaka
    BufferCallbackParams buffer_callback_params
    Buffer callback params.
    Definition: packager.h:66
    -
    std::string master_playlist_output
    HLS master playlist output path.
    Definition: hls_params.h:27
    -
    DASH MPD related parameters.
    Definition: mpd_params.h:16
    -
    Defines a single input/output stream.
    Definition: packager.h:73
    -
    std::string input
    Input/source media file path or network stream URL. Required.
    Definition: packager.h:75
    -
    HlsParams hls_params
    HLS related parameters.
    Definition: packager.h:59
    -
    Status Initialize(const PackagingParams &packaging_params, const std::vector< StreamDescriptor > &stream_descriptors)
    Definition: packager.cc:869
    - -
    std::string default_language
    Definition: mpd_params.h:58
    -
    static std::string DefaultStreamLabelFunction(int max_sd_pixels, int max_hd_pixels, int max_uhd1_pixels, const EncryptionParams::EncryptedStreamAttributes &stream_attributes)
    Definition: packager.cc:1033
    -
    ChunkingParams chunking_params
    Chunking (segmentation) related parameters.
    Definition: packager.h:48
    -
    std::string default_text_language
    Definition: hls_params.h:53
    -
    std::vector< Cuepoint > cue_points
    List of cuepoints.
    -
    HLS related parameters.
    Definition: hls_params.h:23
    -
    std::string LanguageToShortestForm(const std::string &language)
    -
    std::string segment_template
    Specifies segment template. Can be empty.
    Definition: packager.h:85
    -
    static bool Copy(const char *from_file_name, const char *to_file_name)
    Definition: file.cc:281
    -
    static bool ReadFileToString(const char *file_name, std::string *contents)
    Definition: file.cc:216
    -
    bool inject_fake_clock
    Definition: packager.h:31
    -
    Convenience class which initializes and terminates libcrypto threading.
    -
    All the methods that are virtual are virtual for mocking.
    -
    static std::string GetLibraryVersion()
    Definition: packager.cc:1029
    -
    double target_segment_duration
    Definition: hls_params.h:58
    -
    std::string LanguageToISO_639_2(const std::string &language)
    - -
    std::string injected_library_version
    Definition: packager.h:34
    -
    MpdParams mpd_params
    DASH MPD related parameters.
    Definition: packager.h:57
    -
    AdCueGeneratorParams ad_cue_generator_params
    Out of band cuepoint parameters.
    Definition: packager.h:51
    - -
    static bool WriteMediaInfoToFile(const MediaInfo &media_info, const std::string &output_file_path)
    -
    EncryptionParams encryption_params
    Encryption and Decryption Parameters.
    Definition: packager.h:62
    - -
    std::string mpd_output
    MPD output file path.
    Definition: mpd_params.h:18
    -
    A synchronized queue for cue points.
    -
    Status Run()
    Definition: packager.cc:1004
    -
    static std::string MakeCallbackFileName(const BufferCallbackParams &callback_params, const std::string &name)
    Definition: file.cc:379
    -
    std::string output
    Definition: packager.h:83
    - -
    double target_segment_duration
    Definition: mpd_params.h:82
    - -
    Encrypted stream information that is used to determine stream label.
    -
    void OverrideClock(base::Clock *clock)
    -
    std::string default_language
    Definition: hls_params.h:50
    -
    double segment_duration_in_seconds
    Segment duration in seconds.
    -
    Defines Mpd Options.
    Definition: mpd_options.h:25
    -
    void Cancel()
    Cancel packaging. Note that it has to be called from another thread.
    Definition: packager.cc:1021
    -
    Packaging parameters.
    Definition: packager.h:38
    -
    static Status Open(const std::string &filename, std::unique_ptr< FileReader > *out)
    Definition: text_readers.cc:15
    - -
    std::string language
    Definition: packager.h:108
    - -
    std::string default_text_language
    Definition: mpd_params.h:61
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/packager.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/app/job_manager.h"
    +
    12 #include "packager/app/libcrypto_threading.h"
    +
    13 #include "packager/app/muxer_factory.h"
    +
    14 #include "packager/app/packager_util.h"
    +
    15 #include "packager/app/single_thread_job_manager.h"
    +
    16 #include "packager/app/stream_descriptor.h"
    +
    17 #include "packager/base/at_exit.h"
    +
    18 #include "packager/base/files/file_path.h"
    +
    19 #include "packager/base/logging.h"
    +
    20 #include "packager/base/optional.h"
    +
    21 #include "packager/base/path_service.h"
    +
    22 #include "packager/base/strings/string_util.h"
    +
    23 #include "packager/base/strings/stringprintf.h"
    +
    24 #include "packager/base/threading/simple_thread.h"
    +
    25 #include "packager/base/time/clock.h"
    +
    26 #include "packager/file/file.h"
    +
    27 #include "packager/hls/base/hls_notifier.h"
    +
    28 #include "packager/hls/base/simple_hls_notifier.h"
    +
    29 #include "packager/media/base/cc_stream_filter.h"
    +
    30 #include "packager/media/base/container_names.h"
    +
    31 #include "packager/media/base/fourccs.h"
    +
    32 #include "packager/media/base/key_source.h"
    +
    33 #include "packager/media/base/language_utils.h"
    +
    34 #include "packager/media/base/muxer.h"
    +
    35 #include "packager/media/base/muxer_options.h"
    +
    36 #include "packager/media/base/muxer_util.h"
    +
    37 #include "packager/media/chunking/chunking_handler.h"
    +
    38 #include "packager/media/chunking/cue_alignment_handler.h"
    +
    39 #include "packager/media/chunking/text_chunker.h"
    +
    40 #include "packager/media/crypto/encryption_handler.h"
    +
    41 #include "packager/media/demuxer/demuxer.h"
    +
    42 #include "packager/media/event/muxer_listener_factory.h"
    +
    43 #include "packager/media/event/vod_media_info_dump_muxer_listener.h"
    +
    44 #include "packager/media/formats/ttml/ttml_to_mp4_handler.h"
    +
    45 #include "packager/media/formats/webvtt/text_padder.h"
    +
    46 #include "packager/media/formats/webvtt/webvtt_to_mp4_handler.h"
    +
    47 #include "packager/media/replicator/replicator.h"
    +
    48 #include "packager/media/trick_play/trick_play_handler.h"
    +
    49 #include "packager/mpd/base/media_info.pb.h"
    +
    50 #include "packager/mpd/base/mpd_builder.h"
    +
    51 #include "packager/mpd/base/simple_mpd_notifier.h"
    +
    52 #include "packager/status_macros.h"
    +
    53 #include "packager/version/version.h"
    +
    54 
    +
    55 namespace shaka {
    +
    56 
    +
    57 // TODO(kqyang): Clean up namespaces.
    +
    58 using media::Demuxer;
    +
    59 using media::JobManager;
    +
    60 using media::KeySource;
    +
    61 using media::MuxerOptions;
    +
    62 using media::SingleThreadJobManager;
    +
    63 using media::SyncPointQueue;
    +
    64 
    +
    65 namespace media {
    +
    66 namespace {
    +
    67 
    +
    68 const char kMediaInfoSuffix[] = ".media_info";
    +
    69 
    +
    70 const int64_t kDefaultTextZeroBiasMs = 10 * 60 * 1000; // 10 minutes
    +
    71 
    +
    72 MuxerListenerFactory::StreamData ToMuxerListenerData(
    +
    73  const StreamDescriptor& stream) {
    +
    74  MuxerListenerFactory::StreamData data;
    +
    75  data.media_info_output = stream.output;
    +
    76 
    +
    77  data.hls_group_id = stream.hls_group_id;
    +
    78  data.hls_name = stream.hls_name;
    +
    79  data.hls_playlist_name = stream.hls_playlist_name;
    +
    80  data.hls_iframe_playlist_name = stream.hls_iframe_playlist_name;
    +
    81  data.hls_characteristics = stream.hls_characteristics;
    +
    82  data.hls_only = stream.hls_only;
    +
    83 
    +
    84  data.dash_accessiblities = stream.dash_accessiblities;
    +
    85  data.dash_roles = stream.dash_roles;
    +
    86  data.dash_only = stream.dash_only;
    +
    87  return data;
    +
    88 };
    +
    89 
    +
    90 // TODO(rkuroiwa): Write TTML and WebVTT parser (demuxing) for a better check
    +
    91 // and for supporting live/segmenting (muxing). With a demuxer and a muxer,
    +
    92 // CreateAllJobs() shouldn't treat text as a special case.
    +
    93 bool DetermineTextFileCodec(const std::string& file, std::string* out) {
    +
    94  CHECK(out);
    +
    95 
    +
    96  std::string content;
    +
    97  if (!File::ReadFileToString(file.c_str(), &content)) {
    +
    98  LOG(ERROR) << "Failed to open file " << file
    +
    99  << " to determine file format.";
    +
    100  return false;
    +
    101  }
    +
    102 
    +
    103  const uint8_t* content_data =
    +
    104  reinterpret_cast<const uint8_t*>(content.data());
    +
    105  MediaContainerName container_name =
    +
    106  DetermineContainer(content_data, content.size());
    +
    107 
    +
    108  if (container_name == CONTAINER_WEBVTT) {
    +
    109  *out = "wvtt";
    +
    110  return true;
    +
    111  }
    +
    112 
    +
    113  if (container_name == CONTAINER_TTML) {
    +
    114  *out = "ttml";
    +
    115  return true;
    +
    116  }
    +
    117 
    +
    118  return false;
    +
    119 }
    +
    120 
    +
    121 MediaContainerName GetOutputFormat(const StreamDescriptor& descriptor) {
    +
    122  if (!descriptor.output_format.empty()) {
    +
    123  MediaContainerName format =
    +
    124  DetermineContainerFromFormatName(descriptor.output_format);
    +
    125  if (format == CONTAINER_UNKNOWN) {
    +
    126  LOG(ERROR) << "Unable to determine output format from '"
    +
    127  << descriptor.output_format << "'.";
    +
    128  }
    +
    129  return format;
    +
    130  }
    +
    131 
    +
    132  base::Optional<MediaContainerName> format_from_output;
    +
    133  base::Optional<MediaContainerName> format_from_segment;
    +
    134  if (!descriptor.output.empty()) {
    +
    135  format_from_output = DetermineContainerFromFileName(descriptor.output);
    +
    136  if (format_from_output.value() == CONTAINER_UNKNOWN) {
    +
    137  LOG(ERROR) << "Unable to determine output format from '"
    +
    138  << descriptor.output << "'.";
    +
    139  }
    +
    140  }
    +
    141  if (!descriptor.segment_template.empty()) {
    +
    142  format_from_segment =
    +
    143  DetermineContainerFromFileName(descriptor.segment_template);
    +
    144  if (format_from_segment.value() == CONTAINER_UNKNOWN) {
    +
    145  LOG(ERROR) << "Unable to determine output format from '"
    +
    146  << descriptor.segment_template << "'.";
    +
    147  }
    +
    148  }
    +
    149 
    +
    150  if (format_from_output && format_from_segment) {
    +
    151  if (format_from_output.value() != format_from_segment.value()) {
    +
    152  LOG(ERROR) << "Output format determined from '" << descriptor.output
    +
    153  << "' differs from output format determined from '"
    +
    154  << descriptor.segment_template << "'.";
    +
    155  return CONTAINER_UNKNOWN;
    +
    156  }
    +
    157  }
    +
    158 
    +
    159  if (format_from_output)
    +
    160  return format_from_output.value();
    +
    161  if (format_from_segment)
    +
    162  return format_from_segment.value();
    +
    163  return CONTAINER_UNKNOWN;
    +
    164 }
    +
    165 
    +
    166 MediaContainerName GetTextOutputCodec(const StreamDescriptor& descriptor) {
    +
    167  const auto output_container = GetOutputFormat(descriptor);
    +
    168  if (output_container != CONTAINER_MOV)
    +
    169  return output_container;
    +
    170 
    +
    171  const auto input_container = DetermineContainerFromFileName(descriptor.input);
    +
    172  if (base::EqualsCaseInsensitiveASCII(descriptor.output_format, "vtt+mp4") ||
    +
    173  base::EqualsCaseInsensitiveASCII(descriptor.output_format,
    +
    174  "webvtt+mp4")) {
    +
    175  return CONTAINER_WEBVTT;
    +
    176  } else if (!base::EqualsCaseInsensitiveASCII(descriptor.output_format,
    +
    177  "ttml+mp4") &&
    +
    178  input_container == CONTAINER_WEBVTT) {
    +
    179  // With WebVTT input, default to WebVTT output.
    +
    180  return CONTAINER_WEBVTT;
    +
    181  } else {
    +
    182  // Otherwise default to TTML since it has more features.
    +
    183  return CONTAINER_TTML;
    +
    184  }
    +
    185 }
    +
    186 
    +
    187 bool IsTextStream(const StreamDescriptor& stream) {
    +
    188  if (stream.stream_selector == "text")
    +
    189  return true;
    +
    190  if (base::EqualsCaseInsensitiveASCII(stream.output_format, "vtt+mp4") ||
    +
    191  base::EqualsCaseInsensitiveASCII(stream.output_format, "webvtt+mp4") ||
    +
    192  base::EqualsCaseInsensitiveASCII(stream.output_format, "ttml+mp4")) {
    +
    193  return true;
    +
    194  }
    +
    195 
    +
    196  auto output_format = GetOutputFormat(stream);
    +
    197  return output_format == CONTAINER_WEBVTT || output_format == CONTAINER_TTML;
    +
    198 }
    +
    199 
    +
    200 Status ValidateStreamDescriptor(bool dump_stream_info,
    +
    201  const StreamDescriptor& stream) {
    +
    202  if (stream.input.empty()) {
    +
    203  return Status(error::INVALID_ARGUMENT, "Stream input not specified.");
    +
    204  }
    +
    205 
    +
    206  // The only time a stream can have no outputs, is when dump stream info is
    +
    207  // set.
    +
    208  if (dump_stream_info && stream.output.empty() &&
    +
    209  stream.segment_template.empty()) {
    +
    210  return Status::OK;
    +
    211  }
    +
    212 
    +
    213  if (stream.output.empty() && stream.segment_template.empty()) {
    +
    214  return Status(error::INVALID_ARGUMENT,
    +
    215  "Streams must specify 'output' or 'segment template'.");
    +
    216  }
    +
    217 
    +
    218  // Whenever there is output, a stream must be selected.
    +
    219  if (stream.stream_selector.empty()) {
    +
    220  return Status(error::INVALID_ARGUMENT,
    +
    221  "Stream stream_selector not specified.");
    +
    222  }
    +
    223 
    +
    224  // If a segment template is provided, it must be valid.
    +
    225  if (stream.segment_template.length()) {
    +
    226  RETURN_IF_ERROR(ValidateSegmentTemplate(stream.segment_template));
    +
    227  }
    +
    228 
    +
    229  // There are some specifics that must be checked based on which format
    +
    230  // we are writing to.
    +
    231  const MediaContainerName output_format = GetOutputFormat(stream);
    +
    232 
    +
    233  if (output_format == CONTAINER_UNKNOWN) {
    +
    234  return Status(error::INVALID_ARGUMENT, "Unsupported output format.");
    +
    235  }
    +
    236  if (output_format == MediaContainerName::CONTAINER_MPEG2TS) {
    +
    237  if (stream.segment_template.empty()) {
    +
    238  return Status(
    +
    239  error::INVALID_ARGUMENT,
    +
    240  "Please specify 'segment_template'. Single file TS output is "
    +
    241  "not supported.");
    +
    242  }
    +
    243 
    +
    244  // Right now the init segment is saved in |output| for multi-segment
    +
    245  // content. However, for TS all segments must be self-initializing so
    +
    246  // there cannot be an init segment.
    +
    247  if (stream.output.length()) {
    +
    248  return Status(error::INVALID_ARGUMENT,
    +
    249  "All TS segments must be self-initializing. Stream "
    +
    250  "descriptors 'output' or 'init_segment' are not allowed.");
    +
    251  }
    +
    252  } else if (output_format == CONTAINER_WEBVTT ||
    +
    253  output_format == CONTAINER_TTML ||
    +
    254  output_format == CONTAINER_AAC || output_format == CONTAINER_MP3 ||
    +
    255  output_format == CONTAINER_AC3 ||
    +
    256  output_format == CONTAINER_EAC3) {
    +
    257  // There is no need for an init segment when outputting because there is no
    +
    258  // initialization data.
    +
    259  if (stream.segment_template.length() && stream.output.length()) {
    +
    260  return Status(
    +
    261  error::INVALID_ARGUMENT,
    +
    262  "Segmented subtitles or PackedAudio output cannot have an init "
    +
    263  "segment. Do not specify stream descriptors 'output' or "
    +
    264  "'init_segment' when using 'segment_template'.");
    +
    265  }
    +
    266  } else {
    +
    267  // For any other format, if there is a segment template, there must be an
    +
    268  // init segment provided.
    +
    269  if (stream.segment_template.length() && stream.output.empty()) {
    +
    270  return Status(error::INVALID_ARGUMENT,
    +
    271  "Please specify 'init_segment'. All non-TS multi-segment "
    +
    272  "content must provide an init segment.");
    +
    273  }
    +
    274  }
    +
    275 
    +
    276  if (stream.output.find('$') != std::string::npos) {
    +
    277  if (output_format == CONTAINER_WEBVTT) {
    +
    278  return Status(
    +
    279  error::UNIMPLEMENTED,
    +
    280  "WebVTT output with one file per Representation per Period "
    +
    281  "is not supported yet. Please use fMP4 instead. If that needs to be "
    +
    282  "supported, please file a feature request on GitHub.");
    +
    283  }
    +
    284  // "$" is only allowed if the output file name is a template, which is
    +
    285  // used to support one file per Representation per Period when there are
    +
    286  // Ad Cues.
    +
    287  RETURN_IF_ERROR(ValidateSegmentTemplate(stream.output));
    +
    288  }
    +
    289 
    +
    290  return Status::OK;
    +
    291 }
    +
    292 
    +
    293 Status ValidateParams(const PackagingParams& packaging_params,
    +
    294  const std::vector<StreamDescriptor>& stream_descriptors) {
    +
    295  if (!packaging_params.chunking_params.segment_sap_aligned &&
    +
    296  packaging_params.chunking_params.subsegment_sap_aligned) {
    +
    297  return Status(error::INVALID_ARGUMENT,
    +
    298  "Setting segment_sap_aligned to false but "
    +
    299  "subsegment_sap_aligned to true is not allowed.");
    +
    300  }
    +
    301 
    +
    302  if (stream_descriptors.empty()) {
    +
    303  return Status(error::INVALID_ARGUMENT,
    +
    304  "Stream descriptors cannot be empty.");
    +
    305  }
    +
    306 
    +
    307  // On demand profile generates single file segment while live profile
    +
    308  // generates multiple segments specified using segment template.
    +
    309  const bool on_demand_dash_profile =
    +
    310  stream_descriptors.begin()->segment_template.empty();
    +
    311  std::set<std::string> outputs;
    +
    312  std::set<std::string> segment_templates;
    +
    313  for (const auto& descriptor : stream_descriptors) {
    +
    314  if (on_demand_dash_profile != descriptor.segment_template.empty()) {
    +
    315  return Status(error::INVALID_ARGUMENT,
    +
    316  "Inconsistent stream descriptor specification: "
    +
    317  "segment_template should be specified for none or all "
    +
    318  "stream descriptors.");
    +
    319  }
    +
    320 
    +
    321  RETURN_IF_ERROR(ValidateStreamDescriptor(
    +
    322  packaging_params.test_params.dump_stream_info, descriptor));
    +
    323 
    +
    324  if (base::StartsWith(descriptor.input, "udp://",
    +
    325  base::CompareCase::SENSITIVE)) {
    +
    326  const HlsParams& hls_params = packaging_params.hls_params;
    +
    327  if (!hls_params.master_playlist_output.empty() &&
    +
    328  hls_params.playlist_type == HlsPlaylistType::kVod) {
    +
    329  LOG(WARNING)
    +
    330  << "Seeing UDP input with HLS Playlist Type set to VOD. The "
    +
    331  "playlists will only be generated when UDP socket is closed. "
    +
    332  "If you want to do live packaging, --hls_playlist_type needs to "
    +
    333  "be set to LIVE.";
    +
    334  }
    +
    335  // Skip the check for DASH as DASH defaults to 'dynamic' MPD when segment
    +
    336  // template is provided.
    +
    337  }
    +
    338 
    +
    339  if (!descriptor.output.empty()) {
    +
    340  if (outputs.find(descriptor.output) != outputs.end()) {
    +
    341  return Status(
    +
    342  error::INVALID_ARGUMENT,
    +
    343  "Seeing duplicated outputs '" + descriptor.output +
    +
    344  "' in stream descriptors. Every output must be unique.");
    +
    345  }
    +
    346  outputs.insert(descriptor.output);
    +
    347  }
    +
    348  if (!descriptor.segment_template.empty()) {
    +
    349  if (segment_templates.find(descriptor.segment_template) !=
    +
    350  segment_templates.end()) {
    +
    351  return Status(error::INVALID_ARGUMENT,
    +
    352  "Seeing duplicated segment templates '" +
    +
    353  descriptor.segment_template +
    +
    354  "' in stream descriptors. Every segment template "
    +
    355  "must be unique.");
    +
    356  }
    +
    357  segment_templates.insert(descriptor.segment_template);
    +
    358  }
    +
    359  }
    +
    360 
    +
    361  if (packaging_params.output_media_info && !on_demand_dash_profile) {
    +
    362  // TODO(rkuroiwa, kqyang): Support partial media info dump for live.
    +
    363  return Status(error::UNIMPLEMENTED,
    +
    364  "--output_media_info is only supported for on-demand profile "
    +
    365  "(not using segment_template).");
    +
    366  }
    +
    367 
    +
    368  if (on_demand_dash_profile &&
    +
    369  !packaging_params.mpd_params.mpd_output.empty() &&
    +
    370  !packaging_params.mp4_output_params.generate_sidx_in_media_segments) {
    +
    371  return Status(error::UNIMPLEMENTED,
    +
    372  "--generate_sidx_in_media_segments is required for DASH "
    +
    373  "on-demand profile (not using segment_template).");
    +
    374  }
    +
    375 
    +
    376  return Status::OK;
    +
    377 }
    +
    378 
    +
    379 bool StreamDescriptorCompareFn(const StreamDescriptor& a,
    +
    380  const StreamDescriptor& b) {
    +
    381  // This function is used by std::sort() to sort the stream descriptors.
    +
    382  // Note that std::sort() need a comparator that return true iff the first
    +
    383  // argument is strictly lower than the second one. That is: must return false
    +
    384  // when they are equal. The requirement is enforced in gcc/g++ but not in
    +
    385  // clang.
    +
    386  if (a.input == b.input) {
    +
    387  if (a.stream_selector == b.stream_selector) {
    +
    388  // The MPD notifier requires that the main track comes first, so make
    +
    389  // sure that happens.
    +
    390  return a.trick_play_factor < b.trick_play_factor;
    +
    391  }
    +
    392  return a.stream_selector < b.stream_selector;
    +
    393  }
    +
    394 
    +
    395  return a.input < b.input;
    +
    396 }
    +
    397 
    +
    398 // A fake clock that always return time 0 (epoch). Should only be used for
    +
    399 // testing.
    +
    400 class FakeClock : public base::Clock {
    +
    401  public:
    +
    402  base::Time Now() override { return base::Time(); }
    +
    403 };
    +
    404 
    +
    405 bool StreamInfoToTextMediaInfo(const StreamDescriptor& stream_descriptor,
    +
    406  MediaInfo* text_media_info) {
    +
    407  std::string codec;
    +
    408  if (!DetermineTextFileCodec(stream_descriptor.input, &codec)) {
    +
    409  LOG(ERROR) << "Failed to determine the text file format for "
    +
    410  << stream_descriptor.input;
    +
    411  return false;
    +
    412  }
    +
    413 
    +
    414  MediaInfo::TextInfo* text_info = text_media_info->mutable_text_info();
    +
    415  text_info->set_codec(codec);
    +
    416 
    +
    417  const std::string& language = stream_descriptor.language;
    +
    418  if (!language.empty()) {
    +
    419  text_info->set_language(language);
    +
    420  }
    +
    421 
    +
    422  text_media_info->set_media_file_name(stream_descriptor.output);
    +
    423  text_media_info->set_container_type(MediaInfo::CONTAINER_TEXT);
    +
    424 
    +
    425  if (stream_descriptor.bandwidth != 0) {
    +
    426  text_media_info->set_bandwidth(stream_descriptor.bandwidth);
    +
    427  } else {
    +
    428  // Text files are usually small and since the input is one file; there's no
    +
    429  // way for the player to do ranged requests. So set this value to something
    +
    430  // reasonable.
    +
    431  const int kDefaultTextBandwidth = 256;
    +
    432  text_media_info->set_bandwidth(kDefaultTextBandwidth);
    +
    433  }
    +
    434 
    +
    435  if (!stream_descriptor.dash_roles.empty()) {
    +
    436  for (const auto& dash_role : stream_descriptor.dash_roles) {
    +
    437  text_media_info->add_dash_roles(dash_role);
    +
    438  }
    +
    439  }
    +
    440 
    +
    441  return true;
    +
    442 }
    +
    443 
    +
    447 Status CreateDemuxer(const StreamDescriptor& stream,
    +
    448  const PackagingParams& packaging_params,
    +
    449  std::shared_ptr<Demuxer>* new_demuxer) {
    +
    450  std::shared_ptr<Demuxer> demuxer = std::make_shared<Demuxer>(stream.input);
    +
    451  demuxer->set_dump_stream_info(packaging_params.test_params.dump_stream_info);
    +
    452 
    +
    453  if (packaging_params.decryption_params.key_provider != KeyProvider::kNone) {
    +
    454  std::unique_ptr<KeySource> decryption_key_source(
    +
    455  CreateDecryptionKeySource(packaging_params.decryption_params));
    +
    456  if (!decryption_key_source) {
    +
    457  return Status(
    +
    458  error::INVALID_ARGUMENT,
    +
    459  "Must define decryption key source when defining key provider");
    +
    460  }
    +
    461  demuxer->SetKeySource(std::move(decryption_key_source));
    +
    462  }
    +
    463 
    +
    464  *new_demuxer = std::move(demuxer);
    +
    465  return Status::OK;
    +
    466 }
    +
    467 
    +
    468 std::shared_ptr<MediaHandler> CreateEncryptionHandler(
    +
    469  const PackagingParams& packaging_params,
    +
    470  const StreamDescriptor& stream,
    +
    471  KeySource* key_source) {
    +
    472  if (stream.skip_encryption) {
    +
    473  return nullptr;
    +
    474  }
    +
    475 
    +
    476  if (!key_source) {
    +
    477  return nullptr;
    +
    478  }
    +
    479 
    +
    480  // Make a copy so that we can modify it for this specific stream.
    +
    481  EncryptionParams encryption_params = packaging_params.encryption_params;
    +
    482 
    +
    483  // Use Sample AES in MPEG2TS.
    +
    484  // TODO(kqyang): Consider adding a new flag to enable Sample AES as we
    +
    485  // will support CENC in TS in the future.
    +
    486  if (GetOutputFormat(stream) == CONTAINER_MPEG2TS ||
    +
    487  GetOutputFormat(stream) == CONTAINER_AAC ||
    +
    488  GetOutputFormat(stream) == CONTAINER_AC3 ||
    +
    489  GetOutputFormat(stream) == CONTAINER_EAC3) {
    +
    490  VLOG(1) << "Use Apple Sample AES encryption for MPEG2TS or Packed Audio.";
    +
    491  encryption_params.protection_scheme = kAppleSampleAesProtectionScheme;
    +
    492  }
    +
    493 
    +
    494  if (!stream.drm_label.empty()) {
    +
    495  const std::string& drm_label = stream.drm_label;
    +
    496  encryption_params.stream_label_func =
    +
    497  [drm_label](const EncryptionParams::EncryptedStreamAttributes&) {
    +
    498  return drm_label;
    +
    499  };
    +
    500  } else if (!encryption_params.stream_label_func) {
    +
    501  const int kDefaultMaxSdPixels = 768 * 576;
    +
    502  const int kDefaultMaxHdPixels = 1920 * 1080;
    +
    503  const int kDefaultMaxUhd1Pixels = 4096 * 2160;
    +
    504  encryption_params.stream_label_func = std::bind(
    +
    505  &Packager::DefaultStreamLabelFunction, kDefaultMaxSdPixels,
    +
    506  kDefaultMaxHdPixels, kDefaultMaxUhd1Pixels, std::placeholders::_1);
    +
    507  }
    +
    508 
    +
    509  return std::make_shared<EncryptionHandler>(encryption_params, key_source);
    +
    510 }
    +
    511 
    +
    512 std::unique_ptr<MediaHandler> CreateTextChunker(
    +
    513  const ChunkingParams& chunking_params) {
    +
    514  const float segment_length_in_seconds =
    +
    515  chunking_params.segment_duration_in_seconds;
    +
    516  return std::unique_ptr<MediaHandler>(
    +
    517  new TextChunker(segment_length_in_seconds));
    +
    518 }
    +
    519 
    +
    520 Status CreateTtmlJobs(
    +
    521  const std::vector<std::reference_wrapper<const StreamDescriptor>>& streams,
    +
    522  const PackagingParams& packaging_params,
    +
    523  SyncPointQueue* sync_points,
    +
    524  MuxerFactory* muxer_factory,
    +
    525  MpdNotifier* mpd_notifier,
    +
    526  JobManager* job_manager) {
    +
    527  DCHECK(job_manager);
    +
    528  for (const StreamDescriptor& stream : streams) {
    +
    529  // Check input to ensure that output is possible.
    +
    530  if (!packaging_params.hls_params.master_playlist_output.empty() &&
    +
    531  !stream.dash_only) {
    +
    532  return Status(error::INVALID_ARGUMENT,
    +
    533  "HLS does not support TTML in xml format.");
    +
    534  }
    +
    535 
    +
    536  if (!stream.segment_template.empty()) {
    +
    537  return Status(error::INVALID_ARGUMENT,
    +
    538  "Segmented TTML is not supported.");
    +
    539  }
    +
    540 
    +
    541  if (GetOutputFormat(stream) != CONTAINER_TTML) {
    +
    542  return Status(error::INVALID_ARGUMENT,
    +
    543  "Converting TTML to other formats is not supported");
    +
    544  }
    +
    545 
    +
    546  if (!stream.output.empty()) {
    +
    547  if (!File::Copy(stream.input.c_str(), stream.output.c_str())) {
    +
    548  std::string error;
    +
    549  base::StringAppendF(
    +
    550  &error, "Failed to copy the input file (%s) to output file (%s).",
    +
    551  stream.input.c_str(), stream.output.c_str());
    +
    552  return Status(error::FILE_FAILURE, error);
    +
    553  }
    +
    554 
    +
    555  MediaInfo text_media_info;
    +
    556  if (!StreamInfoToTextMediaInfo(stream, &text_media_info)) {
    +
    557  return Status(error::INVALID_ARGUMENT,
    +
    558  "Could not create media info for stream.");
    +
    559  }
    +
    560 
    +
    561  // If we are outputting to MPD, just add the input to the outputted
    +
    562  // manifest.
    +
    563  if (mpd_notifier) {
    +
    564  uint32_t unused;
    +
    565  if (mpd_notifier->NotifyNewContainer(text_media_info, &unused)) {
    +
    566  mpd_notifier->Flush();
    +
    567  } else {
    +
    568  return Status(error::PARSER_FAILURE,
    +
    569  "Failed to process text file " + stream.input);
    +
    570  }
    +
    571  }
    +
    572 
    +
    573  if (packaging_params.output_media_info) {
    + +
    575  text_media_info, stream.output + kMediaInfoSuffix);
    +
    576  }
    +
    577  }
    +
    578  }
    +
    579 
    +
    580  return Status::OK;
    +
    581 }
    +
    582 
    +
    583 Status CreateAudioVideoJobs(
    +
    584  const std::vector<std::reference_wrapper<const StreamDescriptor>>& streams,
    +
    585  const PackagingParams& packaging_params,
    +
    586  KeySource* encryption_key_source,
    +
    587  SyncPointQueue* sync_points,
    +
    588  MuxerListenerFactory* muxer_listener_factory,
    +
    589  MuxerFactory* muxer_factory,
    +
    590  JobManager* job_manager) {
    +
    591  DCHECK(muxer_listener_factory);
    +
    592  DCHECK(muxer_factory);
    +
    593  DCHECK(job_manager);
    +
    594  // Store all the demuxers in a map so that we can look up a stream's demuxer.
    +
    595  // This is step one in making this part of the pipeline less dependant on
    +
    596  // order.
    +
    597  std::map<std::string, std::shared_ptr<Demuxer>> sources;
    +
    598  std::map<std::string, std::shared_ptr<MediaHandler>> cue_aligners;
    +
    599 
    +
    600  for (const StreamDescriptor& stream : streams) {
    +
    601  bool seen_input_before = sources.find(stream.input) != sources.end();
    +
    602  if (seen_input_before) {
    +
    603  continue;
    +
    604  }
    +
    605 
    +
    606  RETURN_IF_ERROR(
    +
    607  CreateDemuxer(stream, packaging_params, &sources[stream.input]));
    +
    608  cue_aligners[stream.input] =
    +
    609  sync_points ? std::make_shared<CueAlignmentHandler>(sync_points)
    +
    610  : nullptr;
    +
    611  }
    +
    612 
    +
    613  for (auto& source : sources) {
    +
    614  job_manager->Add("RemuxJob", source.second);
    +
    615  }
    +
    616 
    +
    617  // Replicators are shared among all streams with the same input and stream
    +
    618  // selector.
    +
    619  std::shared_ptr<MediaHandler> replicator;
    +
    620 
    +
    621  std::string previous_input;
    +
    622  std::string previous_selector;
    +
    623 
    +
    624  for (const StreamDescriptor& stream : streams) {
    +
    625  // Get the demuxer for this stream.
    +
    626  auto& demuxer = sources[stream.input];
    +
    627  auto& cue_aligner = cue_aligners[stream.input];
    +
    628 
    +
    629  const bool new_input_file = stream.input != previous_input;
    +
    630  const bool new_stream =
    +
    631  new_input_file || previous_selector != stream.stream_selector;
    +
    632  const bool is_text = IsTextStream(stream);
    +
    633  previous_input = stream.input;
    +
    634  previous_selector = stream.stream_selector;
    +
    635 
    +
    636  // If the stream has no output, then there is no reason setting-up the rest
    +
    637  // of the pipeline.
    +
    638  if (stream.output.empty() && stream.segment_template.empty()) {
    +
    639  continue;
    +
    640  }
    +
    641 
    +
    642  // Just because it is a different stream descriptor does not mean it is a
    +
    643  // new stream. Multiple stream descriptors may have the same stream but
    +
    644  // only differ by trick play factor.
    +
    645  if (new_stream) {
    +
    646  if (!stream.language.empty()) {
    +
    647  demuxer->SetLanguageOverride(stream.stream_selector, stream.language);
    +
    648  }
    +
    649 
    +
    650  std::vector<std::shared_ptr<MediaHandler>> handlers;
    +
    651  if (is_text) {
    +
    652  handlers.emplace_back(
    +
    653  std::make_shared<TextPadder>(kDefaultTextZeroBiasMs));
    +
    654  }
    +
    655  if (sync_points) {
    +
    656  handlers.emplace_back(cue_aligner);
    +
    657  }
    +
    658  if (!is_text) {
    +
    659  handlers.emplace_back(std::make_shared<ChunkingHandler>(
    +
    660  packaging_params.chunking_params));
    +
    661  handlers.emplace_back(CreateEncryptionHandler(packaging_params, stream,
    +
    662  encryption_key_source));
    +
    663  }
    +
    664 
    +
    665  replicator = std::make_shared<Replicator>();
    +
    666  handlers.emplace_back(replicator);
    +
    667 
    +
    668  RETURN_IF_ERROR(MediaHandler::Chain(handlers));
    +
    669  RETURN_IF_ERROR(demuxer->SetHandler(stream.stream_selector, handlers[0]));
    +
    670  }
    +
    671 
    +
    672  // Create the muxer (output) for this track.
    +
    673  const auto output_format = GetOutputFormat(stream);
    +
    674  std::shared_ptr<Muxer> muxer =
    +
    675  muxer_factory->CreateMuxer(output_format, stream);
    +
    676  if (!muxer) {
    +
    677  return Status(error::INVALID_ARGUMENT, "Failed to create muxer for " +
    +
    678  stream.input + ":" +
    +
    679  stream.stream_selector);
    +
    680  }
    +
    681 
    +
    682  std::unique_ptr<MuxerListener> muxer_listener =
    +
    683  muxer_listener_factory->CreateListener(ToMuxerListenerData(stream));
    +
    684  muxer->SetMuxerListener(std::move(muxer_listener));
    +
    685 
    +
    686  std::vector<std::shared_ptr<MediaHandler>> handlers;
    +
    687  handlers.emplace_back(replicator);
    +
    688 
    +
    689  // Trick play is optional.
    +
    690  if (stream.trick_play_factor) {
    +
    691  handlers.emplace_back(
    +
    692  std::make_shared<TrickPlayHandler>(stream.trick_play_factor));
    +
    693  }
    +
    694 
    +
    695  if (stream.cc_index >= 0) {
    +
    696  handlers.emplace_back(
    +
    697  std::make_shared<CcStreamFilter>(stream.language, stream.cc_index));
    +
    698  }
    +
    699 
    +
    700  if (is_text &&
    +
    701  (!stream.segment_template.empty() || output_format == CONTAINER_MOV)) {
    +
    702  handlers.emplace_back(
    +
    703  CreateTextChunker(packaging_params.chunking_params));
    +
    704  }
    +
    705 
    +
    706  if (is_text && output_format == CONTAINER_MOV) {
    +
    707  const auto output_codec = GetTextOutputCodec(stream);
    +
    708  if (output_codec == CONTAINER_WEBVTT) {
    +
    709  handlers.emplace_back(std::make_shared<WebVttToMp4Handler>());
    +
    710  } else if (output_codec == CONTAINER_TTML) {
    +
    711  handlers.emplace_back(std::make_shared<ttml::TtmlToMp4Handler>());
    +
    712  }
    +
    713  }
    +
    714 
    +
    715  handlers.emplace_back(muxer);
    +
    716  RETURN_IF_ERROR(MediaHandler::Chain(handlers));
    +
    717  }
    +
    718 
    +
    719  return Status::OK;
    +
    720 }
    +
    721 
    +
    722 Status CreateAllJobs(const std::vector<StreamDescriptor>& stream_descriptors,
    +
    723  const PackagingParams& packaging_params,
    +
    724  MpdNotifier* mpd_notifier,
    +
    725  KeySource* encryption_key_source,
    +
    726  SyncPointQueue* sync_points,
    +
    727  MuxerListenerFactory* muxer_listener_factory,
    +
    728  MuxerFactory* muxer_factory,
    +
    729  JobManager* job_manager) {
    +
    730  DCHECK(muxer_factory);
    +
    731  DCHECK(muxer_listener_factory);
    +
    732  DCHECK(job_manager);
    +
    733 
    +
    734  // Group all streams based on which pipeline they will use.
    +
    735  std::vector<std::reference_wrapper<const StreamDescriptor>> ttml_streams;
    +
    736  std::vector<std::reference_wrapper<const StreamDescriptor>>
    +
    737  audio_video_streams;
    +
    738 
    +
    739  bool has_transport_audio_video_streams = false;
    +
    740  bool has_non_transport_audio_video_streams = false;
    +
    741 
    +
    742  for (const StreamDescriptor& stream : stream_descriptors) {
    +
    743  const auto input_container = DetermineContainerFromFileName(stream.input);
    +
    744  const auto output_format = GetOutputFormat(stream);
    +
    745  if (input_container == CONTAINER_TTML) {
    +
    746  ttml_streams.push_back(stream);
    +
    747  } else {
    +
    748  audio_video_streams.push_back(stream);
    +
    749  switch (output_format) {
    +
    750  case CONTAINER_MPEG2TS:
    +
    751  case CONTAINER_AAC:
    +
    752  case CONTAINER_MP3:
    +
    753  case CONTAINER_AC3:
    +
    754  case CONTAINER_EAC3:
    +
    755  has_transport_audio_video_streams = true;
    +
    756  break;
    +
    757  case CONTAINER_TTML:
    +
    758  case CONTAINER_WEBVTT:
    +
    759  break;
    +
    760  default:
    +
    761  has_non_transport_audio_video_streams = true;
    +
    762  break;
    +
    763  }
    +
    764  }
    +
    765  }
    +
    766 
    +
    767  // Audio/Video streams need to be in sorted order so that demuxers and trick
    +
    768  // play handlers get setup correctly.
    +
    769  std::sort(audio_video_streams.begin(), audio_video_streams.end(),
    +
    770  media::StreamDescriptorCompareFn);
    +
    771 
    +
    772  if (packaging_params.transport_stream_timestamp_offset_ms > 0) {
    +
    773  if (has_transport_audio_video_streams &&
    +
    774  has_non_transport_audio_video_streams) {
    +
    775  LOG(WARNING) << "There may be problems mixing transport streams and "
    +
    776  "non-transport streams. For example, the subtitles may "
    +
    777  "be out of sync with non-transport streams.";
    +
    778  } else if (has_non_transport_audio_video_streams) {
    +
    779  // Don't insert the X-TIMESTAMP-MAP in WebVTT if there is no transport
    +
    780  // stream.
    +
    781  muxer_factory->SetTsStreamOffset(0);
    +
    782  }
    +
    783  }
    +
    784 
    +
    785  RETURN_IF_ERROR(CreateTtmlJobs(ttml_streams, packaging_params, sync_points,
    +
    786  muxer_factory, mpd_notifier, job_manager));
    +
    787  RETURN_IF_ERROR(CreateAudioVideoJobs(
    +
    788  audio_video_streams, packaging_params, encryption_key_source, sync_points,
    +
    789  muxer_listener_factory, muxer_factory, job_manager));
    +
    790 
    +
    791  // Initialize processing graph.
    +
    792  return job_manager->InitializeJobs();
    +
    793 }
    +
    794 
    +
    795 } // namespace
    +
    796 } // namespace media
    +
    797 
    +
    798 struct Packager::PackagerInternal {
    +
    799  media::FakeClock fake_clock;
    +
    800  std::unique_ptr<KeySource> encryption_key_source;
    +
    801  std::unique_ptr<MpdNotifier> mpd_notifier;
    +
    802  std::unique_ptr<hls::HlsNotifier> hls_notifier;
    +
    803  BufferCallbackParams buffer_callback_params;
    +
    804  std::unique_ptr<media::JobManager> job_manager;
    +
    805 };
    +
    806 
    +
    807 Packager::Packager() {}
    +
    808 
    +
    809 Packager::~Packager() {}
    +
    810 
    + +
    812  const PackagingParams& packaging_params,
    +
    813  const std::vector<StreamDescriptor>& stream_descriptors) {
    +
    814  // Needed by base::WorkedPool used in ThreadedIoFile.
    +
    815  static base::AtExitManager exit;
    +
    816  static media::LibcryptoThreading libcrypto_threading;
    +
    817 
    +
    818  if (internal_)
    +
    819  return Status(error::INVALID_ARGUMENT, "Already initialized.");
    +
    820 
    +
    821  RETURN_IF_ERROR(media::ValidateParams(packaging_params, stream_descriptors));
    +
    822 
    +
    823  if (!packaging_params.test_params.injected_library_version.empty()) {
    +
    824  SetPackagerVersionForTesting(
    +
    825  packaging_params.test_params.injected_library_version);
    +
    826  }
    +
    827 
    +
    828  std::unique_ptr<PackagerInternal> internal(new PackagerInternal);
    +
    829 
    +
    830  // Create encryption key source if needed.
    +
    831  if (packaging_params.encryption_params.key_provider != KeyProvider::kNone) {
    +
    832  internal->encryption_key_source = CreateEncryptionKeySource(
    +
    833  static_cast<media::FourCC>(
    +
    834  packaging_params.encryption_params.protection_scheme),
    +
    835  packaging_params.encryption_params);
    +
    836  if (!internal->encryption_key_source)
    +
    837  return Status(error::INVALID_ARGUMENT, "Failed to create key source.");
    +
    838  }
    +
    839 
    +
    840  // Update MPD output and HLS output if needed.
    +
    841  MpdParams mpd_params = packaging_params.mpd_params;
    +
    842  HlsParams hls_params = packaging_params.hls_params;
    +
    843 
    +
    844  // |target_segment_duration| is needed for bandwidth estimation and also for
    +
    845  // DASH approximate segment timeline.
    +
    846  const double target_segment_duration =
    + +
    848  mpd_params.target_segment_duration = target_segment_duration;
    +
    849  hls_params.target_segment_duration = target_segment_duration;
    +
    850 
    +
    851  // Store callback params to make it available during packaging.
    +
    852  internal->buffer_callback_params = packaging_params.buffer_callback_params;
    +
    853  if (internal->buffer_callback_params.write_func) {
    + +
    855  internal->buffer_callback_params, mpd_params.mpd_output);
    + +
    857  internal->buffer_callback_params, hls_params.master_playlist_output);
    +
    858  }
    +
    859 
    +
    860  // Both DASH and HLS require language to follow RFC5646
    +
    861  // (https://tools.ietf.org/html/rfc5646), which requires the language to be
    +
    862  // in the shortest form.
    +
    863  mpd_params.default_language =
    + +
    865  mpd_params.default_text_language =
    + +
    867  hls_params.default_language =
    + +
    869  hls_params.default_text_language =
    + +
    871  hls_params.is_independent_segments =
    +
    872  packaging_params.chunking_params.segment_sap_aligned;
    +
    873 
    +
    874  if (!mpd_params.mpd_output.empty()) {
    +
    875  const bool on_demand_dash_profile =
    +
    876  stream_descriptors.begin()->segment_template.empty();
    +
    877  const MpdOptions mpd_options =
    +
    878  media::GetMpdOptions(on_demand_dash_profile, mpd_params);
    +
    879  internal->mpd_notifier.reset(new SimpleMpdNotifier(mpd_options));
    +
    880  if (!internal->mpd_notifier->Init()) {
    +
    881  LOG(ERROR) << "MpdNotifier failed to initialize.";
    +
    882  return Status(error::INVALID_ARGUMENT,
    +
    883  "Failed to initialize MpdNotifier.");
    +
    884  }
    +
    885  }
    +
    886 
    +
    887  if (!hls_params.master_playlist_output.empty()) {
    +
    888  internal->hls_notifier.reset(new hls::SimpleHlsNotifier(hls_params));
    +
    889  }
    +
    890 
    +
    891  std::unique_ptr<SyncPointQueue> sync_points;
    +
    892  if (!packaging_params.ad_cue_generator_params.cue_points.empty()) {
    +
    893  sync_points.reset(
    +
    894  new SyncPointQueue(packaging_params.ad_cue_generator_params));
    +
    895  }
    +
    896  if (packaging_params.single_threaded) {
    +
    897  internal->job_manager.reset(
    +
    898  new SingleThreadJobManager(std::move(sync_points)));
    +
    899  } else {
    +
    900  internal->job_manager.reset(new JobManager(std::move(sync_points)));
    +
    901  }
    +
    902 
    +
    903  std::vector<StreamDescriptor> streams_for_jobs;
    +
    904 
    +
    905  for (const StreamDescriptor& descriptor : stream_descriptors) {
    +
    906  // We may need to overwrite some values, so make a copy first.
    +
    907  StreamDescriptor copy = descriptor;
    +
    908 
    +
    909  if (internal->buffer_callback_params.read_func) {
    +
    910  copy.input = File::MakeCallbackFileName(internal->buffer_callback_params,
    +
    911  descriptor.input);
    +
    912  }
    +
    913 
    +
    914  if (internal->buffer_callback_params.write_func) {
    +
    915  copy.output = File::MakeCallbackFileName(internal->buffer_callback_params,
    +
    916  descriptor.output);
    + +
    918  internal->buffer_callback_params, descriptor.segment_template);
    +
    919  }
    +
    920 
    +
    921  // Update language to ISO_639_2 code if set.
    +
    922  if (!copy.language.empty()) {
    +
    923  copy.language = LanguageToISO_639_2(descriptor.language);
    +
    924  if (copy.language == "und") {
    +
    925  return Status(
    +
    926  error::INVALID_ARGUMENT,
    +
    927  "Unknown/invalid language specified: " + descriptor.language);
    +
    928  }
    +
    929  }
    +
    930 
    +
    931  streams_for_jobs.push_back(copy);
    +
    932  }
    +
    933 
    +
    934  media::MuxerFactory muxer_factory(packaging_params);
    +
    935  if (packaging_params.test_params.inject_fake_clock) {
    +
    936  muxer_factory.OverrideClock(&internal->fake_clock);
    +
    937  }
    +
    938 
    +
    939  media::MuxerListenerFactory muxer_listener_factory(
    +
    940  packaging_params.output_media_info, internal->mpd_notifier.get(),
    +
    941  internal->hls_notifier.get());
    +
    942 
    +
    943  RETURN_IF_ERROR(media::CreateAllJobs(
    +
    944  streams_for_jobs, packaging_params, internal->mpd_notifier.get(),
    +
    945  internal->encryption_key_source.get(),
    +
    946  internal->job_manager->sync_points(), &muxer_listener_factory,
    +
    947  &muxer_factory, internal->job_manager.get()));
    +
    948 
    +
    949  internal_ = std::move(internal);
    +
    950  return Status::OK;
    +
    951 }
    +
    952 
    + +
    954  if (!internal_)
    +
    955  return Status(error::INVALID_ARGUMENT, "Not yet initialized.");
    +
    956 
    +
    957  RETURN_IF_ERROR(internal_->job_manager->RunJobs());
    +
    958 
    +
    959  if (internal_->hls_notifier) {
    +
    960  if (!internal_->hls_notifier->Flush())
    +
    961  return Status(error::INVALID_ARGUMENT, "Failed to flush Hls.");
    +
    962  }
    +
    963  if (internal_->mpd_notifier) {
    +
    964  if (!internal_->mpd_notifier->Flush())
    +
    965  return Status(error::INVALID_ARGUMENT, "Failed to flush Mpd.");
    +
    966  }
    +
    967  return Status::OK;
    +
    968 }
    +
    969 
    + +
    971  if (!internal_) {
    +
    972  LOG(INFO) << "Not yet initialized. Return directly.";
    +
    973  return;
    +
    974  }
    +
    975  internal_->job_manager->CancelJobs();
    +
    976 }
    +
    977 
    + +
    979  return GetPackagerVersion();
    +
    980 }
    +
    981 
    + +
    983  int max_sd_pixels,
    +
    984  int max_hd_pixels,
    +
    985  int max_uhd1_pixels,
    +
    986  const EncryptionParams::EncryptedStreamAttributes& stream_attributes) {
    +
    987  if (stream_attributes.stream_type ==
    +
    988  EncryptionParams::EncryptedStreamAttributes::kAudio)
    +
    989  return "AUDIO";
    +
    990  if (stream_attributes.stream_type ==
    +
    991  EncryptionParams::EncryptedStreamAttributes::kVideo) {
    +
    992  const int pixels = stream_attributes.oneof.video.width *
    +
    993  stream_attributes.oneof.video.height;
    +
    994  if (pixels <= max_sd_pixels)
    +
    995  return "SD";
    +
    996  if (pixels <= max_hd_pixels)
    +
    997  return "HD";
    +
    998  if (pixels <= max_uhd1_pixels)
    +
    999  return "UHD1";
    +
    1000  return "UHD2";
    +
    1001  }
    +
    1002  return "";
    +
    1003 }
    +
    1004 
    +
    1005 } // namespace shaka
    +
    static std::string MakeCallbackFileName(const BufferCallbackParams &callback_params, const std::string &name)
    Definition: file.cc:399
    +
    static bool ReadFileToString(const char *file_name, std::string *contents)
    Definition: file.cc:230
    +
    static bool Copy(const char *from_file_name, const char *to_file_name)
    Definition: file.cc:297
    +
    Status Run()
    Definition: packager.cc:953
    +
    void Cancel()
    Cancel packaging. Note that it has to be called from another thread.
    Definition: packager.cc:970
    +
    static std::string DefaultStreamLabelFunction(int max_sd_pixels, int max_hd_pixels, int max_uhd1_pixels, const EncryptionParams::EncryptedStreamAttributes &stream_attributes)
    Definition: packager.cc:982
    +
    static std::string GetLibraryVersion()
    Definition: packager.cc:978
    +
    Status Initialize(const PackagingParams &packaging_params, const std::vector< StreamDescriptor > &stream_descriptors)
    Definition: packager.cc:811
    + + + + +
    Convenience class which initializes and terminates libcrypto threading.
    + +
    void OverrideClock(base::Clock *clock)
    + + +
    A synchronized queue for cue points.
    +
    static bool WriteMediaInfoToFile(const MediaInfo &media_info, const std::string &output_file_path)
    +
    All the methods that are virtual are virtual for mocking.
    +
    std::string LanguageToISO_639_2(const std::string &language)
    +
    std::string LanguageToShortestForm(const std::string &language)
    +
    std::vector< Cuepoint > cue_points
    List of cuepoints.
    +
    double segment_duration_in_seconds
    Segment duration in seconds.
    + +
    Encrypted stream information that is used to determine stream label.
    + +
    HLS related parameters.
    Definition: hls_params.h:23
    +
    std::string default_text_language
    Definition: hls_params.h:53
    +
    double target_segment_duration
    Definition: hls_params.h:61
    +
    std::string default_language
    Definition: hls_params.h:50
    +
    std::string master_playlist_output
    HLS master playlist output path.
    Definition: hls_params.h:27
    +
    Defines Mpd Options.
    Definition: mpd_options.h:25
    +
    DASH MPD related parameters.
    Definition: mpd_params.h:16
    +
    std::string default_language
    Definition: mpd_params.h:58
    +
    double target_segment_duration
    Definition: mpd_params.h:82
    +
    std::string mpd_output
    MPD output file path.
    Definition: mpd_params.h:18
    +
    std::string default_text_language
    Definition: mpd_params.h:61
    +
    Packaging parameters.
    Definition: packager.h:38
    +
    EncryptionParams encryption_params
    Encryption and Decryption Parameters.
    Definition: packager.h:65
    +
    HlsParams hls_params
    HLS related parameters.
    Definition: packager.h:62
    + +
    AdCueGeneratorParams ad_cue_generator_params
    Out of band cuepoint parameters.
    Definition: packager.h:51
    +
    BufferCallbackParams buffer_callback_params
    Buffer callback params.
    Definition: packager.h:69
    +
    ChunkingParams chunking_params
    Chunking (segmentation) related parameters.
    Definition: packager.h:48
    +
    MpdParams mpd_params
    DASH MPD related parameters.
    Definition: packager.h:60
    + +
    Defines a single input/output stream.
    Definition: packager.h:76
    +
    std::string output
    Definition: packager.h:86
    +
    std::string input
    Input/source media file path or network stream URL. Required.
    Definition: packager.h:78
    +
    std::string language
    Definition: packager.h:111
    +
    std::string segment_template
    Specifies segment template. Can be empty.
    Definition: packager.h:88
    +
    bool inject_fake_clock
    Definition: packager.h:31
    +
    std::string injected_library_version
    Definition: packager.h:34
    diff --git a/docs/d3/d51/classshaka_1_1media_1_1LibcryptoThreading.html b/docs/d3/d51/classshaka_1_1media_1_1LibcryptoThreading.html index 18c3501642..19de1ee71a 100644 --- a/docs/d3/d51/classshaka_1_1media_1_1LibcryptoThreading.html +++ b/docs/d3/d51/classshaka_1_1media_1_1LibcryptoThreading.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::LibcryptoThreading Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d3/d53/classshaka_1_1media_1_1JobManager.html b/docs/d3/d53/classshaka_1_1media_1_1JobManager.html index 3b670fbee6..842b349197 100644 --- a/docs/d3/d53/classshaka_1_1media_1_1JobManager.html +++ b/docs/d3/d53/classshaka_1_1media_1_1JobManager.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::JobManager Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::JobManager Class Reference
    +
    +Inheritance diagram for shaka::media::JobManager:
    +
    +
    + + +shaka::media::SingleThreadJobManager + +
    + + + +

    +Classes

    struct  JobEntry
     
    void  +virtual Status  +virtual Status  @@ -91,6 +110,27 @@ void  +

    Public Member Functions

    @@ -80,10 +99,10 @@ Public Member Functions
    Add (const std::string &name, std::shared_ptr< OriginHandler > handler)
     
    -Status InitializeJobs ()
    InitializeJobs ()
     
    -Status RunJobs ()
    RunJobs ()
     
    void CancelJobs ()
    CancelJobs () SyncPointQueuesync_points ()
     
    + + + + + +

    +Protected Member Functions

    JobManager (const JobManager &)=delete
     
    +JobManageroperator= (const JobManager &)=delete
     
    + + + + + + +

    +Protected Attributes

    +std::vector< JobEntryjob_entries_
     
    +std::vector< std::unique_ptr< Job > > jobs_
     
    +std::unique_ptr< SyncPointQueuesync_points_
     

    Detailed Description

    @@ -102,9 +142,7 @@ void CancelJobs () diff --git a/docs/d3/d53/classshaka_1_1media_1_1JobManager.png b/docs/d3/d53/classshaka_1_1media_1_1JobManager.png new file mode 100644 index 0000000000000000000000000000000000000000..4bfd5f11429718ac7b6921700b5564e3d0e17b7f GIT binary patch literal 863 zcmeAS@N?(olHy`uVBq!ia0vp^Z-F>~gBeI3I?f~pq$C1-LR|m<{|{uoc=NTi|Ih>= z3ycpOIKbL@M;^%KC<*clW&kPzfvcxNj2IZ0-g&w>hEy=Vo%^<^MS;h)|N6|@|L*Tr z)u?bp-@W!$#jiDfr@w2f=FXns+08B%{=W6@Hh~Hc8}I9r&lA{H0;{>pk_A zySE2!wX5X6zxqi?#@YsWYuNPv5e(_V)et zOLAQT4`$ri8ouS;Bi3c!76%glZkSY@cKOKSYgI)z7u5Ra*(#hVvz2_X;@;1DOn+A1 zc48TFESPZU35-hV3RGuP$JH5q#RbcGj|&YD_;0|##^~O z%__1%%XoL*;PaRn$zJ?o7Ekh~8{ubtZbi2>n&qtD{q5yJ<)~v5wjI2%tM`!kxkHYf zW!)(^dkkF{pV=!pW5a5@hlVdhUT5=M_CC$`jaQw&IQ)%dW5NDFo3n0@GmK|)ZrPK^ zcak@C?mOL8TP7`YI=6Vi*Gh}DxsPsz7HQ4)k+$-4l=g`^_Kk`;clcgl3>;hOb#A7waDPyl5e zH9YMDo@UA~E^XEGoWAPgmh(@yy}2=|WbP~f-x;djm*#`RQfkYjE6e9?`D}B({G#~r XT?WV16epht<^~2&S3j3^P6 + + + + + + +Shaka Packager SDK: shaka::media::TextFragment Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::TextFragment Struct Reference
    +
    +
    + +

    #include <text_sample.h>

    + + + + + + + + + + + + + + +

    +Public Member Functions

    TextFragment (const TextFragmentStyle &style, const std::vector< TextFragment > &sub_fragments)
     
    TextFragment (const TextFragmentStyle &style, const char *body)
     
    TextFragment (const TextFragmentStyle &style, const std::string &body)
     
    TextFragment (const TextFragmentStyle &style, const std::vector< uint8_t > &image)
     
    TextFragment (const TextFragmentStyle &style, bool newline)
     
    +bool is_empty () const
     
    + + + + + + + + + + + + +

    +Public Attributes

    +TextFragmentStyle style
     
    +std::vector< TextFragmentsub_fragments
     
    +std::string body
     
    +std::vector< uint8_t > image
     PNG image data.
     
    +bool newline = false
     
    +

    Detailed Description

    +

    Represents a recursive structure of styled blocks of text. Only one of sub_fragments, body, image, or newline will be set.

    + +

    Definition at line 89 of file text_sample.h.

    +

    The documentation for this struct was generated from the following files: +
    + + + + diff --git a/docs/d3/d56/decrypt__config_8cc_source.html b/docs/d3/d56/decrypt__config_8cc_source.html index abb9117be9..e90ab8e419 100644 --- a/docs/d3/d56/decrypt__config_8cc_source.html +++ b/docs/d3/d56/decrypt__config_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/decrypt_config.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    decrypt_config.cc
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/base/decrypt_config.h"
    6 
    7 #include "packager/base/logging.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 
    12 DecryptConfig::DecryptConfig(const std::vector<uint8_t>& key_id,
    13  const std::vector<uint8_t>& iv,
    14  const std::vector<SubsampleEntry>& subsamples)
    15  : DecryptConfig(key_id, iv, subsamples, FOURCC_cenc, 0, 0) {}
    16 
    17 DecryptConfig::DecryptConfig(const std::vector<uint8_t>& key_id,
    18  const std::vector<uint8_t>& iv,
    19  const std::vector<SubsampleEntry>& subsamples,
    20  FourCC protection_scheme,
    21  uint8_t crypt_byte_block,
    22  uint8_t skip_byte_block)
    23  : key_id_(key_id),
    24  iv_(iv),
    25  subsamples_(subsamples),
    26  protection_scheme_(protection_scheme),
    27  crypt_byte_block_(crypt_byte_block),
    28  skip_byte_block_(skip_byte_block) {
    29  CHECK_GT(key_id.size(), 0u);
    30 }
    31 
    32 DecryptConfig::~DecryptConfig() {}
    33 
    35  size_t size = 0;
    36  for (const SubsampleEntry& subsample : subsamples_)
    37  size += subsample.clear_bytes + subsample.cipher_bytes;
    38  return size;
    39 }
    40 
    41 } // namespace media
    42 } // namespace shaka
    DecryptConfig(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< SubsampleEntry > &subsamples)
    - - -
    All the methods that are virtual are virtual for mocking.
    -
    size_t GetTotalSizeOfSubsamples() const
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/base/decrypt_config.h"
    +
    6 
    +
    7 #include "packager/base/logging.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 
    +
    12 DecryptConfig::DecryptConfig(const std::vector<uint8_t>& key_id,
    +
    13  const std::vector<uint8_t>& iv,
    +
    14  const std::vector<SubsampleEntry>& subsamples)
    +
    15  : DecryptConfig(key_id, iv, subsamples, FOURCC_cenc, 0, 0) {}
    +
    16 
    +
    17 DecryptConfig::DecryptConfig(const std::vector<uint8_t>& key_id,
    +
    18  const std::vector<uint8_t>& iv,
    +
    19  const std::vector<SubsampleEntry>& subsamples,
    +
    20  FourCC protection_scheme,
    +
    21  uint8_t crypt_byte_block,
    +
    22  uint8_t skip_byte_block)
    +
    23  : key_id_(key_id),
    +
    24  iv_(iv),
    +
    25  subsamples_(subsamples),
    +
    26  protection_scheme_(protection_scheme),
    +
    27  crypt_byte_block_(crypt_byte_block),
    +
    28  skip_byte_block_(skip_byte_block) {
    +
    29  CHECK_GT(key_id.size(), 0u);
    +
    30 }
    +
    31 
    +
    32 DecryptConfig::~DecryptConfig() {}
    +
    33 
    + +
    35  size_t size = 0;
    +
    36  for (const SubsampleEntry& subsample : subsamples_)
    +
    37  size += subsample.clear_bytes + subsample.cipher_bytes;
    +
    38  return size;
    +
    39 }
    +
    40 
    +
    41 } // namespace media
    +
    42 } // namespace shaka
    + +
    DecryptConfig(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< SubsampleEntry > &subsamples)
    +
    size_t GetTotalSizeOfSubsamples() const
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/d3/d5f/sync__point__queue_8h_source.html b/docs/d3/d5f/sync__point__queue_8h_source.html index 715695e38d..3c34d92038 100644 --- a/docs/d3/d5f/sync__point__queue_8h_source.html +++ b/docs/d3/d5f/sync__point__queue_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking/sync_point_queue.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    sync_point_queue.h
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include <map>
    8 #include <memory>
    9 
    10 #include "packager/base/synchronization/condition_variable.h"
    11 #include "packager/base/synchronization/lock.h"
    12 #include "packager/media/public/ad_cue_generator_params.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 struct CueEvent;
    18 
    21  public:
    22  explicit SyncPointQueue(const AdCueGeneratorParams& params);
    23  ~SyncPointQueue() = default;
    24 
    27  void AddThread();
    28 
    30  void Cancel();
    31 
    36  double GetHint(double time_in_seconds);
    37 
    44  std::shared_ptr<const CueEvent> GetNext(double hint_in_seconds);
    45 
    48  std::shared_ptr<const CueEvent> PromoteAt(double time_in_seconds);
    49 
    53  bool HasMore(double hint_in_seconds) const;
    54 
    55  private:
    56  SyncPointQueue(const SyncPointQueue&) = delete;
    57  SyncPointQueue& operator=(const SyncPointQueue&) = delete;
    58 
    59  // PromoteAt() without locking. It is called by PromoteAt() and other
    60  // functions that have locks.
    61  std::shared_ptr<const CueEvent> PromoteAtNoLocking(double time_in_seconds);
    62 
    63  base::Lock lock_;
    64  base::ConditionVariable sync_condition_;
    65  size_t thread_count_ = 0;
    66  size_t waiting_thread_count_ = 0;
    67  bool cancelled_ = false;
    68 
    69  std::map<double, std::shared_ptr<CueEvent>> unpromoted_;
    70  std::map<double, std::shared_ptr<CueEvent>> promoted_;
    71 };
    72 
    73 } // namespace media
    74 } // namespace shaka
    -
    bool HasMore(double hint_in_seconds) const
    -
    All the methods that are virtual are virtual for mocking.
    -
    std::shared_ptr< const CueEvent > GetNext(double hint_in_seconds)
    -
    Cuepoint generator related parameters.
    -
    A synchronized queue for cue points.
    -
    std::shared_ptr< const CueEvent > PromoteAt(double time_in_seconds)
    -
    void Cancel()
    Cancel the queue and unblock all threads.
    -
    double GetHint(double time_in_seconds)
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include <map>
    +
    8 #include <memory>
    +
    9 
    +
    10 #include "packager/base/synchronization/condition_variable.h"
    +
    11 #include "packager/base/synchronization/lock.h"
    +
    12 #include "packager/media/public/ad_cue_generator_params.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 struct CueEvent;
    +
    18 
    + +
    21  public:
    +
    22  explicit SyncPointQueue(const AdCueGeneratorParams& params);
    +
    23  ~SyncPointQueue() = default;
    +
    24 
    +
    27  void AddThread();
    +
    28 
    +
    30  void Cancel();
    +
    31 
    +
    36  double GetHint(double time_in_seconds);
    +
    37 
    +
    44  std::shared_ptr<const CueEvent> GetNext(double hint_in_seconds);
    +
    45 
    +
    48  std::shared_ptr<const CueEvent> PromoteAt(double time_in_seconds);
    +
    49 
    +
    53  bool HasMore(double hint_in_seconds) const;
    +
    54 
    +
    55  private:
    +
    56  SyncPointQueue(const SyncPointQueue&) = delete;
    +
    57  SyncPointQueue& operator=(const SyncPointQueue&) = delete;
    +
    58 
    +
    59  // PromoteAt() without locking. It is called by PromoteAt() and other
    +
    60  // functions that have locks.
    +
    61  std::shared_ptr<const CueEvent> PromoteAtNoLocking(double time_in_seconds);
    +
    62 
    +
    63  base::Lock lock_;
    +
    64  base::ConditionVariable sync_condition_;
    +
    65  size_t thread_count_ = 0;
    +
    66  size_t waiting_thread_count_ = 0;
    +
    67  bool cancelled_ = false;
    +
    68 
    +
    69  std::map<double, std::shared_ptr<CueEvent>> unpromoted_;
    +
    70  std::map<double, std::shared_ptr<CueEvent>> promoted_;
    +
    71 };
    +
    72 
    +
    73 } // namespace media
    +
    74 } // namespace shaka
    +
    A synchronized queue for cue points.
    +
    std::shared_ptr< const CueEvent > PromoteAt(double time_in_seconds)
    +
    std::shared_ptr< const CueEvent > GetNext(double hint_in_seconds)
    +
    bool HasMore(double hint_in_seconds) const
    +
    void Cancel()
    Cancel the queue and unblock all threads.
    + +
    double GetHint(double time_in_seconds)
    +
    All the methods that are virtual are virtual for mocking.
    +
    Cuepoint generator related parameters.
    diff --git a/docs/d3/d62/continuity__counter_8h_source.html b/docs/d3/d62/continuity__counter_8h_source.html index c85376319e..b93fe01a78 100644 --- a/docs/d3/d62/continuity__counter_8h_source.html +++ b/docs/d3/d62/continuity__counter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/continuity_counter.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    continuity_counter.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_CONTINUITY_COUNTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_CONTINUITY_COUNTER_H_
    9 
    10 #include "packager/base/macros.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 namespace mp2t {
    15 
    17  public:
    20 
    24  int GetNext();
    25 
    26  private:
    27  int counter_ = 0;
    28  DISALLOW_COPY_AND_ASSIGN(ContinuityCounter);
    29 };
    30 
    31 } // namespace mp2t
    32 } // namespace media
    33 } // namespace shaka
    34 
    35 #endif // PACKAGER_MEDIA_FORMATS_MP2T_CONTINUITY_COUNTER_H_
    All the methods that are virtual are virtual for mocking.
    - - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_CONTINUITY_COUNTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_CONTINUITY_COUNTER_H_
    +
    9 
    +
    10 #include "packager/base/macros.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 namespace mp2t {
    +
    15 
    + +
    17  public:
    + + +
    20 
    +
    24  int GetNext();
    +
    25 
    +
    26  private:
    +
    27  int counter_ = 0;
    +
    28  DISALLOW_COPY_AND_ASSIGN(ContinuityCounter);
    +
    29 };
    +
    30 
    +
    31 } // namespace mp2t
    +
    32 } // namespace media
    +
    33 } // namespace shaka
    +
    34 
    +
    35 #endif // PACKAGER_MEDIA_FORMATS_MP2T_CONTINUITY_COUNTER_H_
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/d62/rcheck_8h_source.html b/docs/d3/d62/rcheck_8h_source.html index 4512e35b16..dd3e170edc 100644 --- a/docs/d3/d62/rcheck_8h_source.html +++ b/docs/d3/d62/rcheck_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/rcheck.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    rcheck.h
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_BASE_RCHECK_H_
    6 #define PACKAGER_MEDIA_BASE_RCHECK_H_
    7 
    8 #include "packager/base/logging.h"
    9 
    10 #define RCHECK(x) \
    11  do { \
    12  if (!(x)) { \
    13  LOG(ERROR) << "Failure while processing: " << #x; \
    14  return false; \
    15  } \
    16  } while (0)
    17 
    18 #endif // PACKAGER_MEDIA_BASE_RCHECK_H_
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_BASE_RCHECK_H_
    +
    6 #define PACKAGER_MEDIA_BASE_RCHECK_H_
    +
    7 
    +
    8 #include "packager/base/logging.h"
    +
    9 
    +
    10 #define RCHECK(x) \
    +
    11  do { \
    +
    12  if (!(x)) { \
    +
    13  LOG(ERROR) << "Failure while processing: " << #x; \
    +
    14  return false; \
    +
    15  } \
    +
    16  } while (0)
    +
    17 
    +
    18 #endif // PACKAGER_MEDIA_BASE_RCHECK_H_
    +
    diff --git a/docs/d3/d66/structshaka_1_1media_1_1mp4_1_1DataEntryUrl-members.html b/docs/d3/d66/structshaka_1_1media_1_1mp4_1_1DataEntryUrl-members.html index dc697a7a00..5b6bbcda0e 100644 --- a/docs/d3/d66/structshaka_1_1media_1_1mp4_1_1DataEntryUrl-members.html +++ b/docs/d3/d66/structshaka_1_1media_1_1mp4_1_1DataEntryUrl-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d3/d67/classshaka_1_1media_1_1WebMVideoClient.html b/docs/d3/d67/classshaka_1_1media_1_1WebMVideoClient.html index 5e4bb708c0..562f34c44d 100644 --- a/docs/d3/d67/classshaka_1_1media_1_1WebMVideoClient.html +++ b/docs/d3/d67/classshaka_1_1media_1_1WebMVideoClient.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMVideoClient Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::WebMParserClient - -
    + + @@ -148,7 +151,7 @@ Additional Inherited Members

    Public Member Functions

    -

    Create a VideoStreamInfo with the data in |track_num|, |codec_id|, |codec_private|, |is_encrypted| and the fields parsed from the last video track element this object was used to parse.

    Returns
    A VideoStreamInfo if successful.
    +

    Create a VideoStreamInfo with the data in |track_num|, |codec_id|, |codec_private|, |is_encrypted| and the fields parsed from the last video track element this object was used to parse.

    Returns
    A VideoStreamInfo if successful.
    An empty pointer if there was unexpected values in the provided parameters or video track element fields.
    @@ -171,7 +174,7 @@ An empty pointer if there was unexpected values in the provided parameters or vi
    -

    Extracts VPCodecConfigurationRecord parsed from codec private data and Colour element.

    +

    Extracts VPCodecConfigurationRecord parsed from codec private data and Colour element.

    Definition at line 130 of file webm_video_client.cc.

    @@ -184,9 +187,7 @@ An empty pointer if there was unexpected values in the provided parameters or vi
    diff --git a/docs/d3/d6e/structshaka_1_1MpdParams_1_1UtcTiming.html b/docs/d3/d6e/structshaka_1_1MpdParams_1_1UtcTiming.html index 7ba6d1fd3e..7ed5e8a0f2 100644 --- a/docs/d3/d6e/structshaka_1_1MpdParams_1_1UtcTiming.html +++ b/docs/d3/d6e/structshaka_1_1MpdParams_1_1UtcTiming.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MpdParams::UtcTiming Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    value
    diff --git a/docs/d3/d6f/ad__cue__generator__params_8h_source.html b/docs/d3/d6f/ad__cue__generator__params_8h_source.html index bb76bc340d..97fe363772 100644 --- a/docs/d3/d6f/ad__cue__generator__params_8h_source.html +++ b/docs/d3/d6f/ad__cue__generator__params_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/public/ad_cue_generator_params.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    ad_cue_generator_params.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_PUBLIC_AD_CUE_GENERATOR_PARAMS_H_
    8 #define PACKAGER_MEDIA_PUBLIC_AD_CUE_GENERATOR_PARAMS_H_
    9 
    10 #include <vector>
    11 
    12 namespace shaka {
    13 
    14 struct Cuepoint {
    17 
    19  double duration_in_seconds = 0;
    20 };
    21 
    25  std::vector<Cuepoint> cue_points;
    26 };
    27 
    28 } // namespace shaka
    29 
    30 #endif // PACKAGER_MEDIA_PUBLIC_AD_CUE_GENERATOR_PARAMS_H_
    -
    std::vector< Cuepoint > cue_points
    List of cuepoints.
    -
    All the methods that are virtual are virtual for mocking.
    -
    double duration_in_seconds
    Duration of the ad.
    -
    Cuepoint generator related parameters.
    -
    double start_time_in_seconds
    Start time of the cuepoint relative to start of the stream.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_PUBLIC_AD_CUE_GENERATOR_PARAMS_H_
    +
    8 #define PACKAGER_MEDIA_PUBLIC_AD_CUE_GENERATOR_PARAMS_H_
    +
    9 
    +
    10 #include <vector>
    +
    11 
    +
    12 namespace shaka {
    +
    13 
    +
    14 struct Cuepoint {
    + +
    17 
    +
    19  double duration_in_seconds = 0;
    +
    20 };
    +
    21 
    + +
    25  std::vector<Cuepoint> cue_points;
    +
    26 };
    +
    27 
    +
    28 } // namespace shaka
    +
    29 
    +
    30 #endif // PACKAGER_MEDIA_PUBLIC_AD_CUE_GENERATOR_PARAMS_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    Cuepoint generator related parameters.
    +
    std::vector< Cuepoint > cue_points
    List of cuepoints.
    + +
    double start_time_in_seconds
    Start time of the cuepoint relative to start of the stream.
    +
    double duration_in_seconds
    Duration of the ad.
    diff --git a/docs/d3/d71/classshaka_1_1media_1_1mp2t_1_1TsMuxer.html b/docs/d3/d71/classshaka_1_1media_1_1mp2t_1_1TsMuxer.html index 0c8926df9c..91b0a7998e 100644 --- a/docs/d3/d71/classshaka_1_1media_1_1mp2t_1_1TsMuxer.html +++ b/docs/d3/d71/classshaka_1_1media_1_1mp2t_1_1TsMuxer.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::TsMuxer Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::Muxer shaka::media::MediaHandler - -
    + + @@ -121,9 +124,9 @@ bool  - - + + @@ -208,9 +211,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/d3/d73/classshaka_1_1File.html b/docs/d3/d73/classshaka_1_1File.html index 9f8059abb0..148831da79 100644 --- a/docs/d3/d73/classshaka_1_1File.html +++ b/docs/d3/d73/classshaka_1_1File.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::File Class Reference @@ -29,18 +29,21 @@

    Public Member Functions

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::Muxer
    const MuxerOptionsoptions () const
    - + +/* @license-end */
    shaka::CallbackFile -shaka::LocalFile -shaka::MemoryFile -shaka::ThreadedIoFile -shaka::UdpFile - -
    +shaka::HttpFile +shaka::LocalFile +shaka::MemoryFile +shaka::ThreadedIoFile +shaka::UdpFile + + @@ -160,7 +164,7 @@ class 

    Public Member Functions

    ThreadedIoFile

    Detailed Description

    Define an abstract file interface.

    -

    Definition at line 26 of file file.h.

    +

    Definition at line 27 of file file.h.

    Constructor & Destructor Documentation

    ◆ ~File()

    @@ -186,7 +190,7 @@ class 
    ThreadedIoFile

    Do not call the destructor directly (with the "delete" keyword) nor use std::unique_ptr; instead use Close().

    -

    Definition at line 174 of file file.h.

    +

    Definition at line 175 of file file.h.

    @@ -213,9 +217,9 @@ class 
    ThreadedIoFile
    -

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.
    +

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.
    -

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::LocalFile, shaka::MemoryFile, and shaka::CallbackFile.

    +

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::MemoryFile, shaka::LocalFile, shaka::HttpFile, and shaka::CallbackFile.

    @@ -261,7 +265,7 @@ class ThreadedIoFile
    Returns
    true on success, false otherwise.
    -

    Definition at line 281 of file file.cc.

    +

    Definition at line 297 of file file.cc.

    @@ -307,7 +311,7 @@ class ThreadedIoFile
    Returns
    Number of bytes written, or a value < 0 on error.
    -

    Definition at line 316 of file file.cc.

    +

    Definition at line 333 of file file.cc.

    @@ -360,7 +364,7 @@ class ThreadedIoFile
    Returns
    Number of bytes written, or a value < 0 on error.
    -

    Definition at line 320 of file file.cc.

    +

    Definition at line 337 of file file.cc.

    @@ -395,7 +399,7 @@ class ThreadedIoFile
    Returns
    true if successful, false otherwise.
    -

    Definition at line 198 of file file.cc.

    +

    Definition at line 212 of file file.cc.

    @@ -423,7 +427,7 @@ class ThreadedIoFile
    Returns
    The file name. Note that the file type prefix has been stripped off.
    -

    Definition at line 94 of file file.h.

    +

    Definition at line 95 of file file.h.

    @@ -449,9 +453,9 @@ class ThreadedIoFile
    -

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.
    +

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.
    -

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::LocalFile, shaka::MemoryFile, and shaka::CallbackFile.

    +

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::MemoryFile, shaka::LocalFile, shaka::HttpFile, and shaka::CallbackFile.

    @@ -480,7 +484,7 @@ class ThreadedIoFile
    Returns
    The size of a file in bytes on success, a value < 0 otherwise. The file will be opened and closed in the process.
    -

    Definition at line 207 of file file.cc.

    +

    Definition at line 221 of file file.cc.

    @@ -515,7 +519,7 @@ class ThreadedIoFile
    Returns
    true if file_name is a local and regular file.
    -

    Definition at line 354 of file file.cc.

    +

    Definition at line 374 of file file.cc.

    @@ -554,13 +558,13 @@ class ThreadedIoFile

    Generate callback file name. NOTE: THE GENERATED NAME IS ONLY VAID WHILE callback_params IS VALID.

    Parameters
    - +
    callback_paramsreferences BufferCallbackParams, which will be embedded in the generated callback file name.
    callback_paramsreferences BufferCallbackParams, which will be embedded in the generated callback file name.
    nameis the name of the buffer, which will be embedded in the generated callback file name.
    -

    Definition at line 379 of file file.cc.

    +

    Definition at line 399 of file file.cc.

    @@ -597,16 +601,16 @@ class ThreadedIoFile
    -

    Open the specified file. This is a file factory method, it opens a proper file automatically based on prefix, e.g. "file://" for LocalFile.

    Parameters
    +

    Open the specified file. This is a file factory method, it opens a proper file automatically based on prefix, e.g. "file://" for LocalFile.

    Parameters
    file_namecontains the name of the file to be accessed.
    modecontains file access mode. Implementation dependent.
    -
    Returns
    A File pointer on success, false otherwise.
    +
    Returns
    A File pointer on success, false otherwise.
    -

    Definition at line 176 of file file.cc.

    +

    Definition at line 190 of file file.cc.

    @@ -643,16 +647,16 @@ class ThreadedIoFile
    -

    Open the specified file in direct-access mode (no buffering). This is a file factory method, it opens a proper file automatically based on prefix, e.g. "file://" for LocalFile.

    Parameters
    +

    Open the specified file in direct-access mode (no buffering). This is a file factory method, it opens a proper file automatically based on prefix, e.g. "file://" for LocalFile.

    Parameters
    file_namecontains the name of the file to be accessed.
    modecontains file access mode. Implementation dependent.
    -
    Returns
    A File pointer on success, false otherwise.
    +
    Returns
    A File pointer on success, false otherwise.
    -

    Definition at line 187 of file file.cc.

    +

    Definition at line 201 of file file.cc.

    @@ -698,14 +702,14 @@ class ThreadedIoFileParse and extract callback params.

    Parameters
    - +
    callback_file_nameis the name of the callback file which contains callback_params and name.
    callback_paramspoints to the parsed BufferCallbackParams pointer.
    callback_paramspoints to the parsed BufferCallbackParams pointer.
    namepoints to the parsed name.
    Returns
    true on success, false otherwise.
    -

    Definition at line 389 of file file.cc.

    +

    Definition at line 409 of file file.cc.

    @@ -751,7 +755,7 @@ class ThreadedIoFile
    Returns
    Number of bytes read, or a value < 0 on error. Zero on end-of-file, or if 'length' is zero.
    -

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::LocalFile, shaka::MemoryFile, and shaka::CallbackFile.

    +

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::MemoryFile, shaka::LocalFile, shaka::HttpFile, and shaka::CallbackFile.

    @@ -797,7 +801,7 @@ class ThreadedIoFile
    Returns
    true on success, false otherwise.
    -

    Definition at line 216 of file file.cc.

    +

    Definition at line 230 of file file.cc.

    @@ -832,7 +836,7 @@ class ThreadedIoFile
    Returns
    true on success, false otherwise.
    -

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::LocalFile, shaka::MemoryFile, and shaka::CallbackFile.

    +

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::MemoryFile, shaka::LocalFile, shaka::HttpFile, and shaka::CallbackFile.

    @@ -860,7 +864,7 @@ class ThreadedIoFile
    Returns
    Size of the file in bytes. A return value less than zero indicates a problem getting the size.
    -

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::LocalFile, shaka::MemoryFile, and shaka::CallbackFile.

    +

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::MemoryFile, shaka::LocalFile, shaka::HttpFile, and shaka::CallbackFile.

    @@ -895,7 +899,7 @@ class ThreadedIoFile
    Returns
    true on succcess, false otherwise.
    -

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::LocalFile, shaka::MemoryFile, and shaka::CallbackFile.

    +

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::MemoryFile, shaka::LocalFile, shaka::HttpFile, and shaka::CallbackFile.

    @@ -941,7 +945,7 @@ class ThreadedIoFile
    Returns
    Number of bytes written, or a value < 0 on error.
    -

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::LocalFile, shaka::MemoryFile, and shaka::CallbackFile.

    +

    Implemented in shaka::UdpFile, shaka::ThreadedIoFile, shaka::MemoryFile, shaka::LocalFile, shaka::HttpFile, and shaka::CallbackFile.

    @@ -987,7 +991,7 @@ class ThreadedIoFile
    Returns
    true on success, false otherwise.
    -

    Definition at line 262 of file file.cc.

    +

    Definition at line 277 of file file.cc.

    @@ -1033,7 +1037,7 @@ class ThreadedIoFile
    Returns
    true on success, false otherwise.
    -

    Definition at line 234 of file file.cc.

    +

    Definition at line 248 of file file.cc.

    @@ -1044,9 +1048,7 @@ class ThreadedIoFile diff --git a/docs/d3/d73/classshaka_1_1File.png b/docs/d3/d73/classshaka_1_1File.png index 30b2c5a71ef8cfbda44c3144e9bdfce7eb7a6b10..7bb97417b5f70edfc9f141306bb64d41f3ec0588 100644 GIT binary patch literal 1705 zcmchYdo-JO7{{ZgHN~2)b+4Qur6`ALn7T}tM1w@!GNn=C&?u^_R_kuV|) zT>S-=X}_thwx)?G@1HgWsqCB2S^K6155Be|O@F_QS!u@82U%`PDh3#Yx|-RAk@;+NmOgA(N%4uoisE`V|OnDA*b@6rVGo z=lUcX5cA@~YZ}_D`Q*#y~k zL{z@ccWgTu)FXz2t~fKTVpIBKwB;##PVMG^Gh>!XqE$M>^tx9uZ71u z-p9Bq0bSWaext4e=x!@?d2dr#Bzc#-6kQ^Y?ZxR{+o9%Apg3C_t0Z^s{g*&~zyK5y z+0j2H7aJYuy_2s~T<$@E`62s&0?-20 zjePJDFt$7Y)3(Vyj3_E|yDO2(oKE*e_S>OT1w<~RElK$h&7rbOBR@+Hu8Na zKwePP9a|5IOGLg2Pyy;i8HrNntqVobvjZu1hZrW)en`}da-#wh^k+$w`}=&!kCts> z@7B%3R*iSOM@wr!{~(R^FiA9EAg|e?7P^}RH3LjxjewV)UJ=43 z)x%j9beK~KPWMXw=|1;{Mfx107ZKCCisjckeh4;#4X%tI;Dl8w8zrQ_f_5GhMbdMJ z<99(jsUiFj{PJP2=%u^GZO`TL5bL4#xN$3so{m8yAvdyQynZ9fr@UQtbg1u`Y|Of; z#d1!21xj(sQ(~mH2jxd3t``OL60s3l94X@R^`@caKZ{O2C3;C1$q<^$z?roEWzi|= z^%3nQ;j*Oa$?A&GSE7~WZpGR?Zl6R|@8VX9aF?xjb$LYB*fq(52>6>On_RNiEtr^M=x@ocfCFPFx3sx!`eIraYnr7^rRLe zN=qi+9497-WbKLf4`#w+p3lKr3qCdOd$7o-Dj>eQL|hTzN(eXi1_#GE#c|QxNInw& zR+-SAV=tUwI6Wqhz>Z0Y&;^?>VH z&u%q);=mC-T;pW)re;t_wB(mM(ldAvxXJ#5`>LhoF34ZnOFl>DlQ*W;!<^ZVlRB%m zgzqFL`9a6X)iGv ztHQB~z+i*Ho)pcQtd{43ey5Z%>5AUe=;os>QzO_^L*8&HoYKLGedNjfShNy!iIh;$ z{FrD)5c$PC`e_6lJl4OlQroqP<~Wnj)o)L35TUh(rR1~eDUBbJX?cs>I661JkSq=I ztQ2|EiwWUr)!u~ z>$x(RoF%TUkC|S*?M;!Rhu>L~!|@Ev7ZN4f9!fJ9Ft9y1UeoC*CUt;ePkSqy0mJkI zPRtSw-U$mCc@C&kiia)k>R?Am_6utl0-}-OmBCsy^YfFCL*&F-k z$1eUyFRvZHUa~Gy_XlT!JU4Fw!#(B9ODQkzoVH?PzRZ%-3Vv`zPHwA`;@`gbc}<;Mh;ik{pM~NF1i|h*K7B?C zSO>`30#1;5J6J$6F-#yQ>NR5cTB0rS2O9$q(AZEn2Id5Ye^y}SjfGn-0$s@jHitFO z?l#C9-#3C>t`w0@q}h-Vg*oMbe4@hU_r1DVMS8J*^EEa(?zY}sMLPzz$V zvT=}a(0NzksX?c9_bi?ANzE_BOS5*)iYYGel#xF-2e=_}e07<#d8(_R;M$7NI7n`LH)#;KPro-1S( zzW!%TQnBZ)55Wsx?+td6m;7$HusHmm^up=wk(2l={k{b+-2Qjc5>wlS-`D->xbU*C z)yaNUef5mxN1rb~?)B9pZ{B>b7r(Y$_4l1S>*GA#vpX|Mf>ninVgrr&}e#^M5USxuS2cu&!;}r?s>F!mOTJi*ee%{=TUos^Vsbarf=b zt8a&uZ(m#^`g(`S^F?c&kNAfPs7%(7T{^L1*V0L;?@BaErsT}lkbLq}pmnxc_nU1- zJ<~*f`Mh40eZDNm{l#^&(?-4fZr{AmvMO)&@hfk4MxA{;{C za_qggBkxt>rhped6RLi!y;1q@w#e>_pPZIQZ||M>E<)u?_Nnua|8D)d=iRE1&#Jl8 zrxj1VurPFai=B9`ZS<-ce-&1`ywvDE``NA9iCurALgWMuaTTGei%)K@R(tC8VsD1$ z!t-17YW5V#a<}q@$Jkz4U4Jb$t9j46y!+CVUiq&wQ3rZ!&Gvh|lYFN1d=ja8o@(~p zAas#MpxTLZE%$5!61P^lp604uRO;^J9n`+{f^}M6+TXJGKNr5fvp4epoC_y2cF*-< zJE>wNnEHItlncj&t!}T2c=2uCi;U|li-kc!@%Mb0&YTOcrypK@>wI(O{mM_*)AR3N z-Ff`_rm)#r|6V?6Ip@0i-cs*rp=avAF?H3|H~3l1+PuFhj*CimUvt{tx^w+yk+r@X zrFE?rPBx4W3I#%J?B4Y?(Dm_`2Tq+)zwNXf!W5B>u1cOoaZ`QRK9M! zFiGUoMwgezA~O(a_Pn`TQKpLK0rcbxQvAqe(v{;tk9N#f^{k!aG3nQx7QLlY^cQIP kYA&r|1ZR?c`WNfdS|{CS&4~XCETI`ZUHx3vIVCg!0Muc=O8@`> diff --git a/docs/d3/d73/classshaka_1_1media_1_1webm_1_1WebMMuxer.html b/docs/d3/d73/classshaka_1_1media_1_1webm_1_1WebMMuxer.html index bb47d3efd1..e5beac0bd7 100644 --- a/docs/d3/d73/classshaka_1_1media_1_1webm_1_1WebMMuxer.html +++ b/docs/d3/d73/classshaka_1_1media_1_1webm_1_1WebMMuxer.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::webm::WebMMuxer Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::Muxer shaka::media::MediaHandler - -
    + + - + - - + + @@ -212,9 +215,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/d3/d75/classshaka_1_1media_1_1AesEncryptor.html b/docs/d3/d75/classshaka_1_1media_1_1AesEncryptor.html index 09f3945993..b13ef720e9 100644 --- a/docs/d3/d75/classshaka_1_1media_1_1AesEncryptor.html +++ b/docs/d3/d75/classshaka_1_1media_1_1AesEncryptor.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::AesEncryptor Class Reference @@ -29,18 +29,21 @@

    Public Member Functions

     WebMMuxer (const MuxerOptions &options)
     Create a WebMMuxer object from MuxerOptions.
     Create a WebMMuxer object from MuxerOptions.
     
    - Public Member Functions inherited from shaka::media::Muxer
    @@ -125,9 +128,9 @@ bool 

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::Muxer
    const MuxerOptionsoptions () const
    - + +/* @license-end */
    shaka::media::AesCryptor shaka::media::AesCbcEncryptor shaka::media::AesCtrEncryptor - -
    + + @@ -113,8 +116,8 @@ bool  - @@ -215,9 +218,7 @@ AES_KEY * 

    Public Member Functions

    Crypt (const uint

    Additional Inherited Members

    - Public Types inherited from shaka::media::AesCryptor
    enum  ConstantIvFlag { kUseConstantIv, -kDontUseConstantIv +
    enum  ConstantIvFlag { kUseConstantIv +, kDontUseConstantIv }
     
    - Static Public Member Functions inherited from shaka::media::AesCryptor
    mutable_aes_key< diff --git a/docs/d3/d75/classshaka_1_1media_1_1mp4_1_1ChunkInfoIterator-members.html b/docs/d3/d75/classshaka_1_1media_1_1mp4_1_1ChunkInfoIterator-members.html index fd5b353b85..36cd6cdecd 100644 --- a/docs/d3/d75/classshaka_1_1media_1_1mp4_1_1ChunkInfoIterator-members.html +++ b/docs/d3/d75/classshaka_1_1media_1_1mp4_1_1ChunkInfoIterator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d3/d76/muxer__flags_8h_source.html b/docs/d3/d76/muxer__flags_8h_source.html index 774b21a43b..02dd3f721d 100644 --- a/docs/d3/d76/muxer__flags_8h_source.html +++ b/docs/d3/d76/muxer__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/muxer_flags.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    muxer_flags.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Defines Muxer flags.
    8 
    9 #ifndef APP_MUXER_FLAGS_H_
    10 #define APP_MUXER_FLAGS_H_
    11 
    12 #include <gflags/gflags.h>
    13 
    14 DECLARE_double(clear_lead);
    15 DECLARE_double(segment_duration);
    16 DECLARE_bool(segment_sap_aligned);
    17 DECLARE_double(fragment_duration);
    18 DECLARE_bool(fragment_sap_aligned);
    19 DECLARE_bool(generate_sidx_in_media_segments);
    20 DECLARE_string(temp_dir);
    21 DECLARE_bool(mp4_include_pssh_in_stream);
    22 DECLARE_int32(transport_stream_timestamp_offset_ms);
    23 
    24 #endif // APP_MUXER_FLAGS_H_
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Defines Muxer flags.
    +
    8 
    +
    9 #ifndef APP_MUXER_FLAGS_H_
    +
    10 #define APP_MUXER_FLAGS_H_
    +
    11 
    +
    12 #include <gflags/gflags.h>
    +
    13 
    +
    14 DECLARE_double(clear_lead);
    +
    15 DECLARE_double(segment_duration);
    +
    16 DECLARE_bool(segment_sap_aligned);
    +
    17 DECLARE_double(fragment_duration);
    +
    18 DECLARE_bool(fragment_sap_aligned);
    +
    19 DECLARE_bool(generate_sidx_in_media_segments);
    +
    20 DECLARE_string(temp_dir);
    +
    21 DECLARE_bool(mp4_include_pssh_in_stream);
    +
    22 DECLARE_int32(transport_stream_timestamp_offset_ms);
    +
    23 
    +
    24 #endif // APP_MUXER_FLAGS_H_
    +
    diff --git a/docs/d3/d77/structshaka_1_1media_1_1mp4_1_1TextSampleEntry-members.html b/docs/d3/d77/structshaka_1_1media_1_1mp4_1_1TextSampleEntry-members.html index 406b3ae292..5b4ae92f4c 100644 --- a/docs/d3/d77/structshaka_1_1media_1_1mp4_1_1TextSampleEntry-members.html +++ b/docs/d3/d77/structshaka_1_1media_1_1mp4_1_1TextSampleEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */ diff --git a/docs/d3/d7a/ttml__muxer_8h_source.html b/docs/d3/d7a/ttml__muxer_8h_source.html new file mode 100644 index 0000000000..1afed487d5 --- /dev/null +++ b/docs/d3/d7a/ttml__muxer_8h_source.html @@ -0,0 +1,120 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/ttml/ttml_muxer.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    ttml_muxer.h
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_TTML_TTML_MUXER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_TTML_TTML_MUXER_H_
    +
    9 
    +
    10 #include "packager/media/base/text_muxer.h"
    +
    11 #include "packager/media/formats/ttml/ttml_generator.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace ttml {
    +
    16 
    +
    17 class TtmlMuxer : public TextMuxer {
    +
    18  public:
    +
    19  explicit TtmlMuxer(const MuxerOptions& options);
    +
    20  ~TtmlMuxer() override;
    +
    21 
    +
    22  private:
    +
    23  Status InitializeStream(TextStreamInfo* stream) override;
    +
    24  Status AddTextSampleInternal(const TextSample& sample) override;
    +
    25  Status WriteToFile(const std::string& filename, uint64_t* size) override;
    +
    26 
    +
    27  TtmlGenerator generator_;
    +
    28 };
    +
    29 
    +
    30 } // namespace ttml
    +
    31 } // namespace media
    +
    32 } // namespace shaka
    +
    33 
    +
    34 #endif // PACKAGER_MEDIA_FORMATS_TTML_TTML_MUXER_H_
    + + + + + + +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    + + + + diff --git a/docs/d3/d7b/classshaka_1_1media_1_1RsaPublicKey-members.html b/docs/d3/d7b/classshaka_1_1media_1_1RsaPublicKey-members.html index c2a00f539a..ae9a8f1da2 100644 --- a/docs/d3/d7b/classshaka_1_1media_1_1RsaPublicKey-members.html +++ b/docs/d3/d7b/classshaka_1_1media_1_1RsaPublicKey-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d3/d7c/classshaka_1_1media_1_1WebMAudioClient.html b/docs/d3/d7c/classshaka_1_1media_1_1WebMAudioClient.html index f0a8948633..95c570a443 100644 --- a/docs/d3/d7c/classshaka_1_1media_1_1WebMAudioClient.html +++ b/docs/d3/d7c/classshaka_1_1media_1_1WebMAudioClient.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMAudioClient Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::WebMParserClient - -
    + + @@ -173,7 +176,7 @@ Additional Inherited Members

    Public Member Functions

    -

    Create an AudioStreamInfo with the parameters specified.

    Parameters
    +

    Create an AudioStreamInfo with the parameters specified.

    Parameters
    @@ -185,7 +188,7 @@ Additional Inherited Members
    track_numindicates the track number.
    codec_idis the codec identifier.
    -
    Returns
    An AudioStreamInfo if successful.
    +
    Returns
    An AudioStreamInfo if successful.
    An empty pointer if there was unexpected values in the provided parameters or audio track element fields.
    @@ -200,9 +203,7 @@ An empty pointer if there was unexpected values in the provided parameters or au
    diff --git a/docs/d3/d7d/structshaka_1_1media_1_1TextRegion-members.html b/docs/d3/d7d/structshaka_1_1media_1_1TextRegion-members.html new file mode 100644 index 0000000000..a675fb4c0f --- /dev/null +++ b/docs/d3/d7d/structshaka_1_1media_1_1TextRegion-members.html @@ -0,0 +1,88 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::TextRegion Member List
    +
    + + + + + diff --git a/docs/d3/d80/muxer__util_8h_source.html b/docs/d3/d80/muxer__util_8h_source.html index a48620f910..3c709b165f 100644 --- a/docs/d3/d80/muxer__util_8h_source.html +++ b/docs/d3/d80/muxer__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/muxer_util.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    muxer_util.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Muxer utility functions.
    8 
    9 #ifndef PACKAGER_MEDIA_BASE_MUXER_UTIL_H_
    10 #define PACKAGER_MEDIA_BASE_MUXER_UTIL_H_
    11 
    12 #include <stdint.h>
    13 
    14 #include "packager/status.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 class StreamInfo;
    20 
    25 // ISO/IEC 23009-1:2012 5.3.9.4.4.
    26 Status ValidateSegmentTemplate(const std::string& segment_template);
    27 
    35 std::string GetSegmentName(const std::string& segment_template,
    36  uint64_t segment_start_time,
    37  uint32_t segment_index,
    38  uint32_t bandwidth);
    39 
    40 } // namespace media
    41 } // namespace shaka
    42 
    43 #endif // PACKAGER_MEDIA_BASE_MUXER_UTIL_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Muxer utility functions.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_BASE_MUXER_UTIL_H_
    +
    10 #define PACKAGER_MEDIA_BASE_MUXER_UTIL_H_
    +
    11 
    +
    12 #include <stdint.h>
    +
    13 
    +
    14 #include "packager/status.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 class StreamInfo;
    +
    20 
    +
    25 // ISO/IEC 23009-1:2012 5.3.9.4.4.
    +
    26 Status ValidateSegmentTemplate(const std::string& segment_template);
    +
    27 
    +
    35 std::string GetSegmentName(const std::string& segment_template,
    +
    36  uint64_t segment_start_time,
    +
    37  uint32_t segment_index,
    +
    38  uint32_t bandwidth);
    +
    39 
    +
    40 } // namespace media
    +
    41 } // namespace shaka
    +
    42 
    +
    43 #endif // PACKAGER_MEDIA_BASE_MUXER_UTIL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/d87/structshaka_1_1media_1_1mp4_1_1SampleToChunk.html b/docs/d3/d87/structshaka_1_1media_1_1mp4_1_1SampleToChunk.html index 4dae6a4426..80a1b5de75 100644 --- a/docs/d3/d87/structshaka_1_1media_1_1mp4_1_1SampleToChunk.html +++ b/docs/d3/d87/structshaka_1_1media_1_1mp4_1_1SampleToChunk.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleToChunk Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 454 of file box_definitions.h.

    +

    Definition at line 467 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 763 of file box_definitions.cc.

    +

    Definition at line 776 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/d3/d87/trick__play__handler_8cc_source.html b/docs/d3/d87/trick__play__handler_8cc_source.html index 314dc69903..9a0d658a72 100644 --- a/docs/d3/d87/trick__play__handler_8cc_source.html +++ b/docs/d3/d87/trick__play__handler_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/trick_play/trick_play_handler.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    trick_play_handler.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/trick_play/trick_play_handler.h"
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/media/base/video_stream_info.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 namespace {
    15 const size_t kStreamIndexIn = 0;
    16 const size_t kStreamIndexOut = 0;
    17 } // namespace
    18 
    19 TrickPlayHandler::TrickPlayHandler(uint32_t factor) : factor_(factor) {
    20  DCHECK_GE(factor, 1u)
    21  << "Trick Play Handles must have a factor of 1 or higher.";
    22 }
    23 
    24 Status TrickPlayHandler::InitializeInternal() {
    25  return Status::OK;
    26 }
    27 
    28 Status TrickPlayHandler::Process(std::unique_ptr<StreamData> stream_data) {
    29  DCHECK(stream_data);
    30  DCHECK_EQ(stream_data->stream_index, kStreamIndexIn);
    31 
    32  switch (stream_data->stream_data_type) {
    33  case StreamDataType::kStreamInfo:
    34  return OnStreamInfo(*stream_data->stream_info);
    35 
    36  case StreamDataType::kSegmentInfo:
    37  return OnSegmentInfo(std::move(stream_data->segment_info));
    38 
    39  case StreamDataType::kMediaSample:
    40  return OnMediaSample(*stream_data->media_sample);
    41 
    42  case StreamDataType::kCueEvent:
    43  // Add the cue event to be dispatched later.
    44  delayed_messages_.push_back(std::move(stream_data));
    45  return Status::OK;
    46 
    47  default:
    48  return Status(error::TRICK_PLAY_ERROR,
    49  "Trick play only supports stream info, segment info, and "
    50  "media sample messages.");
    51  }
    52 }
    53 
    54 Status TrickPlayHandler::OnFlushRequest(size_t input_stream_index) {
    55  DCHECK_EQ(input_stream_index, 0u);
    56 
    57  // Send everything out in its "as-is" state as we no longer need to update
    58  // anything.
    59  Status s;
    60  while (s.ok() && delayed_messages_.size()) {
    61  s.Update(Dispatch(std::move(delayed_messages_.front())));
    62  delayed_messages_.pop_front();
    63  }
    64 
    65  return s.ok() ? MediaHandler::FlushAllDownstreams() : s;
    66 }
    67 
    68 Status TrickPlayHandler::OnStreamInfo(const StreamInfo& info) {
    69  if (info.stream_type() != kStreamVideo) {
    70  return Status(error::TRICK_PLAY_ERROR,
    71  "Trick play does not support non-video stream");
    72  }
    73 
    74  // Copy the video so we can edit it. Set play back rate to be zero. It will be
    75  // updated later before being dispatched downstream.
    76  video_info_ = std::make_shared<VideoStreamInfo>(
    77  static_cast<const VideoStreamInfo&>(info));
    78 
    79  if (video_info_->trick_play_factor() > 0) {
    80  return Status(error::TRICK_PLAY_ERROR,
    81  "This stream is already a trick play stream.");
    82  }
    83 
    84  video_info_->set_trick_play_factor(factor_);
    85  video_info_->set_playback_rate(0);
    86 
    87  // Add video info to the message queue so that it can be sent out with all
    88  // other messages. It won't be sent until the second trick play frame comes
    89  // through. Until then, it can be updated via the |video_info_| member.
    90  delayed_messages_.push_back(
    91  StreamData::FromStreamInfo(kStreamIndexOut, video_info_));
    92 
    93  return Status::OK;
    94 }
    95 
    96 Status TrickPlayHandler::OnSegmentInfo(
    97  std::shared_ptr<const SegmentInfo> info) {
    98  if (delayed_messages_.empty()) {
    99  return Status(error::TRICK_PLAY_ERROR,
    100  "Cannot handle segments with no preceding samples.");
    101  }
    102 
    103  // Trick play does not care about sub segments, only full segments matter.
    104  if (info->is_subsegment) {
    105  return Status::OK;
    106  }
    107 
    108  const StreamDataType previous_type =
    109  delayed_messages_.back()->stream_data_type;
    110 
    111  switch (previous_type) {
    112  case StreamDataType::kSegmentInfo:
    113  // In the case that there was an empty segment (no trick frame between in
    114  // a segment) extend the previous segment to include the empty segment to
    115  // avoid holes.
    116  previous_segment_->duration += info->duration;
    117  return Status::OK;
    118 
    119  case StreamDataType::kMediaSample:
    120  // The segment has ended and there are media samples in the segment.
    121  // Add the segment info to the list of delayed messages. Segment info will
    122  // not get sent downstream until the next trick play frame comes through
    123  // or flush is called.
    124  previous_segment_ = std::make_shared<SegmentInfo>(*info);
    125  delayed_messages_.push_back(
    126  StreamData::FromSegmentInfo(kStreamIndexOut, previous_segment_));
    127  return Status::OK;
    128 
    129  default:
    130  return Status(error::TRICK_PLAY_ERROR,
    131  "Unexpected sample in trick play deferred queue : type=" +
    132  std::to_string(static_cast<int>(previous_type)));
    133  }
    134 }
    135 
    136 Status TrickPlayHandler::OnMediaSample(const MediaSample& sample) {
    137  total_frames_++;
    138 
    139  if (sample.is_key_frame()) {
    140  total_key_frames_++;
    141 
    142  if ((total_key_frames_ - 1) % factor_ == 0) {
    143  return OnTrickFrame(sample);
    144  }
    145  }
    146 
    147  // Update this now as it may be sent out soon via the delay message queue.
    148  if (total_trick_frames_ < 2) {
    149  // At this point, video_info will be at the head of the delay message queue
    150  // and can still be updated safely.
    151 
    152  // The play back rate is determined by the number of frames between the
    153  // first two trick play frames. The first trick play frame will be the
    154  // first frame in the video.
    155  video_info_->set_playback_rate(total_frames_);
    156  }
    157 
    158  // If the frame is not a trick play frame, then take the duration of this
    159  // frame and add it to the previous trick play frame so that it will span the
    160  // gap created by not passing this frame through.
    161  DCHECK(previous_trick_frame_);
    162  previous_trick_frame_->set_duration(previous_trick_frame_->duration() +
    163  sample.duration());
    164 
    165  return Status::OK;
    166 }
    167 
    168 Status TrickPlayHandler::OnTrickFrame(const MediaSample& sample) {
    169  total_trick_frames_++;
    170 
    171  // Make a message we can store until later.
    172  previous_trick_frame_ = sample.Clone();
    173 
    174  // Add the message to our queue so that it will be ready to go out.
    175  delayed_messages_.push_back(
    176  StreamData::FromMediaSample(kStreamIndexOut, previous_trick_frame_));
    177 
    178  // We need two trick play frames before we can send out our stream info, so we
    179  // cannot send this media sample until after we send our sample info
    180  // downstream.
    181  if (total_trick_frames_ < 2) {
    182  return Status::OK;
    183  }
    184 
    185  // Send out all delayed messages up until the new trick play frame we just
    186  // added.
    187  Status s;
    188  while (s.ok() && delayed_messages_.size() > 1) {
    189  s.Update(Dispatch(std::move(delayed_messages_.front())));
    190  delayed_messages_.pop_front();
    191  }
    192  return s;
    193 }
    194 
    195 } // namespace media
    196 } // namespace shaka
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    -
    All the methods that are virtual are virtual for mocking.
    -
    Status FlushAllDownstreams()
    Flush all connected downstream handlers.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/trick_play/trick_play_handler.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/media/base/video_stream_info.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 namespace {
    +
    15 const size_t kStreamIndexIn = 0;
    +
    16 const size_t kStreamIndexOut = 0;
    +
    17 } // namespace
    +
    18 
    +
    19 TrickPlayHandler::TrickPlayHandler(uint32_t factor) : factor_(factor) {
    +
    20  DCHECK_GE(factor, 1u)
    +
    21  << "Trick Play Handles must have a factor of 1 or higher.";
    +
    22 }
    +
    23 
    +
    24 Status TrickPlayHandler::InitializeInternal() {
    +
    25  return Status::OK;
    +
    26 }
    +
    27 
    +
    28 Status TrickPlayHandler::Process(std::unique_ptr<StreamData> stream_data) {
    +
    29  DCHECK(stream_data);
    +
    30  DCHECK_EQ(stream_data->stream_index, kStreamIndexIn);
    +
    31 
    +
    32  switch (stream_data->stream_data_type) {
    +
    33  case StreamDataType::kStreamInfo:
    +
    34  return OnStreamInfo(*stream_data->stream_info);
    +
    35 
    +
    36  case StreamDataType::kSegmentInfo:
    +
    37  return OnSegmentInfo(std::move(stream_data->segment_info));
    +
    38 
    +
    39  case StreamDataType::kMediaSample:
    +
    40  return OnMediaSample(*stream_data->media_sample);
    +
    41 
    +
    42  case StreamDataType::kCueEvent:
    +
    43  // Add the cue event to be dispatched later.
    +
    44  delayed_messages_.push_back(std::move(stream_data));
    +
    45  return Status::OK;
    +
    46 
    +
    47  default:
    +
    48  return Status(error::TRICK_PLAY_ERROR,
    +
    49  "Trick play only supports stream info, segment info, and "
    +
    50  "media sample messages.");
    +
    51  }
    +
    52 }
    +
    53 
    +
    54 Status TrickPlayHandler::OnFlushRequest(size_t input_stream_index) {
    +
    55  DCHECK_EQ(input_stream_index, 0u);
    +
    56 
    +
    57  // Send everything out in its "as-is" state as we no longer need to update
    +
    58  // anything.
    +
    59  Status s;
    +
    60  while (s.ok() && delayed_messages_.size()) {
    +
    61  s.Update(Dispatch(std::move(delayed_messages_.front())));
    +
    62  delayed_messages_.pop_front();
    +
    63  }
    +
    64 
    +
    65  return s.ok() ? MediaHandler::FlushAllDownstreams() : s;
    +
    66 }
    +
    67 
    +
    68 Status TrickPlayHandler::OnStreamInfo(const StreamInfo& info) {
    +
    69  if (info.stream_type() != kStreamVideo) {
    +
    70  return Status(error::TRICK_PLAY_ERROR,
    +
    71  "Trick play does not support non-video stream");
    +
    72  }
    +
    73 
    +
    74  // Copy the video so we can edit it. Set play back rate to be zero. It will be
    +
    75  // updated later before being dispatched downstream.
    +
    76  video_info_ = std::make_shared<VideoStreamInfo>(
    +
    77  static_cast<const VideoStreamInfo&>(info));
    +
    78 
    +
    79  if (video_info_->trick_play_factor() > 0) {
    +
    80  return Status(error::TRICK_PLAY_ERROR,
    +
    81  "This stream is already a trick play stream.");
    +
    82  }
    +
    83 
    +
    84  video_info_->set_trick_play_factor(factor_);
    +
    85  video_info_->set_playback_rate(0);
    +
    86 
    +
    87  // Add video info to the message queue so that it can be sent out with all
    +
    88  // other messages. It won't be sent until the second trick play frame comes
    +
    89  // through. Until then, it can be updated via the |video_info_| member.
    +
    90  delayed_messages_.push_back(
    +
    91  StreamData::FromStreamInfo(kStreamIndexOut, video_info_));
    +
    92 
    +
    93  return Status::OK;
    +
    94 }
    +
    95 
    +
    96 Status TrickPlayHandler::OnSegmentInfo(
    +
    97  std::shared_ptr<const SegmentInfo> info) {
    +
    98  if (delayed_messages_.empty()) {
    +
    99  return Status(error::TRICK_PLAY_ERROR,
    +
    100  "Cannot handle segments with no preceding samples.");
    +
    101  }
    +
    102 
    +
    103  // Trick play does not care about sub segments, only full segments matter.
    +
    104  if (info->is_subsegment) {
    +
    105  return Status::OK;
    +
    106  }
    +
    107 
    +
    108  const StreamDataType previous_type =
    +
    109  delayed_messages_.back()->stream_data_type;
    +
    110 
    +
    111  switch (previous_type) {
    +
    112  case StreamDataType::kSegmentInfo:
    +
    113  // In the case that there was an empty segment (no trick frame between in
    +
    114  // a segment) extend the previous segment to include the empty segment to
    +
    115  // avoid holes.
    +
    116  previous_segment_->duration += info->duration;
    +
    117  return Status::OK;
    +
    118 
    +
    119  case StreamDataType::kMediaSample:
    +
    120  // The segment has ended and there are media samples in the segment.
    +
    121  // Add the segment info to the list of delayed messages. Segment info will
    +
    122  // not get sent downstream until the next trick play frame comes through
    +
    123  // or flush is called.
    +
    124  previous_segment_ = std::make_shared<SegmentInfo>(*info);
    +
    125  delayed_messages_.push_back(
    +
    126  StreamData::FromSegmentInfo(kStreamIndexOut, previous_segment_));
    +
    127  return Status::OK;
    +
    128 
    +
    129  default:
    +
    130  return Status(error::TRICK_PLAY_ERROR,
    +
    131  "Unexpected sample in trick play deferred queue : type=" +
    +
    132  std::to_string(static_cast<int>(previous_type)));
    +
    133  }
    +
    134 }
    +
    135 
    +
    136 Status TrickPlayHandler::OnMediaSample(const MediaSample& sample) {
    +
    137  total_frames_++;
    +
    138 
    +
    139  if (sample.is_key_frame()) {
    +
    140  total_key_frames_++;
    +
    141 
    +
    142  if ((total_key_frames_ - 1) % factor_ == 0) {
    +
    143  return OnTrickFrame(sample);
    +
    144  }
    +
    145  }
    +
    146  // If the frame is not a trick play frame, then take the duration of this
    +
    147  // frame and add it to the previous trick play frame so that it will span the
    +
    148  // gap created by not passing this frame through.
    +
    149  DCHECK(previous_trick_frame_);
    +
    150  previous_trick_frame_->set_duration(previous_trick_frame_->duration() +
    +
    151  sample.duration());
    +
    152 
    +
    153  return Status::OK;
    +
    154 }
    +
    155 
    +
    156 Status TrickPlayHandler::OnTrickFrame(const MediaSample& sample) {
    +
    157  total_trick_frames_++;
    +
    158 
    +
    159  // Make a message we can store until later.
    +
    160  previous_trick_frame_ = sample.Clone();
    +
    161 
    +
    162  // Add the message to our queue so that it will be ready to go out.
    +
    163  delayed_messages_.push_back(
    +
    164  StreamData::FromMediaSample(kStreamIndexOut, previous_trick_frame_));
    +
    165 
    +
    166  // We need two trick play frames before we can send out our stream info, so we
    +
    167  // cannot send this media sample until after we send our sample info
    +
    168  // downstream.
    +
    169  if (total_trick_frames_ < 2) {
    +
    170  return Status::OK;
    +
    171  }
    +
    172 
    +
    173  // Update this now as it may be sent out soon via the delay message queue.
    +
    174  if (total_trick_frames_ == 2) {
    +
    175  // At this point, video_info will be at the head of the delay message queue
    +
    176  // and can still be updated safely.
    +
    177 
    +
    178  // The play back rate is determined by the number of frames between the
    +
    179  // first two trick play frames. The first trick play frame will be the
    +
    180  // first frame in the video.
    +
    181  video_info_->set_playback_rate(total_frames_ - 1);
    +
    182  }
    +
    183 
    +
    184  // Send out all delayed messages up until the new trick play frame we just
    +
    185  // added.
    +
    186  Status s;
    +
    187  while (s.ok() && delayed_messages_.size() > 1) {
    +
    188  s.Update(Dispatch(std::move(delayed_messages_.front())));
    +
    189  delayed_messages_.pop_front();
    +
    190  }
    +
    191  return s;
    +
    192 }
    +
    193 
    +
    194 } // namespace media
    +
    195 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/d8d/webm__audio__client_8h_source.html b/docs/d3/d8d/webm__audio__client_8h_source.html index 1fba8e155e..ce1b11bec9 100644 --- a/docs/d3/d8d/webm__audio__client_8h_source.html +++ b/docs/d3/d8d/webm__audio__client_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_audio_client.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    webm_audio_client.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_AUDIO_CLIENT_H_
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_AUDIO_CLIENT_H_
    7 
    8 #include <memory>
    9 #include <string>
    10 #include <vector>
    11 
    12 #include "packager/media/base/audio_stream_info.h"
    13 #include "packager/media/formats/webm/webm_parser.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 class AudioDecoderConfig;
    18 
    21  public:
    23  ~WebMAudioClient() override;
    24 
    26  void Reset();
    27 
    43  std::shared_ptr<AudioStreamInfo> GetAudioStreamInfo(
    44  int64_t track_num,
    45  const std::string& codec_id,
    46  const std::vector<uint8_t>& codec_private,
    47  int64_t seek_preroll,
    48  int64_t codec_delay,
    49  const std::string& language,
    50  bool is_encrypted);
    51 
    52  private:
    53  // WebMParserClient implementation.
    54  bool OnUInt(int id, int64_t val) override;
    55  bool OnFloat(int id, double val) override;
    56 
    57  int channels_;
    58  double samples_per_second_;
    59  double output_samples_per_second_;
    60 
    61  DISALLOW_COPY_AND_ASSIGN(WebMAudioClient);
    62 };
    63 
    64 } // namespace media
    65 } // namespace shaka
    66 
    67 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_AUDIO_CLIENT_H_
    All the methods that are virtual are virtual for mocking.
    -
    std::shared_ptr< AudioStreamInfo > GetAudioStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, int64_t seek_preroll, int64_t codec_delay, const std::string &language, bool is_encrypted)
    -
    void Reset()
    Reset this object&#39;s state so it can process a new audio track element.
    - -
    Helper class used to parse an Audio element inside a TrackEntry element.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_AUDIO_CLIENT_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_AUDIO_CLIENT_H_
    +
    7 
    +
    8 #include <memory>
    +
    9 #include <string>
    +
    10 #include <vector>
    +
    11 
    +
    12 #include "packager/media/base/audio_stream_info.h"
    +
    13 #include "packager/media/formats/webm/webm_parser.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 class AudioDecoderConfig;
    +
    18 
    + +
    21  public:
    + +
    23  ~WebMAudioClient() override;
    +
    24 
    +
    26  void Reset();
    +
    27 
    +
    43  std::shared_ptr<AudioStreamInfo> GetAudioStreamInfo(
    +
    44  int64_t track_num,
    +
    45  const std::string& codec_id,
    +
    46  const std::vector<uint8_t>& codec_private,
    +
    47  int64_t seek_preroll,
    +
    48  int64_t codec_delay,
    +
    49  const std::string& language,
    +
    50  bool is_encrypted);
    +
    51 
    +
    52  private:
    +
    53  // WebMParserClient implementation.
    +
    54  bool OnUInt(int id, int64_t val) override;
    +
    55  bool OnFloat(int id, double val) override;
    +
    56 
    +
    57  int channels_;
    +
    58  double samples_per_second_;
    +
    59  double output_samples_per_second_;
    +
    60 
    +
    61  DISALLOW_COPY_AND_ASSIGN(WebMAudioClient);
    +
    62 };
    +
    63 
    +
    64 } // namespace media
    +
    65 } // namespace shaka
    +
    66 
    +
    67 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_AUDIO_CLIENT_H_
    +
    Helper class used to parse an Audio element inside a TrackEntry element.
    +
    std::shared_ptr< AudioStreamInfo > GetAudioStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, int64_t seek_preroll, int64_t codec_delay, const std::string &language, bool is_encrypted)
    +
    void Reset()
    Reset this object's state so it can process a new audio track element.
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/d90/ec3__audio__util_8cc_source.html b/docs/d3/d90/ec3__audio__util_8cc_source.html index 1affd8832c..2ec24adf86 100644 --- a/docs/d3/d90/ec3__audio__util_8cc_source.html +++ b/docs/d3/d90/ec3__audio__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/ec3_audio_util.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    ec3_audio_util.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/ec3_audio_util.h"
    8 
    9 #include "packager/base/macros.h"
    10 #include "packager/base/strings/string_number_conversions.h"
    11 #include "packager/media/base/bit_reader.h"
    12 #include "packager/media/base/rcheck.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 namespace {
    18 
    19 // Channels bit map. 16 bits.
    20 // Bit, Location
    21 // 0(MSB), Left
    22 // 1, Center
    23 // 2, Right
    24 // 3, Left Surround
    25 // 4, Right Surround
    26 // 5, Left center/Right center pair
    27 // 6, Left rear surround/Right rear surround pair
    28 // 7, Center surround
    29 // 8, Top center surround
    30 // 9, Left surround direct/Right surround direct pair
    31 // 10, Left wide/Right wide pair
    32 // 11, Lvertical height/Right vertical height pair
    33 // 12, Center vertical height
    34 // 13, Lts/Rts pair
    35 // 14, LFE2
    36 // 15, LFE
    37 enum kEC3AudioChannelMap {
    38  kLeft = 0x8000,
    39  kCenter = 0x4000,
    40  kRight = 0x2000,
    41  kLeftSurround = 0x1000,
    42  kRightSurround = 0x800,
    43  kLcRcPair = 0x400,
    44  kLrsRrsPair = 0x200,
    45  kCenterSurround = 0x100,
    46  kTopCenterSurround = 0x80,
    47  kLsdRsdPair = 0x40,
    48  kLwRwPair = 0x20,
    49  kLvhRvhPair = 0x10,
    50  kCenterVerticalHeight = 0x8,
    51  kLtsRtsPair = 0x4,
    52  kLFE2 = 0x2,
    53  kLFEScreen = 0x1
    54 };
    55 // Number of channels for the channel bit above. The first entry corresponds to
    56 // kLeft, which has one channel. All the XxxPairs bits have two channels.
    57 const size_t kChannelCountArray[] = {
    58  1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 2, 1, 1,
    59 };
    60 static_assert(arraysize(kChannelCountArray) == 16u,
    61  "Channel count array should have 16 entries.");
    62 
    63 // EC3 Audio coding mode map (acmod) to determine EC3 audio channel layout. The
    64 // value stands for the existence of Left, Center, Right, Left surround, and
    65 // Right surround.
    66 const uint16_t kEC3AudioCodingModeMap[] = {
    67  kLeft | kRight,
    68  kCenter,
    69  kLeft | kRight,
    70  kLeft | kCenter | kRight,
    71  kLeft | kRight | kLeftSurround | kRightSurround,
    72  kLeft | kCenter | kRight | kLeftSurround | kRightSurround,
    73  kLeft | kRight | kLeftSurround | kRightSurround,
    74  kLeft | kCenter | kRight | kLeftSurround | kRightSurround,
    75 };
    76 
    77 // Reverse bit order.
    78 uint8_t ReverseBits8(uint8_t n) {
    79  n = ((n >> 1) & 0x55) | ((n & 0x55) << 1);
    80  n = ((n >> 2) & 0x33) | ((n & 0x33) << 2);
    81  return ((n >> 4) & 0x0f) | ((n & 0x0f) << 4);
    82 }
    83 
    84 bool ExtractEc3Data(const std::vector<uint8_t>& ec3_data,
    85  uint8_t* audio_coding_mode,
    86  bool* lfe_channel_on,
    87  uint16_t* dependent_substreams_layout) {
    88  BitReader bit_reader(ec3_data.data(), ec3_data.size());
    89  // Read number of independent substreams and parse the independent substreams.
    90  uint8_t number_independent_substreams;
    91  RCHECK(bit_reader.SkipBits(13) &&
    92  bit_reader.ReadBits(3, &number_independent_substreams));
    93  // The value of this field is one less than the number of independent
    94  // substreams present.
    95  ++number_independent_substreams;
    96 
    97  // Parse audio_coding_mode, dependent_substreams_layout and lfe_channel_on
    98  // from the first independent substream.
    99  // Independent substream in EC3Specific box:
    100  // fscod: 2 bits
    101  // bsid: 5 bits
    102  // reserved_1: 1 bit
    103  // asvc: 1 bit
    104  // bsmod: 3 bits
    105  // acmod: 3 bits
    106  // lfeon: 1 bit
    107  // reserved_2: 3 bits
    108  // num_dep_sub: 4 bits
    109  // If num_dep_sub > 0, chan_loc is present and the size is 9 bits.
    110  // Otherwise, reserved_3 is present and the size is 1 bit.
    111  // chan_loc: 9 bits
    112  // reserved_3: 1 bit
    113  RCHECK(bit_reader.SkipBits(12));
    114  RCHECK(bit_reader.ReadBits(3, audio_coding_mode));
    115  RCHECK(bit_reader.ReadBits(1, lfe_channel_on));
    116 
    117  uint8_t number_dependent_substreams = 0;
    118  RCHECK(bit_reader.SkipBits(3));
    119  RCHECK(bit_reader.ReadBits(4, &number_dependent_substreams));
    120 
    121  *dependent_substreams_layout = 0;
    122  if (number_dependent_substreams > 0) {
    123  RCHECK(bit_reader.ReadBits(9, dependent_substreams_layout));
    124  }
    125 
    126  return true;
    127 }
    128 
    129 } // namespace
    130 
    131 bool CalculateEC3ChannelMap(const std::vector<uint8_t>& ec3_data,
    132  uint32_t* channel_map) {
    133  uint8_t audio_coding_mode;
    134  bool lfe_channel_on;
    135  uint16_t dependent_substreams_layout;
    136  if (!ExtractEc3Data(ec3_data, &audio_coding_mode, &lfe_channel_on,
    137  &dependent_substreams_layout)) {
    138  LOG(WARNING) << "Seeing invalid EC3 data: "
    139  << base::HexEncode(ec3_data.data(), ec3_data.size());
    140  return false;
    141  }
    142 
    143  // Dependent substreams layout bit map:
    144  // Bit, Location
    145  // 0, Lc/Rc pair
    146  // 1, Lrs/Rrs pair
    147  // 2, Cs
    148  // 3, Ts
    149  // 4, Lsd/Rsd pair
    150  // 5, Lw/Rw pair
    151  // 6, Lvh/Rvh pair
    152  // 7, Cvh
    153  // 8(MSB), LFE2
    154  // Reverse bit order of dependent substreams channel layout (LFE2 not
    155  // included) to apply on channel_map bit 5 - 12.
    156  const uint8_t reversed_dependent_substreams_layout =
    157  ReverseBits8(dependent_substreams_layout & 0xFF);
    158 
    159  *channel_map = kEC3AudioCodingModeMap[audio_coding_mode] |
    160  (reversed_dependent_substreams_layout << 3);
    161  if (dependent_substreams_layout & 0x100)
    162  *channel_map |= kLFE2;
    163  if (lfe_channel_on)
    164  *channel_map |= kLFEScreen;
    165  return true;
    166 }
    167 
    168 size_t GetEc3NumChannels(const std::vector<uint8_t>& ec3_data) {
    169  uint32_t channel_map;
    170  if (!CalculateEC3ChannelMap(ec3_data, &channel_map))
    171  return 0;
    172 
    173  size_t num_channels = 0;
    174  int bit = kLeft;
    175  for (size_t channel_count : kChannelCountArray) {
    176  if (channel_map & bit)
    177  num_channels += channel_count;
    178  bit >>= 1;
    179  }
    180  DCHECK_EQ(bit, 0);
    181  return num_channels;
    182 }
    183 
    184 } // namespace media
    185 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/ec3_audio_util.h"
    +
    8 
    +
    9 #include "packager/base/macros.h"
    +
    10 #include "packager/base/strings/string_number_conversions.h"
    +
    11 #include "packager/media/base/bit_reader.h"
    +
    12 #include "packager/media/base/rcheck.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 namespace {
    +
    18 
    +
    19 // Channels bit map. 16 bits.
    +
    20 // Bit, Location
    +
    21 // 0(MSB), Left
    +
    22 // 1, Center
    +
    23 // 2, Right
    +
    24 // 3, Left Surround
    +
    25 // 4, Right Surround
    +
    26 // 5, Left center/Right center pair
    +
    27 // 6, Left rear surround/Right rear surround pair
    +
    28 // 7, Center surround
    +
    29 // 8, Top center surround
    +
    30 // 9, Left surround direct/Right surround direct pair
    +
    31 // 10, Left wide/Right wide pair
    +
    32 // 11, Lvertical height/Right vertical height pair
    +
    33 // 12, Center vertical height
    +
    34 // 13, Lts/Rts pair
    +
    35 // 14, LFE2
    +
    36 // 15, LFE
    +
    37 enum kEC3AudioChannelMap {
    +
    38  kLeft = 0x8000,
    +
    39  kCenter = 0x4000,
    +
    40  kRight = 0x2000,
    +
    41  kLeftSurround = 0x1000,
    +
    42  kRightSurround = 0x800,
    +
    43  kLcRcPair = 0x400,
    +
    44  kLrsRrsPair = 0x200,
    +
    45  kCenterSurround = 0x100,
    +
    46  kTopCenterSurround = 0x80,
    +
    47  kLsdRsdPair = 0x40,
    +
    48  kLwRwPair = 0x20,
    +
    49  kLvhRvhPair = 0x10,
    +
    50  kCenterVerticalHeight = 0x8,
    +
    51  kLtsRtsPair = 0x4,
    +
    52  kLFE2 = 0x2,
    +
    53  kLFEScreen = 0x1
    +
    54 };
    +
    55 // Number of channels for the channel bit above. The first entry corresponds to
    +
    56 // kLeft, which has one channel. All the XxxPairs bits have two channels.
    +
    57 const size_t kChannelCountArray[] = {
    +
    58  1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 2, 1, 1,
    +
    59 };
    +
    60 static_assert(arraysize(kChannelCountArray) == 16u,
    +
    61  "Channel count array should have 16 entries.");
    +
    62 
    +
    63 // EC3 Audio coding mode map (acmod) to determine EC3 audio channel layout. The
    +
    64 // value stands for the existence of Left, Center, Right, Left surround, and
    +
    65 // Right surround.
    +
    66 const uint16_t kEC3AudioCodingModeMap[] = {
    +
    67  kLeft | kRight,
    +
    68  kCenter,
    +
    69  kLeft | kRight,
    +
    70  kLeft | kCenter | kRight,
    +
    71  kLeft | kRight | kLeftSurround | kRightSurround,
    +
    72  kLeft | kCenter | kRight | kLeftSurround | kRightSurround,
    +
    73  kLeft | kRight | kLeftSurround | kRightSurround,
    +
    74  kLeft | kCenter | kRight | kLeftSurround | kRightSurround,
    +
    75 };
    +
    76 
    +
    77 // Reverse bit order.
    +
    78 uint8_t ReverseBits8(uint8_t n) {
    +
    79  n = ((n >> 1) & 0x55) | ((n & 0x55) << 1);
    +
    80  n = ((n >> 2) & 0x33) | ((n & 0x33) << 2);
    +
    81  return ((n >> 4) & 0x0f) | ((n & 0x0f) << 4);
    +
    82 }
    +
    83 
    +
    84 // Mapping of channel configurations to the MPEG audio value based on
    +
    85 // ETSI TS 102 366 V1.4.1 Digital Audio Compression (AC-3, Enhanced AC-3)
    +
    86 // Standard Table I.1.1
    +
    87 uint32_t EC3ChannelMaptoMPEGValue(uint32_t channel_map) {
    +
    88  uint32_t ret = 0;
    +
    89 
    +
    90  switch (channel_map) {
    +
    91  case kCenter:
    +
    92  ret = 1;
    +
    93  break;
    +
    94  case kLeft | kRight:
    +
    95  ret = 2;
    +
    96  break;
    +
    97  case kCenter| kLeft | kRight:
    +
    98  ret = 3;
    +
    99  break;
    +
    100  case kCenter | kLeft | kRight | kCenterSurround:
    +
    101  ret = 4;
    +
    102  break;
    +
    103  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround:
    +
    104  ret = 5;
    +
    105  break;
    +
    106  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
    +
    107  kLFEScreen:
    +
    108  ret = 6;
    +
    109  break;
    +
    110  case kCenter | kLeft | kRight | kLwRwPair | kLeftSurround | kRightSurround |
    +
    111  kLFEScreen:
    +
    112  ret = 7;
    +
    113  break;
    +
    114  case kLeft | kRight | kCenterSurround:
    +
    115  ret = 9;
    +
    116  break;
    +
    117  case kLeft | kRight | kLeftSurround | kRightSurround:
    +
    118  ret = 10;
    +
    119  break;
    +
    120  case kCenter | kLeft | kRight | kLrsRrsPair | kCenterSurround | kLFEScreen:
    +
    121  ret = 11;
    +
    122  break;
    +
    123  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
    +
    124  kLrsRrsPair | kLFEScreen:
    +
    125  ret = 12;
    +
    126  break;
    +
    127  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
    +
    128  kLFEScreen | kLvhRvhPair:
    +
    129  ret = 14;
    +
    130  break;
    +
    131  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
    +
    132  kLFEScreen | kLvhRvhPair | kLtsRtsPair:
    +
    133  ret = 16;
    +
    134  break;
    +
    135  case kCenter | kLeft | kRight | kLeftSurround | kRightSurround |
    +
    136  kLFEScreen | kLvhRvhPair | kCenterVerticalHeight | kLtsRtsPair |
    +
    137  kTopCenterSurround:
    +
    138  ret = 17;
    +
    139  break;
    +
    140  case kCenter | kLeft | kRight | kLsdRsdPair | kLrsRrsPair | kLFEScreen |
    +
    141  kLvhRvhPair | kLtsRtsPair:
    +
    142  ret = 19;
    +
    143  break;
    +
    144  default:
    +
    145  ret = 0xFFFFFFFF;
    +
    146  }
    +
    147  return ret;
    +
    148 }
    +
    149 
    +
    150 bool ExtractEc3Data(const std::vector<uint8_t>& ec3_data,
    +
    151  uint8_t* audio_coding_mode,
    +
    152  bool* lfe_channel_on,
    +
    153  uint16_t* dependent_substreams_layout,
    +
    154  uint32_t* ec3_joc_complexity) {
    +
    155  BitReader bit_reader(ec3_data.data(), ec3_data.size());
    +
    156  // Read number of independent substreams and parse the independent substreams.
    +
    157  uint8_t number_independent_substreams;
    +
    158  RCHECK(bit_reader.SkipBits(13) &&
    +
    159  bit_reader.ReadBits(3, &number_independent_substreams));
    +
    160  // The value of this field is one less than the number of independent
    +
    161  // substreams present.
    +
    162  ++number_independent_substreams;
    +
    163 
    +
    164  // Parse audio_coding_mode, dependent_substreams_layout and lfe_channel_on
    +
    165  // from the first independent substream.
    +
    166  // Independent substream in EC3Specific box:
    +
    167  // fscod: 2 bits
    +
    168  // bsid: 5 bits
    +
    169  // reserved_1: 1 bit
    +
    170  // asvc: 1 bit
    +
    171  // bsmod: 3 bits
    +
    172  // acmod: 3 bits
    +
    173  // lfeon: 1 bit
    +
    174  // reserved_2: 3 bits
    +
    175  // num_dep_sub: 4 bits
    +
    176  // If num_dep_sub > 0, chan_loc is present and the size is 9 bits.
    +
    177  // Otherwise, reserved_3 is present and the size is 1 bit.
    +
    178  // chan_loc: 9 bits
    +
    179  // reserved_3: 1 bit
    +
    180  RCHECK(bit_reader.SkipBits(12));
    +
    181  RCHECK(bit_reader.ReadBits(3, audio_coding_mode));
    +
    182  RCHECK(bit_reader.ReadBits(1, lfe_channel_on));
    +
    183 
    +
    184  uint8_t number_dependent_substreams = 0;
    +
    185  RCHECK(bit_reader.SkipBits(3));
    +
    186  RCHECK(bit_reader.ReadBits(4, &number_dependent_substreams));
    +
    187 
    +
    188  *dependent_substreams_layout = 0;
    +
    189  if (number_dependent_substreams > 0) {
    +
    190  RCHECK(bit_reader.ReadBits(9, dependent_substreams_layout));
    +
    191  } else {
    +
    192  RCHECK(bit_reader.SkipBits(1));
    +
    193  }
    +
    194  *ec3_joc_complexity = 0;
    +
    195  if (bit_reader.bits_available() < 16) {
    +
    196  return true;
    +
    197  }
    +
    198 
    +
    199  RCHECK(bit_reader.SkipBits(7));
    +
    200  bool ec3_joc_flag;
    +
    201  RCHECK(bit_reader.ReadBits(1, &ec3_joc_flag));
    +
    202  if (ec3_joc_flag) {
    +
    203  RCHECK(bit_reader.ReadBits(8, ec3_joc_complexity));
    +
    204  }
    +
    205  return true;
    +
    206 }
    +
    207 
    +
    208 } // namespace
    +
    209 
    +
    210 bool CalculateEC3ChannelMap(const std::vector<uint8_t>& ec3_data,
    +
    211  uint32_t* channel_map) {
    +
    212  uint8_t audio_coding_mode;
    +
    213  bool lfe_channel_on;
    +
    214  uint16_t dependent_substreams_layout;
    +
    215  uint32_t ec3_joc_complexity;
    +
    216  if (!ExtractEc3Data(ec3_data, &audio_coding_mode, &lfe_channel_on,
    +
    217  &dependent_substreams_layout, &ec3_joc_complexity)) {
    +
    218  LOG(WARNING) << "Seeing invalid EC3 data: "
    +
    219  << base::HexEncode(ec3_data.data(), ec3_data.size());
    +
    220  return false;
    +
    221  }
    +
    222 
    +
    223  // Dependent substreams layout bit map:
    +
    224  // Bit, Location
    +
    225  // 0, Lc/Rc pair
    +
    226  // 1, Lrs/Rrs pair
    +
    227  // 2, Cs
    +
    228  // 3, Ts
    +
    229  // 4, Lsd/Rsd pair
    +
    230  // 5, Lw/Rw pair
    +
    231  // 6, Lvh/Rvh pair
    +
    232  // 7, Cvh
    +
    233  // 8(MSB), LFE2
    +
    234  // Reverse bit order of dependent substreams channel layout (LFE2 not
    +
    235  // included) to apply on channel_map bit 5 - 12.
    +
    236  const uint8_t reversed_dependent_substreams_layout =
    +
    237  ReverseBits8(dependent_substreams_layout & 0xFF);
    +
    238 
    +
    239  *channel_map = kEC3AudioCodingModeMap[audio_coding_mode] |
    +
    240  (reversed_dependent_substreams_layout << 3);
    +
    241  if (dependent_substreams_layout & 0x100)
    +
    242  *channel_map |= kLFE2;
    +
    243  if (lfe_channel_on)
    +
    244  *channel_map |= kLFEScreen;
    +
    245  return true;
    +
    246 }
    +
    247 
    +
    248 bool CalculateEC3ChannelMPEGValue(const std::vector<uint8_t>& ec3_data,
    +
    249  uint32_t* ec3_channel_mpeg_value) {
    +
    250  uint32_t channel_map;
    +
    251  if (!CalculateEC3ChannelMap(ec3_data, &channel_map))
    +
    252  return false;
    +
    253  *ec3_channel_mpeg_value = EC3ChannelMaptoMPEGValue(channel_map);
    +
    254  return true;
    +
    255 }
    +
    256 
    +
    257 size_t GetEc3NumChannels(const std::vector<uint8_t>& ec3_data) {
    +
    258  uint32_t channel_map;
    +
    259  if (!CalculateEC3ChannelMap(ec3_data, &channel_map))
    +
    260  return 0;
    +
    261 
    +
    262  size_t num_channels = 0;
    +
    263  int bit = kLeft;
    +
    264  for (size_t channel_count : kChannelCountArray) {
    +
    265  if (channel_map & bit)
    +
    266  num_channels += channel_count;
    +
    267  bit >>= 1;
    +
    268  }
    +
    269  DCHECK_EQ(bit, 0);
    +
    270  return num_channels;
    +
    271 }
    +
    272 
    +
    273 bool GetEc3JocComplexity(const std::vector<uint8_t>& ec3_data,
    +
    274  uint32_t* ec3_joc_complexity) {
    +
    275  uint8_t audio_coding_mode;
    +
    276  bool lfe_channel_on;
    +
    277  uint16_t dependent_substreams_layout;
    +
    278 
    +
    279  if (!ExtractEc3Data(ec3_data, &audio_coding_mode, &lfe_channel_on,
    +
    280  &dependent_substreams_layout, ec3_joc_complexity)) {
    +
    281  LOG(WARNING) << "Seeing invalid EC3 data: "
    +
    282  << base::HexEncode(ec3_data.data(), ec3_data.size());
    +
    283  return false;
    +
    284  }
    +
    285  return true;
    +
    286 }
    +
    287 
    +
    288 } // namespace media
    +
    289 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/d91/classshaka_1_1media_1_1H264Parser.html b/docs/d3/d91/classshaka_1_1media_1_1H264Parser.html index ccf66b4307..9a46cb1f86 100644 --- a/docs/d3/d91/classshaka_1_1media_1_1H264Parser.html +++ b/docs/d3/d91/classshaka_1_1media_1_1H264Parser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264Parser Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Public Types

    -enum  Result { kOk, -kInvalidStream, -kUnsupportedStream, -kEOStream +enum  Result { kOk +, kInvalidStream +, kUnsupportedStream +, kEOStream }   @@ -103,7 +106,7 @@ Result 
    ParseSEI (const

    Detailed Description

    -

    Definition at line 250 of file h264_parser.h.

    +

    Definition at line 242 of file h264_parser.h.


    The documentation for this class was generated from the following files:
    diff --git a/docs/d3/d93/media__handler_8h_source.html b/docs/d3/d93/media__handler_8h_source.html index cbe8d8c608..738bb53fe3 100644 --- a/docs/d3/d93/media__handler_8h_source.html +++ b/docs/d3/d93/media__handler_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/media_handler.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    media_handler.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_MEDIA_HANDLER_H_
    8 #define PACKAGER_MEDIA_BASE_MEDIA_HANDLER_H_
    9 
    10 #include <map>
    11 #include <memory>
    12 #include <utility>
    13 
    14 #include "packager/media/base/media_sample.h"
    15 #include "packager/media/base/stream_info.h"
    16 #include "packager/media/base/text_sample.h"
    17 #include "packager/status.h"
    18 
    19 namespace shaka {
    20 namespace media {
    21 
    22 enum class StreamDataType {
    23  kUnknown,
    24  kStreamInfo,
    25  kMediaSample,
    26  kTextSample,
    27  kSegmentInfo,
    28  kScte35Event,
    29  kCueEvent,
    30 };
    31 
    32 std::string StreamDataTypeToString(StreamDataType type);
    33 
    34 // Scte35Event represents cuepoint markers in input streams. It will be used
    35 // to represent out of band cuepoint markers too.
    36 struct Scte35Event {
    37  std::string id;
    38  // Segmentation type id from SCTE35 segmentation descriptor.
    39  int type = 0;
    40  double start_time_in_seconds = 0;
    41  double duration_in_seconds = 0;
    42  std::string cue_data;
    43 };
    44 
    45 enum class CueEventType { kCueIn, kCueOut, kCuePoint };
    46 
    47 // In server-based model, Chunking Handler consolidates SCTE-35 events and
    48 // generates CueEvent before an ad is about to be inserted.
    49 struct CueEvent {
    50  CueEventType type = CueEventType::kCuePoint;
    51  double time_in_seconds;
    52  std::string cue_data;
    53 };
    54 
    55 struct SegmentInfo {
    56  bool is_subsegment = false;
    57  bool is_encrypted = false;
    58  int64_t start_timestamp = -1;
    59  int64_t duration = 0;
    60  // This is only available if key rotation is enabled. Note that we may have
    61  // a |key_rotation_encryption_config| even if the segment is not encrypted,
    62  // which is the case for clear lead.
    63  std::shared_ptr<EncryptionConfig> key_rotation_encryption_config;
    64 };
    65 
    66 // TODO(kqyang): Should we use protobuf?
    67 struct StreamData {
    68  size_t stream_index = static_cast<size_t>(-1);
    69  StreamDataType stream_data_type = StreamDataType::kUnknown;
    70 
    71  std::shared_ptr<const StreamInfo> stream_info;
    72  std::shared_ptr<const MediaSample> media_sample;
    73  std::shared_ptr<const TextSample> text_sample;
    74  std::shared_ptr<const SegmentInfo> segment_info;
    75  std::shared_ptr<const Scte35Event> scte35_event;
    76  std::shared_ptr<const CueEvent> cue_event;
    77 
    78  static std::unique_ptr<StreamData> FromStreamInfo(
    79  size_t stream_index,
    80  std::shared_ptr<const StreamInfo> stream_info) {
    81  std::unique_ptr<StreamData> stream_data(new StreamData);
    82  stream_data->stream_index = stream_index;
    83  stream_data->stream_data_type = StreamDataType::kStreamInfo;
    84  stream_data->stream_info = std::move(stream_info);
    85  return stream_data;
    86  }
    87 
    88  static std::unique_ptr<StreamData> FromMediaSample(
    89  size_t stream_index,
    90  std::shared_ptr<const MediaSample> media_sample) {
    91  std::unique_ptr<StreamData> stream_data(new StreamData);
    92  stream_data->stream_index = stream_index;
    93  stream_data->stream_data_type = StreamDataType::kMediaSample;
    94  stream_data->media_sample = std::move(media_sample);
    95  return stream_data;
    96  }
    97 
    98  static std::unique_ptr<StreamData> FromTextSample(
    99  size_t stream_index,
    100  std::shared_ptr<const TextSample> text_sample) {
    101  std::unique_ptr<StreamData> stream_data(new StreamData);
    102  stream_data->stream_index = stream_index;
    103  stream_data->stream_data_type = StreamDataType::kTextSample;
    104  stream_data->text_sample = std::move(text_sample);
    105  return stream_data;
    106  }
    107 
    108  static std::unique_ptr<StreamData> FromSegmentInfo(
    109  size_t stream_index,
    110  std::shared_ptr<const SegmentInfo> segment_info) {
    111  std::unique_ptr<StreamData> stream_data(new StreamData);
    112  stream_data->stream_index = stream_index;
    113  stream_data->stream_data_type = StreamDataType::kSegmentInfo;
    114  stream_data->segment_info = std::move(segment_info);
    115  return stream_data;
    116  }
    117 
    118  static std::unique_ptr<StreamData> FromScte35Event(
    119  size_t stream_index,
    120  std::shared_ptr<const Scte35Event> scte35_event) {
    121  std::unique_ptr<StreamData> stream_data(new StreamData);
    122  stream_data->stream_index = stream_index;
    123  stream_data->stream_data_type = StreamDataType::kScte35Event;
    124  stream_data->scte35_event = std::move(scte35_event);
    125  return stream_data;
    126  }
    127 
    128  static std::unique_ptr<StreamData> FromCueEvent(
    129  size_t stream_index,
    130  std::shared_ptr<const CueEvent> cue_event) {
    131  std::unique_ptr<StreamData> stream_data(new StreamData);
    132  stream_data->stream_index = stream_index;
    133  stream_data->stream_data_type = StreamDataType::kCueEvent;
    134  stream_data->cue_event = std::move(cue_event);
    135  return stream_data;
    136  }
    137 };
    138 
    155  public:
    156  MediaHandler() = default;
    157  virtual ~MediaHandler() = default;
    158 
    160  Status SetHandler(size_t output_stream_index,
    161  std::shared_ptr<MediaHandler> handler);
    162 
    164  Status AddHandler(std::shared_ptr<MediaHandler> handler) {
    165  return SetHandler(next_output_stream_index_, handler);
    166  }
    167 
    170  Status Initialize();
    171 
    173  bool IsConnected() { return num_input_streams_ > 0; }
    174 
    175  static Status Chain(
    176  std::initializer_list<std::shared_ptr<MediaHandler>> list);
    177 
    178  protected:
    181  virtual Status InitializeInternal() = 0;
    182 
    187  virtual Status Process(std::unique_ptr<StreamData> stream_data) = 0;
    188 
    190  virtual Status OnFlushRequest(size_t input_stream_index);
    191 
    193  virtual bool ValidateOutputStreamIndex(size_t stream_index) const;
    194 
    197  Status Dispatch(std::unique_ptr<StreamData> stream_data) const;
    198 
    201  size_t stream_index,
    202  std::shared_ptr<const StreamInfo> stream_info) const {
    203  return Dispatch(
    204  StreamData::FromStreamInfo(stream_index, std::move(stream_info)));
    205  }
    206 
    209  size_t stream_index,
    210  std::shared_ptr<const MediaSample> media_sample) const {
    211  return Dispatch(
    212  StreamData::FromMediaSample(stream_index, std::move(media_sample)));
    213  }
    214 
    216  // DispatchTextSample should only be override for testing.
    218  size_t stream_index,
    219  std::shared_ptr<const TextSample> text_sample) const {
    220  return Dispatch(
    221  StreamData::FromTextSample(stream_index, std::move(text_sample)));
    222  }
    223 
    226  size_t stream_index,
    227  std::shared_ptr<const SegmentInfo> segment_info) const {
    228  return Dispatch(
    229  StreamData::FromSegmentInfo(stream_index, std::move(segment_info)));
    230  }
    231 
    234  size_t stream_index,
    235  std::shared_ptr<const Scte35Event> scte35_event) const {
    236  return Dispatch(
    237  StreamData::FromScte35Event(stream_index, std::move(scte35_event)));
    238  }
    239 
    241  Status DispatchCueEvent(size_t stream_index,
    242  std::shared_ptr<const CueEvent> cue_event) const {
    243  return Dispatch(
    244  StreamData::FromCueEvent(stream_index, std::move(cue_event)));
    245  }
    246 
    248  Status FlushDownstream(size_t output_stream_index);
    249 
    251  Status FlushAllDownstreams();
    252 
    253  bool initialized() { return initialized_; }
    254  size_t num_input_streams() const { return num_input_streams_; }
    255  size_t next_output_stream_index() const { return next_output_stream_index_; }
    256  const std::map<size_t, std::pair<std::shared_ptr<MediaHandler>, size_t>>&
    257  output_handlers() {
    258  return output_handlers_;
    259  }
    260 
    261  private:
    262  MediaHandler(const MediaHandler&) = delete;
    263  MediaHandler& operator=(const MediaHandler&) = delete;
    264 
    265  bool initialized_ = false;
    266  // Number of input streams.
    267  size_t num_input_streams_ = 0;
    268  // The next available output stream index, used by AddHandler.
    269  size_t next_output_stream_index_ = 0;
    270  // output stream index -> {output handler, output handler input stream index}
    271  // map.
    272  std::map<size_t, std::pair<std::shared_ptr<MediaHandler>, size_t>>
    273  output_handlers_;
    274 };
    275 
    276 } // namespace media
    277 } // namespace shaka
    278 
    279 #endif // PACKAGER_MEDIA_BASE_MEDIA_HANDLER_H_
    Status DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
    Dispatch the stream info to downstream handlers.
    - - - -
    bool IsConnected()
    Validate if the handler is connected to its upstream handler.
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    Status DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
    Dispatch the text sample to downstream handlers.
    -
    Status AddHandler(std::shared_ptr< MediaHandler > handler)
    Connect downstream handler to the next available output stream index.
    -
    Status DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) const
    Dispatch the segment info to downstream handlers.
    -
    Status DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) const
    Dispatch the cue event to downstream handlers.
    -
    Status DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) const
    Dispatch the scte35 event to downstream handlers.
    - -
    Status DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
    Dispatch the media sample to downstream handlers.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_MEDIA_HANDLER_H_
    +
    8 #define PACKAGER_MEDIA_BASE_MEDIA_HANDLER_H_
    +
    9 
    +
    10 #include <map>
    +
    11 #include <memory>
    +
    12 #include <utility>
    +
    13 
    +
    14 #include "packager/media/base/media_sample.h"
    +
    15 #include "packager/media/base/stream_info.h"
    +
    16 #include "packager/media/base/text_sample.h"
    +
    17 #include "packager/status.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 
    +
    22 enum class StreamDataType {
    +
    23  kUnknown,
    +
    24  kStreamInfo,
    +
    25  kMediaSample,
    +
    26  kTextSample,
    +
    27  kSegmentInfo,
    +
    28  kScte35Event,
    +
    29  kCueEvent,
    +
    30 };
    +
    31 
    +
    32 std::string StreamDataTypeToString(StreamDataType type);
    +
    33 
    +
    34 // Scte35Event represents cuepoint markers in input streams. It will be used
    +
    35 // to represent out of band cuepoint markers too.
    +
    36 struct Scte35Event {
    +
    37  std::string id;
    +
    38  // Segmentation type id from SCTE35 segmentation descriptor.
    +
    39  int type = 0;
    +
    40  double start_time_in_seconds = 0;
    +
    41  double duration_in_seconds = 0;
    +
    42  std::string cue_data;
    +
    43 };
    +
    44 
    +
    45 enum class CueEventType { kCueIn, kCueOut, kCuePoint };
    +
    46 
    +
    47 // In server-based model, Chunking Handler consolidates SCTE-35 events and
    +
    48 // generates CueEvent before an ad is about to be inserted.
    +
    49 struct CueEvent {
    +
    50  CueEventType type = CueEventType::kCuePoint;
    +
    51  double time_in_seconds;
    +
    52  std::string cue_data;
    +
    53 };
    +
    54 
    +
    55 struct SegmentInfo {
    +
    56  bool is_subsegment = false;
    +
    57  bool is_encrypted = false;
    +
    58  int64_t start_timestamp = -1;
    +
    59  int64_t duration = 0;
    +
    60  // This is only available if key rotation is enabled. Note that we may have
    +
    61  // a |key_rotation_encryption_config| even if the segment is not encrypted,
    +
    62  // which is the case for clear lead.
    +
    63  std::shared_ptr<EncryptionConfig> key_rotation_encryption_config;
    +
    64 };
    +
    65 
    +
    66 // TODO(kqyang): Should we use protobuf?
    +
    67 struct StreamData {
    +
    68  size_t stream_index = static_cast<size_t>(-1);
    +
    69  StreamDataType stream_data_type = StreamDataType::kUnknown;
    +
    70 
    +
    71  std::shared_ptr<const StreamInfo> stream_info;
    +
    72  std::shared_ptr<const MediaSample> media_sample;
    +
    73  std::shared_ptr<const TextSample> text_sample;
    +
    74  std::shared_ptr<const SegmentInfo> segment_info;
    +
    75  std::shared_ptr<const Scte35Event> scte35_event;
    +
    76  std::shared_ptr<const CueEvent> cue_event;
    +
    77 
    +
    78  static std::unique_ptr<StreamData> FromStreamInfo(
    +
    79  size_t stream_index,
    +
    80  std::shared_ptr<const StreamInfo> stream_info) {
    +
    81  std::unique_ptr<StreamData> stream_data(new StreamData);
    +
    82  stream_data->stream_index = stream_index;
    +
    83  stream_data->stream_data_type = StreamDataType::kStreamInfo;
    +
    84  stream_data->stream_info = std::move(stream_info);
    +
    85  return stream_data;
    +
    86  }
    +
    87 
    +
    88  static std::unique_ptr<StreamData> FromMediaSample(
    +
    89  size_t stream_index,
    +
    90  std::shared_ptr<const MediaSample> media_sample) {
    +
    91  std::unique_ptr<StreamData> stream_data(new StreamData);
    +
    92  stream_data->stream_index = stream_index;
    +
    93  stream_data->stream_data_type = StreamDataType::kMediaSample;
    +
    94  stream_data->media_sample = std::move(media_sample);
    +
    95  return stream_data;
    +
    96  }
    +
    97 
    +
    98  static std::unique_ptr<StreamData> FromTextSample(
    +
    99  size_t stream_index,
    +
    100  std::shared_ptr<const TextSample> text_sample) {
    +
    101  std::unique_ptr<StreamData> stream_data(new StreamData);
    +
    102  stream_data->stream_index = stream_index;
    +
    103  stream_data->stream_data_type = StreamDataType::kTextSample;
    +
    104  stream_data->text_sample = std::move(text_sample);
    +
    105  return stream_data;
    +
    106  }
    +
    107 
    +
    108  static std::unique_ptr<StreamData> FromSegmentInfo(
    +
    109  size_t stream_index,
    +
    110  std::shared_ptr<const SegmentInfo> segment_info) {
    +
    111  std::unique_ptr<StreamData> stream_data(new StreamData);
    +
    112  stream_data->stream_index = stream_index;
    +
    113  stream_data->stream_data_type = StreamDataType::kSegmentInfo;
    +
    114  stream_data->segment_info = std::move(segment_info);
    +
    115  return stream_data;
    +
    116  }
    +
    117 
    +
    118  static std::unique_ptr<StreamData> FromScte35Event(
    +
    119  size_t stream_index,
    +
    120  std::shared_ptr<const Scte35Event> scte35_event) {
    +
    121  std::unique_ptr<StreamData> stream_data(new StreamData);
    +
    122  stream_data->stream_index = stream_index;
    +
    123  stream_data->stream_data_type = StreamDataType::kScte35Event;
    +
    124  stream_data->scte35_event = std::move(scte35_event);
    +
    125  return stream_data;
    +
    126  }
    +
    127 
    +
    128  static std::unique_ptr<StreamData> FromCueEvent(
    +
    129  size_t stream_index,
    +
    130  std::shared_ptr<const CueEvent> cue_event) {
    +
    131  std::unique_ptr<StreamData> stream_data(new StreamData);
    +
    132  stream_data->stream_index = stream_index;
    +
    133  stream_data->stream_data_type = StreamDataType::kCueEvent;
    +
    134  stream_data->cue_event = std::move(cue_event);
    +
    135  return stream_data;
    +
    136  }
    +
    137 };
    +
    138 
    + +
    155  public:
    +
    156  MediaHandler() = default;
    +
    157  virtual ~MediaHandler() = default;
    +
    158 
    +
    160  Status SetHandler(size_t output_stream_index,
    +
    161  std::shared_ptr<MediaHandler> handler);
    +
    162 
    +
    164  Status AddHandler(std::shared_ptr<MediaHandler> handler) {
    +
    165  return SetHandler(next_output_stream_index_, handler);
    +
    166  }
    +
    167 
    +
    170  Status Initialize();
    +
    171 
    +
    173  bool IsConnected() { return num_input_streams_ > 0; }
    +
    174 
    +
    175  static Status Chain(const std::vector<std::shared_ptr<MediaHandler>>& list);
    +
    176 
    +
    177  protected:
    +
    180  virtual Status InitializeInternal() = 0;
    +
    181 
    +
    186  virtual Status Process(std::unique_ptr<StreamData> stream_data) = 0;
    +
    187 
    +
    189  virtual Status OnFlushRequest(size_t input_stream_index);
    +
    190 
    +
    192  virtual bool ValidateOutputStreamIndex(size_t stream_index) const;
    +
    193 
    +
    196  Status Dispatch(std::unique_ptr<StreamData> stream_data) const;
    +
    197 
    + +
    200  size_t stream_index,
    +
    201  std::shared_ptr<const StreamInfo> stream_info) const {
    +
    202  return Dispatch(
    +
    203  StreamData::FromStreamInfo(stream_index, std::move(stream_info)));
    +
    204  }
    +
    205 
    + +
    208  size_t stream_index,
    +
    209  std::shared_ptr<const MediaSample> media_sample) const {
    +
    210  return Dispatch(
    +
    211  StreamData::FromMediaSample(stream_index, std::move(media_sample)));
    +
    212  }
    +
    213 
    +
    215  // DispatchTextSample should only be override for testing.
    + +
    217  size_t stream_index,
    +
    218  std::shared_ptr<const TextSample> text_sample) const {
    +
    219  return Dispatch(
    +
    220  StreamData::FromTextSample(stream_index, std::move(text_sample)));
    +
    221  }
    +
    222 
    + +
    225  size_t stream_index,
    +
    226  std::shared_ptr<const SegmentInfo> segment_info) const {
    +
    227  return Dispatch(
    +
    228  StreamData::FromSegmentInfo(stream_index, std::move(segment_info)));
    +
    229  }
    +
    230 
    + +
    233  size_t stream_index,
    +
    234  std::shared_ptr<const Scte35Event> scte35_event) const {
    +
    235  return Dispatch(
    +
    236  StreamData::FromScte35Event(stream_index, std::move(scte35_event)));
    +
    237  }
    +
    238 
    +
    240  Status DispatchCueEvent(size_t stream_index,
    +
    241  std::shared_ptr<const CueEvent> cue_event) const {
    +
    242  return Dispatch(
    +
    243  StreamData::FromCueEvent(stream_index, std::move(cue_event)));
    +
    244  }
    +
    245 
    +
    247  Status FlushDownstream(size_t output_stream_index);
    +
    248 
    + +
    251 
    +
    252  bool initialized() { return initialized_; }
    +
    253  size_t num_input_streams() const { return num_input_streams_; }
    +
    254  size_t next_output_stream_index() const { return next_output_stream_index_; }
    +
    255  const std::map<size_t, std::pair<std::shared_ptr<MediaHandler>, size_t>>&
    +
    256  output_handlers() {
    +
    257  return output_handlers_;
    +
    258  }
    +
    259 
    +
    260  private:
    +
    261  MediaHandler(const MediaHandler&) = delete;
    +
    262  MediaHandler& operator=(const MediaHandler&) = delete;
    +
    263 
    +
    264  bool initialized_ = false;
    +
    265  // Number of input streams.
    +
    266  size_t num_input_streams_ = 0;
    +
    267  // The next available output stream index, used by AddHandler.
    +
    268  size_t next_output_stream_index_ = 0;
    +
    269  // output stream index -> {output handler, output handler input stream index}
    +
    270  // map.
    +
    271  std::map<size_t, std::pair<std::shared_ptr<MediaHandler>, size_t>>
    +
    272  output_handlers_;
    +
    273 };
    +
    274 
    +
    275 } // namespace media
    +
    276 } // namespace shaka
    +
    277 
    +
    278 #endif // PACKAGER_MEDIA_BASE_MEDIA_HANDLER_H_
    + + +
    Status DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) const
    Dispatch the cue event to downstream handlers.
    +
    virtual Status InitializeInternal()=0
    +
    bool IsConnected()
    Validate if the handler is connected to its upstream handler.
    +
    Status SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
    Connect downstream handler at the specified output stream index.
    +
    Status DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) const
    Dispatch the segment info to downstream handlers.
    +
    virtual Status OnFlushRequest(size_t input_stream_index)
    Event handler for flush request at the specific input stream index.
    +
    Status DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
    Dispatch the media sample to downstream handlers.
    +
    Status DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
    Dispatch the text sample to downstream handlers.
    +
    Status DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) const
    Dispatch the scte35 event to downstream handlers.
    +
    Status FlushAllDownstreams()
    Flush all connected downstream handlers.
    +
    virtual bool ValidateOutputStreamIndex(size_t stream_index) const
    Validate if the stream at the specified index actually exists.
    +
    virtual Status Process(std::unique_ptr< StreamData > stream_data)=0
    +
    Status DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
    Dispatch the stream info to downstream handlers.
    +
    Status FlushDownstream(size_t output_stream_index)
    Flush the downstream connected at the specified output stream index.
    + +
    Status AddHandler(std::shared_ptr< MediaHandler > handler)
    Connect downstream handler to the next available output stream index.
    +
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    +
    All the methods that are virtual are virtual for mocking.
    + + + +
    diff --git a/docs/d3/d95/classshaka_1_1hls_1_1MockMediaPlaylist.html b/docs/d3/d95/classshaka_1_1hls_1_1MockMediaPlaylist.html index fabb1b0d9e..60c9b7fab5 100644 --- a/docs/d3/d95/classshaka_1_1hls_1_1MockMediaPlaylist.html +++ b/docs/d3/d95/classshaka_1_1hls_1_1MockMediaPlaylist.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::hls::MockMediaPlaylist Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::hls::MediaPlaylist - -
    +shaka::hls::MediaPlaylist + + @@ -117,6 +120,15 @@ Public Member Functions + + + + + + @@ -181,6 +193,12 @@ void  + + + + + + @@ -192,24 +210,27 @@ void  + +

    Public Member Functions

     MOCK_CONST_METHOD0 (GetNumChannels, int())
     
    MOCK_CONST_METHOD0 (GetEC3JocComplexity, int())
     
    MOCK_CONST_METHOD0 (GetAC4ImsFlag, bool())
     
    MOCK_CONST_METHOD0 (GetAC4CbiFlag, bool())
     
     MOCK_CONST_METHOD2 (GetDisplayResolution, bool(uint32_t *width, uint32_t *height))
     
     
    virtual int GetNumChannels () const
     
    virtual int GetEC3JocComplexity () const
     
    virtual bool GetAC4ImsFlag () const
     
    virtual bool GetAC4CbiFlag () const
     
    virtual bool GetDisplayResolution (uint32_t *width, uint32_t *height) const
     
    virtual std::string GetVideoRange () const
    const std::vector< std::string > & characteristics () const
     
    +bool is_dvs () const
     
    - -

    Additional Inherited Members

    - Public Types inherited from shaka::hls::MediaPlaylist
    enum  MediaPlaylistStreamType {
    -  kUnknown, -kAudio, -kVideo, -kVideoIFramesOnly, -
    +
    enum class  MediaPlaylistStreamType {
    +  kUnknown +, kAudio +, kVideo +, kVideoIFramesOnly +,
      kSubtitle
    }
     
    enum  EncryptionMethod { kNone, -kAes128, -kSampleAes, -kSampleAesCenc +
    enum class  EncryptionMethod { kNone +, kAes128 +, kSampleAes +, kSampleAesCenc }
     
    @@ -223,9 +244,7 @@ Additional Inherited Members diff --git a/docs/d3/d9a/classshaka_1_1media_1_1MediaHandlerGraphTestBase.html b/docs/d3/d9a/classshaka_1_1media_1_1MediaHandlerGraphTestBase.html index 98202b055d..2cdaa992cd 100644 --- a/docs/d3/d9a/classshaka_1_1media_1_1MediaHandlerGraphTestBase.html +++ b/docs/d3/d9a/classshaka_1_1media_1_1MediaHandlerGraphTestBase.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MediaHandlerGraphTestBase Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MediaHandlerTestBase - -
    + + @@ -147,7 +150,7 @@ std::unique_ptr<

    Detailed Description

    -

    Definition at line 364 of file media_handler_test_base.h.

    +

    Definition at line 360 of file media_handler_test_base.h.

    Member Function Documentation

    ◆ GetOutputStreamDataVector()

    @@ -173,7 +176,7 @@ std::unique_ptr<
    Returns
    the output stream data vector from handler.
    -

    Definition at line 368 of file media_handler_test_base.cc.

    +

    Definition at line 364 of file media_handler_test_base.cc.

    @@ -201,7 +204,7 @@ std::unique_ptr<
    Returns
    some a downstream handler that can be used for connecting.
    -

    Definition at line 385 of file media_handler_test_base.h.

    +

    Definition at line 381 of file media_handler_test_base.h.

    @@ -229,7 +232,7 @@ std::unique_ptr<
    Returns
    some random handler that can be used for testing.
    -

    Definition at line 382 of file media_handler_test_base.h.

    +

    Definition at line 378 of file media_handler_test_base.h.

    @@ -240,9 +243,7 @@ std::unique_ptr< diff --git a/docs/d3/d9a/classshaka_1_1media_1_1MediaHandlerGraphTestBase.png b/docs/d3/d9a/classshaka_1_1media_1_1MediaHandlerGraphTestBase.png index a97304a5553f0329245ec02a869dabdf3ce89efd..336c2934a024d77ba311f30ac5b6f2b2913be120 100644 GIT binary patch delta 1052 zcmZ{iZ7|z+0LOp-e}aZEqeltlEIMvw+?8lO#U#BFN3IiE4-s;0uk~y_)oC8|He9R1 zDJja>ooXWqZ7qtDbWCX2ScV&b!py$oW{i}+GBu5Llf{!VGJyy+4sgJ zV^HoYCxAj>{1AqgFjb+%RzKwSVP`~;DWTIpK`ChEXN*|NCOPqfq;7-9n^lFA;r;T4 zuxw-t&pGiE(01GI4B)D5Y|l{` z3j2u;xKFE}L<5vNR9-$j{RJQr=H(m$AtiMDr0hhqA=6&dsL7b`;=d;hhs1SUO(3ig z^su|ftH<955N2-;A|wI)ghh`$n1&K%`FGNAj&*+zwU`8T!g?r=rT{NqKP#0zY0wAC zG&YiPV@dfbqYL5;tI0Pww>W9`-CKF)&B;`HVl&2h#4x)cWKQo1Jbnpj*4OZZ%qBy$ zo`If9)xCGlnX5o$-QQ=>qIaAmFA>@uF+?WO;vSew3Z1`+>4-}79+>M*PlSEh*^yQ) zv1jc@uK4sWI|pT7k3G2SUE$<+gF$B6bC*W?Df5C&6QcwW<*mn@)AP` z?gVwK5wJJruGt7(6VuGPDt3zubK7fuQ)6Yv0I7?!)R%$r5hs0jbHM-VeDQg6Nl7|_ zEVaOdN$H@Fn5sD4+P9Fq9aiDXnqlat*B@milUZ3_2?+bv{t;ma?pTGcb0F2#xqIlw z#@#YM!&v?x;|gN3PQSU_Huu)a2T%XN{>M$N<>VN)@^J?2X9U6F(Eau9;7pK(@t1Zt zT(14Su?bV?se~1QF6uVo3gUjpQItJZ@Vs+D zm)NRpsf!uX!+BIc^7t}Wdq~YKmQ0ndqRW~rq~RLqYgG4}MT=c?s$3*pm=#`79ewx>CjU1g67 z*dN@P)Ltu?L^KmterwbmL}_W(E=aIIBc_q>VQPQV&AB!J@>ynmMyQERP# zU-trd|Gb~QUA5Nw!}?bM1TBHq3iqE{YyENEe**e2b_oOppgz9>`%kU4{-|yPP;0IK zf)YRiNC36g8dnJ*0VIG@N(n50TlEBptmpuq&)@{219&}uYy#l{WD`sP2>>9nlllTI ze|PHfcswGDhlogAC4dBw07OLM>Q4ZQh>XjQL_}P@Y_qeCm;J`X{+}CS*|6+?BBHLh zYn>GlxzOJNAR^{E(wed}qt5_vjm`Bb0v7nRu0JQPR zhTFK=yJ!2i15ooe5fL%hIee}-u_$z?52k80#1E7^aKT-pL?lkH(?G{rh)^=?) zCEx-$Hq-#xlqR8Kw~{-rfy*Z7WMSXJd;;b}IoYm_O9^-Jwtnq;FW=||^S%P=S9SZXANPrU)fc`3 zA|e5l01`j~5D|&11dsp{z~k|F1Qx)pdICgNbO6t1a01Z*yq-Tcf$#vb2_}F901#OT z03fmw06=6V0D#C!005Dd001H@lM4eEe>+u5DUn41h^qvU01^N|TulHhjSsSU*=A=O zFZ+#&{XaK^v*Gr!0$6oybo6v!TuW=Wc3NTH^OQ!Poae`L4*+9%uOIK2Esrr0R5k~IHJYOJ zd<8I42gg~l09bo~o?ig8II;bQUdEg?RU^**62aU00000NkvXX1g=70f(g{V A1poj5 diff --git a/docs/d3/d9c/encryption__handler_8cc_source.html b/docs/d3/d9c/encryption__handler_8cc_source.html index 8314e1e3b6..b2f3bc6108 100644 --- a/docs/d3/d9c/encryption__handler_8cc_source.html +++ b/docs/d3/d9c/encryption__handler_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto/encryption_handler.cc Source File @@ -29,18 +29,21 @@

    Protected Member Functions

    - + +/* @license-end */
    encryption_handler.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/crypto/encryption_handler.h"
    8 
    9 #include <stddef.h>
    10 #include <stdint.h>
    11 
    12 #include <algorithm>
    13 
    14 #include "packager/media/base/aes_encryptor.h"
    15 #include "packager/media/base/audio_stream_info.h"
    16 #include "packager/media/base/key_source.h"
    17 #include "packager/media/base/macros.h"
    18 #include "packager/media/base/media_sample.h"
    19 #include "packager/media/base/video_stream_info.h"
    20 #include "packager/media/crypto/aes_encryptor_factory.h"
    21 #include "packager/media/crypto/subsample_generator.h"
    22 #include "packager/status_macros.h"
    23 
    24 namespace shaka {
    25 namespace media {
    26 
    27 namespace {
    28 // The encryption handler only supports a single output.
    29 const size_t kStreamIndex = 0;
    30 
    31 // The default KID, KEY and IV for key rotation are all 0s.
    32 // They are placeholders and are not really being used to encrypt data.
    33 const uint8_t kKeyRotationDefaultKeyId[] = {
    34  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    35 };
    36 const uint8_t kKeyRotationDefaultKey[] = {
    37  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    38 };
    39 const uint8_t kKeyRotationDefaultIv[] = {
    40  0, 0, 0, 0, 0, 0, 0, 0,
    41 };
    42 
    43 std::string GetStreamLabelForEncryption(
    44  const StreamInfo& stream_info,
    45  const std::function<std::string(
    46  const EncryptionParams::EncryptedStreamAttributes& stream_attributes)>&
    47  stream_label_func) {
    48  EncryptionParams::EncryptedStreamAttributes stream_attributes;
    49  if (stream_info.stream_type() == kStreamAudio) {
    50  stream_attributes.stream_type =
    51  EncryptionParams::EncryptedStreamAttributes::kAudio;
    52  } else if (stream_info.stream_type() == kStreamVideo) {
    53  const VideoStreamInfo& video_stream_info =
    54  static_cast<const VideoStreamInfo&>(stream_info);
    55  stream_attributes.stream_type =
    56  EncryptionParams::EncryptedStreamAttributes::kVideo;
    57  stream_attributes.oneof.video.width = video_stream_info.width();
    58  stream_attributes.oneof.video.height = video_stream_info.height();
    59  }
    60  return stream_label_func(stream_attributes);
    61 }
    62 
    63 bool IsPatternEncryptionScheme(FourCC protection_scheme) {
    64  return protection_scheme == kAppleSampleAesProtectionScheme ||
    65  protection_scheme == FOURCC_cbcs || protection_scheme == FOURCC_cens;
    66 }
    67 
    68 } // namespace
    69 
    70 EncryptionHandler::EncryptionHandler(const EncryptionParams& encryption_params,
    71  KeySource* key_source)
    72  : encryption_params_(encryption_params),
    73  protection_scheme_(
    74  static_cast<FourCC>(encryption_params.protection_scheme)),
    75  key_source_(key_source),
    76  subsample_generator_(
    77  new SubsampleGenerator(encryption_params.vp9_subsample_encryption)),
    78  encryptor_factory_(new AesEncryptorFactory) {}
    79 
    80 EncryptionHandler::~EncryptionHandler() = default;
    81 
    83  if (!encryption_params_.stream_label_func) {
    84  return Status(error::INVALID_ARGUMENT, "Stream label function not set.");
    85  }
    86  if (num_input_streams() != 1 || next_output_stream_index() != 1) {
    87  return Status(error::INVALID_ARGUMENT,
    88  "Expects exactly one input and output.");
    89  }
    90  return Status::OK;
    91 }
    92 
    93 Status EncryptionHandler::Process(std::unique_ptr<StreamData> stream_data) {
    94  switch (stream_data->stream_data_type) {
    95  case StreamDataType::kStreamInfo:
    96  return ProcessStreamInfo(*stream_data->stream_info);
    97  case StreamDataType::kSegmentInfo: {
    98  std::shared_ptr<SegmentInfo> segment_info(new SegmentInfo(
    99  *stream_data->segment_info));
    100 
    101  segment_info->is_encrypted = remaining_clear_lead_ <= 0;
    102 
    103  const bool key_rotation_enabled = crypto_period_duration_ != 0;
    104  if (key_rotation_enabled)
    105  segment_info->key_rotation_encryption_config = encryption_config_;
    106  if (!segment_info->is_subsegment) {
    107  if (key_rotation_enabled)
    108  check_new_crypto_period_ = true;
    109  if (remaining_clear_lead_ > 0)
    110  remaining_clear_lead_ -= segment_info->duration;
    111  }
    112 
    113  return DispatchSegmentInfo(kStreamIndex, segment_info);
    114  }
    115  case StreamDataType::kMediaSample:
    116  return ProcessMediaSample(std::move(stream_data->media_sample));
    117  default:
    118  VLOG(3) << "Stream data type "
    119  << static_cast<int>(stream_data->stream_data_type) << " ignored.";
    120  return Dispatch(std::move(stream_data));
    121  }
    122 }
    123 
    124 Status EncryptionHandler::ProcessStreamInfo(const StreamInfo& clear_info) {
    125  if (clear_info.is_encrypted()) {
    126  return Status(error::INVALID_ARGUMENT,
    127  "Input stream is already encrypted.");
    128  }
    129 
    130  DCHECK_NE(kStreamUnknown, clear_info.stream_type());
    131  DCHECK_NE(kStreamText, clear_info.stream_type());
    132  std::shared_ptr<StreamInfo> stream_info = clear_info.Clone();
    133  RETURN_IF_ERROR(
    134  subsample_generator_->Initialize(protection_scheme_, *stream_info));
    135 
    136  remaining_clear_lead_ =
    137  encryption_params_.clear_lead_in_seconds * stream_info->time_scale();
    138  crypto_period_duration_ =
    139  encryption_params_.crypto_period_duration_in_seconds *
    140  stream_info->time_scale();
    141  codec_ = stream_info->codec();
    142  stream_label_ = GetStreamLabelForEncryption(
    143  *stream_info, encryption_params_.stream_label_func);
    144 
    145  SetupProtectionPattern(stream_info->stream_type());
    146 
    147  EncryptionKey encryption_key;
    148  const bool key_rotation_enabled = crypto_period_duration_ != 0;
    149  if (key_rotation_enabled) {
    150  check_new_crypto_period_ = true;
    151  // Setup dummy key id, key and iv to signal encryption for key rotation.
    152  encryption_key.key_id.assign(std::begin(kKeyRotationDefaultKeyId),
    153  std::end(kKeyRotationDefaultKeyId));
    154  encryption_key.key.assign(std::begin(kKeyRotationDefaultKey),
    155  std::end(kKeyRotationDefaultKey));
    156  encryption_key.iv.assign(std::begin(kKeyRotationDefaultIv),
    157  std::end(kKeyRotationDefaultIv));
    158  } else {
    159  RETURN_IF_ERROR(key_source_->GetKey(stream_label_, &encryption_key));
    160  }
    161  if (!CreateEncryptor(encryption_key))
    162  return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
    163 
    164  stream_info->set_is_encrypted(true);
    165  stream_info->set_has_clear_lead(encryption_params_.clear_lead_in_seconds > 0);
    166  stream_info->set_encryption_config(*encryption_config_);
    167 
    168  return DispatchStreamInfo(kStreamIndex, stream_info);
    169 }
    170 
    171 Status EncryptionHandler::ProcessMediaSample(
    172  std::shared_ptr<const MediaSample> clear_sample) {
    173  DCHECK(clear_sample);
    174 
    175  // Process the frame even if the frame is not encrypted as the next
    176  // (encrypted) frame may be dependent on this clear frame.
    177  std::vector<SubsampleEntry> subsamples;
    178  RETURN_IF_ERROR(subsample_generator_->GenerateSubsamples(
    179  clear_sample->data(), clear_sample->data_size(), &subsamples));
    180 
    181  // Need to setup the encryptor for new segments even if this segment does not
    182  // need to be encrypted, so we can signal encryption metadata earlier to
    183  // allows clients to prefetch the keys.
    184  if (check_new_crypto_period_) {
    185  // |dts| can be negative, e.g. after EditList adjustments. Normalized to 0
    186  // in that case.
    187  const int64_t dts = std::max(clear_sample->dts(), static_cast<int64_t>(0));
    188  const int64_t current_crypto_period_index = dts / crypto_period_duration_;
    189  const uint32_t crypto_period_duration_in_seconds =
    190  static_cast<uint32_t>(encryption_params_.crypto_period_duration_in_seconds);
    191  if (current_crypto_period_index != prev_crypto_period_index_) {
    192  EncryptionKey encryption_key;
    193  RETURN_IF_ERROR(key_source_->GetCryptoPeriodKey(
    194  current_crypto_period_index, crypto_period_duration_in_seconds,
    195  stream_label_, &encryption_key));
    196  if (!CreateEncryptor(encryption_key))
    197  return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
    198  prev_crypto_period_index_ = current_crypto_period_index;
    199  }
    200  check_new_crypto_period_ = false;
    201  }
    202 
    203  // Since there is no encryption needed right now, send the clear copy
    204  // downstream so we can save the costs of copying it.
    205  if (remaining_clear_lead_ > 0) {
    206  return DispatchMediaSample(kStreamIndex, std::move(clear_sample));
    207  }
    208 
    209  std::shared_ptr<uint8_t> cipher_sample_data(
    210  new uint8_t[clear_sample->data_size()], std::default_delete<uint8_t[]>());
    211 
    212  const uint8_t* source = clear_sample->data();
    213  uint8_t* dest = cipher_sample_data.get();
    214  if (!subsamples.empty()) {
    215  size_t total_size = 0;
    216  for (const SubsampleEntry& subsample : subsamples) {
    217  if (subsample.clear_bytes > 0) {
    218  memcpy(dest, source, subsample.clear_bytes);
    219  source += subsample.clear_bytes;
    220  dest += subsample.clear_bytes;
    221  total_size += subsample.clear_bytes;
    222  }
    223  if (subsample.cipher_bytes > 0) {
    224  EncryptBytes(source, subsample.cipher_bytes, dest);
    225  source += subsample.cipher_bytes;
    226  dest += subsample.cipher_bytes;
    227  total_size += subsample.cipher_bytes;
    228  }
    229  }
    230  DCHECK_EQ(total_size, clear_sample->data_size());
    231  } else {
    232  EncryptBytes(source, clear_sample->data_size(), dest);
    233  }
    234 
    235  std::shared_ptr<MediaSample> cipher_sample(clear_sample->Clone());
    236  cipher_sample->TransferData(std::move(cipher_sample_data),
    237  clear_sample->data_size());
    238 
    239  // Finish initializing the sample before sending it downstream. We must
    240  // wait until now to finish the initialization as we will lose access to
    241  // |decrypt_config| once we set it.
    242  cipher_sample->set_is_encrypted(true);
    243  std::unique_ptr<DecryptConfig> decrypt_config(new DecryptConfig(
    244  encryption_config_->key_id, encryptor_->iv(), subsamples,
    245  protection_scheme_, crypt_byte_block_, skip_byte_block_));
    246  cipher_sample->set_decrypt_config(std::move(decrypt_config));
    247 
    248  encryptor_->UpdateIv();
    249 
    250  return DispatchMediaSample(kStreamIndex, std::move(cipher_sample));
    251 }
    252 
    253 void EncryptionHandler::SetupProtectionPattern(StreamType stream_type) {
    254  if (stream_type == kStreamVideo &&
    255  IsPatternEncryptionScheme(protection_scheme_)) {
    256  // Use 1:9 pattern.
    257  crypt_byte_block_ = 1u;
    258  skip_byte_block_ = 9u;
    259  } else {
    260  // Audio stream in pattern encryption scheme does not use pattern; it uses
    261  // whole-block full sample encryption instead. Non-pattern encryption does
    262  // not have pattern.
    263  crypt_byte_block_ = 0u;
    264  skip_byte_block_ = 0u;
    265  }
    266 }
    267 
    268 bool EncryptionHandler::CreateEncryptor(const EncryptionKey& encryption_key) {
    269  std::unique_ptr<AesCryptor> encryptor = encryptor_factory_->CreateEncryptor(
    270  protection_scheme_, crypt_byte_block_, skip_byte_block_, codec_,
    271  encryption_key.key, encryption_key.iv);
    272  if (!encryptor)
    273  return false;
    274  encryptor_ = std::move(encryptor);
    275 
    276  encryption_config_.reset(new EncryptionConfig);
    277  encryption_config_->protection_scheme = protection_scheme_;
    278  encryption_config_->crypt_byte_block = crypt_byte_block_;
    279  encryption_config_->skip_byte_block = skip_byte_block_;
    280 
    281  const std::vector<uint8_t>& iv = encryptor_->iv();
    282  if (encryptor_->use_constant_iv()) {
    283  encryption_config_->per_sample_iv_size = 0;
    284  encryption_config_->constant_iv = iv;
    285  } else {
    286  encryption_config_->per_sample_iv_size = static_cast<uint8_t>(iv.size());
    287  }
    288 
    289  encryption_config_->key_id = encryption_key.key_id;
    290  encryption_config_->key_system_info = encryption_key.key_system_info;
    291  return true;
    292 }
    293 
    294 void EncryptionHandler::EncryptBytes(const uint8_t* source,
    295  size_t source_size,
    296  uint8_t* dest) {
    297  DCHECK(source);
    298  DCHECK(dest);
    299  DCHECK(encryptor_);
    300  CHECK(encryptor_->Crypt(source, source_size, dest));
    301 }
    302 
    303 void EncryptionHandler::InjectSubsampleGeneratorForTesting(
    304  std::unique_ptr<SubsampleGenerator> generator) {
    305  subsample_generator_ = std::move(generator);
    306 }
    307 
    308 void EncryptionHandler::InjectEncryptorFactoryForTesting(
    309  std::unique_ptr<AesEncryptorFactory> encryptor_factory) {
    310  encryptor_factory_ = std::move(encryptor_factory);
    311 }
    312 
    313 } // namespace media
    314 } // namespace shaka
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    virtual std::unique_ptr< StreamInfo > Clone() const =0
    - - - -
    All the methods that are virtual are virtual for mocking.
    - - -
    Status Process(std::unique_ptr< StreamData > stream_data) override
    - - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/crypto/encryption_handler.h"
    +
    8 
    +
    9 #include <stddef.h>
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <algorithm>
    +
    13 
    +
    14 #include "packager/media/base/aes_encryptor.h"
    +
    15 #include "packager/media/base/audio_stream_info.h"
    +
    16 #include "packager/media/base/common_pssh_generator.h"
    +
    17 #include "packager/media/base/key_source.h"
    +
    18 #include "packager/media/base/macros.h"
    +
    19 #include "packager/media/base/media_sample.h"
    +
    20 #include "packager/media/base/playready_pssh_generator.h"
    +
    21 #include "packager/media/base/protection_system_ids.h"
    +
    22 #include "packager/media/base/video_stream_info.h"
    +
    23 #include "packager/media/base/widevine_pssh_generator.h"
    +
    24 #include "packager/media/crypto/aes_encryptor_factory.h"
    +
    25 #include "packager/media/crypto/subsample_generator.h"
    +
    26 #include "packager/status_macros.h"
    +
    27 
    +
    28 namespace shaka {
    +
    29 namespace media {
    +
    30 
    +
    31 namespace {
    +
    32 // The encryption handler only supports a single output.
    +
    33 const size_t kStreamIndex = 0;
    +
    34 
    +
    35 // The default KID, KEY and IV for key rotation are all 0s.
    +
    36 // They are placeholders and are not really being used to encrypt data.
    +
    37 const uint8_t kKeyRotationDefaultKeyId[] = {
    +
    38  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    +
    39 };
    +
    40 const uint8_t kKeyRotationDefaultKey[] = {
    +
    41  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    +
    42 };
    +
    43 const uint8_t kKeyRotationDefaultIv[] = {
    +
    44  0, 0, 0, 0, 0, 0, 0, 0,
    +
    45 };
    +
    46 
    +
    47 std::string GetStreamLabelForEncryption(
    +
    48  const StreamInfo& stream_info,
    +
    49  const std::function<std::string(
    +
    50  const EncryptionParams::EncryptedStreamAttributes& stream_attributes)>&
    +
    51  stream_label_func) {
    +
    52  EncryptionParams::EncryptedStreamAttributes stream_attributes;
    +
    53  if (stream_info.stream_type() == kStreamAudio) {
    +
    54  stream_attributes.stream_type =
    +
    55  EncryptionParams::EncryptedStreamAttributes::kAudio;
    +
    56  } else if (stream_info.stream_type() == kStreamVideo) {
    +
    57  const VideoStreamInfo& video_stream_info =
    +
    58  static_cast<const VideoStreamInfo&>(stream_info);
    +
    59  stream_attributes.stream_type =
    +
    60  EncryptionParams::EncryptedStreamAttributes::kVideo;
    +
    61  stream_attributes.oneof.video.width = video_stream_info.width();
    +
    62  stream_attributes.oneof.video.height = video_stream_info.height();
    +
    63  }
    +
    64  return stream_label_func(stream_attributes);
    +
    65 }
    +
    66 
    +
    67 bool IsPatternEncryptionScheme(FourCC protection_scheme) {
    +
    68  return protection_scheme == kAppleSampleAesProtectionScheme ||
    +
    69  protection_scheme == FOURCC_cbcs || protection_scheme == FOURCC_cens;
    +
    70 }
    +
    71 
    +
    72 void FillPsshGenerators(
    +
    73  const EncryptionParams& encryption_params,
    +
    74  std::vector<std::unique_ptr<PsshGenerator>>* pssh_generators,
    +
    75  std::vector<std::vector<uint8_t>>* no_pssh_systems) {
    +
    76  if (has_flag(encryption_params.protection_systems,
    + +
    78  pssh_generators->emplace_back(new CommonPsshGenerator());
    +
    79  }
    +
    80 
    +
    81  if (has_flag(encryption_params.protection_systems,
    +
    82  ProtectionSystem::kPlayReady)) {
    +
    83  pssh_generators->emplace_back(new PlayReadyPsshGenerator(
    +
    84  encryption_params.playready_extra_header_data,
    +
    85  static_cast<FourCC>(encryption_params.protection_scheme)));
    +
    86  }
    +
    87 
    +
    88  if (has_flag(encryption_params.protection_systems,
    +
    89  ProtectionSystem::kWidevine)) {
    +
    90  pssh_generators->emplace_back(new WidevinePsshGenerator(
    +
    91  static_cast<FourCC>(encryption_params.protection_scheme)));
    +
    92  }
    +
    93 
    +
    94  if (has_flag(encryption_params.protection_systems,
    +
    95  ProtectionSystem::kFairPlay)) {
    +
    96  no_pssh_systems->emplace_back(std::begin(kFairPlaySystemId),
    +
    97  std::end(kFairPlaySystemId));
    +
    98  }
    +
    99  // We only support Marlin Adaptive Streaming Specification – Simple Profile
    +
    100  // with Implicit Content ID Mapping, which does not need a PSSH. Marlin
    +
    101  // specific PSSH with Explicit Content ID Mapping is not generated.
    +
    102  if (has_flag(encryption_params.protection_systems,
    +
    103  ProtectionSystem::kMarlin)) {
    +
    104  no_pssh_systems->emplace_back(std::begin(kMarlinSystemId),
    +
    105  std::end(kMarlinSystemId));
    +
    106  }
    +
    107 
    +
    108  if (pssh_generators->empty() && no_pssh_systems->empty() &&
    +
    109  (encryption_params.key_provider != KeyProvider::kRawKey ||
    +
    110  encryption_params.raw_key.pssh.empty())) {
    +
    111  pssh_generators->emplace_back(new CommonPsshGenerator());
    +
    112  }
    +
    113 }
    +
    114 
    +
    115 void AddProtectionSystemIfNotExist(
    +
    116  const ProtectionSystemSpecificInfo& pssh_info,
    +
    117  EncryptionConfig* encryption_config) {
    +
    118  for (const auto& info : encryption_config->key_system_info) {
    +
    119  if (info.system_id == pssh_info.system_id)
    +
    120  return;
    +
    121  }
    +
    122  encryption_config->key_system_info.push_back(pssh_info);
    +
    123 }
    +
    124 
    +
    125 Status FillProtectionSystemInfo(const EncryptionParams& encryption_params,
    +
    126  const EncryptionKey& encryption_key,
    +
    127  EncryptionConfig* encryption_config) {
    +
    128  // If generating dummy keys for key rotation, don't generate PSSH info.
    +
    129  if (encryption_key.key_ids.empty())
    +
    130  return Status::OK;
    +
    131 
    +
    132  std::vector<std::unique_ptr<PsshGenerator>> pssh_generators;
    +
    133  std::vector<std::vector<uint8_t>> no_pssh_systems;
    +
    134  FillPsshGenerators(encryption_params, &pssh_generators, &no_pssh_systems);
    +
    135 
    +
    136  encryption_config->key_system_info = encryption_key.key_system_info;
    +
    137  for (const auto& pssh_generator : pssh_generators) {
    +
    138  const bool support_multiple_keys = pssh_generator->SupportMultipleKeys();
    +
    139  if (support_multiple_keys) {
    +
    140  ProtectionSystemSpecificInfo info;
    +
    141  RETURN_IF_ERROR(pssh_generator->GeneratePsshFromKeyIds(
    +
    142  encryption_key.key_ids, &info));
    +
    143  AddProtectionSystemIfNotExist(info, encryption_config);
    +
    144  } else {
    +
    145  ProtectionSystemSpecificInfo info;
    +
    146  RETURN_IF_ERROR(pssh_generator->GeneratePsshFromKeyIdAndKey(
    +
    147  encryption_key.key_id, encryption_key.key, &info));
    +
    148  AddProtectionSystemIfNotExist(info, encryption_config);
    +
    149  }
    +
    150  }
    +
    151 
    +
    152  for (const auto& no_pssh_system : no_pssh_systems) {
    +
    153  ProtectionSystemSpecificInfo info;
    +
    154  info.system_id = no_pssh_system;
    +
    155  AddProtectionSystemIfNotExist(info, encryption_config);
    +
    156  }
    +
    157 
    +
    158  return Status::OK;
    +
    159 }
    +
    160 
    +
    161 } // namespace
    +
    162 
    +
    163 EncryptionHandler::EncryptionHandler(const EncryptionParams& encryption_params,
    +
    164  KeySource* key_source)
    +
    165  : encryption_params_(encryption_params),
    +
    166  protection_scheme_(
    +
    167  static_cast<FourCC>(encryption_params.protection_scheme)),
    +
    168  key_source_(key_source),
    +
    169  subsample_generator_(
    +
    170  new SubsampleGenerator(encryption_params.vp9_subsample_encryption)),
    +
    171  encryptor_factory_(new AesEncryptorFactory) {}
    +
    172 
    +
    173 EncryptionHandler::~EncryptionHandler() = default;
    +
    174 
    +
    175 Status EncryptionHandler::InitializeInternal() {
    +
    176  if (!encryption_params_.stream_label_func) {
    +
    177  return Status(error::INVALID_ARGUMENT, "Stream label function not set.");
    +
    178  }
    +
    179  if (num_input_streams() != 1 || next_output_stream_index() != 1) {
    +
    180  return Status(error::INVALID_ARGUMENT,
    +
    181  "Expects exactly one input and output.");
    +
    182  }
    +
    183  return Status::OK;
    +
    184 }
    +
    185 
    +
    186 Status EncryptionHandler::Process(std::unique_ptr<StreamData> stream_data) {
    +
    187  switch (stream_data->stream_data_type) {
    +
    188  case StreamDataType::kStreamInfo:
    +
    189  return ProcessStreamInfo(*stream_data->stream_info);
    +
    190  case StreamDataType::kSegmentInfo: {
    +
    191  std::shared_ptr<SegmentInfo> segment_info(new SegmentInfo(
    +
    192  *stream_data->segment_info));
    +
    193 
    +
    194  segment_info->is_encrypted = remaining_clear_lead_ <= 0;
    +
    195 
    +
    196  const bool key_rotation_enabled = crypto_period_duration_ != 0;
    +
    197  if (key_rotation_enabled)
    +
    198  segment_info->key_rotation_encryption_config = encryption_config_;
    +
    199  if (!segment_info->is_subsegment) {
    +
    200  if (key_rotation_enabled)
    +
    201  check_new_crypto_period_ = true;
    +
    202  if (remaining_clear_lead_ > 0)
    +
    203  remaining_clear_lead_ -= segment_info->duration;
    +
    204  }
    +
    205 
    +
    206  return DispatchSegmentInfo(kStreamIndex, segment_info);
    +
    207  }
    +
    208  case StreamDataType::kMediaSample:
    +
    209  return ProcessMediaSample(std::move(stream_data->media_sample));
    +
    210  default:
    +
    211  VLOG(3) << "Stream data type "
    +
    212  << static_cast<int>(stream_data->stream_data_type) << " ignored.";
    +
    213  return Dispatch(std::move(stream_data));
    +
    214  }
    +
    215 }
    +
    216 
    +
    217 Status EncryptionHandler::ProcessStreamInfo(const StreamInfo& clear_info) {
    +
    218  if (clear_info.is_encrypted()) {
    +
    219  return Status(error::INVALID_ARGUMENT,
    +
    220  "Input stream is already encrypted.");
    +
    221  }
    +
    222 
    +
    223  DCHECK_NE(kStreamUnknown, clear_info.stream_type());
    +
    224  DCHECK_NE(kStreamText, clear_info.stream_type());
    +
    225  std::shared_ptr<StreamInfo> stream_info = clear_info.Clone();
    +
    226  RETURN_IF_ERROR(
    +
    227  subsample_generator_->Initialize(protection_scheme_, *stream_info));
    +
    228 
    +
    229  remaining_clear_lead_ =
    +
    230  encryption_params_.clear_lead_in_seconds * stream_info->time_scale();
    +
    231  crypto_period_duration_ =
    +
    232  encryption_params_.crypto_period_duration_in_seconds *
    +
    233  stream_info->time_scale();
    +
    234  codec_ = stream_info->codec();
    +
    235  stream_label_ = GetStreamLabelForEncryption(
    +
    236  *stream_info, encryption_params_.stream_label_func);
    +
    237 
    +
    238  SetupProtectionPattern(stream_info->stream_type());
    +
    239 
    +
    240  EncryptionKey encryption_key;
    +
    241  const bool key_rotation_enabled = crypto_period_duration_ != 0;
    +
    242  if (key_rotation_enabled) {
    +
    243  check_new_crypto_period_ = true;
    +
    244  // Setup dummy key id, key and iv to signal encryption for key rotation.
    +
    245  encryption_key.key_id.assign(std::begin(kKeyRotationDefaultKeyId),
    +
    246  std::end(kKeyRotationDefaultKeyId));
    +
    247  encryption_key.key.assign(std::begin(kKeyRotationDefaultKey),
    +
    248  std::end(kKeyRotationDefaultKey));
    +
    249  encryption_key.iv.assign(std::begin(kKeyRotationDefaultIv),
    +
    250  std::end(kKeyRotationDefaultIv));
    +
    251  } else {
    +
    252  RETURN_IF_ERROR(key_source_->GetKey(stream_label_, &encryption_key));
    +
    253  }
    +
    254  if (!CreateEncryptor(encryption_key))
    +
    255  return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
    +
    256 
    +
    257  stream_info->set_is_encrypted(true);
    +
    258  stream_info->set_has_clear_lead(encryption_params_.clear_lead_in_seconds > 0);
    +
    259  stream_info->set_encryption_config(*encryption_config_);
    +
    260 
    +
    261  return DispatchStreamInfo(kStreamIndex, stream_info);
    +
    262 }
    +
    263 
    +
    264 Status EncryptionHandler::ProcessMediaSample(
    +
    265  std::shared_ptr<const MediaSample> clear_sample) {
    +
    266  DCHECK(clear_sample);
    +
    267 
    +
    268  // Process the frame even if the frame is not encrypted as the next
    +
    269  // (encrypted) frame may be dependent on this clear frame.
    +
    270  std::vector<SubsampleEntry> subsamples;
    +
    271  RETURN_IF_ERROR(subsample_generator_->GenerateSubsamples(
    +
    272  clear_sample->data(), clear_sample->data_size(), &subsamples));
    +
    273 
    +
    274  // Need to setup the encryptor for new segments even if this segment does not
    +
    275  // need to be encrypted, so we can signal encryption metadata earlier to
    +
    276  // allows clients to prefetch the keys.
    +
    277  if (check_new_crypto_period_) {
    +
    278  // |dts| can be negative, e.g. after EditList adjustments. Normalized to 0
    +
    279  // in that case.
    +
    280  const int64_t dts = std::max(clear_sample->dts(), static_cast<int64_t>(0));
    +
    281  const int64_t current_crypto_period_index = dts / crypto_period_duration_;
    +
    282  const uint32_t crypto_period_duration_in_seconds =
    +
    283  static_cast<uint32_t>(encryption_params_.crypto_period_duration_in_seconds);
    +
    284  if (current_crypto_period_index != prev_crypto_period_index_) {
    +
    285  EncryptionKey encryption_key;
    +
    286  RETURN_IF_ERROR(key_source_->GetCryptoPeriodKey(
    +
    287  current_crypto_period_index, crypto_period_duration_in_seconds,
    +
    288  stream_label_, &encryption_key));
    +
    289  if (!CreateEncryptor(encryption_key))
    +
    290  return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
    +
    291  prev_crypto_period_index_ = current_crypto_period_index;
    +
    292  }
    +
    293  check_new_crypto_period_ = false;
    +
    294  }
    +
    295 
    +
    296  // Since there is no encryption needed right now, send the clear copy
    +
    297  // downstream so we can save the costs of copying it.
    +
    298  if (remaining_clear_lead_ > 0) {
    +
    299  return DispatchMediaSample(kStreamIndex, std::move(clear_sample));
    +
    300  }
    +
    301 
    +
    302  std::shared_ptr<uint8_t> cipher_sample_data(
    +
    303  new uint8_t[clear_sample->data_size()], std::default_delete<uint8_t[]>());
    +
    304 
    +
    305  const uint8_t* source = clear_sample->data();
    +
    306  uint8_t* dest = cipher_sample_data.get();
    +
    307  if (!subsamples.empty()) {
    +
    308  size_t total_size = 0;
    +
    309  for (const SubsampleEntry& subsample : subsamples) {
    +
    310  if (subsample.clear_bytes > 0) {
    +
    311  memcpy(dest, source, subsample.clear_bytes);
    +
    312  source += subsample.clear_bytes;
    +
    313  dest += subsample.clear_bytes;
    +
    314  total_size += subsample.clear_bytes;
    +
    315  }
    +
    316  if (subsample.cipher_bytes > 0) {
    +
    317  EncryptBytes(source, subsample.cipher_bytes, dest);
    +
    318  source += subsample.cipher_bytes;
    +
    319  dest += subsample.cipher_bytes;
    +
    320  total_size += subsample.cipher_bytes;
    +
    321  }
    +
    322  }
    +
    323  DCHECK_EQ(total_size, clear_sample->data_size());
    +
    324  } else {
    +
    325  EncryptBytes(source, clear_sample->data_size(), dest);
    +
    326  }
    +
    327 
    +
    328  std::shared_ptr<MediaSample> cipher_sample(clear_sample->Clone());
    +
    329  cipher_sample->TransferData(std::move(cipher_sample_data),
    +
    330  clear_sample->data_size());
    +
    331 
    +
    332  // Finish initializing the sample before sending it downstream. We must
    +
    333  // wait until now to finish the initialization as we will lose access to
    +
    334  // |decrypt_config| once we set it.
    +
    335  cipher_sample->set_is_encrypted(true);
    +
    336  std::unique_ptr<DecryptConfig> decrypt_config(new DecryptConfig(
    +
    337  encryption_config_->key_id, encryptor_->iv(), subsamples,
    +
    338  protection_scheme_, crypt_byte_block_, skip_byte_block_));
    +
    339  cipher_sample->set_decrypt_config(std::move(decrypt_config));
    +
    340 
    +
    341  encryptor_->UpdateIv();
    +
    342 
    +
    343  return DispatchMediaSample(kStreamIndex, std::move(cipher_sample));
    +
    344 }
    +
    345 
    +
    346 void EncryptionHandler::SetupProtectionPattern(StreamType stream_type) {
    +
    347  if (stream_type == kStreamVideo &&
    +
    348  IsPatternEncryptionScheme(protection_scheme_)) {
    +
    349  crypt_byte_block_ = encryption_params_.crypt_byte_block;
    +
    350  skip_byte_block_ = encryption_params_.skip_byte_block;
    +
    351  } else {
    +
    352  // Audio stream in pattern encryption scheme does not use pattern; it uses
    +
    353  // whole-block full sample encryption instead. Non-pattern encryption does
    +
    354  // not have pattern.
    +
    355  crypt_byte_block_ = 0u;
    +
    356  skip_byte_block_ = 0u;
    +
    357  }
    +
    358 }
    +
    359 
    +
    360 bool EncryptionHandler::CreateEncryptor(const EncryptionKey& encryption_key) {
    +
    361  std::unique_ptr<AesCryptor> encryptor = encryptor_factory_->CreateEncryptor(
    +
    362  protection_scheme_, crypt_byte_block_, skip_byte_block_, codec_,
    +
    363  encryption_key.key, encryption_key.iv);
    +
    364  if (!encryptor)
    +
    365  return false;
    +
    366  encryptor_ = std::move(encryptor);
    +
    367 
    +
    368  encryption_config_.reset(new EncryptionConfig);
    +
    369  encryption_config_->protection_scheme = protection_scheme_;
    +
    370  encryption_config_->crypt_byte_block = crypt_byte_block_;
    +
    371  encryption_config_->skip_byte_block = skip_byte_block_;
    +
    372 
    +
    373  const std::vector<uint8_t>& iv = encryptor_->iv();
    +
    374  if (encryptor_->use_constant_iv()) {
    +
    375  encryption_config_->per_sample_iv_size = 0;
    +
    376  encryption_config_->constant_iv = iv;
    +
    377  } else {
    +
    378  encryption_config_->per_sample_iv_size = static_cast<uint8_t>(iv.size());
    +
    379  }
    +
    380 
    +
    381  encryption_config_->key_id = encryption_key.key_id;
    +
    382  const auto status = FillProtectionSystemInfo(
    +
    383  encryption_params_, encryption_key, encryption_config_.get());
    +
    384  return status.ok();
    +
    385 }
    +
    386 
    +
    387 void EncryptionHandler::EncryptBytes(const uint8_t* source,
    +
    388  size_t source_size,
    +
    389  uint8_t* dest) {
    +
    390  DCHECK(source);
    +
    391  DCHECK(dest);
    +
    392  DCHECK(encryptor_);
    +
    393  CHECK(encryptor_->Crypt(source, source_size, dest));
    +
    394 }
    +
    395 
    +
    396 void EncryptionHandler::InjectSubsampleGeneratorForTesting(
    +
    397  std::unique_ptr<SubsampleGenerator> generator) {
    +
    398  subsample_generator_ = std::move(generator);
    +
    399 }
    +
    400 
    +
    401 void EncryptionHandler::InjectEncryptorFactoryForTesting(
    +
    402  std::unique_ptr<AesEncryptorFactory> encryptor_factory) {
    +
    403  encryptor_factory_ = std::move(encryptor_factory);
    +
    404 }
    +
    405 
    +
    406 } // namespace media
    +
    407 } // namespace shaka
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    virtual std::unique_ptr< StreamInfo > Clone() const =0
    +
    All the methods that are virtual are virtual for mocking.
    +
    @ kCommon
    The common key system from EME: https://goo.gl/s8RIhr.
    +
    diff --git a/docs/d3/da0/ec3__audio__util_8h_source.html b/docs/d3/da0/ec3__audio__util_8h_source.html index 87c1e4b8c7..9a5b89b586 100644 --- a/docs/d3/da0/ec3__audio__util_8h_source.html +++ b/docs/d3/da0/ec3__audio__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/ec3_audio_util.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    ec3_audio_util.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Enhanced AC3 audio utility functions.
    8 
    9 #ifndef PACKAGER_MEDIA_CODECS_EC3_AUDIO_UTIL_H_
    10 #define PACKAGER_MEDIA_CODECS_EC3_AUDIO_UTIL_H_
    11 
    12 #include <stddef.h>
    13 #include <stdint.h>
    14 #include <vector>
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    22 bool CalculateEC3ChannelMap(const std::vector<uint8_t>& ec3_data,
    23  uint32_t* channel_map);
    24 
    28 size_t GetEc3NumChannels(const std::vector<uint8_t>& ec3_data);
    29 
    30 } // namespace media
    31 } // namespace shaka
    32 
    33 #endif // PACKAGER_MEDIA_CODECS_EC3_AUDIO_UTIL_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Enhanced AC3 audio utility functions.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_CODECS_EC3_AUDIO_UTIL_H_
    +
    10 #define PACKAGER_MEDIA_CODECS_EC3_AUDIO_UTIL_H_
    +
    11 
    +
    12 #include <stddef.h>
    +
    13 #include <stdint.h>
    +
    14 #include <vector>
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    22 bool CalculateEC3ChannelMap(const std::vector<uint8_t>& ec3_data,
    +
    23  uint32_t* channel_map);
    +
    24 
    +
    28 size_t GetEc3NumChannels(const std::vector<uint8_t>& ec3_data);
    +
    29 
    +
    34 bool CalculateEC3ChannelMPEGValue(const std::vector<uint8_t>& ec3_data,
    +
    35  uint32_t* ec3_channel_mpeg_value);
    +
    36 
    +
    40 bool GetEc3JocComplexity(const std::vector<uint8_t>& ec3_data,
    +
    41  uint32_t* ec3_joc_complexity);
    +
    42 
    +
    43 } // namespace media
    +
    44 } // namespace shaka
    +
    45 
    +
    46 #endif // PACKAGER_MEDIA_CODECS_EC3_AUDIO_UTIL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/da1/classshaka_1_1media_1_1webm_1_1SingleSegmentSegmenter.html b/docs/d3/da1/classshaka_1_1media_1_1webm_1_1SingleSegmentSegmenter.html index a8861305e1..bf12441de0 100644 --- a/docs/d3/da1/classshaka_1_1media_1_1webm_1_1SingleSegmentSegmenter.html +++ b/docs/d3/da1/classshaka_1_1media_1_1webm_1_1SingleSegmentSegmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::webm::SingleSegmentSegmenter Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::webm::Segmenter shaka::media::webm::TwoPassSingleSegmentSegmenter - -
    + + @@ -158,7 +161,7 @@ uint64_t  - + @@ -282,9 +285,7 @@ uint64_t 

    Public Member Functions

     
    void UpdateProgress (uint64_t progress)
     Update segmentation progress using ProgressListener.
     Update segmentation progress using ProgressListener.
     
    void set_progress_target (uint64_t target)
    duration () c diff --git a/docs/d3/da2/structshaka_1_1media_1_1mp4_1_1SchemeType.html b/docs/d3/da2/structshaka_1_1media_1_1mp4_1_1SchemeType.html index 9e219ed1ca..84a7540986 100644 --- a/docs/d3/da2/structshaka_1_1media_1_1mp4_1_1SchemeType.html +++ b/docs/d3/da2/structshaka_1_1media_1_1mp4_1_1SchemeType.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SchemeType Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -124,7 +127,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 136 of file box_definitions.h.

    +

    Definition at line 137 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -152,7 +155,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 403 of file box_definitions.cc.

    +

    Definition at line 415 of file box_definitions.cc.

    @@ -163,9 +166,7 @@ Additional Inherited Members diff --git a/docs/d3/da5/structshaka_1_1MpdParams_1_1UtcTiming-members.html b/docs/d3/da5/structshaka_1_1MpdParams_1_1UtcTiming-members.html index ae9732a6ff..f8bbdeeddc 100644 --- a/docs/d3/da5/structshaka_1_1MpdParams_1_1UtcTiming-members.html +++ b/docs/d3/da5/structshaka_1_1MpdParams_1_1UtcTiming-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d3/dad/structshaka_1_1media_1_1mp4_1_1ID3v2.html b/docs/d3/dad/structshaka_1_1media_1_1mp4_1_1ID3v2.html index 405aa395ef..4c00adbb1c 100644 --- a/docs/d3/dad/structshaka_1_1media_1_1mp4_1_1ID3v2.html +++ b/docs/d3/dad/structshaka_1_1media_1_1mp4_1_1ID3v2.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::ID3v2 Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -130,7 +133,7 @@ Additional Inherited Members

    Detailed Description

    Implemented per http://mp4ra.org/#/references.

    -

    Definition at line 241 of file box_definitions.h.

    +

    Definition at line 242 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -158,7 +161,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1361 of file box_definitions.cc.

    +

    Definition at line 1387 of file box_definitions.cc.

    @@ -169,9 +172,7 @@ Additional Inherited Members diff --git a/docs/d3/db4/classshaka_1_1media_1_1WebMWebVTTParser-members.html b/docs/d3/db4/classshaka_1_1media_1_1WebMWebVTTParser-members.html index 131d805500..5561064553 100644 --- a/docs/d3/db4/classshaka_1_1media_1_1WebMWebVTTParser-members.html +++ b/docs/d3/db4/classshaka_1_1media_1_1WebMWebVTTParser-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    diff --git a/docs/d3/db5/structshaka_1_1media_1_1mp4_1_1Track.html b/docs/d3/db5/structshaka_1_1media_1_1mp4_1_1Track.html index bd3cbc6b63..6f7edfbfde 100644 --- a/docs/d3/db5/structshaka_1_1media_1_1mp4_1_1Track.html +++ b/docs/d3/db5/structshaka_1_1media_1_1mp4_1_1Track.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Track Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 635 of file box_definitions.h.

    +

    Definition at line 653 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2215 of file box_definitions.cc.

    +

    Definition at line 2296 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/d3/db6/webm__parser_8cc_source.html b/docs/d3/db6/webm__parser_8cc_source.html index 393b397e06..711492c59d 100644 --- a/docs/d3/db6/webm__parser_8cc_source.html +++ b/docs/d3/db6/webm__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webm_parser.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/webm/webm_parser.h"
    6 
    7 // This file contains code to parse WebM file elements. It was created
    8 // from information in the Matroska spec.
    9 // http://www.matroska.org/technical/specs/index.html
    10 // This file contains code for encrypted WebM. Current WebM
    11 // encrypted request for comments specification is here
    12 // http://wiki.webmproject.org/encryption/webm-encryption-rfc
    13 
    14 #include <limits>
    15 
    16 #include "packager/base/logging.h"
    17 #include "packager/base/numerics/safe_conversions.h"
    18 #include "packager/media/formats/webm/webm_constants.h"
    19 
    20 namespace shaka {
    21 namespace media {
    22 
    23 enum ElementType {
    24  UNKNOWN,
    25  LIST, // Referred to as Master Element in the Matroska spec.
    26  UINT,
    27  FLOAT,
    28  BINARY,
    29  STRING,
    30  SKIP,
    31 };
    32 
    33 struct ElementIdInfo {
    34  ElementType type_;
    35  int id_;
    36 };
    37 
    38 struct ListElementInfo {
    39  int id_;
    40  int level_;
    41  const ElementIdInfo* id_info_;
    42  int id_info_count_;
    43 };
    44 
    45 // The following are tables indicating what IDs are valid sub-elements
    46 // of particular elements. If an element is encountered that doesn't
    47 // appear in the list, a parsing error is signalled. Some elements are
    48 // marked as SKIP because they are valid, but we don't care about them
    49 // right now.
    50 static const ElementIdInfo kEBMLHeaderIds[] = {
    51  {UINT, kWebMIdEBMLVersion},
    52  {UINT, kWebMIdEBMLReadVersion},
    53  {UINT, kWebMIdEBMLMaxIDLength},
    54  {UINT, kWebMIdEBMLMaxSizeLength},
    55  {STRING, kWebMIdDocType},
    56  {UINT, kWebMIdDocTypeVersion},
    57  {UINT, kWebMIdDocTypeReadVersion},
    58 };
    59 
    60 static const ElementIdInfo kSegmentIds[] = {
    61  {LIST, kWebMIdSeekHead},
    62  {LIST, kWebMIdInfo},
    63  {LIST, kWebMIdCluster},
    64  {LIST, kWebMIdTracks},
    65  {LIST, kWebMIdCues},
    66  {LIST, kWebMIdAttachments},
    67  {LIST, kWebMIdChapters},
    68  {LIST, kWebMIdTags},
    69 };
    70 
    71 static const ElementIdInfo kSeekHeadIds[] = {
    72  {LIST, kWebMIdSeek},
    73 };
    74 
    75 static const ElementIdInfo kSeekIds[] = {
    76  {BINARY, kWebMIdSeekID},
    77  {UINT, kWebMIdSeekPosition},
    78 };
    79 
    80 static const ElementIdInfo kInfoIds[] = {
    81  {BINARY, kWebMIdSegmentUID},
    82  {STRING, kWebMIdSegmentFilename},
    83  {BINARY, kWebMIdPrevUID},
    84  {STRING, kWebMIdPrevFilename},
    85  {BINARY, kWebMIdNextUID},
    86  {STRING, kWebMIdNextFilename},
    87  {BINARY, kWebMIdSegmentFamily},
    88  {LIST, kWebMIdChapterTranslate},
    89  {UINT, kWebMIdTimecodeScale},
    90  {FLOAT, kWebMIdDuration},
    91  {BINARY, kWebMIdDateUTC},
    92  {STRING, kWebMIdTitle},
    93  {STRING, kWebMIdMuxingApp},
    94  {STRING, kWebMIdWritingApp},
    95 };
    96 
    97 static const ElementIdInfo kChapterTranslateIds[] = {
    98  {UINT, kWebMIdChapterTranslateEditionUID},
    99  {UINT, kWebMIdChapterTranslateCodec},
    100  {BINARY, kWebMIdChapterTranslateID},
    101 };
    102 
    103 static const ElementIdInfo kClusterIds[] = {
    104  {BINARY, kWebMIdSimpleBlock},
    105  {UINT, kWebMIdTimecode},
    106  {LIST, kWebMIdSilentTracks},
    107  {UINT, kWebMIdPosition},
    108  {UINT, kWebMIdPrevSize},
    109  {LIST, kWebMIdBlockGroup},
    110 };
    111 
    112 static const ElementIdInfo kSilentTracksIds[] = {
    113  {UINT, kWebMIdSilentTrackNumber},
    114 };
    115 
    116 static const ElementIdInfo kBlockGroupIds[] = {
    117  {BINARY, kWebMIdBlock},
    118  {LIST, kWebMIdBlockAdditions},
    119  {UINT, kWebMIdBlockDuration},
    120  {UINT, kWebMIdReferencePriority},
    121  {BINARY, kWebMIdReferenceBlock},
    122  {BINARY, kWebMIdCodecState},
    123  {BINARY, kWebMIdDiscardPadding},
    124  {LIST, kWebMIdSlices},
    125 };
    126 
    127 static const ElementIdInfo kBlockAdditionsIds[] = {
    128  {LIST, kWebMIdBlockMore},
    129 };
    130 
    131 static const ElementIdInfo kBlockMoreIds[] = {
    132  {UINT, kWebMIdBlockAddID},
    133  {BINARY, kWebMIdBlockAdditional},
    134 };
    135 
    136 static const ElementIdInfo kSlicesIds[] = {
    137  {LIST, kWebMIdTimeSlice},
    138 };
    139 
    140 static const ElementIdInfo kTimeSliceIds[] = {
    141  {UINT, kWebMIdLaceNumber},
    142 };
    143 
    144 static const ElementIdInfo kTracksIds[] = {
    145  {LIST, kWebMIdTrackEntry},
    146 };
    147 
    148 static const ElementIdInfo kTrackEntryIds[] = {
    149  {UINT, kWebMIdTrackNumber},
    150  {BINARY, kWebMIdTrackUID},
    151  {UINT, kWebMIdTrackType},
    152  {UINT, kWebMIdFlagEnabled},
    153  {UINT, kWebMIdFlagDefault},
    154  {UINT, kWebMIdFlagForced},
    155  {UINT, kWebMIdFlagLacing},
    156  {UINT, kWebMIdMinCache},
    157  {UINT, kWebMIdMaxCache},
    158  {UINT, kWebMIdDefaultDuration},
    159  {FLOAT, kWebMIdTrackTimecodeScale},
    160  {UINT, kWebMIdMaxBlockAdditionId},
    161  {STRING, kWebMIdName},
    162  {STRING, kWebMIdLanguage},
    163  {STRING, kWebMIdCodecID},
    164  {BINARY, kWebMIdCodecPrivate},
    165  {STRING, kWebMIdCodecName},
    166  {UINT, kWebMIdAttachmentLink},
    167  {UINT, kWebMIdCodecDecodeAll},
    168  {UINT, kWebMIdTrackOverlay},
    169  {UINT, kWebMIdCodecDelay},
    170  {UINT, kWebMIdSeekPreRoll},
    171  {LIST, kWebMIdTrackTranslate},
    172  {LIST, kWebMIdVideo},
    173  {LIST, kWebMIdAudio},
    174  {LIST, kWebMIdTrackOperation},
    175  {LIST, kWebMIdContentEncodings},
    176 };
    177 
    178 static const ElementIdInfo kTrackTranslateIds[] = {
    179  {UINT, kWebMIdTrackTranslateEditionUID},
    180  {UINT, kWebMIdTrackTranslateCodec},
    181  {BINARY, kWebMIdTrackTranslateTrackID},
    182 };
    183 
    184 static const ElementIdInfo kVideoIds[] = {
    185  {UINT, kWebMIdFlagInterlaced},
    186  {UINT, kWebMIdStereoMode},
    187  {UINT, kWebMIdAlphaMode},
    188  {UINT, kWebMIdPixelWidth},
    189  {UINT, kWebMIdPixelHeight},
    190  {UINT, kWebMIdPixelCropBottom},
    191  {UINT, kWebMIdPixelCropTop},
    192  {UINT, kWebMIdPixelCropLeft},
    193  {UINT, kWebMIdPixelCropRight},
    194  {UINT, kWebMIdDisplayWidth},
    195  {UINT, kWebMIdDisplayHeight},
    196  {UINT, kWebMIdDisplayUnit},
    197  {UINT, kWebMIdAspectRatioType},
    198  {BINARY, kWebMIdColorSpace},
    199  {FLOAT, kWebMIdFrameRate},
    200  {LIST, kWebMIdColor},
    201 };
    202 
    203 static const ElementIdInfo kColorIds[] = {
    204  {UINT, kWebMIdColorMatrixCoefficients},
    205  {UINT, kWebMIdColorBitsPerChannel},
    206  {UINT, kWebMIdColorChromaSubsamplingHorz},
    207  {UINT, kWebMIdColorChromaSubsamplingVert},
    208  {UINT, kWebMIdColorCbSamplingHorz},
    209  {UINT, kWebMIdColorCbSamplingVert},
    210  {UINT, kWebMIdColorChromaSitingHorz},
    211  {UINT, kWebMIdColorChromaSitingVert},
    212  {UINT, kWebMIdColorRange},
    213  {UINT, kWebMIdColorTransferCharacteristics},
    214  {UINT, kWebMIdColorPrimaries},
    215  {UINT, kWebMIdColorMaxCLL},
    216  {UINT, kWebMIdColorMaxFALL},
    217  {LIST, kWebMIdColorMasteringMetadata},
    218 };
    219 
    220 static const ElementIdInfo kAudioIds[] = {
    221  {FLOAT, kWebMIdSamplingFrequency},
    222  {FLOAT, kWebMIdOutputSamplingFrequency},
    223  {UINT, kWebMIdChannels},
    224  {UINT, kWebMIdBitDepth},
    225 };
    226 
    227 static const ElementIdInfo kTrackOperationIds[] = {
    228  {LIST, kWebMIdTrackCombinePlanes},
    229  {LIST, kWebMIdJoinBlocks},
    230 };
    231 
    232 static const ElementIdInfo kTrackCombinePlanesIds[] = {
    233  {LIST, kWebMIdTrackPlane},
    234 };
    235 
    236 static const ElementIdInfo kTrackPlaneIds[] = {
    237  {UINT, kWebMIdTrackPlaneUID},
    238  {UINT, kWebMIdTrackPlaneType},
    239 };
    240 
    241 static const ElementIdInfo kJoinBlocksIds[] = {
    242  {UINT, kWebMIdTrackJoinUID},
    243 };
    244 
    245 static const ElementIdInfo kContentEncodingsIds[] = {
    246  {LIST, kWebMIdContentEncoding},
    247 };
    248 
    249 static const ElementIdInfo kContentEncodingIds[] = {
    250  {UINT, kWebMIdContentEncodingOrder},
    251  {UINT, kWebMIdContentEncodingScope},
    252  {UINT, kWebMIdContentEncodingType},
    253  {LIST, kWebMIdContentCompression},
    254  {LIST, kWebMIdContentEncryption},
    255 };
    256 
    257 static const ElementIdInfo kContentCompressionIds[] = {
    258  {UINT, kWebMIdContentCompAlgo},
    259  {BINARY, kWebMIdContentCompSettings},
    260 };
    261 
    262 static const ElementIdInfo kContentEncryptionIds[] = {
    263  {LIST, kWebMIdContentEncAESSettings},
    264  {UINT, kWebMIdContentEncAlgo},
    265  {BINARY, kWebMIdContentEncKeyID},
    266  {BINARY, kWebMIdContentSignature},
    267  {BINARY, kWebMIdContentSigKeyID},
    268  {UINT, kWebMIdContentSigAlgo},
    269  {UINT, kWebMIdContentSigHashAlgo},
    270 };
    271 
    272 static const ElementIdInfo kContentEncAESSettingsIds[] = {
    273  {UINT, kWebMIdAESSettingsCipherMode},
    274 };
    275 
    276 static const ElementIdInfo kCuesIds[] = {
    277  {LIST, kWebMIdCuePoint},
    278 };
    279 
    280 static const ElementIdInfo kCuePointIds[] = {
    281  {UINT, kWebMIdCueTime},
    282  {LIST, kWebMIdCueTrackPositions},
    283 };
    284 
    285 static const ElementIdInfo kCueTrackPositionsIds[] = {
    286  {UINT, kWebMIdCueTrack},
    287  {UINT, kWebMIdCueClusterPosition},
    288  {UINT, kWebMIdCueBlockNumber},
    289  {UINT, kWebMIdCueCodecState},
    290  {LIST, kWebMIdCueReference},
    291 };
    292 
    293 static const ElementIdInfo kCueReferenceIds[] = {
    294  {UINT, kWebMIdCueRefTime},
    295 };
    296 
    297 static const ElementIdInfo kAttachmentsIds[] = {
    298  {LIST, kWebMIdAttachedFile},
    299 };
    300 
    301 static const ElementIdInfo kAttachedFileIds[] = {
    302  {STRING, kWebMIdFileDescription},
    303  {STRING, kWebMIdFileName},
    304  {STRING, kWebMIdFileMimeType},
    305  {BINARY, kWebMIdFileData},
    306  {UINT, kWebMIdFileUID},
    307 };
    308 
    309 static const ElementIdInfo kChaptersIds[] = {
    310  {LIST, kWebMIdEditionEntry},
    311 };
    312 
    313 static const ElementIdInfo kEditionEntryIds[] = {
    314  {UINT, kWebMIdEditionUID},
    315  {UINT, kWebMIdEditionFlagHidden},
    316  {UINT, kWebMIdEditionFlagDefault},
    317  {UINT, kWebMIdEditionFlagOrdered},
    318  {LIST, kWebMIdChapterAtom},
    319 };
    320 
    321 static const ElementIdInfo kChapterAtomIds[] = {
    322  {UINT, kWebMIdChapterUID},
    323  {UINT, kWebMIdChapterTimeStart},
    324  {UINT, kWebMIdChapterTimeEnd},
    325  {UINT, kWebMIdChapterFlagHidden},
    326  {UINT, kWebMIdChapterFlagEnabled},
    327  {BINARY, kWebMIdChapterSegmentUID},
    328  {UINT, kWebMIdChapterSegmentEditionUID},
    329  {UINT, kWebMIdChapterPhysicalEquiv},
    330  {LIST, kWebMIdChapterTrack},
    331  {LIST, kWebMIdChapterDisplay},
    332  {LIST, kWebMIdChapProcess},
    333 };
    334 
    335 static const ElementIdInfo kChapterTrackIds[] = {
    336  {UINT, kWebMIdChapterTrackNumber},
    337 };
    338 
    339 static const ElementIdInfo kChapterDisplayIds[] = {
    340  {STRING, kWebMIdChapString},
    341  {STRING, kWebMIdChapLanguage},
    342  {STRING, kWebMIdChapCountry},
    343 };
    344 
    345 static const ElementIdInfo kChapProcessIds[] = {
    346  {UINT, kWebMIdChapProcessCodecID},
    347  {BINARY, kWebMIdChapProcessPrivate},
    348  {LIST, kWebMIdChapProcessCommand},
    349 };
    350 
    351 static const ElementIdInfo kChapProcessCommandIds[] = {
    352  {UINT, kWebMIdChapProcessTime},
    353  {BINARY, kWebMIdChapProcessData},
    354 };
    355 
    356 static const ElementIdInfo kTagsIds[] = {
    357  {LIST, kWebMIdTag},
    358 };
    359 
    360 static const ElementIdInfo kTagIds[] = {
    361  {LIST, kWebMIdTargets},
    362  {LIST, kWebMIdSimpleTag},
    363 };
    364 
    365 static const ElementIdInfo kTargetsIds[] = {
    366  {UINT, kWebMIdTargetTypeValue},
    367  {STRING, kWebMIdTargetType},
    368  {UINT, kWebMIdTagTrackUID},
    369  {UINT, kWebMIdTagEditionUID},
    370  {UINT, kWebMIdTagChapterUID},
    371  {UINT, kWebMIdTagAttachmentUID},
    372 };
    373 
    374 static const ElementIdInfo kSimpleTagIds[] = {
    375  {STRING, kWebMIdTagName},
    376  {STRING, kWebMIdTagLanguage},
    377  {UINT, kWebMIdTagDefault},
    378  {STRING, kWebMIdTagString},
    379  {BINARY, kWebMIdTagBinary},
    380 };
    381 
    382 #define LIST_ELEMENT_INFO(id, level, id_info) \
    383  { (id), (level), (id_info), arraysize(id_info) }
    384 
    385 static const ListElementInfo kListElementInfo[] = {
    386  LIST_ELEMENT_INFO(kWebMIdCluster, 1, kClusterIds),
    387  LIST_ELEMENT_INFO(kWebMIdEBMLHeader, 0, kEBMLHeaderIds),
    388  LIST_ELEMENT_INFO(kWebMIdSegment, 0, kSegmentIds),
    389  LIST_ELEMENT_INFO(kWebMIdSeekHead, 1, kSeekHeadIds),
    390  LIST_ELEMENT_INFO(kWebMIdSeek, 2, kSeekIds),
    391  LIST_ELEMENT_INFO(kWebMIdInfo, 1, kInfoIds),
    392  LIST_ELEMENT_INFO(kWebMIdChapterTranslate, 2, kChapterTranslateIds),
    393  LIST_ELEMENT_INFO(kWebMIdSilentTracks, 2, kSilentTracksIds),
    394  LIST_ELEMENT_INFO(kWebMIdBlockGroup, 2, kBlockGroupIds),
    395  LIST_ELEMENT_INFO(kWebMIdBlockAdditions, 3, kBlockAdditionsIds),
    396  LIST_ELEMENT_INFO(kWebMIdBlockMore, 4, kBlockMoreIds),
    397  LIST_ELEMENT_INFO(kWebMIdSlices, 3, kSlicesIds),
    398  LIST_ELEMENT_INFO(kWebMIdTimeSlice, 4, kTimeSliceIds),
    399  LIST_ELEMENT_INFO(kWebMIdTracks, 1, kTracksIds),
    400  LIST_ELEMENT_INFO(kWebMIdTrackEntry, 2, kTrackEntryIds),
    401  LIST_ELEMENT_INFO(kWebMIdTrackTranslate, 3, kTrackTranslateIds),
    402  LIST_ELEMENT_INFO(kWebMIdVideo, 3, kVideoIds),
    403  LIST_ELEMENT_INFO(kWebMIdColor, 4, kColorIds),
    404  LIST_ELEMENT_INFO(kWebMIdAudio, 3, kAudioIds),
    405  LIST_ELEMENT_INFO(kWebMIdTrackOperation, 3, kTrackOperationIds),
    406  LIST_ELEMENT_INFO(kWebMIdTrackCombinePlanes, 4, kTrackCombinePlanesIds),
    407  LIST_ELEMENT_INFO(kWebMIdTrackPlane, 5, kTrackPlaneIds),
    408  LIST_ELEMENT_INFO(kWebMIdJoinBlocks, 4, kJoinBlocksIds),
    409  LIST_ELEMENT_INFO(kWebMIdContentEncodings, 3, kContentEncodingsIds),
    410  LIST_ELEMENT_INFO(kWebMIdContentEncoding, 4, kContentEncodingIds),
    411  LIST_ELEMENT_INFO(kWebMIdContentCompression, 5, kContentCompressionIds),
    412  LIST_ELEMENT_INFO(kWebMIdContentEncryption, 5, kContentEncryptionIds),
    413  LIST_ELEMENT_INFO(kWebMIdContentEncAESSettings, 6, kContentEncAESSettingsIds),
    414  LIST_ELEMENT_INFO(kWebMIdCues, 1, kCuesIds),
    415  LIST_ELEMENT_INFO(kWebMIdCuePoint, 2, kCuePointIds),
    416  LIST_ELEMENT_INFO(kWebMIdCueTrackPositions, 3, kCueTrackPositionsIds),
    417  LIST_ELEMENT_INFO(kWebMIdCueReference, 4, kCueReferenceIds),
    418  LIST_ELEMENT_INFO(kWebMIdAttachments, 1, kAttachmentsIds),
    419  LIST_ELEMENT_INFO(kWebMIdAttachedFile, 2, kAttachedFileIds),
    420  LIST_ELEMENT_INFO(kWebMIdChapters, 1, kChaptersIds),
    421  LIST_ELEMENT_INFO(kWebMIdEditionEntry, 2, kEditionEntryIds),
    422  LIST_ELEMENT_INFO(kWebMIdChapterAtom, 3, kChapterAtomIds),
    423  LIST_ELEMENT_INFO(kWebMIdChapterTrack, 4, kChapterTrackIds),
    424  LIST_ELEMENT_INFO(kWebMIdChapterDisplay, 4, kChapterDisplayIds),
    425  LIST_ELEMENT_INFO(kWebMIdChapProcess, 4, kChapProcessIds),
    426  LIST_ELEMENT_INFO(kWebMIdChapProcessCommand, 5, kChapProcessCommandIds),
    427  LIST_ELEMENT_INFO(kWebMIdTags, 1, kTagsIds),
    428  LIST_ELEMENT_INFO(kWebMIdTag, 2, kTagIds),
    429  LIST_ELEMENT_INFO(kWebMIdTargets, 3, kTargetsIds),
    430  LIST_ELEMENT_INFO(kWebMIdSimpleTag, 3, kSimpleTagIds),
    431 };
    432 
    433 // Parses an element header id or size field. These fields are variable length
    434 // encoded. The first byte indicates how many bytes the field occupies.
    435 // |buf| - The buffer to parse.
    436 // |size| - The number of bytes in |buf|
    437 // |max_bytes| - The maximum number of bytes the field can be. ID fields
    438 // set this to 4 & element size fields set this to 8. If the
    439 // first byte indicates a larger field size than this it is a
    440 // parser error.
    441 // |mask_first_byte| - For element size fields the field length encoding bits
    442 // need to be masked off. This parameter is true for
    443 // element size fields and is false for ID field values.
    444 //
    445 // Returns: The number of bytes parsed on success. -1 on error.
    446 static int ParseWebMElementHeaderField(const uint8_t* buf,
    447  int size,
    448  int max_bytes,
    449  bool mask_first_byte,
    450  int64_t* num) {
    451  DCHECK(buf);
    452  DCHECK(num);
    453 
    454  if (size < 0)
    455  return -1;
    456 
    457  if (size == 0)
    458  return 0;
    459 
    460  int mask = 0x80;
    461  uint8_t ch = buf[0];
    462  int extra_bytes = -1;
    463  bool all_ones = false;
    464  for (int i = 0; i < max_bytes; ++i) {
    465  if ((ch & mask) != 0) {
    466  mask = ~mask & 0xff;
    467  *num = mask_first_byte ? ch & mask : ch;
    468  all_ones = (ch & mask) == mask;
    469  extra_bytes = i;
    470  break;
    471  }
    472  mask = 0x80 | mask >> 1;
    473  }
    474 
    475  if (extra_bytes == -1)
    476  return -1;
    477 
    478  // Return 0 if we need more data.
    479  if ((1 + extra_bytes) > size)
    480  return 0;
    481 
    482  int bytes_used = 1;
    483 
    484  for (int i = 0; i < extra_bytes; ++i) {
    485  ch = buf[bytes_used++];
    486  all_ones &= (ch == 0xff);
    487  *num = (*num << 8) | ch;
    488  }
    489 
    490  if (all_ones)
    491  *num = std::numeric_limits<int64_t>::max();
    492 
    493  return bytes_used;
    494 }
    495 
    496 int WebMParseElementHeader(const uint8_t* buf,
    497  int size,
    498  int* id,
    499  int64_t* element_size) {
    500  DCHECK(buf);
    501  DCHECK_GE(size, 0);
    502  DCHECK(id);
    503  DCHECK(element_size);
    504 
    505  if (size == 0)
    506  return 0;
    507 
    508  int64_t tmp = 0;
    509  int num_id_bytes = ParseWebMElementHeaderField(buf, size, 4, false, &tmp);
    510 
    511  if (num_id_bytes <= 0)
    512  return num_id_bytes;
    513 
    514  if (tmp == std::numeric_limits<int64_t>::max())
    515  tmp = kWebMReservedId;
    516 
    517  *id = static_cast<int>(tmp);
    518 
    519  int num_size_bytes = ParseWebMElementHeaderField(buf + num_id_bytes,
    520  size - num_id_bytes,
    521  8, true, &tmp);
    522 
    523  if (num_size_bytes <= 0)
    524  return num_size_bytes;
    525 
    526  if (tmp == std::numeric_limits<int64_t>::max())
    527  tmp = kWebMUnknownSize;
    528 
    529  *element_size = tmp;
    530  DVLOG(3) << "WebMParseElementHeader() : id " << std::hex << *id << std::dec
    531  << " size " << *element_size;
    532  return num_id_bytes + num_size_bytes;
    533 }
    534 
    535 // Finds ElementType for a specific ID.
    536 static ElementType FindIdType(int id,
    537  const ElementIdInfo* id_info,
    538  int id_info_count) {
    539 
    540  // Check for global element IDs that can be anywhere.
    541  if (id == kWebMIdVoid || id == kWebMIdCRC32)
    542  return SKIP;
    543 
    544  for (int i = 0; i < id_info_count; ++i) {
    545  if (id == id_info[i].id_)
    546  return id_info[i].type_;
    547  }
    548 
    549  return UNKNOWN;
    550 }
    551 
    552 // Finds ListElementInfo for a specific ID.
    553 static const ListElementInfo* FindListInfo(int id) {
    554  for (size_t i = 0; i < arraysize(kListElementInfo); ++i) {
    555  if (id == kListElementInfo[i].id_)
    556  return &kListElementInfo[i];
    557  }
    558 
    559  return NULL;
    560 }
    561 
    562 static int FindListLevel(int id) {
    563  const ListElementInfo* list_info = FindListInfo(id);
    564  if (list_info)
    565  return list_info->level_;
    566 
    567  return -1;
    568 }
    569 
    570 static int ParseUInt(const uint8_t* buf,
    571  int size,
    572  int id,
    573  WebMParserClient* client) {
    574  if ((size <= 0) || (size > 8))
    575  return -1;
    576 
    577  // Read in the big-endian integer.
    578  uint64_t value = 0;
    579  for (int i = 0; i < size; ++i)
    580  value = (value << 8) | buf[i];
    581 
    582  // We use int64_t in place of uint64_t everywhere for convenience. See this
    583  // bug
    584  // for more details: http://crbug.com/366750#c3
    585  if (!base::IsValueInRangeForNumericType<int64_t>(value))
    586  return -1;
    587 
    588  if (!client->OnUInt(id, value))
    589  return -1;
    590 
    591  return size;
    592 }
    593 
    594 static int ParseFloat(const uint8_t* buf,
    595  int size,
    596  int id,
    597  WebMParserClient* client) {
    598  if ((size != 4) && (size != 8))
    599  return -1;
    600 
    601  double value = -1;
    602 
    603  // Read the bytes from big-endian form into a native endian integer.
    604  int64_t tmp = 0;
    605  for (int i = 0; i < size; ++i)
    606  tmp = (tmp << 8) | buf[i];
    607 
    608  // Use a union to convert the integer bit pattern into a floating point
    609  // number.
    610  if (size == 4) {
    611  union {
    612  int32_t src;
    613  float dst;
    614  } tmp2;
    615  tmp2.src = static_cast<int32_t>(tmp);
    616  value = tmp2.dst;
    617  } else if (size == 8) {
    618  union {
    619  int64_t src;
    620  double dst;
    621  } tmp2;
    622  tmp2.src = tmp;
    623  value = tmp2.dst;
    624  } else {
    625  return -1;
    626  }
    627 
    628  if (!client->OnFloat(id, value))
    629  return -1;
    630 
    631  return size;
    632 }
    633 
    634 static int ParseBinary(const uint8_t* buf,
    635  int size,
    636  int id,
    637  WebMParserClient* client) {
    638  return client->OnBinary(id, buf, size) ? size : -1;
    639 }
    640 
    641 static int ParseString(const uint8_t* buf,
    642  int size,
    643  int id,
    644  WebMParserClient* client) {
    645  const uint8_t* end = static_cast<const uint8_t*>(memchr(buf, '\0', size));
    646  int length = (end != NULL) ? static_cast<int>(end - buf) : size;
    647  std::string str(reinterpret_cast<const char*>(buf), length);
    648  return client->OnString(id, str) ? size : -1;
    649 }
    650 
    651 static int ParseNonListElement(ElementType type,
    652  int id,
    653  int64_t element_size,
    654  const uint8_t* buf,
    655  int size,
    656  WebMParserClient* client) {
    657  DCHECK_GE(size, element_size);
    658 
    659  int result = -1;
    660  switch(type) {
    661  case LIST:
    662  NOTIMPLEMENTED();
    663  result = -1;
    664  break;
    665  case UINT:
    666  result = ParseUInt(buf, element_size, id, client);
    667  break;
    668  case FLOAT:
    669  result = ParseFloat(buf, element_size, id, client);
    670  break;
    671  case BINARY:
    672  result = ParseBinary(buf, element_size, id, client);
    673  break;
    674  case STRING:
    675  result = ParseString(buf, element_size, id, client);
    676  break;
    677  case SKIP:
    678  result = element_size;
    679  break;
    680  default:
    681  DVLOG(1) << "Unhandled ID type " << type;
    682  return -1;
    683  };
    684 
    685  DCHECK_LE(result, size);
    686  return result;
    687 }
    688 
    689 WebMParserClient::WebMParserClient() {}
    690 WebMParserClient::~WebMParserClient() {}
    691 
    692 WebMParserClient* WebMParserClient::OnListStart(int id) {
    693  DVLOG(1) << "Unexpected list element start with ID " << std::hex << id;
    694  return NULL;
    695 }
    696 
    697 bool WebMParserClient::OnListEnd(int id) {
    698  DVLOG(1) << "Unexpected list element end with ID " << std::hex << id;
    699  return false;
    700 }
    701 
    702 bool WebMParserClient::OnUInt(int id, int64_t val) {
    703  DVLOG(1) << "Unexpected unsigned integer element with ID " << std::hex << id;
    704  return false;
    705 }
    706 
    707 bool WebMParserClient::OnFloat(int id, double val) {
    708  DVLOG(1) << "Unexpected float element with ID " << std::hex << id;
    709  return false;
    710 }
    711 
    712 bool WebMParserClient::OnBinary(int id, const uint8_t* data, int size) {
    713  DVLOG(1) << "Unexpected binary element with ID " << std::hex << id;
    714  return false;
    715 }
    716 
    717 bool WebMParserClient::OnString(int id, const std::string& str) {
    718  DVLOG(1) << "Unexpected string element with ID " << std::hex << id;
    719  return false;
    720 }
    721 
    723  : state_(NEED_LIST_HEADER),
    724  root_id_(id),
    725  root_level_(FindListLevel(id)),
    726  root_client_(client) {
    727  DCHECK_GE(root_level_, 0);
    728  DCHECK(client);
    729 }
    730 
    731 WebMListParser::~WebMListParser() {}
    732 
    734  ChangeState(NEED_LIST_HEADER);
    735  list_state_stack_.clear();
    736 }
    737 
    738 int WebMListParser::Parse(const uint8_t* buf, int size) {
    739  DCHECK(buf);
    740 
    741  if (size < 0 || state_ == PARSE_ERROR || state_ == DONE_PARSING_LIST)
    742  return -1;
    743 
    744  if (size == 0)
    745  return 0;
    746 
    747  const uint8_t* cur = buf;
    748  int cur_size = size;
    749  int bytes_parsed = 0;
    750 
    751  while (cur_size > 0 && state_ != PARSE_ERROR && state_ != DONE_PARSING_LIST) {
    752  int element_id = 0;
    753  int64_t element_size = 0;
    754  int result = WebMParseElementHeader(cur, cur_size, &element_id,
    755  &element_size);
    756 
    757  if (result < 0)
    758  return result;
    759 
    760  if (result == 0)
    761  return bytes_parsed;
    762 
    763  switch(state_) {
    764  case NEED_LIST_HEADER: {
    765  if (element_id != root_id_) {
    766  ChangeState(PARSE_ERROR);
    767  return -1;
    768  }
    769 
    770  // Only allow Segment & Cluster to have an unknown size.
    771  if (element_size == kWebMUnknownSize &&
    772  (element_id != kWebMIdSegment) &&
    773  (element_id != kWebMIdCluster)) {
    774  ChangeState(PARSE_ERROR);
    775  return -1;
    776  }
    777 
    778  ChangeState(INSIDE_LIST);
    779  if (!OnListStart(root_id_, element_size))
    780  return -1;
    781 
    782  break;
    783  }
    784 
    785  case INSIDE_LIST: {
    786  int header_size = result;
    787  const uint8_t* element_data = cur + header_size;
    788  int element_data_size = cur_size - header_size;
    789 
    790  if (element_size < element_data_size)
    791  element_data_size = element_size;
    792 
    793  result = ParseListElement(header_size, element_id, element_size,
    794  element_data, element_data_size);
    795 
    796  DCHECK_LE(result, header_size + element_data_size);
    797  if (result < 0) {
    798  ChangeState(PARSE_ERROR);
    799  return -1;
    800  }
    801 
    802  if (result == 0)
    803  return bytes_parsed;
    804 
    805  break;
    806  }
    807  case DONE_PARSING_LIST:
    808  case PARSE_ERROR:
    809  // Shouldn't be able to get here.
    810  NOTIMPLEMENTED();
    811  break;
    812  }
    813 
    814  cur += result;
    815  cur_size -= result;
    816  bytes_parsed += result;
    817  }
    818 
    819  return (state_ == PARSE_ERROR) ? -1 : bytes_parsed;
    820 }
    821 
    823  return state_ == DONE_PARSING_LIST;
    824 }
    825 
    826 void WebMListParser::ChangeState(State new_state) {
    827  state_ = new_state;
    828 }
    829 
    830 int WebMListParser::ParseListElement(int header_size,
    831  int id,
    832  int64_t element_size,
    833  const uint8_t* data,
    834  int size) {
    835  DCHECK_GT(list_state_stack_.size(), 0u);
    836 
    837  ListState& list_state = list_state_stack_.back();
    838  DCHECK(list_state.element_info_);
    839 
    840  const ListElementInfo* element_info = list_state.element_info_;
    841  ElementType id_type =
    842  FindIdType(id, element_info->id_info_, element_info->id_info_count_);
    843 
    844  // Unexpected ID.
    845  if (id_type == UNKNOWN) {
    846  if (list_state.size_ != kWebMUnknownSize ||
    847  !IsSiblingOrAncestor(list_state.id_, id)) {
    848  DVLOG(1) << "No ElementType info for ID 0x" << std::hex << id;
    849  return -1;
    850  }
    851 
    852  // We've reached the end of a list of unknown size. Update the size now that
    853  // we know it and dispatch the end of list calls.
    854  list_state.size_ = list_state.bytes_parsed_;
    855 
    856  if (!OnListEnd())
    857  return -1;
    858 
    859  // Check to see if all open lists have ended.
    860  if (list_state_stack_.size() == 0)
    861  return 0;
    862 
    863  list_state = list_state_stack_.back();
    864  }
    865 
    866  // Make sure the whole element can fit inside the current list.
    867  int64_t total_element_size = header_size + element_size;
    868  if (list_state.size_ != kWebMUnknownSize &&
    869  list_state.size_ < list_state.bytes_parsed_ + total_element_size) {
    870  return -1;
    871  }
    872 
    873  if (id_type == LIST) {
    874  list_state.bytes_parsed_ += header_size;
    875 
    876  if (!OnListStart(id, element_size))
    877  return -1;
    878  return header_size;
    879  }
    880 
    881  // Make sure we have the entire element before trying to parse a non-list
    882  // element.
    883  if (size < element_size)
    884  return 0;
    885 
    886  int bytes_parsed = ParseNonListElement(id_type, id, element_size,
    887  data, size, list_state.client_);
    888  DCHECK_LE(bytes_parsed, size);
    889 
    890  // Return if an error occurred or we need more data.
    891  // Note: bytes_parsed is 0 for a successful parse of a size 0 element. We
    892  // need to check the element_size to disambiguate the "need more data" case
    893  // from a successful parse.
    894  if (bytes_parsed < 0 || (bytes_parsed == 0 && element_size != 0))
    895  return bytes_parsed;
    896 
    897  int result = header_size + bytes_parsed;
    898  list_state.bytes_parsed_ += result;
    899 
    900  // See if we have reached the end of the current list.
    901  if (list_state.bytes_parsed_ == list_state.size_) {
    902  if (!OnListEnd())
    903  return -1;
    904  }
    905 
    906  return result;
    907 }
    908 
    909 bool WebMListParser::OnListStart(int id, int64_t size) {
    910  const ListElementInfo* element_info = FindListInfo(id);
    911  if (!element_info)
    912  return false;
    913 
    914  int current_level =
    915  root_level_ + static_cast<int>(list_state_stack_.size()) - 1;
    916  if (current_level + 1 != element_info->level_)
    917  return false;
    918 
    919  WebMParserClient* current_list_client = NULL;
    920  if (!list_state_stack_.empty()) {
    921  // Make sure the new list doesn't go past the end of the current list.
    922  ListState current_list_state = list_state_stack_.back();
    923  if (current_list_state.size_ != kWebMUnknownSize &&
    924  current_list_state.size_ < current_list_state.bytes_parsed_ + size)
    925  return false;
    926  current_list_client = current_list_state.client_;
    927  } else {
    928  current_list_client = root_client_;
    929  }
    930 
    931  WebMParserClient* new_list_client = current_list_client->OnListStart(id);
    932  if (!new_list_client)
    933  return false;
    934 
    935  ListState new_list_state = { id, size, 0, element_info, new_list_client };
    936  list_state_stack_.push_back(new_list_state);
    937 
    938  if (size == 0)
    939  return OnListEnd();
    940 
    941  return true;
    942 }
    943 
    944 bool WebMListParser::OnListEnd() {
    945  int lists_ended = 0;
    946  for (; !list_state_stack_.empty(); ++lists_ended) {
    947  const ListState& list_state = list_state_stack_.back();
    948  int64_t bytes_parsed = list_state.bytes_parsed_;
    949  int id = list_state.id_;
    950 
    951  if (bytes_parsed != list_state.size_)
    952  break;
    953 
    954  list_state_stack_.pop_back();
    955 
    956  WebMParserClient* client = NULL;
    957  if (!list_state_stack_.empty()) {
    958  // Update the bytes_parsed_ for the parent element.
    959  list_state_stack_.back().bytes_parsed_ += bytes_parsed;
    960  client = list_state_stack_.back().client_;
    961  } else {
    962  client = root_client_;
    963  }
    964 
    965  if (!client->OnListEnd(id))
    966  return false;
    967  }
    968 
    969  DCHECK_GE(lists_ended, 1);
    970 
    971  if (list_state_stack_.empty())
    972  ChangeState(DONE_PARSING_LIST);
    973 
    974  return true;
    975 }
    976 
    977 bool WebMListParser::IsSiblingOrAncestor(int id_a, int id_b) const {
    978  DCHECK((id_a == kWebMIdSegment) || (id_a == kWebMIdCluster));
    979 
    980  if (id_a == kWebMIdCluster) {
    981  // kWebMIdCluster siblings.
    982  for (size_t i = 0; i < arraysize(kSegmentIds); i++) {
    983  if (kSegmentIds[i].id_ == id_b)
    984  return true;
    985  }
    986  }
    987 
    988  // kWebMIdSegment siblings.
    989  return ((id_b == kWebMIdSegment) || (id_b == kWebMIdEBMLHeader));
    990 }
    991 
    992 } // namespace media
    993 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    - -
    WebMListParser(int id, WebMParserClient *client)
    Definition: webm_parser.cc:722
    -
    void Reset()
    Resets the state of the parser so it can start parsing a new list.
    Definition: webm_parser.cc:733
    -
    int Parse(const uint8_t *buf, int size)
    Definition: webm_parser.cc:738
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/webm/webm_parser.h"
    +
    6 
    +
    7 // This file contains code to parse WebM file elements. It was created
    +
    8 // from information in the Matroska spec.
    +
    9 // http://www.matroska.org/technical/specs/index.html
    +
    10 // This file contains code for encrypted WebM. Current WebM
    +
    11 // encrypted request for comments specification is here
    +
    12 // http://wiki.webmproject.org/encryption/webm-encryption-rfc
    +
    13 
    +
    14 #include <limits>
    +
    15 
    +
    16 #include "packager/base/logging.h"
    +
    17 #include "packager/base/numerics/safe_conversions.h"
    +
    18 #include "packager/media/formats/webm/webm_constants.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 namespace media {
    +
    22 
    +
    23 enum ElementType {
    +
    24  UNKNOWN,
    +
    25  LIST, // Referred to as Master Element in the Matroska spec.
    +
    26  UINT,
    +
    27  FLOAT,
    +
    28  BINARY,
    +
    29  STRING,
    +
    30  SKIP,
    +
    31 };
    +
    32 
    +
    33 struct ElementIdInfo {
    +
    34  ElementType type_;
    +
    35  int id_;
    +
    36 };
    +
    37 
    +
    38 struct ListElementInfo {
    +
    39  int id_;
    +
    40  int level_;
    +
    41  const ElementIdInfo* id_info_;
    +
    42  int id_info_count_;
    +
    43 };
    +
    44 
    +
    45 // The following are tables indicating what IDs are valid sub-elements
    +
    46 // of particular elements. If an element is encountered that doesn't
    +
    47 // appear in the list, a parsing error is signalled. Some elements are
    +
    48 // marked as SKIP because they are valid, but we don't care about them
    +
    49 // right now.
    +
    50 static const ElementIdInfo kEBMLHeaderIds[] = {
    +
    51  {UINT, kWebMIdEBMLVersion},
    +
    52  {UINT, kWebMIdEBMLReadVersion},
    +
    53  {UINT, kWebMIdEBMLMaxIDLength},
    +
    54  {UINT, kWebMIdEBMLMaxSizeLength},
    +
    55  {STRING, kWebMIdDocType},
    +
    56  {UINT, kWebMIdDocTypeVersion},
    +
    57  {UINT, kWebMIdDocTypeReadVersion},
    +
    58 };
    +
    59 
    +
    60 static const ElementIdInfo kSegmentIds[] = {
    +
    61  {LIST, kWebMIdSeekHead},
    +
    62  {LIST, kWebMIdInfo},
    +
    63  {LIST, kWebMIdCluster},
    +
    64  {LIST, kWebMIdTracks},
    +
    65  {LIST, kWebMIdCues},
    +
    66  {LIST, kWebMIdAttachments},
    +
    67  {LIST, kWebMIdChapters},
    +
    68  {LIST, kWebMIdTags},
    +
    69 };
    +
    70 
    +
    71 static const ElementIdInfo kSeekHeadIds[] = {
    +
    72  {LIST, kWebMIdSeek},
    +
    73 };
    +
    74 
    +
    75 static const ElementIdInfo kSeekIds[] = {
    +
    76  {BINARY, kWebMIdSeekID},
    +
    77  {UINT, kWebMIdSeekPosition},
    +
    78 };
    +
    79 
    +
    80 static const ElementIdInfo kInfoIds[] = {
    +
    81  {BINARY, kWebMIdSegmentUID},
    +
    82  {STRING, kWebMIdSegmentFilename},
    +
    83  {BINARY, kWebMIdPrevUID},
    +
    84  {STRING, kWebMIdPrevFilename},
    +
    85  {BINARY, kWebMIdNextUID},
    +
    86  {STRING, kWebMIdNextFilename},
    +
    87  {BINARY, kWebMIdSegmentFamily},
    +
    88  {LIST, kWebMIdChapterTranslate},
    +
    89  {UINT, kWebMIdTimecodeScale},
    +
    90  {FLOAT, kWebMIdDuration},
    +
    91  {BINARY, kWebMIdDateUTC},
    +
    92  {STRING, kWebMIdTitle},
    +
    93  {STRING, kWebMIdMuxingApp},
    +
    94  {STRING, kWebMIdWritingApp},
    +
    95 };
    +
    96 
    +
    97 static const ElementIdInfo kChapterTranslateIds[] = {
    +
    98  {UINT, kWebMIdChapterTranslateEditionUID},
    +
    99  {UINT, kWebMIdChapterTranslateCodec},
    +
    100  {BINARY, kWebMIdChapterTranslateID},
    +
    101 };
    +
    102 
    +
    103 static const ElementIdInfo kClusterIds[] = {
    +
    104  {BINARY, kWebMIdSimpleBlock},
    +
    105  {UINT, kWebMIdTimecode},
    +
    106  {LIST, kWebMIdSilentTracks},
    +
    107  {UINT, kWebMIdPosition},
    +
    108  {UINT, kWebMIdPrevSize},
    +
    109  {LIST, kWebMIdBlockGroup},
    +
    110 };
    +
    111 
    +
    112 static const ElementIdInfo kSilentTracksIds[] = {
    +
    113  {UINT, kWebMIdSilentTrackNumber},
    +
    114 };
    +
    115 
    +
    116 static const ElementIdInfo kBlockGroupIds[] = {
    +
    117  {BINARY, kWebMIdBlock},
    +
    118  {LIST, kWebMIdBlockAdditions},
    +
    119  {UINT, kWebMIdBlockDuration},
    +
    120  {UINT, kWebMIdReferencePriority},
    +
    121  {BINARY, kWebMIdReferenceBlock},
    +
    122  {BINARY, kWebMIdCodecState},
    +
    123  {BINARY, kWebMIdDiscardPadding},
    +
    124  {LIST, kWebMIdSlices},
    +
    125 };
    +
    126 
    +
    127 static const ElementIdInfo kBlockAdditionsIds[] = {
    +
    128  {LIST, kWebMIdBlockMore},
    +
    129 };
    +
    130 
    +
    131 static const ElementIdInfo kBlockMoreIds[] = {
    +
    132  {UINT, kWebMIdBlockAddID},
    +
    133  {BINARY, kWebMIdBlockAdditional},
    +
    134 };
    +
    135 
    +
    136 static const ElementIdInfo kSlicesIds[] = {
    +
    137  {LIST, kWebMIdTimeSlice},
    +
    138 };
    +
    139 
    +
    140 static const ElementIdInfo kTimeSliceIds[] = {
    +
    141  {UINT, kWebMIdLaceNumber},
    +
    142 };
    +
    143 
    +
    144 static const ElementIdInfo kTracksIds[] = {
    +
    145  {LIST, kWebMIdTrackEntry},
    +
    146 };
    +
    147 
    +
    148 static const ElementIdInfo kTrackEntryIds[] = {
    +
    149  {UINT, kWebMIdTrackNumber},
    +
    150  {BINARY, kWebMIdTrackUID},
    +
    151  {UINT, kWebMIdTrackType},
    +
    152  {UINT, kWebMIdFlagEnabled},
    +
    153  {UINT, kWebMIdFlagDefault},
    +
    154  {UINT, kWebMIdFlagForced},
    +
    155  {UINT, kWebMIdFlagLacing},
    +
    156  {UINT, kWebMIdMinCache},
    +
    157  {UINT, kWebMIdMaxCache},
    +
    158  {UINT, kWebMIdDefaultDuration},
    +
    159  {FLOAT, kWebMIdTrackTimecodeScale},
    +
    160  {UINT, kWebMIdMaxBlockAdditionId},
    +
    161  {STRING, kWebMIdName},
    +
    162  {STRING, kWebMIdLanguage},
    +
    163  {STRING, kWebMIdCodecID},
    +
    164  {BINARY, kWebMIdCodecPrivate},
    +
    165  {STRING, kWebMIdCodecName},
    +
    166  {UINT, kWebMIdAttachmentLink},
    +
    167  {UINT, kWebMIdCodecDecodeAll},
    +
    168  {UINT, kWebMIdTrackOverlay},
    +
    169  {UINT, kWebMIdCodecDelay},
    +
    170  {UINT, kWebMIdSeekPreRoll},
    +
    171  {LIST, kWebMIdTrackTranslate},
    +
    172  {LIST, kWebMIdVideo},
    +
    173  {LIST, kWebMIdAudio},
    +
    174  {LIST, kWebMIdTrackOperation},
    +
    175  {LIST, kWebMIdContentEncodings},
    +
    176 };
    +
    177 
    +
    178 static const ElementIdInfo kTrackTranslateIds[] = {
    +
    179  {UINT, kWebMIdTrackTranslateEditionUID},
    +
    180  {UINT, kWebMIdTrackTranslateCodec},
    +
    181  {BINARY, kWebMIdTrackTranslateTrackID},
    +
    182 };
    +
    183 
    +
    184 static const ElementIdInfo kVideoIds[] = {
    +
    185  {UINT, kWebMIdFlagInterlaced},
    +
    186  {UINT, kWebMIdStereoMode},
    +
    187  {UINT, kWebMIdAlphaMode},
    +
    188  {UINT, kWebMIdPixelWidth},
    +
    189  {UINT, kWebMIdPixelHeight},
    +
    190  {UINT, kWebMIdPixelCropBottom},
    +
    191  {UINT, kWebMIdPixelCropTop},
    +
    192  {UINT, kWebMIdPixelCropLeft},
    +
    193  {UINT, kWebMIdPixelCropRight},
    +
    194  {UINT, kWebMIdDisplayWidth},
    +
    195  {UINT, kWebMIdDisplayHeight},
    +
    196  {UINT, kWebMIdDisplayUnit},
    +
    197  {UINT, kWebMIdAspectRatioType},
    +
    198  {BINARY, kWebMIdColorSpace},
    +
    199  {FLOAT, kWebMIdFrameRate},
    +
    200  {LIST, kWebMIdColor},
    +
    201 };
    +
    202 
    +
    203 static const ElementIdInfo kColorIds[] = {
    +
    204  {UINT, kWebMIdColorMatrixCoefficients},
    +
    205  {UINT, kWebMIdColorBitsPerChannel},
    +
    206  {UINT, kWebMIdColorChromaSubsamplingHorz},
    +
    207  {UINT, kWebMIdColorChromaSubsamplingVert},
    +
    208  {UINT, kWebMIdColorCbSamplingHorz},
    +
    209  {UINT, kWebMIdColorCbSamplingVert},
    +
    210  {UINT, kWebMIdColorChromaSitingHorz},
    +
    211  {UINT, kWebMIdColorChromaSitingVert},
    +
    212  {UINT, kWebMIdColorRange},
    +
    213  {UINT, kWebMIdColorTransferCharacteristics},
    +
    214  {UINT, kWebMIdColorPrimaries},
    +
    215  {UINT, kWebMIdColorMaxCLL},
    +
    216  {UINT, kWebMIdColorMaxFALL},
    +
    217  {LIST, kWebMIdColorMasteringMetadata},
    +
    218 };
    +
    219 
    +
    220 static const ElementIdInfo kAudioIds[] = {
    +
    221  {FLOAT, kWebMIdSamplingFrequency},
    +
    222  {FLOAT, kWebMIdOutputSamplingFrequency},
    +
    223  {UINT, kWebMIdChannels},
    +
    224  {UINT, kWebMIdBitDepth},
    +
    225 };
    +
    226 
    +
    227 static const ElementIdInfo kTrackOperationIds[] = {
    +
    228  {LIST, kWebMIdTrackCombinePlanes},
    +
    229  {LIST, kWebMIdJoinBlocks},
    +
    230 };
    +
    231 
    +
    232 static const ElementIdInfo kTrackCombinePlanesIds[] = {
    +
    233  {LIST, kWebMIdTrackPlane},
    +
    234 };
    +
    235 
    +
    236 static const ElementIdInfo kTrackPlaneIds[] = {
    +
    237  {UINT, kWebMIdTrackPlaneUID},
    +
    238  {UINT, kWebMIdTrackPlaneType},
    +
    239 };
    +
    240 
    +
    241 static const ElementIdInfo kJoinBlocksIds[] = {
    +
    242  {UINT, kWebMIdTrackJoinUID},
    +
    243 };
    +
    244 
    +
    245 static const ElementIdInfo kContentEncodingsIds[] = {
    +
    246  {LIST, kWebMIdContentEncoding},
    +
    247 };
    +
    248 
    +
    249 static const ElementIdInfo kContentEncodingIds[] = {
    +
    250  {UINT, kWebMIdContentEncodingOrder},
    +
    251  {UINT, kWebMIdContentEncodingScope},
    +
    252  {UINT, kWebMIdContentEncodingType},
    +
    253  {LIST, kWebMIdContentCompression},
    +
    254  {LIST, kWebMIdContentEncryption},
    +
    255 };
    +
    256 
    +
    257 static const ElementIdInfo kContentCompressionIds[] = {
    +
    258  {UINT, kWebMIdContentCompAlgo},
    +
    259  {BINARY, kWebMIdContentCompSettings},
    +
    260 };
    +
    261 
    +
    262 static const ElementIdInfo kContentEncryptionIds[] = {
    +
    263  {LIST, kWebMIdContentEncAESSettings},
    +
    264  {UINT, kWebMIdContentEncAlgo},
    +
    265  {BINARY, kWebMIdContentEncKeyID},
    +
    266  {BINARY, kWebMIdContentSignature},
    +
    267  {BINARY, kWebMIdContentSigKeyID},
    +
    268  {UINT, kWebMIdContentSigAlgo},
    +
    269  {UINT, kWebMIdContentSigHashAlgo},
    +
    270 };
    +
    271 
    +
    272 static const ElementIdInfo kContentEncAESSettingsIds[] = {
    +
    273  {UINT, kWebMIdAESSettingsCipherMode},
    +
    274 };
    +
    275 
    +
    276 static const ElementIdInfo kCuesIds[] = {
    +
    277  {LIST, kWebMIdCuePoint},
    +
    278 };
    +
    279 
    +
    280 static const ElementIdInfo kCuePointIds[] = {
    +
    281  {UINT, kWebMIdCueTime},
    +
    282  {LIST, kWebMIdCueTrackPositions},
    +
    283 };
    +
    284 
    +
    285 static const ElementIdInfo kCueTrackPositionsIds[] = {
    +
    286  {UINT, kWebMIdCueTrack},
    +
    287  {UINT, kWebMIdCueClusterPosition},
    +
    288  {UINT, kWebMIdCueBlockNumber},
    +
    289  {UINT, kWebMIdCueCodecState},
    +
    290  {LIST, kWebMIdCueReference},
    +
    291 };
    +
    292 
    +
    293 static const ElementIdInfo kCueReferenceIds[] = {
    +
    294  {UINT, kWebMIdCueRefTime},
    +
    295 };
    +
    296 
    +
    297 static const ElementIdInfo kAttachmentsIds[] = {
    +
    298  {LIST, kWebMIdAttachedFile},
    +
    299 };
    +
    300 
    +
    301 static const ElementIdInfo kAttachedFileIds[] = {
    +
    302  {STRING, kWebMIdFileDescription},
    +
    303  {STRING, kWebMIdFileName},
    +
    304  {STRING, kWebMIdFileMimeType},
    +
    305  {BINARY, kWebMIdFileData},
    +
    306  {UINT, kWebMIdFileUID},
    +
    307 };
    +
    308 
    +
    309 static const ElementIdInfo kChaptersIds[] = {
    +
    310  {LIST, kWebMIdEditionEntry},
    +
    311 };
    +
    312 
    +
    313 static const ElementIdInfo kEditionEntryIds[] = {
    +
    314  {UINT, kWebMIdEditionUID},
    +
    315  {UINT, kWebMIdEditionFlagHidden},
    +
    316  {UINT, kWebMIdEditionFlagDefault},
    +
    317  {UINT, kWebMIdEditionFlagOrdered},
    +
    318  {LIST, kWebMIdChapterAtom},
    +
    319 };
    +
    320 
    +
    321 static const ElementIdInfo kChapterAtomIds[] = {
    +
    322  {UINT, kWebMIdChapterUID},
    +
    323  {UINT, kWebMIdChapterTimeStart},
    +
    324  {UINT, kWebMIdChapterTimeEnd},
    +
    325  {UINT, kWebMIdChapterFlagHidden},
    +
    326  {UINT, kWebMIdChapterFlagEnabled},
    +
    327  {BINARY, kWebMIdChapterSegmentUID},
    +
    328  {UINT, kWebMIdChapterSegmentEditionUID},
    +
    329  {UINT, kWebMIdChapterPhysicalEquiv},
    +
    330  {LIST, kWebMIdChapterTrack},
    +
    331  {LIST, kWebMIdChapterDisplay},
    +
    332  {LIST, kWebMIdChapProcess},
    +
    333 };
    +
    334 
    +
    335 static const ElementIdInfo kChapterTrackIds[] = {
    +
    336  {UINT, kWebMIdChapterTrackNumber},
    +
    337 };
    +
    338 
    +
    339 static const ElementIdInfo kChapterDisplayIds[] = {
    +
    340  {STRING, kWebMIdChapString},
    +
    341  {STRING, kWebMIdChapLanguage},
    +
    342  {STRING, kWebMIdChapCountry},
    +
    343 };
    +
    344 
    +
    345 static const ElementIdInfo kChapProcessIds[] = {
    +
    346  {UINT, kWebMIdChapProcessCodecID},
    +
    347  {BINARY, kWebMIdChapProcessPrivate},
    +
    348  {LIST, kWebMIdChapProcessCommand},
    +
    349 };
    +
    350 
    +
    351 static const ElementIdInfo kChapProcessCommandIds[] = {
    +
    352  {UINT, kWebMIdChapProcessTime},
    +
    353  {BINARY, kWebMIdChapProcessData},
    +
    354 };
    +
    355 
    +
    356 static const ElementIdInfo kTagsIds[] = {
    +
    357  {LIST, kWebMIdTag},
    +
    358 };
    +
    359 
    +
    360 static const ElementIdInfo kTagIds[] = {
    +
    361  {LIST, kWebMIdTargets},
    +
    362  {LIST, kWebMIdSimpleTag},
    +
    363 };
    +
    364 
    +
    365 static const ElementIdInfo kTargetsIds[] = {
    +
    366  {UINT, kWebMIdTargetTypeValue},
    +
    367  {STRING, kWebMIdTargetType},
    +
    368  {UINT, kWebMIdTagTrackUID},
    +
    369  {UINT, kWebMIdTagEditionUID},
    +
    370  {UINT, kWebMIdTagChapterUID},
    +
    371  {UINT, kWebMIdTagAttachmentUID},
    +
    372 };
    +
    373 
    +
    374 static const ElementIdInfo kSimpleTagIds[] = {
    +
    375  {STRING, kWebMIdTagName},
    +
    376  {STRING, kWebMIdTagLanguage},
    +
    377  {UINT, kWebMIdTagDefault},
    +
    378  {STRING, kWebMIdTagString},
    +
    379  {BINARY, kWebMIdTagBinary},
    +
    380 };
    +
    381 
    +
    382 #define LIST_ELEMENT_INFO(id, level, id_info) \
    +
    383  { (id), (level), (id_info), arraysize(id_info) }
    +
    384 
    +
    385 static const ListElementInfo kListElementInfo[] = {
    +
    386  LIST_ELEMENT_INFO(kWebMIdCluster, 1, kClusterIds),
    +
    387  LIST_ELEMENT_INFO(kWebMIdEBMLHeader, 0, kEBMLHeaderIds),
    +
    388  LIST_ELEMENT_INFO(kWebMIdSegment, 0, kSegmentIds),
    +
    389  LIST_ELEMENT_INFO(kWebMIdSeekHead, 1, kSeekHeadIds),
    +
    390  LIST_ELEMENT_INFO(kWebMIdSeek, 2, kSeekIds),
    +
    391  LIST_ELEMENT_INFO(kWebMIdInfo, 1, kInfoIds),
    +
    392  LIST_ELEMENT_INFO(kWebMIdChapterTranslate, 2, kChapterTranslateIds),
    +
    393  LIST_ELEMENT_INFO(kWebMIdSilentTracks, 2, kSilentTracksIds),
    +
    394  LIST_ELEMENT_INFO(kWebMIdBlockGroup, 2, kBlockGroupIds),
    +
    395  LIST_ELEMENT_INFO(kWebMIdBlockAdditions, 3, kBlockAdditionsIds),
    +
    396  LIST_ELEMENT_INFO(kWebMIdBlockMore, 4, kBlockMoreIds),
    +
    397  LIST_ELEMENT_INFO(kWebMIdSlices, 3, kSlicesIds),
    +
    398  LIST_ELEMENT_INFO(kWebMIdTimeSlice, 4, kTimeSliceIds),
    +
    399  LIST_ELEMENT_INFO(kWebMIdTracks, 1, kTracksIds),
    +
    400  LIST_ELEMENT_INFO(kWebMIdTrackEntry, 2, kTrackEntryIds),
    +
    401  LIST_ELEMENT_INFO(kWebMIdTrackTranslate, 3, kTrackTranslateIds),
    +
    402  LIST_ELEMENT_INFO(kWebMIdVideo, 3, kVideoIds),
    +
    403  LIST_ELEMENT_INFO(kWebMIdColor, 4, kColorIds),
    +
    404  LIST_ELEMENT_INFO(kWebMIdAudio, 3, kAudioIds),
    +
    405  LIST_ELEMENT_INFO(kWebMIdTrackOperation, 3, kTrackOperationIds),
    +
    406  LIST_ELEMENT_INFO(kWebMIdTrackCombinePlanes, 4, kTrackCombinePlanesIds),
    +
    407  LIST_ELEMENT_INFO(kWebMIdTrackPlane, 5, kTrackPlaneIds),
    +
    408  LIST_ELEMENT_INFO(kWebMIdJoinBlocks, 4, kJoinBlocksIds),
    +
    409  LIST_ELEMENT_INFO(kWebMIdContentEncodings, 3, kContentEncodingsIds),
    +
    410  LIST_ELEMENT_INFO(kWebMIdContentEncoding, 4, kContentEncodingIds),
    +
    411  LIST_ELEMENT_INFO(kWebMIdContentCompression, 5, kContentCompressionIds),
    +
    412  LIST_ELEMENT_INFO(kWebMIdContentEncryption, 5, kContentEncryptionIds),
    +
    413  LIST_ELEMENT_INFO(kWebMIdContentEncAESSettings, 6, kContentEncAESSettingsIds),
    +
    414  LIST_ELEMENT_INFO(kWebMIdCues, 1, kCuesIds),
    +
    415  LIST_ELEMENT_INFO(kWebMIdCuePoint, 2, kCuePointIds),
    +
    416  LIST_ELEMENT_INFO(kWebMIdCueTrackPositions, 3, kCueTrackPositionsIds),
    +
    417  LIST_ELEMENT_INFO(kWebMIdCueReference, 4, kCueReferenceIds),
    +
    418  LIST_ELEMENT_INFO(kWebMIdAttachments, 1, kAttachmentsIds),
    +
    419  LIST_ELEMENT_INFO(kWebMIdAttachedFile, 2, kAttachedFileIds),
    +
    420  LIST_ELEMENT_INFO(kWebMIdChapters, 1, kChaptersIds),
    +
    421  LIST_ELEMENT_INFO(kWebMIdEditionEntry, 2, kEditionEntryIds),
    +
    422  LIST_ELEMENT_INFO(kWebMIdChapterAtom, 3, kChapterAtomIds),
    +
    423  LIST_ELEMENT_INFO(kWebMIdChapterTrack, 4, kChapterTrackIds),
    +
    424  LIST_ELEMENT_INFO(kWebMIdChapterDisplay, 4, kChapterDisplayIds),
    +
    425  LIST_ELEMENT_INFO(kWebMIdChapProcess, 4, kChapProcessIds),
    +
    426  LIST_ELEMENT_INFO(kWebMIdChapProcessCommand, 5, kChapProcessCommandIds),
    +
    427  LIST_ELEMENT_INFO(kWebMIdTags, 1, kTagsIds),
    +
    428  LIST_ELEMENT_INFO(kWebMIdTag, 2, kTagIds),
    +
    429  LIST_ELEMENT_INFO(kWebMIdTargets, 3, kTargetsIds),
    +
    430  LIST_ELEMENT_INFO(kWebMIdSimpleTag, 3, kSimpleTagIds),
    +
    431 };
    +
    432 
    +
    433 // Parses an element header id or size field. These fields are variable length
    +
    434 // encoded. The first byte indicates how many bytes the field occupies.
    +
    435 // |buf| - The buffer to parse.
    +
    436 // |size| - The number of bytes in |buf|
    +
    437 // |max_bytes| - The maximum number of bytes the field can be. ID fields
    +
    438 // set this to 4 & element size fields set this to 8. If the
    +
    439 // first byte indicates a larger field size than this it is a
    +
    440 // parser error.
    +
    441 // |mask_first_byte| - For element size fields the field length encoding bits
    +
    442 // need to be masked off. This parameter is true for
    +
    443 // element size fields and is false for ID field values.
    +
    444 //
    +
    445 // Returns: The number of bytes parsed on success. -1 on error.
    +
    446 static int ParseWebMElementHeaderField(const uint8_t* buf,
    +
    447  int size,
    +
    448  int max_bytes,
    +
    449  bool mask_first_byte,
    +
    450  int64_t* num) {
    +
    451  DCHECK(buf);
    +
    452  DCHECK(num);
    +
    453 
    +
    454  if (size < 0)
    +
    455  return -1;
    +
    456 
    +
    457  if (size == 0)
    +
    458  return 0;
    +
    459 
    +
    460  int mask = 0x80;
    +
    461  uint8_t ch = buf[0];
    +
    462  int extra_bytes = -1;
    +
    463  bool all_ones = false;
    +
    464  for (int i = 0; i < max_bytes; ++i) {
    +
    465  if ((ch & mask) != 0) {
    +
    466  mask = ~mask & 0xff;
    +
    467  *num = mask_first_byte ? ch & mask : ch;
    +
    468  all_ones = (ch & mask) == mask;
    +
    469  extra_bytes = i;
    +
    470  break;
    +
    471  }
    +
    472  mask = 0x80 | mask >> 1;
    +
    473  }
    +
    474 
    +
    475  if (extra_bytes == -1)
    +
    476  return -1;
    +
    477 
    +
    478  // Return 0 if we need more data.
    +
    479  if ((1 + extra_bytes) > size)
    +
    480  return 0;
    +
    481 
    +
    482  int bytes_used = 1;
    +
    483 
    +
    484  for (int i = 0; i < extra_bytes; ++i) {
    +
    485  ch = buf[bytes_used++];
    +
    486  all_ones &= (ch == 0xff);
    +
    487  *num = (*num << 8) | ch;
    +
    488  }
    +
    489 
    +
    490  if (all_ones)
    +
    491  *num = std::numeric_limits<int64_t>::max();
    +
    492 
    +
    493  return bytes_used;
    +
    494 }
    +
    495 
    +
    496 int WebMParseElementHeader(const uint8_t* buf,
    +
    497  int size,
    +
    498  int* id,
    +
    499  int64_t* element_size) {
    +
    500  DCHECK(buf);
    +
    501  DCHECK_GE(size, 0);
    +
    502  DCHECK(id);
    +
    503  DCHECK(element_size);
    +
    504 
    +
    505  if (size == 0)
    +
    506  return 0;
    +
    507 
    +
    508  int64_t tmp = 0;
    +
    509  int num_id_bytes = ParseWebMElementHeaderField(buf, size, 4, false, &tmp);
    +
    510 
    +
    511  if (num_id_bytes <= 0)
    +
    512  return num_id_bytes;
    +
    513 
    +
    514  if (tmp == std::numeric_limits<int64_t>::max())
    +
    515  tmp = kWebMReservedId;
    +
    516 
    +
    517  *id = static_cast<int>(tmp);
    +
    518 
    +
    519  int num_size_bytes = ParseWebMElementHeaderField(buf + num_id_bytes,
    +
    520  size - num_id_bytes,
    +
    521  8, true, &tmp);
    +
    522 
    +
    523  if (num_size_bytes <= 0)
    +
    524  return num_size_bytes;
    +
    525 
    +
    526  if (tmp == std::numeric_limits<int64_t>::max())
    +
    527  tmp = kWebMUnknownSize;
    +
    528 
    +
    529  *element_size = tmp;
    +
    530  DVLOG(3) << "WebMParseElementHeader() : id " << std::hex << *id << std::dec
    +
    531  << " size " << *element_size;
    +
    532  return num_id_bytes + num_size_bytes;
    +
    533 }
    +
    534 
    +
    535 // Finds ElementType for a specific ID.
    +
    536 static ElementType FindIdType(int id,
    +
    537  const ElementIdInfo* id_info,
    +
    538  int id_info_count) {
    +
    539 
    +
    540  // Check for global element IDs that can be anywhere.
    +
    541  if (id == kWebMIdVoid || id == kWebMIdCRC32)
    +
    542  return SKIP;
    +
    543 
    +
    544  for (int i = 0; i < id_info_count; ++i) {
    +
    545  if (id == id_info[i].id_)
    +
    546  return id_info[i].type_;
    +
    547  }
    +
    548 
    +
    549  return UNKNOWN;
    +
    550 }
    +
    551 
    +
    552 // Finds ListElementInfo for a specific ID.
    +
    553 static const ListElementInfo* FindListInfo(int id) {
    +
    554  for (size_t i = 0; i < arraysize(kListElementInfo); ++i) {
    +
    555  if (id == kListElementInfo[i].id_)
    +
    556  return &kListElementInfo[i];
    +
    557  }
    +
    558 
    +
    559  return NULL;
    +
    560 }
    +
    561 
    +
    562 static int FindListLevel(int id) {
    +
    563  const ListElementInfo* list_info = FindListInfo(id);
    +
    564  if (list_info)
    +
    565  return list_info->level_;
    +
    566 
    +
    567  return -1;
    +
    568 }
    +
    569 
    +
    570 static int ParseUInt(const uint8_t* buf,
    +
    571  int size,
    +
    572  int id,
    +
    573  WebMParserClient* client) {
    +
    574  if ((size <= 0) || (size > 8))
    +
    575  return -1;
    +
    576 
    +
    577  // Read in the big-endian integer.
    +
    578  uint64_t value = 0;
    +
    579  for (int i = 0; i < size; ++i)
    +
    580  value = (value << 8) | buf[i];
    +
    581 
    +
    582  // We use int64_t in place of uint64_t everywhere for convenience. See this
    +
    583  // bug
    +
    584  // for more details: http://crbug.com/366750#c3
    +
    585  if (!base::IsValueInRangeForNumericType<int64_t>(value))
    +
    586  return -1;
    +
    587 
    +
    588  if (!client->OnUInt(id, value))
    +
    589  return -1;
    +
    590 
    +
    591  return size;
    +
    592 }
    +
    593 
    +
    594 static int ParseFloat(const uint8_t* buf,
    +
    595  int size,
    +
    596  int id,
    +
    597  WebMParserClient* client) {
    +
    598  if ((size != 4) && (size != 8))
    +
    599  return -1;
    +
    600 
    +
    601  double value = -1;
    +
    602 
    +
    603  // Read the bytes from big-endian form into a native endian integer.
    +
    604  int64_t tmp = 0;
    +
    605  for (int i = 0; i < size; ++i)
    +
    606  tmp = (tmp << 8) | buf[i];
    +
    607 
    +
    608  // Use a union to convert the integer bit pattern into a floating point
    +
    609  // number.
    +
    610  if (size == 4) {
    +
    611  union {
    +
    612  int32_t src;
    +
    613  float dst;
    +
    614  } tmp2;
    +
    615  tmp2.src = static_cast<int32_t>(tmp);
    +
    616  value = tmp2.dst;
    +
    617  } else if (size == 8) {
    +
    618  union {
    +
    619  int64_t src;
    +
    620  double dst;
    +
    621  } tmp2;
    +
    622  tmp2.src = tmp;
    +
    623  value = tmp2.dst;
    +
    624  } else {
    +
    625  return -1;
    +
    626  }
    +
    627 
    +
    628  if (!client->OnFloat(id, value))
    +
    629  return -1;
    +
    630 
    +
    631  return size;
    +
    632 }
    +
    633 
    +
    634 static int ParseBinary(const uint8_t* buf,
    +
    635  int size,
    +
    636  int id,
    +
    637  WebMParserClient* client) {
    +
    638  return client->OnBinary(id, buf, size) ? size : -1;
    +
    639 }
    +
    640 
    +
    641 static int ParseString(const uint8_t* buf,
    +
    642  int size,
    +
    643  int id,
    +
    644  WebMParserClient* client) {
    +
    645  const uint8_t* end = static_cast<const uint8_t*>(memchr(buf, '\0', size));
    +
    646  int length = (end != NULL) ? static_cast<int>(end - buf) : size;
    +
    647  std::string str(reinterpret_cast<const char*>(buf), length);
    +
    648  return client->OnString(id, str) ? size : -1;
    +
    649 }
    +
    650 
    +
    651 static int ParseNonListElement(ElementType type,
    +
    652  int id,
    +
    653  int64_t element_size,
    +
    654  const uint8_t* buf,
    +
    655  int size,
    +
    656  WebMParserClient* client) {
    +
    657  DCHECK_GE(size, element_size);
    +
    658 
    +
    659  int result = -1;
    +
    660  switch(type) {
    +
    661  case LIST:
    +
    662  NOTIMPLEMENTED();
    +
    663  result = -1;
    +
    664  break;
    +
    665  case UINT:
    +
    666  result = ParseUInt(buf, element_size, id, client);
    +
    667  break;
    +
    668  case FLOAT:
    +
    669  result = ParseFloat(buf, element_size, id, client);
    +
    670  break;
    +
    671  case BINARY:
    +
    672  result = ParseBinary(buf, element_size, id, client);
    +
    673  break;
    +
    674  case STRING:
    +
    675  result = ParseString(buf, element_size, id, client);
    +
    676  break;
    +
    677  case SKIP:
    +
    678  result = element_size;
    +
    679  break;
    +
    680  default:
    +
    681  DVLOG(1) << "Unhandled ID type " << type;
    +
    682  return -1;
    +
    683  };
    +
    684 
    +
    685  DCHECK_LE(result, size);
    +
    686  return result;
    +
    687 }
    +
    688 
    +
    689 WebMParserClient::WebMParserClient() {}
    +
    690 WebMParserClient::~WebMParserClient() {}
    +
    691 
    +
    692 WebMParserClient* WebMParserClient::OnListStart(int id) {
    +
    693  DVLOG(1) << "Unexpected list element start with ID " << std::hex << id;
    +
    694  return NULL;
    +
    695 }
    +
    696 
    +
    697 bool WebMParserClient::OnListEnd(int id) {
    +
    698  DVLOG(1) << "Unexpected list element end with ID " << std::hex << id;
    +
    699  return false;
    +
    700 }
    +
    701 
    +
    702 bool WebMParserClient::OnUInt(int id, int64_t val) {
    +
    703  DVLOG(1) << "Unexpected unsigned integer element with ID " << std::hex << id;
    +
    704  return false;
    +
    705 }
    +
    706 
    +
    707 bool WebMParserClient::OnFloat(int id, double val) {
    +
    708  DVLOG(1) << "Unexpected float element with ID " << std::hex << id;
    +
    709  return false;
    +
    710 }
    +
    711 
    +
    712 bool WebMParserClient::OnBinary(int id, const uint8_t* data, int size) {
    +
    713  DVLOG(1) << "Unexpected binary element with ID " << std::hex << id;
    +
    714  return false;
    +
    715 }
    +
    716 
    +
    717 bool WebMParserClient::OnString(int id, const std::string& str) {
    +
    718  DVLOG(1) << "Unexpected string element with ID " << std::hex << id;
    +
    719  return false;
    +
    720 }
    +
    721 
    + +
    723  : state_(NEED_LIST_HEADER),
    +
    724  root_id_(id),
    +
    725  root_level_(FindListLevel(id)),
    +
    726  root_client_(client) {
    +
    727  DCHECK_GE(root_level_, 0);
    +
    728  DCHECK(client);
    +
    729 }
    +
    730 
    +
    731 WebMListParser::~WebMListParser() {}
    +
    732 
    + +
    734  ChangeState(NEED_LIST_HEADER);
    +
    735  list_state_stack_.clear();
    +
    736 }
    +
    737 
    +
    738 int WebMListParser::Parse(const uint8_t* buf, int size) {
    +
    739  DCHECK(buf);
    +
    740 
    +
    741  if (size < 0 || state_ == PARSE_ERROR || state_ == DONE_PARSING_LIST)
    +
    742  return -1;
    +
    743 
    +
    744  if (size == 0)
    +
    745  return 0;
    +
    746 
    +
    747  const uint8_t* cur = buf;
    +
    748  int cur_size = size;
    +
    749  int bytes_parsed = 0;
    +
    750 
    +
    751  while (cur_size > 0 && state_ != PARSE_ERROR && state_ != DONE_PARSING_LIST) {
    +
    752  int element_id = 0;
    +
    753  int64_t element_size = 0;
    +
    754  int result = WebMParseElementHeader(cur, cur_size, &element_id,
    +
    755  &element_size);
    +
    756 
    +
    757  if (result < 0)
    +
    758  return result;
    +
    759 
    +
    760  if (result == 0)
    +
    761  return bytes_parsed;
    +
    762 
    +
    763  switch(state_) {
    +
    764  case NEED_LIST_HEADER: {
    +
    765  if (element_id != root_id_) {
    +
    766  ChangeState(PARSE_ERROR);
    +
    767  return -1;
    +
    768  }
    +
    769 
    +
    770  // Only allow Segment & Cluster to have an unknown size.
    +
    771  if (element_size == kWebMUnknownSize &&
    +
    772  (element_id != kWebMIdSegment) &&
    +
    773  (element_id != kWebMIdCluster)) {
    +
    774  ChangeState(PARSE_ERROR);
    +
    775  return -1;
    +
    776  }
    +
    777 
    +
    778  ChangeState(INSIDE_LIST);
    +
    779  if (!OnListStart(root_id_, element_size))
    +
    780  return -1;
    +
    781 
    +
    782  break;
    +
    783  }
    +
    784 
    +
    785  case INSIDE_LIST: {
    +
    786  int header_size = result;
    +
    787  const uint8_t* element_data = cur + header_size;
    +
    788  int element_data_size = cur_size - header_size;
    +
    789 
    +
    790  if (element_size < element_data_size)
    +
    791  element_data_size = element_size;
    +
    792 
    +
    793  result = ParseListElement(header_size, element_id, element_size,
    +
    794  element_data, element_data_size);
    +
    795 
    +
    796  DCHECK_LE(result, header_size + element_data_size);
    +
    797  if (result < 0) {
    +
    798  ChangeState(PARSE_ERROR);
    +
    799  return -1;
    +
    800  }
    +
    801 
    +
    802  if (result == 0)
    +
    803  return bytes_parsed;
    +
    804 
    +
    805  break;
    +
    806  }
    +
    807  case DONE_PARSING_LIST:
    +
    808  case PARSE_ERROR:
    +
    809  // Shouldn't be able to get here.
    +
    810  NOTIMPLEMENTED();
    +
    811  break;
    +
    812  }
    +
    813 
    +
    814  cur += result;
    +
    815  cur_size -= result;
    +
    816  bytes_parsed += result;
    +
    817  }
    +
    818 
    +
    819  return (state_ == PARSE_ERROR) ? -1 : bytes_parsed;
    +
    820 }
    +
    821 
    + +
    823  return state_ == DONE_PARSING_LIST;
    +
    824 }
    +
    825 
    +
    826 void WebMListParser::ChangeState(State new_state) {
    +
    827  state_ = new_state;
    +
    828 }
    +
    829 
    +
    830 int WebMListParser::ParseListElement(int header_size,
    +
    831  int id,
    +
    832  int64_t element_size,
    +
    833  const uint8_t* data,
    +
    834  int size) {
    +
    835  DCHECK_GT(list_state_stack_.size(), 0u);
    +
    836 
    +
    837  ListState& list_state = list_state_stack_.back();
    +
    838  DCHECK(list_state.element_info_);
    +
    839 
    +
    840  const ListElementInfo* element_info = list_state.element_info_;
    +
    841  ElementType id_type =
    +
    842  FindIdType(id, element_info->id_info_, element_info->id_info_count_);
    +
    843 
    +
    844  // Unexpected ID.
    +
    845  if (id_type == UNKNOWN) {
    +
    846  if (list_state.size_ != kWebMUnknownSize ||
    +
    847  !IsSiblingOrAncestor(list_state.id_, id)) {
    +
    848  DVLOG(1) << "No ElementType info for ID 0x" << std::hex << id;
    +
    849  return -1;
    +
    850  }
    +
    851 
    +
    852  // We've reached the end of a list of unknown size. Update the size now that
    +
    853  // we know it and dispatch the end of list calls.
    +
    854  list_state.size_ = list_state.bytes_parsed_;
    +
    855 
    +
    856  if (!OnListEnd())
    +
    857  return -1;
    +
    858 
    +
    859  // Check to see if all open lists have ended.
    +
    860  if (list_state_stack_.size() == 0)
    +
    861  return 0;
    +
    862 
    +
    863  list_state = list_state_stack_.back();
    +
    864  }
    +
    865 
    +
    866  // Make sure the whole element can fit inside the current list.
    +
    867  int64_t total_element_size = header_size + element_size;
    +
    868  if (list_state.size_ != kWebMUnknownSize &&
    +
    869  list_state.size_ < list_state.bytes_parsed_ + total_element_size) {
    +
    870  return -1;
    +
    871  }
    +
    872 
    +
    873  if (id_type == LIST) {
    +
    874  list_state.bytes_parsed_ += header_size;
    +
    875 
    +
    876  if (!OnListStart(id, element_size))
    +
    877  return -1;
    +
    878  return header_size;
    +
    879  }
    +
    880 
    +
    881  // Make sure we have the entire element before trying to parse a non-list
    +
    882  // element.
    +
    883  if (size < element_size)
    +
    884  return 0;
    +
    885 
    +
    886  int bytes_parsed = ParseNonListElement(id_type, id, element_size,
    +
    887  data, size, list_state.client_);
    +
    888  DCHECK_LE(bytes_parsed, size);
    +
    889 
    +
    890  // Return if an error occurred or we need more data.
    +
    891  // Note: bytes_parsed is 0 for a successful parse of a size 0 element. We
    +
    892  // need to check the element_size to disambiguate the "need more data" case
    +
    893  // from a successful parse.
    +
    894  if (bytes_parsed < 0 || (bytes_parsed == 0 && element_size != 0))
    +
    895  return bytes_parsed;
    +
    896 
    +
    897  int result = header_size + bytes_parsed;
    +
    898  list_state.bytes_parsed_ += result;
    +
    899 
    +
    900  // See if we have reached the end of the current list.
    +
    901  if (list_state.bytes_parsed_ == list_state.size_) {
    +
    902  if (!OnListEnd())
    +
    903  return -1;
    +
    904  }
    +
    905 
    +
    906  return result;
    +
    907 }
    +
    908 
    +
    909 bool WebMListParser::OnListStart(int id, int64_t size) {
    +
    910  const ListElementInfo* element_info = FindListInfo(id);
    +
    911  if (!element_info)
    +
    912  return false;
    +
    913 
    +
    914  int current_level =
    +
    915  root_level_ + static_cast<int>(list_state_stack_.size()) - 1;
    +
    916  if (current_level + 1 != element_info->level_)
    +
    917  return false;
    +
    918 
    +
    919  WebMParserClient* current_list_client = NULL;
    +
    920  if (!list_state_stack_.empty()) {
    +
    921  // Make sure the new list doesn't go past the end of the current list.
    +
    922  ListState current_list_state = list_state_stack_.back();
    +
    923  if (current_list_state.size_ != kWebMUnknownSize &&
    +
    924  current_list_state.size_ < current_list_state.bytes_parsed_ + size)
    +
    925  return false;
    +
    926  current_list_client = current_list_state.client_;
    +
    927  } else {
    +
    928  current_list_client = root_client_;
    +
    929  }
    +
    930 
    +
    931  WebMParserClient* new_list_client = current_list_client->OnListStart(id);
    +
    932  if (!new_list_client)
    +
    933  return false;
    +
    934 
    +
    935  ListState new_list_state = { id, size, 0, element_info, new_list_client };
    +
    936  list_state_stack_.push_back(new_list_state);
    +
    937 
    +
    938  if (size == 0)
    +
    939  return OnListEnd();
    +
    940 
    +
    941  return true;
    +
    942 }
    +
    943 
    +
    944 bool WebMListParser::OnListEnd() {
    +
    945  int lists_ended = 0;
    +
    946  for (; !list_state_stack_.empty(); ++lists_ended) {
    +
    947  const ListState& list_state = list_state_stack_.back();
    +
    948  int64_t bytes_parsed = list_state.bytes_parsed_;
    +
    949  int id = list_state.id_;
    +
    950 
    +
    951  if (bytes_parsed != list_state.size_)
    +
    952  break;
    +
    953 
    +
    954  list_state_stack_.pop_back();
    +
    955 
    +
    956  WebMParserClient* client = NULL;
    +
    957  if (!list_state_stack_.empty()) {
    +
    958  // Update the bytes_parsed_ for the parent element.
    +
    959  list_state_stack_.back().bytes_parsed_ += bytes_parsed;
    +
    960  client = list_state_stack_.back().client_;
    +
    961  } else {
    +
    962  client = root_client_;
    +
    963  }
    +
    964 
    +
    965  if (!client->OnListEnd(id))
    +
    966  return false;
    +
    967  }
    +
    968 
    +
    969  DCHECK_GE(lists_ended, 1);
    +
    970 
    +
    971  if (list_state_stack_.empty())
    +
    972  ChangeState(DONE_PARSING_LIST);
    +
    973 
    +
    974  return true;
    +
    975 }
    +
    976 
    +
    977 bool WebMListParser::IsSiblingOrAncestor(int id_a, int id_b) const {
    +
    978  DCHECK((id_a == kWebMIdSegment) || (id_a == kWebMIdCluster));
    +
    979 
    +
    980  if (id_a == kWebMIdCluster) {
    +
    981  // kWebMIdCluster siblings.
    +
    982  for (size_t i = 0; i < arraysize(kSegmentIds); i++) {
    +
    983  if (kSegmentIds[i].id_ == id_b)
    +
    984  return true;
    +
    985  }
    +
    986  }
    +
    987 
    +
    988  // kWebMIdSegment siblings.
    +
    989  return ((id_b == kWebMIdSegment) || (id_b == kWebMIdEBMLHeader));
    +
    990 }
    +
    991 
    +
    992 } // namespace media
    +
    993 } // namespace shaka
    +
    void Reset()
    Resets the state of the parser so it can start parsing a new list.
    Definition: webm_parser.cc:733
    +
    WebMListParser(int id, WebMParserClient *client)
    Definition: webm_parser.cc:722
    +
    int Parse(const uint8_t *buf, int size)
    Definition: webm_parser.cc:738
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/dbc/seek__head_8cc_source.html b/docs/d3/dbc/seek__head_8cc_source.html index e5b137cea2..55dee40d49 100644 --- a/docs/d3/dbc/seek__head_8cc_source.html +++ b/docs/d3/dbc/seek__head_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/seek_head.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    seek_head.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/webm/seek_head.h"
    8 
    9 #include <algorithm>
    10 #include <limits>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/third_party/libwebm/src/mkvmuxerutil.hpp"
    14 #include "packager/third_party/libwebm/src/webmids.hpp"
    15 
    16 namespace shaka {
    17 namespace media {
    18 namespace {
    19 
    20 // Cluster, Cues, Info, Tracks.
    21 const size_t kElementIdCount = 4u;
    22 
    23 uint64_t EbmlMasterElementWithPayloadSize(mkvmuxer::MkvId id, uint64_t payload_size) {
    24  return EbmlMasterElementSize(id, payload_size) + payload_size;
    25 }
    26 
    27 uint64_t MaxSeekEntrySize() {
    28  const uint64_t max_entry_payload_size =
    29  EbmlElementSize(
    30  mkvmuxer::kMkvSeekID,
    31  static_cast<mkvmuxer::uint64>(std::numeric_limits<uint32_t>::max())) +
    32  EbmlElementSize(mkvmuxer::kMkvSeekPosition,
    33  std::numeric_limits<mkvmuxer::uint64>::max());
    34  return EbmlMasterElementWithPayloadSize(mkvmuxer::kMkvSeek,
    35  max_entry_payload_size);
    36 }
    37 
    38 } // namespace
    39 
    40 SeekHead::SeekHead()
    41  : total_void_size_(EbmlMasterElementWithPayloadSize(
    42  mkvmuxer::kMkvSeekHead,
    43  kElementIdCount * MaxSeekEntrySize())) {}
    44 
    45 SeekHead::~SeekHead() {}
    46 
    47 bool SeekHead::Write(mkvmuxer::IMkvWriter* writer) {
    48  std::vector<SeekElement> seek_elements = CreateSeekElements();
    49  if (seek_elements.empty())
    50  return true;
    51 
    52  uint64_t payload_size = 0;
    53  for (const SeekHead::SeekElement& seek_element : seek_elements) {
    54  payload_size +=
    55  EbmlMasterElementWithPayloadSize(mkvmuxer::kMkvSeek, seek_element.size);
    56  }
    57 
    58  const int64_t start_pos = writer->Position();
    59  if (!WriteEbmlMasterElement(writer, mkvmuxer::kMkvSeekHead, payload_size))
    60  return false;
    61 
    62  for (const SeekHead::SeekElement& element : seek_elements) {
    63  if (!WriteEbmlMasterElement(writer, mkvmuxer::kMkvSeek, element.size) ||
    64  !WriteEbmlElement(writer, mkvmuxer::kMkvSeekID, element.id) ||
    65  !WriteEbmlElement(writer, mkvmuxer::kMkvSeekPosition, element.position))
    66  return false;
    67  }
    68 
    69  // If we wrote void before, then fill in the extra with void.
    70  if (wrote_void_) {
    71  const uint64_t extra_void =
    72  total_void_size_ - (writer->Position() - start_pos);
    73  if (!WriteVoidElement(writer, extra_void))
    74  return false;
    75  }
    76 
    77  return true;
    78 }
    79 
    80 bool SeekHead::WriteVoid(mkvmuxer::IMkvWriter* writer) {
    81  const uint64_t written = WriteVoidElement(writer, total_void_size_);
    82  if (!written)
    83  return false;
    84  wrote_void_ = true;
    85  return true;
    86 }
    87 
    88 std::vector<SeekHead::SeekElement> SeekHead::CreateSeekElements() {
    89  std::vector<SeekHead::SeekElement> seek_elements;
    90  if (info_pos_ != 0)
    91  seek_elements.emplace_back(mkvmuxer::kMkvInfo, info_pos_);
    92  if (tracks_pos_ != 0)
    93  seek_elements.emplace_back(mkvmuxer::kMkvTracks, tracks_pos_);
    94  if (cues_pos_ != 0)
    95  seek_elements.emplace_back(mkvmuxer::kMkvCues, cues_pos_);
    96  if (cluster_pos_ != 0)
    97  seek_elements.emplace_back(mkvmuxer::kMkvCluster, cluster_pos_);
    98  DCHECK_LE(seek_elements.size(), kElementIdCount);
    99 
    100  std::sort(seek_elements.begin(), seek_elements.end(),
    101  [](const SeekHead::SeekElement& left,
    102  const SeekHead::SeekElement& right) {
    103  return left.position < right.position;
    104  });
    105  for (SeekHead::SeekElement& element : seek_elements) {
    106  element.size =
    107  EbmlElementSize(mkvmuxer::kMkvSeekID, element.id) +
    108  EbmlElementSize(mkvmuxer::kMkvSeekPosition, element.position);
    109  }
    110  return seek_elements;
    111 }
    112 
    113 } // namespace media
    114 } // namespace shaka
    bool WriteVoid(mkvmuxer::IMkvWriter *writer)
    Writes a void element large enough to fit the SeekHead.
    Definition: seek_head.cc:80
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool Write(mkvmuxer::IMkvWriter *writer)
    Definition: seek_head.cc:47
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webm/seek_head.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 #include <limits>
    +
    11 
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/third_party/libwebm/src/mkvmuxerutil.hpp"
    +
    14 #include "packager/third_party/libwebm/src/webmids.hpp"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 namespace {
    +
    19 
    +
    20 // Cluster, Cues, Info, Tracks.
    +
    21 const size_t kElementIdCount = 4u;
    +
    22 
    +
    23 uint64_t EbmlMasterElementWithPayloadSize(mkvmuxer::MkvId id, uint64_t payload_size) {
    +
    24  return EbmlMasterElementSize(id, payload_size) + payload_size;
    +
    25 }
    +
    26 
    +
    27 uint64_t MaxSeekEntrySize() {
    +
    28  const uint64_t max_entry_payload_size =
    +
    29  EbmlElementSize(
    +
    30  mkvmuxer::kMkvSeekID,
    +
    31  static_cast<mkvmuxer::uint64>(std::numeric_limits<uint32_t>::max())) +
    +
    32  EbmlElementSize(mkvmuxer::kMkvSeekPosition,
    +
    33  std::numeric_limits<mkvmuxer::uint64>::max());
    +
    34  return EbmlMasterElementWithPayloadSize(mkvmuxer::kMkvSeek,
    +
    35  max_entry_payload_size);
    +
    36 }
    +
    37 
    +
    38 } // namespace
    +
    39 
    +
    40 SeekHead::SeekHead()
    +
    41  : total_void_size_(EbmlMasterElementWithPayloadSize(
    +
    42  mkvmuxer::kMkvSeekHead,
    +
    43  kElementIdCount * MaxSeekEntrySize())) {}
    +
    44 
    +
    45 SeekHead::~SeekHead() {}
    +
    46 
    +
    47 bool SeekHead::Write(mkvmuxer::IMkvWriter* writer) {
    +
    48  std::vector<SeekElement> seek_elements = CreateSeekElements();
    +
    49  if (seek_elements.empty())
    +
    50  return true;
    +
    51 
    +
    52  uint64_t payload_size = 0;
    +
    53  for (const SeekHead::SeekElement& seek_element : seek_elements) {
    +
    54  payload_size +=
    +
    55  EbmlMasterElementWithPayloadSize(mkvmuxer::kMkvSeek, seek_element.size);
    +
    56  }
    +
    57 
    +
    58  const int64_t start_pos = writer->Position();
    +
    59  if (!WriteEbmlMasterElement(writer, mkvmuxer::kMkvSeekHead, payload_size))
    +
    60  return false;
    +
    61 
    +
    62  for (const SeekHead::SeekElement& element : seek_elements) {
    +
    63  if (!WriteEbmlMasterElement(writer, mkvmuxer::kMkvSeek, element.size) ||
    +
    64  !WriteEbmlElement(writer, mkvmuxer::kMkvSeekID, element.id) ||
    +
    65  !WriteEbmlElement(writer, mkvmuxer::kMkvSeekPosition, element.position))
    +
    66  return false;
    +
    67  }
    +
    68 
    +
    69  // If we wrote void before, then fill in the extra with void.
    +
    70  if (wrote_void_) {
    +
    71  const uint64_t extra_void =
    +
    72  total_void_size_ - (writer->Position() - start_pos);
    +
    73  if (!WriteVoidElement(writer, extra_void))
    +
    74  return false;
    +
    75  }
    +
    76 
    +
    77  return true;
    +
    78 }
    +
    79 
    +
    80 bool SeekHead::WriteVoid(mkvmuxer::IMkvWriter* writer) {
    +
    81  const uint64_t written = WriteVoidElement(writer, total_void_size_);
    +
    82  if (!written)
    +
    83  return false;
    +
    84  wrote_void_ = true;
    +
    85  return true;
    +
    86 }
    +
    87 
    +
    88 std::vector<SeekHead::SeekElement> SeekHead::CreateSeekElements() {
    +
    89  std::vector<SeekHead::SeekElement> seek_elements;
    +
    90  if (info_pos_ != 0)
    +
    91  seek_elements.emplace_back(mkvmuxer::kMkvInfo, info_pos_);
    +
    92  if (tracks_pos_ != 0)
    +
    93  seek_elements.emplace_back(mkvmuxer::kMkvTracks, tracks_pos_);
    +
    94  if (cues_pos_ != 0)
    +
    95  seek_elements.emplace_back(mkvmuxer::kMkvCues, cues_pos_);
    +
    96  if (cluster_pos_ != 0)
    +
    97  seek_elements.emplace_back(mkvmuxer::kMkvCluster, cluster_pos_);
    +
    98  DCHECK_LE(seek_elements.size(), kElementIdCount);
    +
    99 
    +
    100  std::sort(seek_elements.begin(), seek_elements.end(),
    +
    101  [](const SeekHead::SeekElement& left,
    +
    102  const SeekHead::SeekElement& right) {
    +
    103  return left.position < right.position;
    +
    104  });
    +
    105  for (SeekHead::SeekElement& element : seek_elements) {
    +
    106  element.size =
    +
    107  EbmlElementSize(mkvmuxer::kMkvSeekID, element.id) +
    +
    108  EbmlElementSize(mkvmuxer::kMkvSeekPosition, element.position);
    +
    109  }
    +
    110  return seek_elements;
    +
    111 }
    +
    112 
    +
    113 } // namespace media
    +
    114 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/dbe/demuxer_8cc_source.html b/docs/d3/dbe/demuxer_8cc_source.html index 26b6eb2677..226e0f2832 100644 --- a/docs/d3/dbe/demuxer_8cc_source.html +++ b/docs/d3/dbe/demuxer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/demuxer/demuxer.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    demuxer.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/demuxer/demuxer.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/base/bind.h"
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/file/file.h"
    15 #include "packager/media/base/decryptor_source.h"
    16 #include "packager/media/base/key_source.h"
    17 #include "packager/media/base/macros.h"
    18 #include "packager/media/base/media_sample.h"
    19 #include "packager/media/base/stream_info.h"
    20 #include "packager/media/formats/mp2t/mp2t_media_parser.h"
    21 #include "packager/media/formats/mp4/mp4_media_parser.h"
    22 #include "packager/media/formats/webm/webm_media_parser.h"
    23 #include "packager/media/formats/wvm/wvm_media_parser.h"
    24 
    25 namespace {
    26 // 65KB, sufficient to determine the container and likely all init data.
    27 const size_t kInitBufSize = 0x10000;
    28 const size_t kBufSize = 0x200000; // 2MB
    29 // Maximum number of allowed queued samples. If we are receiving a lot of
    30 // samples before seeing init_event, something is not right. The number
    31 // set here is arbitrary though.
    32 const size_t kQueuedSamplesLimit = 10000;
    33 const size_t kInvalidStreamIndex = static_cast<size_t>(-1);
    34 const size_t kBaseVideoOutputStreamIndex = 0x100;
    35 const size_t kBaseAudioOutputStreamIndex = 0x200;
    36 const size_t kBaseTextOutputStreamIndex = 0x300;
    37 
    38 std::string GetStreamLabel(size_t stream_index) {
    39  switch (stream_index) {
    40  case kBaseVideoOutputStreamIndex:
    41  return "video";
    42  case kBaseAudioOutputStreamIndex:
    43  return "audio";
    44  case kBaseTextOutputStreamIndex:
    45  return "text";
    46  default:
    47  return base::SizeTToString(stream_index);
    48  }
    49 }
    50 
    51 bool GetStreamIndex(const std::string& stream_label, size_t* stream_index) {
    52  DCHECK(stream_index);
    53  if (stream_label == "video") {
    54  *stream_index = kBaseVideoOutputStreamIndex;
    55  } else if (stream_label == "audio") {
    56  *stream_index = kBaseAudioOutputStreamIndex;
    57  } else if (stream_label == "text") {
    58  *stream_index = kBaseTextOutputStreamIndex;
    59  } else {
    60  // Expect stream_label to be a zero based stream id.
    61  if (!base::StringToSizeT(stream_label, stream_index)) {
    62  LOG(ERROR) << "Invalid argument --stream=" << stream_label << "; "
    63  << "should be 'audio', 'video', 'text', or a number";
    64  return false;
    65  }
    66  }
    67  return true;
    68 }
    69 
    70 }
    71 
    72 namespace shaka {
    73 namespace media {
    74 
    75 Demuxer::Demuxer(const std::string& file_name)
    76  : file_name_(file_name), buffer_(new uint8_t[kBufSize]) {}
    77 
    78 Demuxer::~Demuxer() {
    79  if (media_file_)
    80  media_file_->Close();
    81 }
    82 
    83 void Demuxer::SetKeySource(std::unique_ptr<KeySource> key_source) {
    84  key_source_ = std::move(key_source);
    85 }
    86 
    88  LOG(INFO) << "Demuxer::Run() on file '" << file_name_ << "'.";
    89  Status status = InitializeParser();
    90  // ParserInitEvent callback is called after a few calls to Parse(), which sets
    91  // up the streams. Only after that, we can verify the outputs below.
    92  while (!all_streams_ready_ && status.ok())
    93  status.Update(Parse());
    94  // If no output is defined, then return success after receiving all stream
    95  // info.
    96  if (all_streams_ready_ && output_handlers().empty())
    97  return Status::OK;
    98  if (!init_event_status_.ok())
    99  return init_event_status_;
    100  if (!status.ok())
    101  return status;
    102  // Check if all specified outputs exists.
    103  for (const auto& pair : output_handlers()) {
    104  if (std::find(stream_indexes_.begin(), stream_indexes_.end(), pair.first) ==
    105  stream_indexes_.end()) {
    106  LOG(ERROR) << "Invalid argument, stream=" << GetStreamLabel(pair.first)
    107  << " not available.";
    108  return Status(error::INVALID_ARGUMENT, "Stream not available");
    109  }
    110  }
    111 
    112  while (!cancelled_ && status.ok())
    113  status.Update(Parse());
    114  if (cancelled_ && status.ok())
    115  return Status(error::CANCELLED, "Demuxer run cancelled");
    116 
    117  if (status.error_code() == error::END_OF_STREAM) {
    118  for (size_t stream_index : stream_indexes_) {
    119  status = FlushDownstream(stream_index);
    120  if (!status.ok())
    121  return status;
    122  }
    123  return Status::OK;
    124  }
    125  return status;
    126 }
    127 
    129  cancelled_ = true;
    130 }
    131 
    132 Status Demuxer::SetHandler(const std::string& stream_label,
    133  std::shared_ptr<MediaHandler> handler) {
    134  size_t stream_index = kInvalidStreamIndex;
    135  if (!GetStreamIndex(stream_label, &stream_index)) {
    136  return Status(error::INVALID_ARGUMENT,
    137  "Invalid stream: " + stream_label);
    138  }
    139  return MediaHandler::SetHandler(stream_index, std::move(handler));
    140 }
    141 
    142 void Demuxer::SetLanguageOverride(const std::string& stream_label,
    143  const std::string& language_override) {
    144  size_t stream_index = kInvalidStreamIndex;
    145  if (!GetStreamIndex(stream_label, &stream_index))
    146  LOG(WARNING) << "Invalid stream for language override " << stream_label;
    147  language_overrides_[stream_index] = language_override;
    148 }
    149 
    150 Demuxer::QueuedSample::QueuedSample(uint32_t local_track_id,
    151  std::shared_ptr<MediaSample> local_sample)
    152  : track_id(local_track_id), sample(local_sample) {}
    153 
    154 Demuxer::QueuedSample::~QueuedSample() {}
    155 
    156 Status Demuxer::InitializeParser() {
    157  DCHECK(!media_file_);
    158  DCHECK(!all_streams_ready_);
    159 
    160  LOG(INFO) << "Initialize Demuxer for file '" << file_name_ << "'.";
    161 
    162  media_file_ = File::Open(file_name_.c_str(), "r");
    163  if (!media_file_) {
    164  return Status(error::FILE_FAILURE,
    165  "Cannot open file for reading " + file_name_);
    166  }
    167 
    168  // Read enough bytes before detecting the container.
    169  int64_t bytes_read = 0;
    170  while (static_cast<size_t>(bytes_read) < kInitBufSize) {
    171  int64_t read_result =
    172  media_file_->Read(buffer_.get() + bytes_read, kInitBufSize);
    173  if (read_result < 0)
    174  return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
    175  if (read_result == 0)
    176  break;
    177  bytes_read += read_result;
    178  }
    179  container_name_ = DetermineContainer(buffer_.get(), bytes_read);
    180 
    181  // Initialize media parser.
    182  switch (container_name_) {
    183  case CONTAINER_MOV:
    184  parser_.reset(new mp4::MP4MediaParser());
    185  break;
    186  case CONTAINER_MPEG2TS:
    187  parser_.reset(new mp2t::Mp2tMediaParser());
    188  break;
    189  // Widevine classic (WVM) is derived from MPEG2PS. We do not support
    190  // non-WVM MPEG2PS file, thus we do not differentiate between the two.
    191  // Every MPEG2PS file is assumed to be WVM file. If it turns out not the
    192  // case, an error will be reported when trying to parse the file as WVM
    193  // file.
    194  case CONTAINER_MPEG2PS:
    195  FALLTHROUGH_INTENDED;
    196  case CONTAINER_WVM:
    197  parser_.reset(new wvm::WvmMediaParser());
    198  break;
    199  case CONTAINER_WEBM:
    200  parser_.reset(new WebMMediaParser());
    201  break;
    202  case CONTAINER_UNKNOWN: {
    203  const int64_t kDumpSizeLimit = 512;
    204  LOG(ERROR) << "Failed to detect the container type from the buffer: "
    205  << base::HexEncode(buffer_.get(),
    206  std::min(bytes_read, kDumpSizeLimit));
    207  return Status(error::INVALID_ARGUMENT,
    208  "Failed to detect the container type.");
    209  }
    210  default:
    211  NOTIMPLEMENTED() << "Container " << container_name_
    212  << " is not supported.";
    213  return Status(error::UNIMPLEMENTED, "Container not supported.");
    214  }
    215 
    216  parser_->Init(base::Bind(&Demuxer::ParserInitEvent, base::Unretained(this)),
    217  base::Bind(&Demuxer::NewSampleEvent, base::Unretained(this)),
    218  key_source_.get());
    219 
    220  // Handle trailing 'moov'.
    221  if (container_name_ == CONTAINER_MOV &&
    222  File::IsLocalRegularFile(file_name_.c_str())) {
    223  // TODO(kqyang): Investigate whether we can reuse the existing file
    224  // descriptor |media_file_| instead of opening the same file again.
    225  static_cast<mp4::MP4MediaParser*>(parser_.get())->LoadMoov(file_name_);
    226  }
    227  if (!parser_->Parse(buffer_.get(), bytes_read)) {
    228  return Status(error::PARSER_FAILURE,
    229  "Cannot parse media file " + file_name_);
    230  }
    231  return Status::OK;
    232 }
    233 
    234 void Demuxer::ParserInitEvent(
    235  const std::vector<std::shared_ptr<StreamInfo>>& stream_infos) {
    236  if (dump_stream_info_) {
    237  printf("\nFile \"%s\":\n", file_name_.c_str());
    238  printf("Found %zu stream(s).\n", stream_infos.size());
    239  for (size_t i = 0; i < stream_infos.size(); ++i)
    240  printf("Stream [%zu] %s\n", i, stream_infos[i]->ToString().c_str());
    241  }
    242 
    243  int base_stream_index = 0;
    244  bool video_handler_set =
    245  output_handlers().find(kBaseVideoOutputStreamIndex) !=
    246  output_handlers().end();
    247  bool audio_handler_set =
    248  output_handlers().find(kBaseAudioOutputStreamIndex) !=
    249  output_handlers().end();
    250  bool text_handler_set =
    251  output_handlers().find(kBaseTextOutputStreamIndex) !=
    252  output_handlers().end();
    253  for (const std::shared_ptr<StreamInfo>& stream_info : stream_infos) {
    254  size_t stream_index = base_stream_index;
    255  if (video_handler_set && stream_info->stream_type() == kStreamVideo) {
    256  stream_index = kBaseVideoOutputStreamIndex;
    257  // Only for the first video stream.
    258  video_handler_set = false;
    259  }
    260  if (audio_handler_set && stream_info->stream_type() == kStreamAudio) {
    261  stream_index = kBaseAudioOutputStreamIndex;
    262  // Only for the first audio stream.
    263  audio_handler_set = false;
    264  }
    265  if (text_handler_set && stream_info->stream_type() == kStreamText) {
    266  stream_index = kBaseTextOutputStreamIndex;
    267  text_handler_set = false;
    268  }
    269 
    270  const bool handler_set =
    271  output_handlers().find(stream_index) != output_handlers().end();
    272  if (handler_set) {
    273  track_id_to_stream_index_map_[stream_info->track_id()] = stream_index;
    274  stream_indexes_.push_back(stream_index);
    275  auto iter = language_overrides_.find(stream_index);
    276  if (iter != language_overrides_.end() &&
    277  stream_info->stream_type() != kStreamVideo) {
    278  stream_info->set_language(iter->second);
    279  }
    280  if (stream_info->is_encrypted()) {
    281  init_event_status_.Update(Status(error::INVALID_ARGUMENT,
    282  "A decryption key source is not "
    283  "provided for an encrypted stream."));
    284  } else {
    285  init_event_status_.Update(
    286  DispatchStreamInfo(stream_index, stream_info));
    287  }
    288  } else {
    289  track_id_to_stream_index_map_[stream_info->track_id()] =
    290  kInvalidStreamIndex;
    291  }
    292  ++base_stream_index;
    293  }
    294  all_streams_ready_ = true;
    295 }
    296 
    297 bool Demuxer::NewSampleEvent(uint32_t track_id,
    298  const std::shared_ptr<MediaSample>& sample) {
    299  if (!all_streams_ready_) {
    300  if (queued_samples_.size() >= kQueuedSamplesLimit) {
    301  LOG(ERROR) << "Queued samples limit reached: " << kQueuedSamplesLimit;
    302  return false;
    303  }
    304  queued_samples_.push_back(QueuedSample(track_id, sample));
    305  return true;
    306  }
    307  if (!init_event_status_.ok()) {
    308  return false;
    309  }
    310  while (!queued_samples_.empty()) {
    311  if (!PushSample(queued_samples_.front().track_id,
    312  queued_samples_.front().sample)) {
    313  return false;
    314  }
    315  queued_samples_.pop_front();
    316  }
    317  return PushSample(track_id, sample);
    318 }
    319 
    320 bool Demuxer::PushSample(uint32_t track_id,
    321  const std::shared_ptr<MediaSample>& sample) {
    322  auto stream_index_iter = track_id_to_stream_index_map_.find(track_id);
    323  if (stream_index_iter == track_id_to_stream_index_map_.end()) {
    324  LOG(ERROR) << "Track " << track_id << " not found.";
    325  return false;
    326  }
    327  if (stream_index_iter->second == kInvalidStreamIndex)
    328  return true;
    329  Status status = DispatchMediaSample(stream_index_iter->second, sample);
    330  if (!status.ok()) {
    331  LOG(ERROR) << "Failed to process sample " << stream_index_iter->second
    332  << " " << status;
    333  }
    334  return status.ok();
    335 }
    336 
    337 Status Demuxer::Parse() {
    338  DCHECK(media_file_);
    339  DCHECK(parser_);
    340  DCHECK(buffer_);
    341 
    342  int64_t bytes_read = media_file_->Read(buffer_.get(), kBufSize);
    343  if (bytes_read == 0) {
    344  if (!parser_->Flush())
    345  return Status(error::PARSER_FAILURE, "Failed to flush.");
    346  return Status(error::END_OF_STREAM, "");
    347  } else if (bytes_read < 0) {
    348  return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
    349  }
    350 
    351  return parser_->Parse(buffer_.get(), bytes_read)
    352  ? Status::OK
    353  : Status(error::PARSER_FAILURE,
    354  "Cannot parse media file " + file_name_);
    355 }
    356 
    357 } // namespace media
    358 } // namespace shaka
    Status DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
    Dispatch the stream info to downstream handlers.
    -
    Status SetHandler(const std::string &stream_label, std::shared_ptr< MediaHandler > handler)
    Definition: demuxer.cc:132
    -
    Status Run() override
    Definition: demuxer.cc:87
    - -
    static bool IsLocalRegularFile(const char *file_name)
    Definition: file.cc:354
    -
    void SetLanguageOverride(const std::string &stream_label, const std::string &language_override)
    Definition: demuxer.cc:142
    -
    virtual int64_t Read(void *buffer, uint64_t length)=0
    -
    All the methods that are virtual are virtual for mocking.
    - - - -
    virtual bool Close()=0
    -
    void SetKeySource(std::unique_ptr< KeySource > key_source)
    Definition: demuxer.cc:83
    -
    Status FlushDownstream(size_t output_stream_index)
    Flush the downstream connected at the specified output stream index.
    -
    void Update(Status new_status)
    Definition: status.cc:78
    -
    Demuxer(const std::string &file_name)
    Definition: demuxer.cc:75
    -
    virtual bool Open()=0
    Internal open. Should not be used directly.
    -
    Status DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
    Dispatch the media sample to downstream handlers.
    -
    void Cancel() override
    Definition: demuxer.cc:128
    -
    Status SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
    Connect downstream handler at the specified output stream index.
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/demuxer/demuxer.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/bind.h"
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/base/strings/string_number_conversions.h"
    +
    14 #include "packager/file/file.h"
    +
    15 #include "packager/media/base/decryptor_source.h"
    +
    16 #include "packager/media/base/key_source.h"
    +
    17 #include "packager/media/base/macros.h"
    +
    18 #include "packager/media/base/media_sample.h"
    +
    19 #include "packager/media/base/stream_info.h"
    +
    20 #include "packager/media/formats/mp2t/mp2t_media_parser.h"
    +
    21 #include "packager/media/formats/mp4/mp4_media_parser.h"
    +
    22 #include "packager/media/formats/webm/webm_media_parser.h"
    +
    23 #include "packager/media/formats/webvtt/webvtt_parser.h"
    +
    24 #include "packager/media/formats/wvm/wvm_media_parser.h"
    +
    25 
    +
    26 namespace {
    +
    27 // 65KB, sufficient to determine the container and likely all init data.
    +
    28 const size_t kInitBufSize = 0x10000;
    +
    29 const size_t kBufSize = 0x200000; // 2MB
    +
    30 // Maximum number of allowed queued samples. If we are receiving a lot of
    +
    31 // samples before seeing init_event, something is not right. The number
    +
    32 // set here is arbitrary though.
    +
    33 const size_t kQueuedSamplesLimit = 10000;
    +
    34 const size_t kInvalidStreamIndex = static_cast<size_t>(-1);
    +
    35 const size_t kBaseVideoOutputStreamIndex = 0x100;
    +
    36 const size_t kBaseAudioOutputStreamIndex = 0x200;
    +
    37 const size_t kBaseTextOutputStreamIndex = 0x300;
    +
    38 
    +
    39 std::string GetStreamLabel(size_t stream_index) {
    +
    40  switch (stream_index) {
    +
    41  case kBaseVideoOutputStreamIndex:
    +
    42  return "video";
    +
    43  case kBaseAudioOutputStreamIndex:
    +
    44  return "audio";
    +
    45  case kBaseTextOutputStreamIndex:
    +
    46  return "text";
    +
    47  default:
    +
    48  return base::SizeTToString(stream_index);
    +
    49  }
    +
    50 }
    +
    51 
    +
    52 bool GetStreamIndex(const std::string& stream_label, size_t* stream_index) {
    +
    53  DCHECK(stream_index);
    +
    54  if (stream_label == "video") {
    +
    55  *stream_index = kBaseVideoOutputStreamIndex;
    +
    56  } else if (stream_label == "audio") {
    +
    57  *stream_index = kBaseAudioOutputStreamIndex;
    +
    58  } else if (stream_label == "text") {
    +
    59  *stream_index = kBaseTextOutputStreamIndex;
    +
    60  } else {
    +
    61  // Expect stream_label to be a zero based stream id.
    +
    62  if (!base::StringToSizeT(stream_label, stream_index)) {
    +
    63  LOG(ERROR) << "Invalid argument --stream=" << stream_label << "; "
    +
    64  << "should be 'audio', 'video', 'text', or a number";
    +
    65  return false;
    +
    66  }
    +
    67  }
    +
    68  return true;
    +
    69 }
    +
    70 
    +
    71 }
    +
    72 
    +
    73 namespace shaka {
    +
    74 namespace media {
    +
    75 
    +
    76 Demuxer::Demuxer(const std::string& file_name)
    +
    77  : file_name_(file_name), buffer_(new uint8_t[kBufSize]) {}
    +
    78 
    +
    79 Demuxer::~Demuxer() {
    +
    80  if (media_file_)
    +
    81  media_file_->Close();
    +
    82 }
    +
    83 
    +
    84 void Demuxer::SetKeySource(std::unique_ptr<KeySource> key_source) {
    +
    85  key_source_ = std::move(key_source);
    +
    86 }
    +
    87 
    + +
    89  LOG(INFO) << "Demuxer::Run() on file '" << file_name_ << "'.";
    +
    90  Status status = InitializeParser();
    +
    91  // ParserInitEvent callback is called after a few calls to Parse(), which sets
    +
    92  // up the streams. Only after that, we can verify the outputs below.
    +
    93  while (!all_streams_ready_ && status.ok())
    +
    94  status.Update(Parse());
    +
    95  // If no output is defined, then return success after receiving all stream
    +
    96  // info.
    +
    97  if (all_streams_ready_ && output_handlers().empty())
    +
    98  return Status::OK;
    +
    99  if (!init_event_status_.ok())
    +
    100  return init_event_status_;
    +
    101  if (!status.ok())
    +
    102  return status;
    +
    103  // Check if all specified outputs exists.
    +
    104  for (const auto& pair : output_handlers()) {
    +
    105  if (std::find(stream_indexes_.begin(), stream_indexes_.end(), pair.first) ==
    +
    106  stream_indexes_.end()) {
    +
    107  LOG(ERROR) << "Invalid argument, stream=" << GetStreamLabel(pair.first)
    +
    108  << " not available.";
    +
    109  return Status(error::INVALID_ARGUMENT, "Stream not available");
    +
    110  }
    +
    111  }
    +
    112 
    +
    113  while (!cancelled_ && status.ok())
    +
    114  status.Update(Parse());
    +
    115  if (cancelled_ && status.ok())
    +
    116  return Status(error::CANCELLED, "Demuxer run cancelled");
    +
    117 
    +
    118  if (status.error_code() == error::END_OF_STREAM) {
    +
    119  for (size_t stream_index : stream_indexes_) {
    +
    120  status = FlushDownstream(stream_index);
    +
    121  if (!status.ok())
    +
    122  return status;
    +
    123  }
    +
    124  return Status::OK;
    +
    125  }
    +
    126  return status;
    +
    127 }
    +
    128 
    + +
    130  cancelled_ = true;
    +
    131 }
    +
    132 
    +
    133 Status Demuxer::SetHandler(const std::string& stream_label,
    +
    134  std::shared_ptr<MediaHandler> handler) {
    +
    135  size_t stream_index = kInvalidStreamIndex;
    +
    136  if (!GetStreamIndex(stream_label, &stream_index)) {
    +
    137  return Status(error::INVALID_ARGUMENT,
    +
    138  "Invalid stream: " + stream_label);
    +
    139  }
    +
    140  return MediaHandler::SetHandler(stream_index, std::move(handler));
    +
    141 }
    +
    142 
    +
    143 void Demuxer::SetLanguageOverride(const std::string& stream_label,
    +
    144  const std::string& language_override) {
    +
    145  size_t stream_index = kInvalidStreamIndex;
    +
    146  if (!GetStreamIndex(stream_label, &stream_index))
    +
    147  LOG(WARNING) << "Invalid stream for language override " << stream_label;
    +
    148  language_overrides_[stream_index] = language_override;
    +
    149 }
    +
    150 
    +
    151 Status Demuxer::InitializeParser() {
    +
    152  DCHECK(!media_file_);
    +
    153  DCHECK(!all_streams_ready_);
    +
    154 
    +
    155  LOG(INFO) << "Initialize Demuxer for file '" << file_name_ << "'.";
    +
    156 
    +
    157  media_file_ = File::Open(file_name_.c_str(), "r");
    +
    158  if (!media_file_) {
    +
    159  return Status(error::FILE_FAILURE,
    +
    160  "Cannot open file for reading " + file_name_);
    +
    161  }
    +
    162 
    +
    163  // Read enough bytes before detecting the container.
    +
    164  int64_t bytes_read = 0;
    +
    165  while (static_cast<size_t>(bytes_read) < kInitBufSize) {
    +
    166  int64_t read_result =
    +
    167  media_file_->Read(buffer_.get() + bytes_read, kInitBufSize);
    +
    168  if (read_result < 0)
    +
    169  return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
    +
    170  if (read_result == 0)
    +
    171  break;
    +
    172  bytes_read += read_result;
    +
    173  }
    +
    174  container_name_ = DetermineContainer(buffer_.get(), bytes_read);
    +
    175 
    +
    176  // Initialize media parser.
    +
    177  switch (container_name_) {
    +
    178  case CONTAINER_MOV:
    +
    179  parser_.reset(new mp4::MP4MediaParser());
    +
    180  break;
    +
    181  case CONTAINER_MPEG2TS:
    +
    182  parser_.reset(new mp2t::Mp2tMediaParser());
    +
    183  break;
    +
    184  // Widevine classic (WVM) is derived from MPEG2PS. We do not support
    +
    185  // non-WVM MPEG2PS file, thus we do not differentiate between the two.
    +
    186  // Every MPEG2PS file is assumed to be WVM file. If it turns out not the
    +
    187  // case, an error will be reported when trying to parse the file as WVM
    +
    188  // file.
    +
    189  case CONTAINER_MPEG2PS:
    +
    190  FALLTHROUGH_INTENDED;
    +
    191  case CONTAINER_WVM:
    +
    192  parser_.reset(new wvm::WvmMediaParser());
    +
    193  break;
    +
    194  case CONTAINER_WEBM:
    +
    195  parser_.reset(new WebMMediaParser());
    +
    196  break;
    +
    197  case CONTAINER_WEBVTT:
    +
    198  parser_.reset(new WebVttParser());
    +
    199  break;
    +
    200  case CONTAINER_UNKNOWN: {
    +
    201  const int64_t kDumpSizeLimit = 512;
    +
    202  LOG(ERROR) << "Failed to detect the container type from the buffer: "
    +
    203  << base::HexEncode(buffer_.get(),
    +
    204  std::min(bytes_read, kDumpSizeLimit));
    +
    205  return Status(error::INVALID_ARGUMENT,
    +
    206  "Failed to detect the container type.");
    +
    207  }
    +
    208  default:
    +
    209  NOTIMPLEMENTED() << "Container " << container_name_
    +
    210  << " is not supported.";
    +
    211  return Status(error::UNIMPLEMENTED, "Container not supported.");
    +
    212  }
    +
    213 
    +
    214  parser_->Init(
    +
    215  base::Bind(&Demuxer::ParserInitEvent, base::Unretained(this)),
    +
    216  base::Bind(&Demuxer::NewMediaSampleEvent, base::Unretained(this)),
    +
    217  base::Bind(&Demuxer::NewTextSampleEvent, base::Unretained(this)),
    +
    218  key_source_.get());
    +
    219 
    +
    220  // Handle trailing 'moov'.
    +
    221  if (container_name_ == CONTAINER_MOV &&
    +
    222  File::IsLocalRegularFile(file_name_.c_str())) {
    +
    223  // TODO(kqyang): Investigate whether we can reuse the existing file
    +
    224  // descriptor |media_file_| instead of opening the same file again.
    +
    225  static_cast<mp4::MP4MediaParser*>(parser_.get())->LoadMoov(file_name_);
    +
    226  }
    +
    227  if (!parser_->Parse(buffer_.get(), bytes_read)) {
    +
    228  return Status(error::PARSER_FAILURE,
    +
    229  "Cannot parse media file " + file_name_);
    +
    230  }
    +
    231  return Status::OK;
    +
    232 }
    +
    233 
    +
    234 void Demuxer::ParserInitEvent(
    +
    235  const std::vector<std::shared_ptr<StreamInfo>>& stream_infos) {
    +
    236  if (dump_stream_info_) {
    +
    237  printf("\nFile \"%s\":\n", file_name_.c_str());
    +
    238  printf("Found %zu stream(s).\n", stream_infos.size());
    +
    239  for (size_t i = 0; i < stream_infos.size(); ++i)
    +
    240  printf("Stream [%zu] %s\n", i, stream_infos[i]->ToString().c_str());
    +
    241  }
    +
    242 
    +
    243  int base_stream_index = 0;
    +
    244  bool video_handler_set =
    +
    245  output_handlers().find(kBaseVideoOutputStreamIndex) !=
    +
    246  output_handlers().end();
    +
    247  bool audio_handler_set =
    +
    248  output_handlers().find(kBaseAudioOutputStreamIndex) !=
    +
    249  output_handlers().end();
    +
    250  bool text_handler_set =
    +
    251  output_handlers().find(kBaseTextOutputStreamIndex) !=
    +
    252  output_handlers().end();
    +
    253  for (const std::shared_ptr<StreamInfo>& stream_info : stream_infos) {
    +
    254  size_t stream_index = base_stream_index;
    +
    255  if (video_handler_set && stream_info->stream_type() == kStreamVideo) {
    +
    256  stream_index = kBaseVideoOutputStreamIndex;
    +
    257  // Only for the first video stream.
    +
    258  video_handler_set = false;
    +
    259  }
    +
    260  if (audio_handler_set && stream_info->stream_type() == kStreamAudio) {
    +
    261  stream_index = kBaseAudioOutputStreamIndex;
    +
    262  // Only for the first audio stream.
    +
    263  audio_handler_set = false;
    +
    264  }
    +
    265  if (text_handler_set && stream_info->stream_type() == kStreamText) {
    +
    266  stream_index = kBaseTextOutputStreamIndex;
    +
    267  text_handler_set = false;
    +
    268  }
    +
    269 
    +
    270  const bool handler_set =
    +
    271  output_handlers().find(stream_index) != output_handlers().end();
    +
    272  if (handler_set) {
    +
    273  track_id_to_stream_index_map_[stream_info->track_id()] = stream_index;
    +
    274  stream_indexes_.push_back(stream_index);
    +
    275  auto iter = language_overrides_.find(stream_index);
    +
    276  if (iter != language_overrides_.end() &&
    +
    277  stream_info->stream_type() != kStreamVideo) {
    +
    278  stream_info->set_language(iter->second);
    +
    279  }
    +
    280  if (stream_info->is_encrypted()) {
    +
    281  init_event_status_.Update(Status(error::INVALID_ARGUMENT,
    +
    282  "A decryption key source is not "
    +
    283  "provided for an encrypted stream."));
    +
    284  } else {
    +
    285  init_event_status_.Update(
    +
    286  DispatchStreamInfo(stream_index, stream_info));
    +
    287  }
    +
    288  } else {
    +
    289  track_id_to_stream_index_map_[stream_info->track_id()] =
    +
    290  kInvalidStreamIndex;
    +
    291  }
    +
    292  ++base_stream_index;
    +
    293  }
    +
    294  all_streams_ready_ = true;
    +
    295 }
    +
    296 
    +
    297 bool Demuxer::NewMediaSampleEvent(uint32_t track_id,
    +
    298  std::shared_ptr<MediaSample> sample) {
    +
    299  if (!all_streams_ready_) {
    +
    300  if (queued_media_samples_.size() >= kQueuedSamplesLimit) {
    +
    301  LOG(ERROR) << "Queued samples limit reached: " << kQueuedSamplesLimit;
    +
    302  return false;
    +
    303  }
    +
    304  queued_media_samples_.emplace_back(track_id, sample);
    +
    305  return true;
    +
    306  }
    +
    307  if (!init_event_status_.ok()) {
    +
    308  return false;
    +
    309  }
    +
    310 
    +
    311  while (!queued_media_samples_.empty()) {
    +
    312  if (!PushMediaSample(queued_media_samples_.front().track_id,
    +
    313  queued_media_samples_.front().sample)) {
    +
    314  return false;
    +
    315  }
    +
    316  queued_media_samples_.pop_front();
    +
    317  }
    +
    318  return PushMediaSample(track_id, sample);
    +
    319 }
    +
    320 
    +
    321 bool Demuxer::NewTextSampleEvent(uint32_t track_id,
    +
    322  std::shared_ptr<TextSample> sample) {
    +
    323  if (!all_streams_ready_) {
    +
    324  if (queued_text_samples_.size() >= kQueuedSamplesLimit) {
    +
    325  LOG(ERROR) << "Queued samples limit reached: " << kQueuedSamplesLimit;
    +
    326  return false;
    +
    327  }
    +
    328  queued_text_samples_.emplace_back(track_id, sample);
    +
    329  return true;
    +
    330  }
    +
    331  if (!init_event_status_.ok()) {
    +
    332  return false;
    +
    333  }
    +
    334 
    +
    335  while (!queued_text_samples_.empty()) {
    +
    336  if (!PushTextSample(queued_text_samples_.front().track_id,
    +
    337  queued_text_samples_.front().sample)) {
    +
    338  return false;
    +
    339  }
    +
    340  queued_text_samples_.pop_front();
    +
    341  }
    +
    342  return PushTextSample(track_id, sample);
    +
    343 }
    +
    344 
    +
    345 bool Demuxer::PushMediaSample(uint32_t track_id,
    +
    346  std::shared_ptr<MediaSample> sample) {
    +
    347  auto stream_index_iter = track_id_to_stream_index_map_.find(track_id);
    +
    348  if (stream_index_iter == track_id_to_stream_index_map_.end()) {
    +
    349  LOG(ERROR) << "Track " << track_id << " not found.";
    +
    350  return false;
    +
    351  }
    +
    352  if (stream_index_iter->second == kInvalidStreamIndex)
    +
    353  return true;
    +
    354  Status status = DispatchMediaSample(stream_index_iter->second, sample);
    +
    355  if (!status.ok()) {
    +
    356  LOG(ERROR) << "Failed to process sample " << stream_index_iter->second
    +
    357  << " " << status;
    +
    358  return false;
    +
    359  }
    +
    360  return true;
    +
    361 }
    +
    362 
    +
    363 bool Demuxer::PushTextSample(uint32_t track_id,
    +
    364  std::shared_ptr<TextSample> sample) {
    +
    365  auto stream_index_iter = track_id_to_stream_index_map_.find(track_id);
    +
    366  if (stream_index_iter == track_id_to_stream_index_map_.end()) {
    +
    367  LOG(ERROR) << "Track " << track_id << " not found.";
    +
    368  return false;
    +
    369  }
    +
    370  if (stream_index_iter->second == kInvalidStreamIndex)
    +
    371  return true;
    +
    372  Status status = DispatchTextSample(stream_index_iter->second, sample);
    +
    373  if (!status.ok()) {
    +
    374  LOG(ERROR) << "Failed to process sample " << stream_index_iter->second
    +
    375  << " " << status;
    +
    376  return false;
    +
    377  }
    +
    378  return true;
    +
    379 }
    +
    380 
    +
    381 Status Demuxer::Parse() {
    +
    382  DCHECK(media_file_);
    +
    383  DCHECK(parser_);
    +
    384  DCHECK(buffer_);
    +
    385 
    +
    386  int64_t bytes_read = media_file_->Read(buffer_.get(), kBufSize);
    +
    387  if (bytes_read == 0) {
    +
    388  if (!parser_->Flush())
    +
    389  return Status(error::PARSER_FAILURE, "Failed to flush.");
    +
    390  return Status(error::END_OF_STREAM, "");
    +
    391  } else if (bytes_read < 0) {
    +
    392  return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
    +
    393  }
    +
    394 
    +
    395  return parser_->Parse(buffer_.get(), bytes_read)
    +
    396  ? Status::OK
    +
    397  : Status(error::PARSER_FAILURE,
    +
    398  "Cannot parse media file " + file_name_);
    +
    399 }
    +
    400 
    +
    401 } // namespace media
    +
    402 } // namespace shaka
    +
    virtual bool Open()=0
    Internal open. Should not be used directly.
    +
    virtual int64_t Read(void *buffer, uint64_t length)=0
    +
    static bool IsLocalRegularFile(const char *file_name)
    Definition: file.cc:374
    +
    virtual bool Close()=0
    + +
    void Update(Status new_status)
    Definition: status.cc:78
    +
    Status Run() override
    Definition: demuxer.cc:88
    +
    Status SetHandler(const std::string &stream_label, std::shared_ptr< MediaHandler > handler)
    Definition: demuxer.cc:133
    +
    void Cancel() override
    Definition: demuxer.cc:129
    +
    void SetLanguageOverride(const std::string &stream_label, const std::string &language_override)
    Definition: demuxer.cc:143
    +
    void SetKeySource(std::unique_ptr< KeySource > key_source)
    Definition: demuxer.cc:84
    +
    Demuxer(const std::string &file_name)
    Definition: demuxer.cc:76
    +
    Status SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
    Connect downstream handler at the specified output stream index.
    +
    Status DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
    Dispatch the media sample to downstream handlers.
    +
    Status DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
    Dispatch the text sample to downstream handlers.
    +
    Status DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
    Dispatch the stream info to downstream handlers.
    +
    Status FlushDownstream(size_t output_stream_index)
    Flush the downstream connected at the specified output stream index.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/dbe/structshaka_1_1media_1_1mp4_1_1EditList.html b/docs/d3/dbe/structshaka_1_1media_1_1mp4_1_1EditList.html index 6fe2a009e9..8f94aba71b 100644 --- a/docs/d3/dbe/structshaka_1_1media_1_1mp4_1_1EditList.html +++ b/docs/d3/dbe/structshaka_1_1media_1_1mp4_1_1EditList.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::EditList Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 215 of file box_definitions.h.

    +

    Definition at line 216 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1206 of file box_definitions.cc.

    +

    Definition at line 1224 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/d3/dc0/structshaka_1_1DecryptionParams-members.html b/docs/d3/dc0/structshaka_1_1DecryptionParams-members.html index a349bec98c..8a74217ace 100644 --- a/docs/d3/dc0/structshaka_1_1DecryptionParams-members.html +++ b/docs/d3/dc0/structshaka_1_1DecryptionParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d3/dc1/classshaka_1_1media_1_1mp2t_1_1Mp2tMediaParser.html b/docs/d3/dc1/classshaka_1_1media_1_1mp2t_1_1Mp2tMediaParser.html index 5ce7ce9aee..da8702f5c9 100644 --- a/docs/d3/dc1/classshaka_1_1media_1_1mp2t_1_1Mp2tMediaParser.html +++ b/docs/d3/dc1/classshaka_1_1media_1_1mp2t_1_1Mp2tMediaParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::Mp2tMediaParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MediaParser - -
    + + - - + + @@ -93,8 +96,10 @@ Additional Inherited Members - - + + + +

    Public Member Functions

    MediaParser implementation overrides.
    void Init (const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
     
    void Init (const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
     
    bool Flush () override WARN_UNUSED_RESULT
     
    bool Parse (const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    - Public Types inherited from shaka::media::MediaParser
    typedef base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
     
    typedef base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
     
    typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
     
    typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
     

    Detailed Description

    @@ -126,12 +131,12 @@ Additional Inherited Members

    Implements shaka::media::MediaParser.

    -

    Definition at line 165 of file mp2t_media_parser.cc.

    +

    Definition at line 173 of file mp2t_media_parser.cc.

    - -

    ◆ Init()

    + +

    ◆ Init()

    @@ -148,8 +153,14 @@ Additional Inherited Members - const NewSampleCB &  - new_sample_cb, + const NewMediaSampleCB &  + new_media_sample_cb, + + + + + const NewTextSampleCB &  + new_text_sample_cb, @@ -172,14 +183,16 @@ Additional Inherited Members

    Initialize the parser with necessary callbacks. Must be called before any data is passed to Parse().

    Parameters
    - + + +
    init_cbwill be called once enough data has been parsed to determine the initial stream configurations.
    new_sample_cbwill be called each time a new media sample is available from the parser. May be NULL, and caller retains ownership.
    new_media_sample_cbwill be called each time a new media sample is available from the parser.
    new_text_sample_cbwill be called each time a new text sample is available from the parser.
    decryption_key_sourcethe key source to decrypt the frames. May be NULL, and caller retains ownership.
    -

    Implements shaka::media::MediaParser.

    +

    Implements shaka::media::MediaParser.

    -

    Definition at line 152 of file mp2t_media_parser.cc.

    +

    Definition at line 158 of file mp2t_media_parser.cc.

    @@ -220,7 +233,7 @@ Additional Inherited Members

    Implements shaka::media::MediaParser.

    -

    Definition at line 183 of file mp2t_media_parser.cc.

    +

    Definition at line 191 of file mp2t_media_parser.cc.

    @@ -231,9 +244,7 @@ Additional Inherited Members diff --git a/docs/d3/dd0/classshaka_1_1MpdNotifier.html b/docs/d3/dd0/classshaka_1_1MpdNotifier.html index 431c06f97a..1d8d2876db 100644 --- a/docs/d3/dd0/classshaka_1_1MpdNotifier.html +++ b/docs/d3/dd0/classshaka_1_1MpdNotifier.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MpdNotifier Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::MockMpdNotifier shaka::SimpleMpdNotifier - -
    + + @@ -103,13 +106,15 @@ Public Member Functions + +

    Public Member Functions

     
    virtual bool Flush ()=0
     
    bool include_mspr_pro () const
     
    DashProfile dash_profile () const
     
    MpdType mpd_type () const
     

    Detailed Description

    -

    Interface for publish/subscribe publisher class which notifies MpdBuilder of media-related events.

    +

    Interface for publish/subscribe publisher class which notifies MpdBuilder of media-related events.

    Definition at line 27 of file mpd_notifier.h.

    Member Function Documentation

    @@ -137,7 +142,7 @@ Public Member Functions
    Returns
    The dash profile for this object.
    -

    Definition at line 108 of file mpd_notifier.h.

    +

    Definition at line 111 of file mpd_notifier.h.

    @@ -167,6 +172,34 @@ Public Member Functions

    Implemented in shaka::SimpleMpdNotifier.

    + + + +

    ◆ include_mspr_pro()

    + +
    +
    + + + + + +
    + + + + + + + +
    bool shaka::MpdNotifier::include_mspr_pro () const
    +
    +inline
    +
    +
    Returns
    include_mspr_pro option flag
    + +

    Definition at line 108 of file mpd_notifier.h.

    +
    @@ -221,7 +254,7 @@ Public Member Functions
    Returns
    The mpd type for this object.
    -

    Definition at line 111 of file mpd_notifier.h.

    +

    Definition at line 114 of file mpd_notifier.h.

    @@ -258,7 +291,7 @@ Public Member Functions
    -

    Notifies MpdBuilder that there is a new CueEvent.

    Parameters
    +

    Notifies MpdBuilder that there is a new CueEvent.

    Parameters
    @@ -316,7 +349,7 @@ Public Member Functions
    container_idContainer ID obtained from calling NotifyNewContainer().
    timestampis the timestamp of the CueEvent.
    -

    Notifiers MpdBuilder that there is a new PSSH for the container. This may be called whenever the key has to change, e.g. key rotation.

    Parameters
    +

    Notifiers MpdBuilder that there is a new PSSH for the container. This may be called whenever the key has to change, e.g. key rotation.

    Parameters
    @@ -409,9 +442,9 @@ Public Member Functions
    container_idContainer ID obtained from calling NotifyNewContainer().
    drm_uuidis the UUID of the DRM for encryption.
    -

    Notifies the MpdBuilder that there is a new container along with media_info. Live may have multiple files (segments) but those should be notified via NotifyNewSegment().

    Parameters
    +

    Notifies the MpdBuilder that there is a new container along with media_info. Live may have multiple files (segments) but those should be notified via NotifyNewSegment().

    Parameters
    - +
    media_infois the MediaInfo that will be passed to MpdBuilder.
    media_infois the MediaInfo that will be passed to MpdBuilder.
    [out]container_idis the numeric ID of the container, possibly for NotifyNewSegment() and AddContentProtectionElement(). Only populated on success.
    @@ -467,7 +500,7 @@ Public Member Functions
    -

    Notifies MpdBuilder that there is a new segment ready. For live, this is usually a new segment, for VOD this is usually a subsegment.

    Parameters
    +

    Notifies MpdBuilder that there is a new segment ready. For live, this is usually a new segment, for VOD this is usually a subsegment.

    Parameters
    @@ -534,9 +567,7 @@ Public Member Functions diff --git a/docs/d3/dd0/structshaka_1_1media_1_1mp4_1_1SegmentType.html b/docs/d3/dd0/structshaka_1_1media_1_1mp4_1_1SegmentType.html index 730b1512c4..a68733318f 100644 --- a/docs/d3/dd0/structshaka_1_1media_1_1mp4_1_1SegmentType.html +++ b/docs/d3/dd0/structshaka_1_1media_1_1mp4_1_1SegmentType.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::mp4::SegmentType Struct Reference @@ -29,18 +29,21 @@
    container_idContainer ID obtained from calling NotifyNewContainer().
    start_timeis the start time of the new segment, in units of the stream's time scale.
    - + +/* @license-end */
    shaka::media::mp4::FileType shaka::media::mp4::Box - -
    + + @@ -116,7 +119,7 @@ std::vector< FourCC > 

    Public Member Functions

    <

    Detailed Description

    -

    Definition at line 54 of file box_definitions.h.

    +

    Definition at line 55 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -144,7 +147,7 @@ std::vector< FourCC > <

    Reimplemented from shaka::media::mp4::FileType.

    -

    Definition at line 157 of file box_definitions.cc.

    +

    Definition at line 169 of file box_definitions.cc.

    @@ -155,9 +158,7 @@ std::vector< FourCC > < diff --git a/docs/d3/dd7/id3__tag_8h_source.html b/docs/d3/dd7/id3__tag_8h_source.html index bf412462ce..08f24d7df6 100644 --- a/docs/d3/dd7/id3__tag_8h_source.html +++ b/docs/d3/dd7/id3__tag_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/id3_tag.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    id3_tag.h
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_ID3_TAG_H_
    8 #define PACKAGER_MEDIA_BASE_ID3_TAG_H_
    9 
    10 #include <string>
    11 #include <vector>
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 class BufferWriter;
    17 
    20 class Id3Tag {
    21  public:
    22  Id3Tag() = default;
    23  virtual ~Id3Tag() = default;
    24 
    29  // This function is made virtual for testing.
    30  virtual void AddPrivateFrame(const std::string& owner,
    31  const std::string& data);
    32 
    36  // This function is made virtual for testing.
    37  virtual bool WriteToBuffer(BufferWriter* buffer_writer);
    38 
    42  // This function is made virtual for testing.
    43  virtual bool WriteToVector(std::vector<uint8_t>* output);
    44 
    45  private:
    46  Id3Tag(const Id3Tag&) = delete;
    47  Id3Tag& operator=(const Id3Tag&) = delete;
    48 
    49  struct PrivateFrame {
    50  std::string owner;
    51  std::string data;
    52  };
    53 
    54  bool WritePrivateFrame(const PrivateFrame& private_frame,
    55  BufferWriter* buffer_writer);
    56 
    57  std::vector<PrivateFrame> private_frames_;
    58 };
    59 
    60 } // namespace media
    61 } // namespace shaka
    62 
    63 #endif // PACKAGER_MEDIA_BASE_ID3_TAG_H_
    -
    virtual bool WriteToVector(std::vector< uint8_t > *output)
    Definition: id3_tag.cc:67
    -
    virtual void AddPrivateFrame(const std::string &owner, const std::string &data)
    Definition: id3_tag.cc:49
    -
    All the methods that are virtual are virtual for mocking.
    - -
    virtual bool WriteToBuffer(BufferWriter *buffer_writer)
    Definition: id3_tag.cc:54
    +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_ID3_TAG_H_
    +
    8 #define PACKAGER_MEDIA_BASE_ID3_TAG_H_
    +
    9 
    +
    10 #include <string>
    +
    11 #include <vector>
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 class BufferWriter;
    +
    17 
    +
    20 class Id3Tag {
    +
    21  public:
    +
    22  Id3Tag() = default;
    +
    23  virtual ~Id3Tag() = default;
    +
    24 
    +
    29  // This function is made virtual for testing.
    +
    30  virtual void AddPrivateFrame(const std::string& owner,
    +
    31  const std::string& data);
    +
    32 
    +
    36  // This function is made virtual for testing.
    +
    37  virtual bool WriteToBuffer(BufferWriter* buffer_writer);
    +
    38 
    +
    42  // This function is made virtual for testing.
    +
    43  virtual bool WriteToVector(std::vector<uint8_t>* output);
    +
    44 
    +
    45  private:
    +
    46  Id3Tag(const Id3Tag&) = delete;
    +
    47  Id3Tag& operator=(const Id3Tag&) = delete;
    +
    48 
    +
    49  struct PrivateFrame {
    +
    50  std::string owner;
    +
    51  std::string data;
    +
    52  };
    +
    53 
    +
    54  bool WritePrivateFrame(const PrivateFrame& private_frame,
    +
    55  BufferWriter* buffer_writer);
    +
    56 
    +
    57  std::vector<PrivateFrame> private_frames_;
    +
    58 };
    +
    59 
    +
    60 } // namespace media
    +
    61 } // namespace shaka
    +
    62 
    +
    63 #endif // PACKAGER_MEDIA_BASE_ID3_TAG_H_
    + + +
    virtual bool WriteToBuffer(BufferWriter *buffer_writer)
    Definition: id3_tag.cc:54
    +
    virtual void AddPrivateFrame(const std::string &owner, const std::string &data)
    Definition: id3_tag.cc:49
    +
    virtual bool WriteToVector(std::vector< uint8_t > *output)
    Definition: id3_tag.cc:67
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/ddf/classshaka_1_1media_1_1PlayReadyPsshGenerator.html b/docs/d3/ddf/classshaka_1_1media_1_1PlayReadyPsshGenerator.html index de1116a8a1..7c91890bfa 100644 --- a/docs/d3/ddf/classshaka_1_1media_1_1PlayReadyPsshGenerator.html +++ b/docs/d3/ddf/classshaka_1_1media_1_1PlayReadyPsshGenerator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::PlayReadyPsshGenerator Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::PsshGenerator - -
    + + - - + + @@ -97,7 +100,7 @@ Public Member Functions

    Public Member Functions

    PlayReadyPsshGenerator (FourCC protection_scheme)
     
    PlayReadyPsshGenerator (const std::string &extra_header_data, FourCC protection_scheme)
     
    PsshGenerator implemetation overrides.
    bool SupportMultipleKeys () override
     

    Detailed Description

    -

    Definition at line 16 of file playready_pssh_generator.h.

    +

    Definition at line 18 of file playready_pssh_generator.h.

    Member Function Documentation

    ◆ SupportMultipleKeys()

    @@ -125,7 +128,7 @@ Public Member Functions

    Implements shaka::media::PsshGenerator.

    -

    Definition at line 161 of file playready_pssh_generator.cc.

    +

    Definition at line 170 of file playready_pssh_generator.cc.

    @@ -136,9 +139,7 @@ Public Member Functions diff --git a/docs/d3/de2/structshaka_1_1FileCloser.html b/docs/d3/de2/structshaka_1_1FileCloser.html index ff06c685e0..93e1122ff6 100644 --- a/docs/d3/de2/structshaka_1_1FileCloser.html +++ b/docs/d3/de2/structshaka_1_1FileCloser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::FileCloser Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    operator() ( diff --git a/docs/d3/de4/seek__head_8h_source.html b/docs/d3/de4/seek__head_8h_source.html index b9bb3b64d6..16bfc0efba 100644 --- a/docs/d3/de4/seek__head_8h_source.html +++ b/docs/d3/de4/seek__head_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/seek_head.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    seek_head.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SEEK_HEAD_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_SEEK_HEAD_H_
    9 
    10 #include <stdint.h>
    11 #include <vector>
    12 
    13 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    20 class SeekHead {
    21  public:
    22  SeekHead();
    23  ~SeekHead();
    24 
    27  bool Write(mkvmuxer::IMkvWriter* writer);
    29  bool WriteVoid(mkvmuxer::IMkvWriter* writer);
    30 
    31  void set_cluster_pos(uint64_t pos) { cluster_pos_ = pos; }
    32  void set_cues_pos(uint64_t pos) { cues_pos_ = pos; }
    33  void set_info_pos(uint64_t pos) { info_pos_ = pos; }
    34  void set_tracks_pos(uint64_t pos) { tracks_pos_ = pos; }
    35 
    36  private:
    37  SeekHead(const SeekHead&) = delete;
    38  SeekHead& operator=(const SeekHead&) = delete;
    39 
    40  struct SeekElement {
    41  mkvmuxer::uint64 id;
    42  mkvmuxer::uint64 position;
    43  mkvmuxer::uint64 size;
    44 
    45  SeekElement(uint64_t seek_id, uint64_t seek_position)
    46  : id(seek_id), position(seek_position), size(0) {}
    47  };
    48 
    49  // Create seek element vector from positions.
    50  std::vector<SeekElement> CreateSeekElements();
    51 
    52  // In practice, these positions, if set, will never be 0, so we use a zero
    53  // value to denote that they are not set.
    54  uint64_t cluster_pos_ = 0;
    55  uint64_t cues_pos_ = 0;
    56  uint64_t info_pos_ = 0;
    57  uint64_t tracks_pos_ = 0;
    58  bool wrote_void_ = false;
    59  const uint64_t total_void_size_ = 0;
    60 };
    61 
    62 } // namespace media
    63 } // namespace shaka
    64 
    65 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SEEK_HEAD_H_
    bool WriteVoid(mkvmuxer::IMkvWriter *writer)
    Writes a void element large enough to fit the SeekHead.
    Definition: seek_head.cc:80
    - -
    All the methods that are virtual are virtual for mocking.
    -
    bool Write(mkvmuxer::IMkvWriter *writer)
    Definition: seek_head.cc:47
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SEEK_HEAD_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_SEEK_HEAD_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <vector>
    +
    12 
    +
    13 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    20 class SeekHead {
    +
    21  public:
    +
    22  SeekHead();
    +
    23  ~SeekHead();
    +
    24 
    +
    27  bool Write(mkvmuxer::IMkvWriter* writer);
    +
    29  bool WriteVoid(mkvmuxer::IMkvWriter* writer);
    +
    30 
    +
    31  void set_cluster_pos(uint64_t pos) { cluster_pos_ = pos; }
    +
    32  void set_cues_pos(uint64_t pos) { cues_pos_ = pos; }
    +
    33  void set_info_pos(uint64_t pos) { info_pos_ = pos; }
    +
    34  void set_tracks_pos(uint64_t pos) { tracks_pos_ = pos; }
    +
    35 
    +
    36  private:
    +
    37  SeekHead(const SeekHead&) = delete;
    +
    38  SeekHead& operator=(const SeekHead&) = delete;
    +
    39 
    +
    40  struct SeekElement {
    +
    41  mkvmuxer::uint64 id;
    +
    42  mkvmuxer::uint64 position;
    +
    43  mkvmuxer::uint64 size;
    +
    44 
    +
    45  SeekElement(uint64_t seek_id, uint64_t seek_position)
    +
    46  : id(seek_id), position(seek_position), size(0) {}
    +
    47  };
    +
    48 
    +
    49  // Create seek element vector from positions.
    +
    50  std::vector<SeekElement> CreateSeekElements();
    +
    51 
    +
    52  // In practice, these positions, if set, will never be 0, so we use a zero
    +
    53  // value to denote that they are not set.
    +
    54  uint64_t cluster_pos_ = 0;
    +
    55  uint64_t cues_pos_ = 0;
    +
    56  uint64_t info_pos_ = 0;
    +
    57  uint64_t tracks_pos_ = 0;
    +
    58  bool wrote_void_ = false;
    +
    59  const uint64_t total_void_size_ = 0;
    +
    60 };
    +
    61 
    +
    62 } // namespace media
    +
    63 } // namespace shaka
    +
    64 
    +
    65 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SEEK_HEAD_H_
    + +
    bool WriteVoid(mkvmuxer::IMkvWriter *writer)
    Writes a void element large enough to fit the SeekHead.
    Definition: seek_head.cc:80
    +
    bool Write(mkvmuxer::IMkvWriter *writer)
    Definition: seek_head.cc:47
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d3/de6/job__manager_8h_source.html b/docs/d3/de6/job__manager_8h_source.html index c9ae06dcb0..50670c39cf 100644 --- a/docs/d3/de6/job__manager_8h_source.html +++ b/docs/d3/de6/job__manager_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/job_manager.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    job_manager.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_APP_JOB_MANAGER_H_
    8 #define PACKAGER_APP_JOB_MANAGER_H_
    9 
    10 #include <memory>
    11 #include <vector>
    12 
    13 #include "packager/base/threading/simple_thread.h"
    14 #include "packager/status.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 class OriginHandler;
    20 class SyncPointQueue;
    21 
    22 // A job is a single line of work that is expected to run in parallel with
    23 // other jobs.
    24 class Job : public base::SimpleThread {
    25  public:
    26  Job(const std::string& name, std::shared_ptr<OriginHandler> work);
    27 
    28  // Request that the job stops executing. This is only a request and
    29  // will not block. If you want to wait for the job to complete, use
    30  // |wait|.
    31  void Cancel();
    32 
    33  // Get the current status of the job. If the job failed to initialize
    34  // or encountered an error during execution this will return the error.
    35  const Status& status() const { return status_; }
    36 
    37  // If you want to wait for this job to complete, this will return the
    38  // WaitableEvent you can wait on.
    39  base::WaitableEvent* wait() { return &wait_; }
    40 
    41  private:
    42  Job(const Job&) = delete;
    43  Job& operator=(const Job&) = delete;
    44 
    45  void Run() override;
    46 
    47  std::shared_ptr<OriginHandler> work_;
    48  Status status_;
    49 
    50  base::WaitableEvent wait_;
    51 };
    52 
    53 // Similar to a thread pool, JobManager manages multiple jobs that are expected
    54 // to run in parallel. It can be used to register, run, and stop a batch of
    55 // jobs.
    56 class JobManager {
    57  public:
    58  // @param sync_points is an optional SyncPointQueue used to synchronize and
    59  // align cue points. JobManager cancels @a sync_points when any job
    60  // fails or is cancelled. It can be NULL.
    61  explicit JobManager(std::unique_ptr<SyncPointQueue> sync_points);
    62 
    63  // Create a new job entry by specifying the origin handler at the top of the
    64  // chain and a name for the thread. This will only register the job. To start
    65  // the job, you need to call |RunJobs|.
    66  void Add(const std::string& name, std::shared_ptr<OriginHandler> handler);
    67 
    68  // Initialize all registered jobs. If any job fails to initialize, this will
    69  // return the error and it will not be safe to call |RunJobs| as not all jobs
    70  // will be properly initialized.
    71  Status InitializeJobs();
    72 
    73  // Run all registered jobs. Before calling this make sure that
    74  // |InitializedJobs| returned |Status::OK|. This call is blocking and will
    75  // block until all jobs exit.
    76  Status RunJobs();
    77 
    78  // Ask all jobs to stop running. This call is non-blocking and can be used to
    79  // unblock a call to |RunJobs|.
    80  void CancelJobs();
    81 
    82  SyncPointQueue* sync_points() { return sync_points_.get(); }
    83 
    84  private:
    85  JobManager(const JobManager&) = delete;
    86  JobManager& operator=(const JobManager&) = delete;
    87 
    88  struct JobEntry {
    89  std::string name;
    90  std::shared_ptr<OriginHandler> worker;
    91  };
    92  // Stores Job entries for delayed construction of Job object.
    93  std::vector<JobEntry> job_entries_;
    94  std::vector<std::unique_ptr<Job>> jobs_;
    95  // Stored in JobManager so JobManager can cancel |sync_points| when any job
    96  // fails or is cancelled.
    97  std::unique_ptr<SyncPointQueue> sync_points_;
    98 };
    99 
    100 } // namespace media
    101 } // namespace shaka
    102 
    103 #endif // PACKAGER_APP_JOB_MANAGER_H_
    All the methods that are virtual are virtual for mocking.
    - - -
    A synchronized queue for cue points.
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_APP_JOB_MANAGER_H_
    +
    8 #define PACKAGER_APP_JOB_MANAGER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <vector>
    +
    12 
    +
    13 #include "packager/base/threading/simple_thread.h"
    +
    14 #include "packager/status.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 class OriginHandler;
    +
    20 class SyncPointQueue;
    +
    21 
    +
    22 // A job is a single line of work that is expected to run in parallel with
    +
    23 // other jobs.
    +
    24 class Job : public base::SimpleThread {
    +
    25  public:
    +
    26  Job(const std::string& name, std::shared_ptr<OriginHandler> work);
    +
    27 
    +
    28  // Request that the job stops executing. This is only a request and
    +
    29  // will not block. If you want to wait for the job to complete, use
    +
    30  // |wait|.
    +
    31  void Cancel();
    +
    32 
    +
    33  // Get the current status of the job. If the job failed to initialize
    +
    34  // or encountered an error during execution this will return the error.
    +
    35  const Status& status() const { return status_; }
    +
    36 
    +
    37  // If you want to wait for this job to complete, this will return the
    +
    38  // WaitableEvent you can wait on.
    +
    39  base::WaitableEvent* wait() { return &wait_; }
    +
    40 
    +
    41  private:
    +
    42  Job(const Job&) = delete;
    +
    43  Job& operator=(const Job&) = delete;
    +
    44 
    +
    45  void Run() override;
    +
    46 
    +
    47  std::shared_ptr<OriginHandler> work_;
    +
    48  Status status_;
    +
    49 
    +
    50  base::WaitableEvent wait_;
    +
    51 };
    +
    52 
    +
    53 // Similar to a thread pool, JobManager manages multiple jobs that are expected
    +
    54 // to run in parallel. It can be used to register, run, and stop a batch of
    +
    55 // jobs.
    +
    56 class JobManager {
    +
    57  public:
    +
    58  // @param sync_points is an optional SyncPointQueue used to synchronize and
    +
    59  // align cue points. JobManager cancels @a sync_points when any job
    +
    60  // fails or is cancelled. It can be NULL.
    +
    61  explicit JobManager(std::unique_ptr<SyncPointQueue> sync_points);
    +
    62 
    +
    63  virtual ~JobManager() = default;
    +
    64 
    +
    65  // Create a new job entry by specifying the origin handler at the top of the
    +
    66  // chain and a name for the thread. This will only register the job. To start
    +
    67  // the job, you need to call |RunJobs|.
    +
    68  void Add(const std::string& name, std::shared_ptr<OriginHandler> handler);
    +
    69 
    +
    70  // Initialize all registered jobs. If any job fails to initialize, this will
    +
    71  // return the error and it will not be safe to call |RunJobs| as not all jobs
    +
    72  // will be properly initialized.
    +
    73  virtual Status InitializeJobs();
    +
    74 
    +
    75  // Run all registered jobs. Before calling this make sure that
    +
    76  // |InitializedJobs| returned |Status::OK|. This call is blocking and will
    +
    77  // block until all jobs exit.
    +
    78  virtual Status RunJobs();
    +
    79 
    +
    80  // Ask all jobs to stop running. This call is non-blocking and can be used to
    +
    81  // unblock a call to |RunJobs|.
    +
    82  void CancelJobs();
    +
    83 
    +
    84  SyncPointQueue* sync_points() { return sync_points_.get(); }
    +
    85 
    +
    86  protected:
    +
    87  JobManager(const JobManager&) = delete;
    +
    88  JobManager& operator=(const JobManager&) = delete;
    +
    89 
    +
    90  struct JobEntry {
    +
    91  std::string name;
    +
    92  std::shared_ptr<OriginHandler> worker;
    +
    93  };
    +
    94  // Stores Job entries for delayed construction of Job object.
    +
    95  std::vector<JobEntry> job_entries_;
    +
    96  std::vector<std::unique_ptr<Job>> jobs_;
    +
    97  // Stored in JobManager so JobManager can cancel |sync_points| when any job
    +
    98  // fails or is cancelled.
    +
    99  std::unique_ptr<SyncPointQueue> sync_points_;
    +
    100 };
    +
    101 
    +
    102 } // namespace media
    +
    103 } // namespace shaka
    +
    104 
    +
    105 #endif // PACKAGER_APP_JOB_MANAGER_H_
    + + + +
    A synchronized queue for cue points.
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/d3/de9/classshaka_1_1media_1_1mp4_1_1BoxBuffer-members.html b/docs/d3/de9/classshaka_1_1media_1_1mp4_1_1BoxBuffer-members.html index d04be39840..3f39c4897f 100644 --- a/docs/d3/de9/classshaka_1_1media_1_1mp4_1_1BoxBuffer-members.html +++ b/docs/d3/de9/classshaka_1_1media_1_1mp4_1_1BoxBuffer-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    reader()shaka::media::mp4::BoxBufferinline Reading() constshaka::media::mp4::BoxBufferinline ReadWriteChild(Box *box)shaka::media::mp4::BoxBufferinline - ReadWriteFourCC(FourCC *fourcc) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteInt16(int16_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteInt32(int32_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteInt64(int64_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteInt64NBytes(int64_t *v, size_t num_bytes) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteString(std::string *str, size_t size)shaka::media::mp4::BoxBufferinline - ReadWriteUInt16(uint16_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteUInt32(uint32_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteUInt64(uint64_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteUInt64NBytes(uint64_t *v, size_t num_bytes)shaka::media::mp4::BoxBufferinline - ReadWriteUInt8(uint8_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - ReadWriteVector(std::vector< uint8_t > *vector, size_t count) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline - Size() constshaka::media::mp4::BoxBufferinline - TryReadWriteChild(Box *box)shaka::media::mp4::BoxBufferinline - writer()shaka::media::mp4::BoxBufferinline - ~BoxBuffer() (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteCString(std::string *str) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteFourCC(FourCC *fourcc) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteInt16(int16_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteInt32(int32_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteInt64(int64_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteInt64NBytes(int64_t *v, size_t num_bytes) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteString(std::string *str, size_t size)shaka::media::mp4::BoxBufferinline + ReadWriteUInt16(uint16_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteUInt32(uint32_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteUInt64(uint64_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteUInt64NBytes(uint64_t *v, size_t num_bytes)shaka::media::mp4::BoxBufferinline + ReadWriteUInt8(uint8_t *v) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + ReadWriteVector(std::vector< uint8_t > *vector, size_t count) (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline + Size() constshaka::media::mp4::BoxBufferinline + TryReadWriteChild(Box *box)shaka::media::mp4::BoxBufferinline + writer()shaka::media::mp4::BoxBufferinline + ~BoxBuffer() (defined in shaka::media::mp4::BoxBuffer)shaka::media::mp4::BoxBufferinline
    diff --git a/docs/d3/de9/structshaka_1_1media_1_1mp4_1_1SampleGroupDescription-members.html b/docs/d3/de9/structshaka_1_1media_1_1mp4_1_1SampleGroupDescription-members.html index ac9f16fb50..015162d4e4 100644 --- a/docs/d3/de9/structshaka_1_1media_1_1mp4_1_1SampleGroupDescription-members.html +++ b/docs/d3/de9/structshaka_1_1media_1_1mp4_1_1SampleGroupDescription-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d3/deb/packed__audio__writer_8cc_source.html b/docs/d3/deb/packed__audio__writer_8cc_source.html index 58c120952d..a553b73250 100644 --- a/docs/d3/deb/packed__audio__writer_8cc_source.html +++ b/docs/d3/deb/packed__audio__writer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/packed_audio/packed_audio_writer.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    packed_audio_writer.cc
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/packed_audio/packed_audio_writer.h"
    8 
    9 #include "packager/media/base/muxer_util.h"
    10 #include "packager/media/formats/packed_audio/packed_audio_segmenter.h"
    11 #include "packager/status_macros.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    17  : Muxer(muxer_options),
    18  transport_stream_timestamp_offset_(
    19  muxer_options.transport_stream_timestamp_offset_ms *
    20  kPackedAudioTimescale / 1000),
    21  segmenter_(new PackedAudioSegmenter(transport_stream_timestamp_offset_)) {
    22 }
    23 
    24 PackedAudioWriter::~PackedAudioWriter() = default;
    25 
    26 Status PackedAudioWriter::InitializeMuxer() {
    27  if (streams().size() > 1u)
    28  return Status(error::MUXER_FAILURE, "Cannot handle more than one streams.");
    29 
    30  RETURN_IF_ERROR(segmenter_->Initialize(*streams()[0]));
    31 
    32  if (options().segment_template.empty()) {
    33  const std::string& file_name = options().output_file_name;
    34  DCHECK(!file_name.empty());
    35  output_file_.reset(File::Open(file_name.c_str(), "w"));
    36  if (!output_file_) {
    37  return Status(error::FILE_FAILURE,
    38  "Cannot open file for write " + file_name);
    39  }
    40  }
    41 
    42  if (muxer_listener()) {
    43  muxer_listener()->OnMediaStart(options(), *streams().front(),
    44  kPackedAudioTimescale,
    45  MuxerListener::kContainerPackedAudio);
    46  }
    47  return Status::OK;
    48 }
    49 
    50 Status PackedAudioWriter::Finalize() {
    51  if (output_file_)
    52  RETURN_IF_ERROR(CloseFile(std::move(output_file_)));
    53 
    54  if (muxer_listener()) {
    55  muxer_listener()->OnMediaEnd(
    56  media_ranges_, total_duration_ * segmenter_->TimescaleScale());
    57  }
    58  return Status::OK;
    59 }
    60 
    61 Status PackedAudioWriter::AddSample(size_t stream_id,
    62  const MediaSample& sample) {
    63  DCHECK_EQ(stream_id, 0u);
    64  return segmenter_->AddSample(sample);
    65 }
    66 
    67 Status PackedAudioWriter::FinalizeSegment(size_t stream_id,
    68  const SegmentInfo& segment_info) {
    69  DCHECK_EQ(stream_id, 0u);
    70  // PackedAudio does not support subsegment.
    71  if (segment_info.is_subsegment)
    72  return Status::OK;
    73 
    74  RETURN_IF_ERROR(segmenter_->FinalizeSegment());
    75 
    76  const uint64_t segment_timestamp =
    77  segment_info.start_timestamp * segmenter_->TimescaleScale();
    78  std::string segment_path =
    79  options().segment_template.empty()
    80  ? options().output_file_name
    81  : GetSegmentName(options().segment_template, segment_timestamp,
    82  segment_number_++, options().bandwidth);
    83 
    84  // Save |segment_size| as it will be cleared after writing.
    85  const size_t segment_size = segmenter_->segment_buffer()->Size();
    86 
    87  RETURN_IF_ERROR(WriteSegment(segment_path, segmenter_->segment_buffer()));
    88  total_duration_ += segment_info.duration;
    89 
    90  if (muxer_listener()) {
    91  muxer_listener()->OnNewSegment(
    92  segment_path, segment_timestamp + transport_stream_timestamp_offset_,
    93  segment_info.duration * segmenter_->TimescaleScale(), segment_size);
    94  }
    95  return Status::OK;
    96 }
    97 
    98 Status PackedAudioWriter::WriteSegment(const std::string& segment_path,
    99  BufferWriter* segment_buffer) {
    100  std::unique_ptr<File, FileCloser> file;
    101  if (output_file_) {
    102  // This is in single segment mode.
    103  Range range;
    104  range.start = media_ranges_.subsegment_ranges.empty()
    105  ? 0
    106  : (media_ranges_.subsegment_ranges.back().end + 1);
    107  range.end = range.start + segment_buffer->Size() - 1;
    108  media_ranges_.subsegment_ranges.push_back(range);
    109  } else {
    110  file.reset(File::Open(segment_path.c_str(), "w"));
    111  if (!file) {
    112  return Status(error::FILE_FAILURE,
    113  "Cannot open file for write " + segment_path);
    114  }
    115  }
    116 
    117  RETURN_IF_ERROR(segment_buffer->WriteToFile(output_file_ ? output_file_.get()
    118  : file.get()));
    119 
    120  if (file)
    121  RETURN_IF_ERROR(CloseFile(std::move(file)));
    122  return Status::OK;
    123 }
    124 
    125 Status PackedAudioWriter::CloseFile(std::unique_ptr<File, FileCloser> file) {
    126  std::string file_name = file->file_name();
    127  if (!file.release()->Close()) {
    128  return Status(
    129  error::FILE_FAILURE,
    130  "Cannot close file " + file_name +
    131  ", possibly file permission issue or running out of disk space.");
    132  }
    133  return Status::OK;
    134 }
    135 
    136 } // namespace media
    137 } // namespace shaka
    - - -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - - -
    PackedAudioWriter(const MuxerOptions &muxer_options)
    Create a MP4Muxer object from MuxerOptions.
    -
    virtual void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds)=0
    -
    virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - -
    virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
    -
    virtual bool Open()=0
    Internal open. Should not be used directly.
    - - -
    Status WriteToFile(File *file)
    - +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/packed_audio/packed_audio_writer.h"
    +
    8 
    +
    9 #include "packager/media/base/muxer_util.h"
    +
    10 #include "packager/media/formats/packed_audio/packed_audio_segmenter.h"
    +
    11 #include "packager/status_macros.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    + +
    17  : Muxer(muxer_options),
    +
    18  transport_stream_timestamp_offset_(
    +
    19  muxer_options.transport_stream_timestamp_offset_ms *
    +
    20  kPackedAudioTimescale / 1000),
    +
    21  segmenter_(new PackedAudioSegmenter(transport_stream_timestamp_offset_)) {
    +
    22 }
    +
    23 
    +
    24 PackedAudioWriter::~PackedAudioWriter() = default;
    +
    25 
    +
    26 Status PackedAudioWriter::InitializeMuxer() {
    +
    27  if (streams().size() > 1u)
    +
    28  return Status(error::MUXER_FAILURE, "Cannot handle more than one streams.");
    +
    29 
    +
    30  RETURN_IF_ERROR(segmenter_->Initialize(*streams()[0]));
    +
    31 
    +
    32  if (options().segment_template.empty()) {
    +
    33  const std::string& file_name = options().output_file_name;
    +
    34  DCHECK(!file_name.empty());
    +
    35  output_file_.reset(File::Open(file_name.c_str(), "w"));
    +
    36  if (!output_file_) {
    +
    37  return Status(error::FILE_FAILURE,
    +
    38  "Cannot open file for write " + file_name);
    +
    39  }
    +
    40  }
    +
    41 
    +
    42  if (muxer_listener()) {
    +
    43  muxer_listener()->OnMediaStart(options(), *streams().front(),
    +
    44  kPackedAudioTimescale,
    +
    45  MuxerListener::kContainerPackedAudio);
    +
    46  }
    +
    47  return Status::OK;
    +
    48 }
    +
    49 
    +
    50 Status PackedAudioWriter::Finalize() {
    +
    51  if (output_file_)
    +
    52  RETURN_IF_ERROR(CloseFile(std::move(output_file_)));
    +
    53 
    +
    54  if (muxer_listener()) {
    +
    55  muxer_listener()->OnMediaEnd(
    +
    56  media_ranges_, total_duration_ * segmenter_->TimescaleScale());
    +
    57  }
    +
    58  return Status::OK;
    +
    59 }
    +
    60 
    +
    61 Status PackedAudioWriter::AddMediaSample(size_t stream_id,
    +
    62  const MediaSample& sample) {
    +
    63  DCHECK_EQ(stream_id, 0u);
    +
    64  return segmenter_->AddSample(sample);
    +
    65 }
    +
    66 
    +
    67 Status PackedAudioWriter::FinalizeSegment(size_t stream_id,
    +
    68  const SegmentInfo& segment_info) {
    +
    69  DCHECK_EQ(stream_id, 0u);
    +
    70  // PackedAudio does not support subsegment.
    +
    71  if (segment_info.is_subsegment)
    +
    72  return Status::OK;
    +
    73 
    +
    74  RETURN_IF_ERROR(segmenter_->FinalizeSegment());
    +
    75 
    +
    76  const uint64_t segment_timestamp =
    +
    77  segment_info.start_timestamp * segmenter_->TimescaleScale();
    +
    78  std::string segment_path =
    +
    79  options().segment_template.empty()
    +
    80  ? options().output_file_name
    +
    81  : GetSegmentName(options().segment_template, segment_timestamp,
    +
    82  segment_number_++, options().bandwidth);
    +
    83 
    +
    84  // Save |segment_size| as it will be cleared after writing.
    +
    85  const size_t segment_size = segmenter_->segment_buffer()->Size();
    +
    86 
    +
    87  RETURN_IF_ERROR(WriteSegment(segment_path, segmenter_->segment_buffer()));
    +
    88  total_duration_ += segment_info.duration;
    +
    89 
    +
    90  if (muxer_listener()) {
    +
    91  muxer_listener()->OnNewSegment(
    +
    92  segment_path, segment_timestamp + transport_stream_timestamp_offset_,
    +
    93  segment_info.duration * segmenter_->TimescaleScale(), segment_size);
    +
    94  }
    +
    95  return Status::OK;
    +
    96 }
    +
    97 
    +
    98 Status PackedAudioWriter::WriteSegment(const std::string& segment_path,
    +
    99  BufferWriter* segment_buffer) {
    +
    100  std::unique_ptr<File, FileCloser> file;
    +
    101  if (output_file_) {
    +
    102  // This is in single segment mode.
    +
    103  Range range;
    +
    104  range.start = media_ranges_.subsegment_ranges.empty()
    +
    105  ? 0
    +
    106  : (media_ranges_.subsegment_ranges.back().end + 1);
    +
    107  range.end = range.start + segment_buffer->Size() - 1;
    +
    108  media_ranges_.subsegment_ranges.push_back(range);
    +
    109  } else {
    +
    110  file.reset(File::Open(segment_path.c_str(), "w"));
    +
    111  if (!file) {
    +
    112  return Status(error::FILE_FAILURE,
    +
    113  "Cannot open file for write " + segment_path);
    +
    114  }
    +
    115  }
    +
    116 
    +
    117  RETURN_IF_ERROR(segment_buffer->WriteToFile(output_file_ ? output_file_.get()
    +
    118  : file.get()));
    +
    119 
    +
    120  if (file)
    +
    121  RETURN_IF_ERROR(CloseFile(std::move(file)));
    +
    122  return Status::OK;
    +
    123 }
    +
    124 
    +
    125 Status PackedAudioWriter::CloseFile(std::unique_ptr<File, FileCloser> file) {
    +
    126  std::string file_name = file->file_name();
    +
    127  if (!file.release()->Close()) {
    +
    128  return Status(
    +
    129  error::FILE_FAILURE,
    +
    130  "Cannot close file " + file_name +
    +
    131  ", possibly file permission issue or running out of disk space.");
    +
    132  }
    +
    133  return Status::OK;
    +
    134 }
    +
    135 
    +
    136 } // namespace media
    +
    137 } // namespace shaka
    +
    virtual bool Open()=0
    Internal open. Should not be used directly.
    + +
    virtual void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds)=0
    +
    virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
    +
    virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
    + + +
    PackedAudioWriter(const MuxerOptions &muxer_options)
    Create a MP4Muxer object from MuxerOptions.
    +
    All the methods that are virtual are virtual for mocking.
    + +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    + +
    diff --git a/docs/d3/df1/box__reader_8cc_source.html b/docs/d3/df1/box__reader_8cc_source.html index 34faaf0e11..78bfcc523b 100644 --- a/docs/d3/df1/box__reader_8cc_source.html +++ b/docs/d3/df1/box__reader_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/box_reader.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    box_reader.cc
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/mp4/box_reader.h"
    6 
    7 #include <inttypes.h>
    8 
    9 #include <limits>
    10 #include <memory>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/stringprintf.h"
    14 #include "packager/media/formats/mp4/box.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 namespace mp4 {
    19 
    20 BoxReader::BoxReader(const uint8_t* buf, size_t size)
    21  : BufferReader(buf, size), type_(FOURCC_NULL), scanned_(false) {
    22  DCHECK(buf);
    23  DCHECK_LT(0u, size);
    24 }
    25 
    26 BoxReader::~BoxReader() {
    27  if (scanned_ && !children_.empty()) {
    28  for (ChildMap::iterator itr = children_.begin(); itr != children_.end();
    29  ++itr) {
    30  DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first);
    31  }
    32  }
    33 }
    34 
    35 // static
    36 BoxReader* BoxReader::ReadBox(const uint8_t* buf,
    37  const size_t buf_size,
    38  bool* err) {
    39  std::unique_ptr<BoxReader> reader(new BoxReader(buf, buf_size));
    40  if (!reader->ReadHeader(err))
    41  return NULL;
    42 
    43  // We don't require the complete box to be available for MDAT box.
    44  if (reader->type() == FOURCC_mdat)
    45  return reader.release();
    46 
    47  if (reader->size() <= buf_size)
    48  return reader.release();
    49 
    50  return NULL;
    51 }
    52 
    53 // static
    54 bool BoxReader::StartBox(const uint8_t* buf,
    55  const size_t buf_size,
    56  FourCC* type,
    57  uint64_t* box_size,
    58  bool* err) {
    59  BoxReader reader(buf, buf_size);
    60  if (!reader.ReadHeader(err))
    61  return false;
    62  *type = reader.type();
    63  *box_size = reader.size();
    64  return true;
    65 }
    66 
    68  DCHECK(!scanned_);
    69  scanned_ = true;
    70 
    71  while (pos() < size()) {
    72  std::unique_ptr<BoxReader> child(
    73  new BoxReader(&data()[pos()], size() - pos()));
    74  bool err;
    75  if (!child->ReadHeader(&err))
    76  return false;
    77 
    78  FourCC box_type = child->type();
    79  size_t box_size = child->size();
    80  children_.insert(std::pair<FourCC, std::unique_ptr<BoxReader>>(
    81  box_type, std::move(child)));
    82  VLOG(2) << "Child " << FourCCToString(box_type) << " size 0x" << std::hex
    83  << box_size << std::dec;
    84  RCHECK(SkipBytes(box_size));
    85  }
    86 
    87  return true;
    88 }
    89 
    90 bool BoxReader::ReadChild(Box* child) {
    91  DCHECK(scanned_);
    92  FourCC child_type = child->BoxType();
    93 
    94  ChildMap::iterator itr = children_.find(child_type);
    95  RCHECK(itr != children_.end());
    96  DVLOG(2) << "Found a " << FourCCToString(child_type) << " box.";
    97  RCHECK(child->Parse(itr->second.get()));
    98  children_.erase(itr);
    99  return true;
    100 }
    101 
    103  return children_.count(child->BoxType()) > 0;
    104 }
    105 
    107  if (!children_.count(child->BoxType()))
    108  return true;
    109  return ReadChild(child);
    110 }
    111 
    112 bool BoxReader::ReadHeader(bool* err) {
    113  uint64_t size = 0;
    114  *err = false;
    115 
    116  if (!ReadNBytesInto8(&size, sizeof(uint32_t)) || !ReadFourCC(&type_))
    117  return false;
    118 
    119  if (size == 0) {
    120  // Boxes that run to EOS are not supported.
    121  NOTIMPLEMENTED() << base::StringPrintf("Box '%s' run to EOS.",
    122  FourCCToString(type_).c_str());
    123  *err = true;
    124  return false;
    125  } else if (size == 1) {
    126  if (!Read8(&size))
    127  return false;
    128  }
    129 
    130  // The box should have at least the size of what have been parsed.
    131  if (size < pos()) {
    132  LOG(ERROR) << base::StringPrintf("Box '%s' with size (%" PRIu64
    133  ") is invalid.",
    134  FourCCToString(type_).c_str(),
    135  size);
    136  *err = true;
    137  return false;
    138  }
    139 
    140  // 'mdat' box could have a 64-bit size; other boxes should be very small.
    141  if (size > static_cast<uint64_t>(std::numeric_limits<int32_t>::max()) &&
    142  type_ != FOURCC_mdat) {
    143  LOG(ERROR) << base::StringPrintf("Box '%s' size (%" PRIu64
    144  ") is too large.",
    145  FourCCToString(type_).c_str(),
    146  size);
    147  *err = true;
    148  return false;
    149  }
    150 
    151  // Note that the pos_ head has advanced to the byte immediately after the
    152  // header, which is where we want it.
    153  set_size(size);
    154  return true;
    155 }
    156 
    157 } // namespace mp4
    158 } // namespace media
    159 } // namespace shaka
    virtual FourCC BoxType() const =0
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool ScanChildren() WARN_UNUSED_RESULT
    Definition: box_reader.cc:67
    -
    uint32_t box_size()
    Definition: box.h:55
    - -
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    -
    bool ReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:90
    -
    bool Parse(BoxReader *reader)
    Definition: box.cc:19
    -
    bool TryReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:106
    -
    static bool StartBox(const uint8_t *buf, const size_t buf_size, FourCC *type, uint64_t *box_size, bool *err) WARN_UNUSED_RESULT
    Definition: box_reader.cc:54
    -
    bool ChildExist(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:102
    -
    static BoxReader * ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)
    Definition: box_reader.cc:36
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/mp4/box_reader.h"
    +
    6 
    +
    7 #include <inttypes.h>
    +
    8 
    +
    9 #include <limits>
    +
    10 #include <memory>
    +
    11 
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/base/strings/stringprintf.h"
    +
    14 #include "packager/media/formats/mp4/box.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 namespace mp4 {
    +
    19 
    +
    20 BoxReader::BoxReader(const uint8_t* buf, size_t size)
    +
    21  : BufferReader(buf, size), type_(FOURCC_NULL), scanned_(false) {
    +
    22  DCHECK(buf);
    +
    23  DCHECK_LT(0u, size);
    +
    24 }
    +
    25 
    +
    26 BoxReader::~BoxReader() {
    +
    27  if (scanned_ && !children_.empty()) {
    +
    28  for (ChildMap::iterator itr = children_.begin(); itr != children_.end();
    +
    29  ++itr) {
    +
    30  DVLOG(1) << "Skipping unknown box: " << FourCCToString(itr->first);
    +
    31  }
    +
    32  }
    +
    33 }
    +
    34 
    +
    35 // static
    +
    36 BoxReader* BoxReader::ReadBox(const uint8_t* buf,
    +
    37  const size_t buf_size,
    +
    38  bool* err) {
    +
    39  std::unique_ptr<BoxReader> reader(new BoxReader(buf, buf_size));
    +
    40  if (!reader->ReadHeader(err))
    +
    41  return NULL;
    +
    42 
    +
    43  // We don't require the complete box to be available for MDAT box.
    +
    44  if (reader->type() == FOURCC_mdat)
    +
    45  return reader.release();
    +
    46 
    +
    47  if (reader->size() <= buf_size)
    +
    48  return reader.release();
    +
    49 
    +
    50  return NULL;
    +
    51 }
    +
    52 
    +
    53 // static
    +
    54 bool BoxReader::StartBox(const uint8_t* buf,
    +
    55  const size_t buf_size,
    +
    56  FourCC* type,
    +
    57  uint64_t* box_size,
    +
    58  bool* err) {
    +
    59  BoxReader reader(buf, buf_size);
    +
    60  if (!reader.ReadHeader(err))
    +
    61  return false;
    +
    62  *type = reader.type();
    +
    63  *box_size = reader.size();
    +
    64  return true;
    +
    65 }
    +
    66 
    +
    67 bool BoxReader::ScanChildren() {
    +
    68  DCHECK(!scanned_);
    +
    69  scanned_ = true;
    +
    70 
    +
    71  while (pos() < size()) {
    +
    72  std::unique_ptr<BoxReader> child(
    +
    73  new BoxReader(&data()[pos()], size() - pos()));
    +
    74  bool err;
    +
    75  if (!child->ReadHeader(&err))
    +
    76  return false;
    +
    77 
    +
    78  FourCC box_type = child->type();
    +
    79  size_t box_size = child->size();
    +
    80  children_.insert(std::pair<FourCC, std::unique_ptr<BoxReader>>(
    +
    81  box_type, std::move(child)));
    +
    82  VLOG(2) << "Child " << FourCCToString(box_type) << " size 0x" << std::hex
    +
    83  << box_size << std::dec;
    +
    84  RCHECK(SkipBytes(box_size));
    +
    85  }
    +
    86 
    +
    87  return true;
    +
    88 }
    +
    89 
    +
    90 bool BoxReader::ReadChild(Box* child) {
    +
    91  DCHECK(scanned_);
    +
    92  FourCC child_type = child->BoxType();
    +
    93 
    +
    94  ChildMap::iterator itr = children_.find(child_type);
    +
    95  RCHECK(itr != children_.end());
    +
    96  DVLOG(2) << "Found a " << FourCCToString(child_type) << " box.";
    +
    97  RCHECK(child->Parse(itr->second.get()));
    +
    98  children_.erase(itr);
    +
    99  return true;
    +
    100 }
    +
    101 
    +
    102 bool BoxReader::ChildExist(Box* child) {
    +
    103  return children_.count(child->BoxType()) > 0;
    +
    104 }
    +
    105 
    +
    106 bool BoxReader::TryReadChild(Box* child) {
    +
    107  if (!children_.count(child->BoxType()))
    +
    108  return true;
    +
    109  return ReadChild(child);
    +
    110 }
    +
    111 
    +
    112 bool BoxReader::ReadHeader(bool* err) {
    +
    113  uint64_t size = 0;
    +
    114  *err = false;
    +
    115 
    +
    116  if (!ReadNBytesInto8(&size, sizeof(uint32_t)) || !ReadFourCC(&type_))
    +
    117  return false;
    +
    118 
    +
    119  if (size == 0) {
    +
    120  // Boxes that run to EOS are not supported.
    +
    121  NOTIMPLEMENTED() << base::StringPrintf("Box '%s' run to EOS.",
    +
    122  FourCCToString(type_).c_str());
    +
    123  *err = true;
    +
    124  return false;
    +
    125  } else if (size == 1) {
    +
    126  if (!Read8(&size))
    +
    127  return false;
    +
    128  }
    +
    129 
    +
    130  // The box should have at least the size of what have been parsed.
    +
    131  if (size < pos()) {
    +
    132  LOG(ERROR) << base::StringPrintf("Box '%s' with size (%" PRIu64
    +
    133  ") is invalid.",
    +
    134  FourCCToString(type_).c_str(),
    +
    135  size);
    +
    136  *err = true;
    +
    137  return false;
    +
    138  }
    +
    139 
    +
    140  // 'mdat' box could have a 64-bit size; other boxes should be very small.
    +
    141  if (size > static_cast<uint64_t>(std::numeric_limits<int32_t>::max()) &&
    +
    142  type_ != FOURCC_mdat) {
    +
    143  LOG(ERROR) << base::StringPrintf("Box '%s' size (%" PRIu64
    +
    144  ") is too large.",
    +
    145  FourCCToString(type_).c_str(),
    +
    146  size);
    +
    147  *err = true;
    +
    148  return false;
    +
    149  }
    +
    150 
    +
    151  // Note that the pos_ head has advanced to the byte immediately after the
    +
    152  // header, which is where we want it.
    +
    153  set_size(size);
    +
    154  return true;
    +
    155 }
    +
    156 
    +
    157 } // namespace mp4
    +
    158 } // namespace media
    +
    159 } // namespace shaka
    +
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    +
    All the methods that are virtual are virtual for mocking.
    + +
    bool Parse(BoxReader *reader)
    Definition: box.cc:19
    +
    virtual FourCC BoxType() const =0
    diff --git a/docs/d3/df4/structshaka_1_1media_1_1CueEventInfo-members.html b/docs/d3/df4/structshaka_1_1media_1_1CueEventInfo-members.html index 0dd57a9043..b22f847fc4 100644 --- a/docs/d3/df4/structshaka_1_1media_1_1CueEventInfo-members.html +++ b/docs/d3/df4/structshaka_1_1media_1_1CueEventInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d3/dfb/classshaka_1_1media_1_1CueAlignmentHandler-members.html b/docs/d3/dfb/classshaka_1_1media_1_1CueAlignmentHandler-members.html index 469aa1ba58..e481f1de6e 100644 --- a/docs/d3/dfb/classshaka_1_1media_1_1CueAlignmentHandler-members.html +++ b/docs/d3/dfb/classshaka_1_1media_1_1CueAlignmentHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    This is the complete list of members for shaka::media::CueAlignmentHandler, including all inherited members.

    - + @@ -95,9 +98,7 @@ $(function() {
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
    Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    CueAlignmentHandler(SyncPointQueue *sync_points) (defined in shaka::media::CueAlignmentHandler)shaka::media::CueAlignmentHandlerexplicit
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    diff --git a/docs/d3/dfe/classshaka_1_1media_1_1AesPatternCryptor.html b/docs/d3/dfe/classshaka_1_1media_1_1AesPatternCryptor.html index e82dda0fda..4b1358ed3f 100644 --- a/docs/d3/dfe/classshaka_1_1media_1_1AesPatternCryptor.html +++ b/docs/d3/dfe/classshaka_1_1media_1_1AesPatternCryptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AesPatternCryptor Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::AesCryptor - -
    + + - -

    Public Types

    enum  PatternEncryptionMode { kEncryptIfCryptByteBlockRemaining, -kSkipIfCryptByteBlockRemaining +
    enum  PatternEncryptionMode { kEncryptIfCryptByteBlockRemaining +, kSkipIfCryptByteBlockRemaining }
     
    - Public Types inherited from shaka::media::AesCryptor
    enum  ConstantIvFlag { kUseConstantIv, -kDontUseConstantIv +
    enum  ConstantIvFlag { kUseConstantIv +, kDontUseConstantIv }
     
    @@ -276,9 +279,7 @@ AES_KEY * 
    mutable_aes_key< diff --git a/docs/d4/d00/mp4_2multi__segment__segmenter_8cc_source.html b/docs/d4/d00/mp4_2multi__segment__segmenter_8cc_source.html index 5d1b7f18bd..7665b7fc9d 100644 --- a/docs/d4/d00/mp4_2multi__segment__segmenter_8cc_source.html +++ b/docs/d4/d00/mp4_2multi__segment__segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/multi_segment_segmenter.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    multi_segment_segmenter.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp4/multi_segment_segmenter.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/base/strings/string_number_conversions.h"
    12 #include "packager/base/strings/string_util.h"
    13 #include "packager/file/file.h"
    14 #include "packager/file/file_closer.h"
    15 #include "packager/media/base/buffer_writer.h"
    16 #include "packager/media/base/muxer_options.h"
    17 #include "packager/media/base/muxer_util.h"
    18 #include "packager/media/event/muxer_listener.h"
    19 #include "packager/media/formats/mp4/box_definitions.h"
    20 #include "packager/media/formats/mp4/key_frame_info.h"
    21 #include "packager/status_macros.h"
    22 
    23 namespace shaka {
    24 namespace media {
    25 namespace mp4 {
    26 
    27 MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options,
    28  std::unique_ptr<FileType> ftyp,
    29  std::unique_ptr<Movie> moov)
    30  : Segmenter(options, std::move(ftyp), std::move(moov)),
    31  styp_(new SegmentType),
    32  num_segments_(0) {
    33  // Use the same brands for styp as ftyp.
    34  styp_->major_brand = Segmenter::ftyp()->major_brand;
    35  styp_->compatible_brands = Segmenter::ftyp()->compatible_brands;
    36  // Replace 'cmfc' with 'cmfs' for CMAF segments compatibility.
    37  std::replace(styp_->compatible_brands.begin(), styp_->compatible_brands.end(),
    38  FOURCC_cmfc, FOURCC_cmfs);
    39 }
    40 
    41 MultiSegmentSegmenter::~MultiSegmentSegmenter() {}
    42 
    43 bool MultiSegmentSegmenter::GetInitRange(size_t* offset, size_t* size) {
    44  VLOG(1) << "MultiSegmentSegmenter outputs init segment: "
    45  << options().output_file_name;
    46  return false;
    47 }
    48 
    49 bool MultiSegmentSegmenter::GetIndexRange(size_t* offset, size_t* size) {
    50  VLOG(1) << "MultiSegmentSegmenter does not have index range.";
    51  return false;
    52 }
    53 
    54 std::vector<Range> MultiSegmentSegmenter::GetSegmentRanges() {
    55  VLOG(1) << "MultiSegmentSegmenter does not have media segment ranges.";
    56  return std::vector<Range>();
    57 }
    58 
    59 Status MultiSegmentSegmenter::DoInitialize() {
    60  return WriteInitSegment();
    61 }
    62 
    63 Status MultiSegmentSegmenter::DoFinalize() {
    64  // Update init segment with media duration set.
    65  RETURN_IF_ERROR(WriteInitSegment());
    66  SetComplete();
    67  return Status::OK;
    68 }
    69 
    70 Status MultiSegmentSegmenter::DoFinalizeSegment() {
    71  return WriteSegment();
    72 }
    73 
    74 Status MultiSegmentSegmenter::WriteInitSegment() {
    75  DCHECK(ftyp());
    76  DCHECK(moov());
    77  // Generate the output file with init segment.
    78  std::unique_ptr<File, FileCloser> file(
    79  File::Open(options().output_file_name.c_str(), "w"));
    80  if (!file) {
    81  return Status(error::FILE_FAILURE,
    82  "Cannot open file for write " + options().output_file_name);
    83  }
    84  std::unique_ptr<BufferWriter> buffer(new BufferWriter);
    85  ftyp()->Write(buffer.get());
    86  moov()->Write(buffer.get());
    87  return buffer->WriteToFile(file.get());
    88 }
    89 
    90 Status MultiSegmentSegmenter::WriteSegment() {
    91  DCHECK(sidx());
    92  DCHECK(fragment_buffer());
    93  DCHECK(styp_);
    94 
    95  DCHECK(!sidx()->references.empty());
    96  // earliest_presentation_time is the earliest presentation time of any access
    97  // unit in the reference stream in the first subsegment.
    98  sidx()->earliest_presentation_time =
    99  sidx()->references[0].earliest_presentation_time;
    100 
    101  std::unique_ptr<BufferWriter> buffer(new BufferWriter());
    102  std::unique_ptr<File, FileCloser> file;
    103  std::string file_name;
    104  if (options().segment_template.empty()) {
    105  // Append the segment to output file if segment template is not specified.
    106  file_name = options().output_file_name.c_str();
    107  file.reset(File::Open(file_name.c_str(), "a"));
    108  if (!file) {
    109  return Status(error::FILE_FAILURE, "Cannot open file for append " +
    110  options().output_file_name);
    111  }
    112  } else {
    113  file_name = GetSegmentName(options().segment_template,
    114  sidx()->earliest_presentation_time,
    115  num_segments_++, options().bandwidth);
    116  file.reset(File::Open(file_name.c_str(), "w"));
    117  if (!file) {
    118  return Status(error::FILE_FAILURE,
    119  "Cannot open file for write " + file_name);
    120  }
    121  styp_->Write(buffer.get());
    122  }
    123 
    124  if (options().mp4_params.generate_sidx_in_media_segments)
    125  sidx()->Write(buffer.get());
    126 
    127  const size_t segment_header_size = buffer->Size();
    128  const size_t segment_size = segment_header_size + fragment_buffer()->Size();
    129  DCHECK_NE(segment_size, 0u);
    130 
    131  RETURN_IF_ERROR(buffer->WriteToFile(file.get()));
    132  if (muxer_listener()) {
    133  for (const KeyFrameInfo& key_frame_info : key_frame_infos()) {
    134  muxer_listener()->OnKeyFrame(
    135  key_frame_info.timestamp,
    136  segment_header_size + key_frame_info.start_byte_offset,
    137  key_frame_info.size);
    138  }
    139  }
    140  RETURN_IF_ERROR(fragment_buffer()->WriteToFile(file.get()));
    141 
    142  // Close the file, which also does flushing, to make sure the file is written
    143  // before manifest is updated.
    144  if (!file.release()->Close()) {
    145  return Status(
    146  error::FILE_FAILURE,
    147  "Cannot close file " + file_name +
    148  ", possibly file permission issue or running out of disk space.");
    149  }
    150 
    151  uint64_t segment_duration = 0;
    152  // ISO/IEC 23009-1:2012: the value shall be identical to sum of the the
    153  // values of all Subsegment_duration fields in the first ‘sidx’ box.
    154  for (size_t i = 0; i < sidx()->references.size(); ++i)
    155  segment_duration += sidx()->references[i].subsegment_duration;
    156 
    157  UpdateProgress(segment_duration);
    158  if (muxer_listener()) {
    159  muxer_listener()->OnSampleDurationReady(sample_duration());
    160  muxer_listener()->OnNewSegment(file_name,
    161  sidx()->earliest_presentation_time,
    162  segment_duration, segment_size);
    163  }
    164 
    165  return Status::OK;
    166 }
    167 
    168 } // namespace mp4
    169 } // namespace media
    170 } // namespace shaka
    virtual void OnSampleDurationReady(uint32_t sample_duration)=0
    -
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    bool GetInitRange(size_t *offset, size_t *size) override
    -
    bool GetIndexRange(size_t *offset, size_t *size) override
    -
    Tracks key frame information.
    -
    virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
    -
    virtual bool Open()=0
    Internal open. Should not be used directly.
    -
    virtual void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp4/multi_segment_segmenter.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/strings/string_number_conversions.h"
    +
    12 #include "packager/base/strings/string_util.h"
    +
    13 #include "packager/file/file.h"
    +
    14 #include "packager/file/file_closer.h"
    +
    15 #include "packager/media/base/buffer_writer.h"
    +
    16 #include "packager/media/base/muxer_options.h"
    +
    17 #include "packager/media/base/muxer_util.h"
    +
    18 #include "packager/media/event/muxer_listener.h"
    +
    19 #include "packager/media/formats/mp4/box_definitions.h"
    +
    20 #include "packager/media/formats/mp4/key_frame_info.h"
    +
    21 #include "packager/status_macros.h"
    +
    22 
    +
    23 namespace shaka {
    +
    24 namespace media {
    +
    25 namespace mp4 {
    +
    26 
    +
    27 MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options,
    +
    28  std::unique_ptr<FileType> ftyp,
    +
    29  std::unique_ptr<Movie> moov)
    +
    30  : Segmenter(options, std::move(ftyp), std::move(moov)),
    +
    31  styp_(new SegmentType),
    +
    32  num_segments_(0) {
    +
    33  // Use the same brands for styp as ftyp.
    +
    34  styp_->major_brand = Segmenter::ftyp()->major_brand;
    +
    35  styp_->compatible_brands = Segmenter::ftyp()->compatible_brands;
    +
    36  // Replace 'cmfc' with 'cmfs' for CMAF segments compatibility.
    +
    37  std::replace(styp_->compatible_brands.begin(), styp_->compatible_brands.end(),
    +
    38  FOURCC_cmfc, FOURCC_cmfs);
    +
    39 }
    +
    40 
    +
    41 MultiSegmentSegmenter::~MultiSegmentSegmenter() {}
    +
    42 
    +
    43 bool MultiSegmentSegmenter::GetInitRange(size_t* offset, size_t* size) {
    +
    44  VLOG(1) << "MultiSegmentSegmenter outputs init segment: "
    +
    45  << options().output_file_name;
    +
    46  return false;
    +
    47 }
    +
    48 
    +
    49 bool MultiSegmentSegmenter::GetIndexRange(size_t* offset, size_t* size) {
    +
    50  VLOG(1) << "MultiSegmentSegmenter does not have index range.";
    +
    51  return false;
    +
    52 }
    +
    53 
    +
    54 std::vector<Range> MultiSegmentSegmenter::GetSegmentRanges() {
    +
    55  VLOG(1) << "MultiSegmentSegmenter does not have media segment ranges.";
    +
    56  return std::vector<Range>();
    +
    57 }
    +
    58 
    +
    59 Status MultiSegmentSegmenter::DoInitialize() {
    +
    60  return WriteInitSegment();
    +
    61 }
    +
    62 
    +
    63 Status MultiSegmentSegmenter::DoFinalize() {
    +
    64  // Update init segment with media duration set.
    +
    65  RETURN_IF_ERROR(WriteInitSegment());
    +
    66  SetComplete();
    +
    67  return Status::OK;
    +
    68 }
    +
    69 
    +
    70 Status MultiSegmentSegmenter::DoFinalizeSegment() {
    +
    71  return WriteSegment();
    +
    72 }
    +
    73 
    +
    74 Status MultiSegmentSegmenter::WriteInitSegment() {
    +
    75  DCHECK(ftyp());
    +
    76  DCHECK(moov());
    +
    77  // Generate the output file with init segment.
    +
    78  std::unique_ptr<File, FileCloser> file(
    +
    79  File::Open(options().output_file_name.c_str(), "w"));
    +
    80  if (!file) {
    +
    81  return Status(error::FILE_FAILURE,
    +
    82  "Cannot open file for write " + options().output_file_name);
    +
    83  }
    +
    84  std::unique_ptr<BufferWriter> buffer(new BufferWriter);
    +
    85  ftyp()->Write(buffer.get());
    +
    86  moov()->Write(buffer.get());
    +
    87  return buffer->WriteToFile(file.get());
    +
    88 }
    +
    89 
    +
    90 Status MultiSegmentSegmenter::WriteSegment() {
    +
    91  DCHECK(sidx());
    +
    92  DCHECK(fragment_buffer());
    +
    93  DCHECK(styp_);
    +
    94 
    +
    95  DCHECK(!sidx()->references.empty());
    +
    96  // earliest_presentation_time is the earliest presentation time of any access
    +
    97  // unit in the reference stream in the first subsegment.
    +
    98  sidx()->earliest_presentation_time =
    +
    99  sidx()->references[0].earliest_presentation_time;
    +
    100 
    +
    101  std::unique_ptr<BufferWriter> buffer(new BufferWriter());
    +
    102  std::unique_ptr<File, FileCloser> file;
    +
    103  std::string file_name;
    +
    104  if (options().segment_template.empty()) {
    +
    105  // Append the segment to output file if segment template is not specified.
    +
    106  file_name = options().output_file_name.c_str();
    +
    107  file.reset(File::Open(file_name.c_str(), "a"));
    +
    108  if (!file) {
    +
    109  return Status(error::FILE_FAILURE, "Cannot open file for append " +
    +
    110  options().output_file_name);
    +
    111  }
    +
    112  } else {
    +
    113  file_name = GetSegmentName(options().segment_template,
    +
    114  sidx()->earliest_presentation_time,
    +
    115  num_segments_++, options().bandwidth);
    +
    116  file.reset(File::Open(file_name.c_str(), "w"));
    +
    117  if (!file) {
    +
    118  return Status(error::FILE_FAILURE,
    +
    119  "Cannot open file for write " + file_name);
    +
    120  }
    +
    121  styp_->Write(buffer.get());
    +
    122  }
    +
    123 
    +
    124  if (options().mp4_params.generate_sidx_in_media_segments)
    +
    125  sidx()->Write(buffer.get());
    +
    126 
    +
    127  const size_t segment_header_size = buffer->Size();
    +
    128  const size_t segment_size = segment_header_size + fragment_buffer()->Size();
    +
    129  DCHECK_NE(segment_size, 0u);
    +
    130 
    +
    131  RETURN_IF_ERROR(buffer->WriteToFile(file.get()));
    +
    132  if (muxer_listener()) {
    +
    133  for (const KeyFrameInfo& key_frame_info : key_frame_infos()) {
    +
    134  muxer_listener()->OnKeyFrame(
    +
    135  key_frame_info.timestamp,
    +
    136  segment_header_size + key_frame_info.start_byte_offset,
    +
    137  key_frame_info.size);
    +
    138  }
    +
    139  }
    +
    140  RETURN_IF_ERROR(fragment_buffer()->WriteToFile(file.get()));
    +
    141 
    +
    142  // Close the file, which also does flushing, to make sure the file is written
    +
    143  // before manifest is updated.
    +
    144  if (!file.release()->Close()) {
    +
    145  return Status(
    +
    146  error::FILE_FAILURE,
    +
    147  "Cannot close file " + file_name +
    +
    148  ", possibly file permission issue or running out of disk space.");
    +
    149  }
    +
    150 
    +
    151  uint64_t segment_duration = 0;
    +
    152  // ISO/IEC 23009-1:2012: the value shall be identical to sum of the the
    +
    153  // values of all Subsegment_duration fields in the first ‘sidx’ box.
    +
    154  for (size_t i = 0; i < sidx()->references.size(); ++i)
    +
    155  segment_duration += sidx()->references[i].subsegment_duration;
    +
    156 
    +
    157  UpdateProgress(segment_duration);
    +
    158  if (muxer_listener()) {
    +
    159  muxer_listener()->OnSampleDurationReady(sample_duration());
    +
    160  muxer_listener()->OnNewSegment(file_name,
    +
    161  sidx()->earliest_presentation_time,
    +
    162  segment_duration, segment_size);
    +
    163  }
    +
    164 
    +
    165  return Status::OK;
    +
    166 }
    +
    167 
    +
    168 } // namespace mp4
    +
    169 } // namespace media
    +
    170 } // namespace shaka
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/d07/classshaka_1_1media_1_1AesEncryptorFactory.html b/docs/d4/d07/classshaka_1_1media_1_1AesEncryptorFactory.html index bb8b0d0e7e..787b786587 100644 --- a/docs/d4/d07/classshaka_1_1media_1_1AesEncryptorFactory.html +++ b/docs/d4/d07/classshaka_1_1media_1_1AesEncryptorFactory.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AesEncryptorFactory Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d4/d08/classshaka_1_1media_1_1mp4_1_1MP4MediaParser-members.html b/docs/d4/d08/classshaka_1_1media_1_1mp4_1_1MP4MediaParser-members.html index 1cf57200a3..430e084be1 100644 --- a/docs/d4/d08/classshaka_1_1media_1_1mp4_1_1MP4MediaParser-members.html +++ b/docs/d4/d08/classshaka_1_1media_1_1mp4_1_1MP4MediaParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::mp4::MP4MediaParser, including all inherited members.

    - + - - - - + + + + +
    Flush() override WARN_UNUSED_RESULTshaka::media::mp4::MP4MediaParservirtual
    Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) overrideshaka::media::mp4::MP4MediaParservirtual
    Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) overrideshaka::media::mp4::MP4MediaParservirtual
    InitCB typedefshaka::media::MediaParser
    LoadMoov(const std::string &file_path)shaka::media::mp4::MP4MediaParser
    MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinline
    MP4MediaParser() (defined in shaka::media::mp4::MP4MediaParser)shaka::media::mp4::MP4MediaParser
    NewSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULTshaka::media::mp4::MP4MediaParservirtual
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    ~MP4MediaParser() override (defined in shaka::media::mp4::MP4MediaParser)shaka::media::mp4::MP4MediaParser
    NewMediaSampleCB typedefshaka::media::MediaParser
    NewTextSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULTshaka::media::mp4::MP4MediaParservirtual
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    ~MP4MediaParser() override (defined in shaka::media::mp4::MP4MediaParser)shaka::media::mp4::MP4MediaParser
    diff --git a/docs/d4/d0b/classshaka_1_1media_1_1TextTrack.html b/docs/d4/d0b/classshaka_1_1media_1_1TextTrack.html index c44ac9d0db..7d5042af55 100644 --- a/docs/d4/d0b/classshaka_1_1media_1_1TextTrack.html +++ b/docs/d4/d0b/classshaka_1_1media_1_1TextTrack.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::TextTrack Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    addWebVTTCue<
    diff --git a/docs/d4/d0c/text__readers_8h_source.html b/docs/d4/d0c/text__readers_8h_source.html index f683dc0d11..0458098137 100644 --- a/docs/d4/d0c/text__readers_8h_source.html +++ b/docs/d4/d0c/text__readers_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/text_readers.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    text_readers.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_TEXT_READERS_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_TEXT_READERS_H_
    9 
    10 #include <memory>
    11 #include <string>
    12 #include <vector>
    13 
    14 #include "packager/file/file_closer.h"
    15 #include "packager/status.h"
    16 
    17 namespace shaka {
    18 class File;
    19 
    20 namespace media {
    21 
    23 class FileReader {
    24  public:
    29  static Status Open(const std::string& filename,
    30  std::unique_ptr<FileReader>* out);
    31 
    35  bool Next(char* out);
    36 
    37  private:
    38  explicit FileReader(std::unique_ptr<File, FileCloser> file);
    39 
    40  FileReader(const FileReader& reader) = delete;
    41  FileReader operator=(const FileReader& reader) = delete;
    42 
    43  std::unique_ptr<File, FileCloser> file_;
    44 };
    45 
    47  public:
    48  explicit PeekingReader(std::unique_ptr<FileReader> source);
    49 
    50  bool Peek(char* out);
    51  bool Next(char* out);
    52 
    53  private:
    54  PeekingReader(const PeekingReader&) = delete;
    55  PeekingReader operator=(const PeekingReader&) = delete;
    56 
    57  std::unique_ptr<FileReader> source_;
    58  char cached_next_ = 0;
    59  bool has_cached_next_ = false;
    60 };
    61 
    62 class LineReader {
    63  public:
    64  explicit LineReader(std::unique_ptr<FileReader> source);
    65 
    66  bool Next(std::string* out);
    67 
    68  private:
    69  LineReader(const LineReader&) = delete;
    70  LineReader operator=(const LineReader&) = delete;
    71 
    72  PeekingReader source_;
    73 };
    74 
    75 class BlockReader {
    76  public:
    77  explicit BlockReader(std::unique_ptr<FileReader> source);
    78 
    79  bool Next(std::vector<std::string>* out);
    80 
    81  private:
    82  BlockReader(const BlockReader&) = delete;
    83  BlockReader operator=(const BlockReader&) = delete;
    84 
    85  LineReader source_;
    86 };
    87 
    88 } // namespace media
    89 } // namespace shaka
    90 
    91 #endif // MEDIA_FORMATS_WEBVTT_TEXT_READERS_H_
    -
    All the methods that are virtual are virtual for mocking.
    - -
    bool Next(char *out)
    Definition: text_readers.cc:32
    -
    Class to read character-by-character from a file.
    Definition: text_readers.h:23
    - - -
    static Status Open(const std::string &filename, std::unique_ptr< FileReader > *out)
    Definition: text_readers.cc:15
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_TEXT_READERS_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_TEXT_READERS_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <string>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/media/base/byte_queue.h"
    +
    15 #include "packager/status.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 class File;
    +
    19 
    +
    20 namespace media {
    +
    21 
    +
    22 class LineReader {
    +
    23  public:
    +
    24  LineReader();
    +
    25 
    +
    27  void PushData(const uint8_t* data, size_t data_size);
    +
    30  bool Next(std::string* out);
    +
    33  void Flush();
    +
    34 
    +
    35  private:
    +
    36  LineReader(const LineReader&) = delete;
    +
    37  LineReader operator=(const LineReader&) = delete;
    +
    38 
    +
    39  ByteQueue buffer_;
    +
    40  bool should_flush_;
    +
    41 };
    +
    42 
    +
    43 class BlockReader {
    +
    44  public:
    +
    45  BlockReader();
    +
    46 
    +
    48  void PushData(const uint8_t* data, size_t data_size);
    +
    51  bool Next(std::vector<std::string>* out);
    +
    54  void Flush();
    +
    55 
    +
    56  private:
    +
    57  BlockReader(const BlockReader&) = delete;
    +
    58  BlockReader operator=(const BlockReader&) = delete;
    +
    59 
    +
    60  LineReader source_;
    +
    61  std::vector<std::string> temp_;
    +
    62  bool should_flush_;
    +
    63 };
    +
    64 
    +
    65 } // namespace media
    +
    66 } // namespace shaka
    +
    67 
    +
    68 #endif // MEDIA_FORMATS_WEBVTT_TEXT_READERS_H_
    + +
    void PushData(const uint8_t *data, size_t data_size)
    Pushes data onto the end of the buffer.
    Definition: text_readers.cc:73
    + +
    bool Next(std::vector< std::string > *out)
    Definition: text_readers.cc:78
    + + + +
    bool Next(std::string *out)
    Definition: text_readers.cc:24
    +
    void PushData(const uint8_t *data, size_t data_size)
    Pushes data onto the end of the buffer.
    Definition: text_readers.cc:18
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/d15/gflags__hex__bytes_8cc_source.html b/docs/d4/d15/gflags__hex__bytes_8cc_source.html index 0ed12be744..b8b24b8025 100644 --- a/docs/d4/d15/gflags__hex__bytes_8cc_source.html +++ b/docs/d4/d15/gflags__hex__bytes_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/gflags_hex_bytes.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    gflags_hex_bytes.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/app/gflags_hex_bytes.h"
    8 
    9 #include "packager/base/strings/string_number_conversions.h"
    10 
    11 namespace shaka {
    12 
    13 bool ValidateHexString(const char* flagname,
    14  const std::string& value,
    15  std::vector<uint8_t>* value_bytes) {
    16  std::vector<uint8_t> temp_value_bytes;
    17  if (!value.empty() && !base::HexStringToBytes(value, &temp_value_bytes)) {
    18  printf("Invalid hex string for --%s: %s\n", flagname, value.c_str());
    19  return false;
    20  }
    21  value_bytes->swap(temp_value_bytes);
    22  return true;
    23 }
    24 
    25 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/app/gflags_hex_bytes.h"
    +
    8 
    +
    9 #include "packager/base/strings/string_number_conversions.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 
    +
    13 bool ValidateHexString(const char* flagname,
    +
    14  const std::string& value,
    +
    15  std::vector<uint8_t>* value_bytes) {
    +
    16  std::vector<uint8_t> temp_value_bytes;
    +
    17  if (!value.empty() && !base::HexStringToBytes(value, &temp_value_bytes)) {
    +
    18  printf("Invalid hex string for --%s: %s\n", flagname, value.c_str());
    +
    19  return false;
    +
    20  }
    +
    21  value_bytes->swap(temp_value_bytes);
    +
    22  return true;
    +
    23 }
    +
    24 
    +
    25 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/d18/structshaka_1_1media_1_1mp4_1_1EditListEntry.html b/docs/d4/d18/structshaka_1_1media_1_1mp4_1_1EditListEntry.html index a3f1f5572e..be9d640e5f 100644 --- a/docs/d4/d18/structshaka_1_1media_1_1mp4_1_1EditListEntry.html +++ b/docs/d4/d18/structshaka_1_1media_1_1mp4_1_1EditListEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::EditListEntry Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    media_rate_fractio

    Detailed Description

    -

    Definition at line 208 of file box_definitions.h.

    +

    Definition at line 209 of file box_definitions.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/d4/d1e/webvtt__utils_8h_source.html b/docs/d4/d1e/webvtt__utils_8h_source.html new file mode 100644 index 0000000000..018d93836f --- /dev/null +++ b/docs/d4/d1e/webvtt__utils_8h_source.html @@ -0,0 +1,119 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/webvtt/webvtt_utils.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    webvtt_utils.h
    +
    +
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_UTILS_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_UTILS_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <list>
    +
    13 #include <memory>
    +
    14 #include <string>
    +
    15 
    +
    16 #include "packager/base/strings/string_piece.h"
    +
    17 #include "packager/media/base/text_sample.h"
    +
    18 #include "packager/media/base/text_stream_info.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 namespace media {
    +
    22 
    +
    23 // Parse a timestamp into milliseconds using the two patterns defined by WebVtt:
    +
    24 // LONG : ##:##:##.### (long can have 2 or more hour digits)
    +
    25 // SHORT : ##:##:###
    +
    26 bool WebVttTimestampToMs(const base::StringPiece& source, uint64_t* out);
    +
    27 
    +
    28 // Create a long form timestamp encoded as a string.
    +
    29 std::string MsToWebVttTimestamp(uint64_t ms);
    +
    30 
    +
    32 std::string WebVttSettingsToString(const TextSettings& settings);
    +
    33 
    +
    35 std::string WebVttFragmentToString(const TextFragment& fragment);
    +
    36 
    +
    39 std::string WebVttGetPreamble(const TextStreamInfo& stream_info);
    +
    40 
    +
    41 } // namespace media
    +
    42 } // namespace shaka
    +
    43 
    +
    44 #endif // PACKAGER_MEDIA_FORMATS_WEBVTT_UTILS_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/d4/d20/classshaka_1_1media_1_1AesCbcEncryptor.html b/docs/d4/d20/classshaka_1_1media_1_1AesCbcEncryptor.html index 4d76b4d2cd..ab1a45aa60 100644 --- a/docs/d4/d20/classshaka_1_1media_1_1AesCbcEncryptor.html +++ b/docs/d4/d20/classshaka_1_1media_1_1AesCbcEncryptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AesCbcEncryptor Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::AesEncryptor shaka::media::AesCryptor - -
    + + @@ -117,8 +120,8 @@ bool  - @@ -214,9 +217,7 @@ AES_KEY * 

    Public Member Functions

    Crypt (const uint

    Additional Inherited Members

    - Public Types inherited from shaka::media::AesCryptor
    enum  ConstantIvFlag { kUseConstantIv, -kDontUseConstantIv +
    enum  ConstantIvFlag { kUseConstantIv +, kDontUseConstantIv }
     
    - Static Public Member Functions inherited from shaka::media::AesCryptor
    mutable_aes_key< diff --git a/docs/d4/d20/structshaka_1_1media_1_1mp4_1_1ChunkLargeOffset-members.html b/docs/d4/d20/structshaka_1_1media_1_1mp4_1_1ChunkLargeOffset-members.html index 07d57c15d8..40dbecd4c6 100644 --- a/docs/d4/d20/structshaka_1_1media_1_1mp4_1_1ChunkLargeOffset-members.html +++ b/docs/d4/d20/structshaka_1_1media_1_1mp4_1_1ChunkLargeOffset-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d4/d22/structshaka_1_1media_1_1SegmentEventInfo-members.html b/docs/d4/d22/structshaka_1_1media_1_1SegmentEventInfo-members.html index e3097c1879..115f3ba894 100644 --- a/docs/d4/d22/structshaka_1_1media_1_1SegmentEventInfo-members.html +++ b/docs/d4/d22/structshaka_1_1media_1_1SegmentEventInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/d2c/structshaka_1_1media_1_1mp4_1_1ID3v2-members.html b/docs/d4/d2c/structshaka_1_1media_1_1mp4_1_1ID3v2-members.html index 6aac133f22..cb9e5a91b3 100644 --- a/docs/d4/d2c/structshaka_1_1media_1_1mp4_1_1ID3v2-members.html +++ b/docs/d4/d2c/structshaka_1_1media_1_1mp4_1_1ID3v2-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/d33/structshaka_1_1media_1_1mp4_1_1WebVTTSourceLabelBox.html b/docs/d4/d33/structshaka_1_1media_1_1mp4_1_1WebVTTSourceLabelBox.html index 78e2e5dc5d..1fd246e49c 100644 --- a/docs/d4/d33/structshaka_1_1media_1_1mp4_1_1WebVTTSourceLabelBox.html +++ b/docs/d4/d33/structshaka_1_1media_1_1mp4_1_1WebVTTSourceLabelBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::WebVTTSourceLabelBox Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -112,7 +115,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 385 of file box_definitions.h.

    +

    Definition at line 393 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -140,7 +143,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1927 of file box_definitions.cc.

    +

    Definition at line 1976 of file box_definitions.cc.

    @@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d4/d37/io__cache_8cc_source.html b/docs/d4/d37/io__cache_8cc_source.html index aec8a6daa8..c739651c92 100644 --- a/docs/d4/d37/io__cache_8cc_source.html +++ b/docs/d4/d37/io__cache_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/io_cache.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    io_cache.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/file/io_cache.h"
    8 
    9 #include <string.h>
    10 
    11 #include <algorithm>
    12 
    13 #include "packager/base/logging.h"
    14 
    15 namespace shaka {
    16 
    17 using base::AutoLock;
    18 using base::AutoUnlock;
    19 
    20 IoCache::IoCache(uint64_t cache_size)
    21  : cache_size_(cache_size),
    22  read_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
    23  base::WaitableEvent::InitialState::NOT_SIGNALED),
    24  write_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
    25  base::WaitableEvent::InitialState::NOT_SIGNALED),
    26  // Make the buffer one byte larger than the cache so that when the
    27  // condition r_ptr == w_ptr is unambiguous (buffer empty).
    28  circular_buffer_(cache_size + 1),
    29  end_ptr_(&circular_buffer_[0] + cache_size + 1),
    30  r_ptr_(circular_buffer_.data()),
    31  w_ptr_(circular_buffer_.data()),
    32  closed_(false) {}
    33 
    34 IoCache::~IoCache() {
    35  Close();
    36 }
    37 
    38 uint64_t IoCache::Read(void* buffer, uint64_t size) {
    39  DCHECK(buffer);
    40 
    41  AutoLock lock(lock_);
    42  while (!closed_ && (BytesCachedInternal() == 0)) {
    43  AutoUnlock unlock(lock_);
    44  write_event_.Wait();
    45  }
    46 
    47  size = std::min(size, BytesCachedInternal());
    48  uint64_t first_chunk_size(
    49  std::min(size, static_cast<uint64_t>(end_ptr_ - r_ptr_)));
    50  memcpy(buffer, r_ptr_, first_chunk_size);
    51  r_ptr_ += first_chunk_size;
    52  DCHECK_GE(end_ptr_, r_ptr_);
    53  if (r_ptr_ == end_ptr_)
    54  r_ptr_ = &circular_buffer_[0];
    55  uint64_t second_chunk_size(size - first_chunk_size);
    56  if (second_chunk_size) {
    57  memcpy(static_cast<uint8_t*>(buffer) + first_chunk_size, r_ptr_,
    58  second_chunk_size);
    59  r_ptr_ += second_chunk_size;
    60  DCHECK_GT(end_ptr_, r_ptr_);
    61  }
    62  read_event_.Signal();
    63  return size;
    64 }
    65 
    66 uint64_t IoCache::Write(const void* buffer, uint64_t size) {
    67  DCHECK(buffer);
    68 
    69  const uint8_t* r_ptr(static_cast<const uint8_t*>(buffer));
    70  uint64_t bytes_left(size);
    71  while (bytes_left) {
    72  AutoLock lock(lock_);
    73  while (!closed_ && (BytesFreeInternal() == 0)) {
    74  AutoUnlock unlock(lock_);
    75  VLOG(1) << "Circular buffer is full, which can happen if data arrives "
    76  "faster than being consumed by packager. Ignore if it is not "
    77  "live packaging. Otherwise, try increasing --io_cache_size.";
    78  read_event_.Wait();
    79  }
    80  if (closed_)
    81  return 0;
    82 
    83  uint64_t write_size(std::min(bytes_left, BytesFreeInternal()));
    84  uint64_t first_chunk_size(
    85  std::min(write_size, static_cast<uint64_t>(end_ptr_ - w_ptr_)));
    86  memcpy(w_ptr_, r_ptr, first_chunk_size);
    87  w_ptr_ += first_chunk_size;
    88  DCHECK_GE(end_ptr_, w_ptr_);
    89  if (w_ptr_ == end_ptr_)
    90  w_ptr_ = &circular_buffer_[0];
    91  r_ptr += first_chunk_size;
    92  uint64_t second_chunk_size(write_size - first_chunk_size);
    93  if (second_chunk_size) {
    94  memcpy(w_ptr_, r_ptr, second_chunk_size);
    95  w_ptr_ += second_chunk_size;
    96  DCHECK_GT(end_ptr_, w_ptr_);
    97  r_ptr += second_chunk_size;
    98  }
    99  bytes_left -= write_size;
    100  write_event_.Signal();
    101  }
    102  return size;
    103 }
    104 
    106  AutoLock lock(lock_);
    107  r_ptr_ = w_ptr_ = circular_buffer_.data();
    108  // Let any writers know that there is room in the cache.
    109  read_event_.Signal();
    110 }
    111 
    113  AutoLock lock(lock_);
    114  closed_ = true;
    115  read_event_.Signal();
    116  write_event_.Signal();
    117 }
    118 
    120  AutoLock lock(lock_);
    121  CHECK(closed_);
    122  r_ptr_ = w_ptr_ = circular_buffer_.data();
    123  closed_ = false;
    124  read_event_.Reset();
    125  write_event_.Reset();
    126 }
    127 
    129  AutoLock lock(lock_);
    130  return BytesCachedInternal();
    131 }
    132 
    133 uint64_t IoCache::BytesFree() {
    134  AutoLock lock(lock_);
    135  return BytesFreeInternal();
    136 }
    137 
    138 uint64_t IoCache::BytesCachedInternal() {
    139  return (r_ptr_ <= w_ptr_)
    140  ? w_ptr_ - r_ptr_
    141  : (end_ptr_ - r_ptr_) + (w_ptr_ - circular_buffer_.data());
    142 }
    143 
    144 uint64_t IoCache::BytesFreeInternal() {
    145  return cache_size_ - BytesCachedInternal();
    146 }
    147 
    149  AutoLock lock(lock_);
    150  while (!closed_ && BytesCachedInternal()) {
    151  AutoUnlock unlock(lock_);
    152  read_event_.Wait();
    153  }
    154 }
    155 
    156 } // namespace shaka
    void Reopen()
    Reopens the cache. Any data still in the cache will be lost.
    Definition: io_cache.cc:119
    -
    void Clear()
    Empties the cache.
    Definition: io_cache.cc:105
    -
    void Close()
    Definition: io_cache.cc:112
    -
    All the methods that are virtual are virtual for mocking.
    -
    uint64_t Write(const void *buffer, uint64_t size)
    Definition: io_cache.cc:66
    -
    void WaitUntilEmptyOrClosed()
    Waits until the cache is empty or has been closed.
    Definition: io_cache.cc:148
    -
    uint64_t Read(void *buffer, uint64_t size)
    Definition: io_cache.cc:38
    -
    uint64_t BytesFree()
    Definition: io_cache.cc:133
    - -
    uint64_t BytesCached()
    Definition: io_cache.cc:128
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/file/io_cache.h"
    +
    8 
    +
    9 #include <string.h>
    +
    10 
    +
    11 #include <algorithm>
    +
    12 
    +
    13 #include "packager/base/logging.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 
    +
    17 using base::AutoLock;
    +
    18 using base::AutoUnlock;
    +
    19 
    +
    20 IoCache::IoCache(uint64_t cache_size)
    +
    21  : cache_size_(cache_size),
    +
    22  read_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
    +
    23  base::WaitableEvent::InitialState::NOT_SIGNALED),
    +
    24  write_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
    +
    25  base::WaitableEvent::InitialState::NOT_SIGNALED),
    +
    26  // Make the buffer one byte larger than the cache so that when the
    +
    27  // condition r_ptr == w_ptr is unambiguous (buffer empty).
    +
    28  circular_buffer_(cache_size + 1),
    +
    29  end_ptr_(&circular_buffer_[0] + cache_size + 1),
    +
    30  r_ptr_(circular_buffer_.data()),
    +
    31  w_ptr_(circular_buffer_.data()),
    +
    32  closed_(false) {}
    +
    33 
    +
    34 IoCache::~IoCache() {
    +
    35  Close();
    +
    36 }
    +
    37 
    +
    38 uint64_t IoCache::Read(void* buffer, uint64_t size) {
    +
    39  DCHECK(buffer);
    +
    40 
    +
    41  AutoLock lock(lock_);
    +
    42  while (!closed_ && (BytesCachedInternal() == 0)) {
    +
    43  AutoUnlock unlock(lock_);
    +
    44  write_event_.Wait();
    +
    45  }
    +
    46 
    +
    47  size = std::min(size, BytesCachedInternal());
    +
    48  uint64_t first_chunk_size(
    +
    49  std::min(size, static_cast<uint64_t>(end_ptr_ - r_ptr_)));
    +
    50  memcpy(buffer, r_ptr_, first_chunk_size);
    +
    51  r_ptr_ += first_chunk_size;
    +
    52  DCHECK_GE(end_ptr_, r_ptr_);
    +
    53  if (r_ptr_ == end_ptr_)
    +
    54  r_ptr_ = &circular_buffer_[0];
    +
    55  uint64_t second_chunk_size(size - first_chunk_size);
    +
    56  if (second_chunk_size) {
    +
    57  memcpy(static_cast<uint8_t*>(buffer) + first_chunk_size, r_ptr_,
    +
    58  second_chunk_size);
    +
    59  r_ptr_ += second_chunk_size;
    +
    60  DCHECK_GT(end_ptr_, r_ptr_);
    +
    61  }
    +
    62  read_event_.Signal();
    +
    63  return size;
    +
    64 }
    +
    65 
    +
    66 uint64_t IoCache::Write(const void* buffer, uint64_t size) {
    +
    67  DCHECK(buffer);
    +
    68 
    +
    69  const uint8_t* r_ptr(static_cast<const uint8_t*>(buffer));
    +
    70  uint64_t bytes_left(size);
    +
    71  while (bytes_left) {
    +
    72  AutoLock lock(lock_);
    +
    73  while (!closed_ && (BytesFreeInternal() == 0)) {
    +
    74  AutoUnlock unlock(lock_);
    +
    75  VLOG(1) << "Circular buffer is full, which can happen if data arrives "
    +
    76  "faster than being consumed by packager. Ignore if it is not "
    +
    77  "live packaging. Otherwise, try increasing --io_cache_size.";
    +
    78  read_event_.Wait();
    +
    79  }
    +
    80  if (closed_)
    +
    81  return 0;
    +
    82 
    +
    83  uint64_t write_size(std::min(bytes_left, BytesFreeInternal()));
    +
    84  uint64_t first_chunk_size(
    +
    85  std::min(write_size, static_cast<uint64_t>(end_ptr_ - w_ptr_)));
    +
    86  memcpy(w_ptr_, r_ptr, first_chunk_size);
    +
    87  w_ptr_ += first_chunk_size;
    +
    88  DCHECK_GE(end_ptr_, w_ptr_);
    +
    89  if (w_ptr_ == end_ptr_)
    +
    90  w_ptr_ = &circular_buffer_[0];
    +
    91  r_ptr += first_chunk_size;
    +
    92  uint64_t second_chunk_size(write_size - first_chunk_size);
    +
    93  if (second_chunk_size) {
    +
    94  memcpy(w_ptr_, r_ptr, second_chunk_size);
    +
    95  w_ptr_ += second_chunk_size;
    +
    96  DCHECK_GT(end_ptr_, w_ptr_);
    +
    97  r_ptr += second_chunk_size;
    +
    98  }
    +
    99  bytes_left -= write_size;
    +
    100  write_event_.Signal();
    +
    101  }
    +
    102  return size;
    +
    103 }
    +
    104 
    +
    105 void IoCache::Clear() {
    +
    106  AutoLock lock(lock_);
    +
    107  r_ptr_ = w_ptr_ = circular_buffer_.data();
    +
    108  // Let any writers know that there is room in the cache.
    +
    109  read_event_.Signal();
    +
    110 }
    +
    111 
    +
    112 void IoCache::Close() {
    +
    113  AutoLock lock(lock_);
    +
    114  closed_ = true;
    +
    115  read_event_.Signal();
    +
    116  write_event_.Signal();
    +
    117 }
    +
    118 
    +
    119 void IoCache::Reopen() {
    +
    120  AutoLock lock(lock_);
    +
    121  CHECK(closed_);
    +
    122  r_ptr_ = w_ptr_ = circular_buffer_.data();
    +
    123  closed_ = false;
    +
    124  read_event_.Reset();
    +
    125  write_event_.Reset();
    +
    126 }
    +
    127 
    +
    128 uint64_t IoCache::BytesCached() {
    +
    129  AutoLock lock(lock_);
    +
    130  return BytesCachedInternal();
    +
    131 }
    +
    132 
    +
    133 uint64_t IoCache::BytesFree() {
    +
    134  AutoLock lock(lock_);
    +
    135  return BytesFreeInternal();
    +
    136 }
    +
    137 
    +
    138 uint64_t IoCache::BytesCachedInternal() {
    +
    139  return (r_ptr_ <= w_ptr_)
    +
    140  ? w_ptr_ - r_ptr_
    +
    141  : (end_ptr_ - r_ptr_) + (w_ptr_ - circular_buffer_.data());
    +
    142 }
    +
    143 
    +
    144 uint64_t IoCache::BytesFreeInternal() {
    +
    145  return cache_size_ - BytesCachedInternal();
    +
    146 }
    +
    147 
    +
    148 void IoCache::WaitUntilEmptyOrClosed() {
    +
    149  AutoLock lock(lock_);
    +
    150  while (!closed_ && BytesCachedInternal()) {
    +
    151  AutoUnlock unlock(lock_);
    +
    152  read_event_.Wait();
    +
    153  }
    +
    154 }
    +
    155 
    +
    156 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/d3a/structshaka_1_1media_1_1H264Sps-members.html b/docs/d4/d3a/structshaka_1_1media_1_1H264Sps-members.html index b57a8bcc0f..73779a5460 100644 --- a/docs/d4/d3a/structshaka_1_1media_1_1H264Sps-members.html +++ b/docs/d4/d3a/structshaka_1_1media_1_1H264Sps-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    frame_cropping_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps frame_mbs_only_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps gaps_in_frame_num_value_allowed_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps - H264Sps() (defined in shaka::media::H264Sps)shaka::media::H264Sps - level_idc (defined in shaka::media::H264Sps)shaka::media::H264Sps - log2_max_frame_num_minus4 (defined in shaka::media::H264Sps)shaka::media::H264Sps - log2_max_pic_order_cnt_lsb_minus4 (defined in shaka::media::H264Sps)shaka::media::H264Sps - max_dec_frame_buffering (defined in shaka::media::H264Sps)shaka::media::H264Sps - max_num_ref_frames (defined in shaka::media::H264Sps)shaka::media::H264Sps - max_num_reorder_frames (defined in shaka::media::H264Sps)shaka::media::H264Sps - mb_adaptive_frame_field_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps - num_ref_frames_in_pic_order_cnt_cycle (defined in shaka::media::H264Sps)shaka::media::H264Sps - offset_for_non_ref_pic (defined in shaka::media::H264Sps)shaka::media::H264Sps - offset_for_ref_frame (defined in shaka::media::H264Sps)shaka::media::H264Sps - offset_for_top_to_bottom_field (defined in shaka::media::H264Sps)shaka::media::H264Sps - pic_height_in_map_units_minus1 (defined in shaka::media::H264Sps)shaka::media::H264Sps - pic_order_cnt_type (defined in shaka::media::H264Sps)shaka::media::H264Sps - pic_width_in_mbs_minus1 (defined in shaka::media::H264Sps)shaka::media::H264Sps - profile_idc (defined in shaka::media::H264Sps)shaka::media::H264Sps - qpprime_y_zero_transform_bypass_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps - sar_height (defined in shaka::media::H264Sps)shaka::media::H264Sps - sar_width (defined in shaka::media::H264Sps)shaka::media::H264Sps - scaling_list4x4 (defined in shaka::media::H264Sps)shaka::media::H264Sps - scaling_list8x8 (defined in shaka::media::H264Sps)shaka::media::H264Sps - separate_colour_plane_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps - seq_parameter_set_id (defined in shaka::media::H264Sps)shaka::media::H264Sps - seq_scaling_matrix_present_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps - transfer_characteristics (defined in shaka::media::H264Sps)shaka::media::H264Sps - vui_parameters_present_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps + level_idc (defined in shaka::media::H264Sps)shaka::media::H264Sps + log2_max_frame_num_minus4 (defined in shaka::media::H264Sps)shaka::media::H264Sps + log2_max_pic_order_cnt_lsb_minus4 (defined in shaka::media::H264Sps)shaka::media::H264Sps + max_dec_frame_buffering (defined in shaka::media::H264Sps)shaka::media::H264Sps + max_num_ref_frames (defined in shaka::media::H264Sps)shaka::media::H264Sps + max_num_reorder_frames (defined in shaka::media::H264Sps)shaka::media::H264Sps + mb_adaptive_frame_field_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps + num_ref_frames_in_pic_order_cnt_cycle (defined in shaka::media::H264Sps)shaka::media::H264Sps + offset_for_non_ref_pic (defined in shaka::media::H264Sps)shaka::media::H264Sps + offset_for_ref_frame (defined in shaka::media::H264Sps)shaka::media::H264Sps + offset_for_top_to_bottom_field (defined in shaka::media::H264Sps)shaka::media::H264Sps + pic_height_in_map_units_minus1 (defined in shaka::media::H264Sps)shaka::media::H264Sps + pic_order_cnt_type (defined in shaka::media::H264Sps)shaka::media::H264Sps + pic_width_in_mbs_minus1 (defined in shaka::media::H264Sps)shaka::media::H264Sps + profile_idc (defined in shaka::media::H264Sps)shaka::media::H264Sps + qpprime_y_zero_transform_bypass_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps + sar_height (defined in shaka::media::H264Sps)shaka::media::H264Sps + sar_width (defined in shaka::media::H264Sps)shaka::media::H264Sps + scaling_list4x4 (defined in shaka::media::H264Sps)shaka::media::H264Sps + scaling_list8x8 (defined in shaka::media::H264Sps)shaka::media::H264Sps + separate_colour_plane_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps + seq_parameter_set_id (defined in shaka::media::H264Sps)shaka::media::H264Sps + seq_scaling_matrix_present_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps + transfer_characteristics (defined in shaka::media::H264Sps)shaka::media::H264Sps + vui_parameters_present_flag (defined in shaka::media::H264Sps)shaka::media::H264Sps
    diff --git a/docs/d4/d40/sample__aes__ec3__cryptor_8h_source.html b/docs/d4/d40/sample__aes__ec3__cryptor_8h_source.html index 68aa4bfa58..d0f009e44f 100644 --- a/docs/d4/d40/sample__aes__ec3__cryptor_8h_source.html +++ b/docs/d4/d40/sample__aes__ec3__cryptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto/sample_aes_ec3_cryptor.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    sample_aes_ec3_cryptor.h
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/aes_cryptor.h"
    8 
    9 #ifndef PACKAGER_MEDIA_CRYPTO_SAMPLE_AES_EC3_CRYPTOR_H_
    10 #define PACKAGER_MEDIA_CRYPTO_SAMPLE_AES_EC3_CRYPTOR_H_
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    18  public:
    22  explicit SampleAesEc3Cryptor(std::unique_ptr<AesCryptor> cryptor);
    23 
    26  bool InitializeWithIv(const std::vector<uint8_t>& key,
    27  const std::vector<uint8_t>& iv) override;
    29 
    30  private:
    32  SampleAesEc3Cryptor& operator=(const SampleAesEc3Cryptor&) = delete;
    33 
    34  // AesCryptor implementation overrides.
    35  bool CryptInternal(const uint8_t* text,
    36  size_t text_size,
    37  uint8_t* crypt_text,
    38  size_t* crypt_text_size) override;
    39  void SetIvInternal() override;
    40 
    41  std::unique_ptr<AesCryptor> cryptor_;
    42 };
    43 
    44 } // namespace media
    45 } // namespace shaka
    46 
    47 #endif // PACKAGER_MEDIA_CRYPTO_SAMPLE_AES_EC3_CRYPTOR_H_
    -
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    -
    All the methods that are virtual are virtual for mocking.
    - -
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    -
    SampleAesEc3Cryptor(std::unique_ptr< AesCryptor > cryptor)
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/aes_cryptor.h"
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_CRYPTO_SAMPLE_AES_EC3_CRYPTOR_H_
    +
    10 #define PACKAGER_MEDIA_CRYPTO_SAMPLE_AES_EC3_CRYPTOR_H_
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    + +
    18  public:
    +
    22  explicit SampleAesEc3Cryptor(std::unique_ptr<AesCryptor> cryptor);
    +
    23 
    +
    26  bool InitializeWithIv(const std::vector<uint8_t>& key,
    +
    27  const std::vector<uint8_t>& iv) override;
    +
    29 
    +
    30  private:
    + +
    32  SampleAesEc3Cryptor& operator=(const SampleAesEc3Cryptor&) = delete;
    +
    33 
    +
    34  // AesCryptor implementation overrides.
    +
    35  bool CryptInternal(const uint8_t* text,
    +
    36  size_t text_size,
    +
    37  uint8_t* crypt_text,
    +
    38  size_t* crypt_text_size) override;
    +
    39  void SetIvInternal() override;
    +
    40 
    +
    41  std::unique_ptr<AesCryptor> cryptor_;
    +
    42 };
    +
    43 
    +
    44 } // namespace media
    +
    45 } // namespace shaka
    +
    46 
    +
    47 #endif // PACKAGER_MEDIA_CRYPTO_SAMPLE_AES_EC3_CRYPTOR_H_
    + +
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    + +
    SampleAesEc3Cryptor(std::unique_ptr< AesCryptor > cryptor)
    +
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/d43/classshaka_1_1media_1_1ChunkingHandler.html b/docs/d4/d43/classshaka_1_1media_1_1ChunkingHandler.html index 10ac8df0ae..910f656aab 100644 --- a/docs/d4/d43/classshaka_1_1media_1_1ChunkingHandler.html +++ b/docs/d4/d43/classshaka_1_1media_1_1ChunkingHandler.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ChunkingHandler Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::MediaHandler - -
    + + @@ -175,9 +178,9 @@ class  - - + +

    Public Member Functions

    ChunkingHandlerTest<

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     

    Detailed Description

    ChunkingHandler splits the samples into segments / subsegments based on the specified chunking params. This handler is a one-in one-out handler. There can be multiple chunking handler running in different threads or even different processes, we use the "consistent chunking algorithm" to make sure the chunks in different streams are aligned without explicit communcating with each other - which is not efficient and often difficult.

    @@ -257,9 +260,7 @@ static Status
    diff --git a/docs/d4/d4a/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationOffset-members.html b/docs/d4/d4a/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationOffset-members.html index d3812b2285..a751deaa67 100644 --- a/docs/d4/d4a/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationOffset-members.html +++ b/docs/d4/d4a/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationOffset-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/d4c/structshaka_1_1media_1_1H264WeightingFactors.html b/docs/d4/d4c/structshaka_1_1media_1_1H264WeightingFactors.html index 24aeba3734..a2b7a0abd9 100644 --- a/docs/d4/d4c/structshaka_1_1media_1_1H264WeightingFactors.html +++ b/docs/d4/d4c/structshaka_1_1media_1_1H264WeightingFactors.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264WeightingFactors Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    chroma_offset [32]

    Detailed Description

    -

    Definition at line 129 of file h264_parser.h.

    +

    Definition at line 125 of file h264_parser.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/d4/d51/ttml__muxer_8cc_source.html b/docs/d4/d51/ttml__muxer_8cc_source.html new file mode 100644 index 0000000000..b2c03b2df7 --- /dev/null +++ b/docs/d4/d51/ttml__muxer_8cc_source.html @@ -0,0 +1,125 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/ttml/ttml_muxer.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    ttml_muxer.cc
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/ttml/ttml_muxer.h"
    +
    8 
    +
    9 #include "packager/file/file.h"
    +
    10 #include "packager/status_macros.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 namespace ttml {
    +
    15 
    +
    16 TtmlMuxer::TtmlMuxer(const MuxerOptions& options) : TextMuxer(options) {}
    +
    17 TtmlMuxer::~TtmlMuxer() {}
    +
    18 
    +
    19 Status TtmlMuxer::InitializeStream(TextStreamInfo* stream) {
    +
    20  stream->set_codec(kCodecTtml);
    +
    21  stream->set_codec_string("ttml");
    +
    22  generator_.Initialize(stream->regions(), stream->language(),
    +
    23  stream->time_scale());
    +
    24  return Status::OK;
    +
    25 }
    +
    26 
    +
    27 Status TtmlMuxer::AddTextSampleInternal(const TextSample& sample) {
    +
    28  generator_.AddSample(sample);
    +
    29  return Status::OK;
    +
    30 }
    +
    31 
    +
    32 Status TtmlMuxer::WriteToFile(const std::string& filename, uint64_t* size) {
    +
    33  std::string data;
    +
    34  if (!generator_.Dump(&data))
    +
    35  return Status(error::INTERNAL_ERROR, "Error generating XML");
    +
    36  generator_.Reset();
    +
    37  *size = data.size();
    +
    38 
    +
    39  if (!File::WriteStringToFile(filename.c_str(), data))
    +
    40  return Status(error::FILE_FAILURE, "Failed to write " + filename);
    +
    41  return Status::OK;
    +
    42 }
    +
    43 
    +
    44 } // namespace ttml
    +
    45 } // namespace media
    +
    46 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/d4/d56/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header-members.html b/docs/d4/d56/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header-members.html new file mode 100644 index 0000000000..7ebdc56b61 --- /dev/null +++ b/docs/d4/d56/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header-members.html @@ -0,0 +1,96 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::mp2t::Mpeg1Header Member List
    +
    +
    + +

    This is the complete list of members for shaka::media::mp2t::Mpeg1Header, including all inherited members.

    + + + + + + + + + + + + + + + + +
    AudioHeader()=default (defined in shaka::media::mp2t::AudioHeader)shaka::media::mp2t::AudioHeader
    GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const overrideshaka::media::mp2t::Mpeg1Headervirtual
    GetFrameSize() const overrideshaka::media::mp2t::Mpeg1Headervirtual
    GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const overrideshaka::media::mp2t::Mpeg1Headervirtual
    GetHeaderSize() const overrideshaka::media::mp2t::Mpeg1Headervirtual
    GetMinFrameSize() const overrideshaka::media::mp2t::Mpeg1Headervirtual
    GetNumChannels() const overrideshaka::media::mp2t::Mpeg1Headervirtual
    GetObjectType() const overrideshaka::media::mp2t::Mpeg1Headervirtual
    GetSamplesPerFrame() const overrideshaka::media::mp2t::Mpeg1Headervirtual
    GetSamplingFrequency() const overrideshaka::media::mp2t::Mpeg1Headervirtual
    IsSyncWord(const uint8_t *buf) const overrideshaka::media::mp2t::Mpeg1Headervirtual
    Mpeg1Header()=default (defined in shaka::media::mp2t::Mpeg1Header)shaka::media::mp2t::Mpeg1Header
    Parse(const uint8_t *mpeg1_frame, size_t mpeg1_frame_size) overrideshaka::media::mp2t::Mpeg1Headervirtual
    ~AudioHeader()=default (defined in shaka::media::mp2t::AudioHeader)shaka::media::mp2t::AudioHeadervirtual
    ~Mpeg1Header() override=default (defined in shaka::media::mp2t::Mpeg1Header)shaka::media::mp2t::Mpeg1Header
    + + + + diff --git a/docs/d4/d58/classshaka_1_1media_1_1Nalu-members.html b/docs/d4/d58/classshaka_1_1media_1_1Nalu-members.html index 5c147b9ad2..e1c67ed37a 100644 --- a/docs/d4/d58/classshaka_1_1media_1_1Nalu-members.html +++ b/docs/d4/d58/classshaka_1_1media_1_1Nalu-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/d59/classshaka_1_1media_1_1WebMWebVTTParser.html b/docs/d4/d59/classshaka_1_1media_1_1WebMWebVTTParser.html index 978a4773c6..17c1037a21 100644 --- a/docs/d4/d59/classshaka_1_1media_1_1WebMWebVTTParser.html +++ b/docs/d4/d59/classshaka_1_1media_1_1WebMWebVTTParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMWebVTTParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/d5c/classshaka_1_1media_1_1DecryptConfig-members.html b/docs/d4/d5c/classshaka_1_1media_1_1DecryptConfig-members.html index ac495f537e..2845299b96 100644 --- a/docs/d4/d5c/classshaka_1_1media_1_1DecryptConfig-members.html +++ b/docs/d4/d5c/classshaka_1_1media_1_1DecryptConfig-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d4/d60/structshaka_1_1media_1_1TextRegion.html b/docs/d4/d60/structshaka_1_1media_1_1TextRegion.html new file mode 100644 index 0000000000..708db7a2f0 --- /dev/null +++ b/docs/d4/d60/structshaka_1_1media_1_1TextRegion.html @@ -0,0 +1,163 @@ + + + + + + + +Shaka Packager SDK: shaka::media::TextRegion Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::TextRegion Struct Reference
    +
    +
    + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    +TextNumber width {100, TextUnitType::kPercent}
     The width of the region; percent units are relative to the window.
     
    +TextNumber height {100, TextUnitType::kPercent}
     The height of the region; percent units are relative to the window.
     
    TextNumber window_anchor_x {0, TextUnitType::kPercent}
     
    +TextNumber window_anchor_y {0, TextUnitType::kPercent}
     
    TextNumber region_anchor_x {0, TextUnitType::kPercent}
     
    +TextNumber region_anchor_y {0, TextUnitType::kPercent}
     
    bool scroll = false
     
    +

    Detailed Description

    +
    +

    Definition at line 19 of file text_stream_info.h.

    +

    Member Data Documentation

    + +

    ◆ region_anchor_x

    + +
    +
    + + + + +
    TextNumber shaka::media::TextRegion::region_anchor_x {0, TextUnitType::kPercent}
    +
    +

    The x and y coordinates of the anchor point within the region. Percent units are relative to the region size. For example: if this is (100, 100), then the bottom right of the region should be placed at the window anchor point. See https://www.w3.org/TR/webvtt1/#regions.

    + +

    Definition at line 35 of file text_stream_info.h.

    + +
    +
    + +

    ◆ scroll

    + +
    +
    + + + + +
    bool shaka::media::TextRegion::scroll = false
    +
    +

    If true, cues are scrolled up when adding new cues; if false, cues are added above existing cues or replace existing ones.

    + +

    Definition at line 40 of file text_stream_info.h.

    + +
    +
    + +

    ◆ window_anchor_x

    + +
    +
    + + + + +
    TextNumber shaka::media::TextRegion::window_anchor_x {0, TextUnitType::kPercent}
    +
    +

    The x and y coordinates of the anchor point within the window. Percent units are relative to the window. In WebVTT this is called the "viewport region anchor".

    + +

    Definition at line 28 of file text_stream_info.h.

    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/docs/d4/d61/ad__cue__generator__flags_8h_source.html b/docs/d4/d61/ad__cue__generator__flags_8h_source.html index 99c030b510..4e52739a10 100644 --- a/docs/d4/d61/ad__cue__generator__flags_8h_source.html +++ b/docs/d4/d61/ad__cue__generator__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/ad_cue_generator_flags.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    ad_cue_generator_flags.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_APP_AD_CUE_GENERATOR_FLAGS_H_
    8 #define PACKAGER_APP_AD_CUE_GENERATOR_FLAGS_H_
    9 
    10 #include <gflags/gflags.h>
    11 
    12 DECLARE_string(ad_cues);
    13 
    14 #endif // PACKAGER_APP_AD_CUE_GENERATOR_FLAGS_H_
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_APP_AD_CUE_GENERATOR_FLAGS_H_
    +
    8 #define PACKAGER_APP_AD_CUE_GENERATOR_FLAGS_H_
    +
    9 
    +
    10 #include <gflags/gflags.h>
    +
    11 
    +
    12 DECLARE_string(ad_cues);
    +
    13 
    +
    14 #endif // PACKAGER_APP_AD_CUE_GENERATOR_FLAGS_H_
    +
    diff --git a/docs/d4/d6b/classshaka_1_1media_1_1ttml_1_1TtmlMuxer-members.html b/docs/d4/d6b/classshaka_1_1media_1_1ttml_1_1TtmlMuxer-members.html new file mode 100644 index 0000000000..f2cb0965b3 --- /dev/null +++ b/docs/d4/d6b/classshaka_1_1media_1_1ttml_1_1TtmlMuxer-members.html @@ -0,0 +1,120 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::ttml::TtmlMuxer Member List
    +
    +
    + +

    This is the complete list of members for shaka::media::ttml::TtmlMuxer, including all inherited members.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
    Cancel()shaka::media::Muxer
    Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    clock() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
    DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) constshaka::media::MediaHandlerinlineprotected
    DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) constshaka::media::MediaHandlerinlineprotected
    DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) constshaka::media::MediaHandlerinlineprotected
    DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) constshaka::media::MediaHandlerinlineprotected
    FlushAllDownstreams()shaka::media::MediaHandlerprotected
    FlushDownstream(size_t output_stream_index)shaka::media::MediaHandlerprotected
    Initialize()shaka::media::MediaHandler
    initialized() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    InitializeInternal() overrideshaka::media::Muxerinlineprotectedvirtual
    IsConnected()shaka::media::MediaHandlerinline
    MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandler
    Muxer(const MuxerOptions &options) (defined in shaka::media::Muxer)shaka::media::Muxerexplicit
    muxer_listener() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
    next_output_stream_index() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    num_input_streams() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    OnFlushRequest(size_t input_stream_index) overrideshaka::media::Muxerprotectedvirtual
    options() const (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
    output_handlers() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    Process(std::unique_ptr< StreamData > stream_data) overrideshaka::media::Muxerprotectedvirtual
    progress_listener() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
    set_clock(base::Clock *clock)shaka::media::Muxerinline
    SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandler
    SetMuxerListener(std::unique_ptr< MuxerListener > muxer_listener)shaka::media::Muxer
    SetProgressListener(std::unique_ptr< ProgressListener > progress_listener)shaka::media::Muxer
    streams() const (defined in shaka::media::Muxer)shaka::media::Muxerinline
    TextMuxer(const MuxerOptions &options) (defined in shaka::media::TextMuxer)shaka::media::TextMuxerexplicit
    TtmlMuxer(const MuxerOptions &options) (defined in shaka::media::ttml::TtmlMuxer)shaka::media::ttml::TtmlMuxerexplicit
    ValidateOutputStreamIndex(size_t stream_index) constshaka::media::MediaHandlerprotectedvirtual
    ~MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandlervirtual
    ~Muxer() (defined in shaka::media::Muxer)shaka::media::Muxervirtual
    ~TextMuxer() override (defined in shaka::media::TextMuxer)shaka::media::TextMuxer
    ~TtmlMuxer() override (defined in shaka::media::ttml::TtmlMuxer)shaka::media::ttml::TtmlMuxer
    + + + + diff --git a/docs/d4/d70/structshaka_1_1SegmentInfo-members.html b/docs/d4/d70/structshaka_1_1SegmentInfo-members.html index 05a18c465d..cfa0b54751 100644 --- a/docs/d4/d70/structshaka_1_1SegmentInfo-members.html +++ b/docs/d4/d70/structshaka_1_1SegmentInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/d87/nalu__reader_8h_source.html b/docs/d4/d87/nalu__reader_8h_source.html index 24b396c68f..3ddfe742be 100644 --- a/docs/d4/d87/nalu__reader_8h_source.html +++ b/docs/d4/d87/nalu__reader_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/nalu_reader.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    nalu_reader.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_NALU_READER_H_
    8 #define PACKAGER_MEDIA_CODECS_NALU_READER_H_
    9 
    10 #include <stdint.h>
    11 #include <stdlib.h>
    12 
    13 #include "packager/base/compiler_specific.h"
    14 #include "packager/base/macros.h"
    15 #include "packager/media/base/decrypt_config.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    20 // Used as the |nalu_length_size| argument to NaluReader to indicate to use
    21 // AnnexB byte streams. An AnnexB byte stream starts with 3 or 4 byte start
    22 // codes instead of a fixed size NAL unit length.
    23 const uint8_t kIsAnnexbByteStream = 0;
    24 
    27 class Nalu {
    28  public:
    29  enum H264NaluType {
    30  H264_Unspecified = 0,
    31  H264_NonIDRSlice = 1,
    32  H264_IDRSlice = 5,
    33  H264_SEIMessage = 6,
    34  H264_SPS = 7,
    35  H264_PPS = 8,
    36  H264_AUD = 9,
    37  H264_EOSeq = 10,
    38  H264_FillerData = 12,
    39  H264_SPSExtension = 13,
    40  H264_PrefixNALUnit = 14,
    41  H264_SubsetSPS = 15,
    42  H264_DepthParameterSet = 16,
    43  H264_Reserved17 = 17,
    44  H264_Reserved18 = 18,
    45  H264_CodedSliceExtension = 20,
    46  H264_Reserved22 = 22,
    47  };
    48  enum H265NaluType {
    49  H265_TRAIL_N = 0,
    50  H265_TRAIL_R = 1,
    51  H265_TSA_N = 2,
    52  H265_TSA_R = 3,
    53  H265_STSA_N = 4,
    54  H265_STSA_R = 5,
    55  H265_RASL_R = 9,
    56 
    57  H265_RSV_VCL_N10 = 10,
    58  H265_RSV_VCL_R15 = 15,
    59 
    60  H265_BLA_W_LP = 16,
    61  H265_IDR_W_RADL = 19,
    62  H265_IDR_N_LP = 20,
    63  H265_CRA_NUT = 21,
    64 
    65  H265_RSV_IRAP_VCL22 = 22,
    66  H265_RSV_IRAP_VCL23 = 23,
    67  H265_RSV_VCL31 = 31,
    68 
    69  H265_VPS = 32,
    70  H265_SPS = 33,
    71  H265_PPS = 34,
    72  H265_AUD = 35,
    73 
    74  H265_EOS = 36,
    75  H265_EOB = 37,
    76  H265_FD = 38,
    77 
    78  H265_PREFIX_SEI = 39,
    79 
    80  H265_RSV_NVCL41 = 41,
    81  H265_RSV_NVCL44 = 44,
    82  H265_UNSPEC48 = 48,
    83  H265_UNSPEC55 = 55,
    84  };
    85  enum CodecType {
    86  kH264,
    87  kH265,
    88  };
    89 
    90  Nalu();
    91 
    92  bool Initialize(CodecType type,
    93  const uint8_t* data,
    94  uint64_t size) WARN_UNUSED_RESULT;
    95 
    97  const uint8_t* data() const { return data_; }
    98 
    100  uint64_t header_size() const { return header_size_; }
    102  uint64_t payload_size() const { return payload_size_; }
    103 
    104  // H.264 Specific:
    105  int ref_idc() const { return ref_idc_; }
    106 
    107  // H.265 Specific:
    108  int nuh_layer_id() const { return nuh_layer_id_; }
    109  int nuh_temporal_id() const { return nuh_temporal_id_; }
    110 
    113  int type() const { return type_; }
    114  bool is_aud() const { return is_aud_; }
    115  bool is_vcl() const { return is_vcl_; }
    117  bool is_video_slice() const { return is_video_slice_; }
    118  bool can_start_access_unit() const { return can_start_access_unit_; }
    119 
    120  private:
    121  bool InitializeFromH264(const uint8_t* data, uint64_t size);
    122  bool InitializeFromH265(const uint8_t* data, uint64_t size);
    123 
    124  // A pointer to the NALU (i.e. points to the header). This pointer is not
    125  // owned by this instance.
    126  const uint8_t* data_ = nullptr;
    127  // NALU header size (e.g. 1 byte for H.264). Note that it does not include
    128  // header extension data in some NAL units.
    129  uint64_t header_size_ = 0;
    130  // Size of data after the header.
    131  uint64_t payload_size_ = 0;
    132 
    133  int ref_idc_ = 0;
    134  int nuh_layer_id_ = 0;
    135  int nuh_temporal_id_ = 0;
    136  int type_ = 0;
    137  bool is_aud_ = false;
    138  bool is_vcl_ = false;
    139  bool is_video_slice_ = false;
    140  bool can_start_access_unit_ = false;
    141 
    142  // Don't use DISALLOW_COPY_AND_ASSIGN since it is just numbers and a pointer
    143  // it does not own. This allows Nalus to be stored in a vector.
    144 };
    145 
    149 class NaluReader {
    150  public:
    151  enum Result {
    152  kOk,
    153  kInvalidStream, // error in stream
    154  kEOStream, // end of stream
    155  };
    156 
    160  NaluReader(Nalu::CodecType type,
    161  uint8_t nal_length_size,
    162  const uint8_t* stream,
    163  uint64_t stream_size);
    164 
    175  NaluReader(Nalu::CodecType type,
    176  uint8_t nal_length_size,
    177  const uint8_t* stream,
    178  uint64_t stream_size,
    179  const std::vector<SubsampleEntry>& subsamples);
    180  ~NaluReader();
    181 
    182  // Find offset from start of data to next NALU start code
    183  // and size of found start code (3 or 4 bytes).
    184  // If no start code is found, offset is pointing to the first unprocessed byte
    185  // (i.e. the first byte that was not considered as a possible start of a start
    186  // code) and |*start_code_size| is set to 0.
    187  // Postconditions:
    188  // - |*offset| is between 0 and |data_size| included.
    189  // It is strictly less than |data_size| if |data_size| > 0.
    190  // - |*start_code_size| is either 0, 3 or 4.
    191  static bool FindStartCode(const uint8_t* data,
    192  uint64_t data_size,
    193  uint64_t* offset,
    194  uint8_t* start_code_size);
    195 
    204  static bool FindStartCodeInClearRange(
    205  const uint8_t* data,
    206  uint64_t data_size,
    207  uint64_t* offset,
    208  uint8_t* start_code_size,
    209  const std::vector<SubsampleEntry>& subsamples);
    210 
    216  Result Advance(Nalu* nalu);
    217 
    219  bool StartsWithStartCode();
    220 
    221  private:
    222  enum Format {
    223  kAnnexbByteStreamFormat,
    224  kNalUnitStreamFormat
    225  };
    226 
    227  // Move the stream pointer to the beginning of the next NALU,
    228  // i.e. pointing at the next start code.
    229  // Return true if a NALU has been found.
    230  // If a NALU is found:
    231  // - its size in bytes is returned in |*nalu_size| and includes
    232  // the start code as well as the trailing zero bits.
    233  // - the size in bytes of the start code is returned in |*start_code_size|.
    234  bool LocateNaluByStartCode(uint64_t* nalu_size, uint8_t* start_code_size);
    235 
    236  // Pointer to the current NALU in the stream.
    237  const uint8_t* stream_;
    238  // The remaining size of the stream.
    239  uint64_t stream_size_;
    240  // The type of NALU being read.
    241  Nalu::CodecType nalu_type_;
    242  // The number of bytes the prefix length is; only valid if format is
    243  // kAnnexbByteStreamFormat.
    244  uint8_t nalu_length_size_;
    245  // The format of the stream.
    246  Format format_;
    247 
    248  // subsamples left in stream_.
    249  std::vector<SubsampleEntry> subsamples_;
    250 
    251  DISALLOW_COPY_AND_ASSIGN(NaluReader);
    252 };
    253 
    254 } // namespace media
    255 } // namespace shaka
    256 
    257 #endif // PACKAGER_MEDIA_CODECS_NALU_READER_H_
    bool is_video_slice() const
    Slice data partition NALs are not considered as slice NALs.
    Definition: nalu_reader.h:117
    -
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    - -
    All the methods that are virtual are virtual for mocking.
    -
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    - -
    int type() const
    Definition: nalu_reader.h:113
    -
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_NALU_READER_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_NALU_READER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <stdlib.h>
    +
    12 
    +
    13 #include "packager/base/compiler_specific.h"
    +
    14 #include "packager/base/macros.h"
    +
    15 #include "packager/media/base/decrypt_config.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    +
    20 // Used as the |nalu_length_size| argument to NaluReader to indicate to use
    +
    21 // AnnexB byte streams. An AnnexB byte stream starts with 3 or 4 byte start
    +
    22 // codes instead of a fixed size NAL unit length.
    +
    23 const uint8_t kIsAnnexbByteStream = 0;
    +
    24 
    +
    27 class Nalu {
    +
    28  public:
    +
    29  enum H264NaluType {
    +
    30  H264_Unspecified = 0,
    +
    31  H264_NonIDRSlice = 1,
    +
    32  H264_IDRSlice = 5,
    +
    33  H264_SEIMessage = 6,
    +
    34  H264_SPS = 7,
    +
    35  H264_PPS = 8,
    +
    36  H264_AUD = 9,
    +
    37  H264_EOSeq = 10,
    +
    38  H264_FillerData = 12,
    +
    39  H264_SPSExtension = 13,
    +
    40  H264_PrefixNALUnit = 14,
    +
    41  H264_SubsetSPS = 15,
    +
    42  H264_DepthParameterSet = 16,
    +
    43  H264_Reserved17 = 17,
    +
    44  H264_Reserved18 = 18,
    +
    45  H264_CodedSliceExtension = 20,
    +
    46  H264_Reserved22 = 22,
    +
    47  };
    +
    48  enum H265NaluType {
    +
    49  H265_TRAIL_N = 0,
    +
    50  H265_TRAIL_R = 1,
    +
    51  H265_TSA_N = 2,
    +
    52  H265_TSA_R = 3,
    +
    53  H265_STSA_N = 4,
    +
    54  H265_STSA_R = 5,
    +
    55  H265_RASL_R = 9,
    +
    56 
    +
    57  H265_RSV_VCL_N10 = 10,
    +
    58  H265_RSV_VCL_R15 = 15,
    +
    59 
    +
    60  H265_BLA_W_LP = 16,
    +
    61  H265_IDR_W_RADL = 19,
    +
    62  H265_IDR_N_LP = 20,
    +
    63  H265_CRA_NUT = 21,
    +
    64 
    +
    65  H265_RSV_IRAP_VCL22 = 22,
    +
    66  H265_RSV_IRAP_VCL23 = 23,
    +
    67  H265_RSV_VCL31 = 31,
    +
    68 
    +
    69  H265_VPS = 32,
    +
    70  H265_SPS = 33,
    +
    71  H265_PPS = 34,
    +
    72  H265_AUD = 35,
    +
    73 
    +
    74  H265_EOS = 36,
    +
    75  H265_EOB = 37,
    +
    76  H265_FD = 38,
    +
    77 
    +
    78  H265_PREFIX_SEI = 39,
    +
    79 
    +
    80  H265_RSV_NVCL41 = 41,
    +
    81  H265_RSV_NVCL44 = 44,
    +
    82  H265_UNSPEC48 = 48,
    +
    83  H265_UNSPEC55 = 55,
    +
    84  };
    +
    85  enum CodecType {
    +
    86  kH264,
    +
    87  kH265,
    +
    88  };
    +
    89 
    +
    90  Nalu();
    +
    91 
    +
    92  bool Initialize(CodecType type,
    +
    93  const uint8_t* data,
    +
    94  uint64_t size) WARN_UNUSED_RESULT;
    +
    95 
    +
    97  const uint8_t* data() const { return data_; }
    +
    98 
    +
    100  uint64_t header_size() const { return header_size_; }
    +
    102  uint64_t payload_size() const { return payload_size_; }
    +
    103 
    +
    104  // H.264 Specific:
    +
    105  int ref_idc() const { return ref_idc_; }
    +
    106 
    +
    107  // H.265 Specific:
    +
    108  int nuh_layer_id() const { return nuh_layer_id_; }
    +
    109  int nuh_temporal_id() const { return nuh_temporal_id_; }
    +
    110 
    +
    113  int type() const { return type_; }
    +
    114  bool is_aud() const { return is_aud_; }
    +
    115  bool is_vcl() const { return is_vcl_; }
    +
    117  bool is_video_slice() const { return is_video_slice_; }
    +
    118  bool can_start_access_unit() const { return can_start_access_unit_; }
    +
    119 
    +
    120  private:
    +
    121  bool InitializeFromH264(const uint8_t* data, uint64_t size);
    +
    122  bool InitializeFromH265(const uint8_t* data, uint64_t size);
    +
    123 
    +
    124  // A pointer to the NALU (i.e. points to the header). This pointer is not
    +
    125  // owned by this instance.
    +
    126  const uint8_t* data_ = nullptr;
    +
    127  // NALU header size (e.g. 1 byte for H.264). Note that it does not include
    +
    128  // header extension data in some NAL units.
    +
    129  uint64_t header_size_ = 0;
    +
    130  // Size of data after the header.
    +
    131  uint64_t payload_size_ = 0;
    +
    132 
    +
    133  int ref_idc_ = 0;
    +
    134  int nuh_layer_id_ = 0;
    +
    135  int nuh_temporal_id_ = 0;
    +
    136  int type_ = 0;
    +
    137  bool is_aud_ = false;
    +
    138  bool is_vcl_ = false;
    +
    139  bool is_video_slice_ = false;
    +
    140  bool can_start_access_unit_ = false;
    +
    141 
    +
    142  // Don't use DISALLOW_COPY_AND_ASSIGN since it is just numbers and a pointer
    +
    143  // it does not own. This allows Nalus to be stored in a vector.
    +
    144 };
    +
    145 
    +
    149 class NaluReader {
    +
    150  public:
    +
    151  enum Result {
    +
    152  kOk,
    +
    153  kInvalidStream, // error in stream
    +
    154  kEOStream, // end of stream
    +
    155  };
    +
    156 
    +
    160  NaluReader(Nalu::CodecType type,
    +
    161  uint8_t nal_length_size,
    +
    162  const uint8_t* stream,
    +
    163  uint64_t stream_size);
    +
    164 
    +
    175  NaluReader(Nalu::CodecType type,
    +
    176  uint8_t nal_length_size,
    +
    177  const uint8_t* stream,
    +
    178  uint64_t stream_size,
    +
    179  const std::vector<SubsampleEntry>& subsamples);
    +
    180  ~NaluReader();
    +
    181 
    +
    182  // Find offset from start of data to next NALU start code
    +
    183  // and size of found start code (3 or 4 bytes).
    +
    184  // If no start code is found, offset is pointing to the first unprocessed byte
    +
    185  // (i.e. the first byte that was not considered as a possible start of a start
    +
    186  // code) and |*start_code_size| is set to 0.
    +
    187  // Postconditions:
    +
    188  // - |*offset| is between 0 and |data_size| included.
    +
    189  // It is strictly less than |data_size| if |data_size| > 0.
    +
    190  // - |*start_code_size| is either 0, 3 or 4.
    +
    191  static bool FindStartCode(const uint8_t* data,
    +
    192  uint64_t data_size,
    +
    193  uint64_t* offset,
    +
    194  uint8_t* start_code_size);
    +
    195 
    +
    204  static bool FindStartCodeInClearRange(
    +
    205  const uint8_t* data,
    +
    206  uint64_t data_size,
    +
    207  uint64_t* offset,
    +
    208  uint8_t* start_code_size,
    +
    209  const std::vector<SubsampleEntry>& subsamples);
    +
    210 
    +
    216  Result Advance(Nalu* nalu);
    +
    217 
    +
    219  bool StartsWithStartCode();
    +
    220 
    +
    221  private:
    +
    222  enum Format {
    +
    223  kAnnexbByteStreamFormat,
    +
    224  kNalUnitStreamFormat
    +
    225  };
    +
    226 
    +
    227  // Move the stream pointer to the beginning of the next NALU,
    +
    228  // i.e. pointing at the next start code.
    +
    229  // Return true if a NALU has been found.
    +
    230  // If a NALU is found:
    +
    231  // - its size in bytes is returned in |*nalu_size| and includes
    +
    232  // the start code as well as the trailing zero bits.
    +
    233  // - the size in bytes of the start code is returned in |*start_code_size|.
    +
    234  bool LocateNaluByStartCode(uint64_t* nalu_size, uint8_t* start_code_size);
    +
    235 
    +
    236  // Pointer to the current NALU in the stream.
    +
    237  const uint8_t* stream_;
    +
    238  // The remaining size of the stream.
    +
    239  uint64_t stream_size_;
    +
    240  // The type of NALU being read.
    +
    241  Nalu::CodecType nalu_type_;
    +
    242  // The number of bytes the prefix length is; only valid if format is
    +
    243  // kAnnexbByteStreamFormat.
    +
    244  uint8_t nalu_length_size_;
    +
    245  // The format of the stream.
    +
    246  Format format_;
    +
    247 
    +
    248  // subsamples left in stream_.
    +
    249  std::vector<SubsampleEntry> subsamples_;
    +
    250 
    +
    251  DISALLOW_COPY_AND_ASSIGN(NaluReader);
    +
    252 };
    +
    253 
    +
    254 } // namespace media
    +
    255 } // namespace shaka
    +
    256 
    +
    257 #endif // PACKAGER_MEDIA_CODECS_NALU_READER_H_
    + +
    NaluReader(Nalu::CodecType type, uint8_t nal_length_size, const uint8_t *stream, uint64_t stream_size)
    Definition: nalu_reader.cc:214
    + +
    static bool FindStartCodeInClearRange(const uint8_t *data, uint64_t data_size, uint64_t *offset, uint8_t *start_code_size, const std::vector< SubsampleEntry > &subsamples)
    Definition: nalu_reader.cc:346
    +
    Result Advance(Nalu *nalu)
    Definition: nalu_reader.cc:241
    + +
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    +
    bool is_video_slice() const
    Slice data partition NALs are not considered as slice NALs.
    Definition: nalu_reader.h:117
    +
    int type() const
    Definition: nalu_reader.h:113
    +
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    +
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/d87/text__sample_8cc_source.html b/docs/d4/d87/text__sample_8cc_source.html index cc1273addd..c69c9e9233 100644 --- a/docs/d4/d87/text__sample_8cc_source.html +++ b/docs/d4/d87/text__sample_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/text_sample.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    text_sample.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/text_sample.h"
    8 
    9 #include "packager/base/logging.h"
    10 
    11 namespace shaka {
    12 namespace media {
    13 
    14 int64_t TextSample::EndTime() const {
    15  return start_time_ + duration_;
    16 }
    17 
    18 void TextSample::SetTime(int64_t start_time, int64_t end_time) {
    19  DCHECK_GE(start_time, 0);
    20  DCHECK_GT(end_time, 0);
    21  DCHECK_LT(start_time, end_time);
    22  start_time_ = start_time;
    23  duration_ = end_time - start_time;
    24 }
    25 
    26 void TextSample::AppendStyle(const std::string& style) {
    27  if (settings_.length()) {
    28  settings_ += " ";
    29  }
    30  settings_ += style;
    31 }
    32 
    33 void TextSample::AppendPayload(const std::string& payload) {
    34  if (payload_.length()) {
    35  payload_ += "\n";
    36  }
    37  payload_ += payload;
    38 }
    39 
    40 } // namespace media
    41 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/text_sample.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 #include <functional>
    +
    11 
    +
    12 #include "packager/base/logging.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 bool TextFragment::is_empty() const {
    +
    18  return std::all_of(sub_fragments.begin(), sub_fragments.end(),
    +
    19  std::mem_fn(&TextFragment::is_empty)) &&
    +
    20  body.empty() && image.empty();
    +
    21 }
    +
    22 
    +
    23 TextSample::TextSample(const std::string& id,
    +
    24  int64_t start_time,
    +
    25  int64_t end_time,
    +
    26  const TextSettings& settings,
    +
    27  const TextFragment& body)
    +
    28  : id_(id),
    +
    29  start_time_(start_time),
    +
    30  duration_(end_time - start_time),
    +
    31  settings_(settings),
    +
    32  body_(body) {}
    +
    33 
    +
    34 int64_t TextSample::EndTime() const {
    +
    35  return start_time_ + duration_;
    +
    36 }
    +
    37 
    +
    38 } // namespace media
    +
    39 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    std::vector< uint8_t > image
    PNG image data.
    Definition: text_sample.h:109
    diff --git a/docs/d4/d8a/classshaka_1_1media_1_1HEVCDecoderConfigurationRecord.html b/docs/d4/d8a/classshaka_1_1media_1_1HEVCDecoderConfigurationRecord.html index 702c4faee6..face9fe40f 100644 --- a/docs/d4/d8a/classshaka_1_1media_1_1HEVCDecoderConfigurationRecord.html +++ b/docs/d4/d8a/classshaka_1_1media_1_1HEVCDecoderConfigurationRecord.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::HEVCDecoderConfigurationRecord Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::DecoderConfigurationRecord - -
    + + @@ -155,9 +158,7 @@ void 

    Public Member Functions

    diff --git a/docs/d4/d8c/classshaka_1_1BandwidthEstimator-members.html b/docs/d4/d8c/classshaka_1_1BandwidthEstimator-members.html index e257535add..67346ab6ac 100644 --- a/docs/d4/d8c/classshaka_1_1BandwidthEstimator-members.html +++ b/docs/d4/d8c/classshaka_1_1BandwidthEstimator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d4/d8d/structshaka_1_1media_1_1mp4_1_1EC3Specific.html b/docs/d4/d8d/structshaka_1_1media_1_1mp4_1_1EC3Specific.html index f23ac3a60f..30075f81ec 100644 --- a/docs/d4/d8d/structshaka_1_1media_1_1mp4_1_1EC3Specific.html +++ b/docs/d4/d8d/structshaka_1_1media_1_1mp4_1_1EC3Specific.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::EC3Specific Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -112,7 +115,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 330 of file box_definitions.h.

    +

    Definition at line 331 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -140,7 +143,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1746 of file box_definitions.cc.

    +

    Definition at line 1772 of file box_definitions.cc.

    @@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d4/d9b/classshaka_1_1media_1_1MediaHandlerTestBase.html b/docs/d4/d9b/classshaka_1_1media_1_1MediaHandlerTestBase.html index 999d0e0e7f..02e73cf0b3 100644 --- a/docs/d4/d9b/classshaka_1_1media_1_1MediaHandlerTestBase.html +++ b/docs/d4/d9b/classshaka_1_1media_1_1MediaHandlerTestBase.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MediaHandlerTestBase Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MediaHandlerGraphTestBase - -
    + + @@ -132,7 +135,7 @@ std::unique_ptr<

    Detailed Description

    -

    Definition at line 292 of file media_handler_test_base.h.

    +

    Definition at line 288 of file media_handler_test_base.h.


    The documentation for this class was generated from the following files:
    • packager/media/base/media_handler_test_base.h
    • packager/media/base/media_handler_test_base.cc
    • @@ -140,9 +143,7 @@ std::unique_ptr< diff --git a/docs/d4/d9b/classshaka_1_1media_1_1MediaHandlerTestBase.png b/docs/d4/d9b/classshaka_1_1media_1_1MediaHandlerTestBase.png index 8760b9fd0ad3b7d12a0f3212d737255a2193e5f4..33afdd3016350ed9de43504d41bb814cccb4deb3 100644 GIT binary patch delta 1054 zcmV+(1mXMS2)GH5TYm&cNklL2u5%4oZ#^ueaZx|-gefis_)ZBGT^yIQEe{g&iq(YRn_3Hj zP*uIuy#d?|;3IubRrOSNXTX;3s;c+sKTrays`n`YB!C2`b}7~ zS#Md#gTG^9y>qu19M%pF9M{uooCUbhy8r;qwT0D1*Nk2P;2Kt|mk3+{Sc09OuTHno zVs0rf4vfju-ZL`*P7DtKb$sG*jk!9kHp}e}z|6OS0L^s{VBK`_y!o_S@6*p+j|km= zHFo8-pt9$@GH z4S-q#drBPuY^O2Dw3;-P(wbcxHYMN!*c@5_b;^=3d)JaXuYt=Z=tR+;LZ1PBQg&w7 zhC>N>8PIjh<{L7Wz)AmnsRw*jQ%(t8bS2xQ;VV7h%%NKXzuyCf5;)F(AGCXTP1_#3 z_2nCSn|WUW^J}{O(vSCvb=42P0ssM&01`j~0EnvukN^@uDWwD!z^!@!L{@YFk4JC< z(E-fwADcjU0NDf+K$ETl80uFU^6fgx@+vpYeU1>K5gyl(4g&BH0Rufu}}8%)ujb+EZ^(L zOS9oMjsT6B1E4i*iq^9$BGSktjJzyw-%eQ;_SoCn^$fkuystp*+qMMO zkHY||?e(=-Lv YKP*126oz3FHWnTYm%dNklanb0FDN%s%AWM6OU!Ud~8SnM;ff(Q%0z&{&_tM zVEtO3y$)5?AJ*RjAZQ8HR=9tus{Xj1&wz6py99y)uy29=OF>ojNA(y0Rn@;i2_OL^ z09DnvN&pEU0hCfoU;#X;7eHi12k?3YClDRL`}t!N2oE5eU;;=00Fjjd03s^^07O=k z?E)izcv7X55?K_0xJm#CAOQfx)vo~b|9%nH+ibL~^T}UZ*nhc4Ob%-Y2ijPz=2d_j z{V4!IH;%A|=(^b_09?ar^$~#^09&x{|97XyY%{l%HwVUKwfD>nfD6M0pw2HG?lD(~ z)n@y70x;`+AV4>+0qlovo)4e)=yQ2JwMFQE?y)=X4Gm-aZ*Nzh>U>rxW_V}cWW_Cj zcEVX=Qv#01bWdZ=900vxSJ$4Mfj`K4| za5%I8>XId4&aNeQT?4mG(21hIg)sxhq#Vrd4W|9ZsxJm#CAOVPo#MJl$+6G6RNChw%CqJNAJ4f)OcZ_$51r`sE&Q<WuFVj3*_Q0AR_XQ>E`V&BJwpQ yfCTXG0uT}Twh}-BNB|-t9&z;suq?|GSpNael+U%`@iwji0000 + + + + + + +Shaka Packager SDK: shaka::media::TextFragmentStyle Struct Reference + + + + + + + + + +
      +
      +

    Protected Member Functions

    + + + + + +
    +
    Shaka Packager SDK +
    +
    + + + + + + + + + +
    +
    + + +
    + +
    + + + +
    + +
    +
    shaka::media::TextFragmentStyle Struct Reference
    +
    +
    + + + + + + + + +

    +Public Attributes

    +base::Optional< bool > underline
     
    +base::Optional< bool > bold
     
    +base::Optional< bool > italic
     
    +

    Detailed Description

    +
    +

    Definition at line 81 of file text_sample.h.

    +

    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/docs/d4/da6/classshaka_1_1media_1_1PlayReadyKeySource.html b/docs/d4/da6/classshaka_1_1media_1_1PlayReadyKeySource.html index 4b0ea34da8..70a36e927c 100644 --- a/docs/d4/da6/classshaka_1_1media_1_1PlayReadyKeySource.html +++ b/docs/d4/da6/classshaka_1_1media_1_1PlayReadyKeySource.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::PlayReadyKeySource Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::media::KeySource - -
    +shaka::media::KeySource + + - - - - + + - - - @@ -107,29 +104,19 @@ void  - - -

    Public Member Functions

     PlayReadyKeySource (const std::string &server_url, int protection_systems_flags, FourCC protection_scheme)
     
     PlayReadyKeySource (const std::string &server_url, const std::string &client_cert_file, const std::string &client_cert_private_key_file, const std::string &client_cert_private_key_password, int protection_systems_flags, FourCC protection_scheme)
     
     PlayReadyKeySource (const std::string &server_url, ProtectionSystem protection_systems)
     
    virtual Status FetchKeysWithProgramIdentifier (const std::string &program_identifier)
     
    -void SetCaFile (const std::string &ca_file)
     Sets the Certificate Authority file for validating self-signed certificates.
     
    KeySource implementation overrides.
    Status FetchKeys (EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
     
     
    Status GetCryptoPeriodKey (uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
     
    - Public Member Functions inherited from shaka::media::KeySource
    KeySource (int protection_systems_flags, FourCC protection_scheme)
     
    -

    Static Public Member Functions

    static std::unique_ptr< PlayReadyKeySourceCreateFromKeyAndKeyId (const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key)
     
    - - - -

    -Additional Inherited Members

    - Protected Member Functions inherited from shaka::media::KeySource
    Status UpdateProtectionSystemInfo (EncryptionKeyMap *encryption_key_map)
     

    Detailed Description

    A key source that uses PlayReady for encryption.

    Definition at line 20 of file playready_key_source.h.

    Constructor & Destructor Documentation

    - -

    ◆ PlayReadyKeySource() [1/2]

    + +

    ◆ PlayReadyKeySource()

    @@ -143,14 +130,8 @@ Additional Inherited Members - int  - protection_systems_flags, - - - - - FourCC  - protection_scheme  + ProtectionSystem  + protection_systems  @@ -159,82 +140,16 @@ Additional Inherited Members
    -

    Creates a new PlayReadyKeySource from the given packaging information.

    Parameters
    +

    Creates a new PlayReadyKeySource from the given packaging information.

    Parameters
    - - +
    server_urlPlayReady packaging server url.
    protection_systems_flagsis the flags indicating which PSSH should be included.
    protection_schemeis the Protection Scheme to be used for encryption. It needs to be signalled in Widevine PSSH. This argument can be ignored if Widevine PSSH is not generated.
    protection_systemsis the enum indicating which PSSH should be included.

    Definition at line 65 of file playready_key_source.cc.

    -
    -
    - -

    ◆ PlayReadyKeySource() [2/2]

    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    shaka::media::PlayReadyKeySource::PlayReadyKeySource (const std::string & server_url,
    const std::string & client_cert_file,
    const std::string & client_cert_private_key_file,
    const std::string & client_cert_private_key_password,
    int protection_systems_flags,
    FourCC protection_scheme 
    )
    -
    -

    Creates a new PlayReadyKeySource from the given packaging information.

    Parameters
    - - - - - - - -
    server_urlPlayReady packaging server url.
    client_cert_fileabsolute path to a client certificate.
    client_cert_private_key_fileabsolute path to the private file for the client certificate.
    client_cert_private_key_passwordpassword for the private key.
    protection_systems_flagsis the flags indicating which PSSH should be included.
    protection_schemeis the Protection Scheme to be used for encryption. It needs to be signalled in Widevine PSSH. This argument can be ignored if Widevine PSSH is not generated.
    -
    -
    - -

    Definition at line 79 of file playready_key_source.cc.

    -

    Member Function Documentation

    @@ -271,7 +186,7 @@ Additional Inherited Members
    -

    Creates a new PlayReadyKeySource from the given data. Returns null if the strings are invalid. Note: GetKey on the created key source will always return the same key for all track types.

    +

    Creates a new PlayReadyKeySource from the given data. Returns null if the strings are invalid. Note: GetKey on the created key source will always return the same key for all track types.

    @@ -319,7 +234,7 @@ Additional Inherited Members

    Implements shaka::media::KeySource.

    -

    Definition at line 200 of file playready_key_source.cc.

    +

    Definition at line 170 of file playready_key_source.cc.

    @@ -381,7 +296,7 @@ Additional Inherited Members

    Implements shaka::media::KeySource.

    -

    Definition at line 227 of file playready_key_source.cc.

    +

    Definition at line 197 of file playready_key_source.cc.

    @@ -429,7 +344,7 @@ Additional Inherited Members

    Implements shaka::media::KeySource.

    -

    Definition at line 206 of file playready_key_source.cc.

    +

    Definition at line 176 of file playready_key_source.cc.

    @@ -477,7 +392,7 @@ Additional Inherited Members

    Implements shaka::media::KeySource.

    -

    Definition at line 217 of file playready_key_source.cc.

    +

    Definition at line 187 of file playready_key_source.cc.

    @@ -488,9 +403,7 @@ Additional Inherited Members diff --git a/docs/d4/da7/segmenter__test__base_8cc_source.html b/docs/d4/da7/segmenter__test__base_8cc_source.html index 914be504b0..c923906994 100644 --- a/docs/d4/da7/segmenter__test__base_8cc_source.html +++ b/docs/d4/da7/segmenter__test__base_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/segmenter_test_base.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    segmenter_test_base.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/webm/segmenter_test_base.h"
    8 
    9 #include "packager/file/memory_file.h"
    10 #include "packager/media/formats/webm/webm_constants.h"
    11 #include "packager/version/version.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace {
    16 
    17 // The contents of a frame does not mater.
    18 const uint8_t kTestMediaSampleData[] = {0xde, 0xad, 0xbe, 0xef, 0x00};
    19 const uint8_t kTestMediaSampleSideData[] = {
    20  // First 8 bytes of side_data is the BlockAddID element in big endian.
    21  0x12, 0x34, 0x56, 0x78, 0x9a, 0x00, 0x00, 0x00,
    22  0x73, 0x69, 0x64, 0x65, 0x00};
    23 
    24 const int kTrackId = 1;
    25 const uint64_t kDurationInSeconds = 8;
    26 const Codec kCodec = kCodecVP8;
    27 const std::string kCodecString = "vp8";
    28 const std::string kLanguage = "en";
    29 const uint16_t kWidth = 100;
    30 const uint16_t kHeight = 100;
    31 const uint16_t kPixelWidth = 100;
    32 const uint16_t kPixelHeight = 100;
    33 const uint8_t kTransferCharacteristics = 0;
    34 const int16_t kTrickPlayFactor = 1;
    35 const uint8_t kNaluLengthSize = 0;
    36 
    37 } // namespace
    38 
    39 SegmentTestBase::SegmentTestBase() {}
    40 
    41 void SegmentTestBase::SetUp() {
    42  SetPackagerVersionForTesting("test");
    43 
    44  output_file_name_ = std::string(kMemoryFilePrefix) + "output-file.webm";
    45  cur_timestamp_ = 0;
    46 }
    47 
    48 void SegmentTestBase::TearDown() {
    50 }
    51 
    52 std::shared_ptr<MediaSample> SegmentTestBase::CreateSample(
    53  KeyFrameFlag key_frame_flag,
    54  uint64_t duration,
    55  SideDataFlag side_data_flag) {
    56  std::shared_ptr<MediaSample> sample;
    57  const bool is_key_frame = key_frame_flag == kKeyFrame;
    58  if (side_data_flag == kGenerateSideData) {
    59  sample = MediaSample::CopyFrom(
    60  kTestMediaSampleData, sizeof(kTestMediaSampleData),
    61  kTestMediaSampleSideData, sizeof(kTestMediaSampleSideData),
    62  is_key_frame);
    63  } else {
    64  sample = MediaSample::CopyFrom(kTestMediaSampleData,
    65  sizeof(kTestMediaSampleData), is_key_frame);
    66  }
    67  sample->set_dts(cur_timestamp_);
    68  sample->set_pts(cur_timestamp_);
    69  sample->set_duration(duration);
    70 
    71  cur_timestamp_ += duration;
    72  return sample;
    73 }
    74 
    76  MuxerOptions ret;
    77  ret.output_file_name = output_file_name_;
    78  // Use memory files for temp storage. Normally this would be a bad idea
    79  // since it wouldn't support large files, but for tests the files are small.
    80  ret.temp_dir = std::string(kMemoryFilePrefix) + "temp/";
    81  return ret;
    82 }
    83 
    85  uint32_t time_scale) const {
    86  return new VideoStreamInfo(
    87  kTrackId, time_scale, kDurationInSeconds * time_scale, kCodec,
    88  H26xStreamFormat::kUnSpecified, kCodecString, NULL, 0, kWidth, kHeight,
    89  kPixelWidth, kPixelHeight, kTransferCharacteristics, kTrickPlayFactor,
    90  kNaluLengthSize, kLanguage, false);
    91 }
    92 
    93 std::string SegmentTestBase::OutputFileName() const {
    94  return output_file_name_;
    95 }
    96 
    97 SegmentTestBase::ClusterParser::ClusterParser() {}
    98 
    99 SegmentTestBase::ClusterParser::~ClusterParser() {}
    100 
    101 void SegmentTestBase::ClusterParser::PopulateFromCluster(
    102  const std::string& file_name) {
    103  frame_timecodes_.clear();
    104  std::string file_contents;
    105  ASSERT_TRUE(File::ReadFileToString(file_name.c_str(), &file_contents));
    106 
    107  const uint8_t* data = reinterpret_cast<const uint8_t*>(file_contents.c_str());
    108  const size_t size = file_contents.size();
    109  WebMListParser cluster_parser(kWebMIdCluster, this);
    110  size_t position = 0;
    111  while (position < size) {
    112  int read = cluster_parser.Parse(data + position,
    113  static_cast<int>(size - position));
    114  ASSERT_LT(0, read);
    115 
    116  cluster_parser.Reset();
    117  position += read;
    118  }
    119 }
    120 
    121 void SegmentTestBase::ClusterParser::PopulateFromSegment(
    122  const std::string& file_name) {
    123  frame_timecodes_.clear();
    124  std::string file_contents;
    125  ASSERT_TRUE(File::ReadFileToString(file_name.c_str(), &file_contents));
    126 
    127  const uint8_t* data = reinterpret_cast<const uint8_t*>(file_contents.c_str());
    128  const size_t size = file_contents.size();
    129  WebMListParser header_parser(kWebMIdEBMLHeader, this);
    130  int offset = header_parser.Parse(data, static_cast<int>(size));
    131  ASSERT_LT(0, offset);
    132 
    133  WebMListParser segment_parser(kWebMIdSegment, this);
    134  ASSERT_LT(
    135  0, segment_parser.Parse(data + offset, static_cast<int>(size) - offset));
    136 }
    137 
    138 size_t SegmentTestBase::ClusterParser::GetFrameCountForCluster(
    139  size_t cluster_index) const {
    140  DCHECK_LT(cluster_index, frame_timecodes_.size());
    141  return frame_timecodes_[cluster_index].size();
    142 }
    143 
    144 int64_t SegmentTestBase::ClusterParser::GetFrameTimecode(
    145  size_t cluster_index,
    146  size_t frame_index) const {
    147  DCHECK_LT(cluster_index, frame_timecodes_.size());
    148  DCHECK_LT(frame_index, frame_timecodes_[cluster_index].size());
    149  return frame_timecodes_[cluster_index][frame_index];
    150 }
    151 
    152 size_t SegmentTestBase::ClusterParser::cluster_count() const {
    153  return frame_timecodes_.size();
    154 }
    155 
    156 WebMParserClient* SegmentTestBase::ClusterParser::OnListStart(int id) {
    157  if (id == kWebMIdCluster) {
    158  if (in_cluster_)
    159  return NULL;
    160 
    161  frame_timecodes_.emplace_back();
    162  cluster_timecode_ = -1;
    163  in_cluster_ = true;
    164  }
    165 
    166  return this;
    167 }
    168 
    169 bool SegmentTestBase::ClusterParser::OnListEnd(int id) {
    170  if (id == kWebMIdCluster) {
    171  if (!in_cluster_)
    172  return false;
    173  in_cluster_ = false;
    174  }
    175 
    176  return true;
    177 }
    178 
    179 bool SegmentTestBase::ClusterParser::OnUInt(int id, int64_t val) {
    180  if (id == kWebMIdTimecode)
    181  cluster_timecode_ = val;
    182  return true;
    183 }
    184 
    185 bool SegmentTestBase::ClusterParser::OnFloat(int id, double val) {
    186  return true;
    187 }
    188 
    189 bool SegmentTestBase::ClusterParser::OnBinary(int id,
    190  const uint8_t* data,
    191  int size) {
    192  if (in_cluster_ && (id == kWebMIdSimpleBlock || id == kWebMIdBlock)) {
    193  if (cluster_timecode_ == -1) {
    194  LOG(WARNING) << "Cluster timecode not yet available";
    195  return false;
    196  }
    197  int timecode = data[1] << 8 | data[2];
    198  frame_timecodes_.back().push_back(cluster_timecode_ + timecode);
    199  }
    200 
    201  return true;
    202 }
    203 
    204 bool SegmentTestBase::ClusterParser::OnString(int id, const std::string& str) {
    205  return true;
    206 }
    207 
    208 } // namespace media
    209 } // namespace shaka
    -
    static void DeleteAll()
    Definition: memory_file.cc:186
    - -
    static bool ReadFileToString(const char *file_name, std::string *contents)
    Definition: file.cc:216
    -
    VideoStreamInfo * CreateVideoStreamInfo(uint32_t time_scale) const
    Creates a video stream info object for testing.
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    -
    MuxerOptions CreateMuxerOptions() const
    Creates a Muxer options object for testing.
    -
    std::shared_ptr< MediaSample > CreateSample(KeyFrameFlag key_frame_flag, uint64_t duration, SideDataFlag side_data_flag)
    Creates a new media sample.
    -
    void Reset()
    Resets the state of the parser so it can start parsing a new list.
    Definition: webm_parser.cc:733
    -
    int Parse(const uint8_t *buf, int size)
    Definition: webm_parser.cc:738
    -
    std::string OutputFileName() const
    Gets the file name of the current output file.
    -
    std::string temp_dir
    Specify temporary directory for intermediate files.
    Definition: muxer_options.h:43
    -
    static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
    Definition: media_sample.cc:42
    -
    Holds video stream information.
    - +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webm/segmenter_test_base.h"
    +
    8 
    +
    9 #include "packager/file/memory_file.h"
    +
    10 #include "packager/media/formats/webm/webm_constants.h"
    +
    11 #include "packager/version/version.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace {
    +
    16 
    +
    17 // The contents of a frame does not mater.
    +
    18 const uint8_t kTestMediaSampleData[] = {0xde, 0xad, 0xbe, 0xef, 0x00};
    +
    19 const uint8_t kTestMediaSampleSideData[] = {
    +
    20  // First 8 bytes of side_data is the BlockAddID element in big endian.
    +
    21  0x12, 0x34, 0x56, 0x78, 0x9a, 0x00, 0x00, 0x00,
    +
    22  0x73, 0x69, 0x64, 0x65, 0x00};
    +
    23 
    +
    24 const int kTrackId = 1;
    +
    25 const uint64_t kDurationInSeconds = 8;
    +
    26 const Codec kCodec = kCodecVP8;
    +
    27 const std::string kCodecString = "vp8";
    +
    28 const std::string kLanguage = "en";
    +
    29 const uint16_t kWidth = 100;
    +
    30 const uint16_t kHeight = 100;
    +
    31 const uint16_t kPixelWidth = 100;
    +
    32 const uint16_t kPixelHeight = 100;
    +
    33 const uint8_t kTransferCharacteristics = 0;
    +
    34 const int16_t kTrickPlayFactor = 1;
    +
    35 const uint8_t kNaluLengthSize = 0;
    +
    36 
    +
    37 } // namespace
    +
    38 
    +
    39 SegmentTestBase::SegmentTestBase() {}
    +
    40 
    +
    41 void SegmentTestBase::SetUp() {
    +
    42  SetPackagerVersionForTesting("test");
    +
    43 
    +
    44  output_file_name_ = std::string(kMemoryFilePrefix) + "output-file.webm";
    +
    45  cur_timestamp_ = 0;
    +
    46 }
    +
    47 
    +
    48 void SegmentTestBase::TearDown() {
    + +
    50 }
    +
    51 
    +
    52 std::shared_ptr<MediaSample> SegmentTestBase::CreateSample(
    +
    53  KeyFrameFlag key_frame_flag,
    +
    54  uint64_t duration,
    +
    55  SideDataFlag side_data_flag) {
    +
    56  std::shared_ptr<MediaSample> sample;
    +
    57  const bool is_key_frame = key_frame_flag == kKeyFrame;
    +
    58  if (side_data_flag == kGenerateSideData) {
    +
    59  sample = MediaSample::CopyFrom(
    +
    60  kTestMediaSampleData, sizeof(kTestMediaSampleData),
    +
    61  kTestMediaSampleSideData, sizeof(kTestMediaSampleSideData),
    +
    62  is_key_frame);
    +
    63  } else {
    +
    64  sample = MediaSample::CopyFrom(kTestMediaSampleData,
    +
    65  sizeof(kTestMediaSampleData), is_key_frame);
    +
    66  }
    +
    67  sample->set_dts(cur_timestamp_);
    +
    68  sample->set_pts(cur_timestamp_);
    +
    69  sample->set_duration(duration);
    +
    70 
    +
    71  cur_timestamp_ += duration;
    +
    72  return sample;
    +
    73 }
    +
    74 
    + +
    76  MuxerOptions ret;
    +
    77  ret.output_file_name = output_file_name_;
    +
    78  // Use memory files for temp storage. Normally this would be a bad idea
    +
    79  // since it wouldn't support large files, but for tests the files are small.
    +
    80  ret.temp_dir = std::string(kMemoryFilePrefix) + "temp/";
    +
    81  return ret;
    +
    82 }
    +
    83 
    + +
    85  uint32_t time_scale) const {
    +
    86  return new VideoStreamInfo(
    +
    87  kTrackId, time_scale, kDurationInSeconds * time_scale, kCodec,
    +
    88  H26xStreamFormat::kUnSpecified, kCodecString, NULL, 0, kWidth, kHeight,
    +
    89  kPixelWidth, kPixelHeight, kTransferCharacteristics, kTrickPlayFactor,
    +
    90  kNaluLengthSize, kLanguage, false);
    +
    91 }
    +
    92 
    +
    93 std::string SegmentTestBase::OutputFileName() const {
    +
    94  return output_file_name_;
    +
    95 }
    +
    96 
    +
    97 SegmentTestBase::ClusterParser::ClusterParser() {}
    +
    98 
    +
    99 SegmentTestBase::ClusterParser::~ClusterParser() {}
    +
    100 
    +
    101 void SegmentTestBase::ClusterParser::PopulateFromCluster(
    +
    102  const std::string& file_name) {
    +
    103  frame_timecodes_.clear();
    +
    104  std::string file_contents;
    +
    105  ASSERT_TRUE(File::ReadFileToString(file_name.c_str(), &file_contents));
    +
    106 
    +
    107  const uint8_t* data = reinterpret_cast<const uint8_t*>(file_contents.c_str());
    +
    108  const size_t size = file_contents.size();
    +
    109  WebMListParser cluster_parser(kWebMIdCluster, this);
    +
    110  size_t position = 0;
    +
    111  while (position < size) {
    +
    112  int read = cluster_parser.Parse(data + position,
    +
    113  static_cast<int>(size - position));
    +
    114  ASSERT_LT(0, read);
    +
    115 
    +
    116  cluster_parser.Reset();
    +
    117  position += read;
    +
    118  }
    +
    119 }
    +
    120 
    +
    121 void SegmentTestBase::ClusterParser::PopulateFromSegment(
    +
    122  const std::string& file_name) {
    +
    123  frame_timecodes_.clear();
    +
    124  std::string file_contents;
    +
    125  ASSERT_TRUE(File::ReadFileToString(file_name.c_str(), &file_contents));
    +
    126 
    +
    127  const uint8_t* data = reinterpret_cast<const uint8_t*>(file_contents.c_str());
    +
    128  const size_t size = file_contents.size();
    +
    129  WebMListParser header_parser(kWebMIdEBMLHeader, this);
    +
    130  int offset = header_parser.Parse(data, static_cast<int>(size));
    +
    131  ASSERT_LT(0, offset);
    +
    132 
    +
    133  WebMListParser segment_parser(kWebMIdSegment, this);
    +
    134  ASSERT_LT(
    +
    135  0, segment_parser.Parse(data + offset, static_cast<int>(size) - offset));
    +
    136 }
    +
    137 
    +
    138 size_t SegmentTestBase::ClusterParser::GetFrameCountForCluster(
    +
    139  size_t cluster_index) const {
    +
    140  DCHECK_LT(cluster_index, frame_timecodes_.size());
    +
    141  return frame_timecodes_[cluster_index].size();
    +
    142 }
    +
    143 
    +
    144 int64_t SegmentTestBase::ClusterParser::GetFrameTimecode(
    +
    145  size_t cluster_index,
    +
    146  size_t frame_index) const {
    +
    147  DCHECK_LT(cluster_index, frame_timecodes_.size());
    +
    148  DCHECK_LT(frame_index, frame_timecodes_[cluster_index].size());
    +
    149  return frame_timecodes_[cluster_index][frame_index];
    +
    150 }
    +
    151 
    +
    152 size_t SegmentTestBase::ClusterParser::cluster_count() const {
    +
    153  return frame_timecodes_.size();
    +
    154 }
    +
    155 
    +
    156 WebMParserClient* SegmentTestBase::ClusterParser::OnListStart(int id) {
    +
    157  if (id == kWebMIdCluster) {
    +
    158  if (in_cluster_)
    +
    159  return NULL;
    +
    160 
    +
    161  frame_timecodes_.emplace_back();
    +
    162  cluster_timecode_ = -1;
    +
    163  in_cluster_ = true;
    +
    164  }
    +
    165 
    +
    166  return this;
    +
    167 }
    +
    168 
    +
    169 bool SegmentTestBase::ClusterParser::OnListEnd(int id) {
    +
    170  if (id == kWebMIdCluster) {
    +
    171  if (!in_cluster_)
    +
    172  return false;
    +
    173  in_cluster_ = false;
    +
    174  }
    +
    175 
    +
    176  return true;
    +
    177 }
    +
    178 
    +
    179 bool SegmentTestBase::ClusterParser::OnUInt(int id, int64_t val) {
    +
    180  if (id == kWebMIdTimecode)
    +
    181  cluster_timecode_ = val;
    +
    182  return true;
    +
    183 }
    +
    184 
    +
    185 bool SegmentTestBase::ClusterParser::OnFloat(int id, double val) {
    +
    186  return true;
    +
    187 }
    +
    188 
    +
    189 bool SegmentTestBase::ClusterParser::OnBinary(int id,
    +
    190  const uint8_t* data,
    +
    191  int size) {
    +
    192  if (in_cluster_ && (id == kWebMIdSimpleBlock || id == kWebMIdBlock)) {
    +
    193  if (cluster_timecode_ == -1) {
    +
    194  LOG(WARNING) << "Cluster timecode not yet available";
    +
    195  return false;
    +
    196  }
    +
    197  int timecode = data[1] << 8 | data[2];
    +
    198  frame_timecodes_.back().push_back(cluster_timecode_ + timecode);
    +
    199  }
    +
    200 
    +
    201  return true;
    +
    202 }
    +
    203 
    +
    204 bool SegmentTestBase::ClusterParser::OnString(int id, const std::string& str) {
    +
    205  return true;
    +
    206 }
    +
    207 
    +
    208 } // namespace media
    +
    209 } // namespace shaka
    +
    static bool ReadFileToString(const char *file_name, std::string *contents)
    Definition: file.cc:230
    +
    static void DeleteAll()
    Definition: memory_file.cc:186
    +
    static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
    Definition: media_sample.cc:42
    +
    MuxerOptions CreateMuxerOptions() const
    Creates a Muxer options object for testing.
    +
    std::string OutputFileName() const
    Gets the file name of the current output file.
    +
    VideoStreamInfo * CreateVideoStreamInfo(uint32_t time_scale) const
    Creates a video stream info object for testing.
    +
    std::shared_ptr< MediaSample > CreateSample(KeyFrameFlag key_frame_flag, uint64_t duration, SideDataFlag side_data_flag)
    Creates a new media sample.
    +
    Holds video stream information.
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    + +
    std::string temp_dir
    Specify temporary directory for intermediate files.
    Definition: muxer_options.h:43
    diff --git a/docs/d4/da9/subtitle__composer_8cc_source.html b/docs/d4/da9/subtitle__composer_8cc_source.html new file mode 100644 index 0000000000..a219012725 --- /dev/null +++ b/docs/d4/da9/subtitle__composer_8cc_source.html @@ -0,0 +1,333 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/dvb/subtitle_composer.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    subtitle_composer.cc
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/dvb/subtitle_composer.h"
    +
    8 
    +
    9 #include <png.h>
    +
    10 #include <string.h>
    +
    11 
    +
    12 #include "packager/base/logging.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 namespace {
    +
    18 
    +
    19 const uint16_t kDefaultWidth = 720;
    +
    20 const uint16_t kDefaultHeight = 576;
    +
    21 const RgbaColor kTransparent{0, 0, 0, 0};
    +
    22 
    +
    23 struct PngFreeHelper {
    +
    24  PngFreeHelper(png_structp* png, png_infop* info) : png(png), info(info) {}
    +
    25  ~PngFreeHelper() { png_destroy_write_struct(png, info); }
    +
    26 
    +
    27  png_structp* png;
    +
    28  png_infop* info;
    +
    29 };
    +
    30 
    +
    31 void PngWriteData(png_structp png, png_bytep data, png_size_t length) {
    +
    32  auto* output = reinterpret_cast<std::vector<uint8_t>*>(png_get_io_ptr(png));
    +
    33  output->insert(output->end(), data, data + length);
    +
    34 }
    +
    35 
    +
    36 void PngFlushData(png_structp png) {}
    +
    37 
    +
    38 bool IsTransparent(const RgbaColor* colors, uint16_t width, uint16_t height) {
    +
    39  for (size_t i = 0; i < static_cast<size_t>(width) * height; i++) {
    +
    40  if (colors[i].a != 0)
    +
    41  return false;
    +
    42  }
    +
    43  return true;
    +
    44 }
    +
    45 
    +
    46 bool GetImageData(const DvbImageBuilder* image,
    +
    47  std::vector<uint8_t>* data,
    +
    48  uint16_t* width,
    +
    49  uint16_t* height) {
    +
    50  // CAREFUL in this method since this uses long-jumps. A long-jump causes the
    +
    51  // execution to jump to another point *without executing returns*. This
    +
    52  // causes C++ objects to not get destroyed. This also causes the same code to
    +
    53  // be executed twice, so C++ objects can be initialized twice.
    +
    54  //
    +
    55  // So long as we don't create C++ objects after the long-jump point,
    +
    56  // everything should work fine. If we early-return after the long-jump, the
    +
    57  // destructors will still be called; if we long-jump, we won't call the
    +
    58  // constructors since we're past that point.
    +
    59  auto png =
    +
    60  png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
    +
    61  auto info = png_create_info_struct(png);
    +
    62  PngFreeHelper helper(&png, &info);
    +
    63  if (!png || !info) {
    +
    64  LOG(ERROR) << "Error creating libpng struct";
    +
    65  return false;
    +
    66  }
    +
    67  if (setjmp(png_jmpbuf(png))) {
    +
    68  // If any png_* functions fail, the code will jump back to here.
    +
    69  LOG(ERROR) << "Error writing PNG image";
    +
    70  return false;
    +
    71  }
    +
    72  png_set_write_fn(png, data, &PngWriteData, &PngFlushData);
    +
    73 
    +
    74  const RgbaColor* pixels;
    +
    75  if (!image->GetPixels(&pixels, width, height))
    +
    76  return false;
    +
    77  if (IsTransparent(pixels, *width, *height))
    +
    78  return true; // Skip empty/transparent images.
    +
    79  png_set_IHDR(png, info, *width, *height, 8, PNG_COLOR_TYPE_RGBA,
    +
    80  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
    +
    81  PNG_FILTER_TYPE_BASE);
    +
    82  png_write_info(png, info);
    +
    83 
    +
    84  const uint8_t* in_data = reinterpret_cast<const uint8_t*>(pixels);
    +
    85  for (size_t y = 0; y < *height; y++) {
    +
    86  size_t offset = image->max_width() * y * sizeof(RgbaColor);
    +
    87  png_write_row(png, in_data + offset);
    +
    88  }
    +
    89  png_write_end(png, nullptr);
    +
    90 
    +
    91  return true;
    +
    92 }
    +
    93 
    +
    94 } // namespace
    +
    95 
    +
    96 SubtitleComposer::SubtitleComposer()
    +
    97  : display_width_(kDefaultWidth), display_height_(kDefaultHeight) {}
    +
    98 
    +
    99 SubtitleComposer::~SubtitleComposer() {}
    +
    100 
    +
    101 void SubtitleComposer::SetDisplaySize(uint16_t width, uint16_t height) {
    +
    102  display_width_ = width;
    +
    103  display_height_ = height;
    +
    104 }
    +
    105 
    +
    106 bool SubtitleComposer::SetRegionInfo(uint8_t region_id,
    +
    107  uint8_t color_space_id,
    +
    108  uint16_t width,
    +
    109  uint16_t height) {
    +
    110  auto* region = &regions_[region_id];
    +
    111  if (region->x + width > display_width_ ||
    +
    112  region->y + height > display_height_) {
    +
    113  LOG(ERROR) << "DVB-sub region won't fit within display";
    +
    114  return false;
    +
    115  }
    +
    116  if (width == 0 || height == 0) {
    +
    117  LOG(ERROR) << "DVB-sub width/height cannot be 0";
    +
    118  return false;
    +
    119  }
    +
    120 
    +
    121  region->width = width;
    +
    122  region->height = height;
    +
    123  region->color_space = &color_spaces_[color_space_id];
    +
    124  return true;
    +
    125 }
    +
    126 
    +
    127 bool SubtitleComposer::SetRegionPosition(uint8_t region_id,
    +
    128  uint16_t x,
    +
    129  uint16_t y) {
    +
    130  auto* region = &regions_[region_id];
    +
    131  if (x + region->width > display_width_ ||
    +
    132  y + region->height > display_height_) {
    +
    133  LOG(ERROR) << "DVB-sub region won't fit within display";
    +
    134  return false;
    +
    135  }
    +
    136 
    +
    137  region->x = x;
    +
    138  region->y = y;
    +
    139  return true;
    +
    140 }
    +
    141 
    +
    142 bool SubtitleComposer::SetObjectInfo(uint16_t object_id,
    +
    143  uint8_t region_id,
    +
    144  uint16_t x,
    +
    145  uint16_t y,
    +
    146  int default_color_code) {
    +
    147  auto region = regions_.find(region_id);
    +
    148  if (region == regions_.end()) {
    +
    149  LOG(ERROR) << "Unknown DVB-sub region: " << (int)region_id
    +
    150  << ", in object: " << object_id;
    +
    151  return false;
    +
    152  }
    +
    153  if (x >= region->second.width || y >= region->second.height) {
    +
    154  LOG(ERROR) << "DVB-sub object is outside region: " << object_id;
    +
    155  return false;
    +
    156  }
    +
    157 
    +
    158  auto* object = &objects_[object_id];
    +
    159  object->region = &region->second;
    +
    160  object->default_color_code = default_color_code;
    +
    161  object->x = x;
    +
    162  object->y = y;
    +
    163  return true;
    +
    164 }
    +
    165 
    +
    166 DvbImageColorSpace* SubtitleComposer::GetColorSpace(uint8_t color_space_id) {
    +
    167  return &color_spaces_[color_space_id];
    +
    168 }
    +
    169 
    +
    170 DvbImageColorSpace* SubtitleComposer::GetColorSpaceForObject(
    +
    171  uint16_t object_id) {
    +
    172  auto info = objects_.find(object_id);
    +
    173  if (info == objects_.end()) {
    +
    174  LOG(ERROR) << "Unknown DVB-sub object: " << object_id;
    +
    175  return nullptr;
    +
    176  }
    +
    177  return info->second.region->color_space;
    +
    178 }
    +
    179 
    +
    180 DvbImageBuilder* SubtitleComposer::GetObjectImage(uint16_t object_id) {
    +
    181  auto it = images_.find(object_id);
    +
    182  if (it == images_.end()) {
    +
    183  auto info = objects_.find(object_id);
    +
    184  if (info == objects_.end()) {
    +
    185  LOG(ERROR) << "Unknown DVB-sub object: " << object_id;
    +
    186  return nullptr;
    +
    187  }
    +
    188 
    +
    189  auto color = info->second.default_color_code < 0
    +
    190  ? kTransparent
    +
    191  : info->second.region->color_space->GetColor(
    +
    192  BitDepth::k8Bit, info->second.default_color_code);
    +
    193  it = images_
    +
    194  .emplace(std::piecewise_construct, std::make_tuple(object_id),
    +
    195  std::make_tuple(
    +
    196  info->second.region->color_space, color,
    +
    197  info->second.region->width - info->second.region->x,
    +
    198  info->second.region->height - info->second.region->y))
    +
    199  .first;
    +
    200  }
    +
    201  return &it->second;
    +
    202 }
    +
    203 
    +
    204 bool SubtitleComposer::GetSamples(
    +
    205  int64_t start,
    +
    206  int64_t end,
    +
    207  std::vector<std::shared_ptr<TextSample>>* samples) const {
    +
    208  for (const auto& pair : objects_) {
    +
    209  auto it = images_.find(pair.first);
    +
    210  if (it == images_.end()) {
    +
    211  LOG(WARNING) << "DVB-sub object " << pair.first
    +
    212  << " doesn't include object data";
    +
    213  continue;
    +
    214  }
    +
    215 
    +
    216  uint16_t width, height;
    +
    217  std::vector<uint8_t> image_data;
    +
    218  if (!GetImageData(&it->second, &image_data, &width, &height))
    +
    219  return false;
    +
    220  if (image_data.empty()) {
    +
    221  VLOG(1) << "Skipping transparent object";
    +
    222  continue;
    +
    223  }
    +
    224  TextFragment body({}, image_data);
    +
    225  DCHECK_LE(width, display_width_);
    +
    226  DCHECK_LE(height, display_height_);
    +
    227 
    +
    228  TextSettings settings;
    +
    229  settings.position.emplace(
    +
    230  (pair.second.x + pair.second.region->x) * 100.0f / display_width_,
    +
    231  TextUnitType::kPercent);
    +
    232  settings.line.emplace(
    +
    233  (pair.second.y + pair.second.region->y) * 100.0f / display_height_,
    +
    234  TextUnitType::kPercent);
    +
    235  settings.width.emplace(width * 100.0f / display_width_,
    +
    236  TextUnitType::kPercent);
    +
    237  settings.height.emplace(height * 100.0f / display_height_,
    +
    238  TextUnitType::kPercent);
    +
    239 
    +
    240  samples->emplace_back(
    +
    241  std::make_shared<TextSample>("", start, end, settings, body));
    +
    242  }
    +
    243 
    +
    244  return true;
    +
    245 }
    +
    246 
    +
    247 void SubtitleComposer::ClearObjects() {
    +
    248  regions_.clear();
    +
    249  objects_.clear();
    +
    250  images_.clear();
    +
    251 }
    +
    252 
    +
    253 } // namespace media
    +
    254 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/d4/dad/structshaka_1_1media_1_1mp4_1_1SampleEncryption.html b/docs/d4/dad/structshaka_1_1media_1_1mp4_1_1SampleEncryption.html index dc8ec3af93..5f6289fc3c 100644 --- a/docs/d4/dad/structshaka_1_1media_1_1mp4_1_1SampleEncryption.html +++ b/docs/d4/dad/structshaka_1_1media_1_1mp4_1_1SampleEncryption.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleEncryption Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -142,7 +145,7 @@ Additional Inherited Members

    Public Types

    Detailed Description

    -

    Definition at line 105 of file box_definitions.h.

    +

    Definition at line 106 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -170,7 +173,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 312 of file box_definitions.cc.

    +

    Definition at line 324 of file box_definitions.cc.

    @@ -208,7 +211,7 @@ Additional Inherited Members
    Returns
    true on success, false otherwise.
    -

    Definition at line 367 of file box_definitions.cc.

    +

    Definition at line 379 of file box_definitions.cc.

    @@ -226,7 +229,7 @@ Additional Inherited Members

    We may not know iv_size before reading this box. In this case, we will store sample encryption data for parsing later when iv_size is known.

    -

    Definition at line 124 of file box_definitions.h.

    +

    Definition at line 125 of file box_definitions.h.

    @@ -237,9 +240,7 @@ Additional Inherited Members diff --git a/docs/d4/db1/structshaka_1_1media_1_1mp4_1_1CompactSampleSize-members.html b/docs/d4/db1/structshaka_1_1media_1_1mp4_1_1CompactSampleSize-members.html index 85a918fb5f..d2248cd4a4 100644 --- a/docs/d4/db1/structshaka_1_1media_1_1mp4_1_1CompactSampleSize-members.html +++ b/docs/d4/db1/structshaka_1_1media_1_1mp4_1_1CompactSampleSize-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/db2/cluster__builder_8h_source.html b/docs/d4/db2/cluster__builder_8h_source.html index b61a0cba5d..c80e5b65e9 100644 --- a/docs/d4/db2/cluster__builder_8h_source.html +++ b/docs/d4/db2/cluster__builder_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/cluster_builder.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    cluster_builder.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_CLUSTER_BUILDER_H_
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_CLUSTER_BUILDER_H_
    7 
    8 #include <stdint.h>
    9 #include <memory>
    10 
    11 #include "packager/base/macros.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 class Cluster {
    17  public:
    18  Cluster(std::unique_ptr<uint8_t[]> data, int size);
    19  ~Cluster();
    20 
    21  const uint8_t* data() const { return data_.get(); }
    22  int size() const { return size_; }
    23 
    24  private:
    25  std::unique_ptr<uint8_t[]> data_;
    26  int size_;
    27 
    28  DISALLOW_IMPLICIT_CONSTRUCTORS(Cluster);
    29 };
    30 
    32  public:
    34  ~ClusterBuilder();
    35 
    36  void SetClusterTimecode(int64_t cluster_timecode);
    37  void AddSimpleBlock(int track_num,
    38  int64_t timecode,
    39  int flags,
    40  const uint8_t* data,
    41  int size);
    42  void AddBlockGroup(int track_num,
    43  int64_t timecode,
    44  int duration,
    45  int flags,
    46  bool is_key_frame,
    47  const uint8_t* data,
    48  int size);
    49  void AddBlockGroupWithoutBlockDuration(int track_num,
    50  int64_t timecode,
    51  int flags,
    52  bool is_key_frame,
    53  const uint8_t* data,
    54  int size);
    55 
    56  std::unique_ptr<Cluster> Finish();
    57  std::unique_ptr<Cluster> FinishWithUnknownSize();
    58 
    59  private:
    60  void AddBlockGroupInternal(int track_num,
    61  int64_t timecode,
    62  bool include_block_duration,
    63  int duration,
    64  int flags,
    65  bool is_key_frame,
    66  const uint8_t* data,
    67  int size);
    68  void Reset();
    69  void ExtendBuffer(int bytes_needed);
    70  void UpdateUInt64(int offset, int64_t value);
    71  void WriteBlock(uint8_t* buf,
    72  int track_num,
    73  int64_t timecode,
    74  int flags,
    75  const uint8_t* data,
    76  int size);
    77 
    78  std::unique_ptr<uint8_t[]> buffer_;
    79  int buffer_size_;
    80  int bytes_used_;
    81  int64_t cluster_timecode_;
    82 
    83  DISALLOW_COPY_AND_ASSIGN(ClusterBuilder);
    84 };
    85 
    86 } // namespace media
    87 } // namespace shaka
    88 
    89 #endif // PACKAGER_MEDIA_FORMATS_WEBM_CLUSTER_BUILDER_H_
    -
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_CLUSTER_BUILDER_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_CLUSTER_BUILDER_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 #include <memory>
    +
    10 
    +
    11 #include "packager/base/macros.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 class Cluster {
    +
    17  public:
    +
    18  Cluster(std::unique_ptr<uint8_t[]> data, int size);
    +
    19  ~Cluster();
    +
    20 
    +
    21  const uint8_t* data() const { return data_.get(); }
    +
    22  int size() const { return size_; }
    +
    23 
    +
    24  private:
    +
    25  std::unique_ptr<uint8_t[]> data_;
    +
    26  int size_;
    +
    27 
    +
    28  DISALLOW_IMPLICIT_CONSTRUCTORS(Cluster);
    +
    29 };
    +
    30 
    + +
    32  public:
    + +
    34  ~ClusterBuilder();
    +
    35 
    +
    36  void SetClusterTimecode(int64_t cluster_timecode);
    +
    37  void AddSimpleBlock(int track_num,
    +
    38  int64_t timecode,
    +
    39  int flags,
    +
    40  const uint8_t* data,
    +
    41  int size);
    +
    42  void AddBlockGroup(int track_num,
    +
    43  int64_t timecode,
    +
    44  int duration,
    +
    45  int flags,
    +
    46  bool is_key_frame,
    +
    47  const uint8_t* data,
    +
    48  int size);
    +
    49  void AddBlockGroupWithoutBlockDuration(int track_num,
    +
    50  int64_t timecode,
    +
    51  int flags,
    +
    52  bool is_key_frame,
    +
    53  const uint8_t* data,
    +
    54  int size);
    +
    55 
    +
    56  std::unique_ptr<Cluster> Finish();
    +
    57  std::unique_ptr<Cluster> FinishWithUnknownSize();
    +
    58 
    +
    59  private:
    +
    60  void AddBlockGroupInternal(int track_num,
    +
    61  int64_t timecode,
    +
    62  bool include_block_duration,
    +
    63  int duration,
    +
    64  int flags,
    +
    65  bool is_key_frame,
    +
    66  const uint8_t* data,
    +
    67  int size);
    +
    68  void Reset();
    +
    69  void ExtendBuffer(int bytes_needed);
    +
    70  void UpdateUInt64(int offset, int64_t value);
    +
    71  void WriteBlock(uint8_t* buf,
    +
    72  int track_num,
    +
    73  int64_t timecode,
    +
    74  int flags,
    +
    75  const uint8_t* data,
    +
    76  int size);
    +
    77 
    +
    78  std::unique_ptr<uint8_t[]> buffer_;
    +
    79  int buffer_size_;
    +
    80  int bytes_used_;
    +
    81  int64_t cluster_timecode_;
    +
    82 
    +
    83  DISALLOW_COPY_AND_ASSIGN(ClusterBuilder);
    +
    84 };
    +
    85 
    +
    86 } // namespace media
    +
    87 } // namespace shaka
    +
    88 
    +
    89 #endif // PACKAGER_MEDIA_FORMATS_WEBM_CLUSTER_BUILDER_H_
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/db4/classshaka_1_1MpdNotifierFactory.html b/docs/d4/db4/classshaka_1_1MpdNotifierFactory.html index 234f12c445..9910dda351 100644 --- a/docs/d4/db4/classshaka_1_1MpdNotifierFactory.html +++ b/docs/d4/db4/classshaka_1_1MpdNotifierFactory.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MpdNotifierFactory Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d4/db9/structshaka_1_1media_1_1mp4_1_1MediaHeader.html b/docs/d4/db9/structshaka_1_1media_1_1mp4_1_1MediaHeader.html index 8ab39e06c1..26527a9183 100644 --- a/docs/d4/db9/structshaka_1_1media_1_1mp4_1_1MediaHeader.html +++ b/docs/d4/db9/structshaka_1_1media_1_1mp4_1_1MediaHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MediaHeader Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -133,7 +136,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 568 of file box_definitions.h.

    +

    Definition at line 581 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -161,7 +164,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1982 of file box_definitions.cc.

    +

    Definition at line 2042 of file box_definitions.cc.

    @@ -172,9 +175,7 @@ Additional Inherited Members diff --git a/docs/d4/dcb/classshaka_1_1UdpFile.html b/docs/d4/dcb/classshaka_1_1UdpFile.html index eb18bd556d..eb6a628941 100644 --- a/docs/d4/dcb/classshaka_1_1UdpFile.html +++ b/docs/d4/dcb/classshaka_1_1UdpFile.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::UdpFile Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -

    Implements UdpFile, which receives UDP unicast and multicast streams. +

    Implements UdpFile, which receives UDP unicast and multicast streams. More...

    #include <udp_file.h>

    @@ -81,9 +84,9 @@ Inheritance diagram for shaka::UdpFile:
    -shaka::File - -
    +shaka::File + + @@ -152,7 +155,7 @@ Additional Inherited Members

    Public Member Functions

     

    Detailed Description

    -

    Implements UdpFile, which receives UDP unicast and multicast streams.

    +

    Implements UdpFile, which receives UDP unicast and multicast streams.

    Definition at line 26 of file udp_file.h.

    Constructor & Destructor Documentation

    @@ -213,7 +216,7 @@ Additional Inherited Members
    -

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.
    +

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.

    Implements shaka::File.

    @@ -243,7 +246,7 @@ Additional Inherited Members
    -

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.
    +

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.

    Implements shaka::File.

    @@ -458,9 +461,7 @@ Additional Inherited Members
    diff --git a/docs/d4/dd3/bit__reader_8h_source.html b/docs/d4/dd3/bit__reader_8h_source.html index b1dd0b60d5..fd88ab5f91 100644 --- a/docs/d4/dd3/bit__reader_8h_source.html +++ b/docs/d4/dd3/bit__reader_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/bit_reader.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    bit_reader.h
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_BASE_BIT_READER_H_
    6 #define PACKAGER_MEDIA_BASE_BIT_READER_H_
    7 
    8 #include <stdint.h>
    9 #include <sys/types.h>
    10 
    11 #include "packager/base/logging.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    17 class BitReader {
    18  public:
    22  BitReader(const uint8_t* data, size_t size);
    23  ~BitReader();
    24 
    34  template <typename T>
    35  bool ReadBits(size_t num_bits, T* out) {
    36  DCHECK_LE(num_bits, sizeof(T) * 8);
    37  uint64_t temp;
    38  bool ret = ReadBitsInternal(num_bits, &temp);
    39  *out = static_cast<T>(temp);
    40  return ret;
    41  }
    42 
    43  // Explicit T=bool overload to make MSVC happy.
    44  bool ReadBits(size_t num_bits, bool* out) {
    45  DCHECK_EQ(num_bits, 1u);
    46  uint64_t temp;
    47  bool ret = ReadBitsInternal(num_bits, &temp);
    48  *out = temp != 0;
    49  return ret;
    50  }
    51 
    58  bool SkipBits(size_t num_bits);
    59 
    69  bool SkipBitsConditional(bool condition, size_t num_bits) {
    70  bool condition_read = true;
    71  if (!ReadBits(1, &condition_read))
    72  return false;
    73  return condition_read == condition ? SkipBits(num_bits) : true;
    74  }
    75 
    78  void SkipToNextByte();
    79 
    86  bool SkipBytes(size_t num_bytes);
    87 
    89  size_t bits_available() const {
    90  return 8 * bytes_left_ + num_remaining_bits_in_curr_byte_;
    91  }
    92 
    94  size_t bit_position() const { return 8 * initial_size_ - bits_available(); }
    95 
    96  private:
    97  // Help function used by ReadBits to avoid inlining the bit reading logic.
    98  bool ReadBitsInternal(size_t num_bits, uint64_t* out);
    99 
    100  // Advance to the next byte, loading it into curr_byte_.
    101  // If the num_remaining_bits_in_curr_byte_ is 0 after this function returns,
    102  // the stream has reached the end.
    103  void UpdateCurrByte();
    104 
    105  // Pointer to the next unread (not in curr_byte_) byte in the stream.
    106  const uint8_t* data_;
    107 
    108  // Initial size of the input data.
    109  size_t initial_size_;
    110 
    111  // Bytes left in the stream (without the curr_byte_).
    112  size_t bytes_left_;
    113 
    114  // Contents of the current byte; first unread bit starting at position
    115  // 8 - num_remaining_bits_in_curr_byte_ from MSB.
    116  uint8_t curr_byte_;
    117 
    118  // Number of bits remaining in curr_byte_
    119  size_t num_remaining_bits_in_curr_byte_;
    120 
    121  private:
    122  DISALLOW_COPY_AND_ASSIGN(BitReader);
    123 };
    124 
    125 } // namespace media
    126 } // namespace shaka
    127 
    128 #endif // PACKAGER_MEDIA_BASE_BIT_READER_H_
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    -
    A class to read bit streams.
    Definition: bit_reader.h:17
    -
    bool SkipBitsConditional(bool condition, size_t num_bits)
    Definition: bit_reader.h:69
    -
    All the methods that are virtual are virtual for mocking.
    -
    size_t bit_position() const
    Definition: bit_reader.h:94
    -
    bool SkipBits(size_t num_bits)
    Definition: bit_reader.cc:24
    - -
    BitReader(const uint8_t *data, size_t size)
    Definition: bit_reader.cc:12
    -
    bool SkipBytes(size_t num_bytes)
    Definition: bit_reader.cc:63
    -
    size_t bits_available() const
    Definition: bit_reader.h:89
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_BASE_BIT_READER_H_
    +
    6 #define PACKAGER_MEDIA_BASE_BIT_READER_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 #include <sys/types.h>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    17 class BitReader {
    +
    18  public:
    +
    22  BitReader(const uint8_t* data, size_t size);
    +
    23  ~BitReader();
    +
    24 
    +
    34  template <typename T>
    +
    35  bool ReadBits(size_t num_bits, T* out) {
    +
    36  DCHECK_LE(num_bits, sizeof(T) * 8);
    +
    37  uint64_t temp;
    +
    38  bool ret = ReadBitsInternal(num_bits, &temp);
    +
    39  *out = static_cast<T>(temp);
    +
    40  return ret;
    +
    41  }
    +
    42 
    +
    43  // Explicit T=bool overload to make MSVC happy.
    +
    44  bool ReadBits(size_t num_bits, bool* out) {
    +
    45  DCHECK_EQ(num_bits, 1u);
    +
    46  uint64_t temp;
    +
    47  bool ret = ReadBitsInternal(num_bits, &temp);
    +
    48  *out = temp != 0;
    +
    49  return ret;
    +
    50  }
    +
    51 
    +
    58  bool SkipBits(size_t num_bits);
    +
    59 
    +
    69  bool SkipBitsConditional(bool condition, size_t num_bits) {
    +
    70  bool condition_read = true;
    +
    71  if (!ReadBits(1, &condition_read))
    +
    72  return false;
    +
    73  return condition_read == condition ? SkipBits(num_bits) : true;
    +
    74  }
    +
    75 
    +
    78  void SkipToNextByte();
    +
    79 
    +
    86  bool SkipBytes(size_t num_bytes);
    +
    87 
    +
    89  size_t bits_available() const {
    +
    90  return 8 * bytes_left_ + num_remaining_bits_in_curr_byte_;
    +
    91  }
    +
    92 
    +
    94  size_t bit_position() const { return 8 * initial_size_ - bits_available(); }
    +
    95 
    +
    97  const uint8_t* current_byte_ptr() const { return data_ - 1; }
    +
    98 
    +
    99  private:
    +
    100  // Help function used by ReadBits to avoid inlining the bit reading logic.
    +
    101  bool ReadBitsInternal(size_t num_bits, uint64_t* out);
    +
    102 
    +
    103  // Advance to the next byte, loading it into curr_byte_.
    +
    104  // If the num_remaining_bits_in_curr_byte_ is 0 after this function returns,
    +
    105  // the stream has reached the end.
    +
    106  void UpdateCurrByte();
    +
    107 
    +
    108  // Pointer to the next unread (not in curr_byte_) byte in the stream.
    +
    109  const uint8_t* data_;
    +
    110 
    +
    111  // Initial size of the input data.
    +
    112  size_t initial_size_;
    +
    113 
    +
    114  // Bytes left in the stream (without the curr_byte_).
    +
    115  size_t bytes_left_;
    +
    116 
    +
    117  // Contents of the current byte; first unread bit starting at position
    +
    118  // 8 - num_remaining_bits_in_curr_byte_ from MSB.
    +
    119  uint8_t curr_byte_;
    +
    120 
    +
    121  // Number of bits remaining in curr_byte_
    +
    122  size_t num_remaining_bits_in_curr_byte_;
    +
    123 
    +
    124  private:
    +
    125  DISALLOW_COPY_AND_ASSIGN(BitReader);
    +
    126 };
    +
    127 
    +
    128 } // namespace media
    +
    129 } // namespace shaka
    +
    130 
    +
    131 #endif // PACKAGER_MEDIA_BASE_BIT_READER_H_
    +
    A class to read bit streams.
    Definition: bit_reader.h:17
    +
    size_t bit_position() const
    Definition: bit_reader.h:94
    +
    BitReader(const uint8_t *data, size_t size)
    Definition: bit_reader.cc:12
    +
    bool SkipBits(size_t num_bits)
    Definition: bit_reader.cc:24
    +
    bool SkipBytes(size_t num_bytes)
    Definition: bit_reader.cc:63
    +
    size_t bits_available() const
    Definition: bit_reader.h:89
    +
    bool SkipBitsConditional(bool condition, size_t num_bits)
    Definition: bit_reader.h:69
    + +
    const uint8_t * current_byte_ptr() const
    Definition: bit_reader.h:97
    +
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/dd4/structshaka_1_1media_1_1mp4_1_1FullBox-members.html b/docs/d4/dd4/structshaka_1_1media_1_1mp4_1_1FullBox-members.html index 044bf5599e..c2dd229611 100644 --- a/docs/d4/dd4/structshaka_1_1media_1_1mp4_1_1FullBox-members.html +++ b/docs/d4/dd4/structshaka_1_1media_1_1mp4_1_1FullBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d4/dd6/raw__key__source_8cc_source.html b/docs/d4/dd6/raw__key__source_8cc_source.html index 7ffcb8df66..c15f869084 100644 --- a/docs/d4/dd6/raw__key__source_8cc_source.html +++ b/docs/d4/dd6/raw__key__source_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/raw_key_source.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    raw_key_source.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/raw_key_source.h"
    8 
    9 #include <algorithm>
    10 #include "packager/base/logging.h"
    11 #include "packager/base/strings/string_number_conversions.h"
    12 #include "packager/media/base/key_source.h"
    13 #include "packager/status_macros.h"
    14 
    15 namespace {
    16 const char kEmptyDrmLabel[] = "";
    17 } // namespace
    18 
    19 namespace shaka {
    20 namespace media {
    21 
    22 RawKeySource::~RawKeySource() {}
    23 
    24 Status RawKeySource::FetchKeys(EmeInitDataType init_data_type,
    25  const std::vector<uint8_t>& init_data) {
    26  // Do nothing for raw key encryption/decryption.
    27  return Status::OK;
    28 }
    29 
    30 Status RawKeySource::GetKey(const std::string& stream_label,
    31  EncryptionKey* key) {
    32  DCHECK(key);
    33  // Try to find the key with label |stream_label|. If it is not available,
    34  // fall back to the default empty label if it is available.
    35  auto iter = encryption_key_map_.find(stream_label);
    36  if (iter == encryption_key_map_.end()) {
    37  iter = encryption_key_map_.find(kEmptyDrmLabel);
    38  if (iter == encryption_key_map_.end()) {
    39  return Status(error::NOT_FOUND,
    40  "Key for '" + stream_label + "' was not found.");
    41  }
    42  }
    43  *key = *iter->second;
    44  return Status::OK;
    45 }
    46 
    47 Status RawKeySource::GetKey(const std::vector<uint8_t>& key_id,
    48  EncryptionKey* key) {
    49  DCHECK(key);
    50  for (const auto& pair : encryption_key_map_) {
    51  if (pair.second->key_id == key_id) {
    52  *key = *pair.second;
    53  return Status::OK;
    54  }
    55  }
    56  return Status(error::INTERNAL_ERROR,
    57  "Key for key_id=" + base::HexEncode(&key_id[0], key_id.size()) +
    58  " was not found.");
    59 }
    60 
    61 Status RawKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
    62  uint32_t crypto_period_duration_in_seconds,
    63  const std::string& stream_label,
    64  EncryptionKey* key) {
    65  RETURN_IF_ERROR(GetKey(stream_label, key));
    66 
    67  // A naive key rotation algorithm is implemented here by left rotating the
    68  // key, key_id and pssh. Note that this implementation is only intended for
    69  // testing purpose. The actual key rotation algorithm can be much more
    70  // complicated.
    71  LOG(WARNING)
    72  << "This naive key rotation algorithm should not be used in production.";
    73  std::rotate(key->key_id.begin(),
    74  key->key_id.begin() + (crypto_period_index % key->key_id.size()),
    75  key->key_id.end());
    76  std::rotate(key->key.begin(),
    77  key->key.begin() + (crypto_period_index % key->key.size()),
    78  key->key.end());
    79 
    80  // Clear |key->key_system_info| to prepare for update. The original
    81  // |key_system_info| is saved as it may still be useful later.
    82  std::vector<ProtectionSystemSpecificInfo> original_key_system_info;
    83  key->key_system_info.swap(original_key_system_info);
    84 
    85  EncryptionKeyMap encryption_key_map;
    86  encryption_key_map[stream_label].reset(new EncryptionKey(*key));
    87  RETURN_IF_ERROR(UpdateProtectionSystemInfo(&encryption_key_map));
    88  key->key_system_info = encryption_key_map[stream_label]->key_system_info;
    89 
    90  // It is possible that the generated |key_system_info| is empty. This happens
    91  // when RawKeyParams.pssh is specified. Restore the original key system info
    92  // in this case.
    93  if (key->key_system_info.empty())
    94  key->key_system_info.swap(original_key_system_info);
    95 
    96  return Status::OK;
    97 }
    98 
    99 std::unique_ptr<RawKeySource> RawKeySource::Create(const RawKeyParams& raw_key,
    100  int protection_systems_flags,
    101  FourCC protection_scheme) {
    102  std::vector<ProtectionSystemSpecificInfo> key_system_info;
    103  bool pssh_provided = false;
    104  if (!raw_key.pssh.empty()) {
    105  pssh_provided = true;
    107  raw_key.pssh.data(), raw_key.pssh.size(), &key_system_info)) {
    108  LOG(ERROR) << "--pssh argument should be full PSSH boxes.";
    109  return std::unique_ptr<RawKeySource>();
    110  }
    111  }
    112 
    113  EncryptionKeyMap encryption_key_map;
    114  for (const auto& entry : raw_key.key_map) {
    115  const std::string& drm_label = entry.first;
    116  const RawKeyParams::KeyInfo& key_pair = entry.second;
    117 
    118  if (key_pair.key_id.size() != 16) {
    119  LOG(ERROR) << "Invalid key ID size '" << key_pair.key_id.size()
    120  << "', must be 16 bytes.";
    121  return std::unique_ptr<RawKeySource>();
    122  }
    123  if (key_pair.key.size() != 16) {
    124  // CENC only supports AES-128, i.e. 16 bytes.
    125  LOG(ERROR) << "Invalid key size '" << key_pair.key.size()
    126  << "', must be 16 bytes.";
    127  return std::unique_ptr<RawKeySource>();
    128  }
    129 
    130  std::unique_ptr<EncryptionKey> encryption_key(new EncryptionKey);
    131  encryption_key->key_id = key_pair.key_id;
    132  encryption_key->key = key_pair.key;
    133  encryption_key->iv = raw_key.iv;
    134  encryption_key->key_system_info = key_system_info;
    135  encryption_key_map[drm_label] = std::move(encryption_key);
    136  }
    137 
    138  // Generate common protection system if no other protection system is
    139  // specified.
    140  if (!pssh_provided && protection_systems_flags == NO_PROTECTION_SYSTEM_FLAG) {
    141  protection_systems_flags = COMMON_PROTECTION_SYSTEM_FLAG;
    142  }
    143 
    144  return std::unique_ptr<RawKeySource>(
    145  new RawKeySource(std::move(encryption_key_map), protection_systems_flags,
    146  protection_scheme));
    147 }
    148 
    149 RawKeySource::RawKeySource()
    150  : KeySource(NO_PROTECTION_SYSTEM_FLAG, FOURCC_NULL) {}
    151 
    152 RawKeySource::RawKeySource(EncryptionKeyMap&& encryption_key_map,
    153  int protection_systems_flags,
    154  FourCC protection_scheme)
    155  : KeySource(protection_systems_flags, protection_scheme),
    156  encryption_key_map_(std::move(encryption_key_map)) {
    157  UpdateProtectionSystemInfo(&encryption_key_map_);
    158 }
    159 
    160 } // namespace media
    161 } // namespace shaka
    static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key, int protection_system_flags, FourCC protection_scheme)
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    Status UpdateProtectionSystemInfo(EncryptionKeyMap *encryption_key_map)
    Definition: key_source.cc:48
    -
    Raw key encryption/decryption parameters, i.e. with key parameters provided.
    Definition: crypto_params.h:86
    -
    std::map< StreamLabel, KeyInfo > key_map
    - -
    std::vector< uint8_t > iv
    Definition: crypto_params.h:90
    -
    A key source that uses raw keys for encryption.
    -
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    -
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    std::vector< uint8_t > pssh
    Definition: crypto_params.h:94
    -
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    -
    static bool ParseBoxes(const uint8_t *data, size_t data_size, std::vector< ProtectionSystemSpecificInfo > *pssh_boxes)
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/raw_key_source.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 #include "packager/base/logging.h"
    +
    11 #include "packager/base/strings/string_number_conversions.h"
    +
    12 #include "packager/media/base/key_source.h"
    +
    13 #include "packager/status_macros.h"
    +
    14 
    +
    15 namespace {
    +
    16 const char kEmptyDrmLabel[] = "";
    +
    17 } // namespace
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 
    +
    22 RawKeySource::~RawKeySource() {}
    +
    23 
    +
    24 Status RawKeySource::FetchKeys(EmeInitDataType init_data_type,
    +
    25  const std::vector<uint8_t>& init_data) {
    +
    26  // Do nothing for raw key encryption/decryption.
    +
    27  return Status::OK;
    +
    28 }
    +
    29 
    +
    30 Status RawKeySource::GetKey(const std::string& stream_label,
    +
    31  EncryptionKey* key) {
    +
    32  DCHECK(key);
    +
    33  // Try to find the key with label |stream_label|. If it is not available,
    +
    34  // fall back to the default empty label if it is available.
    +
    35  auto iter = encryption_key_map_.find(stream_label);
    +
    36  if (iter == encryption_key_map_.end()) {
    +
    37  iter = encryption_key_map_.find(kEmptyDrmLabel);
    +
    38  if (iter == encryption_key_map_.end()) {
    +
    39  return Status(error::NOT_FOUND,
    +
    40  "Key for '" + stream_label + "' was not found.");
    +
    41  }
    +
    42  }
    +
    43  *key = *iter->second;
    +
    44  return Status::OK;
    +
    45 }
    +
    46 
    +
    47 Status RawKeySource::GetKey(const std::vector<uint8_t>& key_id,
    +
    48  EncryptionKey* key) {
    +
    49  DCHECK(key);
    +
    50  for (const auto& pair : encryption_key_map_) {
    +
    51  if (pair.second->key_id == key_id) {
    +
    52  *key = *pair.second;
    +
    53  return Status::OK;
    +
    54  }
    +
    55  }
    +
    56  return Status(error::INTERNAL_ERROR,
    +
    57  "Key for key_id=" + base::HexEncode(&key_id[0], key_id.size()) +
    +
    58  " was not found.");
    +
    59 }
    +
    60 
    +
    61 Status RawKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
    +
    62  uint32_t crypto_period_duration_in_seconds,
    +
    63  const std::string& stream_label,
    +
    64  EncryptionKey* key) {
    +
    65  RETURN_IF_ERROR(GetKey(stream_label, key));
    +
    66 
    +
    67  // A naive key rotation algorithm is implemented here by left rotating the
    +
    68  // key, key_id and pssh. Note that this implementation is only intended for
    +
    69  // testing purpose. The actual key rotation algorithm can be much more
    +
    70  // complicated.
    +
    71  LOG(WARNING)
    +
    72  << "This naive key rotation algorithm should not be used in production.";
    +
    73  std::rotate(key->key_id.begin(),
    +
    74  key->key_id.begin() + (crypto_period_index % key->key_id.size()),
    +
    75  key->key_id.end());
    +
    76  std::rotate(key->key.begin(),
    +
    77  key->key.begin() + (crypto_period_index % key->key.size()),
    +
    78  key->key.end());
    +
    79  key->key_ids.clear();
    +
    80  key->key_ids.emplace_back(key->key_id);
    +
    81 
    +
    82  return Status::OK;
    +
    83 }
    +
    84 
    +
    85 std::unique_ptr<RawKeySource> RawKeySource::Create(
    +
    86  const RawKeyParams& raw_key) {
    +
    87  std::vector<ProtectionSystemSpecificInfo> key_system_info;
    +
    88  if (!raw_key.pssh.empty()) {
    + +
    90  raw_key.pssh.data(), raw_key.pssh.size(), &key_system_info)) {
    +
    91  LOG(ERROR) << "--pssh argument should be full PSSH boxes.";
    +
    92  return std::unique_ptr<RawKeySource>();
    +
    93  }
    +
    94  }
    +
    95 
    +
    96  std::vector<std::vector<uint8_t>> key_ids;
    +
    97  for (const auto& entry : raw_key.key_map)
    +
    98  key_ids.emplace_back(entry.second.key_id);
    +
    99 
    +
    100  EncryptionKeyMap encryption_key_map;
    +
    101  for (const auto& entry : raw_key.key_map) {
    +
    102  const std::string& drm_label = entry.first;
    +
    103  const RawKeyParams::KeyInfo& key_pair = entry.second;
    +
    104 
    +
    105  if (key_pair.key_id.size() != 16) {
    +
    106  LOG(ERROR) << "Invalid key ID size '" << key_pair.key_id.size()
    +
    107  << "', must be 16 bytes.";
    +
    108  return std::unique_ptr<RawKeySource>();
    +
    109  }
    +
    110  if (key_pair.key.size() != 16) {
    +
    111  // CENC only supports AES-128, i.e. 16 bytes.
    +
    112  LOG(ERROR) << "Invalid key size '" << key_pair.key.size()
    +
    113  << "', must be 16 bytes.";
    +
    114  return std::unique_ptr<RawKeySource>();
    +
    115  }
    +
    116  if (!key_pair.iv.empty() && key_pair.iv.size() != 8 && key_pair.iv.size() != 16) {
    +
    117  LOG(ERROR) << "Invalid IV '" << key_pair.iv.size()
    +
    118  << "', must be 8 or 16 bytes.";
    +
    119  return std::unique_ptr<RawKeySource>();
    +
    120  }
    +
    121 
    +
    122  std::unique_ptr<EncryptionKey> encryption_key(new EncryptionKey);
    +
    123  encryption_key->key_id = key_pair.key_id;
    +
    124  encryption_key->key_ids = key_ids;
    +
    125  encryption_key->key = key_pair.key;
    +
    126  encryption_key->iv = (key_pair.iv.empty()) ? raw_key.iv : key_pair.iv;
    +
    127  encryption_key->key_system_info = key_system_info;
    +
    128  encryption_key_map[drm_label] = std::move(encryption_key);
    +
    129  }
    +
    130 
    +
    131  return std::unique_ptr<RawKeySource>(
    +
    132  new RawKeySource(std::move(encryption_key_map)));
    +
    133 }
    +
    134 
    +
    135 RawKeySource::RawKeySource() {}
    +
    136 
    +
    137 RawKeySource::RawKeySource(EncryptionKeyMap&& encryption_key_map)
    +
    138  : encryption_key_map_(std::move(encryption_key_map)) {}
    +
    139 
    +
    140 } // namespace media
    +
    141 } // namespace shaka
    + +
    A key source that uses raw keys for encryption.
    +
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    +
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    +
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    +
    static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key)
    +
    All the methods that are virtual are virtual for mocking.
    + +
    Raw key encryption/decryption parameters, i.e. with key parameters provided.
    +
    std::map< StreamLabel, KeyInfo > key_map
    +
    std::vector< uint8_t > pssh
    +
    std::vector< uint8_t > iv
    + +
    std::vector< std::vector< uint8_t > > key_ids
    The IDs of the other keys to include in PSSH info.
    Definition: key_source.h:43
    +
    std::vector< uint8_t > key_id
    The ID of this key.
    Definition: key_source.h:41
    +
    static bool ParseBoxes(const uint8_t *data, size_t data_size, std::vector< ProtectionSystemSpecificInfo > *pssh_boxes)
    diff --git a/docs/d4/dde/webvtt__util_8h_source.html b/docs/d4/dde/webvtt__util_8h_source.html index 3b77fbf5c5..c5526250f1 100644 --- a/docs/d4/dde/webvtt__util_8h_source.html +++ b/docs/d4/dde/webvtt__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/webvtt_util.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    webvtt_util.h
    -
    1 // Copyright 2013 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_CODECS_WEBVTT_UTIL_H_
    6 #define PACKAGER_MEDIA_CODECS_WEBVTT_UTIL_H_
    7 
    8 #include <vector>
    9 
    10 namespace shaka {
    11 namespace media {
    12 
    13 // Utility function to create side data item for decoder buffer.
    14 template <typename T>
    15 void MakeSideData(T id_begin,
    16  T id_end,
    17  T settings_begin,
    18  T settings_end,
    19  std::vector<uint8_t>* side_data) {
    20  // The DecoderBuffer only supports a single side data item. In the case of
    21  // a WebVTT cue, we can have potentially two side data items. In order to
    22  // avoid disrupting DecoderBuffer any more than we need to, we copy both
    23  // side data items onto a single one, and terminate each with a NUL marker.
    24  side_data->clear();
    25  side_data->insert(side_data->end(), id_begin, id_end);
    26  side_data->push_back(0);
    27  side_data->insert(side_data->end(), settings_begin, settings_end);
    28  side_data->push_back(0);
    29 }
    30 
    31 } // namespace media
    32 } // namespace shaka
    33 
    34 #endif // PACKAGER_MEDIA_CODECS_WEBVTT_UTIL_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2013 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_CODECS_WEBVTT_UTIL_H_
    +
    6 #define PACKAGER_MEDIA_CODECS_WEBVTT_UTIL_H_
    +
    7 
    +
    8 #include <vector>
    +
    9 
    +
    10 namespace shaka {
    +
    11 namespace media {
    +
    12 
    +
    13 // Utility function to create side data item for decoder buffer.
    +
    14 template <typename T>
    +
    15 void MakeSideData(T id_begin,
    +
    16  T id_end,
    +
    17  T settings_begin,
    +
    18  T settings_end,
    +
    19  std::vector<uint8_t>* side_data) {
    +
    20  // The DecoderBuffer only supports a single side data item. In the case of
    +
    21  // a WebVTT cue, we can have potentially two side data items. In order to
    +
    22  // avoid disrupting DecoderBuffer any more than we need to, we copy both
    +
    23  // side data items onto a single one, and terminate each with a NUL marker.
    +
    24  side_data->clear();
    +
    25  side_data->insert(side_data->end(), id_begin, id_end);
    +
    26  side_data->push_back(0);
    +
    27  side_data->insert(side_data->end(), settings_begin, settings_end);
    +
    28  side_data->push_back(0);
    +
    29 }
    +
    30 
    +
    31 } // namespace media
    +
    32 } // namespace shaka
    +
    33 
    +
    34 #endif // PACKAGER_MEDIA_CODECS_WEBVTT_UTIL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/de3/structshaka_1_1media_1_1mp4_1_1DataReference.html b/docs/d4/de3/structshaka_1_1media_1_1mp4_1_1DataReference.html index 3dd7800dc4..058700f8f9 100644 --- a/docs/d4/de3/structshaka_1_1media_1_1mp4_1_1DataReference.html +++ b/docs/d4/de3/structshaka_1_1media_1_1mp4_1_1DataReference.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::DataReference Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 603 of file box_definitions.h.

    +

    Definition at line 620 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2090 of file box_definitions.cc.

    +

    Definition at line 2165 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/d4/de6/classshaka_1_1media_1_1ProgressListener.html b/docs/d4/de6/classshaka_1_1media_1_1ProgressListener.html index 5688cd59cb..cf21d26d96 100644 --- a/docs/d4/de6/classshaka_1_1media_1_1ProgressListener.html +++ b/docs/d4/de6/classshaka_1_1media_1_1ProgressListener.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ProgressListener Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/de7/classshaka_1_1media_1_1VodMediaInfoDumpMuxerListener-members.html b/docs/d4/de7/classshaka_1_1media_1_1VodMediaInfoDumpMuxerListener-members.html index acab681721..70df19c28b 100644 --- a/docs/d4/de7/classshaka_1_1media_1_1VodMediaInfoDumpMuxerListener-members.html +++ b/docs/d4/de7/classshaka_1_1media_1_1VodMediaInfoDumpMuxerListener-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d4/dec/hls__flags_8h_source.html b/docs/d4/dec/hls__flags_8h_source.html index de1a77b176..023b4f2e22 100644 --- a/docs/d4/dec/hls__flags_8h_source.html +++ b/docs/d4/dec/hls__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/hls_flags.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    hls_flags.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_APP_HLS_FLAGS_H_
    8 #define PACKAGER_APP_HLS_FLAGS_H_
    9 
    10 #include <gflags/gflags.h>
    11 
    12 DECLARE_string(hls_master_playlist_output);
    13 DECLARE_string(hls_base_url);
    14 DECLARE_string(hls_key_uri);
    15 DECLARE_string(hls_playlist_type);
    16 
    17 #endif // PACKAGER_APP_HLS_FLAGS_H_
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_APP_HLS_FLAGS_H_
    +
    8 #define PACKAGER_APP_HLS_FLAGS_H_
    +
    9 
    +
    10 #include <gflags/gflags.h>
    +
    11 
    +
    12 DECLARE_string(hls_master_playlist_output);
    +
    13 DECLARE_string(hls_base_url);
    +
    14 DECLARE_string(hls_key_uri);
    +
    15 DECLARE_string(hls_playlist_type);
    +
    16 DECLARE_int32(hls_media_sequence_number);
    +
    17 
    +
    18 #endif // PACKAGER_APP_HLS_FLAGS_H_
    +
    diff --git a/docs/d4/df5/request__signer_8cc_source.html b/docs/d4/df5/request__signer_8cc_source.html index 06e59b9e29..7a020b6180 100644 --- a/docs/d4/df5/request__signer_8cc_source.html +++ b/docs/d4/df5/request__signer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/request_signer.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    request_signer.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/request_signer.h"
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/base/sha1.h"
    11 #include "packager/media/base/aes_encryptor.h"
    12 #include "packager/media/base/rsa_key.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 RequestSigner::RequestSigner(const std::string& signer_name)
    18  : signer_name_(signer_name) {}
    19 RequestSigner::~RequestSigner() {}
    20 
    21 AesRequestSigner::AesRequestSigner(const std::string& signer_name,
    22  std::unique_ptr<AesCbcEncryptor> encryptor)
    23  : RequestSigner(signer_name), aes_cbc_encryptor_(std::move(encryptor)) {
    24  DCHECK(aes_cbc_encryptor_);
    25 }
    26 AesRequestSigner::~AesRequestSigner() {}
    27 
    29  const std::string& signer_name,
    30  const std::vector<uint8_t>& aes_key,
    31  const std::vector<uint8_t>& iv) {
    32  std::unique_ptr<AesCbcEncryptor> encryptor(
    33  new AesCbcEncryptor(kPkcs5Padding, AesCryptor::kUseConstantIv));
    34  if (!encryptor->InitializeWithIv(aes_key, iv))
    35  return NULL;
    36  return new AesRequestSigner(signer_name, std::move(encryptor));
    37 }
    38 
    39 bool AesRequestSigner::GenerateSignature(const std::string& message,
    40  std::string* signature) {
    41  aes_cbc_encryptor_->Crypt(base::SHA1HashString(message), signature);
    42  return true;
    43 }
    44 
    45 RsaRequestSigner::RsaRequestSigner(
    46  const std::string& signer_name,
    47  std::unique_ptr<RsaPrivateKey> rsa_private_key)
    48  : RequestSigner(signer_name), rsa_private_key_(std::move(rsa_private_key)) {
    49  DCHECK(rsa_private_key_);
    50 }
    51 RsaRequestSigner::~RsaRequestSigner() {}
    52 
    54  const std::string& signer_name,
    55  const std::string& pkcs1_rsa_key) {
    56  std::unique_ptr<RsaPrivateKey> rsa_private_key(
    57  RsaPrivateKey::Create(pkcs1_rsa_key));
    58  if (!rsa_private_key)
    59  return NULL;
    60  return new RsaRequestSigner(signer_name, std::move(rsa_private_key));
    61 }
    62 
    63 bool RsaRequestSigner::GenerateSignature(const std::string& message,
    64  std::string* signature) {
    65  return rsa_private_key_->GenerateSignature(message, signature);
    66 }
    67 
    68 } // namespace media
    69 } // namespace shaka
    static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
    -
    static AesRequestSigner * CreateSigner(const std::string &signer_name, const std::vector< uint8_t > &aes_key, const std::vector< uint8_t > &iv)
    -
    STL namespace.
    -
    Abstract class used for signature generation.
    -
    All the methods that are virtual are virtual for mocking.
    - -
    RsaRequestSigner uses RSA-PSS signing.
    -
    bool GenerateSignature(const std::string &message, std::string *signature) override
    RequestSigner implementation override.
    -
    bool GenerateSignature(const std::string &message, std::string *signature) override
    RequestSigner implementation override.
    -
    AesRequestSigner uses AES-CBC signing.
    -
    static RsaPrivateKey * Create(const std::string &serialized_key)
    Definition: rsa_key.cc:96
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/request_signer.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/base/sha1.h"
    +
    11 #include "packager/media/base/aes_encryptor.h"
    +
    12 #include "packager/media/base/rsa_key.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 RequestSigner::RequestSigner(const std::string& signer_name)
    +
    18  : signer_name_(signer_name) {}
    +
    19 RequestSigner::~RequestSigner() {}
    +
    20 
    +
    21 AesRequestSigner::AesRequestSigner(const std::string& signer_name,
    +
    22  std::unique_ptr<AesCbcEncryptor> encryptor)
    +
    23  : RequestSigner(signer_name), aes_cbc_encryptor_(std::move(encryptor)) {
    +
    24  DCHECK(aes_cbc_encryptor_);
    +
    25 }
    +
    26 AesRequestSigner::~AesRequestSigner() {}
    +
    27 
    +
    28 AesRequestSigner* AesRequestSigner::CreateSigner(
    +
    29  const std::string& signer_name,
    +
    30  const std::vector<uint8_t>& aes_key,
    +
    31  const std::vector<uint8_t>& iv) {
    +
    32  std::unique_ptr<AesCbcEncryptor> encryptor(
    +
    33  new AesCbcEncryptor(kPkcs5Padding, AesCryptor::kUseConstantIv));
    +
    34  if (!encryptor->InitializeWithIv(aes_key, iv))
    +
    35  return NULL;
    +
    36  return new AesRequestSigner(signer_name, std::move(encryptor));
    +
    37 }
    +
    38 
    +
    39 bool AesRequestSigner::GenerateSignature(const std::string& message,
    +
    40  std::string* signature) {
    +
    41  aes_cbc_encryptor_->Crypt(base::SHA1HashString(message), signature);
    +
    42  return true;
    +
    43 }
    +
    44 
    +
    45 RsaRequestSigner::RsaRequestSigner(
    +
    46  const std::string& signer_name,
    +
    47  std::unique_ptr<RsaPrivateKey> rsa_private_key)
    +
    48  : RequestSigner(signer_name), rsa_private_key_(std::move(rsa_private_key)) {
    +
    49  DCHECK(rsa_private_key_);
    +
    50 }
    +
    51 RsaRequestSigner::~RsaRequestSigner() {}
    +
    52 
    + +
    54  const std::string& signer_name,
    +
    55  const std::string& pkcs1_rsa_key) {
    +
    56  std::unique_ptr<RsaPrivateKey> rsa_private_key(
    +
    57  RsaPrivateKey::Create(pkcs1_rsa_key));
    +
    58  if (!rsa_private_key)
    +
    59  return NULL;
    +
    60  return new RsaRequestSigner(signer_name, std::move(rsa_private_key));
    +
    61 }
    +
    62 
    +
    63 bool RsaRequestSigner::GenerateSignature(const std::string& message,
    +
    64  std::string* signature) {
    +
    65  return rsa_private_key_->GenerateSignature(message, signature);
    +
    66 }
    +
    67 
    +
    68 } // namespace media
    +
    69 } // namespace shaka
    + +
    AesRequestSigner uses AES-CBC signing.
    +
    Abstract class used for signature generation.
    +
    static RsaPrivateKey * Create(const std::string &serialized_key)
    Definition: rsa_key.cc:96
    +
    RsaRequestSigner uses RSA-PSS signing.
    +
    bool GenerateSignature(const std::string &message, std::string *signature) override
    RequestSigner implementation override.
    +
    static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d4/df9/structshaka_1_1media_1_1mp4_1_1SegmentIndex.html b/docs/d4/df9/structshaka_1_1media_1_1mp4_1_1SegmentIndex.html index d155437d2b..c6571a37ca 100644 --- a/docs/d4/df9/structshaka_1_1media_1_1mp4_1_1SegmentIndex.html +++ b/docs/d4/df9/structshaka_1_1media_1_1mp4_1_1SegmentIndex.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SegmentIndex Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -133,7 +136,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 783 of file box_definitions.h.

    +

    Definition at line 801 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -161,7 +164,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2648 of file box_definitions.cc.

    +

    Definition at line 2737 of file box_definitions.cc.

    @@ -172,9 +175,7 @@ Additional Inherited Members diff --git a/docs/d4/dfa/structshaka_1_1media_1_1RgbaColor.html b/docs/d4/dfa/structshaka_1_1media_1_1RgbaColor.html new file mode 100644 index 0000000000..e706d53b9f --- /dev/null +++ b/docs/d4/dfa/structshaka_1_1media_1_1RgbaColor.html @@ -0,0 +1,113 @@ + + + + + + + +Shaka Packager SDK: shaka::media::RgbaColor Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::RgbaColor Struct Reference
    +
    +
    + + + + + + +

    +Public Member Functions

    +bool operator== (const RgbaColor &other) const
     
    +bool operator!= (const RgbaColor &other) const
     
    + + + + + + + + + +

    +Public Attributes

    +uint8_t r
     
    +uint8_t g
     
    +uint8_t b
     
    +uint8_t a
     
    +

    Detailed Description

    +
    +

    Definition at line 16 of file dvb_image.h.

    +

    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/docs/d4/dfa/structshaka_1_1media_1_1mp4_1_1AC3Specific.html b/docs/d4/dfa/structshaka_1_1media_1_1mp4_1_1AC3Specific.html index 48d856ef8f..26cd629374 100644 --- a/docs/d4/dfa/structshaka_1_1media_1_1mp4_1_1AC3Specific.html +++ b/docs/d4/dfa/structshaka_1_1media_1_1mp4_1_1AC3Specific.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::AC3Specific Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -112,7 +115,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 324 of file box_definitions.h.

    +

    Definition at line 325 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -140,7 +143,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1725 of file box_definitions.cc.

    +

    Definition at line 1751 of file box_definitions.cc.

    @@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d4/dfd/structshaka_1_1media_1_1H265Sps.html b/docs/d4/dfd/structshaka_1_1media_1_1H265Sps.html index a063052457..c573042f0a 100644 --- a/docs/d4/dfd/structshaka_1_1media_1_1H265Sps.html +++ b/docs/d4/dfd/structshaka_1_1media_1_1H265Sps.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265Sps Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    vui_parameters_presen
    diff --git a/docs/d4/dff/webm__media__parser_8cc_source.html b/docs/d4/dff/webm__media__parser_8cc_source.html index 6edcb41a74..f527cf6b28 100644 --- a/docs/d4/dff/webm__media__parser_8cc_source.html +++ b/docs/d4/dff/webm__media__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_media_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webm_media_parser.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/webm/webm_media_parser.h"
    6 
    7 #include <string>
    8 
    9 #include "packager/base/callback.h"
    10 #include "packager/base/callback_helpers.h"
    11 #include "packager/base/logging.h"
    12 #include "packager/media/base/buffer_writer.h"
    13 #include "packager/media/base/timestamp.h"
    14 #include "packager/media/formats/webm/webm_cluster_parser.h"
    15 #include "packager/media/formats/webm/webm_constants.h"
    16 #include "packager/media/formats/webm/webm_content_encodings.h"
    17 #include "packager/media/formats/webm/webm_info_parser.h"
    18 #include "packager/media/formats/webm/webm_tracks_parser.h"
    19 
    20 namespace shaka {
    21 namespace media {
    22 
    23 WebMMediaParser::WebMMediaParser()
    24  : state_(kWaitingForInit), unknown_segment_size_(false) {}
    25 
    26 WebMMediaParser::~WebMMediaParser() {}
    27 
    28 void WebMMediaParser::Init(const InitCB& init_cb,
    29  const NewSampleCB& new_sample_cb,
    30  KeySource* decryption_key_source) {
    31  DCHECK_EQ(state_, kWaitingForInit);
    32  DCHECK(init_cb_.is_null());
    33  DCHECK(!init_cb.is_null());
    34  DCHECK(!new_sample_cb.is_null());
    35 
    36  ChangeState(kParsingHeaders);
    37  init_cb_ = init_cb;
    38  new_sample_cb_ = new_sample_cb;
    39  decryption_key_source_ = decryption_key_source;
    40  ignore_text_tracks_ = true;
    41 }
    42 
    44  DCHECK_NE(state_, kWaitingForInit);
    45 
    46  byte_queue_.Reset();
    47  bool result = true;
    48  if (cluster_parser_)
    49  result = cluster_parser_->Flush();
    50  if (state_ == kParsingClusters) {
    51  ChangeState(kParsingHeaders);
    52  }
    53  return result;
    54 }
    55 
    56 bool WebMMediaParser::Parse(const uint8_t* buf, int size) {
    57  DCHECK_NE(state_, kWaitingForInit);
    58 
    59  if (state_ == kError)
    60  return false;
    61 
    62  byte_queue_.Push(buf, size);
    63 
    64  int result = 0;
    65  int bytes_parsed = 0;
    66  const uint8_t* cur = NULL;
    67  int cur_size = 0;
    68 
    69  byte_queue_.Peek(&cur, &cur_size);
    70  while (cur_size > 0) {
    71  State oldState = state_;
    72  switch (state_) {
    73  case kParsingHeaders:
    74  result = ParseInfoAndTracks(cur, cur_size);
    75  break;
    76 
    77  case kParsingClusters:
    78  result = ParseCluster(cur, cur_size);
    79  break;
    80 
    81  case kWaitingForInit:
    82  case kError:
    83  return false;
    84  }
    85 
    86  if (result < 0) {
    87  ChangeState(kError);
    88  return false;
    89  }
    90 
    91  if (state_ == oldState && result == 0)
    92  break;
    93 
    94  DCHECK_GE(result, 0);
    95  cur += result;
    96  cur_size -= result;
    97  bytes_parsed += result;
    98  }
    99 
    100  byte_queue_.Pop(bytes_parsed);
    101  return true;
    102 }
    103 
    104 void WebMMediaParser::ChangeState(State new_state) {
    105  DVLOG(1) << "ChangeState() : " << state_ << " -> " << new_state;
    106  state_ = new_state;
    107 }
    108 
    109 int WebMMediaParser::ParseInfoAndTracks(const uint8_t* data, int size) {
    110  DVLOG(2) << "ParseInfoAndTracks()";
    111  DCHECK(data);
    112  DCHECK_GT(size, 0);
    113 
    114  const uint8_t* cur = data;
    115  int cur_size = size;
    116  int bytes_parsed = 0;
    117 
    118  int id;
    119  int64_t element_size;
    120  int result = WebMParseElementHeader(cur, cur_size, &id, &element_size);
    121 
    122  if (result <= 0)
    123  return result;
    124 
    125  switch (id) {
    126  case kWebMIdEBMLHeader:
    127  case kWebMIdSeekHead:
    128  case kWebMIdVoid:
    129  case kWebMIdCRC32:
    130  case kWebMIdCues:
    131  case kWebMIdChapters:
    132  case kWebMIdTags:
    133  case kWebMIdAttachments:
    134  // TODO: Implement support for chapters.
    135  if (cur_size < (result + element_size)) {
    136  // We don't have the whole element yet. Signal we need more data.
    137  return 0;
    138  }
    139  // Skip the element.
    140  return result + element_size;
    141  break;
    142  case kWebMIdCluster:
    143  if (!cluster_parser_) {
    144  LOG(ERROR) << "Found Cluster element before Info.";
    145  return -1;
    146  }
    147  ChangeState(kParsingClusters);
    148  return 0;
    149  break;
    150  case kWebMIdSegment:
    151  // Segment of unknown size indicates live stream.
    152  if (element_size == kWebMUnknownSize)
    153  unknown_segment_size_ = true;
    154  // Just consume the segment header.
    155  return result;
    156  break;
    157  case kWebMIdInfo:
    158  // We've found the element we are looking for.
    159  break;
    160  default: {
    161  LOG(ERROR) << "Unexpected element ID 0x" << std::hex << id;
    162  return -1;
    163  }
    164  }
    165 
    166  WebMInfoParser info_parser;
    167  result = info_parser.Parse(cur, cur_size);
    168 
    169  if (result <= 0)
    170  return result;
    171 
    172  cur += result;
    173  cur_size -= result;
    174  bytes_parsed += result;
    175 
    176  WebMTracksParser tracks_parser(ignore_text_tracks_);
    177  result = tracks_parser.Parse(cur, cur_size);
    178 
    179  if (result <= 0)
    180  return result;
    181 
    182  bytes_parsed += result;
    183 
    184  double timecode_scale_in_us = info_parser.timecode_scale() / 1000.0;
    185  int64_t duration_in_us = info_parser.duration() * timecode_scale_in_us;
    186 
    187  std::shared_ptr<AudioStreamInfo> audio_stream_info =
    188  tracks_parser.audio_stream_info();
    189  if (audio_stream_info) {
    190  audio_stream_info->set_duration(duration_in_us);
    191  } else {
    192  VLOG(1) << "No audio track info found.";
    193  }
    194 
    195  std::shared_ptr<VideoStreamInfo> video_stream_info =
    196  tracks_parser.video_stream_info();
    197  if (video_stream_info) {
    198  video_stream_info->set_duration(duration_in_us);
    199  } else {
    200  VLOG(1) << "No video track info found.";
    201  }
    202 
    203  if (!FetchKeysIfNecessary(tracks_parser.audio_encryption_key_id(),
    204  tracks_parser.video_encryption_key_id())) {
    205  return -1;
    206  }
    207 
    208  cluster_parser_.reset(new WebMClusterParser(
    209  info_parser.timecode_scale(), audio_stream_info, video_stream_info,
    210  tracks_parser.vp_config(),
    211  tracks_parser.GetAudioDefaultDuration(timecode_scale_in_us),
    212  tracks_parser.GetVideoDefaultDuration(timecode_scale_in_us),
    213  tracks_parser.text_tracks(), tracks_parser.ignored_tracks(),
    214  tracks_parser.audio_encryption_key_id(),
    215  tracks_parser.video_encryption_key_id(), new_sample_cb_, init_cb_,
    216  decryption_key_source_));
    217 
    218  return bytes_parsed;
    219 }
    220 
    221 int WebMMediaParser::ParseCluster(const uint8_t* data, int size) {
    222  if (!cluster_parser_)
    223  return -1;
    224 
    225  int bytes_parsed = cluster_parser_->Parse(data, size);
    226  if (bytes_parsed < 0)
    227  return bytes_parsed;
    228 
    229  bool cluster_ended = cluster_parser_->cluster_ended();
    230  if (cluster_ended) {
    231  ChangeState(kParsingHeaders);
    232  }
    233 
    234  return bytes_parsed;
    235 }
    236 
    237 bool WebMMediaParser::FetchKeysIfNecessary(
    238  const std::string& audio_encryption_key_id,
    239  const std::string& video_encryption_key_id) {
    240  if (audio_encryption_key_id.empty() && video_encryption_key_id.empty())
    241  return true;
    242  // An error will be returned later if the samples need to be decrypted.
    243  if (!decryption_key_source_)
    244  return true;
    245 
    246  Status status;
    247  if (!audio_encryption_key_id.empty()) {
    248  status.Update(decryption_key_source_->FetchKeys(
    249  EmeInitDataType::WEBM,
    250  std::vector<uint8_t>(audio_encryption_key_id.begin(),
    251  audio_encryption_key_id.end())));
    252  }
    253  if (!video_encryption_key_id.empty()) {
    254  status.Update(decryption_key_source_->FetchKeys(
    255  EmeInitDataType::WEBM,
    256  std::vector<uint8_t>(video_encryption_key_id.begin(),
    257  video_encryption_key_id.end())));
    258  }
    259  if (!status.ok()) {
    260  LOG(ERROR) << "Error fetching decryption keys: " << status;
    261  return false;
    262  }
    263  return true;
    264 }
    265 
    266 } // namespace media
    267 } // namespace shaka
    Parser for WebM Tracks element.
    -
    bool Flush() override WARN_UNUSED_RESULT
    -
    bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    -
    All the methods that are virtual are virtual for mocking.
    -
    void Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
    - -
    base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
    Definition: media_parser.h:43
    -
    void Update(Status new_status)
    Definition: status.cc:78
    -
    int64_t GetAudioDefaultDuration(const double timecode_scale_in_us) const
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    int Parse(const uint8_t *buf, int size)
    - -
    Parser for WebM Info element.
    -
    int Parse(const uint8_t *buf, int size)
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/webm/webm_media_parser.h"
    +
    6 
    +
    7 #include <string>
    +
    8 
    +
    9 #include "packager/base/callback.h"
    +
    10 #include "packager/base/callback_helpers.h"
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/buffer_writer.h"
    +
    13 #include "packager/media/base/timestamp.h"
    +
    14 #include "packager/media/formats/webm/webm_cluster_parser.h"
    +
    15 #include "packager/media/formats/webm/webm_constants.h"
    +
    16 #include "packager/media/formats/webm/webm_content_encodings.h"
    +
    17 #include "packager/media/formats/webm/webm_info_parser.h"
    +
    18 #include "packager/media/formats/webm/webm_tracks_parser.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 namespace media {
    +
    22 
    +
    23 WebMMediaParser::WebMMediaParser()
    +
    24  : state_(kWaitingForInit), unknown_segment_size_(false) {}
    +
    25 
    +
    26 WebMMediaParser::~WebMMediaParser() {}
    +
    27 
    +
    28 void WebMMediaParser::Init(const InitCB& init_cb,
    +
    29  const NewMediaSampleCB& new_media_sample_cb,
    +
    30  const NewTextSampleCB& new_text_sample_cb,
    +
    31  KeySource* decryption_key_source) {
    +
    32  DCHECK_EQ(state_, kWaitingForInit);
    +
    33  DCHECK(init_cb_.is_null());
    +
    34  DCHECK(!init_cb.is_null());
    +
    35  DCHECK(!new_media_sample_cb.is_null());
    +
    36 
    +
    37  ChangeState(kParsingHeaders);
    +
    38  init_cb_ = init_cb;
    +
    39  new_sample_cb_ = new_media_sample_cb;
    +
    40  decryption_key_source_ = decryption_key_source;
    +
    41  ignore_text_tracks_ = true;
    +
    42 }
    +
    43 
    +
    44 bool WebMMediaParser::Flush() {
    +
    45  DCHECK_NE(state_, kWaitingForInit);
    +
    46 
    +
    47  byte_queue_.Reset();
    +
    48  bool result = true;
    +
    49  if (cluster_parser_)
    +
    50  result = cluster_parser_->Flush();
    +
    51  if (state_ == kParsingClusters) {
    +
    52  ChangeState(kParsingHeaders);
    +
    53  }
    +
    54  return result;
    +
    55 }
    +
    56 
    +
    57 bool WebMMediaParser::Parse(const uint8_t* buf, int size) {
    +
    58  DCHECK_NE(state_, kWaitingForInit);
    +
    59 
    +
    60  if (state_ == kError)
    +
    61  return false;
    +
    62 
    +
    63  byte_queue_.Push(buf, size);
    +
    64 
    +
    65  int result = 0;
    +
    66  int bytes_parsed = 0;
    +
    67  const uint8_t* cur = NULL;
    +
    68  int cur_size = 0;
    +
    69 
    +
    70  byte_queue_.Peek(&cur, &cur_size);
    +
    71  while (cur_size > 0) {
    +
    72  State oldState = state_;
    +
    73  switch (state_) {
    +
    74  case kParsingHeaders:
    +
    75  result = ParseInfoAndTracks(cur, cur_size);
    +
    76  break;
    +
    77 
    +
    78  case kParsingClusters:
    +
    79  result = ParseCluster(cur, cur_size);
    +
    80  break;
    +
    81 
    +
    82  case kWaitingForInit:
    +
    83  case kError:
    +
    84  return false;
    +
    85  }
    +
    86 
    +
    87  if (result < 0) {
    +
    88  ChangeState(kError);
    +
    89  return false;
    +
    90  }
    +
    91 
    +
    92  if (state_ == oldState && result == 0)
    +
    93  break;
    +
    94 
    +
    95  DCHECK_GE(result, 0);
    +
    96  cur += result;
    +
    97  cur_size -= result;
    +
    98  bytes_parsed += result;
    +
    99  }
    +
    100 
    +
    101  byte_queue_.Pop(bytes_parsed);
    +
    102  return true;
    +
    103 }
    +
    104 
    +
    105 void WebMMediaParser::ChangeState(State new_state) {
    +
    106  DVLOG(1) << "ChangeState() : " << state_ << " -> " << new_state;
    +
    107  state_ = new_state;
    +
    108 }
    +
    109 
    +
    110 int WebMMediaParser::ParseInfoAndTracks(const uint8_t* data, int size) {
    +
    111  DVLOG(2) << "ParseInfoAndTracks()";
    +
    112  DCHECK(data);
    +
    113  DCHECK_GT(size, 0);
    +
    114 
    +
    115  const uint8_t* cur = data;
    +
    116  int cur_size = size;
    +
    117  int bytes_parsed = 0;
    +
    118 
    +
    119  int id;
    +
    120  int64_t element_size;
    +
    121  int result = WebMParseElementHeader(cur, cur_size, &id, &element_size);
    +
    122 
    +
    123  if (result <= 0)
    +
    124  return result;
    +
    125 
    +
    126  switch (id) {
    +
    127  case kWebMIdEBMLHeader:
    +
    128  case kWebMIdSeekHead:
    +
    129  case kWebMIdVoid:
    +
    130  case kWebMIdCRC32:
    +
    131  case kWebMIdCues:
    +
    132  case kWebMIdChapters:
    +
    133  case kWebMIdTags:
    +
    134  case kWebMIdAttachments:
    +
    135  // TODO: Implement support for chapters.
    +
    136  if (cur_size < (result + element_size)) {
    +
    137  // We don't have the whole element yet. Signal we need more data.
    +
    138  return 0;
    +
    139  }
    +
    140  // Skip the element.
    +
    141  return result + element_size;
    +
    142  break;
    +
    143  case kWebMIdCluster:
    +
    144  if (!cluster_parser_) {
    +
    145  LOG(ERROR) << "Found Cluster element before Info.";
    +
    146  return -1;
    +
    147  }
    +
    148  ChangeState(kParsingClusters);
    +
    149  return 0;
    +
    150  break;
    +
    151  case kWebMIdSegment:
    +
    152  // Segment of unknown size indicates live stream.
    +
    153  if (element_size == kWebMUnknownSize)
    +
    154  unknown_segment_size_ = true;
    +
    155  // Just consume the segment header.
    +
    156  return result;
    +
    157  break;
    +
    158  case kWebMIdInfo:
    +
    159  // We've found the element we are looking for.
    +
    160  break;
    +
    161  default: {
    +
    162  LOG(ERROR) << "Unexpected element ID 0x" << std::hex << id;
    +
    163  return -1;
    +
    164  }
    +
    165  }
    +
    166 
    +
    167  WebMInfoParser info_parser;
    +
    168  result = info_parser.Parse(cur, cur_size);
    +
    169 
    +
    170  if (result <= 0)
    +
    171  return result;
    +
    172 
    +
    173  cur += result;
    +
    174  cur_size -= result;
    +
    175  bytes_parsed += result;
    +
    176 
    +
    177  WebMTracksParser tracks_parser(ignore_text_tracks_);
    +
    178  result = tracks_parser.Parse(cur, cur_size);
    +
    179 
    +
    180  if (result <= 0)
    +
    181  return result;
    +
    182 
    +
    183  bytes_parsed += result;
    +
    184 
    +
    185  double timecode_scale_in_us = info_parser.timecode_scale() / 1000.0;
    +
    186  int64_t duration_in_us = info_parser.duration() * timecode_scale_in_us;
    +
    187 
    +
    188  std::shared_ptr<AudioStreamInfo> audio_stream_info =
    +
    189  tracks_parser.audio_stream_info();
    +
    190  if (audio_stream_info) {
    +
    191  audio_stream_info->set_duration(duration_in_us);
    +
    192  } else {
    +
    193  VLOG(1) << "No audio track info found.";
    +
    194  }
    +
    195 
    +
    196  std::shared_ptr<VideoStreamInfo> video_stream_info =
    +
    197  tracks_parser.video_stream_info();
    +
    198  if (video_stream_info) {
    +
    199  video_stream_info->set_duration(duration_in_us);
    +
    200  } else {
    +
    201  VLOG(1) << "No video track info found.";
    +
    202  }
    +
    203 
    +
    204  if (!FetchKeysIfNecessary(tracks_parser.audio_encryption_key_id(),
    +
    205  tracks_parser.video_encryption_key_id())) {
    +
    206  return -1;
    +
    207  }
    +
    208 
    +
    209  cluster_parser_.reset(new WebMClusterParser(
    +
    210  info_parser.timecode_scale(), audio_stream_info, video_stream_info,
    +
    211  tracks_parser.vp_config(),
    +
    212  tracks_parser.GetAudioDefaultDuration(timecode_scale_in_us),
    +
    213  tracks_parser.GetVideoDefaultDuration(timecode_scale_in_us),
    +
    214  tracks_parser.text_tracks(), tracks_parser.ignored_tracks(),
    +
    215  tracks_parser.audio_encryption_key_id(),
    +
    216  tracks_parser.video_encryption_key_id(), new_sample_cb_, init_cb_,
    +
    217  decryption_key_source_));
    +
    218 
    +
    219  return bytes_parsed;
    +
    220 }
    +
    221 
    +
    222 int WebMMediaParser::ParseCluster(const uint8_t* data, int size) {
    +
    223  if (!cluster_parser_)
    +
    224  return -1;
    +
    225 
    +
    226  int bytes_parsed = cluster_parser_->Parse(data, size);
    +
    227  if (bytes_parsed < 0)
    +
    228  return bytes_parsed;
    +
    229 
    +
    230  bool cluster_ended = cluster_parser_->cluster_ended();
    +
    231  if (cluster_ended) {
    +
    232  ChangeState(kParsingHeaders);
    +
    233  }
    +
    234 
    +
    235  return bytes_parsed;
    +
    236 }
    +
    237 
    +
    238 bool WebMMediaParser::FetchKeysIfNecessary(
    +
    239  const std::string& audio_encryption_key_id,
    +
    240  const std::string& video_encryption_key_id) {
    +
    241  if (audio_encryption_key_id.empty() && video_encryption_key_id.empty())
    +
    242  return true;
    +
    243  // An error will be returned later if the samples need to be decrypted.
    +
    244  if (!decryption_key_source_)
    +
    245  return true;
    +
    246 
    +
    247  Status status;
    +
    248  if (!audio_encryption_key_id.empty()) {
    +
    249  status.Update(decryption_key_source_->FetchKeys(
    +
    250  EmeInitDataType::WEBM,
    +
    251  std::vector<uint8_t>(audio_encryption_key_id.begin(),
    +
    252  audio_encryption_key_id.end())));
    +
    253  }
    +
    254  if (!video_encryption_key_id.empty()) {
    +
    255  status.Update(decryption_key_source_->FetchKeys(
    +
    256  EmeInitDataType::WEBM,
    +
    257  std::vector<uint8_t>(video_encryption_key_id.begin(),
    +
    258  video_encryption_key_id.end())));
    +
    259  }
    +
    260  if (!status.ok()) {
    +
    261  LOG(ERROR) << "Error fetching decryption keys: " << status;
    +
    262  return false;
    +
    263  }
    +
    264  return true;
    +
    265 }
    +
    266 
    +
    267 } // namespace media
    +
    268 } // namespace shaka
    +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
    Definition: media_parser.h:53
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d00/common__pssh__generator_8h_source.html b/docs/d5/d00/common__pssh__generator_8h_source.html index 5e20026761..704fae0bbb 100644 --- a/docs/d5/d00/common__pssh__generator_8h_source.html +++ b/docs/d5/d00/common__pssh__generator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/common_pssh_generator.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    common_pssh_generator.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_COMMON_PSSH_GENERATOR_H_
    8 #define PACKAGER_MEDIA_BASE_COMMON_PSSH_GENERATOR_H_
    9 
    10 #include "packager/media/base/pssh_generator.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    16  public:
    18  ~CommonPsshGenerator() override;
    19 
    22  bool SupportMultipleKeys() override;
    24 
    25  private:
    26  CommonPsshGenerator& operator=(const CommonPsshGenerator&) = delete;
    28 
    29  // PsshGenerator implemetation overrides.
    30 
    31  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
    32  const std::vector<std::vector<uint8_t>>& key_ids) const override;
    33 
    34  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
    35  const std::vector<uint8_t>& key_id,
    36  const std::vector<uint8_t>& key) const override;
    37 };
    38 } // namespace media
    39 } // namespace shaka
    40 
    41 #endif // PACKAGER_MEDIA_BASE_COMMON_PSSH_GENERATOR_H_
    All the methods that are virtual are virtual for mocking.
    - - - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_COMMON_PSSH_GENERATOR_H_
    +
    8 #define PACKAGER_MEDIA_BASE_COMMON_PSSH_GENERATOR_H_
    +
    9 
    +
    10 #include "packager/media/base/pssh_generator.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    + +
    16  public:
    + +
    18  ~CommonPsshGenerator() override;
    +
    19 
    +
    22  bool SupportMultipleKeys() override;
    +
    24 
    +
    25  private:
    +
    26  CommonPsshGenerator& operator=(const CommonPsshGenerator&) = delete;
    + +
    28 
    +
    29  // PsshGenerator implemetation overrides.
    +
    30 
    +
    31  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
    +
    32  const std::vector<std::vector<uint8_t>>& key_ids) const override;
    +
    33 
    +
    34  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
    +
    35  const std::vector<uint8_t>& key_id,
    +
    36  const std::vector<uint8_t>& key) const override;
    +
    37 };
    +
    38 } // namespace media
    +
    39 } // namespace shaka
    +
    40 
    +
    41 #endif // PACKAGER_MEDIA_BASE_COMMON_PSSH_GENERATOR_H_
    + + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d03/structshaka_1_1media_1_1mp4_1_1FileType.html b/docs/d5/d03/structshaka_1_1media_1_1mp4_1_1FileType.html index 333a6dc1cf..8126bbed21 100644 --- a/docs/d5/d03/structshaka_1_1media_1_1mp4_1_1FileType.html +++ b/docs/d5/d03/structshaka_1_1media_1_1mp4_1_1FileType.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::FileType Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::Box shaka::media::mp4::SegmentType - -
    + + @@ -119,7 +122,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 46 of file box_definitions.h.

    +

    Definition at line 47 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Reimplemented in shaka::media::mp4::SegmentType.

    -

    Definition at line 131 of file box_definitions.cc.

    +

    Definition at line 143 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/d5/d05/structshaka_1_1media_1_1mp4_1_1OriginalFormat.html b/docs/d5/d05/structshaka_1_1media_1_1mp4_1_1OriginalFormat.html index 62b8d1a200..284c0029da 100644 --- a/docs/d5/d05/structshaka_1_1media_1_1mp4_1_1OriginalFormat.html +++ b/docs/d5/d05/structshaka_1_1media_1_1mp4_1_1OriginalFormat.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::OriginalFormat Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -112,7 +115,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 130 of file box_definitions.h.

    +

    Definition at line 131 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -140,7 +143,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 388 of file box_definitions.cc.

    +

    Definition at line 400 of file box_definitions.cc.

    @@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d5/d09/structshaka_1_1media_1_1mp4_1_1CueIDBox.html b/docs/d5/d09/structshaka_1_1media_1_1mp4_1_1CueIDBox.html index 646190fa99..3ebe0face0 100644 --- a/docs/d5/d09/structshaka_1_1media_1_1mp4_1_1CueIDBox.html +++ b/docs/d5/d09/structshaka_1_1media_1_1mp4_1_1CueIDBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CueIDBox Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -112,7 +115,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 816 of file box_definitions.h.

    +

    Definition at line 834 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -140,7 +143,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2757 of file box_definitions.cc.

    +

    Definition at line 2861 of file box_definitions.cc.

    @@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d5/d0f/structshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes-members.html b/docs/d5/d0f/structshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes-members.html index 629b6f2b3b..90a1a7fd10 100644 --- a/docs/d5/d0f/structshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes-members.html +++ b/docs/d5/d0f/structshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d5/d11/classshaka_1_1media_1_1WebMInfoParser-members.html b/docs/d5/d11/classshaka_1_1media_1_1WebMInfoParser-members.html index 465716c0fe..49ce34fac4 100644 --- a/docs/d5/d11/classshaka_1_1media_1_1WebMInfoParser-members.html +++ b/docs/d5/d11/classshaka_1_1media_1_1WebMInfoParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d5/d11/structshaka_1_1media_1_1mp4_1_1ElementaryStreamDescriptor.html b/docs/d5/d11/structshaka_1_1media_1_1mp4_1_1ElementaryStreamDescriptor.html index ae1d51b069..7885038fed 100644 --- a/docs/d5/d11/structshaka_1_1media_1_1mp4_1_1ElementaryStreamDescriptor.html +++ b/docs/d5/d11/structshaka_1_1media_1_1mp4_1_1ElementaryStreamDescriptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::ElementaryStreamDescriptor Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -124,7 +127,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 307 of file box_definitions.h.

    +

    Definition at line 308 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -152,7 +155,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1654 of file box_definitions.cc.

    +

    Definition at line 1680 of file box_definitions.cc.

    @@ -163,9 +166,7 @@ Additional Inherited Members diff --git a/docs/d5/d13/classshaka_1_1media_1_1ESDescriptor.html b/docs/d5/d13/classshaka_1_1media_1_1ESDescriptor.html index ad5645b7c5..434cb5727e 100644 --- a/docs/d5/d13/classshaka_1_1media_1_1ESDescriptor.html +++ b/docs/d5/d13/classshaka_1_1media_1_1ESDescriptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ESDescriptor Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::BaseDescriptor - -
    + + - - @@ -121,7 +121,7 @@ void 

    Public Member Functions

    uint16_t esid () const
     
    -void set_esid (uint16_t esid)
     
    const DecoderConfigDescriptordecoder_config_descriptor () const
     

    Detailed Description

    This class parses object type and decoder specific information from an elementary stream descriptor, which is usually contained in an esds box. Please refer to ISO 14496 Part 1 7.2.6.5 for more details.

    -

    Definition at line 171 of file es_descriptor.h.

    +

    Definition at line 173 of file es_descriptor.h.


    The documentation for this class was generated from the following files:
    diff --git a/docs/d5/d15/producer__consumer__queue_8h_source.html b/docs/d5/d15/producer__consumer__queue_8h_source.html index 66b315376f..a1c569d8f0 100644 --- a/docs/d5/d15/producer__consumer__queue_8h_source.html +++ b/docs/d5/d15/producer__consumer__queue_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/producer_consumer_queue.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    producer_consumer_queue.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_PRODUCER_CONSUMER_QUEUE_H_
    8 #define PACKAGER_MEDIA_BASE_PRODUCER_CONSUMER_QUEUE_H_
    9 
    10 #include <deque>
    11 
    12 #include "packager/base/strings/stringprintf.h"
    13 #include "packager/base/synchronization/condition_variable.h"
    14 #include "packager/base/synchronization/lock.h"
    15 #include "packager/base/timer/elapsed_timer.h"
    16 #include "packager/status.h"
    17 
    18 namespace shaka {
    19 namespace media {
    20 
    21 static const size_t kUnlimitedCapacity = 0u;
    22 static const int64_t kInfiniteTimeout = -1;
    23 
    27 template <class T>
    29  public:
    33  explicit ProducerConsumerQueue(size_t capacity);
    34 
    39  ProducerConsumerQueue(size_t capacity, size_t starting_pos);
    40 
    42 
    51  Status Push(const T& element, int64_t timeout_ms);
    52 
    60  Status Pop(T* element, int64_t timeout_ms);
    61 
    74  Status Peek(size_t pos, T* element, int64_t timeout_ms);
    75 
    79  void Stop() {
    80  base::AutoLock l(lock_);
    81  stop_requested_ = true;
    82  not_empty_cv_.Broadcast();
    83  not_full_cv_.Broadcast();
    84  new_element_cv_.Broadcast();
    85  }
    86 
    88  bool Empty() const {
    89  base::AutoLock l(lock_);
    90  return q_.empty();
    91  }
    92 
    94  size_t Size() const {
    95  base::AutoLock l(lock_);
    96  return q_.size();
    97  }
    98 
    101  size_t HeadPos() const {
    102  base::AutoLock l(lock_);
    103  return head_pos_;
    104  }
    105 
    108  size_t TailPos() const {
    109  base::AutoLock l(lock_);
    110  return head_pos_ + q_.size() - 1;
    111  }
    112 
    115  bool Stopped() const {
    116  base::AutoLock l(lock_);
    117  return stop_requested_;
    118  }
    119 
    120  private:
    121  // Move head_pos_ to center on pos.
    122  void SlideHeadOnCenter(size_t pos);
    123 
    124  const size_t capacity_; // Maximum number of elements; zero means unlimited.
    125  mutable base::Lock lock_; // Lock protecting all other variables below.
    126  size_t head_pos_; // Head position.
    127  std::deque<T> q_; // Internal queue holding the elements.
    128  base::ConditionVariable not_empty_cv_;
    129  base::ConditionVariable not_full_cv_;
    130  base::ConditionVariable new_element_cv_;
    131  bool stop_requested_; // True after Stop has been called.
    132 
    133  DISALLOW_COPY_AND_ASSIGN(ProducerConsumerQueue);
    134 };
    135 
    136 // Implementations of non-inline functions.
    137 template <class T>
    139  : capacity_(capacity),
    140  head_pos_(0),
    141  not_empty_cv_(&lock_),
    142  not_full_cv_(&lock_),
    143  new_element_cv_(&lock_),
    144  stop_requested_(false) {}
    145 
    146 template <class T>
    148  size_t starting_pos)
    149  : capacity_(capacity),
    150  head_pos_(starting_pos),
    151  not_empty_cv_(&lock_),
    152  not_full_cv_(&lock_),
    153  new_element_cv_(&lock_),
    154  stop_requested_(false) {
    155 }
    156 
    157 template <class T>
    159 
    160 template <class T>
    161 Status ProducerConsumerQueue<T>::Push(const T& element, int64_t timeout_ms) {
    162  base::AutoLock l(lock_);
    163  bool woken = false;
    164 
    165  // Check for queue shutdown.
    166  if (stop_requested_)
    167  return Status(error::STOPPED, "");
    168 
    169  base::ElapsedTimer timer;
    170  base::TimeDelta timeout_delta = base::TimeDelta::FromMilliseconds(timeout_ms);
    171 
    172  if (capacity_) {
    173  while (q_.size() == capacity_) {
    174  if (timeout_ms < 0) {
    175  // Wait forever, or until Stop.
    176  not_full_cv_.Wait();
    177  } else {
    178  base::TimeDelta elapsed = timer.Elapsed();
    179  if (elapsed < timeout_delta) {
    180  // Wait with timeout, or until Stop.
    181  not_full_cv_.TimedWait(timeout_delta - elapsed);
    182  } else {
    183  // We're through waiting.
    184  return Status(error::TIME_OUT, "Time out on pushing.");
    185  }
    186  }
    187  // Re-check for queue shutdown after waking from Wait.
    188  if (stop_requested_)
    189  return Status(error::STOPPED, "");
    190 
    191  woken = true;
    192  }
    193  DCHECK_LT(q_.size(), capacity_);
    194  }
    195 
    196  // Signal consumer to proceed if we are going to create some elements.
    197  if (q_.empty())
    198  not_empty_cv_.Signal();
    199  new_element_cv_.Signal();
    200 
    201  q_.push_back(element);
    202 
    203  // Signal other producers if we just acquired more capacity.
    204  if (woken && q_.size() != capacity_)
    205  not_full_cv_.Signal();
    206  return Status::OK;
    207 }
    208 
    209 template <class T>
    210 Status ProducerConsumerQueue<T>::Pop(T* element, int64_t timeout_ms) {
    211  base::AutoLock l(lock_);
    212  bool woken = false;
    213 
    214  base::ElapsedTimer timer;
    215  base::TimeDelta timeout_delta = base::TimeDelta::FromMilliseconds(timeout_ms);
    216 
    217  while (q_.empty()) {
    218  if (stop_requested_)
    219  return Status(error::STOPPED, "");
    220 
    221  if (timeout_ms < 0) {
    222  // Wait forever, or until Stop.
    223  not_empty_cv_.Wait();
    224  } else {
    225  base::TimeDelta elapsed = timer.Elapsed();
    226  if (elapsed < timeout_delta) {
    227  // Wait with timeout, or until Stop.
    228  not_empty_cv_.TimedWait(timeout_delta - elapsed);
    229  } else {
    230  // We're through waiting.
    231  return Status(error::TIME_OUT, "Time out on popping.");
    232  }
    233  }
    234  woken = true;
    235  }
    236 
    237  // Signal producer to proceed if we are going to create some capacity.
    238  if (q_.size() == capacity_)
    239  not_full_cv_.Signal();
    240 
    241  *element = q_.front();
    242  q_.pop_front();
    243  ++head_pos_;
    244 
    245  // Signal other consumers if we have more elements.
    246  if (woken && !q_.empty())
    247  not_empty_cv_.Signal();
    248  return Status::OK;
    249 }
    250 
    251 template <class T>
    253  T* element,
    254  int64_t timeout_ms) {
    255  base::AutoLock l(lock_);
    256  if (pos < head_pos_) {
    257  return Status(
    258  error::INVALID_ARGUMENT,
    259  base::StringPrintf(
    260  "pos (%zu) is too small; head is at %zu.", pos, head_pos_));
    261  }
    262 
    263  bool woken = false;
    264 
    265  base::ElapsedTimer timer;
    266  base::TimeDelta timeout_delta = base::TimeDelta::FromMilliseconds(timeout_ms);
    267 
    268  // Move head to create some space (move the sliding window centered @ pos).
    269  SlideHeadOnCenter(pos);
    270 
    271  while (pos >= head_pos_ + q_.size()) {
    272  if (stop_requested_)
    273  return Status(error::STOPPED, "");
    274 
    275  if (timeout_ms < 0) {
    276  // Wait forever, or until Stop.
    277  new_element_cv_.Wait();
    278  } else {
    279  base::TimeDelta elapsed = timer.Elapsed();
    280  if (elapsed < timeout_delta) {
    281  // Wait with timeout, or until Stop.
    282  new_element_cv_.TimedWait(timeout_delta - elapsed);
    283  } else {
    284  // We're through waiting.
    285  return Status(error::TIME_OUT, "Time out on peeking.");
    286  }
    287  }
    288  // Move head to create some space (move the sliding window centered @ pos).
    289  SlideHeadOnCenter(pos);
    290  woken = true;
    291  }
    292 
    293  *element = q_[pos - head_pos_];
    294 
    295  // Signal other consumers if we have more elements.
    296  if (woken && !q_.empty())
    297  new_element_cv_.Signal();
    298  return Status::OK;
    299 }
    300 
    301 template <class T>
    303  lock_.AssertAcquired();
    304 
    305  if (capacity_) {
    306  // Signal producer to proceed if we are going to create some capacity.
    307  if (q_.size() == capacity_ && pos > head_pos_ + capacity_ / 2)
    308  not_full_cv_.Signal();
    309 
    310  while (!q_.empty() && pos > head_pos_ + capacity_ / 2) {
    311  ++head_pos_;
    312  q_.pop_front();
    313  }
    314  }
    315 }
    316 
    317 } // namespace media
    318 } // namespace shaka
    319 
    320 #endif // PACKAGER_MEDIA_BASE_PRODUCER_CONSUMER_QUEUE_H_
    Status Peek(size_t pos, T *element, int64_t timeout_ms)
    - - - - -
    All the methods that are virtual are virtual for mocking.
    - - - - -
    Status Pop(T *element, int64_t timeout_ms)
    -
    Status Push(const T &element, int64_t timeout_ms)
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_PRODUCER_CONSUMER_QUEUE_H_
    +
    8 #define PACKAGER_MEDIA_BASE_PRODUCER_CONSUMER_QUEUE_H_
    +
    9 
    +
    10 #include <deque>
    +
    11 
    +
    12 #include "packager/base/strings/stringprintf.h"
    +
    13 #include "packager/base/synchronization/condition_variable.h"
    +
    14 #include "packager/base/synchronization/lock.h"
    +
    15 #include "packager/base/timer/elapsed_timer.h"
    +
    16 #include "packager/status.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    +
    21 static const size_t kUnlimitedCapacity = 0u;
    +
    22 static const int64_t kInfiniteTimeout = -1;
    +
    23 
    +
    27 template <class T>
    + +
    29  public:
    +
    33  explicit ProducerConsumerQueue(size_t capacity);
    +
    34 
    +
    39  ProducerConsumerQueue(size_t capacity, size_t starting_pos);
    +
    40 
    + +
    42 
    +
    51  Status Push(const T& element, int64_t timeout_ms);
    +
    52 
    +
    60  Status Pop(T* element, int64_t timeout_ms);
    +
    61 
    +
    74  Status Peek(size_t pos, T* element, int64_t timeout_ms);
    +
    75 
    +
    79  void Stop() {
    +
    80  base::AutoLock l(lock_);
    +
    81  stop_requested_ = true;
    +
    82  not_empty_cv_.Broadcast();
    +
    83  not_full_cv_.Broadcast();
    +
    84  new_element_cv_.Broadcast();
    +
    85  }
    +
    86 
    +
    88  bool Empty() const {
    +
    89  base::AutoLock l(lock_);
    +
    90  return q_.empty();
    +
    91  }
    +
    92 
    +
    94  size_t Size() const {
    +
    95  base::AutoLock l(lock_);
    +
    96  return q_.size();
    +
    97  }
    +
    98 
    +
    101  size_t HeadPos() const {
    +
    102  base::AutoLock l(lock_);
    +
    103  return head_pos_;
    +
    104  }
    +
    105 
    +
    108  size_t TailPos() const {
    +
    109  base::AutoLock l(lock_);
    +
    110  return head_pos_ + q_.size() - 1;
    +
    111  }
    +
    112 
    +
    115  bool Stopped() const {
    +
    116  base::AutoLock l(lock_);
    +
    117  return stop_requested_;
    +
    118  }
    +
    119 
    +
    120  private:
    +
    121  // Move head_pos_ to center on pos.
    +
    122  void SlideHeadOnCenter(size_t pos);
    +
    123 
    +
    124  const size_t capacity_; // Maximum number of elements; zero means unlimited.
    +
    125  mutable base::Lock lock_; // Lock protecting all other variables below.
    +
    126  size_t head_pos_; // Head position.
    +
    127  std::deque<T> q_; // Internal queue holding the elements.
    +
    128  base::ConditionVariable not_empty_cv_;
    +
    129  base::ConditionVariable not_full_cv_;
    +
    130  base::ConditionVariable new_element_cv_;
    +
    131  bool stop_requested_; // True after Stop has been called.
    +
    132 
    +
    133  DISALLOW_COPY_AND_ASSIGN(ProducerConsumerQueue);
    +
    134 };
    +
    135 
    +
    136 // Implementations of non-inline functions.
    +
    137 template <class T>
    + +
    139  : capacity_(capacity),
    +
    140  head_pos_(0),
    +
    141  not_empty_cv_(&lock_),
    +
    142  not_full_cv_(&lock_),
    +
    143  new_element_cv_(&lock_),
    +
    144  stop_requested_(false) {}
    +
    145 
    +
    146 template <class T>
    + +
    148  size_t starting_pos)
    +
    149  : capacity_(capacity),
    +
    150  head_pos_(starting_pos),
    +
    151  not_empty_cv_(&lock_),
    +
    152  not_full_cv_(&lock_),
    +
    153  new_element_cv_(&lock_),
    +
    154  stop_requested_(false) {
    +
    155 }
    +
    156 
    +
    157 template <class T>
    + +
    159 
    +
    160 template <class T>
    +
    161 Status ProducerConsumerQueue<T>::Push(const T& element, int64_t timeout_ms) {
    +
    162  base::AutoLock l(lock_);
    +
    163  bool woken = false;
    +
    164 
    +
    165  // Check for queue shutdown.
    +
    166  if (stop_requested_)
    +
    167  return Status(error::STOPPED, "");
    +
    168 
    +
    169  base::ElapsedTimer timer;
    +
    170  base::TimeDelta timeout_delta = base::TimeDelta::FromMilliseconds(timeout_ms);
    +
    171 
    +
    172  if (capacity_) {
    +
    173  while (q_.size() == capacity_) {
    +
    174  if (timeout_ms < 0) {
    +
    175  // Wait forever, or until Stop.
    +
    176  not_full_cv_.Wait();
    +
    177  } else {
    +
    178  base::TimeDelta elapsed = timer.Elapsed();
    +
    179  if (elapsed < timeout_delta) {
    +
    180  // Wait with timeout, or until Stop.
    +
    181  not_full_cv_.TimedWait(timeout_delta - elapsed);
    +
    182  } else {
    +
    183  // We're through waiting.
    +
    184  return Status(error::TIME_OUT, "Time out on pushing.");
    +
    185  }
    +
    186  }
    +
    187  // Re-check for queue shutdown after waking from Wait.
    +
    188  if (stop_requested_)
    +
    189  return Status(error::STOPPED, "");
    +
    190 
    +
    191  woken = true;
    +
    192  }
    +
    193  DCHECK_LT(q_.size(), capacity_);
    +
    194  }
    +
    195 
    +
    196  // Signal consumer to proceed if we are going to create some elements.
    +
    197  if (q_.empty())
    +
    198  not_empty_cv_.Signal();
    +
    199  new_element_cv_.Signal();
    +
    200 
    +
    201  q_.push_back(element);
    +
    202 
    +
    203  // Signal other producers if we just acquired more capacity.
    +
    204  if (woken && q_.size() != capacity_)
    +
    205  not_full_cv_.Signal();
    +
    206  return Status::OK;
    +
    207 }
    +
    208 
    +
    209 template <class T>
    +
    210 Status ProducerConsumerQueue<T>::Pop(T* element, int64_t timeout_ms) {
    +
    211  base::AutoLock l(lock_);
    +
    212  bool woken = false;
    +
    213 
    +
    214  base::ElapsedTimer timer;
    +
    215  base::TimeDelta timeout_delta = base::TimeDelta::FromMilliseconds(timeout_ms);
    +
    216 
    +
    217  while (q_.empty()) {
    +
    218  if (stop_requested_)
    +
    219  return Status(error::STOPPED, "");
    +
    220 
    +
    221  if (timeout_ms < 0) {
    +
    222  // Wait forever, or until Stop.
    +
    223  not_empty_cv_.Wait();
    +
    224  } else {
    +
    225  base::TimeDelta elapsed = timer.Elapsed();
    +
    226  if (elapsed < timeout_delta) {
    +
    227  // Wait with timeout, or until Stop.
    +
    228  not_empty_cv_.TimedWait(timeout_delta - elapsed);
    +
    229  } else {
    +
    230  // We're through waiting.
    +
    231  return Status(error::TIME_OUT, "Time out on popping.");
    +
    232  }
    +
    233  }
    +
    234  woken = true;
    +
    235  }
    +
    236 
    +
    237  // Signal producer to proceed if we are going to create some capacity.
    +
    238  if (q_.size() == capacity_)
    +
    239  not_full_cv_.Signal();
    +
    240 
    +
    241  *element = q_.front();
    +
    242  q_.pop_front();
    +
    243  ++head_pos_;
    +
    244 
    +
    245  // Signal other consumers if we have more elements.
    +
    246  if (woken && !q_.empty())
    +
    247  not_empty_cv_.Signal();
    +
    248  return Status::OK;
    +
    249 }
    +
    250 
    +
    251 template <class T>
    + +
    253  T* element,
    +
    254  int64_t timeout_ms) {
    +
    255  base::AutoLock l(lock_);
    +
    256  if (pos < head_pos_) {
    +
    257  return Status(
    +
    258  error::INVALID_ARGUMENT,
    +
    259  base::StringPrintf(
    +
    260  "pos (%zu) is too small; head is at %zu.", pos, head_pos_));
    +
    261  }
    +
    262 
    +
    263  bool woken = false;
    +
    264 
    +
    265  base::ElapsedTimer timer;
    +
    266  base::TimeDelta timeout_delta = base::TimeDelta::FromMilliseconds(timeout_ms);
    +
    267 
    +
    268  // Move head to create some space (move the sliding window centered @ pos).
    +
    269  SlideHeadOnCenter(pos);
    +
    270 
    +
    271  while (pos >= head_pos_ + q_.size()) {
    +
    272  if (stop_requested_)
    +
    273  return Status(error::STOPPED, "");
    +
    274 
    +
    275  if (timeout_ms < 0) {
    +
    276  // Wait forever, or until Stop.
    +
    277  new_element_cv_.Wait();
    +
    278  } else {
    +
    279  base::TimeDelta elapsed = timer.Elapsed();
    +
    280  if (elapsed < timeout_delta) {
    +
    281  // Wait with timeout, or until Stop.
    +
    282  new_element_cv_.TimedWait(timeout_delta - elapsed);
    +
    283  } else {
    +
    284  // We're through waiting.
    +
    285  return Status(error::TIME_OUT, "Time out on peeking.");
    +
    286  }
    +
    287  }
    +
    288  // Move head to create some space (move the sliding window centered @ pos).
    +
    289  SlideHeadOnCenter(pos);
    +
    290  woken = true;
    +
    291  }
    +
    292 
    +
    293  *element = q_[pos - head_pos_];
    +
    294 
    +
    295  // Signal other consumers if we have more elements.
    +
    296  if (woken && !q_.empty())
    +
    297  new_element_cv_.Signal();
    +
    298  return Status::OK;
    +
    299 }
    +
    300 
    +
    301 template <class T>
    + +
    303  lock_.AssertAcquired();
    +
    304 
    +
    305  if (capacity_) {
    +
    306  // Signal producer to proceed if we are going to create some capacity.
    +
    307  if (q_.size() == capacity_ && pos > head_pos_ + capacity_ / 2)
    +
    308  not_full_cv_.Signal();
    +
    309 
    +
    310  while (!q_.empty() && pos > head_pos_ + capacity_ / 2) {
    +
    311  ++head_pos_;
    +
    312  q_.pop_front();
    +
    313  }
    +
    314  }
    +
    315 }
    +
    316 
    +
    317 } // namespace media
    +
    318 } // namespace shaka
    +
    319 
    +
    320 #endif // PACKAGER_MEDIA_BASE_PRODUCER_CONSUMER_QUEUE_H_
    + + + + + +
    Status Push(const T &element, int64_t timeout_ms)
    + + +
    Status Peek(size_t pos, T *element, int64_t timeout_ms)
    +
    Status Pop(T *element, int64_t timeout_ms)
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d1a/classshaka_1_1Packager-members.html b/docs/d5/d1a/classshaka_1_1Packager-members.html index 463a045e2f..56c546115d 100644 --- a/docs/d5/d1a/classshaka_1_1Packager-members.html +++ b/docs/d5/d1a/classshaka_1_1Packager-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d5/d1a/ts__section_8h_source.html b/docs/d5/d1a/ts__section_8h_source.html index 7f1ddc05ff..86b8d00341 100644 --- a/docs/d5/d1a/ts__section_8h_source.html +++ b/docs/d5/d1a/ts__section_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    ts_section.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_H_
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_H_
    7 
    8 namespace shaka {
    9 namespace media {
    10 namespace mp2t {
    11 
    12 class TsSection {
    13  public:
    14  // From ISO/IEC 13818-1 or ITU H.222 spec: Table 2-3 - PID table.
    15  enum SpecialPid {
    16  kPidPat = 0x0,
    17  kPidCat = 0x1,
    18  kPidTsdt = 0x2,
    19  kPidNullPacket = 0x1fff,
    20  kPidMax = 0x1fff,
    21  };
    22 
    23  virtual ~TsSection() {}
    24 
    25  // Parse the data bytes of the TS packet.
    26  // Return true if parsing is successful.
    27  virtual bool Parse(bool payload_unit_start_indicator,
    28  const uint8_t* buf,
    29  int size) = 0;
    30 
    31  // Process bytes that have not been processed yet (pending buffers in the
    32  // pipe). Flush might thus results in frame emission, as an example.
    33  virtual void Flush() = 0;
    34 
    35  // Reset the state of the parser to its initial state.
    36  virtual void Reset() = 0;
    37 };
    38 
    39 } // namespace mp2t
    40 } // namespace media
    41 } // namespace shaka
    42 
    43 #endif
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_H_
    +
    7 
    +
    8 namespace shaka {
    +
    9 namespace media {
    +
    10 namespace mp2t {
    +
    11 
    +
    12 class TsSection {
    +
    13  public:
    +
    14  // From ISO/IEC 13818-1 or ITU H.222 spec: Table 2-3 - PID table.
    +
    15  enum SpecialPid {
    +
    16  kPidPat = 0x0,
    +
    17  kPidCat = 0x1,
    +
    18  kPidTsdt = 0x2,
    +
    19  kPidNullPacket = 0x1fff,
    +
    20  kPidMax = 0x1fff,
    +
    21  };
    +
    22 
    +
    23  virtual ~TsSection() {}
    +
    24 
    +
    25  // Parse the data bytes of the TS packet.
    +
    26  // Return true if parsing is successful.
    +
    27  virtual bool Parse(bool payload_unit_start_indicator,
    +
    28  const uint8_t* buf,
    +
    29  int size) = 0;
    +
    30 
    +
    31  // Process bytes that have not been processed yet (pending buffers in the
    +
    32  // pipe). Flush might thus results in frame emission, as an example.
    +
    33  virtual bool Flush() = 0;
    +
    34 
    +
    35  // Reset the state of the parser to its initial state.
    +
    36  virtual void Reset() = 0;
    +
    37 };
    +
    38 
    +
    39 } // namespace mp2t
    +
    40 } // namespace media
    +
    41 } // namespace shaka
    +
    42 
    +
    43 #endif
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d1d/playready__pssh__generator_8cc_source.html b/docs/d5/d1d/playready__pssh__generator_8cc_source.html index a16047a886..c599087766 100644 --- a/docs/d5/d1d/playready__pssh__generator_8cc_source.html +++ b/docs/d5/d1d/playready__pssh__generator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/playready_pssh_generator.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    playready_pssh_generator.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/playready_pssh_generator.h"
    8 
    9 #include <openssl/aes.h>
    10 #include <algorithm>
    11 #include <memory>
    12 #include <set>
    13 #include <vector>
    14 
    15 #include "packager/base/base64.h"
    16 #include "packager/base/logging.h"
    17 #include "packager/base/strings/string_number_conversions.h"
    18 #include "packager/base/strings/string_util.h"
    19 #include "packager/media/base/buffer_writer.h"
    20 #include "packager/media/base/protection_system_ids.h"
    21 
    22 namespace shaka {
    23 namespace media {
    24 namespace {
    25 
    26 const uint8_t kPlayReadyPsshBoxVersion = 0;
    27 
    28 // For PlayReady clients 1.0+ that support CTR keys.
    29 const std::string kPlayHeaderObject_4_0 =
    30  "<WRMHEADER "
    31  "xmlns=\"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader\" "
    32  "version=\"4.0.0.0\"><DATA>"
    33  "<PROTECTINFO><KEYLEN>16</KEYLEN><ALGID>AESCTR</ALGID></PROTECTINFO>"
    34  "<KID>$0</KID><CHECKSUM>$1</CHECKSUM>"
    35  "</DATA></WRMHEADER>";
    36 
    37 // For PlayReady clients 4.0+ that support CBC keys.
    38 const std::string kPlayHeaderObject_4_3 =
    39  "<WRMHEADER "
    40  "xmlns=\"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader\" "
    41  "version=\"4.3.0.0\"><DATA><PROTECTINFO><KIDS>"
    42  "<KID ALGID=\"AESCBC\" VALUE=\"$0\"></KID>"
    43  "</KIDS></PROTECTINFO></DATA></WRMHEADER>";
    44 
    45 // Converts the key_id's endianness.
    46 std::vector<uint8_t> ConvertGuidEndianness(const std::vector<uint8_t>& input) {
    47  std::vector<uint8_t> output = input;
    48  if (output.size() > 7) { // Defensive check.
    49  output[0] = input[3];
    50  output[1] = input[2];
    51  output[2] = input[1];
    52  output[3] = input[0];
    53  output[4] = input[5];
    54  output[5] = input[4];
    55  output[6] = input[7];
    56  output[7] = input[6];
    57  // 8-15 are an array of bytes with no endianness.
    58  }
    59  return output;
    60 }
    61 
    62 // Generates the data section of a PlayReady PSSH.
    63 // PlayReady PSSH Data is a PlayReady Header Object, which is described at
    64 // https://docs.microsoft.com/en-us/playready/specifications/playready-header-specification
    65 Status GeneratePlayReadyPsshData(const std::vector<uint8_t>& key_id,
    66  const std::vector<uint8_t>& key,
    67  const FourCC protection_scheme,
    68  std::vector<uint8_t>* output) {
    69  CHECK(output);
    70  std::vector<uint8_t> key_id_converted = ConvertGuidEndianness(key_id);
    71  std::vector<uint8_t> encrypted_key_id(key_id_converted.size());
    72  std::unique_ptr<AES_KEY> aes_key(new AES_KEY);
    73  CHECK_EQ(AES_set_encrypt_key(key.data(), key.size() * 8, aes_key.get()), 0);
    74  AES_ecb_encrypt(key_id_converted.data(), encrypted_key_id.data(),
    75  aes_key.get(), AES_ENCRYPT);
    76  std::string checksum =
    77  std::string(encrypted_key_id.begin(), encrypted_key_id.end())
    78  .substr(0, 8);
    79  std::string base64_checksum;
    80  base::Base64Encode(checksum, &base64_checksum);
    81  std::string base64_key_id;
    82  base::Base64Encode(
    83  std::string(key_id_converted.begin(), key_id_converted.end()),
    84  &base64_key_id);
    85 
    86  std::string playready_header;
    87 
    88  switch (protection_scheme) {
    89  case FOURCC_cbc1:
    90  case FOURCC_cbcs:
    91  playready_header = kPlayHeaderObject_4_3;
    92  base::ReplaceFirstSubstringAfterOffset(&playready_header, 0, "$0",
    93  base64_key_id);
    94  break;
    95 
    96  case FOURCC_cenc:
    97  case FOURCC_cens:
    98  playready_header = kPlayHeaderObject_4_0;
    99  base::ReplaceFirstSubstringAfterOffset(&playready_header, 0, "$0",
    100  base64_key_id);
    101  base::ReplaceFirstSubstringAfterOffset(&playready_header, 0, "$1",
    102  base64_checksum);
    103  break;
    104 
    105  default:
    106  return Status(error::INVALID_ARGUMENT,
    107  "The provided protection scheme is not supported.");
    108  }
    109 
    110  // Create a PlayReady Record.
    111  // Outline in section '2.PlayReady Records' of
    112  // 'PlayReady Header Object' document. Note data is in little endian format.
    113  std::vector<uint16_t> record_value =
    114  std::vector<uint16_t>(playready_header.begin(), playready_header.end());
    115  shaka::media::BufferWriter writer_pr_record;
    116  uint16_t record_type =
    117  1; // Indicates that the record contains a rights management header.
    118  uint16_t record_length = record_value.size() * 2;
    119  writer_pr_record.AppendInt(static_cast<uint8_t>(record_type & 0xff));
    120  writer_pr_record.AppendInt(static_cast<uint8_t>((record_type >> 8) & 0xff));
    121  writer_pr_record.AppendInt(static_cast<uint8_t>(record_length & 0xff));
    122  writer_pr_record.AppendInt(static_cast<uint8_t>((record_length >> 8) & 0xff));
    123  for (auto record_item : record_value) {
    124  writer_pr_record.AppendInt(static_cast<uint8_t>(record_item & 0xff));
    125  writer_pr_record.AppendInt(static_cast<uint8_t>((record_item >> 8) & 0xff));
    126  }
    127 
    128  // Create the PlayReady Header object.
    129  // Outline in section '1.PlayReady Header Objects' of
    130  // 'PlayReady Header Object' document. Note data is in little endian format.
    131  shaka::media::BufferWriter writer_pr_header_object;
    132  uint32_t playready_header_length = writer_pr_record.Size() + 4 + 2;
    133  uint16_t record_count = 1;
    134  writer_pr_header_object.AppendInt(
    135  static_cast<uint8_t>(playready_header_length & 0xff));
    136  writer_pr_header_object.AppendInt(
    137  static_cast<uint8_t>((playready_header_length >> 8) & 0xff));
    138  writer_pr_header_object.AppendInt(
    139  static_cast<uint8_t>((playready_header_length >> 16) & 0xff));
    140  writer_pr_header_object.AppendInt(
    141  static_cast<uint8_t>((playready_header_length >> 24) & 0xff));
    142  writer_pr_header_object.AppendInt(static_cast<uint8_t>(record_count & 0xff));
    143  writer_pr_header_object.AppendInt(
    144  static_cast<uint8_t>((record_count >> 8) & 0xff));
    145  writer_pr_header_object.AppendBuffer(writer_pr_record);
    146  *output = std::vector<uint8_t>(
    147  writer_pr_header_object.Buffer(),
    148  writer_pr_header_object.Buffer() + writer_pr_header_object.Size());
    149  return Status::OK;
    150 }
    151 } // namespace
    152 
    153 PlayReadyPsshGenerator::PlayReadyPsshGenerator(FourCC protection_scheme)
    154  : PsshGenerator(std::vector<uint8_t>(std::begin(kPlayReadySystemId),
    155  std::end(kPlayReadySystemId)),
    156  kPlayReadyPsshBoxVersion),
    157  protection_scheme_(protection_scheme) {}
    158 
    159 PlayReadyPsshGenerator::~PlayReadyPsshGenerator() {}
    160 
    162  return false;
    163 }
    164 
    165 base::Optional<std::vector<uint8_t>>
    166 PlayReadyPsshGenerator::GeneratePsshDataFromKeyIdAndKey(
    167  const std::vector<uint8_t>& key_id,
    168  const std::vector<uint8_t>& key) const {
    169  std::vector<uint8_t> pssh_data;
    170  Status status =
    171  GeneratePlayReadyPsshData(key_id, key, protection_scheme_, &pssh_data);
    172  if (!status.ok()) {
    173  LOG(ERROR) << status.ToString();
    174  return base::nullopt;
    175  }
    176 
    177  return pssh_data;
    178 }
    179 
    180 base::Optional<std::vector<uint8_t>>
    181 PlayReadyPsshGenerator::GeneratePsshDataFromKeyIds(
    182  const std::vector<std::vector<uint8_t>>& key_ids) const {
    183  NOTIMPLEMENTED();
    184  return base::nullopt;
    185 }
    186 
    187 } // namespace media
    188 } // namespace shaka
    std::string ToString() const
    Definition: status.cc:83
    -
    const uint8_t * Buffer() const
    Definition: buffer_writer.h:61
    -
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    - - - - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/playready_pssh_generator.h"
    +
    8 
    +
    9 #include <openssl/aes.h>
    +
    10 #include <algorithm>
    +
    11 #include <memory>
    +
    12 #include <set>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/base/base64.h"
    +
    16 #include "packager/base/logging.h"
    +
    17 #include "packager/base/strings/string_number_conversions.h"
    +
    18 #include "packager/base/strings/string_util.h"
    +
    19 #include "packager/media/base/buffer_writer.h"
    +
    20 #include "packager/media/base/protection_system_ids.h"
    +
    21 
    +
    22 namespace shaka {
    +
    23 namespace media {
    +
    24 namespace {
    +
    25 
    +
    26 const uint8_t kPlayReadyPsshBoxVersion = 0;
    +
    27 
    +
    28 // For PlayReady clients 1.0+ that support CTR keys.
    +
    29 const std::string kPlayHeaderObject_4_0 =
    +
    30  "<WRMHEADER "
    +
    31  "xmlns=\"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader\" "
    +
    32  "version=\"4.0.0.0\"><DATA>"
    +
    33  "<PROTECTINFO><KEYLEN>16</KEYLEN><ALGID>AESCTR</ALGID></PROTECTINFO>"
    +
    34  "<KID>$0</KID><CHECKSUM>$1</CHECKSUM>"
    +
    35  "</DATA>$2</WRMHEADER>";
    +
    36 
    +
    37 // For PlayReady clients 4.0+ that support CBC keys.
    +
    38 const std::string kPlayHeaderObject_4_3 =
    +
    39  "<WRMHEADER "
    +
    40  "xmlns=\"http://schemas.microsoft.com/DRM/2007/03/PlayReadyHeader\" "
    +
    41  "version=\"4.3.0.0\"><DATA><PROTECTINFO><KIDS>"
    +
    42  "<KID ALGID=\"AESCBC\" VALUE=\"$0\"></KID>"
    +
    43  "</KIDS></PROTECTINFO></DATA>$1</WRMHEADER>";
    +
    44 
    +
    45 // Converts the key_id's endianness.
    +
    46 std::vector<uint8_t> ConvertGuidEndianness(const std::vector<uint8_t>& input) {
    +
    47  std::vector<uint8_t> output = input;
    +
    48  if (output.size() > 7) { // Defensive check.
    +
    49  output[0] = input[3];
    +
    50  output[1] = input[2];
    +
    51  output[2] = input[1];
    +
    52  output[3] = input[0];
    +
    53  output[4] = input[5];
    +
    54  output[5] = input[4];
    +
    55  output[6] = input[7];
    +
    56  output[7] = input[6];
    +
    57  // 8-15 are an array of bytes with no endianness.
    +
    58  }
    +
    59  return output;
    +
    60 }
    +
    61 
    +
    62 // Generates the data section of a PlayReady PSSH.
    +
    63 // PlayReady PSSH Data is a PlayReady Header Object, which is described at
    +
    64 // https://docs.microsoft.com/en-us/playready/specifications/playready-header-specification
    +
    65 Status GeneratePlayReadyPsshData(const std::vector<uint8_t>& key_id,
    +
    66  const std::vector<uint8_t>& key,
    +
    67  const std::string& extra_header_data,
    +
    68  const FourCC protection_scheme,
    +
    69  std::vector<uint8_t>* output) {
    +
    70  CHECK(output);
    +
    71  std::vector<uint8_t> key_id_converted = ConvertGuidEndianness(key_id);
    +
    72  std::vector<uint8_t> encrypted_key_id(key_id_converted.size());
    +
    73  std::unique_ptr<AES_KEY> aes_key(new AES_KEY);
    +
    74  CHECK_EQ(AES_set_encrypt_key(key.data(), key.size() * 8, aes_key.get()), 0);
    +
    75  AES_ecb_encrypt(key_id_converted.data(), encrypted_key_id.data(),
    +
    76  aes_key.get(), AES_ENCRYPT);
    +
    77  std::string checksum =
    +
    78  std::string(encrypted_key_id.begin(), encrypted_key_id.end())
    +
    79  .substr(0, 8);
    +
    80  std::string base64_checksum;
    +
    81  base::Base64Encode(checksum, &base64_checksum);
    +
    82  std::string base64_key_id;
    +
    83  base::Base64Encode(
    +
    84  std::string(key_id_converted.begin(), key_id_converted.end()),
    +
    85  &base64_key_id);
    +
    86 
    +
    87  std::string playready_header;
    +
    88 
    +
    89  switch (protection_scheme) {
    +
    90  case kAppleSampleAesProtectionScheme:
    +
    91  case FOURCC_cbc1:
    +
    92  case FOURCC_cbcs:
    +
    93  playready_header = kPlayHeaderObject_4_3;
    +
    94  base::ReplaceFirstSubstringAfterOffset(&playready_header, 0, "$0",
    +
    95  base64_key_id);
    +
    96  base::ReplaceFirstSubstringAfterOffset(&playready_header, 0, "$1",
    +
    97  extra_header_data);
    +
    98  break;
    +
    99 
    +
    100  case FOURCC_cenc:
    +
    101  case FOURCC_cens:
    +
    102  playready_header = kPlayHeaderObject_4_0;
    +
    103  base::ReplaceFirstSubstringAfterOffset(&playready_header, 0, "$0",
    +
    104  base64_key_id);
    +
    105  base::ReplaceFirstSubstringAfterOffset(&playready_header, 0, "$1",
    +
    106  base64_checksum);
    +
    107  base::ReplaceFirstSubstringAfterOffset(&playready_header, 0, "$2",
    +
    108  extra_header_data);
    +
    109  break;
    +
    110 
    +
    111  default:
    +
    112  return Status(error::INVALID_ARGUMENT,
    +
    113  "The provided protection scheme is not supported.");
    +
    114  }
    +
    115 
    +
    116  // Create a PlayReady Record.
    +
    117  // Outline in section '2.PlayReady Records' of
    +
    118  // 'PlayReady Header Object' document. Note data is in little endian format.
    +
    119  std::vector<uint16_t> record_value =
    +
    120  std::vector<uint16_t>(playready_header.begin(), playready_header.end());
    +
    121  shaka::media::BufferWriter writer_pr_record;
    +
    122  uint16_t record_type =
    +
    123  1; // Indicates that the record contains a rights management header.
    +
    124  uint16_t record_length = record_value.size() * 2;
    +
    125  writer_pr_record.AppendInt(static_cast<uint8_t>(record_type & 0xff));
    +
    126  writer_pr_record.AppendInt(static_cast<uint8_t>((record_type >> 8) & 0xff));
    +
    127  writer_pr_record.AppendInt(static_cast<uint8_t>(record_length & 0xff));
    +
    128  writer_pr_record.AppendInt(static_cast<uint8_t>((record_length >> 8) & 0xff));
    +
    129  for (auto record_item : record_value) {
    +
    130  writer_pr_record.AppendInt(static_cast<uint8_t>(record_item & 0xff));
    +
    131  writer_pr_record.AppendInt(static_cast<uint8_t>((record_item >> 8) & 0xff));
    +
    132  }
    +
    133 
    +
    134  // Create the PlayReady Header object.
    +
    135  // Outline in section '1.PlayReady Header Objects' of
    +
    136  // 'PlayReady Header Object' document. Note data is in little endian format.
    +
    137  shaka::media::BufferWriter writer_pr_header_object;
    +
    138  uint32_t playready_header_length = writer_pr_record.Size() + 4 + 2;
    +
    139  uint16_t record_count = 1;
    +
    140  writer_pr_header_object.AppendInt(
    +
    141  static_cast<uint8_t>(playready_header_length & 0xff));
    +
    142  writer_pr_header_object.AppendInt(
    +
    143  static_cast<uint8_t>((playready_header_length >> 8) & 0xff));
    +
    144  writer_pr_header_object.AppendInt(
    +
    145  static_cast<uint8_t>((playready_header_length >> 16) & 0xff));
    +
    146  writer_pr_header_object.AppendInt(
    +
    147  static_cast<uint8_t>((playready_header_length >> 24) & 0xff));
    +
    148  writer_pr_header_object.AppendInt(static_cast<uint8_t>(record_count & 0xff));
    +
    149  writer_pr_header_object.AppendInt(
    +
    150  static_cast<uint8_t>((record_count >> 8) & 0xff));
    +
    151  writer_pr_header_object.AppendBuffer(writer_pr_record);
    +
    152  *output = std::vector<uint8_t>(
    +
    153  writer_pr_header_object.Buffer(),
    +
    154  writer_pr_header_object.Buffer() + writer_pr_header_object.Size());
    +
    155  return Status::OK;
    +
    156 }
    +
    157 } // namespace
    +
    158 
    +
    159 PlayReadyPsshGenerator::PlayReadyPsshGenerator(
    +
    160  const std::string& extra_header_data,
    +
    161  FourCC protection_scheme)
    +
    162  : PsshGenerator(std::vector<uint8_t>(std::begin(kPlayReadySystemId),
    +
    163  std::end(kPlayReadySystemId)),
    +
    164  kPlayReadyPsshBoxVersion),
    +
    165  extra_header_data_(extra_header_data),
    +
    166  protection_scheme_(protection_scheme) {}
    +
    167 
    +
    168 PlayReadyPsshGenerator::~PlayReadyPsshGenerator() {}
    +
    169 
    +
    170 bool PlayReadyPsshGenerator::SupportMultipleKeys() {
    +
    171  return false;
    +
    172 }
    +
    173 
    +
    174 base::Optional<std::vector<uint8_t>>
    +
    175 PlayReadyPsshGenerator::GeneratePsshDataFromKeyIdAndKey(
    +
    176  const std::vector<uint8_t>& key_id,
    +
    177  const std::vector<uint8_t>& key) const {
    +
    178  std::vector<uint8_t> pssh_data;
    +
    179  Status status = GeneratePlayReadyPsshData(key_id, key, extra_header_data_,
    +
    180  protection_scheme_, &pssh_data);
    +
    181  if (!status.ok()) {
    +
    182  LOG(ERROR) << status.ToString();
    +
    183  return base::nullopt;
    +
    184  }
    +
    185 
    +
    186  return pssh_data;
    +
    187 }
    +
    188 
    +
    189 base::Optional<std::vector<uint8_t>>
    +
    190 PlayReadyPsshGenerator::GeneratePsshDataFromKeyIds(
    +
    191  const std::vector<std::vector<uint8_t>>& key_ids) const {
    +
    192  NOTIMPLEMENTED();
    +
    193  return base::nullopt;
    +
    194 }
    +
    195 
    +
    196 } // namespace media
    +
    197 } // namespace shaka
    + +
    std::string ToString() const
    Definition: status.cc:83
    + + +
    const uint8_t * Buffer() const
    Definition: buffer_writer.h:61
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d26/classshaka_1_1media_1_1mp4_1_1TrackRunIterator-members.html b/docs/d5/d26/classshaka_1_1media_1_1mp4_1_1TrackRunIterator-members.html index 1e1ad170f8..b2a65f408f 100644 --- a/docs/d5/d26/classshaka_1_1media_1_1mp4_1_1TrackRunIterator-members.html +++ b/docs/d5/d26/classshaka_1_1media_1_1mp4_1_1TrackRunIterator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d5/d27/key__fetcher_8cc_source.html b/docs/d5/d27/key__fetcher_8cc_source.html index 4527f82ead..3dda55fa11 100644 --- a/docs/d5/d27/key__fetcher_8cc_source.html +++ b/docs/d5/d27/key__fetcher_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/key_fetcher.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    key_fetcher.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/key_fetcher.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 
    12 KeyFetcher::KeyFetcher() {}
    13 KeyFetcher::~KeyFetcher() {}
    14 
    15 } // namespace media
    16 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/key_fetcher.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 
    +
    12 KeyFetcher::KeyFetcher() {}
    +
    13 KeyFetcher::~KeyFetcher() {}
    +
    14 
    +
    15 } // namespace media
    +
    16 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d28/webvtt__utils_8cc_source.html b/docs/d5/d28/webvtt__utils_8cc_source.html new file mode 100644 index 0000000000..47dedebf76 --- /dev/null +++ b/docs/d5/d28/webvtt__utils_8cc_source.html @@ -0,0 +1,391 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/webvtt/webvtt_utils.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    webvtt_utils.cc
    +
    +
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webvtt/webvtt_utils.h"
    +
    8 
    +
    9 #include <ctype.h>
    +
    10 #include <inttypes.h>
    +
    11 
    +
    12 #include <regex>
    +
    13 #include <unordered_set>
    +
    14 
    +
    15 #include "packager/base/logging.h"
    +
    16 #include "packager/base/strings/string_number_conversions.h"
    +
    17 #include "packager/base/strings/stringprintf.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 
    +
    22 namespace {
    +
    23 
    +
    24 bool GetTotalMilliseconds(uint64_t hours,
    +
    25  uint64_t minutes,
    +
    26  uint64_t seconds,
    +
    27  uint64_t ms,
    +
    28  uint64_t* out) {
    +
    29  DCHECK(out);
    +
    30  if (minutes > 59 || seconds > 59 || ms > 999) {
    +
    31  VLOG(1) << "Hours:" << hours << " Minutes:" << minutes
    +
    32  << " Seconds:" << seconds << " MS:" << ms
    +
    33  << " shoud have never made it to GetTotalMilliseconds";
    +
    34  return false;
    +
    35  }
    +
    36  *out = 60 * 60 * 1000 * hours + 60 * 1000 * minutes + 1000 * seconds + ms;
    +
    37  return true;
    +
    38 }
    +
    39 
    +
    40 enum class StyleTagKind {
    +
    41  kUnderline,
    +
    42  kBold,
    +
    43  kItalic,
    +
    44 };
    +
    45 
    +
    46 std::string GetOpenTag(StyleTagKind tag) {
    +
    47  switch (tag) {
    +
    48  case StyleTagKind::kUnderline:
    +
    49  return "<u>";
    +
    50  case StyleTagKind::kBold:
    +
    51  return "<b>";
    +
    52  case StyleTagKind::kItalic:
    +
    53  return "<i>";
    +
    54  }
    +
    55  return ""; // Not reached, but Windows doesn't like NOTREACHED.
    +
    56 }
    +
    57 
    +
    58 std::string GetCloseTag(StyleTagKind tag) {
    +
    59  switch (tag) {
    +
    60  case StyleTagKind::kUnderline:
    +
    61  return "</u>";
    +
    62  case StyleTagKind::kBold:
    +
    63  return "</b>";
    +
    64  case StyleTagKind::kItalic:
    +
    65  return "</i>";
    +
    66  }
    +
    67  return ""; // Not reached, but Windows doesn't like NOTREACHED.
    +
    68 }
    +
    69 
    +
    70 std::string WriteFragment(const TextFragment& fragment,
    +
    71  std::list<StyleTagKind>* tags) {
    +
    72  std::string ret;
    +
    73  size_t local_tag_count = 0;
    +
    74  auto has = [tags](StyleTagKind tag) {
    +
    75  return std::find(tags->begin(), tags->end(), tag) != tags->end();
    +
    76  };
    +
    77  auto push_tag = [tags, &local_tag_count, &has](StyleTagKind tag) {
    +
    78  if (has(tag)) {
    +
    79  return std::string();
    +
    80  }
    +
    81  tags->push_back(tag);
    +
    82  local_tag_count++;
    +
    83  return GetOpenTag(tag);
    +
    84  };
    +
    85 
    +
    86  if ((fragment.style.underline == false && has(StyleTagKind::kUnderline)) ||
    +
    87  (fragment.style.bold == false && has(StyleTagKind::kBold)) ||
    +
    88  (fragment.style.italic == false && has(StyleTagKind::kItalic))) {
    +
    89  LOG(WARNING) << "WebVTT output doesn't support disabling "
    +
    90  "underline/bold/italic within a cue";
    +
    91  }
    +
    92 
    +
    93  if (fragment.newline) {
    +
    94  // Newlines represent separate WebVTT cues. So close the existing tags to
    +
    95  // be nice and re-open them on the new line.
    +
    96  for (auto it = tags->rbegin(); it != tags->rend(); it++) {
    +
    97  ret += GetCloseTag(*it);
    +
    98  }
    +
    99  ret += "\n";
    +
    100  for (const auto tag : *tags) {
    +
    101  ret += GetOpenTag(tag);
    +
    102  }
    +
    103  } else {
    +
    104  if (fragment.style.underline == true) {
    +
    105  ret += push_tag(StyleTagKind::kUnderline);
    +
    106  }
    +
    107  if (fragment.style.bold == true) {
    +
    108  ret += push_tag(StyleTagKind::kBold);
    +
    109  }
    +
    110  if (fragment.style.italic == true) {
    +
    111  ret += push_tag(StyleTagKind::kItalic);
    +
    112  }
    +
    113 
    +
    114  if (!fragment.body.empty()) {
    +
    115  // Replace newlines and consecutive whitespace with a single space. If
    +
    116  // the user wanted an explicit newline, they should use the "newline"
    +
    117  // field.
    +
    118  std::regex whitespace("\\s+", std::regex_constants::ECMAScript);
    +
    119  ret += std::regex_replace(fragment.body, whitespace, std::string(" "));
    +
    120  } else {
    +
    121  for (const auto& frag : fragment.sub_fragments) {
    +
    122  ret += WriteFragment(frag, tags);
    +
    123  }
    +
    124  }
    +
    125 
    +
    126  // Pop all the local tags we pushed.
    +
    127  while (local_tag_count > 0) {
    +
    128  ret += GetCloseTag(tags->back());
    +
    129  tags->pop_back();
    +
    130  local_tag_count--;
    +
    131  }
    +
    132  }
    +
    133  return ret;
    +
    134 }
    +
    135 
    +
    136 } // namespace
    +
    137 
    +
    138 bool WebVttTimestampToMs(const base::StringPiece& source, uint64_t* out) {
    +
    139  DCHECK(out);
    +
    140 
    +
    141  if (source.length() < 9) {
    +
    142  LOG(WARNING) << "Timestamp '" << source << "' is mal-formed";
    +
    143  return false;
    +
    144  }
    +
    145 
    +
    146  const size_t minutes_begin = source.length() - 9;
    +
    147  const size_t seconds_begin = source.length() - 6;
    +
    148  const size_t milliseconds_begin = source.length() - 3;
    +
    149 
    +
    150  uint64_t hours = 0;
    +
    151  uint64_t minutes = 0;
    +
    152  uint64_t seconds = 0;
    +
    153  uint64_t ms = 0;
    +
    154 
    +
    155  const bool has_hours =
    +
    156  minutes_begin >= 3 && source[minutes_begin - 1] == ':' &&
    +
    157  base::StringToUint64(source.substr(0, minutes_begin - 1), &hours);
    +
    158 
    +
    159  if ((minutes_begin == 0 || has_hours) && source[seconds_begin - 1] == ':' &&
    +
    160  source[milliseconds_begin - 1] == '.' &&
    +
    161  base::StringToUint64(source.substr(minutes_begin, 2), &minutes) &&
    +
    162  base::StringToUint64(source.substr(seconds_begin, 2), &seconds) &&
    +
    163  base::StringToUint64(source.substr(milliseconds_begin, 3), &ms)) {
    +
    164  return GetTotalMilliseconds(hours, minutes, seconds, ms, out);
    +
    165  }
    +
    166 
    +
    167  LOG(WARNING) << "Timestamp '" << source << "' is mal-formed";
    +
    168  return false;
    +
    169 }
    +
    170 
    +
    171 std::string MsToWebVttTimestamp(uint64_t ms) {
    +
    172  uint64_t remaining = ms;
    +
    173 
    +
    174  uint64_t only_ms = remaining % 1000;
    +
    175  remaining /= 1000;
    +
    176  uint64_t only_seconds = remaining % 60;
    +
    177  remaining /= 60;
    +
    178  uint64_t only_minutes = remaining % 60;
    +
    179  remaining /= 60;
    +
    180  uint64_t only_hours = remaining;
    +
    181 
    +
    182  return base::StringPrintf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64
    +
    183  ".%03" PRIu64,
    +
    184  only_hours, only_minutes, only_seconds, only_ms);
    +
    185 }
    +
    186 
    +
    187 std::string WebVttSettingsToString(const TextSettings& settings) {
    +
    188  std::string ret;
    +
    189  if (!settings.region.empty()) {
    +
    190  ret += " region:";
    +
    191  ret += settings.region;
    +
    192  }
    +
    193  if (settings.line) {
    +
    194  switch (settings.line->type) {
    +
    195  case TextUnitType::kPercent:
    +
    196  ret += " line:";
    +
    197  ret += base::DoubleToString(settings.line->value);
    +
    198  ret += "%";
    +
    199  break;
    +
    200  case TextUnitType::kLines:
    +
    201  ret += " line:";
    +
    202  ret += base::DoubleToString(settings.line->value);
    +
    203  break;
    +
    204  case TextUnitType::kPixels:
    +
    205  LOG(WARNING) << "WebVTT doesn't support pixel line settings";
    +
    206  break;
    +
    207  }
    +
    208  }
    +
    209  if (settings.position) {
    +
    210  if (settings.position->type == TextUnitType::kPercent) {
    +
    211  ret += " position:";
    +
    212  ret += base::DoubleToString(settings.position->value);
    +
    213  ret += "%";
    +
    214  } else {
    +
    215  LOG(WARNING) << "WebVTT only supports percent position settings";
    +
    216  }
    +
    217  }
    +
    218  if (settings.width) {
    +
    219  if (settings.width->type == TextUnitType::kPercent) {
    +
    220  ret += " size:";
    +
    221  ret += base::DoubleToString(settings.width->value);
    +
    222  ret += "%";
    +
    223  } else {
    +
    224  LOG(WARNING) << "WebVTT only supports percent width settings";
    +
    225  }
    +
    226  }
    +
    227  if (settings.height) {
    +
    228  LOG(WARNING) << "WebVTT doesn't support cue heights";
    +
    229  }
    +
    230  if (settings.writing_direction != WritingDirection::kHorizontal) {
    +
    231  ret += " direction:";
    +
    232  if (settings.writing_direction == WritingDirection::kVerticalGrowingLeft) {
    +
    233  ret += "rl";
    +
    234  } else {
    +
    235  ret += "lr";
    +
    236  }
    +
    237  }
    +
    238  switch (settings.text_alignment) {
    +
    239  case TextAlignment::kStart:
    +
    240  ret += " align:start";
    +
    241  break;
    +
    242  case TextAlignment::kEnd:
    +
    243  ret += " align:end";
    +
    244  break;
    +
    245  case TextAlignment::kLeft:
    +
    246  ret += " align:left";
    +
    247  break;
    +
    248  case TextAlignment::kRight:
    +
    249  ret += " align:right";
    +
    250  break;
    +
    251  case TextAlignment::kCenter:
    +
    252  break;
    +
    253  }
    +
    254 
    +
    255  if (!ret.empty()) {
    +
    256  DCHECK_EQ(ret[0], ' ');
    +
    257  ret.erase(0, 1);
    +
    258  }
    +
    259  return ret;
    +
    260 }
    +
    261 
    +
    262 std::string WebVttFragmentToString(const TextFragment& fragment) {
    +
    263  std::list<StyleTagKind> tags;
    +
    264  return WriteFragment(fragment, &tags);
    +
    265 }
    +
    266 
    +
    267 std::string WebVttGetPreamble(const TextStreamInfo& stream_info) {
    +
    268  std::string ret;
    +
    269  for (const auto& pair : stream_info.regions()) {
    +
    270  if (!ret.empty()) {
    +
    271  ret += "\n\n";
    +
    272  }
    +
    273 
    +
    274  if (pair.second.width.type != TextUnitType::kPercent ||
    +
    275  pair.second.height.type != TextUnitType::kLines ||
    +
    276  pair.second.window_anchor_x.type != TextUnitType::kPercent ||
    +
    277  pair.second.window_anchor_y.type != TextUnitType::kPercent ||
    +
    278  pair.second.region_anchor_x.type != TextUnitType::kPercent ||
    +
    279  pair.second.region_anchor_y.type != TextUnitType::kPercent) {
    +
    280  LOG(WARNING) << "Unsupported unit type in WebVTT region";
    +
    281  continue;
    +
    282  }
    +
    283 
    +
    284  base::StringAppendF(
    +
    285  &ret,
    +
    286  "REGION\n"
    +
    287  "id:%s\n"
    +
    288  "width:%f%%\n"
    +
    289  "lines:%d\n"
    +
    290  "viewportanchor:%f%%,%f%%\n"
    +
    291  "regionanchor:%f%%,%f%%",
    +
    292  pair.first.c_str(), pair.second.width.value,
    +
    293  static_cast<int>(pair.second.height.value),
    +
    294  pair.second.window_anchor_x.value, pair.second.window_anchor_y.value,
    +
    295  pair.second.region_anchor_x.value, pair.second.region_anchor_y.value);
    +
    296  if (pair.second.scroll) {
    +
    297  ret += "\nscroll:up";
    +
    298  }
    +
    299  }
    +
    300 
    +
    301  if (!stream_info.css_styles().empty()) {
    +
    302  if (!ret.empty()) {
    +
    303  ret += "\n\n";
    +
    304  }
    +
    305  ret += "STYLE\n" + stream_info.css_styles();
    +
    306  }
    +
    307 
    +
    308  return ret;
    +
    309 }
    +
    310 
    +
    311 } // namespace media
    +
    312 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/d5/d2a/proto__json__util_8cc_source.html b/docs/d5/d2a/proto__json__util_8cc_source.html index c6c8cf10cb..e267610cb7 100644 --- a/docs/d5/d2a/proto__json__util_8cc_source.html +++ b/docs/d5/d2a/proto__json__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/proto_json_util.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    proto_json_util.cc
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/proto_json_util.h"
    8 
    9 #include <google/protobuf/util/json_util.h>
    10 
    11 #include "packager/base/logging.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 std::string MessageToJsonString(const google::protobuf::Message& message) {
    17  google::protobuf::util::JsonPrintOptions json_print_options;
    18  json_print_options.preserve_proto_field_names = true;
    19 
    20  std::string result;
    21  GOOGLE_CHECK_OK(google::protobuf::util::MessageToJsonString(
    22  message, &result, json_print_options));
    23  return result;
    24 }
    25 
    26 bool JsonStringToMessage(const std::string& input,
    27  google::protobuf::Message* message) {
    28  google::protobuf::util::JsonParseOptions json_parse_options;
    29  json_parse_options.ignore_unknown_fields = true;
    30 
    31  auto status = google::protobuf::util::JsonStringToMessage(input, message,
    32  json_parse_options);
    33  if (!status.ok()) {
    34  LOG(ERROR) << "Failed to parse from JSON: " << input
    35  << " error: " << status.error_message();
    36  return false;
    37  }
    38  return true;
    39 }
    40 
    41 } // namespace media
    42 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/proto_json_util.h"
    +
    8 
    +
    9 #include <google/protobuf/util/json_util.h>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 std::string MessageToJsonString(const google::protobuf::Message& message) {
    +
    17  google::protobuf::util::JsonPrintOptions json_print_options;
    +
    18  json_print_options.preserve_proto_field_names = true;
    +
    19 
    +
    20  std::string result;
    +
    21  GOOGLE_CHECK_OK(google::protobuf::util::MessageToJsonString(
    +
    22  message, &result, json_print_options));
    +
    23  return result;
    +
    24 }
    +
    25 
    +
    26 bool JsonStringToMessage(const std::string& input,
    +
    27  google::protobuf::Message* message) {
    +
    28  google::protobuf::util::JsonParseOptions json_parse_options;
    +
    29  json_parse_options.ignore_unknown_fields = true;
    +
    30 
    +
    31  auto status = google::protobuf::util::JsonStringToMessage(input, message,
    +
    32  json_parse_options);
    +
    33  if (!status.ok()) {
    +
    34  LOG(ERROR) << "Failed to parse from JSON: " << input
    +
    35  << " error: " << status.error_message();
    +
    36  return false;
    +
    37  }
    +
    38  return true;
    +
    39 }
    +
    40 
    +
    41 } // namespace media
    +
    42 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d33/classshaka_1_1media_1_1ProducerConsumerQueue.html b/docs/d5/d33/classshaka_1_1media_1_1ProducerConsumerQueue.html index 786e49fe80..a5f1e4953f 100644 --- a/docs/d5/d33/classshaka_1_1media_1_1ProducerConsumerQueue.html +++ b/docs/d5/d33/classshaka_1_1media_1_1ProducerConsumerQueue.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ProducerConsumerQueue< T > Class Template Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d5/d3b/structshaka_1_1media_1_1mp4_1_1Media-members.html b/docs/d5/d3b/structshaka_1_1media_1_1mp4_1_1Media-members.html index a6c2f4ac1a..570d4f466f 100644 --- a/docs/d5/d3b/structshaka_1_1media_1_1mp4_1_1Media-members.html +++ b/docs/d5/d3b/structshaka_1_1media_1_1mp4_1_1Media-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d5/d3e/classshaka_1_1media_1_1TextChunker.html b/docs/d5/d3e/classshaka_1_1media_1_1TextChunker.html index 0757a74b5c..06e318a119 100644 --- a/docs/d5/d3e/classshaka_1_1media_1_1TextChunker.html +++ b/docs/d5/d3e/classshaka_1_1media_1_1TextChunker.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::TextChunker Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MediaHandler - -
    + + @@ -103,9 +106,9 @@ bool  - - + + @@ -168,9 +171,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/d5/d40/webm_2single__segment__segmenter_8h_source.html b/docs/d5/d40/webm_2single__segment__segmenter_8h_source.html index 6125c49c97..bd0f6785bd 100644 --- a/docs/d5/d40/webm_2single__segment__segmenter_8h_source.html +++ b/docs/d5/d40/webm_2single__segment__segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/formats/webm/single_segment_segmenter.h Source File @@ -29,18 +29,21 @@

    Public Member Functions

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    virtual bool ValidateOutputStreamIndex (size_t stream_index) const
    - + +/* @license-end */
    single_segment_segmenter.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SINGLE_SEGMENT_SEGMENTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_SINGLE_SEGMENT_SEGMENTER_H_
    9 
    10 #include "packager/media/formats/webm/segmenter.h"
    11 
    12 #include <memory>
    13 #include "packager/media/formats/webm/mkv_writer.h"
    14 #include "packager/status.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 struct MuxerOptions;
    20 
    21 namespace webm {
    22 
    27  public:
    28  explicit SingleSegmentSegmenter(const MuxerOptions& options);
    29  ~SingleSegmentSegmenter() override;
    30 
    33  Status FinalizeSegment(uint64_t start_timestamp,
    34  uint64_t duration_timestamp,
    35  bool is_subsegment) override;
    36  bool GetInitRangeStartAndEnd(uint64_t* start, uint64_t* end) override;
    37  bool GetIndexRangeStartAndEnd(uint64_t* start, uint64_t* end) override;
    38  std::vector<Range> GetSegmentRanges() override;
    40 
    41  protected:
    42  MkvWriter* writer() { return writer_.get(); }
    43  uint64_t init_end() { return init_end_; }
    44  void set_init_end(uint64_t end) { init_end_ = end; }
    45  void set_index_start(uint64_t start) { index_start_ = start; }
    46  void set_index_end(uint64_t end) { index_end_ = end; }
    47  void set_writer(std::unique_ptr<MkvWriter> writer) {
    48  writer_ = std::move(writer);
    49  }
    50 
    51  // Segmenter implementation overrides.
    52  Status DoInitialize() override;
    53  Status DoFinalize() override;
    54 
    55  private:
    56  // Segmenter implementation overrides.
    57  Status NewSegment(uint64_t start_timestamp, bool is_subsegment) override;
    58 
    59  std::unique_ptr<MkvWriter> writer_;
    60  uint64_t init_end_;
    61  uint64_t index_start_;
    62  uint64_t index_end_;
    63 
    64  DISALLOW_COPY_AND_ASSIGN(SingleSegmentSegmenter);
    65 };
    66 
    67 } // namespace webm
    68 } // namespace media
    69 } // namespace shaka
    70 
    71 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SINGLE_SEGMENT_SEGMENTER_H_
    bool GetInitRangeStartAndEnd(uint64_t *start, uint64_t *end) override
    - -
    bool GetIndexRangeStartAndEnd(uint64_t *start, uint64_t *end) override
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    An implementation of IMkvWriter using our File type.
    Definition: mkv_writer.h:21
    - -
    Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration_timestamp, bool is_subsegment) override
    Finalize the (sub)segment.
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SINGLE_SEGMENT_SEGMENTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_SINGLE_SEGMENT_SEGMENTER_H_
    +
    9 
    +
    10 #include "packager/media/formats/webm/segmenter.h"
    +
    11 
    +
    12 #include <memory>
    +
    13 #include "packager/media/formats/webm/mkv_writer.h"
    +
    14 #include "packager/status.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 struct MuxerOptions;
    +
    20 
    +
    21 namespace webm {
    +
    22 
    + +
    27  public:
    +
    28  explicit SingleSegmentSegmenter(const MuxerOptions& options);
    +
    29  ~SingleSegmentSegmenter() override;
    +
    30 
    +
    33  Status FinalizeSegment(uint64_t start_timestamp,
    +
    34  uint64_t duration_timestamp,
    +
    35  bool is_subsegment) override;
    +
    36  bool GetInitRangeStartAndEnd(uint64_t* start, uint64_t* end) override;
    +
    37  bool GetIndexRangeStartAndEnd(uint64_t* start, uint64_t* end) override;
    +
    38  std::vector<Range> GetSegmentRanges() override;
    +
    40 
    +
    41  protected:
    +
    42  MkvWriter* writer() { return writer_.get(); }
    +
    43  uint64_t init_end() { return init_end_; }
    +
    44  void set_init_end(uint64_t end) { init_end_ = end; }
    +
    45  void set_index_start(uint64_t start) { index_start_ = start; }
    +
    46  void set_index_end(uint64_t end) { index_end_ = end; }
    +
    47  void set_writer(std::unique_ptr<MkvWriter> writer) {
    +
    48  writer_ = std::move(writer);
    +
    49  }
    +
    50 
    +
    51  // Segmenter implementation overrides.
    +
    52  Status DoInitialize() override;
    +
    53  Status DoFinalize() override;
    +
    54 
    +
    55  private:
    +
    56  // Segmenter implementation overrides.
    +
    57  Status NewSegment(uint64_t start_timestamp, bool is_subsegment) override;
    +
    58 
    +
    59  std::unique_ptr<MkvWriter> writer_;
    +
    60  uint64_t init_end_;
    +
    61  uint64_t index_start_;
    +
    62  uint64_t index_end_;
    +
    63 
    +
    64  DISALLOW_COPY_AND_ASSIGN(SingleSegmentSegmenter);
    +
    65 };
    +
    66 
    +
    67 } // namespace webm
    +
    68 } // namespace media
    +
    69 } // namespace shaka
    +
    70 
    +
    71 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SINGLE_SEGMENT_SEGMENTER_H_
    + +
    An implementation of IMkvWriter using our File type.
    Definition: mkv_writer.h:21
    + + +
    bool GetIndexRangeStartAndEnd(uint64_t *start, uint64_t *end) override
    +
    Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration_timestamp, bool is_subsegment) override
    Finalize the (sub)segment.
    +
    bool GetInitRangeStartAndEnd(uint64_t *start, uint64_t *end) override
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/d5/d4b/classshaka_1_1media_1_1mp2t_1_1TsSectionPsi-members.html b/docs/d5/d4b/classshaka_1_1media_1_1mp2t_1_1TsSectionPsi-members.html index 56cfd08058..ded13d80d0 100644 --- a/docs/d5/d4b/classshaka_1_1media_1_1mp2t_1_1TsSectionPsi-members.html +++ b/docs/d5/d4b/classshaka_1_1media_1_1mp2t_1_1TsSectionPsi-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d5/d4b/packed__audio__writer_8h_source.html b/docs/d5/d4b/packed__audio__writer_8h_source.html index 4fca309d74..7f598ddb3e 100644 --- a/docs/d5/d4b/packed__audio__writer_8h_source.html +++ b/docs/d5/d4b/packed__audio__writer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/packed_audio/packed_audio_writer.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    packed_audio_writer.h
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_WRITER_H_
    8 #define PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_WRITER_H_
    9 
    10 #include "packager/file/file_closer.h"
    11 #include "packager/media/base/muxer.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 class BufferWriter;
    17 class PackedAudioSegmenter;
    18 
    23 class PackedAudioWriter : public Muxer {
    24  public:
    26  explicit PackedAudioWriter(const MuxerOptions& muxer_options);
    27  ~PackedAudioWriter() override;
    28 
    29  private:
    30  friend class PackedAudioWriterTest;
    31 
    32  PackedAudioWriter(const PackedAudioWriter&) = delete;
    33  PackedAudioWriter& operator=(const PackedAudioWriter&) = delete;
    34 
    35  // Muxer implementations.
    36  Status InitializeMuxer() override;
    37  Status Finalize() override;
    38  Status AddSample(size_t stream_id, const MediaSample& sample) override;
    39  Status FinalizeSegment(size_t stream_id, const SegmentInfo& sample) override;
    40 
    41  Status WriteSegment(const std::string& segment_path,
    42  BufferWriter* segment_buffer);
    43 
    44  Status CloseFile(std::unique_ptr<File, FileCloser> file);
    45 
    46  const uint32_t transport_stream_timestamp_offset_ = 0;
    47  std::unique_ptr<PackedAudioSegmenter> segmenter_;
    48 
    49  // Used in single segment mode.
    50  std::unique_ptr<File, FileCloser> output_file_;
    51  // Keeps track of segment ranges in single segment mode.
    52  MuxerListener::MediaRanges media_ranges_;
    53  uint64_t total_duration_ = 0;
    54 
    55  // Used in multi-segment mode for segment template.
    56  uint64_t segment_number_ = 0;
    57 };
    58 
    59 } // namespace media
    60 } // namespace shaka
    61 
    62 #endif // PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_WRITER_H_
    - -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - - - -
    PackedAudioWriter(const MuxerOptions &muxer_options)
    Create a MP4Muxer object from MuxerOptions.
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_WRITER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_WRITER_H_
    +
    9 
    +
    10 #include "packager/file/file_closer.h"
    +
    11 #include "packager/media/base/muxer.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 class BufferWriter;
    +
    17 class PackedAudioSegmenter;
    +
    18 
    +
    23 class PackedAudioWriter : public Muxer {
    +
    24  public:
    +
    26  explicit PackedAudioWriter(const MuxerOptions& muxer_options);
    +
    27  ~PackedAudioWriter() override;
    +
    28 
    +
    29  private:
    +
    30  friend class PackedAudioWriterTest;
    +
    31 
    +
    32  PackedAudioWriter(const PackedAudioWriter&) = delete;
    +
    33  PackedAudioWriter& operator=(const PackedAudioWriter&) = delete;
    +
    34 
    +
    35  // Muxer implementations.
    +
    36  Status InitializeMuxer() override;
    +
    37  Status Finalize() override;
    +
    38  Status AddMediaSample(size_t stream_id, const MediaSample& sample) override;
    +
    39  Status FinalizeSegment(size_t stream_id, const SegmentInfo& sample) override;
    +
    40 
    +
    41  Status WriteSegment(const std::string& segment_path,
    +
    42  BufferWriter* segment_buffer);
    +
    43 
    +
    44  Status CloseFile(std::unique_ptr<File, FileCloser> file);
    +
    45 
    +
    46  const uint32_t transport_stream_timestamp_offset_ = 0;
    +
    47  std::unique_ptr<PackedAudioSegmenter> segmenter_;
    +
    48 
    +
    49  // Used in single segment mode.
    +
    50  std::unique_ptr<File, FileCloser> output_file_;
    +
    51  // Keeps track of segment ranges in single segment mode.
    +
    52  MuxerListener::MediaRanges media_ranges_;
    +
    53  uint64_t total_duration_ = 0;
    +
    54 
    +
    55  // Used in multi-segment mode for segment template.
    +
    56  uint64_t segment_number_ = 0;
    +
    57 };
    +
    58 
    +
    59 } // namespace media
    +
    60 } // namespace shaka
    +
    61 
    +
    62 #endif // PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_WRITER_H_
    + + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    + + +
    PackedAudioWriter(const MuxerOptions &muxer_options)
    Create a MP4Muxer object from MuxerOptions.
    +
    All the methods that are virtual are virtual for mocking.
    + +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    diff --git a/docs/d5/d4d/box_8cc_source.html b/docs/d5/d4d/box_8cc_source.html index b7d060658d..f217efc55c 100644 --- a/docs/d5/d4d/box_8cc_source.html +++ b/docs/d5/d4d/box_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/box.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    box.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp4/box.h"
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/media/formats/mp4/box_buffer.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 namespace mp4 {
    15 
    16 Box::Box() : box_size_(0) {}
    17 Box::~Box() {}
    18 
    19 bool Box::Parse(BoxReader* reader) {
    20  DCHECK(reader);
    21  BoxBuffer buffer(reader);
    22  return ReadWriteInternal(&buffer);
    23 }
    24 
    25 void Box::Write(BufferWriter* writer) {
    26  DCHECK(writer);
    27  // Compute and update box size.
    28  uint32_t size = ComputeSize();
    29  DCHECK_EQ(size, box_size_);
    30 
    31  size_t buffer_size_before_write = writer->Size();
    32  BoxBuffer buffer(writer);
    33  CHECK(ReadWriteInternal(&buffer));
    34  DCHECK_EQ(box_size_, writer->Size() - buffer_size_before_write)
    35  << FourCCToString(BoxType());
    36 }
    37 
    38 void Box::WriteHeader(BufferWriter* writer) {
    39  DCHECK(writer);
    40  // Compute and update box size.
    41  uint32_t size = ComputeSize();
    42  DCHECK_EQ(size, box_size_);
    43 
    44  size_t buffer_size_before_write = writer->Size();
    45  BoxBuffer buffer(writer);
    46  CHECK(ReadWriteHeaderInternal(&buffer));
    47  DCHECK_EQ(HeaderSize(), writer->Size() - buffer_size_before_write);
    48 }
    49 
    50 uint32_t Box::ComputeSize() {
    51  box_size_ = static_cast<uint32_t>(ComputeSizeInternal());
    52  return box_size_;
    53 }
    54 
    55 uint32_t Box::HeaderSize() const {
    56  const uint32_t kFourCCSize = 4;
    57  // We don't support 64-bit size.
    58  return kFourCCSize + sizeof(uint32_t);
    59 }
    60 
    61 bool Box::ReadWriteHeaderInternal(BoxBuffer* buffer) {
    62  if (buffer->Reading()) {
    63  // Skip for read mode, which is handled already in BoxReader.
    64  } else {
    65  CHECK(buffer->ReadWriteUInt32(&box_size_));
    66  FourCC fourcc = BoxType();
    67  CHECK(buffer->ReadWriteFourCC(&fourcc));
    68  }
    69  return true;
    70 }
    71 
    72 FullBox::FullBox() = default;
    73 FullBox::~FullBox() = default;
    74 
    75 uint32_t FullBox::HeaderSize() const {
    76  // Additional 1-byte version and 3-byte flags.
    77  return Box::HeaderSize() + 1 + 3;
    78 }
    79 
    80 bool FullBox::ReadWriteHeaderInternal(BoxBuffer* buffer) {
    81  RCHECK(Box::ReadWriteHeaderInternal(buffer));
    82 
    83  uint32_t vflags;
    84  if (buffer->Reading()) {
    85  RCHECK(buffer->ReadWriteUInt32(&vflags));
    86  this->version = vflags >> 24;
    87  this->flags = vflags & 0x00FFFFFF;
    88  } else {
    89  vflags = (this->version << 24) | this->flags;
    90  RCHECK(buffer->ReadWriteUInt32(&vflags));
    91  }
    92  return true;
    93 }
    94 
    95 } // namespace mp4
    96 } // namespace media
    97 } // namespace shaka
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp4/box.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/media/formats/mp4/box_buffer.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 namespace mp4 {
    +
    15 
    +
    16 Box::Box() : box_size_(0) {}
    +
    17 Box::~Box() {}
    +
    18 
    +
    19 bool Box::Parse(BoxReader* reader) {
    +
    20  DCHECK(reader);
    +
    21  BoxBuffer buffer(reader);
    +
    22  return ReadWriteInternal(&buffer);
    +
    23 }
    +
    24 
    +
    25 void Box::Write(BufferWriter* writer) {
    +
    26  DCHECK(writer);
    +
    27  // Compute and update box size.
    +
    28  uint32_t size = ComputeSize();
    +
    29  DCHECK_EQ(size, box_size_);
    +
    30 
    +
    31  size_t buffer_size_before_write = writer->Size();
    +
    32  BoxBuffer buffer(writer);
    +
    33  CHECK(ReadWriteInternal(&buffer));
    +
    34  DCHECK_EQ(box_size_, writer->Size() - buffer_size_before_write)
    +
    35  << FourCCToString(BoxType());
    +
    36 }
    +
    37 
    +
    38 void Box::WriteHeader(BufferWriter* writer) {
    +
    39  DCHECK(writer);
    +
    40  // Compute and update box size.
    +
    41  uint32_t size = ComputeSize();
    +
    42  DCHECK_EQ(size, box_size_);
    +
    43 
    +
    44  size_t buffer_size_before_write = writer->Size();
    +
    45  BoxBuffer buffer(writer);
    +
    46  CHECK(ReadWriteHeaderInternal(&buffer));
    +
    47  DCHECK_EQ(HeaderSize(), writer->Size() - buffer_size_before_write);
    +
    48 }
    +
    49 
    +
    50 uint32_t Box::ComputeSize() {
    +
    51  box_size_ = static_cast<uint32_t>(ComputeSizeInternal());
    +
    52  return box_size_;
    +
    53 }
    +
    54 
    +
    55 uint32_t Box::HeaderSize() const {
    +
    56  const uint32_t kFourCCSize = 4;
    +
    57  // We don't support 64-bit size.
    +
    58  return kFourCCSize + sizeof(uint32_t);
    +
    59 }
    +
    60 
    +
    61 bool Box::ReadWriteHeaderInternal(BoxBuffer* buffer) {
    +
    62  if (buffer->Reading()) {
    +
    63  // Skip for read mode, which is handled already in BoxReader.
    +
    64  } else {
    +
    65  CHECK(buffer->ReadWriteUInt32(&box_size_));
    +
    66  FourCC fourcc = BoxType();
    +
    67  CHECK(buffer->ReadWriteFourCC(&fourcc));
    +
    68  }
    +
    69  return true;
    +
    70 }
    +
    71 
    +
    72 FullBox::FullBox() = default;
    +
    73 FullBox::~FullBox() = default;
    +
    74 
    +
    75 uint32_t FullBox::HeaderSize() const {
    +
    76  // Additional 1-byte version and 3-byte flags.
    +
    77  return Box::HeaderSize() + 1 + 3;
    +
    78 }
    +
    79 
    +
    80 bool FullBox::ReadWriteHeaderInternal(BoxBuffer* buffer) {
    +
    81  RCHECK(Box::ReadWriteHeaderInternal(buffer));
    +
    82 
    +
    83  uint32_t vflags;
    +
    84  if (buffer->Reading()) {
    +
    85  RCHECK(buffer->ReadWriteUInt32(&vflags));
    +
    86  this->version = vflags >> 24;
    +
    87  this->flags = vflags & 0x00FFFFFF;
    +
    88  } else {
    +
    89  vflags = (this->version << 24) | this->flags;
    +
    90  RCHECK(buffer->ReadWriteUInt32(&vflags));
    +
    91  }
    +
    92  return true;
    +
    93 }
    +
    94 
    +
    95 } // namespace mp4
    +
    96 } // namespace media
    +
    97 } // namespace shaka
    + + + +
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d51/packed__audio__segmenter_8cc_source.html b/docs/d5/d51/packed__audio__segmenter_8cc_source.html index 1ee7b33953..412c41e4db 100644 --- a/docs/d5/d51/packed__audio__segmenter_8cc_source.html +++ b/docs/d5/d51/packed__audio__segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/packed_audio/packed_audio_segmenter.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    packed_audio_segmenter.cc
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/packed_audio/packed_audio_segmenter.h"
    8 
    9 #include <memory>
    10 
    11 #include "packager/media/base/id3_tag.h"
    12 #include "packager/media/base/media_sample.h"
    13 #include "packager/media/codecs/aac_audio_specific_config.h"
    14 #include "packager/media/codecs/hls_audio_util.h"
    15 #include "packager/status_macros.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 namespace {
    20 std::string TimestampToString(uint64_t timestamp) {
    21  // https://tools.ietf.org/html/rfc8216 The ID3 payload MUST be a 33-bit MPEG-2
    22  // Program Elementary Stream timestamp expressed as a big-endian eight-octet
    23  // number, with the upper 31 bits set to zero.
    24  timestamp &= 0x1FFFFFFFFull;
    25 
    26  BufferWriter buffer;
    27  buffer.AppendInt(timestamp);
    28  return std::string(buffer.Buffer(), buffer.Buffer() + buffer.Size());
    29 }
    30 } // namespace
    31 
    33  uint32_t transport_stream_timestamp_offset)
    34  : transport_stream_timestamp_offset_(transport_stream_timestamp_offset) {}
    35 
    36 PackedAudioSegmenter::~PackedAudioSegmenter() = default;
    37 
    39  const StreamType stream_type = stream_info.stream_type();
    40  if (stream_type != StreamType::kStreamAudio) {
    41  LOG(ERROR) << "PackedAudioSegmenter cannot handle stream type "
    42  << stream_type;
    43  return Status(error::MUXER_FAILURE, "Unsupported stream type.");
    44  }
    45 
    46  codec_ = stream_info.codec();
    47  audio_codec_config_ = stream_info.codec_config();
    48  timescale_scale_ = kPackedAudioTimescale / stream_info.time_scale();
    49 
    50  if (codec_ == kCodecAAC) {
    51  adts_converter_ = CreateAdtsConverter();
    52  if (!adts_converter_->Parse(audio_codec_config_)) {
    53  return Status(error::MUXER_FAILURE, "Invalid audio codec configuration.");
    54  }
    55  }
    56 
    57  return Status::OK;
    58 }
    59 
    61  if (sample.is_encrypted() && audio_setup_information_.empty())
    62  RETURN_IF_ERROR(EncryptionAudioSetup(sample));
    63 
    64  if (start_of_new_segment_) {
    65  RETURN_IF_ERROR(StartNewSegment(sample));
    66  start_of_new_segment_ = false;
    67  }
    68 
    69  if (adts_converter_) {
    70  std::vector<uint8_t> audio_frame;
    71  if (!adts_converter_->ConvertToADTS(sample.data(), sample.data_size(),
    72  &audio_frame))
    73  return Status(error::MUXER_FAILURE, "Failed to convert to ADTS.");
    74  segment_buffer_.AppendArray(audio_frame.data(), audio_frame.size());
    75  } else {
    76  segment_buffer_.AppendArray(sample.data(), sample.data_size());
    77  }
    78  return Status::OK;
    79 }
    80 
    82  start_of_new_segment_ = true;
    83  return Status::OK;
    84 }
    85 
    87  return timescale_scale_;
    88 }
    89 
    90 std::unique_ptr<AACAudioSpecificConfig>
    91 PackedAudioSegmenter::CreateAdtsConverter() {
    92  return std::unique_ptr<AACAudioSpecificConfig>(new AACAudioSpecificConfig);
    93 }
    94 
    95 std::unique_ptr<Id3Tag> PackedAudioSegmenter::CreateId3Tag() {
    96  return std::unique_ptr<Id3Tag>(new Id3Tag);
    97 }
    98 
    99 Status PackedAudioSegmenter::EncryptionAudioSetup(const MediaSample& sample) {
    100  // For codecs other than AC3, audio setup data is the audio codec
    101  // configuration data.
    102  const uint8_t* audio_setup_data = audio_codec_config_.data();
    103  size_t audio_setup_data_size = audio_codec_config_.size();
    104  if (codec_ == kCodecAC3) {
    105  // https://goo.gl/N7Tvqi MPEG-2 Stream Encryption Format for HTTP Live
    106  // Streaming 2.3.2.2 AC-3 Setup: For AC-3, the setup_data in the
    107  // audio_setup_information is the first 10 bytes of the audio data (the
    108  // syncframe()).
    109  const size_t kSetupDataSize = 10u;
    110  if (sample.data_size() < kSetupDataSize) {
    111  LOG(ERROR) << "Sample is too small for AC3: " << sample.data_size();
    112  return Status(error::MUXER_FAILURE, "Sample is too small for AC3.");
    113  }
    114  audio_setup_data = sample.data();
    115  audio_setup_data_size = kSetupDataSize;
    116  }
    117 
    118  BufferWriter buffer;
    119  if (!WriteAudioSetupInformation(codec_, audio_setup_data,
    120  audio_setup_data_size, &buffer)) {
    121  return Status(error::MUXER_FAILURE,
    122  "Failed to write audio setup information.");
    123  }
    124  audio_setup_information_.assign(buffer.Buffer(),
    125  buffer.Buffer() + buffer.Size());
    126  return Status::OK;
    127 }
    128 
    129 Status PackedAudioSegmenter::StartNewSegment(const MediaSample& sample) {
    130  segment_buffer_.Clear();
    131 
    132  const int64_t pts =
    133  sample.pts() * timescale_scale_ + transport_stream_timestamp_offset_;
    134  if (pts < 0) {
    135  LOG(ERROR) << "Seeing negative timestamp " << pts
    136  << " after applying offset "
    137  << transport_stream_timestamp_offset_
    138  << ". Please check if it is expected. Adjust "
    139  "--transport_stream_timestamp_offset_ms if needed.";
    140  return Status(error::MUXER_FAILURE, "Unsupported negative timestamp.");
    141  }
    142 
    143  // Use a unique_ptr so it can be mocked for testing.
    144  std::unique_ptr<Id3Tag> id3_tag = CreateId3Tag();
    145  id3_tag->AddPrivateFrame(kTimestampOwnerIdentifier, TimestampToString(pts));
    146  if (!audio_setup_information_.empty()) {
    147  id3_tag->AddPrivateFrame(kAudioDescriptionOwnerIdentifier,
    148  audio_setup_information_);
    149  }
    150  CHECK(id3_tag->WriteToBuffer(&segment_buffer_));
    151 
    152  return Status::OK;
    153 }
    154 
    155 } // namespace media
    156 } // namespace shaka
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    const uint8_t * Buffer() const
    Definition: buffer_writer.h:61
    - -
    All the methods that are virtual are virtual for mocking.
    - - -
    virtual Status Initialize(const StreamInfo &stream_info)
    - -
    Class to hold a media sample.
    Definition: media_sample.h:22
    -
    PackedAudioSegmenter(uint32_t transport_stream_timestamp_offset)
    -
    virtual Status AddSample(const MediaSample &sample)
    - +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/packed_audio/packed_audio_segmenter.h"
    +
    8 
    +
    9 #include <memory>
    +
    10 
    +
    11 #include "packager/media/base/id3_tag.h"
    +
    12 #include "packager/media/base/media_sample.h"
    +
    13 #include "packager/media/codecs/aac_audio_specific_config.h"
    +
    14 #include "packager/media/codecs/hls_audio_util.h"
    +
    15 #include "packager/status_macros.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 namespace {
    +
    20 std::string TimestampToString(uint64_t timestamp) {
    +
    21  // https://tools.ietf.org/html/rfc8216 The ID3 payload MUST be a 33-bit MPEG-2
    +
    22  // Program Elementary Stream timestamp expressed as a big-endian eight-octet
    +
    23  // number, with the upper 31 bits set to zero.
    +
    24  timestamp &= 0x1FFFFFFFFull;
    +
    25 
    +
    26  BufferWriter buffer;
    +
    27  buffer.AppendInt(timestamp);
    +
    28  return std::string(buffer.Buffer(), buffer.Buffer() + buffer.Size());
    +
    29 }
    +
    30 } // namespace
    +
    31 
    + +
    33  uint32_t transport_stream_timestamp_offset)
    +
    34  : transport_stream_timestamp_offset_(transport_stream_timestamp_offset) {}
    +
    35 
    +
    36 PackedAudioSegmenter::~PackedAudioSegmenter() = default;
    +
    37 
    + +
    39  const StreamType stream_type = stream_info.stream_type();
    +
    40  if (stream_type != StreamType::kStreamAudio) {
    +
    41  LOG(ERROR) << "PackedAudioSegmenter cannot handle stream type "
    +
    42  << stream_type;
    +
    43  return Status(error::MUXER_FAILURE, "Unsupported stream type.");
    +
    44  }
    +
    45 
    +
    46  codec_ = stream_info.codec();
    +
    47  audio_codec_config_ = stream_info.codec_config();
    +
    48  timescale_scale_ = kPackedAudioTimescale / stream_info.time_scale();
    +
    49 
    +
    50  if (codec_ == kCodecAAC) {
    +
    51  adts_converter_ = CreateAdtsConverter();
    +
    52  if (!adts_converter_->Parse(audio_codec_config_)) {
    +
    53  return Status(error::MUXER_FAILURE, "Invalid audio codec configuration.");
    +
    54  }
    +
    55  }
    +
    56 
    +
    57  return Status::OK;
    +
    58 }
    +
    59 
    + +
    61  if (sample.is_encrypted() && audio_setup_information_.empty())
    +
    62  RETURN_IF_ERROR(EncryptionAudioSetup(sample));
    +
    63 
    +
    64  if (start_of_new_segment_) {
    +
    65  RETURN_IF_ERROR(StartNewSegment(sample));
    +
    66  start_of_new_segment_ = false;
    +
    67  }
    +
    68 
    +
    69  if (adts_converter_) {
    +
    70  std::vector<uint8_t> audio_frame;
    +
    71  if (!adts_converter_->ConvertToADTS(sample.data(), sample.data_size(),
    +
    72  &audio_frame))
    +
    73  return Status(error::MUXER_FAILURE, "Failed to convert to ADTS.");
    +
    74  segment_buffer_.AppendArray(audio_frame.data(), audio_frame.size());
    +
    75  } else {
    +
    76  segment_buffer_.AppendArray(sample.data(), sample.data_size());
    +
    77  }
    +
    78  return Status::OK;
    +
    79 }
    +
    80 
    + +
    82  start_of_new_segment_ = true;
    +
    83  return Status::OK;
    +
    84 }
    +
    85 
    + +
    87  return timescale_scale_;
    +
    88 }
    +
    89 
    +
    90 std::unique_ptr<AACAudioSpecificConfig>
    +
    91 PackedAudioSegmenter::CreateAdtsConverter() {
    +
    92  return std::unique_ptr<AACAudioSpecificConfig>(new AACAudioSpecificConfig);
    +
    93 }
    +
    94 
    +
    95 std::unique_ptr<Id3Tag> PackedAudioSegmenter::CreateId3Tag() {
    +
    96  return std::unique_ptr<Id3Tag>(new Id3Tag);
    +
    97 }
    +
    98 
    +
    99 Status PackedAudioSegmenter::EncryptionAudioSetup(const MediaSample& sample) {
    +
    100  // For codecs other than AC3, audio setup data is the audio codec
    +
    101  // configuration data.
    +
    102  const uint8_t* audio_setup_data = audio_codec_config_.data();
    +
    103  size_t audio_setup_data_size = audio_codec_config_.size();
    +
    104  if (codec_ == kCodecAC3) {
    +
    105  // https://goo.gl/N7Tvqi MPEG-2 Stream Encryption Format for HTTP Live
    +
    106  // Streaming 2.3.2.2 AC-3 Setup: For AC-3, the setup_data in the
    +
    107  // audio_setup_information is the first 10 bytes of the audio data (the
    +
    108  // syncframe()).
    +
    109  const size_t kSetupDataSize = 10u;
    +
    110  if (sample.data_size() < kSetupDataSize) {
    +
    111  LOG(ERROR) << "Sample is too small for AC3: " << sample.data_size();
    +
    112  return Status(error::MUXER_FAILURE, "Sample is too small for AC3.");
    +
    113  }
    +
    114  audio_setup_data = sample.data();
    +
    115  audio_setup_data_size = kSetupDataSize;
    +
    116  }
    +
    117 
    +
    118  BufferWriter buffer;
    +
    119  if (!WriteAudioSetupInformation(codec_, audio_setup_data,
    +
    120  audio_setup_data_size, &buffer)) {
    +
    121  return Status(error::MUXER_FAILURE,
    +
    122  "Failed to write audio setup information.");
    +
    123  }
    +
    124  audio_setup_information_.assign(buffer.Buffer(),
    +
    125  buffer.Buffer() + buffer.Size());
    +
    126  return Status::OK;
    +
    127 }
    +
    128 
    +
    129 Status PackedAudioSegmenter::StartNewSegment(const MediaSample& sample) {
    +
    130  segment_buffer_.Clear();
    +
    131 
    +
    132  const int64_t pts =
    +
    133  sample.pts() * timescale_scale_ + transport_stream_timestamp_offset_;
    +
    134  if (pts < 0) {
    +
    135  LOG(ERROR) << "Seeing negative timestamp " << pts
    +
    136  << " after applying offset "
    +
    137  << transport_stream_timestamp_offset_
    +
    138  << ". Please check if it is expected. Adjust "
    +
    139  "--transport_stream_timestamp_offset_ms if needed.";
    +
    140  return Status(error::MUXER_FAILURE, "Unsupported negative timestamp.");
    +
    141  }
    +
    142 
    +
    143  // Use a unique_ptr so it can be mocked for testing.
    +
    144  std::unique_ptr<Id3Tag> id3_tag = CreateId3Tag();
    +
    145  id3_tag->AddPrivateFrame(kTimestampOwnerIdentifier, TimestampToString(pts));
    +
    146  if (!audio_setup_information_.empty()) {
    +
    147  id3_tag->AddPrivateFrame(kAudioDescriptionOwnerIdentifier,
    +
    148  audio_setup_information_);
    +
    149  }
    +
    150  CHECK(id3_tag->WriteToBuffer(&segment_buffer_));
    +
    151 
    +
    152  return Status::OK;
    +
    153 }
    +
    154 
    +
    155 } // namespace media
    +
    156 } // namespace shaka
    + + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    PackedAudioSegmenter(uint32_t transport_stream_timestamp_offset)
    +
    virtual Status Initialize(const StreamInfo &stream_info)
    +
    virtual Status AddSample(const MediaSample &sample)
    + + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d52/ts__section__pes_8h_source.html b/docs/d5/d52/ts__section__pes_8h_source.html index a50a52638e..4418190728 100644 --- a/docs/d5/d52/ts__section__pes_8h_source.html +++ b/docs/d5/d52/ts__section__pes_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section_pes.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    ts_section_pes.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PES_H_
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PES_H_
    7 
    8 #include <stdint.h>
    9 #include <memory>
    10 #include "packager/base/compiler_specific.h"
    11 #include "packager/media/base/byte_queue.h"
    12 #include "packager/media/formats/mp2t/ts_section.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 namespace mp2t {
    17 
    18 class EsParser;
    19 
    20 class TsSectionPes : public TsSection {
    21  public:
    22  explicit TsSectionPes(std::unique_ptr<EsParser> es_parser);
    23  ~TsSectionPes() override;
    24 
    25  // TsSection implementation.
    26  bool Parse(bool payload_unit_start_indicator,
    27  const uint8_t* buf,
    28  int size) override;
    29  void Flush() override;
    30  void Reset() override;
    31 
    32  private:
    33  // Emit a reassembled PES packet.
    34  // Return true if successful.
    35  // |emit_for_unknown_size| is used to force emission for PES packets
    36  // whose size is unknown.
    37  bool Emit(bool emit_for_unknown_size);
    38 
    39  // Parse a PES packet, return true if successful.
    40  bool ParseInternal(const uint8_t* raw_pes, int raw_pes_size);
    41 
    42  void ResetPesState();
    43 
    44  // Bytes of the current PES.
    45  ByteQueue pes_byte_queue_;
    46 
    47  // ES parser.
    48  std::unique_ptr<EsParser> es_parser_;
    49 
    50  // Do not start parsing before getting a unit start indicator.
    51  bool wait_for_pusi_;
    52 
    53  // Used to unroll PTS and DTS.
    54  bool previous_pts_valid_;
    55  int64_t previous_pts_;
    56  bool previous_dts_valid_;
    57  int64_t previous_dts_;
    58 
    59  DISALLOW_COPY_AND_ASSIGN(TsSectionPes);
    60 };
    61 
    62 } // namespace mp2t
    63 } // namespace media
    64 } // namespace shaka
    65 
    66 #endif
    67 
    All the methods that are virtual are virtual for mocking.
    - - - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PES_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PES_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 #include <memory>
    +
    10 #include "packager/base/compiler_specific.h"
    +
    11 #include "packager/media/base/byte_queue.h"
    +
    12 #include "packager/media/formats/mp2t/ts_section.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 namespace mp2t {
    +
    17 
    +
    18 class EsParser;
    +
    19 
    +
    20 class TsSectionPes : public TsSection {
    +
    21  public:
    +
    22  explicit TsSectionPes(std::unique_ptr<EsParser> es_parser);
    +
    23  ~TsSectionPes() override;
    +
    24 
    +
    25  // TsSection implementation.
    +
    26  bool Parse(bool payload_unit_start_indicator,
    +
    27  const uint8_t* buf,
    +
    28  int size) override;
    +
    29  bool Flush() override;
    +
    30  void Reset() override;
    +
    31 
    +
    32  private:
    +
    33  // Emit a reassembled PES packet.
    +
    34  // Return true if successful.
    +
    35  // |emit_for_unknown_size| is used to force emission for PES packets
    +
    36  // whose size is unknown.
    +
    37  bool Emit(bool emit_for_unknown_size);
    +
    38 
    +
    39  // Parse a PES packet, return true if successful.
    +
    40  bool ParseInternal(const uint8_t* raw_pes, int raw_pes_size);
    +
    41 
    +
    42  void ResetPesState();
    +
    43 
    +
    44  // Bytes of the current PES.
    +
    45  ByteQueue pes_byte_queue_;
    +
    46 
    +
    47  // ES parser.
    +
    48  std::unique_ptr<EsParser> es_parser_;
    +
    49 
    +
    50  // Do not start parsing before getting a unit start indicator.
    +
    51  bool wait_for_pusi_;
    +
    52 
    +
    53  // Used to unroll PTS and DTS.
    +
    54  bool previous_pts_valid_;
    +
    55  int64_t previous_pts_;
    +
    56  bool previous_dts_valid_;
    +
    57  int64_t previous_dts_;
    +
    58 
    +
    59  DISALLOW_COPY_AND_ASSIGN(TsSectionPes);
    +
    60 };
    +
    61 
    +
    62 } // namespace mp2t
    +
    63 } // namespace media
    +
    64 } // namespace shaka
    +
    65 
    +
    66 #endif
    +
    67 
    + + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d53/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationSize-members.html b/docs/d5/d53/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationSize-members.html index c932d12076..f621ec766c 100644 --- a/docs/d5/d53/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationSize-members.html +++ b/docs/d5/d53/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationSize-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d5/d57/classshaka_1_1RepresentationStateChangeListener-members.html b/docs/d5/d57/classshaka_1_1RepresentationStateChangeListener-members.html index 61ed7622c5..adb053adbb 100644 --- a/docs/d5/d57/classshaka_1_1RepresentationStateChangeListener-members.html +++ b/docs/d5/d57/classshaka_1_1RepresentationStateChangeListener-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d5/d58/classshaka_1_1media_1_1DecoderConfigDescriptor.html b/docs/d5/d58/classshaka_1_1media_1_1DecoderConfigDescriptor.html index d9c15840de..ccde0a1d66 100644 --- a/docs/d5/d58/classshaka_1_1media_1_1DecoderConfigDescriptor.html +++ b/docs/d5/d58/classshaka_1_1media_1_1DecoderConfigDescriptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::DecoderConfigDescriptor Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::BaseDescriptor - -
    + + @@ -143,7 +146,7 @@ void 

    Public Member Functions

    Detailed Description

    Implements DecoderConfig descriptor according to ISO 14496-1:2004 7.2.6.6 DecoderConfigDescriptor.

    -

    Definition at line 103 of file es_descriptor.h.

    +

    Definition at line 105 of file es_descriptor.h.

    Member Function Documentation

    ◆ IsAAC()

    @@ -169,7 +172,7 @@ void 
    Returns
    true if the stream is AAC.
    -

    Definition at line 122 of file es_descriptor.h.

    +

    Definition at line 124 of file es_descriptor.h.

    @@ -197,7 +200,7 @@ void 
    Returns
    true if the stream is DTS.
    -

    Definition at line 128 of file es_descriptor.h.

    +

    Definition at line 130 of file es_descriptor.h.

    @@ -208,9 +211,7 @@ void 
    diff --git a/docs/d5/d59/classshaka_1_1MockRepresentation-members.html b/docs/d5/d59/classshaka_1_1MockRepresentation-members.html index 161134c50d..b2e2935b35 100644 --- a/docs/d5/d59/classshaka_1_1MockRepresentation-members.html +++ b/docs/d5/d59/classshaka_1_1MockRepresentation-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    AddNewSegment(int64_t start_time, int64_t duration, uint64_t size)shaka::Representationvirtual GetMediaInfo() constshaka::Representationvirtual GetStartAndEndTimestamps(double *start_timestamp_seconds, double *end_timestamp_seconds) constshaka::Representation - GetXml()shaka::Representation + GetXml()shaka::Representation id() constshaka::Representationinline Init()shaka::Representation kSuppressFrameRate enum value (defined in shaka::Representation)shaka::Representation @@ -98,9 +101,7 @@ $(function() {
    diff --git a/docs/d5/d5a/webvtt__timestamp_8cc_source.html b/docs/d5/d5a/webvtt__timestamp_8cc_source.html deleted file mode 100644 index 95a94edba8..0000000000 --- a/docs/d5/d5a/webvtt__timestamp_8cc_source.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - -Shaka Packager SDK: packager/media/formats/webvtt/webvtt_timestamp.cc Source File - - - - - - - - - -
    -
    - - - - - - -
    -
    Shaka Packager SDK -
    -
    -
    - - - - - - - - -
    -
    - - -
    - -
    - - -
    -
    -
    -
    webvtt_timestamp.cc
    -
    -
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/webvtt/webvtt_timestamp.h"
    8 
    9 #include <ctype.h>
    10 #include <inttypes.h>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/base/strings/stringprintf.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 namespace {
    19 
    20 bool GetTotalMilliseconds(uint64_t hours,
    21  uint64_t minutes,
    22  uint64_t seconds,
    23  uint64_t ms,
    24  uint64_t* out) {
    25  DCHECK(out);
    26  if (minutes > 59 || seconds > 59 || ms > 999) {
    27  VLOG(1) << "Hours:" << hours << " Minutes:" << minutes
    28  << " Seconds:" << seconds << " MS:" << ms
    29  << " shoud have never made it to GetTotalMilliseconds";
    30  return false;
    31  }
    32  *out = 60 * 60 * 1000 * hours + 60 * 1000 * minutes + 1000 * seconds + ms;
    33  return true;
    34 }
    35 } // namespace
    36 
    37 bool WebVttTimestampToMs(const base::StringPiece& source, uint64_t* out) {
    38  DCHECK(out);
    39 
    40  if (source.length() < 9) {
    41  LOG(WARNING) << "Timestamp '" << source << "' is mal-formed";
    42  return false;
    43  }
    44 
    45  const size_t minutes_begin = source.length() - 9;
    46  const size_t seconds_begin = source.length() - 6;
    47  const size_t milliseconds_begin = source.length() - 3;
    48 
    49  uint64_t hours = 0;
    50  uint64_t minutes = 0;
    51  uint64_t seconds = 0;
    52  uint64_t ms = 0;
    53 
    54  const bool has_hours =
    55  minutes_begin >= 3 && source[minutes_begin - 1] == ':' &&
    56  base::StringToUint64(source.substr(0, minutes_begin - 1), &hours);
    57 
    58  if ((minutes_begin == 0 || has_hours) && source[seconds_begin - 1] == ':' &&
    59  source[milliseconds_begin - 1] == '.' &&
    60  base::StringToUint64(source.substr(minutes_begin, 2), &minutes) &&
    61  base::StringToUint64(source.substr(seconds_begin, 2), &seconds) &&
    62  base::StringToUint64(source.substr(milliseconds_begin, 3), &ms)) {
    63  return GetTotalMilliseconds(hours, minutes, seconds, ms, out);
    64  }
    65 
    66  LOG(WARNING) << "Timestamp '" << source << "' is mal-formed";
    67  return false;
    68 }
    69 
    70 std::string MsToWebVttTimestamp(uint64_t ms) {
    71  uint64_t remaining = ms;
    72 
    73  uint64_t only_ms = remaining % 1000;
    74  remaining /= 1000;
    75  uint64_t only_seconds = remaining % 60;
    76  remaining /= 60;
    77  uint64_t only_minutes = remaining % 60;
    78  remaining /= 60;
    79  uint64_t only_hours = remaining;
    80 
    81  return base::StringPrintf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64
    82  ".%03" PRIu64,
    83  only_hours, only_minutes, only_seconds, only_ms);
    84 }
    85 } // namespace media
    86 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    -
    - - - - diff --git a/docs/d5/d5b/dvb__sub__parser_8cc_source.html b/docs/d5/d5b/dvb__sub__parser_8cc_source.html new file mode 100644 index 0000000000..ad4260f3f8 --- /dev/null +++ b/docs/d5/d5b/dvb__sub__parser_8cc_source.html @@ -0,0 +1,562 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/dvb/dvb_sub_parser.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    dvb_sub_parser.cc
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/dvb/dvb_sub_parser.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 namespace {
    +
    18 
    +
    19 RgbaColor ConvertYuv(uint8_t Y, uint8_t Cr, uint8_t Cb, uint8_t T) {
    +
    20  // Converts based on ITU-R BT.601.
    +
    21  // See https://en.wikipedia.org/wiki/YCbCr
    +
    22  //
    +
    23  // Note that the T value should be interpolated based on a full transparency
    +
    24  // being 256. This means that T=255 should not be fully transparent. Y=0 is
    +
    25  // used to signal full transparency.
    +
    26  // Values for Y<16 (except Y=0) are invalid, so clamp to 16.
    +
    27  RgbaColor color;
    +
    28  const double y_transform = 255.0 / 219 * (std::max<uint8_t>(Y, 16) - 16);
    +
    29  const double cb_transform = 255.0 / 244 * 1.772 * (Cb - 128);
    +
    30  const double cr_transform = 255.0 / 244 * 1.402 * (Cr - 128);
    +
    31  const double f1 = 0.114 / 0.587;
    +
    32  const double f2 = 0.299 / 0.587;
    +
    33  color.r = static_cast<uint8_t>(y_transform + cr_transform);
    +
    34  color.g =
    +
    35  static_cast<uint8_t>(y_transform - cb_transform * f1 - cr_transform * f2);
    +
    36  color.b = static_cast<uint8_t>(y_transform + cb_transform);
    +
    37  color.a = Y == 0 ? 0 : (T == 0 ? 255 : 256 - T);
    +
    38  return color;
    +
    39 }
    +
    40 
    +
    41 } // namespace
    +
    42 
    +
    43 DvbSubParser::DvbSubParser() : last_pts_(0), timeout_(0) {}
    +
    44 
    +
    45 DvbSubParser::~DvbSubParser() {}
    +
    46 
    +
    47 bool DvbSubParser::Parse(DvbSubSegmentType segment_type,
    +
    48  int64_t pts,
    +
    49  const uint8_t* payload,
    +
    50  size_t size,
    +
    51  std::vector<std::shared_ptr<TextSample>>* samples) {
    +
    52  switch (segment_type) {
    +
    53  case DvbSubSegmentType::kPageComposition:
    +
    54  return ParsePageComposition(pts, payload, size, samples);
    +
    55  case DvbSubSegmentType::kRegionComposition:
    +
    56  return ParseRegionComposition(payload, size);
    +
    57  case DvbSubSegmentType::kClutDefinition:
    +
    58  return ParseClutDefinition(payload, size);
    +
    59  case DvbSubSegmentType::kObjectData:
    +
    60  return ParseObjectData(pts, payload, size);
    +
    61  case DvbSubSegmentType::kDisplayDefinition:
    +
    62  return ParseDisplayDefinition(payload, size);
    +
    63  case DvbSubSegmentType::kEndOfDisplay:
    +
    64  // This signals all the current objects are available. But we need to
    +
    65  // know the end time, so we do nothing for now.
    +
    66  return true;
    +
    67  default:
    +
    68  LOG(WARNING) << "Unknown DVB-sub segment_type=0x" << std::hex
    +
    69  << static_cast<uint32_t>(segment_type);
    +
    70  return true;
    +
    71  }
    +
    72 }
    +
    73 
    +
    74 bool DvbSubParser::Flush(std::vector<std::shared_ptr<TextSample>>* samples) {
    +
    75  RCHECK(composer_.GetSamples(last_pts_, last_pts_ + timeout_ * kMpeg2Timescale,
    +
    76  samples));
    +
    77  composer_.ClearObjects();
    +
    78  return true;
    +
    79 }
    +
    80 
    +
    81 const DvbImageColorSpace* DvbSubParser::GetColorSpace(uint8_t clut_id) {
    +
    82  return composer_.GetColorSpace(clut_id);
    +
    83 }
    +
    84 
    +
    85 const DvbImageBuilder* DvbSubParser::GetImageForObject(uint16_t object_id) {
    +
    86  return composer_.GetObjectImage(object_id);
    +
    87 }
    +
    88 
    +
    89 bool DvbSubParser::ParsePageComposition(
    +
    90  int64_t pts,
    +
    91  const uint8_t* data,
    +
    92  size_t size,
    +
    93  std::vector<std::shared_ptr<TextSample>>* samples) {
    +
    94  // See ETSI EN 300 743 Section 7.2.2.
    +
    95  BitReader reader(data, size);
    +
    96 
    +
    97  uint8_t page_state;
    +
    98  RCHECK(reader.ReadBits(8, &timeout_));
    +
    99  RCHECK(reader.SkipBits(4)); // page_version_number
    +
    100  RCHECK(reader.ReadBits(2, &page_state));
    +
    101  RCHECK(reader.SkipBits(2)); // reserved
    +
    102  if (page_state == 0x1 || page_state == 0x2) {
    +
    103  // If this is a "acquisition point" or a "mode change", then this is a new
    +
    104  // page and we should clear the old data.
    +
    105  RCHECK(composer_.GetSamples(last_pts_, pts, samples));
    +
    106  composer_.ClearObjects();
    +
    107  last_pts_ = pts;
    +
    108  }
    +
    109 
    +
    110  while (reader.bits_available() > 0u) {
    +
    111  uint8_t region_id;
    +
    112  uint16_t x, y;
    +
    113  RCHECK(reader.ReadBits(8, &region_id));
    +
    114  RCHECK(reader.SkipBits(8)); // reserved
    +
    115  RCHECK(reader.ReadBits(16, &x));
    +
    116  RCHECK(reader.ReadBits(16, &y));
    +
    117 
    +
    118  RCHECK(composer_.SetRegionPosition(region_id, x, y));
    +
    119  }
    +
    120 
    +
    121  return true;
    +
    122 }
    +
    123 
    +
    124 bool DvbSubParser::ParseRegionComposition(const uint8_t* data, size_t size) {
    +
    125  // See ETSI EN 300 743 Section 7.2.3.
    +
    126  BitReader reader(data, size);
    +
    127 
    +
    128  uint8_t region_id, clut_id;
    +
    129  uint16_t region_width, region_height;
    +
    130  bool region_fill_flag;
    +
    131  int background_pixel_code;
    +
    132  RCHECK(reader.ReadBits(8, &region_id));
    +
    133  RCHECK(reader.SkipBits(4)); // region_version_number
    +
    134  RCHECK(reader.ReadBits(1, &region_fill_flag));
    +
    135  RCHECK(reader.SkipBits(3)); // reserved
    +
    136  RCHECK(reader.ReadBits(16, &region_width));
    +
    137  RCHECK(reader.ReadBits(16, &region_height));
    +
    138  RCHECK(reader.SkipBits(3)); // region_level_of_compatibility
    +
    139  RCHECK(reader.SkipBits(3)); // region_depth
    +
    140  RCHECK(reader.SkipBits(2)); // reserved
    +
    141  RCHECK(reader.ReadBits(8, &clut_id));
    +
    142  RCHECK(reader.ReadBits(8, &background_pixel_code));
    +
    143  RCHECK(reader.SkipBits(4)); // region_4-bit_pixel_code
    +
    144  RCHECK(reader.SkipBits(2)); // region_2-bit_pixel_code
    +
    145  RCHECK(reader.SkipBits(2)); // reserved
    +
    146  RCHECK(
    +
    147  composer_.SetRegionInfo(region_id, clut_id, region_width, region_height));
    +
    148  if (!region_fill_flag)
    +
    149  background_pixel_code = -1;
    +
    150 
    +
    151  while (reader.bits_available() > 0) {
    +
    152  uint16_t object_id, x, y;
    +
    153  uint8_t object_type;
    +
    154  RCHECK(reader.ReadBits(16, &object_id));
    +
    155  RCHECK(reader.ReadBits(2, &object_type));
    +
    156  RCHECK(reader.SkipBits(2)); // object_provider_flag
    +
    157  RCHECK(reader.ReadBits(12, &x));
    +
    158  RCHECK(reader.SkipBits(4)); // reserved
    +
    159  RCHECK(reader.ReadBits(12, &y));
    +
    160 
    +
    161  if (object_type == 0x01 || object_type == 0x02) {
    +
    162  RCHECK(reader.SkipBits(8)); // foreground_pixel_code
    +
    163  RCHECK(reader.SkipBits(8)); // background_pixel_code
    +
    164  }
    +
    165  RCHECK(composer_.SetObjectInfo(object_id, region_id, x, y,
    +
    166  background_pixel_code));
    +
    167  }
    +
    168 
    +
    169  return true;
    +
    170 }
    +
    171 
    +
    172 bool DvbSubParser::ParseClutDefinition(const uint8_t* data, size_t size) {
    +
    173  // See ETSI EN 300 743 Section 7.2.4.
    +
    174  BitReader reader(data, size);
    +
    175 
    +
    176  uint8_t clut_id;
    +
    177  RCHECK(reader.ReadBits(8, &clut_id));
    +
    178  auto* color_space = composer_.GetColorSpace(clut_id);
    +
    179  RCHECK(reader.SkipBits(4)); // CLUT_version_number
    +
    180  RCHECK(reader.SkipBits(4)); // reserved
    +
    181  while (reader.bits_available() > 0) {
    +
    182  uint8_t clut_entry_id;
    +
    183  uint8_t has_2_bit;
    +
    184  uint8_t has_4_bit;
    +
    185  uint8_t has_8_bit;
    +
    186  uint8_t full_range_flag;
    +
    187  RCHECK(reader.ReadBits(8, &clut_entry_id));
    +
    188  RCHECK(reader.ReadBits(1, &has_2_bit));
    +
    189  RCHECK(reader.ReadBits(1, &has_4_bit));
    +
    190  RCHECK(reader.ReadBits(1, &has_8_bit));
    +
    191  RCHECK(reader.SkipBits(4)); // reserved
    +
    192  RCHECK(reader.ReadBits(1, &full_range_flag));
    +
    193 
    +
    194  if (has_2_bit + has_4_bit + has_8_bit != 1) {
    +
    195  LOG(ERROR) << "Must specify exactly one bit depth in CLUT definition";
    +
    196  return false;
    +
    197  }
    +
    198  const BitDepth bit_depth =
    +
    199  has_2_bit ? BitDepth::k2Bit
    +
    200  : (has_4_bit ? BitDepth::k4Bit : BitDepth::k8Bit);
    +
    201 
    +
    202  uint8_t Y, Cr, Cb, T;
    +
    203  if (full_range_flag) {
    +
    204  RCHECK(reader.ReadBits(8, &Y));
    +
    205  RCHECK(reader.ReadBits(8, &Cr));
    +
    206  RCHECK(reader.ReadBits(8, &Cb));
    +
    207  RCHECK(reader.ReadBits(8, &T));
    +
    208  } else {
    +
    209  // These store the most-significant bits, so shift them up.
    +
    210  RCHECK(reader.ReadBits(6, &Y));
    +
    211  Y <<= 2;
    +
    212  RCHECK(reader.ReadBits(4, &Cr));
    +
    213  Cr <<= 4;
    +
    214  RCHECK(reader.ReadBits(4, &Cb));
    +
    215  Cb <<= 4;
    +
    216  RCHECK(reader.ReadBits(2, &T));
    +
    217  T <<= 6;
    +
    218  }
    +
    219  color_space->SetColor(bit_depth, clut_entry_id, ConvertYuv(Y, Cr, Cb, T));
    +
    220  }
    +
    221 
    +
    222  return true;
    +
    223 }
    +
    224 
    +
    225 bool DvbSubParser::ParseObjectData(int64_t pts,
    +
    226  const uint8_t* data,
    +
    227  size_t size) {
    +
    228  // See ETSI EN 300 743 Section 7.2.5 Table 17.
    +
    229  BitReader reader(data, size);
    +
    230 
    +
    231  uint16_t object_id;
    +
    232  uint8_t object_coding_method;
    +
    233  RCHECK(reader.ReadBits(16, &object_id));
    +
    234  RCHECK(reader.SkipBits(4)); // object_version_number
    +
    235  RCHECK(reader.ReadBits(2, &object_coding_method));
    +
    236  RCHECK(reader.SkipBits(1)); // non_modifying_colour_flag
    +
    237  RCHECK(reader.SkipBits(1)); // reserved
    +
    238 
    +
    239  auto* image = composer_.GetObjectImage(object_id);
    +
    240  auto* color_space = composer_.GetColorSpaceForObject(object_id);
    +
    241  if (!image || !color_space)
    +
    242  return false;
    +
    243 
    +
    244  if (object_coding_method == 0) {
    +
    245  uint16_t top_field_length;
    +
    246  uint16_t bottom_field_length;
    +
    247  RCHECK(reader.ReadBits(16, &top_field_length));
    +
    248  RCHECK(reader.ReadBits(16, &bottom_field_length));
    +
    249 
    +
    250  RCHECK(ParsePixelDataSubObject(top_field_length, true, &reader, color_space,
    +
    251  image));
    +
    252  RCHECK(ParsePixelDataSubObject(bottom_field_length, false, &reader,
    +
    253  color_space, image));
    +
    254  // Ignore 8_stuff_bits since we don't need to read to the end.
    +
    255 
    +
    256  if (bottom_field_length == 0) {
    +
    257  // If there are no bottom rows, then the top rows are used instead. See
    +
    258  // beginning of section 7.2.5.1.
    +
    259  image->MirrorToBottomRows();
    +
    260  }
    +
    261  } else {
    +
    262  LOG(ERROR) << "Unsupported DVB-sub object coding method: "
    +
    263  << static_cast<int>(object_coding_method);
    +
    264  return false;
    +
    265  }
    +
    266  return true;
    +
    267 }
    +
    268 
    +
    269 bool DvbSubParser::ParseDisplayDefinition(const uint8_t* data, size_t size) {
    +
    270  // See ETSI EN 300 743 Section 7.2.1.
    +
    271  BitReader reader(data, size);
    +
    272 
    +
    273  uint16_t width, height;
    +
    274  RCHECK(reader.SkipBits(4)); // dds_version_number
    +
    275  RCHECK(reader.SkipBits(1)); // display_window_flag
    +
    276  RCHECK(reader.SkipBits(3)); // reserved
    +
    277  RCHECK(reader.ReadBits(16, &width));
    +
    278  RCHECK(reader.ReadBits(16, &height));
    +
    279  // Size is stored as -1.
    +
    280  composer_.SetDisplaySize(width + 1, height + 1);
    +
    281 
    +
    282  return true;
    +
    283 }
    +
    284 
    +
    285 bool DvbSubParser::ParsePixelDataSubObject(size_t sub_object_length,
    +
    286  bool is_top_fields,
    +
    287  BitReader* reader,
    +
    288  DvbImageColorSpace* color_space,
    +
    289  DvbImageBuilder* image) {
    +
    290  const size_t start = reader->bit_position() / 8;
    +
    291  while (reader->bit_position() / 8 < start + sub_object_length) {
    +
    292  // See ETSI EN 300 743 Section 7.2.5.1 Table 20
    +
    293  uint8_t data_type;
    +
    294  RCHECK(reader->ReadBits(8, &data_type));
    +
    295  uint8_t temp[16];
    +
    296  switch (data_type) {
    +
    297  case 0x10:
    +
    298  RCHECK(Parse2BitPixelData(is_top_fields, reader, image));
    +
    299  reader->SkipToNextByte();
    +
    300  break;
    +
    301  case 0x11:
    +
    302  RCHECK(Parse4BitPixelData(is_top_fields, reader, image));
    +
    303  reader->SkipToNextByte();
    +
    304  break;
    +
    305  case 0x12:
    +
    306  RCHECK(Parse8BitPixelData(is_top_fields, reader, image));
    +
    307  break;
    +
    308  case 0x20:
    +
    309  for (int i = 0; i < 4; i++) {
    +
    310  RCHECK(reader->ReadBits(4, &temp[i]));
    +
    311  }
    +
    312  color_space->Set2To4BitDepthMap(temp);
    +
    313  break;
    +
    314  case 0x21:
    +
    315  for (int i = 0; i < 4; i++) {
    +
    316  RCHECK(reader->ReadBits(8, &temp[i]));
    +
    317  }
    +
    318  color_space->Set2To8BitDepthMap(temp);
    +
    319  break;
    +
    320  case 0x22:
    +
    321  for (int i = 0; i < 16; i++) {
    +
    322  RCHECK(reader->ReadBits(8, &temp[i]));
    +
    323  }
    +
    324  color_space->Set4To8BitDepthMap(temp);
    +
    325  break;
    +
    326  case 0xf0:
    +
    327  image->NewRow(is_top_fields);
    +
    328  break;
    +
    329  default:
    +
    330  LOG(ERROR) << "Unsupported DVB-sub pixel data format: 0x" << std::hex
    +
    331  << static_cast<int>(data_type);
    +
    332  return false;
    +
    333  }
    +
    334  }
    +
    335  return true;
    +
    336 }
    +
    337 
    +
    338 bool DvbSubParser::Parse2BitPixelData(bool is_top_fields,
    +
    339  BitReader* reader,
    +
    340  DvbImageBuilder* image) {
    +
    341  // 2-bit/pixel code string, Section 7.2.5.2.1, Table 22.
    +
    342  while (true) {
    +
    343  uint8_t peek;
    +
    344  RCHECK(reader->ReadBits(2, &peek));
    +
    345  if (peek != 0) {
    +
    346  RCHECK(image->AddPixel(BitDepth::k2Bit, peek, is_top_fields));
    +
    347  } else {
    +
    348  uint8_t switch_1;
    +
    349  RCHECK(reader->ReadBits(1, &switch_1));
    +
    350  if (switch_1 == 1) {
    +
    351  uint8_t count_minus_3;
    +
    352  RCHECK(reader->ReadBits(3, &count_minus_3));
    +
    353  RCHECK(reader->ReadBits(2, &peek));
    +
    354  for (uint8_t i = 0; i < count_minus_3 + 3; i++)
    +
    355  RCHECK(image->AddPixel(BitDepth::k2Bit, peek, is_top_fields));
    +
    356  } else {
    +
    357  uint8_t switch_2;
    +
    358  RCHECK(reader->ReadBits(1, &switch_2));
    +
    359  if (switch_2 == 1) {
    +
    360  RCHECK(image->AddPixel(BitDepth::k2Bit, 0, is_top_fields));
    +
    361  } else {
    +
    362  uint8_t switch_3;
    +
    363  RCHECK(reader->ReadBits(2, &switch_3));
    +
    364  if (switch_3 == 0) {
    +
    365  break;
    +
    366  } else if (switch_3 == 1) {
    +
    367  RCHECK(image->AddPixel(BitDepth::k2Bit, 0, is_top_fields));
    +
    368  RCHECK(image->AddPixel(BitDepth::k2Bit, 0, is_top_fields));
    +
    369  } else if (switch_3 == 2) {
    +
    370  uint8_t count_minus_12;
    +
    371  RCHECK(reader->ReadBits(4, &count_minus_12));
    +
    372  RCHECK(reader->ReadBits(2, &peek));
    +
    373  for (uint8_t i = 0; i < count_minus_12 + 12; i++)
    +
    374  RCHECK(image->AddPixel(BitDepth::k2Bit, peek, is_top_fields));
    +
    375  } else if (switch_3 == 3) {
    +
    376  uint8_t count_minus_29;
    +
    377  RCHECK(reader->ReadBits(8, &count_minus_29));
    +
    378  RCHECK(reader->ReadBits(2, &peek));
    +
    379  for (uint8_t i = 0; i < count_minus_29 + 29; i++)
    +
    380  RCHECK(image->AddPixel(BitDepth::k2Bit, peek, is_top_fields));
    +
    381  }
    +
    382  }
    +
    383  }
    +
    384  }
    +
    385  }
    +
    386 
    +
    387  return true;
    +
    388 }
    +
    389 
    +
    390 bool DvbSubParser::Parse4BitPixelData(bool is_top_fields,
    +
    391  BitReader* reader,
    +
    392  DvbImageBuilder* image) {
    +
    393  // 4-bit/pixel code string, Section 7.2.5.2.2, Table 24.
    +
    394  DCHECK(reader->bits_available() % 8 == 0);
    +
    395  while (true) {
    +
    396  uint8_t peek;
    +
    397  RCHECK(reader->ReadBits(4, &peek));
    +
    398  if (peek != 0) {
    +
    399  RCHECK(image->AddPixel(BitDepth::k4Bit, peek, is_top_fields));
    +
    400  } else {
    +
    401  uint8_t switch_1;
    +
    402  RCHECK(reader->ReadBits(1, &switch_1));
    +
    403  if (switch_1 == 0) {
    +
    404  RCHECK(reader->ReadBits(3, &peek));
    +
    405  if (peek != 0) {
    +
    406  for (int i = 0; i < peek + 2; i++)
    +
    407  RCHECK(image->AddPixel(BitDepth::k4Bit, 0, is_top_fields));
    +
    408  } else {
    +
    409  break;
    +
    410  }
    +
    411  } else {
    +
    412  uint8_t switch_2;
    +
    413  RCHECK(reader->ReadBits(1, &switch_2));
    +
    414  if (switch_2 == 0) {
    +
    415  RCHECK(reader->ReadBits(2, &peek)); // run_length_4-7
    +
    416  uint8_t code;
    +
    417  RCHECK(reader->ReadBits(4, &code));
    +
    418  for (int i = 0; i < peek + 4; i++)
    +
    419  RCHECK(image->AddPixel(BitDepth::k4Bit, code, is_top_fields));
    +
    420  } else {
    +
    421  uint8_t switch_3;
    +
    422  RCHECK(reader->ReadBits(2, &switch_3));
    +
    423  if (switch_3 == 0) {
    +
    424  RCHECK(image->AddPixel(BitDepth::k4Bit, 0, is_top_fields));
    +
    425  } else if (switch_3 == 1) {
    +
    426  RCHECK(image->AddPixel(BitDepth::k4Bit, 0, is_top_fields));
    +
    427  RCHECK(image->AddPixel(BitDepth::k4Bit, 0, is_top_fields));
    +
    428  } else if (switch_3 == 2) {
    +
    429  RCHECK(reader->ReadBits(4, &peek)); // run_length_9-24
    +
    430  uint8_t code;
    +
    431  RCHECK(reader->ReadBits(4, &code));
    +
    432  for (int i = 0; i < peek + 9; i++)
    +
    433  RCHECK(image->AddPixel(BitDepth::k4Bit, code, is_top_fields));
    +
    434  } else {
    +
    435  // switch_3 == 3
    +
    436  RCHECK(reader->ReadBits(8, &peek)); // run_length_25-280
    +
    437  uint8_t code;
    +
    438  RCHECK(reader->ReadBits(4, &code));
    +
    439  for (int i = 0; i < peek + 25; i++)
    +
    440  RCHECK(image->AddPixel(BitDepth::k4Bit, code, is_top_fields));
    +
    441  }
    +
    442  }
    +
    443  }
    +
    444  }
    +
    445  }
    +
    446  return true;
    +
    447 }
    +
    448 
    +
    449 bool DvbSubParser::Parse8BitPixelData(bool is_top_fields,
    +
    450  BitReader* reader,
    +
    451  DvbImageBuilder* image) {
    +
    452  // 8-bit/pixel code string, Section 7.2.5.2.3, Table 26.
    +
    453  while (true) {
    +
    454  uint8_t peek;
    +
    455  RCHECK(reader->ReadBits(8, &peek));
    +
    456  if (peek != 0) {
    +
    457  RCHECK(image->AddPixel(BitDepth::k8Bit, peek, is_top_fields));
    +
    458  } else {
    +
    459  uint8_t switch_1;
    +
    460  RCHECK(reader->ReadBits(1, &switch_1));
    +
    461  if (switch_1 == 0) {
    +
    462  RCHECK(reader->ReadBits(7, &peek));
    +
    463  if (peek != 0) {
    +
    464  for (uint8_t i = 0; i < peek; i++)
    +
    465  RCHECK(image->AddPixel(BitDepth::k8Bit, 0, is_top_fields));
    +
    466  } else {
    +
    467  break;
    +
    468  }
    +
    469  } else {
    +
    470  uint8_t count;
    +
    471  RCHECK(reader->ReadBits(7, &count));
    +
    472  RCHECK(reader->ReadBits(8, &peek));
    +
    473  for (uint8_t i = 0; i < count; i++)
    +
    474  RCHECK(image->AddPixel(BitDepth::k8Bit, peek, is_top_fields));
    +
    475  }
    +
    476  }
    +
    477  }
    +
    478 
    +
    479  return true;
    +
    480 }
    +
    481 
    +
    482 } // namespace media
    +
    483 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/d5/d5c/continuity__counter_8cc_source.html b/docs/d5/d5c/continuity__counter_8cc_source.html index 723536a089..9ccbd00587 100644 --- a/docs/d5/d5c/continuity__counter_8cc_source.html +++ b/docs/d5/d5c/continuity__counter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/continuity_counter.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    continuity_counter.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp2t/continuity_counter.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 namespace mp2t {
    12 
    13 ContinuityCounter::ContinuityCounter() {}
    14 ContinuityCounter::~ContinuityCounter() {}
    15 
    17  int ret = counter_;
    18  ++counter_;
    19  counter_ %= 16;
    20  return ret;
    21 }
    22 
    23 } // namespace mp2t
    24 } // namespace media
    25 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/continuity_counter.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 namespace mp2t {
    +
    12 
    +
    13 ContinuityCounter::ContinuityCounter() {}
    +
    14 ContinuityCounter::~ContinuityCounter() {}
    +
    15 
    + +
    17  int ret = counter_;
    +
    18  ++counter_;
    +
    19  counter_ %= 16;
    +
    20  return ret;
    +
    21 }
    +
    22 
    +
    23 } // namespace mp2t
    +
    24 } // namespace media
    +
    25 } // namespace shaka
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d63/classshaka_1_1media_1_1mp2t_1_1EsParserH265.html b/docs/d5/d63/classshaka_1_1media_1_1mp2t_1_1EsParserH265.html index 449d9b777b..83ed1b2e74 100644 --- a/docs/d5/d63/classshaka_1_1media_1_1mp2t_1_1EsParserH265.html +++ b/docs/d5/d63/classshaka_1_1media_1_1mp2t_1_1EsParserH265.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::EsParserH265 Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp2t::EsParserH26x shaka::media::mp2t::EsParser - -
    + + @@ -95,9 +98,9 @@ void  - - + + @@ -112,12 +115,15 @@ uint32_t  - - - - + + + + + + @@ -133,9 +139,7 @@ const diff --git a/docs/d5/d63/network__util_8cc_source.html b/docs/d5/d63/network__util_8cc_source.html index 84101519f0..cc7f76b212 100644 --- a/docs/d5/d63/network__util_8cc_source.html +++ b/docs/d5/d63/network__util_8cc_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/base/network_util.cc Source File @@ -29,18 +29,21 @@

    Public Member Functions

    Reset () override
    bool Parse (const uint8_t *buf, int size, int64_t pts, int64_t dts) override
     
    -void Flush () override
     
    +bool Flush () override
     
    void Reset () override
     
    pid ()

    Additional Inherited Members

    - Public Types inherited from shaka::media::mp2t::EsParser
    -typedef base::Callback< void(const std::shared_ptr< StreamInfo > &)> NewStreamInfoCB
     
    -typedef base::Callback< void(uint32_t, const std::shared_ptr< MediaSample > &)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< StreamInfo >)> NewStreamInfoCB
     
    +typedef base::Callback< void(std::shared_ptr< MediaSample >)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< TextSample >)> EmitTextSampleCB
     
    - Protected Member Functions inherited from shaka::media::mp2t::EsParserH26x
    const H26xByteToUnitStreamConverterstream_converter () const
    - + +/* @license-end */
    network_util.cc
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/base/network_util.h"
    6 
    7 namespace shaka {
    8 namespace media {
    9 
    10 uint32_t ntohlFromBuffer(const unsigned char* buf) {
    11  return (static_cast<uint32_t>(buf[0]) << 24) |
    12  (static_cast<uint32_t>(buf[1]) << 16) |
    13  (static_cast<uint32_t>(buf[2]) << 8) | (static_cast<uint32_t>(buf[3]));
    14 }
    15 
    16 uint16_t ntohsFromBuffer(const unsigned char* buf) {
    17  return (static_cast<uint16_t>(buf[0]) << 8) | (static_cast<uint16_t>(buf[1]));
    18 }
    19 
    20 uint64_t ntohllFromBuffer(const unsigned char* buf) {
    21  return (static_cast<uint64_t>(buf[0]) << 56) |
    22  (static_cast<uint64_t>(buf[1]) << 48) |
    23  (static_cast<uint64_t>(buf[2]) << 40) |
    24  (static_cast<uint64_t>(buf[3]) << 32) |
    25  (static_cast<uint64_t>(buf[4]) << 24) |
    26  (static_cast<uint64_t>(buf[5]) << 16) |
    27  (static_cast<uint64_t>(buf[6]) << 8) | (static_cast<uint64_t>(buf[7]));
    28 }
    29 
    30 } // namespace media
    31 } // namespace shaka
    32 
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/base/network_util.h"
    +
    6 
    +
    7 namespace shaka {
    +
    8 namespace media {
    +
    9 
    +
    10 uint32_t ntohlFromBuffer(const unsigned char* buf) {
    +
    11  return (static_cast<uint32_t>(buf[0]) << 24) |
    +
    12  (static_cast<uint32_t>(buf[1]) << 16) |
    +
    13  (static_cast<uint32_t>(buf[2]) << 8) | (static_cast<uint32_t>(buf[3]));
    +
    14 }
    +
    15 
    +
    16 uint16_t ntohsFromBuffer(const unsigned char* buf) {
    +
    17  return (static_cast<uint16_t>(buf[0]) << 8) | (static_cast<uint16_t>(buf[1]));
    +
    18 }
    +
    19 
    +
    20 uint64_t ntohllFromBuffer(const unsigned char* buf) {
    +
    21  return (static_cast<uint64_t>(buf[0]) << 56) |
    +
    22  (static_cast<uint64_t>(buf[1]) << 48) |
    +
    23  (static_cast<uint64_t>(buf[2]) << 40) |
    +
    24  (static_cast<uint64_t>(buf[3]) << 32) |
    +
    25  (static_cast<uint64_t>(buf[4]) << 24) |
    +
    26  (static_cast<uint64_t>(buf[5]) << 16) |
    +
    27  (static_cast<uint64_t>(buf[6]) << 8) | (static_cast<uint64_t>(buf[7]));
    +
    28 }
    +
    29 
    +
    30 } // namespace media
    +
    31 } // namespace shaka
    +
    32 
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d66/classshaka_1_1media_1_1NalUnitToByteStreamConverter.html b/docs/d5/d66/classshaka_1_1media_1_1NalUnitToByteStreamConverter.html index 1545c4813b..bfc2a773f4 100644 --- a/docs/d5/d66/classshaka_1_1media_1_1NalUnitToByteStreamConverter.html +++ b/docs/d5/d66/classshaka_1_1media_1_1NalUnitToByteStreamConverter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::NalUnitToByteStreamConverter Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    NalUnitToByteStreamC
    Returns
    true on success, false otherwise.
    -

    Definition at line 256 of file nal_unit_to_byte_stream_converter.cc.

    +

    Definition at line 259 of file nal_unit_to_byte_stream_converter.cc.

    @@ -220,7 +223,7 @@ class NalUnitToByteStreamC
    Returns
    true on success, false otherwise.
    -

    Definition at line 269 of file nal_unit_to_byte_stream_converter.cc.

    +

    Definition at line 272 of file nal_unit_to_byte_stream_converter.cc.

    @@ -277,9 +280,7 @@ class NalUnitToByteStreamC diff --git a/docs/d5/d69/classshaka_1_1media_1_1WidevinePsshGenerator.html b/docs/d5/d69/classshaka_1_1media_1_1WidevinePsshGenerator.html index 95498610d6..905df0e86d 100644 --- a/docs/d5/d69/classshaka_1_1media_1_1WidevinePsshGenerator.html +++ b/docs/d5/d69/classshaka_1_1media_1_1WidevinePsshGenerator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WidevinePsshGenerator Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::PsshGenerator - -
    + + @@ -136,9 +139,7 @@ Public Member Functions diff --git a/docs/d5/d6d/classshaka_1_1media_1_1AesEncryptorFactory-members.html b/docs/d5/d6d/classshaka_1_1media_1_1AesEncryptorFactory-members.html index 86d6d1690e..76d1a6c9f1 100644 --- a/docs/d5/d6d/classshaka_1_1media_1_1AesEncryptorFactory-members.html +++ b/docs/d5/d6d/classshaka_1_1media_1_1AesEncryptorFactory-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    diff --git a/docs/d5/d6f/vlog__flags_8cc_source.html b/docs/d5/d6f/vlog__flags_8cc_source.html index 38f3fa795d..b002396949 100644 --- a/docs/d5/d6f/vlog__flags_8cc_source.html +++ b/docs/d5/d6f/vlog__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/vlog_flags.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    vlog_flags.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Defines verbose logging flags.
    8 
    9 #include "packager/app/vlog_flags.h"
    10 
    11 DEFINE_int32(v,
    12  0,
    13  "Show all VLOG(m) or DVLOG(m) messages for m <= this. "
    14  "Overridable by --vmodule.");
    15 DEFINE_string(
    16  vmodule,
    17  "",
    18  "Per-module verbose level."
    19  "Argument is a comma-separated list of <module name>=<log level>. "
    20  "<module name> is a glob pattern, matched against the filename base "
    21  "(that is, name ignoring .cc/.h./-inl.h). "
    22  "A pattern without slashes matches just the file name portion, otherwise "
    23  "the whole file path (still without .cc/.h./-inl.h) is matched. "
    24  "? and * in the glob pattern match any single or sequence of characters "
    25  "respectively including slashes. "
    26  "<log level> overrides any value given by --v.");
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Defines verbose logging flags.
    +
    8 
    +
    9 #include "packager/app/vlog_flags.h"
    +
    10 
    +
    11 DEFINE_int32(v,
    +
    12  0,
    +
    13  "Show all VLOG(m) or DVLOG(m) messages for m <= this. "
    +
    14  "Overridable by --vmodule.");
    +
    15 DEFINE_string(
    +
    16  vmodule,
    +
    17  "",
    +
    18  "Per-module verbose level."
    +
    19  "Argument is a comma-separated list of <module name>=<log level>. "
    +
    20  "<module name> is a glob pattern, matched against the filename base "
    +
    21  "(that is, name ignoring .cc/.h./-inl.h). "
    +
    22  "A pattern without slashes matches just the file name portion, otherwise "
    +
    23  "the whole file path (still without .cc/.h./-inl.h) is matched. "
    +
    24  "? and * in the glob pattern match any single or sequence of characters "
    +
    25  "respectively including slashes. "
    +
    26  "<log level> overrides any value given by --v.");
    +
    diff --git a/docs/d5/d72/avc__decoder__configuration__record_8cc_source.html b/docs/d5/d72/avc__decoder__configuration__record_8cc_source.html index 6b153019f6..9ed1e5cb9d 100644 --- a/docs/d5/d72/avc__decoder__configuration__record_8cc_source.html +++ b/docs/d5/d72/avc__decoder__configuration__record_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/avc_decoder_configuration_record.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    avc_decoder_configuration_record.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/avc_decoder_configuration_record.h"
    8 
    9 #include "packager/base/strings/string_number_conversions.h"
    10 #include "packager/base/strings/string_util.h"
    11 #include "packager/media/base/buffer_reader.h"
    12 #include "packager/media/base/rcheck.h"
    13 #include "packager/media/codecs/h264_parser.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    18 AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord()
    19  : version_(0),
    20  profile_indication_(0),
    21  profile_compatibility_(0),
    22  avc_level_(0) {}
    23 
    24 AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() {}
    25 
    26 bool AVCDecoderConfigurationRecord::ParseInternal() {
    27  // See ISO 14496-15 sec 5.3.3.1.2
    28  BufferReader reader(data(), data_size());
    29 
    30  RCHECK(reader.Read1(&version_) && version_ == 1 &&
    31  reader.Read1(&profile_indication_) &&
    32  reader.Read1(&profile_compatibility_) && reader.Read1(&avc_level_));
    33 
    34  uint8_t length_size_minus_one;
    35  RCHECK(reader.Read1(&length_size_minus_one));
    36  if ((length_size_minus_one & 0x3) == 2) {
    37  LOG(ERROR) << "Invalid NALU length size.";
    38  return false;
    39  }
    40  set_nalu_length_size((length_size_minus_one & 0x3) + 1);
    41 
    42  uint8_t num_sps;
    43  RCHECK(reader.Read1(&num_sps));
    44  num_sps &= 0x1f;
    45  if (num_sps < 1) {
    46  VLOG(1) << "No SPS found.";
    47  }
    48 
    49  for (uint8_t i = 0; i < num_sps; i++) {
    50  uint16_t size = 0;
    51  RCHECK(reader.Read2(&size));
    52  const uint8_t* nalu_data = reader.data() + reader.pos();
    53  RCHECK(reader.SkipBytes(size));
    54 
    55  Nalu nalu;
    56  RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
    57  RCHECK(nalu.type() == Nalu::H264_SPS);
    58  AddNalu(nalu);
    59 
    60  if (i == 0) {
    61  // It is unlikely to have more than one SPS in practice. Also there's
    62  // no way to change the {coded,pixel}_{width,height} dynamically from
    63  // VideoStreamInfo.
    64  int sps_id = 0;
    65  H264Parser parser;
    66  RCHECK(parser.ParseSps(nalu, &sps_id) == H264Parser::kOk);
    67  set_transfer_characteristics(
    68  parser.GetSps(sps_id)->transfer_characteristics);
    69  RCHECK(ExtractResolutionFromSps(*parser.GetSps(sps_id), &coded_width_,
    70  &coded_height_, &pixel_width_,
    71  &pixel_height_));
    72  }
    73  }
    74 
    75  uint8_t pps_count;
    76  RCHECK(reader.Read1(&pps_count));
    77  for (uint8_t i = 0; i < pps_count; i++) {
    78  uint16_t size = 0;
    79  RCHECK(reader.Read2(&size));
    80  const uint8_t* nalu_data = reader.data() + reader.pos();
    81  RCHECK(reader.SkipBytes(size));
    82 
    83  Nalu nalu;
    84  RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
    85  RCHECK(nalu.type() == Nalu::H264_PPS);
    86  AddNalu(nalu);
    87  }
    88 
    89  return true;
    90 }
    91 
    93  FourCC codec_fourcc) const {
    94  return GetCodecString(codec_fourcc, profile_indication_,
    95  profile_compatibility_, avc_level_);
    96 }
    97 
    99  FourCC codec_fourcc,
    100  uint8_t profile_indication,
    101  uint8_t profile_compatibility,
    102  uint8_t avc_level) {
    103  const uint8_t bytes[] = {profile_indication, profile_compatibility,
    104  avc_level};
    105  return FourCCToString(codec_fourcc) + "." +
    106  base::ToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
    107 }
    108 
    109 } // namespace media
    110 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    -
    std::string GetCodecString(FourCC codec_fourcc) const
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/avc_decoder_configuration_record.h"
    +
    8 
    +
    9 #include "packager/base/strings/string_number_conversions.h"
    +
    10 #include "packager/base/strings/string_util.h"
    +
    11 #include "packager/media/base/buffer_reader.h"
    +
    12 #include "packager/media/base/rcheck.h"
    +
    13 #include "packager/media/codecs/h264_parser.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    18 AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() = default;
    +
    19 
    +
    20 AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() = default;
    +
    21 
    +
    22 bool AVCDecoderConfigurationRecord::ParseInternal() {
    +
    23  // See ISO 14496-15 sec 5.3.3.1.2
    +
    24  BufferReader reader(data(), data_size());
    +
    25 
    +
    26  RCHECK(reader.Read1(&version_) && version_ == 1 &&
    +
    27  reader.Read1(&profile_indication_) &&
    +
    28  reader.Read1(&profile_compatibility_) && reader.Read1(&avc_level_));
    +
    29 
    +
    30  uint8_t length_size_minus_one;
    +
    31  RCHECK(reader.Read1(&length_size_minus_one));
    +
    32  if ((length_size_minus_one & 0x3) == 2) {
    +
    33  LOG(ERROR) << "Invalid NALU length size.";
    +
    34  return false;
    +
    35  }
    +
    36  set_nalu_length_size((length_size_minus_one & 0x3) + 1);
    +
    37 
    +
    38  uint8_t num_sps;
    +
    39  RCHECK(reader.Read1(&num_sps));
    +
    40  num_sps &= 0x1f;
    +
    41  if (num_sps < 1) {
    +
    42  VLOG(1) << "No SPS found.";
    +
    43  }
    +
    44 
    +
    45  for (uint8_t i = 0; i < num_sps; i++) {
    +
    46  uint16_t size = 0;
    +
    47  RCHECK(reader.Read2(&size));
    +
    48  const uint8_t* nalu_data = reader.data() + reader.pos();
    +
    49  RCHECK(reader.SkipBytes(size));
    +
    50 
    +
    51  Nalu nalu;
    +
    52  RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
    +
    53  RCHECK(nalu.type() == Nalu::H264_SPS);
    +
    54  AddNalu(nalu);
    +
    55 
    +
    56  if (i == 0) {
    +
    57  // It is unlikely to have more than one SPS in practice. Also there's
    +
    58  // no way to change the {coded,pixel}_{width,height} dynamically from
    +
    59  // VideoStreamInfo.
    +
    60  int sps_id = 0;
    +
    61  H264Parser parser;
    +
    62  RCHECK(parser.ParseSps(nalu, &sps_id) == H264Parser::kOk);
    + +
    64  parser.GetSps(sps_id)->transfer_characteristics);
    +
    65  RCHECK(ExtractResolutionFromSps(*parser.GetSps(sps_id), &coded_width_,
    +
    66  &coded_height_, &pixel_width_,
    +
    67  &pixel_height_));
    +
    68  }
    +
    69  }
    +
    70 
    +
    71  uint8_t pps_count;
    +
    72  RCHECK(reader.Read1(&pps_count));
    +
    73  for (uint8_t i = 0; i < pps_count; i++) {
    +
    74  uint16_t size = 0;
    +
    75  RCHECK(reader.Read2(&size));
    +
    76  const uint8_t* nalu_data = reader.data() + reader.pos();
    +
    77  RCHECK(reader.SkipBytes(size));
    +
    78 
    +
    79  Nalu nalu;
    +
    80  RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
    +
    81  RCHECK(nalu.type() == Nalu::H264_PPS);
    +
    82  AddNalu(nalu);
    +
    83  }
    +
    84 
    +
    85  if (profile_indication_ == 100 || profile_indication_ == 110 ||
    +
    86  profile_indication_ == 122 || profile_indication_ == 144) {
    +
    87 
    +
    88  uint8_t sps_ext_count;
    +
    89  if (!reader.Read1(&chroma_format_) || !reader.Read1(&bit_depth_luma_minus8_) ||
    +
    90  !reader.Read1(&bit_depth_chroma_minus8_) || !reader.Read1(&sps_ext_count)) {
    +
    91  LOG(WARNING) << "Insufficient bits in bitstream for given AVC profile";
    +
    92  return true;
    +
    93  }
    +
    94  chroma_format_ &= 0x3;
    +
    95  bit_depth_luma_minus8_ &= 0x7;
    +
    96  bit_depth_chroma_minus8_ &= 0x7;
    +
    97  for (uint8_t i = 0; i < sps_ext_count; i++) {
    +
    98  uint16_t size = 0;
    +
    99  RCHECK(reader.Read2(&size));
    +
    100  const uint8_t* nalu_data = reader.data() + reader.pos();
    +
    101  RCHECK(reader.SkipBytes(size));
    +
    102 
    +
    103  Nalu nalu;
    +
    104  RCHECK(nalu.Initialize(Nalu::kH264, nalu_data, size));
    +
    105  RCHECK(nalu.type() == Nalu::H264_SPSExtension);
    +
    106  AddNalu(nalu);
    +
    107  }
    +
    108  }
    +
    109  return true;
    +
    110 }
    +
    111 
    + +
    113  FourCC codec_fourcc) const {
    +
    114  return GetCodecString(codec_fourcc, profile_indication_,
    +
    115  profile_compatibility_, avc_level_);
    +
    116 }
    +
    117 
    + +
    119  FourCC codec_fourcc,
    +
    120  uint8_t profile_indication,
    +
    121  uint8_t profile_compatibility,
    +
    122  uint8_t avc_level) {
    +
    123  const uint8_t bytes[] = {profile_indication, profile_compatibility,
    +
    124  avc_level};
    +
    125  return FourCCToString(codec_fourcc) + "." +
    +
    126  base::ToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
    +
    127 }
    +
    128 
    +
    129 } // namespace media
    +
    130 } // namespace shaka
    + + +
    void AddNalu(const Nalu &nalu)
    Adds the given Nalu to the configuration.
    +
    void set_transfer_characteristics(uint8_t transfer_characteristics)
    Sets the transfer characteristics.
    +
    void set_nalu_length_size(uint8_t nalu_length_size)
    Sets the size of the NAL unit length field.
    + + +
    int type() const
    Definition: nalu_reader.h:113
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d76/classshaka_1_1hls_1_1HlsEntry.html b/docs/d5/d76/classshaka_1_1hls_1_1HlsEntry.html index d56d29590b..3db8630300 100644 --- a/docs/d5/d76/classshaka_1_1hls_1_1HlsEntry.html +++ b/docs/d5/d76/classshaka_1_1hls_1_1HlsEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::hls::HlsEntry Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Public Types

    -enum  EntryType { kExtInf, -kExtKey, -kExtDiscontinuity, -kExtPlacementOpportunity +enum class  EntryType { kExtInf +, kExtKey +, kExtDiscontinuity +, kExtPlacementOpportunity }   @@ -106,9 +109,7 @@ Protected Member Functions diff --git a/docs/d5/d7b/box__definitions_8h_source.html b/docs/d5/d7b/box__definitions_8h_source.html index 1ef3f1f4fa..f192428bf3 100644 --- a/docs/d5/d7b/box__definitions_8h_source.html +++ b/docs/d5/d7b/box__definitions_8h_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/formats/mp4/box_definitions.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    box_definitions.h
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_H_
    6 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_H_
    7 
    8 #include <vector>
    9 
    10 #include "packager/media/base/decrypt_config.h"
    11 #include "packager/media/base/fourccs.h"
    12 #include "packager/media/codecs/aac_audio_specific_config.h"
    13 #include "packager/media/codecs/es_descriptor.h"
    14 #include "packager/media/formats/mp4/box.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 class BufferReader;
    20 
    21 namespace mp4 {
    22 
    23 enum TrackType {
    24  kInvalid = 0,
    25  kVideo,
    26  kAudio,
    27  kHint,
    28  kText,
    29 };
    30 
    31 class BoxBuffer;
    32 
    33 #define DECLARE_BOX_METHODS(T) \
    34  public: \
    35  T(); \
    36  ~T() override; \
    37  \
    38  FourCC BoxType() const override; \
    39  \
    40  private: \
    41  bool ReadWriteInternal(BoxBuffer* buffer) override; \
    42  size_t ComputeSizeInternal() override; \
    43  \
    44  public:
    45 
    46 struct FileType : Box {
    47  DECLARE_BOX_METHODS(FileType);
    48 
    49  FourCC major_brand = FOURCC_NULL;
    50  uint32_t minor_version = 0;
    51  std::vector<FourCC> compatible_brands;
    52 };
    53 
    55  FourCC BoxType() const override;
    56 };
    57 
    59  DECLARE_BOX_METHODS(ProtectionSystemSpecificHeader);
    60 
    61  std::vector<uint8_t> raw_box;
    62 };
    63 
    65  DECLARE_BOX_METHODS(SampleAuxiliaryInformationOffset);
    66 
    67  std::vector<uint64_t> offsets;
    68 };
    69 
    71  DECLARE_BOX_METHODS(SampleAuxiliaryInformationSize);
    72 
    73  uint8_t default_sample_info_size = 0;
    74  uint32_t sample_count = 0;
    75  std::vector<uint8_t> sample_info_sizes;
    76 };
    77 
    85  bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer* buffer);
    92  bool ParseFromBuffer(uint8_t iv_size,
    93  bool has_subsamples,
    94  BufferReader* reader);
    96  uint32_t ComputeSize() const;
    99  uint32_t GetTotalSizeOfSubsamples() const;
    100 
    101  std::vector<uint8_t> initialization_vector;
    102  std::vector<SubsampleEntry> subsamples;
    103 };
    104 
    106  static const uint8_t kInvalidIvSize = 1;
    107 
    108  enum SampleEncryptionFlags {
    109  kUseSubsampleEncryption = 2,
    110  };
    111 
    112  DECLARE_BOX_METHODS(SampleEncryption);
    118  bool ParseFromSampleEncryptionData(
    119  uint8_t iv_size,
    120  std::vector<SampleEncryptionEntry>* sample_encryption_entries) const;
    121 
    124  std::vector<uint8_t> sample_encryption_data;
    125 
    126  uint8_t iv_size = kInvalidIvSize;
    127  std::vector<SampleEncryptionEntry> sample_encryption_entries;
    128 };
    129 
    130 struct OriginalFormat : Box {
    131  DECLARE_BOX_METHODS(OriginalFormat);
    132 
    133  FourCC format = FOURCC_NULL;
    134 };
    135 
    136 struct SchemeType : FullBox {
    137  DECLARE_BOX_METHODS(SchemeType);
    138 
    139  FourCC type = FOURCC_NULL;
    140  uint32_t version = 0u;
    141 };
    142 
    144  DECLARE_BOX_METHODS(TrackEncryption);
    145 
    146  uint8_t default_is_protected = 0;
    147  uint8_t default_per_sample_iv_size = 0;
    148  // Default to a vector of 16 zeros.
    149  std::vector<uint8_t> default_kid = std::vector<uint8_t>(16, 0);
    150 
    151  // For pattern-based encryption.
    152  uint8_t default_crypt_byte_block = 0;
    153  uint8_t default_skip_byte_block = 0;
    154 
    155  // Present only if
    156  // |default_is_protected == 1 && default_per_sample_iv_size == 0|.
    157  std::vector<uint8_t> default_constant_iv;
    158 };
    159 
    160 struct SchemeInfo : Box {
    161  DECLARE_BOX_METHODS(SchemeInfo);
    162 
    163  TrackEncryption track_encryption;
    164 };
    165 
    167  DECLARE_BOX_METHODS(ProtectionSchemeInfo);
    168 
    169  OriginalFormat format;
    170  SchemeType type;
    171  SchemeInfo info;
    172 };
    173 
    175  DECLARE_BOX_METHODS(MovieHeader);
    176 
    177  uint64_t creation_time = 0;
    178  uint64_t modification_time = 0;
    179  uint32_t timescale = 0;
    180  uint64_t duration = 0;
    181  int32_t rate = 1 << 16;
    182  int16_t volume = 1 << 8;
    183  uint32_t next_track_id = 0;
    184 };
    185 
    187  enum TrackHeaderFlags {
    188  kTrackEnabled = 0x000001,
    189  kTrackInMovie = 0x000002,
    190  kTrackInPreview = 0x000004,
    191  };
    192 
    193  DECLARE_BOX_METHODS(TrackHeader);
    194 
    195  uint64_t creation_time = 0;
    196  uint64_t modification_time = 0;
    197  uint32_t track_id = 0;
    198  uint64_t duration = 0;
    199  int16_t layer = 0;
    200  int16_t alternate_group = 0;
    201  int16_t volume = -1;
    202  // width and height specify the track's visual presentation size as
    203  // fixed-point 16.16 values.
    204  uint32_t width = 0;
    205  uint32_t height = 0;
    206 };
    207 
    209  uint64_t segment_duration = 0;
    210  int64_t media_time = 0;
    211  int16_t media_rate_integer = 0;
    212  int16_t media_rate_fraction = 0;
    213 };
    214 
    215 struct EditList : FullBox {
    216  DECLARE_BOX_METHODS(EditList);
    217 
    218  std::vector<EditListEntry> edits;
    219 };
    220 
    221 struct Edit : Box {
    222  DECLARE_BOX_METHODS(Edit);
    223 
    224  EditList list;
    225 };
    226 
    228  DECLARE_BOX_METHODS(HandlerReference);
    229 
    230  FourCC handler_type = FOURCC_NULL;
    231 };
    232 
    233 struct Language {
    234  bool ReadWrite(BoxBuffer* buffer);
    235  uint32_t ComputeSize() const;
    236 
    237  std::string code;
    238 };
    239 
    241 struct ID3v2 : FullBox {
    242  DECLARE_BOX_METHODS(ID3v2);
    243 
    244  Language language;
    245  std::vector<uint8_t> id3v2_data;
    246 };
    247 
    248 struct Metadata : FullBox {
    249  DECLARE_BOX_METHODS(Metadata);
    250 
    251  HandlerReference handler;
    252  ID3v2 id3v2;
    253 };
    254 
    255 // This defines a common structure for various CodecConfiguration boxes:
    256 // AVCConfiguration, HEVCConfiguration and VPCodecConfiguration.
    257 // Note that unlike the other two CodecConfiguration boxes, VPCodecConfiguration
    258 // box inherits from FullBox instead of Box, according to VP Codec ISO Media
    259 // File Format Binding specification. It will be handled properly in the
    260 // implementation.
    262  DECLARE_BOX_METHODS(CodecConfiguration);
    263 
    264  FourCC box_type = FOURCC_NULL;
    265  // Contains full codec configuration record, including possible extension
    266  // boxes.
    267  std::vector<uint8_t> data;
    268 };
    269 
    271  DECLARE_BOX_METHODS(PixelAspectRatio);
    272 
    273  uint32_t h_spacing = 0u;
    274  uint32_t v_spacing = 0u;
    275 };
    276 
    278  DECLARE_BOX_METHODS(VideoSampleEntry);
    279 
    280  // Returns actual format of this sample entry.
    281  FourCC GetActualFormat() const {
    282  return format == FOURCC_encv ? sinf.format.format : format;
    283  }
    284  // Returns the box type of codec configuration box from video format.
    285  FourCC GetCodecConfigurationBoxType(FourCC format) const;
    286 
    287  // Convert |extra_codec_configs| to vector.
    288  std::vector<uint8_t> ExtraCodecConfigsAsVector() const;
    289  // Parse |extra_codec_configs| from vector.
    290  bool ParseExtraCodecConfigsVector(const std::vector<uint8_t>& data);
    291 
    292  FourCC format = FOURCC_NULL;
    293  // data_reference_index is 1-based and "dref" box is mandatory so it is
    294  // always present.
    295  uint16_t data_reference_index = 1u;
    296  uint16_t width = 0u;
    297  uint16_t height = 0u;
    298 
    299  PixelAspectRatio pixel_aspect;
    301  CodecConfiguration codec_configuration;
    302  // Some codecs, e.g. Dolby Vision, have extra codec configuration boxes that
    303  // need to be propagated to muxers.
    304  std::vector<CodecConfiguration> extra_codec_configs;
    305 };
    306 
    308  DECLARE_BOX_METHODS(ElementaryStreamDescriptor);
    309 
    310  AACAudioSpecificConfig aac_audio_specific_config;
    311  ESDescriptor es_descriptor;
    312 };
    313 
    314 struct DTSSpecific : Box {
    315  DECLARE_BOX_METHODS(DTSSpecific);
    316 
    317  uint32_t sampling_frequency = 0u;
    318  uint32_t max_bitrate = 0u;
    319  uint32_t avg_bitrate = 0u;
    320  uint8_t pcm_sample_depth = 0u;
    321  std::vector<uint8_t> extra_data;
    322 };
    323 
    324 struct AC3Specific : Box {
    325  DECLARE_BOX_METHODS(AC3Specific);
    326 
    327  std::vector<uint8_t> data;
    328 };
    329 
    330 struct EC3Specific : Box {
    331  DECLARE_BOX_METHODS(EC3Specific);
    332 
    333  std::vector<uint8_t> data;
    334 };
    335 
    336 struct OpusSpecific : Box {
    337  DECLARE_BOX_METHODS(OpusSpecific);
    338 
    339  std::vector<uint8_t> opus_identification_header;
    340  // The number of priming samples. Extracted from |opus_identification_header|.
    341  uint16_t preskip = 0u;
    342 };
    343 
    344 // FLAC specific decoder configuration box:
    345 // https://github.com/xiph/flac/blob/master/doc/isoflac.txt
    346 // We do not care about the actual data inside, which is simply copied over.
    348  DECLARE_BOX_METHODS(FlacSpecific);
    349 
    350  std::vector<uint8_t> data;
    351 };
    352 
    354  DECLARE_BOX_METHODS(AudioSampleEntry);
    355 
    356  // Returns actual format of this sample entry.
    357  FourCC GetActualFormat() const {
    358  return format == FOURCC_enca ? sinf.format.format : format;
    359  }
    360 
    361  FourCC format = FOURCC_NULL;
    362  // data_reference_index is 1-based and "dref" box is mandatory so it is
    363  // always present.
    364  uint16_t data_reference_index = 1u;
    365  uint16_t channelcount = 2u;
    366  uint16_t samplesize = 16u;
    367  uint32_t samplerate = 0u;
    368 
    370 
    372  DTSSpecific ddts;
    373  AC3Specific dac3;
    374  EC3Specific dec3;
    375  OpusSpecific dops;
    376  FlacSpecific dfla;
    377 };
    378 
    380  DECLARE_BOX_METHODS(WebVTTConfigurationBox);
    381 
    382  std::string config;
    383 };
    384 
    386  DECLARE_BOX_METHODS(WebVTTSourceLabelBox);
    387 
    388  std::string source_label;
    389 };
    390 
    392  DECLARE_BOX_METHODS(TextSampleEntry);
    393 
    394  // Specifies fourcc of this sample entry. It needs to be set on write, e.g.
    395  // set to 'wvtt' to write WVTTSampleEntry; On read, it is recovered from box
    396  // header.
    397  FourCC format = FOURCC_NULL;
    398 
    399  // data_reference_index is 1-based and "dref" box is mandatory so it is
    400  // always present.
    401  uint16_t data_reference_index = 1u;
    402 
    403  // Sub boxes for wvtt text sample entry.
    404  WebVTTConfigurationBox config;
    405  WebVTTSourceLabelBox label;
    406  // Optional MPEG4BitRateBox.
    407 };
    408 
    410  DECLARE_BOX_METHODS(SampleDescription);
    411 
    412  TrackType type = kInvalid;
    413  // TODO(kqyang): Clean up the code to have one single member, e.g. by creating
    414  // SampleEntry struct, std::vector<SampleEntry> sample_entries.
    415  std::vector<VideoSampleEntry> video_entries;
    416  std::vector<AudioSampleEntry> audio_entries;
    417  std::vector<TextSampleEntry> text_entries;
    418 };
    419 
    420 struct DecodingTime {
    421  uint32_t sample_count;
    422  uint32_t sample_delta;
    423 };
    424 
    425 // stts.
    427  DECLARE_BOX_METHODS(DecodingTimeToSample);
    428 
    429  std::vector<DecodingTime> decoding_time;
    430 };
    431 
    433  uint32_t sample_count;
    434  // If version == 0, sample_offset is uint32_t;
    435  // If version == 1, sample_offset is int32_t.
    436  // Use int64_t so both can be supported properly.
    437  int64_t sample_offset;
    438 };
    439 
    440 // ctts. Optional.
    442  DECLARE_BOX_METHODS(CompositionTimeToSample);
    443 
    444  std::vector<CompositionOffset> composition_offset;
    445 };
    446 
    447 struct ChunkInfo {
    448  uint32_t first_chunk;
    449  uint32_t samples_per_chunk;
    450  uint32_t sample_description_index;
    451 };
    452 
    453 // stsc.
    455  DECLARE_BOX_METHODS(SampleToChunk);
    456 
    457  std::vector<ChunkInfo> chunk_info;
    458 };
    459 
    460 // stsz.
    461 struct SampleSize : FullBox {
    462  DECLARE_BOX_METHODS(SampleSize);
    463 
    464  uint32_t sample_size = 0u;
    465  uint32_t sample_count = 0u;
    466  std::vector<uint32_t> sizes;
    467 };
    468 
    469 // stz2.
    471  DECLARE_BOX_METHODS(CompactSampleSize);
    472 
    473  uint8_t field_size = 0u;
    474  std::vector<uint32_t> sizes;
    475 };
    476 
    477 // co64.
    479  DECLARE_BOX_METHODS(ChunkLargeOffset);
    480 
    481  std::vector<uint64_t> offsets;
    482 };
    483 
    484 // stco.
    486  DECLARE_BOX_METHODS(ChunkOffset);
    487 };
    488 
    489 // stss. Optional.
    490 struct SyncSample : FullBox {
    491  DECLARE_BOX_METHODS(SyncSample);
    492 
    493  std::vector<uint32_t> sample_number;
    494 };
    495 
    497  bool ReadWrite(BoxBuffer* buffer);
    498  uint32_t ComputeSize() const;
    499 
    500  uint8_t is_protected = 0u;
    501  uint8_t per_sample_iv_size = 0u;
    502  std::vector<uint8_t> key_id;
    503 
    504  // For pattern-based encryption.
    505  uint8_t crypt_byte_block = 0u;
    506  uint8_t skip_byte_block = 0u;
    507 
    508  // Present only if |is_protected == 1 && per_sample_iv_size == 0|.
    509  std::vector<uint8_t> constant_iv;
    510 };
    511 
    513  bool ReadWrite(BoxBuffer* buffer);
    514  uint32_t ComputeSize() const;
    515 
    516  int16_t roll_distance = 0;
    517 };
    518 
    520  DECLARE_BOX_METHODS(SampleGroupDescription);
    521 
    522  template <typename T>
    523  bool ReadWriteEntries(BoxBuffer* buffer, std::vector<T>* entries);
    524 
    525  uint32_t grouping_type = 0;
    526  // Only present if grouping_type == 'seig'.
    527  std::vector<CencSampleEncryptionInfoEntry>
    528  cenc_sample_encryption_info_entries;
    529  // Only present if grouping_type == 'roll'.
    530  std::vector<AudioRollRecoveryEntry> audio_roll_recovery_entries;
    531 };
    532 
    534  enum GroupDescriptionIndexBase {
    535  kTrackGroupDescriptionIndexBase = 0,
    536  kTrackFragmentGroupDescriptionIndexBase = 0x10000,
    537  };
    538 
    539  uint32_t sample_count = 0u;
    540  uint32_t group_description_index = 0u;
    541 };
    542 
    544  DECLARE_BOX_METHODS(SampleToGroup);
    545 
    546  uint32_t grouping_type = 0u;
    547  uint32_t grouping_type_parameter = 0u; // Version 1 only.
    548  std::vector<SampleToGroupEntry> entries;
    549 };
    550 
    551 struct SampleTable : Box {
    552  DECLARE_BOX_METHODS(SampleTable);
    553 
    554  SampleDescription description;
    555  DecodingTimeToSample decoding_time_to_sample;
    556  CompositionTimeToSample composition_time_to_sample;
    557  SampleToChunk sample_to_chunk;
    558  // Either SampleSize or CompactSampleSize must present. Store in SampleSize.
    559  SampleSize sample_size;
    560  // Either ChunkOffset or ChunkLargeOffset must present. Store in
    561  // ChunkLargeOffset.
    562  ChunkLargeOffset chunk_large_offset;
    563  SyncSample sync_sample;
    564  std::vector<SampleGroupDescription> sample_group_descriptions;
    565  std::vector<SampleToGroup> sample_to_groups;
    566 };
    567 
    569  DECLARE_BOX_METHODS(MediaHeader);
    570 
    571  uint64_t creation_time = 0u;
    572  uint64_t modification_time = 0u;
    573  uint32_t timescale = 0u;
    574  uint64_t duration = 0u;
    575  Language language;
    576 };
    577 
    579  DECLARE_BOX_METHODS(VideoMediaHeader);
    580 
    581  uint16_t graphicsmode = 0u;
    582  uint16_t opcolor_red = 0u;
    583  uint16_t opcolor_green = 0u;
    584  uint16_t opcolor_blue = 0u;
    585 };
    586 
    588  DECLARE_BOX_METHODS(SoundMediaHeader);
    589 
    590  uint16_t balance = 0u;
    591 };
    592 
    594  DECLARE_BOX_METHODS(SubtitleMediaHeader);
    595 };
    596 
    598  DECLARE_BOX_METHODS(DataEntryUrl);
    599 
    600  std::vector<uint8_t> location;
    601 };
    602 
    604  DECLARE_BOX_METHODS(DataReference);
    605 
    606  // Can be either url or urn box. Fix to url box for now.
    607  std::vector<DataEntryUrl> data_entry = std::vector<DataEntryUrl>(1);
    608 };
    609 
    611  DECLARE_BOX_METHODS(DataInformation);
    612 
    613  DataReference dref;
    614 };
    615 
    617  DECLARE_BOX_METHODS(MediaInformation);
    618 
    619  DataInformation dinf;
    620  SampleTable sample_table;
    621  // Exactly one specific meida header shall be present, vmhd, smhd, hmhd, nmhd.
    622  VideoMediaHeader vmhd;
    623  SoundMediaHeader smhd;
    624  SubtitleMediaHeader sthd;
    625 };
    626 
    627 struct Media : Box {
    628  DECLARE_BOX_METHODS(Media);
    629 
    630  MediaHeader header;
    631  HandlerReference handler;
    632  MediaInformation information;
    633 };
    634 
    635 struct Track : Box {
    636  DECLARE_BOX_METHODS(Track);
    637 
    638  TrackHeader header;
    639  Media media;
    640  Edit edit;
    641  SampleEncryption sample_encryption;
    642 };
    643 
    645  DECLARE_BOX_METHODS(MovieExtendsHeader);
    646 
    647  uint64_t fragment_duration = 0u;
    648 };
    649 
    651  DECLARE_BOX_METHODS(TrackExtends);
    652 
    653  uint32_t track_id = 0u;
    654  uint32_t default_sample_description_index = 0u;
    655  uint32_t default_sample_duration = 0u;
    656  uint32_t default_sample_size = 0u;
    657  uint32_t default_sample_flags = 0u;
    658 };
    659 
    660 struct MovieExtends : Box {
    661  DECLARE_BOX_METHODS(MovieExtends);
    662 
    663  MovieExtendsHeader header;
    664  std::vector<TrackExtends> tracks;
    665 };
    666 
    667 struct Movie : Box {
    668  DECLARE_BOX_METHODS(Movie);
    669 
    670  MovieHeader header;
    671  Metadata metadata; // Used to hold version information.
    672  MovieExtends extends;
    673  std::vector<Track> tracks;
    674  std::vector<ProtectionSystemSpecificHeader> pssh;
    675 };
    676 
    678  DECLARE_BOX_METHODS(TrackFragmentDecodeTime);
    679 
    680  uint64_t decode_time = 0u;
    681 };
    682 
    684  DECLARE_BOX_METHODS(MovieFragmentHeader);
    685 
    686  uint32_t sequence_number = 0u;
    687 };
    688 
    690  enum TrackFragmentFlagsMasks {
    691  kBaseDataOffsetPresentMask = 0x000001,
    692  kSampleDescriptionIndexPresentMask = 0x000002,
    693  kDefaultSampleDurationPresentMask = 0x000008,
    694  kDefaultSampleSizePresentMask = 0x000010,
    695  kDefaultSampleFlagsPresentMask = 0x000020,
    696  kDurationIsEmptyMask = 0x010000,
    697  kDefaultBaseIsMoofMask = 0x020000,
    698  };
    699 
    700  enum SampleFlagsMasks {
    701  kReservedMask = 0xFC000000,
    702  kSampleDependsOnMask = 0x03000000,
    703  kSampleIsDependedOnMask = 0x00C00000,
    704  kSampleHasRedundancyMask = 0x00300000,
    705  kSamplePaddingValueMask = 0x000E0000,
    706  kNonKeySampleMask = 0x00010000,
    707  kSampleDegradationPriorityMask = 0x0000FFFF,
    708  };
    709 
    710  DECLARE_BOX_METHODS(TrackFragmentHeader);
    711 
    712  uint32_t track_id = 0u;
    713  uint32_t sample_description_index = 0u;
    714  uint32_t default_sample_duration = 0u;
    715  uint32_t default_sample_size = 0u;
    716  uint32_t default_sample_flags = 0u;
    717 };
    718 
    720  enum TrackFragmentFlagsMasks {
    721  kDataOffsetPresentMask = 0x000001,
    722  kFirstSampleFlagsPresentMask = 0x000004,
    723  kSampleDurationPresentMask = 0x000100,
    724  kSampleSizePresentMask = 0x000200,
    725  kSampleFlagsPresentMask = 0x000400,
    726  kSampleCompTimeOffsetsPresentMask = 0x000800,
    727  };
    728 
    729  DECLARE_BOX_METHODS(TrackFragmentRun);
    730 
    731  uint32_t sample_count = 0u;
    732  uint32_t data_offset = 0u;
    733  std::vector<uint32_t> sample_flags;
    734  std::vector<uint32_t> sample_sizes;
    735  std::vector<uint32_t> sample_durations;
    736  std::vector<int64_t> sample_composition_time_offsets;
    737 };
    738 
    739 struct TrackFragment : Box {
    740  DECLARE_BOX_METHODS(TrackFragment);
    741 
    742  TrackFragmentHeader header;
    743  std::vector<TrackFragmentRun> runs;
    744  bool decode_time_absent = false;
    745  TrackFragmentDecodeTime decode_time;
    746  std::vector<SampleGroupDescription> sample_group_descriptions;
    747  std::vector<SampleToGroup> sample_to_groups;
    748  SampleAuxiliaryInformationSize auxiliary_size;
    749  SampleAuxiliaryInformationOffset auxiliary_offset;
    750  SampleEncryption sample_encryption;
    751 };
    752 
    753 struct MovieFragment : Box {
    754  DECLARE_BOX_METHODS(MovieFragment);
    755 
    756  MovieFragmentHeader header;
    757  std::vector<TrackFragment> tracks;
    758  std::vector<ProtectionSystemSpecificHeader> pssh;
    759 };
    760 
    762  enum SAPType {
    763  TypeUnknown = 0,
    764  Type1 = 1, // T(ept) = T(dec) = T(sap) = T(ptf)
    765  Type2 = 2, // T(ept) = T(dec) = T(sap) < T(ptf)
    766  Type3 = 3, // T(ept) < T(dec) = T(sap) <= T(ptf)
    767  Type4 = 4, // T(ept) <= T(ptf) < T(dec) = T(sap)
    768  Type5 = 5, // T(ept) = T(dec) < T(sap)
    769  Type6 = 6, // T(ept) < T(dec) < T(sap)
    770  };
    771 
    772  bool reference_type = false;
    773  uint32_t referenced_size = 0u;
    774  uint32_t subsegment_duration = 0u;
    775  bool starts_with_sap = false;
    776  SAPType sap_type = TypeUnknown;
    777  uint32_t sap_delta_time = 0u;
    778  // We add this field to keep track of earliest_presentation_time in this
    779  // subsegment. It is not part of SegmentReference.
    780  uint64_t earliest_presentation_time = 0u;
    781 };
    782 
    784  DECLARE_BOX_METHODS(SegmentIndex);
    785 
    786  uint32_t reference_id = 0u;
    787  uint32_t timescale = 0u;
    788  uint64_t earliest_presentation_time = 0u;
    789  uint64_t first_offset = 0u;
    790  std::vector<SegmentReference> references;
    791 };
    792 
    793 // The actual data is parsed and written separately.
    794 struct MediaData : Box {
    795  DECLARE_BOX_METHODS(MediaData);
    796 
    797  uint32_t data_size = 0u;
    798 };
    799 
    800 // Using negative value as "not set". It is very unlikely that 2^31 cues happen
    801 // at once.
    802 const int kCueSourceIdNotSet = -1;
    803 
    804 struct CueSourceIDBox : Box {
    805  DECLARE_BOX_METHODS(CueSourceIDBox);
    806 
    807  int32_t source_id = kCueSourceIdNotSet;
    808 };
    809 
    810 struct CueTimeBox : Box {
    811  DECLARE_BOX_METHODS(CueTimeBox);
    812 
    813  std::string cue_current_time;
    814 };
    815 
    816 struct CueIDBox : Box {
    817  DECLARE_BOX_METHODS(CueIDBox);
    818 
    819  std::string cue_id;
    820 };
    821 
    822 struct CueSettingsBox : Box {
    823  DECLARE_BOX_METHODS(CueSettingsBox);
    824 
    825  std::string settings;
    826 };
    827 
    828 struct CuePayloadBox : Box {
    829  DECLARE_BOX_METHODS(CuePayloadBox);
    830 
    831  std::string cue_text;
    832 };
    833 
    834 struct VTTEmptyCueBox : Box {
    835  DECLARE_BOX_METHODS(VTTEmptyCueBox);
    836 };
    837 
    839  DECLARE_BOX_METHODS(VTTAdditionalTextBox);
    840 
    841  std::string cue_additional_text;
    842 };
    843 
    844 struct VTTCueBox : Box {
    845  DECLARE_BOX_METHODS(VTTCueBox);
    846 
    847  CueSourceIDBox cue_source_id;
    848  CueIDBox cue_id;
    849  CueTimeBox cue_time;
    850  CueSettingsBox cue_settings;
    851  CuePayloadBox cue_payload;
    852 };
    853 
    854 #undef DECLARE_BOX
    855 
    856 } // namespace mp4
    857 } // namespace media
    858 } // namespace shaka
    859 
    860 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_H_
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    All the methods that are virtual are virtual for mocking.
    - - - - - - - - - -
    uint32_t ComputeSize()
    Definition: box.cc:50
    - - - - - - - - - -
    std::vector< uint8_t > sample_encryption_data
    - - - - - - - - - - - - - - - - - - - - -
    Implemented per http://mp4ra.org/#/references.
    - - - - - - - - - - - - - - - - - - - -
    FourCC BoxType() const override
    - - - +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_H_
    +
    7 
    +
    8 #include <vector>
    +
    9 
    +
    10 #include "packager/media/base/decrypt_config.h"
    +
    11 #include "packager/media/base/fourccs.h"
    +
    12 #include "packager/media/codecs/aac_audio_specific_config.h"
    +
    13 #include "packager/media/codecs/es_descriptor.h"
    +
    14 #include "packager/media/formats/mp4/box.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 class BufferReader;
    +
    20 
    +
    21 namespace mp4 {
    +
    22 
    +
    23 enum TrackType {
    +
    24  kInvalid = 0,
    +
    25  kVideo,
    +
    26  kAudio,
    +
    27  kHint,
    +
    28  kText,
    +
    29  kSubtitle,
    +
    30 };
    +
    31 
    +
    32 class BoxBuffer;
    +
    33 
    +
    34 #define DECLARE_BOX_METHODS(T) \
    +
    35  public: \
    +
    36  T(); \
    +
    37  ~T() override; \
    +
    38  \
    +
    39  FourCC BoxType() const override; \
    +
    40  \
    +
    41  private: \
    +
    42  bool ReadWriteInternal(BoxBuffer* buffer) override; \
    +
    43  size_t ComputeSizeInternal() override; \
    +
    44  \
    +
    45  public:
    +
    46 
    +
    47 struct FileType : Box {
    +
    48  DECLARE_BOX_METHODS(FileType);
    +
    49 
    +
    50  FourCC major_brand = FOURCC_NULL;
    +
    51  uint32_t minor_version = 0;
    +
    52  std::vector<FourCC> compatible_brands;
    +
    53 };
    +
    54 
    + +
    56  FourCC BoxType() const override;
    +
    57 };
    +
    58 
    + +
    60  DECLARE_BOX_METHODS(ProtectionSystemSpecificHeader);
    +
    61 
    +
    62  std::vector<uint8_t> raw_box;
    +
    63 };
    +
    64 
    + +
    66  DECLARE_BOX_METHODS(SampleAuxiliaryInformationOffset);
    +
    67 
    +
    68  std::vector<uint64_t> offsets;
    +
    69 };
    +
    70 
    + +
    72  DECLARE_BOX_METHODS(SampleAuxiliaryInformationSize);
    +
    73 
    +
    74  uint8_t default_sample_info_size = 0;
    +
    75  uint32_t sample_count = 0;
    +
    76  std::vector<uint8_t> sample_info_sizes;
    +
    77 };
    +
    78 
    + +
    86  bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer* buffer);
    +
    93  bool ParseFromBuffer(uint8_t iv_size,
    +
    94  bool has_subsamples,
    +
    95  BufferReader* reader);
    +
    97  uint32_t ComputeSize() const;
    +
    100  uint32_t GetTotalSizeOfSubsamples() const;
    +
    101 
    +
    102  std::vector<uint8_t> initialization_vector;
    +
    103  std::vector<SubsampleEntry> subsamples;
    +
    104 };
    +
    105 
    + +
    107  static const uint8_t kInvalidIvSize = 1;
    +
    108 
    +
    109  enum SampleEncryptionFlags {
    +
    110  kUseSubsampleEncryption = 2,
    +
    111  };
    +
    112 
    +
    113  DECLARE_BOX_METHODS(SampleEncryption);
    + +
    120  uint8_t iv_size,
    +
    121  std::vector<SampleEncryptionEntry>* sample_encryption_entries) const;
    +
    122 
    +
    125  std::vector<uint8_t> sample_encryption_data;
    +
    126 
    +
    127  uint8_t iv_size = kInvalidIvSize;
    +
    128  std::vector<SampleEncryptionEntry> sample_encryption_entries;
    +
    129 };
    +
    130 
    +
    131 struct OriginalFormat : Box {
    +
    132  DECLARE_BOX_METHODS(OriginalFormat);
    +
    133 
    +
    134  FourCC format = FOURCC_NULL;
    +
    135 };
    +
    136 
    +
    137 struct SchemeType : FullBox {
    +
    138  DECLARE_BOX_METHODS(SchemeType);
    +
    139 
    +
    140  FourCC type = FOURCC_NULL;
    +
    141  uint32_t version = 0u;
    +
    142 };
    +
    143 
    + +
    145  DECLARE_BOX_METHODS(TrackEncryption);
    +
    146 
    +
    147  uint8_t default_is_protected = 0;
    +
    148  uint8_t default_per_sample_iv_size = 0;
    +
    149  // Default to a vector of 16 zeros.
    +
    150  std::vector<uint8_t> default_kid = std::vector<uint8_t>(16, 0);
    +
    151 
    +
    152  // For pattern-based encryption.
    +
    153  uint8_t default_crypt_byte_block = 0;
    +
    154  uint8_t default_skip_byte_block = 0;
    +
    155 
    +
    156  // Present only if
    +
    157  // |default_is_protected == 1 && default_per_sample_iv_size == 0|.
    +
    158  std::vector<uint8_t> default_constant_iv;
    +
    159 };
    +
    160 
    +
    161 struct SchemeInfo : Box {
    +
    162  DECLARE_BOX_METHODS(SchemeInfo);
    +
    163 
    +
    164  TrackEncryption track_encryption;
    +
    165 };
    +
    166 
    + +
    168  DECLARE_BOX_METHODS(ProtectionSchemeInfo);
    +
    169 
    +
    170  OriginalFormat format;
    +
    171  SchemeType type;
    +
    172  SchemeInfo info;
    +
    173 };
    +
    174 
    + +
    176  DECLARE_BOX_METHODS(MovieHeader);
    +
    177 
    +
    178  uint64_t creation_time = 0;
    +
    179  uint64_t modification_time = 0;
    +
    180  uint32_t timescale = 0;
    +
    181  uint64_t duration = 0;
    +
    182  int32_t rate = 1 << 16;
    +
    183  int16_t volume = 1 << 8;
    +
    184  uint32_t next_track_id = 0;
    +
    185 };
    +
    186 
    + +
    188  enum TrackHeaderFlags {
    +
    189  kTrackEnabled = 0x000001,
    +
    190  kTrackInMovie = 0x000002,
    +
    191  kTrackInPreview = 0x000004,
    +
    192  };
    +
    193 
    +
    194  DECLARE_BOX_METHODS(TrackHeader);
    +
    195 
    +
    196  uint64_t creation_time = 0;
    +
    197  uint64_t modification_time = 0;
    +
    198  uint32_t track_id = 0;
    +
    199  uint64_t duration = 0;
    +
    200  int16_t layer = 0;
    +
    201  int16_t alternate_group = 0;
    +
    202  int16_t volume = -1;
    +
    203  // width and height specify the track's visual presentation size as
    +
    204  // fixed-point 16.16 values.
    +
    205  uint32_t width = 0;
    +
    206  uint32_t height = 0;
    +
    207 };
    +
    208 
    + +
    210  uint64_t segment_duration = 0;
    +
    211  int64_t media_time = 0;
    +
    212  int16_t media_rate_integer = 0;
    +
    213  int16_t media_rate_fraction = 0;
    +
    214 };
    +
    215 
    +
    216 struct EditList : FullBox {
    +
    217  DECLARE_BOX_METHODS(EditList);
    +
    218 
    +
    219  std::vector<EditListEntry> edits;
    +
    220 };
    +
    221 
    +
    222 struct Edit : Box {
    +
    223  DECLARE_BOX_METHODS(Edit);
    +
    224 
    +
    225  EditList list;
    +
    226 };
    +
    227 
    + +
    229  DECLARE_BOX_METHODS(HandlerReference);
    +
    230 
    +
    231  FourCC handler_type = FOURCC_NULL;
    +
    232 };
    +
    233 
    +
    234 struct Language {
    +
    235  bool ReadWrite(BoxBuffer* buffer);
    +
    236  uint32_t ComputeSize() const;
    +
    237 
    +
    238  std::string code;
    +
    239 };
    +
    240 
    +
    242 struct ID3v2 : FullBox {
    +
    243  DECLARE_BOX_METHODS(ID3v2);
    +
    244 
    +
    245  Language language;
    +
    246  std::vector<uint8_t> id3v2_data;
    +
    247 };
    +
    248 
    +
    249 struct Metadata : FullBox {
    +
    250  DECLARE_BOX_METHODS(Metadata);
    +
    251 
    +
    252  HandlerReference handler;
    +
    253  ID3v2 id3v2;
    +
    254 };
    +
    255 
    +
    256 // This defines a common structure for various CodecConfiguration boxes:
    +
    257 // AVCConfiguration, HEVCConfiguration and VPCodecConfiguration.
    +
    258 // Note that unlike the other two CodecConfiguration boxes, VPCodecConfiguration
    +
    259 // box inherits from FullBox instead of Box, according to VP Codec ISO Media
    +
    260 // File Format Binding specification. It will be handled properly in the
    +
    261 // implementation.
    + +
    263  DECLARE_BOX_METHODS(CodecConfiguration);
    +
    264 
    +
    265  FourCC box_type = FOURCC_NULL;
    +
    266  // Contains full codec configuration record, including possible extension
    +
    267  // boxes.
    +
    268  std::vector<uint8_t> data;
    +
    269 };
    +
    270 
    + +
    272  DECLARE_BOX_METHODS(PixelAspectRatio);
    +
    273 
    +
    274  uint32_t h_spacing = 0u;
    +
    275  uint32_t v_spacing = 0u;
    +
    276 };
    +
    277 
    + +
    279  DECLARE_BOX_METHODS(VideoSampleEntry);
    +
    280 
    +
    281  // Returns actual format of this sample entry.
    +
    282  FourCC GetActualFormat() const {
    +
    283  return format == FOURCC_encv ? sinf.format.format : format;
    +
    284  }
    +
    285  // Returns the box type of codec configuration box from video format.
    +
    286  FourCC GetCodecConfigurationBoxType(FourCC format) const;
    +
    287 
    +
    288  // Convert |extra_codec_configs| to vector.
    +
    289  std::vector<uint8_t> ExtraCodecConfigsAsVector() const;
    +
    290  // Parse |extra_codec_configs| from vector.
    +
    291  bool ParseExtraCodecConfigsVector(const std::vector<uint8_t>& data);
    +
    292 
    +
    293  FourCC format = FOURCC_NULL;
    +
    294  // data_reference_index is 1-based and "dref" box is mandatory so it is
    +
    295  // always present.
    +
    296  uint16_t data_reference_index = 1u;
    +
    297  uint16_t width = 0u;
    +
    298  uint16_t height = 0u;
    +
    299 
    +
    300  PixelAspectRatio pixel_aspect;
    + +
    302  CodecConfiguration codec_configuration;
    +
    303  // Some codecs, e.g. Dolby Vision, have extra codec configuration boxes that
    +
    304  // need to be propagated to muxers.
    +
    305  std::vector<CodecConfiguration> extra_codec_configs;
    +
    306 };
    +
    307 
    + +
    309  DECLARE_BOX_METHODS(ElementaryStreamDescriptor);
    +
    310 
    +
    311  AACAudioSpecificConfig aac_audio_specific_config;
    +
    312  ESDescriptor es_descriptor;
    +
    313 };
    +
    314 
    +
    315 struct DTSSpecific : Box {
    +
    316  DECLARE_BOX_METHODS(DTSSpecific);
    +
    317 
    +
    318  uint32_t sampling_frequency = 0u;
    +
    319  uint32_t max_bitrate = 0u;
    +
    320  uint32_t avg_bitrate = 0u;
    +
    321  uint8_t pcm_sample_depth = 0u;
    +
    322  std::vector<uint8_t> extra_data;
    +
    323 };
    +
    324 
    +
    325 struct AC3Specific : Box {
    +
    326  DECLARE_BOX_METHODS(AC3Specific);
    +
    327 
    +
    328  std::vector<uint8_t> data;
    +
    329 };
    +
    330 
    +
    331 struct EC3Specific : Box {
    +
    332  DECLARE_BOX_METHODS(EC3Specific);
    +
    333 
    +
    334  std::vector<uint8_t> data;
    +
    335 };
    +
    336 
    +
    337 struct AC4Specific : Box {
    +
    338  DECLARE_BOX_METHODS(AC4Specific);
    +
    339 
    +
    340  std::vector<uint8_t> data;
    +
    341 };
    +
    342 
    +
    343 struct OpusSpecific : Box {
    +
    344  DECLARE_BOX_METHODS(OpusSpecific);
    +
    345 
    +
    346  std::vector<uint8_t> opus_identification_header;
    +
    347  // The number of priming samples. Extracted from |opus_identification_header|.
    +
    348  uint16_t preskip = 0u;
    +
    349 };
    +
    350 
    +
    351 // FLAC specific decoder configuration box:
    +
    352 // https://github.com/xiph/flac/blob/master/doc/isoflac.txt
    +
    353 // We do not care about the actual data inside, which is simply copied over.
    + +
    355  DECLARE_BOX_METHODS(FlacSpecific);
    +
    356 
    +
    357  std::vector<uint8_t> data;
    +
    358 };
    +
    359 
    + +
    361  DECLARE_BOX_METHODS(AudioSampleEntry);
    +
    362 
    +
    363  // Returns actual format of this sample entry.
    +
    364  FourCC GetActualFormat() const {
    +
    365  return format == FOURCC_enca ? sinf.format.format : format;
    +
    366  }
    +
    367 
    +
    368  FourCC format = FOURCC_NULL;
    +
    369  // data_reference_index is 1-based and "dref" box is mandatory so it is
    +
    370  // always present.
    +
    371  uint16_t data_reference_index = 1u;
    +
    372  uint16_t channelcount = 2u;
    +
    373  uint16_t samplesize = 16u;
    +
    374  uint32_t samplerate = 0u;
    +
    375 
    + +
    377 
    + +
    379  DTSSpecific ddts;
    +
    380  AC3Specific dac3;
    +
    381  EC3Specific dec3;
    +
    382  AC4Specific dac4;
    +
    383  OpusSpecific dops;
    +
    384  FlacSpecific dfla;
    +
    385 };
    +
    386 
    + +
    388  DECLARE_BOX_METHODS(WebVTTConfigurationBox);
    +
    389 
    +
    390  std::string config;
    +
    391 };
    +
    392 
    + +
    394  DECLARE_BOX_METHODS(WebVTTSourceLabelBox);
    +
    395 
    +
    396  std::string source_label;
    +
    397 };
    +
    398 
    + +
    400  DECLARE_BOX_METHODS(TextSampleEntry);
    +
    401 
    +
    402  // Specifies fourcc of this sample entry. It needs to be set on write, e.g.
    +
    403  // set to 'wvtt' to write WVTTSampleEntry; On read, it is recovered from box
    +
    404  // header.
    +
    405  FourCC format = FOURCC_NULL;
    +
    406 
    +
    407  // data_reference_index is 1-based and "dref" box is mandatory so it is
    +
    408  // always present.
    +
    409  uint16_t data_reference_index = 1u;
    +
    410 
    +
    411  // Sub fields for ttml text sample entry.
    +
    412  std::string namespace_;
    +
    413  std::string schema_location;
    +
    414  // Optional MPEG4BitRateBox.
    +
    415 
    +
    416  // Sub boxes for wvtt text sample entry.
    +
    417  WebVTTConfigurationBox config;
    +
    418  WebVTTSourceLabelBox label;
    +
    419  // Optional MPEG4BitRateBox.
    +
    420 };
    +
    421 
    + +
    423  DECLARE_BOX_METHODS(SampleDescription);
    +
    424 
    +
    425  TrackType type = kInvalid;
    +
    426  // TODO(kqyang): Clean up the code to have one single member, e.g. by creating
    +
    427  // SampleEntry struct, std::vector<SampleEntry> sample_entries.
    +
    428  std::vector<VideoSampleEntry> video_entries;
    +
    429  std::vector<AudioSampleEntry> audio_entries;
    +
    430  std::vector<TextSampleEntry> text_entries;
    +
    431 };
    +
    432 
    +
    433 struct DecodingTime {
    +
    434  uint32_t sample_count;
    +
    435  uint32_t sample_delta;
    +
    436 };
    +
    437 
    +
    438 // stts.
    + +
    440  DECLARE_BOX_METHODS(DecodingTimeToSample);
    +
    441 
    +
    442  std::vector<DecodingTime> decoding_time;
    +
    443 };
    +
    444 
    + +
    446  uint32_t sample_count;
    +
    447  // If version == 0, sample_offset is uint32_t;
    +
    448  // If version == 1, sample_offset is int32_t.
    +
    449  // Use int64_t so both can be supported properly.
    +
    450  int64_t sample_offset;
    +
    451 };
    +
    452 
    +
    453 // ctts. Optional.
    + +
    455  DECLARE_BOX_METHODS(CompositionTimeToSample);
    +
    456 
    +
    457  std::vector<CompositionOffset> composition_offset;
    +
    458 };
    +
    459 
    +
    460 struct ChunkInfo {
    +
    461  uint32_t first_chunk;
    +
    462  uint32_t samples_per_chunk;
    +
    463  uint32_t sample_description_index;
    +
    464 };
    +
    465 
    +
    466 // stsc.
    + +
    468  DECLARE_BOX_METHODS(SampleToChunk);
    +
    469 
    +
    470  std::vector<ChunkInfo> chunk_info;
    +
    471 };
    +
    472 
    +
    473 // stsz.
    +
    474 struct SampleSize : FullBox {
    +
    475  DECLARE_BOX_METHODS(SampleSize);
    +
    476 
    +
    477  uint32_t sample_size = 0u;
    +
    478  uint32_t sample_count = 0u;
    +
    479  std::vector<uint32_t> sizes;
    +
    480 };
    +
    481 
    +
    482 // stz2.
    + +
    484  DECLARE_BOX_METHODS(CompactSampleSize);
    +
    485 
    +
    486  uint8_t field_size = 0u;
    +
    487  std::vector<uint32_t> sizes;
    +
    488 };
    +
    489 
    +
    490 // co64.
    + +
    492  DECLARE_BOX_METHODS(ChunkLargeOffset);
    +
    493 
    +
    494  std::vector<uint64_t> offsets;
    +
    495 };
    +
    496 
    +
    497 // stco.
    + +
    499  DECLARE_BOX_METHODS(ChunkOffset);
    +
    500 };
    +
    501 
    +
    502 // stss. Optional.
    +
    503 struct SyncSample : FullBox {
    +
    504  DECLARE_BOX_METHODS(SyncSample);
    +
    505 
    +
    506  std::vector<uint32_t> sample_number;
    +
    507 };
    +
    508 
    + +
    510  bool ReadWrite(BoxBuffer* buffer);
    +
    511  uint32_t ComputeSize() const;
    +
    512 
    +
    513  uint8_t is_protected = 0u;
    +
    514  uint8_t per_sample_iv_size = 0u;
    +
    515  std::vector<uint8_t> key_id;
    +
    516 
    +
    517  // For pattern-based encryption.
    +
    518  uint8_t crypt_byte_block = 0u;
    +
    519  uint8_t skip_byte_block = 0u;
    +
    520 
    +
    521  // Present only if |is_protected == 1 && per_sample_iv_size == 0|.
    +
    522  std::vector<uint8_t> constant_iv;
    +
    523 };
    +
    524 
    + +
    526  bool ReadWrite(BoxBuffer* buffer);
    +
    527  uint32_t ComputeSize() const;
    +
    528 
    +
    529  int16_t roll_distance = 0;
    +
    530 };
    +
    531 
    + +
    533  DECLARE_BOX_METHODS(SampleGroupDescription);
    +
    534 
    +
    535  template <typename T>
    +
    536  bool ReadWriteEntries(BoxBuffer* buffer, std::vector<T>* entries);
    +
    537 
    +
    538  uint32_t grouping_type = 0;
    +
    539  // Only present if grouping_type == 'seig'.
    +
    540  std::vector<CencSampleEncryptionInfoEntry>
    +
    541  cenc_sample_encryption_info_entries;
    +
    542  // Only present if grouping_type == 'roll'.
    +
    543  std::vector<AudioRollRecoveryEntry> audio_roll_recovery_entries;
    +
    544 };
    +
    545 
    + +
    547  enum GroupDescriptionIndexBase {
    +
    548  kTrackGroupDescriptionIndexBase = 0,
    +
    549  kTrackFragmentGroupDescriptionIndexBase = 0x10000,
    +
    550  };
    +
    551 
    +
    552  uint32_t sample_count = 0u;
    +
    553  uint32_t group_description_index = 0u;
    +
    554 };
    +
    555 
    + +
    557  DECLARE_BOX_METHODS(SampleToGroup);
    +
    558 
    +
    559  uint32_t grouping_type = 0u;
    +
    560  uint32_t grouping_type_parameter = 0u; // Version 1 only.
    +
    561  std::vector<SampleToGroupEntry> entries;
    +
    562 };
    +
    563 
    +
    564 struct SampleTable : Box {
    +
    565  DECLARE_BOX_METHODS(SampleTable);
    +
    566 
    +
    567  SampleDescription description;
    +
    568  DecodingTimeToSample decoding_time_to_sample;
    +
    569  CompositionTimeToSample composition_time_to_sample;
    +
    570  SampleToChunk sample_to_chunk;
    +
    571  // Either SampleSize or CompactSampleSize must present. Store in SampleSize.
    +
    572  SampleSize sample_size;
    +
    573  // Either ChunkOffset or ChunkLargeOffset must present. Store in
    +
    574  // ChunkLargeOffset.
    +
    575  ChunkLargeOffset chunk_large_offset;
    +
    576  SyncSample sync_sample;
    +
    577  std::vector<SampleGroupDescription> sample_group_descriptions;
    +
    578  std::vector<SampleToGroup> sample_to_groups;
    +
    579 };
    +
    580 
    + +
    582  DECLARE_BOX_METHODS(MediaHeader);
    +
    583 
    +
    584  uint64_t creation_time = 0u;
    +
    585  uint64_t modification_time = 0u;
    +
    586  uint32_t timescale = 0u;
    +
    587  uint64_t duration = 0u;
    +
    588  Language language;
    +
    589 };
    +
    590 
    + +
    592  DECLARE_BOX_METHODS(VideoMediaHeader);
    +
    593 
    +
    594  uint16_t graphicsmode = 0u;
    +
    595  uint16_t opcolor_red = 0u;
    +
    596  uint16_t opcolor_green = 0u;
    +
    597  uint16_t opcolor_blue = 0u;
    +
    598 };
    +
    599 
    + +
    601  DECLARE_BOX_METHODS(SoundMediaHeader);
    +
    602 
    +
    603  uint16_t balance = 0u;
    +
    604 };
    +
    605 
    + +
    607  DECLARE_BOX_METHODS(NullMediaHeader);
    +
    608 };
    +
    609 
    + +
    611  DECLARE_BOX_METHODS(SubtitleMediaHeader);
    +
    612 };
    +
    613 
    + +
    615  DECLARE_BOX_METHODS(DataEntryUrl);
    +
    616 
    +
    617  std::vector<uint8_t> location;
    +
    618 };
    +
    619 
    + +
    621  DECLARE_BOX_METHODS(DataReference);
    +
    622 
    +
    623  // Can be either url or urn box. Fix to url box for now.
    +
    624  std::vector<DataEntryUrl> data_entry = std::vector<DataEntryUrl>(1);
    +
    625 };
    +
    626 
    + +
    628  DECLARE_BOX_METHODS(DataInformation);
    +
    629 
    +
    630  DataReference dref;
    +
    631 };
    +
    632 
    + +
    634  DECLARE_BOX_METHODS(MediaInformation);
    +
    635 
    +
    636  DataInformation dinf;
    +
    637  SampleTable sample_table;
    +
    638  // Exactly one specific meida header shall be present, vmhd, smhd, hmhd, nmhd.
    +
    639  VideoMediaHeader vmhd;
    +
    640  SoundMediaHeader smhd;
    +
    641  NullMediaHeader nmhd;
    +
    642  SubtitleMediaHeader sthd;
    +
    643 };
    +
    644 
    +
    645 struct Media : Box {
    +
    646  DECLARE_BOX_METHODS(Media);
    +
    647 
    +
    648  MediaHeader header;
    +
    649  HandlerReference handler;
    +
    650  MediaInformation information;
    +
    651 };
    +
    652 
    +
    653 struct Track : Box {
    +
    654  DECLARE_BOX_METHODS(Track);
    +
    655 
    +
    656  TrackHeader header;
    +
    657  Media media;
    +
    658  Edit edit;
    +
    659  SampleEncryption sample_encryption;
    +
    660 };
    +
    661 
    + +
    663  DECLARE_BOX_METHODS(MovieExtendsHeader);
    +
    664 
    +
    665  uint64_t fragment_duration = 0u;
    +
    666 };
    +
    667 
    + +
    669  DECLARE_BOX_METHODS(TrackExtends);
    +
    670 
    +
    671  uint32_t track_id = 0u;
    +
    672  uint32_t default_sample_description_index = 0u;
    +
    673  uint32_t default_sample_duration = 0u;
    +
    674  uint32_t default_sample_size = 0u;
    +
    675  uint32_t default_sample_flags = 0u;
    +
    676 };
    +
    677 
    +
    678 struct MovieExtends : Box {
    +
    679  DECLARE_BOX_METHODS(MovieExtends);
    +
    680 
    +
    681  MovieExtendsHeader header;
    +
    682  std::vector<TrackExtends> tracks;
    +
    683 };
    +
    684 
    +
    685 struct Movie : Box {
    +
    686  DECLARE_BOX_METHODS(Movie);
    +
    687 
    +
    688  MovieHeader header;
    +
    689  Metadata metadata; // Used to hold version information.
    +
    690  MovieExtends extends;
    +
    691  std::vector<Track> tracks;
    +
    692  std::vector<ProtectionSystemSpecificHeader> pssh;
    +
    693 };
    +
    694 
    + +
    696  DECLARE_BOX_METHODS(TrackFragmentDecodeTime);
    +
    697 
    +
    698  uint64_t decode_time = 0u;
    +
    699 };
    +
    700 
    + +
    702  DECLARE_BOX_METHODS(MovieFragmentHeader);
    +
    703 
    +
    704  uint32_t sequence_number = 0u;
    +
    705 };
    +
    706 
    + +
    708  enum TrackFragmentFlagsMasks {
    +
    709  kBaseDataOffsetPresentMask = 0x000001,
    +
    710  kSampleDescriptionIndexPresentMask = 0x000002,
    +
    711  kDefaultSampleDurationPresentMask = 0x000008,
    +
    712  kDefaultSampleSizePresentMask = 0x000010,
    +
    713  kDefaultSampleFlagsPresentMask = 0x000020,
    +
    714  kDurationIsEmptyMask = 0x010000,
    +
    715  kDefaultBaseIsMoofMask = 0x020000,
    +
    716  };
    +
    717 
    +
    718  enum SampleFlagsMasks {
    +
    719  kReservedMask = 0xFC000000,
    +
    720  kSampleDependsOnMask = 0x03000000,
    +
    721  kSampleIsDependedOnMask = 0x00C00000,
    +
    722  kSampleHasRedundancyMask = 0x00300000,
    +
    723  kSamplePaddingValueMask = 0x000E0000,
    +
    724  kNonKeySampleMask = 0x00010000,
    +
    725  kSampleDegradationPriorityMask = 0x0000FFFF,
    +
    726  };
    +
    727 
    +
    728  DECLARE_BOX_METHODS(TrackFragmentHeader);
    +
    729 
    +
    730  uint32_t track_id = 0u;
    +
    731  uint32_t sample_description_index = 0u;
    +
    732  uint32_t default_sample_duration = 0u;
    +
    733  uint32_t default_sample_size = 0u;
    +
    734  uint32_t default_sample_flags = 0u;
    +
    735 };
    +
    736 
    + +
    738  enum TrackFragmentFlagsMasks {
    +
    739  kDataOffsetPresentMask = 0x000001,
    +
    740  kFirstSampleFlagsPresentMask = 0x000004,
    +
    741  kSampleDurationPresentMask = 0x000100,
    +
    742  kSampleSizePresentMask = 0x000200,
    +
    743  kSampleFlagsPresentMask = 0x000400,
    +
    744  kSampleCompTimeOffsetsPresentMask = 0x000800,
    +
    745  };
    +
    746 
    +
    747  DECLARE_BOX_METHODS(TrackFragmentRun);
    +
    748 
    +
    749  uint32_t sample_count = 0u;
    +
    750  uint32_t data_offset = 0u;
    +
    751  std::vector<uint32_t> sample_flags;
    +
    752  std::vector<uint32_t> sample_sizes;
    +
    753  std::vector<uint32_t> sample_durations;
    +
    754  std::vector<int64_t> sample_composition_time_offsets;
    +
    755 };
    +
    756 
    +
    757 struct TrackFragment : Box {
    +
    758  DECLARE_BOX_METHODS(TrackFragment);
    +
    759 
    +
    760  TrackFragmentHeader header;
    +
    761  std::vector<TrackFragmentRun> runs;
    +
    762  bool decode_time_absent = false;
    +
    763  TrackFragmentDecodeTime decode_time;
    +
    764  std::vector<SampleGroupDescription> sample_group_descriptions;
    +
    765  std::vector<SampleToGroup> sample_to_groups;
    +
    766  SampleAuxiliaryInformationSize auxiliary_size;
    +
    767  SampleAuxiliaryInformationOffset auxiliary_offset;
    +
    768  SampleEncryption sample_encryption;
    +
    769 };
    +
    770 
    +
    771 struct MovieFragment : Box {
    +
    772  DECLARE_BOX_METHODS(MovieFragment);
    +
    773 
    +
    774  MovieFragmentHeader header;
    +
    775  std::vector<TrackFragment> tracks;
    +
    776  std::vector<ProtectionSystemSpecificHeader> pssh;
    +
    777 };
    +
    778 
    + +
    780  enum SAPType {
    +
    781  TypeUnknown = 0,
    +
    782  Type1 = 1, // T(ept) = T(dec) = T(sap) = T(ptf)
    +
    783  Type2 = 2, // T(ept) = T(dec) = T(sap) < T(ptf)
    +
    784  Type3 = 3, // T(ept) < T(dec) = T(sap) <= T(ptf)
    +
    785  Type4 = 4, // T(ept) <= T(ptf) < T(dec) = T(sap)
    +
    786  Type5 = 5, // T(ept) = T(dec) < T(sap)
    +
    787  Type6 = 6, // T(ept) < T(dec) < T(sap)
    +
    788  };
    +
    789 
    +
    790  bool reference_type = false;
    +
    791  uint32_t referenced_size = 0u;
    +
    792  uint32_t subsegment_duration = 0u;
    +
    793  bool starts_with_sap = false;
    +
    794  SAPType sap_type = TypeUnknown;
    +
    795  uint32_t sap_delta_time = 0u;
    +
    796  // We add this field to keep track of earliest_presentation_time in this
    +
    797  // subsegment. It is not part of SegmentReference.
    +
    798  uint64_t earliest_presentation_time = 0u;
    +
    799 };
    +
    800 
    + +
    802  DECLARE_BOX_METHODS(SegmentIndex);
    +
    803 
    +
    804  uint32_t reference_id = 0u;
    +
    805  uint32_t timescale = 0u;
    +
    806  uint64_t earliest_presentation_time = 0u;
    +
    807  uint64_t first_offset = 0u;
    +
    808  std::vector<SegmentReference> references;
    +
    809 };
    +
    810 
    +
    811 // The actual data is parsed and written separately.
    +
    812 struct MediaData : Box {
    +
    813  DECLARE_BOX_METHODS(MediaData);
    +
    814 
    +
    815  uint32_t data_size = 0u;
    +
    816 };
    +
    817 
    +
    818 // Using negative value as "not set". It is very unlikely that 2^31 cues happen
    +
    819 // at once.
    +
    820 const int kCueSourceIdNotSet = -1;
    +
    821 
    +
    822 struct CueSourceIDBox : Box {
    +
    823  DECLARE_BOX_METHODS(CueSourceIDBox);
    +
    824 
    +
    825  int32_t source_id = kCueSourceIdNotSet;
    +
    826 };
    +
    827 
    +
    828 struct CueTimeBox : Box {
    +
    829  DECLARE_BOX_METHODS(CueTimeBox);
    +
    830 
    +
    831  std::string cue_current_time;
    +
    832 };
    +
    833 
    +
    834 struct CueIDBox : Box {
    +
    835  DECLARE_BOX_METHODS(CueIDBox);
    +
    836 
    +
    837  std::string cue_id;
    +
    838 };
    +
    839 
    +
    840 struct CueSettingsBox : Box {
    +
    841  DECLARE_BOX_METHODS(CueSettingsBox);
    +
    842 
    +
    843  std::string settings;
    +
    844 };
    +
    845 
    +
    846 struct CuePayloadBox : Box {
    +
    847  DECLARE_BOX_METHODS(CuePayloadBox);
    +
    848 
    +
    849  std::string cue_text;
    +
    850 };
    +
    851 
    +
    852 struct VTTEmptyCueBox : Box {
    +
    853  DECLARE_BOX_METHODS(VTTEmptyCueBox);
    +
    854 };
    +
    855 
    + +
    857  DECLARE_BOX_METHODS(VTTAdditionalTextBox);
    +
    858 
    +
    859  std::string cue_additional_text;
    +
    860 };
    +
    861 
    +
    862 struct VTTCueBox : Box {
    +
    863  DECLARE_BOX_METHODS(VTTCueBox);
    +
    864 
    +
    865  CueSourceIDBox cue_source_id;
    +
    866  CueIDBox cue_id;
    +
    867  CueTimeBox cue_time;
    +
    868  CueSettingsBox cue_settings;
    +
    869  CuePayloadBox cue_payload;
    +
    870 };
    +
    871 
    +
    872 #undef DECLARE_BOX
    +
    873 
    +
    874 } // namespace mp4
    +
    875 } // namespace media
    +
    876 } // namespace shaka
    +
    877 
    +
    878 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_H_
    + + + + +
    All the methods that are virtual are virtual for mocking.
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Implemented per http://mp4ra.org/#/references.
    + + + + + + + + + + + + + + + + + + + + + + +
    bool ParseFromBuffer(uint8_t iv_size, bool has_subsamples, BufferReader *reader)
    +
    bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer *buffer)
    + + + +
    bool ParseFromSampleEncryptionData(uint8_t iv_size, std::vector< SampleEncryptionEntry > *sample_encryption_entries) const
    +
    std::vector< uint8_t > sample_encryption_data
    + + + + + + + + + + + +
    FourCC BoxType() const override
    + + + + + + + + + + + + + + + + + + +
    diff --git a/docs/d5/d86/structshaka_1_1media_1_1mp4_1_1MediaInformation.html b/docs/d5/d86/structshaka_1_1media_1_1mp4_1_1MediaInformation.html index 8fee772ce5..e2f21be3bf 100644 --- a/docs/d5/d86/structshaka_1_1media_1_1mp4_1_1MediaInformation.html +++ b/docs/d5/d86/structshaka_1_1media_1_1mp4_1_1MediaInformation.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MediaInformation Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -112,6 +115,9 @@ Public Attributes + + @@ -124,7 +130,7 @@ Additional Inherited Members

    Public Member Functions

    SoundMediaHeader smhd
     
    +NullMediaHeader nmhd
     
    SubtitleMediaHeader sthd
     

    Detailed Description

    -

    Definition at line 616 of file box_definitions.h.

    +

    Definition at line 633 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -152,7 +158,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2131 of file box_definitions.cc.

    +

    Definition at line 2206 of file box_definitions.cc.

    @@ -163,9 +169,7 @@ Additional Inherited Members diff --git a/docs/d5/d89/widevine__key__source_8cc_source.html b/docs/d5/d89/widevine__key__source_8cc_source.html index 91f201ded3..b52ffe22a4 100644 --- a/docs/d5/d89/widevine__key__source_8cc_source.html +++ b/docs/d5/d89/widevine__key__source_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/widevine_key_source.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    widevine_key_source.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/widevine_key_source.h"
    8 
    9 #include <gflags/gflags.h>
    10 
    11 #include "packager/base/base64.h"
    12 #include "packager/base/bind.h"
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/media/base/http_key_fetcher.h"
    15 #include "packager/media/base/network_util.h"
    16 #include "packager/media/base/producer_consumer_queue.h"
    17 #include "packager/media/base/protection_system_ids.h"
    18 #include "packager/media/base/protection_system_specific_info.h"
    19 #include "packager/media/base/proto_json_util.h"
    20 #include "packager/media/base/pssh_generator_util.h"
    21 #include "packager/media/base/rcheck.h"
    22 #include "packager/media/base/request_signer.h"
    23 #include "packager/media/base/widevine_common_encryption.pb.h"
    24 
    25 DEFINE_string(video_feature,
    26  "",
    27  "Specify the optional video feature, e.g. HDR.");
    28 
    29 namespace shaka {
    30 namespace media {
    31 namespace {
    32 
    33 const bool kEnableKeyRotation = true;
    34 
    35 // Number of times to retry requesting keys in case of a transient error from
    36 // the server.
    37 const int kNumTransientErrorRetries = 5;
    38 const int kFirstRetryDelayMilliseconds = 1000;
    39 
    40 // Default crypto period count, which is the number of keys to fetch on every
    41 // key rotation enabled request.
    42 const int kDefaultCryptoPeriodCount = 10;
    43 const int kGetKeyTimeoutInSeconds = 5 * 60; // 5 minutes.
    44 const int kKeyFetchTimeoutInSeconds = 60; // 1 minute.
    45 
    46 CommonEncryptionRequest::ProtectionScheme ToCommonEncryptionProtectionScheme(
    47  FourCC protection_scheme) {
    48  switch (protection_scheme) {
    49  case FOURCC_cenc:
    50  return CommonEncryptionRequest::CENC;
    51  case FOURCC_cbcs:
    52  case kAppleSampleAesProtectionScheme:
    53  // Treat sample aes as a variant of cbcs.
    54  return CommonEncryptionRequest::CBCS;
    55  case FOURCC_cbc1:
    56  return CommonEncryptionRequest::CBC1;
    57  case FOURCC_cens:
    58  return CommonEncryptionRequest::CENS;
    59  default:
    60  LOG(WARNING) << "Ignore unrecognized protection scheme "
    61  << FourCCToString(protection_scheme);
    62  return CommonEncryptionRequest::UNSPECIFIED;
    63  }
    64 }
    65 
    66 ProtectionSystemSpecificInfo ProtectionSystemInfoFromPsshProto(
    67  const CommonEncryptionResponse::Track::Pssh& pssh_proto) {
    68  PsshBoxBuilder pssh_builder;
    69  pssh_builder.set_system_id(kWidevineSystemId, arraysize(kWidevineSystemId));
    70 
    71  if (pssh_proto.has_boxes()) {
    72  return {pssh_builder.system_id(),
    73  std::vector<uint8_t>(pssh_proto.boxes().begin(),
    74  pssh_proto.boxes().end())};
    75  } else {
    76  pssh_builder.set_pssh_box_version(0);
    77  const std::vector<uint8_t> pssh_data(pssh_proto.data().begin(),
    78  pssh_proto.data().end());
    79  pssh_builder.set_pssh_data(pssh_data);
    80  return {pssh_builder.system_id(), pssh_builder.CreateBox()};
    81  }
    82 }
    83 
    84 } // namespace
    85 
    86 WidevineKeySource::WidevineKeySource(const std::string& server_url,
    87  int protection_system_flags,
    88  FourCC protection_scheme)
    89  // Widevine PSSH is fetched from Widevine license server.
    90  : KeySource(protection_system_flags & ~WIDEVINE_PROTECTION_SYSTEM_FLAG,
    91  protection_scheme),
    92  generate_widevine_protection_system_(
    93  // Generate Widevine protection system if there are no other
    94  // protection system specified.
    95  protection_system_flags == NO_PROTECTION_SYSTEM_FLAG ||
    96  protection_system_flags & WIDEVINE_PROTECTION_SYSTEM_FLAG),
    97  key_production_thread_("KeyProductionThread",
    98  base::Bind(&WidevineKeySource::FetchKeysTask,
    99  base::Unretained(this))),
    100  key_fetcher_(new HttpKeyFetcher(kKeyFetchTimeoutInSeconds)),
    101  server_url_(server_url),
    102  crypto_period_count_(kDefaultCryptoPeriodCount),
    103  protection_scheme_(protection_scheme),
    104  start_key_production_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
    105  base::WaitableEvent::InitialState::NOT_SIGNALED) {
    106  key_production_thread_.Start();
    107 }
    108 
    109 WidevineKeySource::~WidevineKeySource() {
    110  if (key_pool_)
    111  key_pool_->Stop();
    112  if (key_production_thread_.HasBeenStarted()) {
    113  // Signal the production thread to start key production if it is not
    114  // signaled yet so the thread can be joined.
    115  start_key_production_.Signal();
    116  key_production_thread_.Join();
    117  }
    118 }
    119 
    120 Status WidevineKeySource::FetchKeys(const std::vector<uint8_t>& content_id,
    121  const std::string& policy) {
    122  base::AutoLock scoped_lock(lock_);
    123  common_encryption_request_.reset(new CommonEncryptionRequest);
    124  common_encryption_request_->set_content_id(content_id.data(),
    125  content_id.size());
    126  common_encryption_request_->set_policy(policy);
    127  common_encryption_request_->set_protection_scheme(
    128  ToCommonEncryptionProtectionScheme(protection_scheme_));
    129  if (enable_entitlement_license_)
    130  common_encryption_request_->set_enable_entitlement_license(true);
    131 
    132  return FetchKeysInternal(!kEnableKeyRotation, 0, false);
    133 }
    134 
    135 Status WidevineKeySource::FetchKeys(EmeInitDataType init_data_type,
    136  const std::vector<uint8_t>& init_data) {
    137  std::vector<uint8_t> pssh_data;
    138  uint32_t asset_id = 0;
    139  switch (init_data_type) {
    140  case EmeInitDataType::CENC: {
    141  const std::vector<uint8_t> widevine_system_id(
    142  kWidevineSystemId, kWidevineSystemId + arraysize(kWidevineSystemId));
    143  std::vector<ProtectionSystemSpecificInfo> protection_systems_info;
    145  init_data.data(), init_data.size(), &protection_systems_info)) {
    146  return Status(error::PARSER_FAILURE, "Error parsing the PSSH boxes.");
    147  }
    148  for (const auto& info : protection_systems_info) {
    149  std::unique_ptr<PsshBoxBuilder> pssh_builder =
    150  PsshBoxBuilder::ParseFromBox(info.psshs.data(), info.psshs.size());
    151  if (!pssh_builder)
    152  return Status(error::PARSER_FAILURE, "Error parsing the PSSH box.");
    153  // Use Widevine PSSH if available otherwise construct a Widevine PSSH
    154  // from the first available key ids.
    155  if (info.system_id == widevine_system_id) {
    156  pssh_data = pssh_builder->pssh_data();
    157  break;
    158  } else if (pssh_data.empty() && !pssh_builder->key_ids().empty()) {
    159  pssh_data =
    160  GenerateWidevinePsshDataFromKeyIds(pssh_builder->key_ids());
    161  // Continue to see if there is any Widevine PSSH. The KeyId generated
    162  // PSSH is only used if a Widevine PSSH could not be found.
    163  continue;
    164  }
    165  }
    166  if (pssh_data.empty())
    167  return Status(error::INVALID_ARGUMENT, "No supported PSSHs found.");
    168  break;
    169  }
    170  case EmeInitDataType::WEBM: {
    171  pssh_data = GenerateWidevinePsshDataFromKeyIds({init_data});
    172  break;
    173  }
    174  case EmeInitDataType::WIDEVINE_CLASSIC:
    175  if (init_data.size() < sizeof(asset_id))
    176  return Status(error::INVALID_ARGUMENT, "Invalid asset id.");
    177  asset_id = ntohlFromBuffer(init_data.data());
    178  break;
    179  default:
    180  LOG(ERROR) << "Init data type " << static_cast<int>(init_data_type)
    181  << " not supported.";
    182  return Status(error::INVALID_ARGUMENT, "Unsupported init data type.");
    183  }
    184  const bool widevine_classic =
    185  init_data_type == EmeInitDataType::WIDEVINE_CLASSIC;
    186  base::AutoLock scoped_lock(lock_);
    187  common_encryption_request_.reset(new CommonEncryptionRequest);
    188  if (widevine_classic) {
    189  common_encryption_request_->set_asset_id(asset_id);
    190  } else {
    191  common_encryption_request_->set_pssh_data(pssh_data.data(),
    192  pssh_data.size());
    193  }
    194  return FetchKeysInternal(!kEnableKeyRotation, 0, widevine_classic);
    195 }
    196 
    197 Status WidevineKeySource::GetKey(const std::string& stream_label,
    198  EncryptionKey* key) {
    199  DCHECK(key);
    200  if (encryption_key_map_.find(stream_label) == encryption_key_map_.end()) {
    201  return Status(error::INTERNAL_ERROR,
    202  "Cannot find key for '" + stream_label + "'.");
    203  }
    204  *key = *encryption_key_map_[stream_label];
    205  return Status::OK;
    206 }
    207 
    208 Status WidevineKeySource::GetKey(const std::vector<uint8_t>& key_id,
    209  EncryptionKey* key) {
    210  DCHECK(key);
    211  for (const auto& pair : encryption_key_map_) {
    212  if (pair.second->key_id == key_id) {
    213  *key = *pair.second;
    214  return Status::OK;
    215  }
    216  }
    217  return Status(error::INTERNAL_ERROR,
    218  "Cannot find key with specified key ID");
    219 }
    220 
    221 Status WidevineKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
    222  uint32_t crypto_period_duration_in_seconds,
    223  const std::string& stream_label,
    224  EncryptionKey* key) {
    225  DCHECK(key_production_thread_.HasBeenStarted());
    226  // TODO(kqyang): This is not elegant. Consider refactoring later.
    227  {
    228  base::AutoLock scoped_lock(lock_);
    229  if (!key_production_started_) {
    230  crypto_period_duration_in_seconds_ = crypto_period_duration_in_seconds;
    231  // Another client may have a slightly smaller starting crypto period
    232  // index. Set the initial value to account for that.
    233  first_crypto_period_index_ =
    234  crypto_period_index ? crypto_period_index - 1 : 0;
    235  DCHECK(!key_pool_);
    236  const size_t queue_size = crypto_period_count_ * 10;
    237  key_pool_.reset(
    238  new EncryptionKeyQueue(queue_size, first_crypto_period_index_));
    239  start_key_production_.Signal();
    240  key_production_started_ = true;
    241  } else if (crypto_period_duration_in_seconds_ !=
    242  crypto_period_duration_in_seconds) {
    243  return Status(error::INVALID_ARGUMENT,
    244  "Crypto period duration should not change.");
    245  }
    246  }
    247  return GetKeyInternal(crypto_period_index, stream_label, key);
    248 }
    249 
    250 void WidevineKeySource::set_signer(std::unique_ptr<RequestSigner> signer) {
    251  signer_ = std::move(signer);
    252 }
    253 
    255  std::unique_ptr<KeyFetcher> key_fetcher) {
    256  key_fetcher_ = std::move(key_fetcher);
    257 }
    258 
    259 Status WidevineKeySource::GetKeyInternal(uint32_t crypto_period_index,
    260  const std::string& stream_label,
    261  EncryptionKey* key) {
    262  DCHECK(key_pool_);
    263  DCHECK(key);
    264 
    265  std::shared_ptr<EncryptionKeyMap> encryption_key_map;
    266  Status status = key_pool_->Peek(crypto_period_index, &encryption_key_map,
    267  kGetKeyTimeoutInSeconds * 1000);
    268  if (!status.ok()) {
    269  if (status.error_code() == error::STOPPED) {
    270  CHECK(!common_encryption_request_status_.ok());
    271  return common_encryption_request_status_;
    272  }
    273  return status;
    274  }
    275 
    276  if (encryption_key_map->find(stream_label) == encryption_key_map->end()) {
    277  return Status(error::INTERNAL_ERROR,
    278  "Cannot find key for '" + stream_label + "'.");
    279  }
    280  *key = *encryption_key_map->at(stream_label);
    281  return Status::OK;
    282 }
    283 
    284 void WidevineKeySource::FetchKeysTask() {
    285  // Wait until key production is signaled.
    286  start_key_production_.Wait();
    287  if (!key_pool_ || key_pool_->Stopped())
    288  return;
    289 
    290  Status status = FetchKeysInternal(kEnableKeyRotation,
    291  first_crypto_period_index_,
    292  false);
    293  while (status.ok()) {
    294  first_crypto_period_index_ += crypto_period_count_;
    295  status = FetchKeysInternal(kEnableKeyRotation,
    296  first_crypto_period_index_,
    297  false);
    298  }
    299  common_encryption_request_status_ = status;
    300  key_pool_->Stop();
    301 }
    302 
    303 Status WidevineKeySource::FetchKeysInternal(bool enable_key_rotation,
    304  uint32_t first_crypto_period_index,
    305  bool widevine_classic) {
    306  CommonEncryptionRequest request;
    307  FillRequest(enable_key_rotation, first_crypto_period_index, &request);
    308 
    309  std::string message;
    310  Status status = GenerateKeyMessage(request, &message);
    311  if (!status.ok())
    312  return status;
    313  VLOG(1) << "Message: " << message;
    314 
    315  std::string raw_response;
    316  int64_t sleep_duration = kFirstRetryDelayMilliseconds;
    317 
    318  // Perform client side retries if seeing server transient error to workaround
    319  // server limitation.
    320  for (int i = 0; i < kNumTransientErrorRetries; ++i) {
    321  status = key_fetcher_->FetchKeys(server_url_, message, &raw_response);
    322  if (status.ok()) {
    323  VLOG(1) << "Retry [" << i << "] Response:" << raw_response;
    324 
    325  bool transient_error = false;
    326  if (ExtractEncryptionKey(enable_key_rotation, widevine_classic,
    327  raw_response, &transient_error))
    328  return Status::OK;
    329 
    330  if (!transient_error) {
    331  return Status(
    332  error::SERVER_ERROR,
    333  "Failed to extract encryption key from '" + raw_response + "'.");
    334  }
    335  } else if (status.error_code() != error::TIME_OUT) {
    336  return status;
    337  }
    338 
    339  // Exponential backoff.
    340  if (i != kNumTransientErrorRetries - 1) {
    341  base::PlatformThread::Sleep(
    342  base::TimeDelta::FromMilliseconds(sleep_duration));
    343  sleep_duration *= 2;
    344  }
    345  }
    346  return Status(error::SERVER_ERROR,
    347  "Failed to recover from server internal error.");
    348 }
    349 
    350 void WidevineKeySource::FillRequest(bool enable_key_rotation,
    351  uint32_t first_crypto_period_index,
    352  CommonEncryptionRequest* request) {
    353  DCHECK(common_encryption_request_);
    354  DCHECK(request);
    355  *request = *common_encryption_request_;
    356 
    357  request->add_tracks()->set_type("SD");
    358  request->add_tracks()->set_type("HD");
    359  request->add_tracks()->set_type("UHD1");
    360  request->add_tracks()->set_type("UHD2");
    361  request->add_tracks()->set_type("AUDIO");
    362 
    363  request->add_drm_types(ModularDrmType::WIDEVINE);
    364 
    365  if (enable_key_rotation) {
    366  request->set_first_crypto_period_index(first_crypto_period_index);
    367  request->set_crypto_period_count(crypto_period_count_);
    368  request->set_crypto_period_seconds(crypto_period_duration_in_seconds_);
    369  }
    370 
    371  if (!group_id_.empty())
    372  request->set_group_id(group_id_.data(), group_id_.size());
    373 
    374  if (!FLAGS_video_feature.empty())
    375  request->set_video_feature(FLAGS_video_feature);
    376 }
    377 
    378 Status WidevineKeySource::GenerateKeyMessage(
    379  const CommonEncryptionRequest& request,
    380  std::string* message) {
    381  DCHECK(message);
    382 
    383  SignedModularDrmRequest signed_request;
    384  signed_request.set_request(MessageToJsonString(request));
    385 
    386  // Sign the request.
    387  if (signer_) {
    388  std::string signature;
    389  if (!signer_->GenerateSignature(signed_request.request(), &signature))
    390  return Status(error::INTERNAL_ERROR, "Signature generation failed.");
    391 
    392  signed_request.set_signature(signature);
    393  signed_request.set_signer(signer_->signer_name());
    394  }
    395 
    396  *message = MessageToJsonString(signed_request);
    397  return Status::OK;
    398 }
    399 
    400 bool WidevineKeySource::ExtractEncryptionKey(
    401  bool enable_key_rotation,
    402  bool widevine_classic,
    403  const std::string& response,
    404  bool* transient_error) {
    405  DCHECK(transient_error);
    406  *transient_error = false;
    407 
    408  SignedModularDrmResponse signed_response_proto;
    409  if (!JsonStringToMessage(response, &signed_response_proto)) {
    410  LOG(ERROR) << "Failed to convert JSON to proto: " << response;
    411  return false;
    412  }
    413 
    414  CommonEncryptionResponse response_proto;
    415  if (!JsonStringToMessage(signed_response_proto.response(), &response_proto)) {
    416  LOG(ERROR) << "Failed to convert JSON to proto: "
    417  << signed_response_proto.response();
    418  return false;
    419  }
    420 
    421  if (response_proto.status() != CommonEncryptionResponse::OK) {
    422  LOG(ERROR) << "Received non-OK license response: " << response;
    423  // Server may return INTERNAL_ERROR intermittently, which is a transient
    424  // error and the next client request may succeed without problem.
    425  *transient_error =
    426  (response_proto.status() == CommonEncryptionResponse::INTERNAL_ERROR);
    427  return false;
    428  }
    429 
    430  RCHECK(enable_key_rotation
    431  ? response_proto.tracks_size() >= crypto_period_count_
    432  : response_proto.tracks_size() >= 1);
    433 
    434  uint32_t current_crypto_period_index = first_crypto_period_index_;
    435 
    436  EncryptionKeyMap encryption_key_map;
    437  for (const auto& track : response_proto.tracks()) {
    438  VLOG(2) << "track " << track.ShortDebugString();
    439 
    440  if (enable_key_rotation) {
    441  if (track.crypto_period_index() != current_crypto_period_index) {
    442  if (track.crypto_period_index() != current_crypto_period_index + 1) {
    443  LOG(ERROR) << "Expecting crypto period index "
    444  << current_crypto_period_index << " or "
    445  << current_crypto_period_index + 1 << "; Seen "
    446  << track.crypto_period_index();
    447  return false;
    448  }
    449  if (!PushToKeyPool(&encryption_key_map))
    450  return false;
    451  ++current_crypto_period_index;
    452  }
    453  }
    454 
    455  const std::string& stream_label = track.type();
    456  RCHECK(encryption_key_map.find(stream_label) == encryption_key_map.end());
    457 
    458  std::unique_ptr<EncryptionKey> encryption_key(new EncryptionKey());
    459  encryption_key->key.assign(track.key().begin(), track.key().end());
    460 
    461  // Get key ID and PSSH data for CENC content only.
    462  if (!widevine_classic) {
    463  encryption_key->key_id.assign(track.key_id().begin(),
    464  track.key_id().end());
    465  encryption_key->iv.assign(track.iv().begin(), track.iv().end());
    466 
    467  if (generate_widevine_protection_system_) {
    468  if (track.pssh_size() != 1) {
    469  LOG(ERROR) << "Expecting one and only one pssh, seeing "
    470  << track.pssh_size();
    471  return false;
    472  }
    473  encryption_key->key_system_info.push_back(
    474  ProtectionSystemInfoFromPsshProto(track.pssh(0)));
    475  }
    476  }
    477  encryption_key_map[stream_label] = std::move(encryption_key);
    478  }
    479 
    480  if (!widevine_classic) {
    481  if (!UpdateProtectionSystemInfo(&encryption_key_map).ok()) {
    482  return false;
    483  }
    484  }
    485 
    486  DCHECK(!encryption_key_map.empty());
    487  if (!enable_key_rotation) {
    488  // Merge with previously requested keys.
    489  for (auto& pair : encryption_key_map)
    490  encryption_key_map_[pair.first] = std::move(pair.second);
    491  return true;
    492  }
    493  return PushToKeyPool(&encryption_key_map);
    494 }
    495 
    496 bool WidevineKeySource::PushToKeyPool(
    497  EncryptionKeyMap* encryption_key_map) {
    498  DCHECK(key_pool_);
    499  DCHECK(encryption_key_map);
    500  auto encryption_key_map_shared = std::make_shared<EncryptionKeyMap>();
    501  encryption_key_map_shared->swap(*encryption_key_map);
    502  Status status = key_pool_->Push(encryption_key_map_shared, kInfiniteTimeout);
    503  if (!status.ok()) {
    504  DCHECK_EQ(error::STOPPED, status.error_code());
    505  return false;
    506  }
    507  return true;
    508 }
    509 
    510 } // namespace media
    511 } // namespace shaka
    -
    All the methods that are virtual are virtual for mocking.
    - - - -
    Status UpdateProtectionSystemInfo(EncryptionKeyMap *encryption_key_map)
    Definition: key_source.cc:48
    - -
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    - -
    void set_key_fetcher(std::unique_ptr< KeyFetcher > key_fetcher)
    -
    WidevineKeySource(const std::string &server_url, int protection_systems_flags, FourCC protection_scheme)
    -
    static std::unique_ptr< PsshBoxBuilder > ParseFromBox(const uint8_t *data, size_t data_size)
    -
    void set_signer(std::unique_ptr< RequestSigner > signer)
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    -
    static bool ParseBoxes(const uint8_t *data, size_t data_size, std::vector< ProtectionSystemSpecificInfo > *pssh_boxes)
    -
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/widevine_key_source.h"
    +
    8 
    +
    9 #include <gflags/gflags.h>
    +
    10 
    +
    11 #include "packager/base/base64.h"
    +
    12 #include "packager/base/bind.h"
    +
    13 #include "packager/base/strings/string_number_conversions.h"
    +
    14 #include "packager/media/base/http_key_fetcher.h"
    +
    15 #include "packager/media/base/network_util.h"
    +
    16 #include "packager/media/base/producer_consumer_queue.h"
    +
    17 #include "packager/media/base/protection_system_ids.h"
    +
    18 #include "packager/media/base/protection_system_specific_info.h"
    +
    19 #include "packager/media/base/proto_json_util.h"
    +
    20 #include "packager/media/base/pssh_generator_util.h"
    +
    21 #include "packager/media/base/rcheck.h"
    +
    22 #include "packager/media/base/request_signer.h"
    +
    23 #include "packager/media/base/widevine_common_encryption.pb.h"
    +
    24 
    +
    25 DEFINE_string(video_feature,
    +
    26  "",
    +
    27  "Specify the optional video feature, e.g. HDR.");
    +
    28 
    +
    29 namespace shaka {
    +
    30 namespace media {
    +
    31 namespace {
    +
    32 
    +
    33 const bool kEnableKeyRotation = true;
    +
    34 
    +
    35 // Number of times to retry requesting keys in case of a transient error from
    +
    36 // the server.
    +
    37 const int kNumTransientErrorRetries = 5;
    +
    38 const int kFirstRetryDelayMilliseconds = 1000;
    +
    39 
    +
    40 // Default crypto period count, which is the number of keys to fetch on every
    +
    41 // key rotation enabled request.
    +
    42 const int kDefaultCryptoPeriodCount = 10;
    +
    43 const int kGetKeyTimeoutInSeconds = 5 * 60; // 5 minutes.
    +
    44 const int kKeyFetchTimeoutInSeconds = 60; // 1 minute.
    +
    45 
    +
    46 CommonEncryptionRequest::ProtectionScheme ToCommonEncryptionProtectionScheme(
    +
    47  FourCC protection_scheme) {
    +
    48  switch (protection_scheme) {
    +
    49  case FOURCC_cenc:
    +
    50  return CommonEncryptionRequest::CENC;
    +
    51  case FOURCC_cbcs:
    +
    52  case kAppleSampleAesProtectionScheme:
    +
    53  // Treat sample aes as a variant of cbcs.
    +
    54  return CommonEncryptionRequest::CBCS;
    +
    55  case FOURCC_cbc1:
    +
    56  return CommonEncryptionRequest::CBC1;
    +
    57  case FOURCC_cens:
    +
    58  return CommonEncryptionRequest::CENS;
    +
    59  default:
    +
    60  LOG(WARNING) << "Ignore unrecognized protection scheme "
    +
    61  << FourCCToString(protection_scheme);
    +
    62  return CommonEncryptionRequest::UNSPECIFIED;
    +
    63  }
    +
    64 }
    +
    65 
    +
    66 ProtectionSystemSpecificInfo ProtectionSystemInfoFromPsshProto(
    +
    67  const CommonEncryptionResponse::Track::Pssh& pssh_proto) {
    +
    68  PsshBoxBuilder pssh_builder;
    +
    69  pssh_builder.set_system_id(kWidevineSystemId, arraysize(kWidevineSystemId));
    +
    70 
    +
    71  if (pssh_proto.has_boxes()) {
    +
    72  return {pssh_builder.system_id(),
    +
    73  std::vector<uint8_t>(pssh_proto.boxes().begin(),
    +
    74  pssh_proto.boxes().end())};
    +
    75  } else {
    +
    76  pssh_builder.set_pssh_box_version(0);
    +
    77  const std::vector<uint8_t> pssh_data(pssh_proto.data().begin(),
    +
    78  pssh_proto.data().end());
    +
    79  pssh_builder.set_pssh_data(pssh_data);
    +
    80  return {pssh_builder.system_id(), pssh_builder.CreateBox()};
    +
    81  }
    +
    82 }
    +
    83 
    +
    84 } // namespace
    +
    85 
    +
    86 WidevineKeySource::WidevineKeySource(const std::string& server_url,
    +
    87  ProtectionSystem protection_systems,
    +
    88  FourCC protection_scheme)
    +
    89  // Widevine PSSH is fetched from Widevine license server.
    +
    90  : generate_widevine_protection_system_(
    +
    91  // Generate Widevine protection system if there are no other
    +
    92  // protection system specified.
    +
    93  protection_systems == ProtectionSystem::kNone ||
    +
    94  has_flag(protection_systems, ProtectionSystem::kWidevine)),
    +
    95  key_production_thread_("KeyProductionThread",
    +
    96  base::Bind(&WidevineKeySource::FetchKeysTask,
    +
    97  base::Unretained(this))),
    +
    98  key_fetcher_(new HttpKeyFetcher(kKeyFetchTimeoutInSeconds)),
    +
    99  server_url_(server_url),
    +
    100  crypto_period_count_(kDefaultCryptoPeriodCount),
    +
    101  protection_scheme_(protection_scheme),
    +
    102  start_key_production_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
    +
    103  base::WaitableEvent::InitialState::NOT_SIGNALED) {
    +
    104  key_production_thread_.Start();
    +
    105 }
    +
    106 
    +
    107 WidevineKeySource::~WidevineKeySource() {
    +
    108  if (key_pool_)
    +
    109  key_pool_->Stop();
    +
    110  if (key_production_thread_.HasBeenStarted()) {
    +
    111  // Signal the production thread to start key production if it is not
    +
    112  // signaled yet so the thread can be joined.
    +
    113  start_key_production_.Signal();
    +
    114  key_production_thread_.Join();
    +
    115  }
    +
    116 }
    +
    117 
    +
    118 Status WidevineKeySource::FetchKeys(const std::vector<uint8_t>& content_id,
    +
    119  const std::string& policy) {
    +
    120  base::AutoLock scoped_lock(lock_);
    +
    121  common_encryption_request_.reset(new CommonEncryptionRequest);
    +
    122  common_encryption_request_->set_content_id(content_id.data(),
    +
    123  content_id.size());
    +
    124  common_encryption_request_->set_policy(policy);
    +
    125  common_encryption_request_->set_protection_scheme(
    +
    126  ToCommonEncryptionProtectionScheme(protection_scheme_));
    +
    127  if (enable_entitlement_license_)
    +
    128  common_encryption_request_->set_enable_entitlement_license(true);
    +
    129 
    +
    130  return FetchKeysInternal(!kEnableKeyRotation, 0, false);
    +
    131 }
    +
    132 
    +
    133 Status WidevineKeySource::FetchKeys(EmeInitDataType init_data_type,
    +
    134  const std::vector<uint8_t>& init_data) {
    +
    135  std::vector<uint8_t> pssh_data;
    +
    136  uint32_t asset_id = 0;
    +
    137  switch (init_data_type) {
    +
    138  case EmeInitDataType::CENC: {
    +
    139  const std::vector<uint8_t> widevine_system_id(
    +
    140  kWidevineSystemId, kWidevineSystemId + arraysize(kWidevineSystemId));
    +
    141  std::vector<ProtectionSystemSpecificInfo> protection_systems_info;
    + +
    143  init_data.data(), init_data.size(), &protection_systems_info)) {
    +
    144  return Status(error::PARSER_FAILURE, "Error parsing the PSSH boxes.");
    +
    145  }
    +
    146  for (const auto& info : protection_systems_info) {
    +
    147  std::unique_ptr<PsshBoxBuilder> pssh_builder =
    +
    148  PsshBoxBuilder::ParseFromBox(info.psshs.data(), info.psshs.size());
    +
    149  if (!pssh_builder)
    +
    150  return Status(error::PARSER_FAILURE, "Error parsing the PSSH box.");
    +
    151  // Use Widevine PSSH if available otherwise construct a Widevine PSSH
    +
    152  // from the first available key ids.
    +
    153  if (info.system_id == widevine_system_id) {
    +
    154  pssh_data = pssh_builder->pssh_data();
    +
    155  break;
    +
    156  } else if (pssh_data.empty() && !pssh_builder->key_ids().empty()) {
    +
    157  pssh_data =
    +
    158  GenerateWidevinePsshDataFromKeyIds(pssh_builder->key_ids());
    +
    159  // Continue to see if there is any Widevine PSSH. The KeyId generated
    +
    160  // PSSH is only used if a Widevine PSSH could not be found.
    +
    161  continue;
    +
    162  }
    +
    163  }
    +
    164  if (pssh_data.empty())
    +
    165  return Status(error::INVALID_ARGUMENT, "No supported PSSHs found.");
    +
    166  break;
    +
    167  }
    +
    168  case EmeInitDataType::WEBM: {
    +
    169  pssh_data = GenerateWidevinePsshDataFromKeyIds({init_data});
    +
    170  break;
    +
    171  }
    +
    172  case EmeInitDataType::WIDEVINE_CLASSIC:
    +
    173  if (init_data.size() < sizeof(asset_id))
    +
    174  return Status(error::INVALID_ARGUMENT, "Invalid asset id.");
    +
    175  asset_id = ntohlFromBuffer(init_data.data());
    +
    176  break;
    +
    177  default:
    +
    178  LOG(ERROR) << "Init data type " << static_cast<int>(init_data_type)
    +
    179  << " not supported.";
    +
    180  return Status(error::INVALID_ARGUMENT, "Unsupported init data type.");
    +
    181  }
    +
    182  const bool widevine_classic =
    +
    183  init_data_type == EmeInitDataType::WIDEVINE_CLASSIC;
    +
    184  base::AutoLock scoped_lock(lock_);
    +
    185  common_encryption_request_.reset(new CommonEncryptionRequest);
    +
    186  if (widevine_classic) {
    +
    187  common_encryption_request_->set_asset_id(asset_id);
    +
    188  } else {
    +
    189  common_encryption_request_->set_pssh_data(pssh_data.data(),
    +
    190  pssh_data.size());
    +
    191  }
    +
    192  return FetchKeysInternal(!kEnableKeyRotation, 0, widevine_classic);
    +
    193 }
    +
    194 
    +
    195 Status WidevineKeySource::GetKey(const std::string& stream_label,
    +
    196  EncryptionKey* key) {
    +
    197  DCHECK(key);
    +
    198  if (encryption_key_map_.find(stream_label) == encryption_key_map_.end()) {
    +
    199  return Status(error::INTERNAL_ERROR,
    +
    200  "Cannot find key for '" + stream_label + "'.");
    +
    201  }
    +
    202  *key = *encryption_key_map_[stream_label];
    +
    203  return Status::OK;
    +
    204 }
    +
    205 
    +
    206 Status WidevineKeySource::GetKey(const std::vector<uint8_t>& key_id,
    +
    207  EncryptionKey* key) {
    +
    208  DCHECK(key);
    +
    209  for (const auto& pair : encryption_key_map_) {
    +
    210  if (pair.second->key_id == key_id) {
    +
    211  *key = *pair.second;
    +
    212  return Status::OK;
    +
    213  }
    +
    214  }
    +
    215  return Status(error::INTERNAL_ERROR,
    +
    216  "Cannot find key with specified key ID");
    +
    217 }
    +
    218 
    +
    219 Status WidevineKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
    +
    220  uint32_t crypto_period_duration_in_seconds,
    +
    221  const std::string& stream_label,
    +
    222  EncryptionKey* key) {
    +
    223  DCHECK(key_production_thread_.HasBeenStarted());
    +
    224  // TODO(kqyang): This is not elegant. Consider refactoring later.
    +
    225  {
    +
    226  base::AutoLock scoped_lock(lock_);
    +
    227  if (!key_production_started_) {
    +
    228  crypto_period_duration_in_seconds_ = crypto_period_duration_in_seconds;
    +
    229  // Another client may have a slightly smaller starting crypto period
    +
    230  // index. Set the initial value to account for that.
    +
    231  first_crypto_period_index_ =
    +
    232  crypto_period_index ? crypto_period_index - 1 : 0;
    +
    233  DCHECK(!key_pool_);
    +
    234  const size_t queue_size = crypto_period_count_ * 10;
    +
    235  key_pool_.reset(
    +
    236  new EncryptionKeyQueue(queue_size, first_crypto_period_index_));
    +
    237  start_key_production_.Signal();
    +
    238  key_production_started_ = true;
    +
    239  } else if (crypto_period_duration_in_seconds_ !=
    +
    240  crypto_period_duration_in_seconds) {
    +
    241  return Status(error::INVALID_ARGUMENT,
    +
    242  "Crypto period duration should not change.");
    +
    243  }
    +
    244  }
    +
    245  return GetKeyInternal(crypto_period_index, stream_label, key);
    +
    246 }
    +
    247 
    +
    248 void WidevineKeySource::set_signer(std::unique_ptr<RequestSigner> signer) {
    +
    249  signer_ = std::move(signer);
    +
    250 }
    +
    251 
    + +
    253  std::unique_ptr<KeyFetcher> key_fetcher) {
    +
    254  key_fetcher_ = std::move(key_fetcher);
    +
    255 }
    +
    256 
    +
    257 Status WidevineKeySource::GetKeyInternal(uint32_t crypto_period_index,
    +
    258  const std::string& stream_label,
    +
    259  EncryptionKey* key) {
    +
    260  DCHECK(key_pool_);
    +
    261  DCHECK(key);
    +
    262 
    +
    263  std::shared_ptr<EncryptionKeyMap> encryption_key_map;
    +
    264  Status status = key_pool_->Peek(crypto_period_index, &encryption_key_map,
    +
    265  kGetKeyTimeoutInSeconds * 1000);
    +
    266  if (!status.ok()) {
    +
    267  if (status.error_code() == error::STOPPED) {
    +
    268  CHECK(!common_encryption_request_status_.ok());
    +
    269  return common_encryption_request_status_;
    +
    270  }
    +
    271  return status;
    +
    272  }
    +
    273 
    +
    274  if (encryption_key_map->find(stream_label) == encryption_key_map->end()) {
    +
    275  return Status(error::INTERNAL_ERROR,
    +
    276  "Cannot find key for '" + stream_label + "'.");
    +
    277  }
    +
    278  *key = *encryption_key_map->at(stream_label);
    +
    279  return Status::OK;
    +
    280 }
    +
    281 
    +
    282 void WidevineKeySource::FetchKeysTask() {
    +
    283  // Wait until key production is signaled.
    +
    284  start_key_production_.Wait();
    +
    285  if (!key_pool_ || key_pool_->Stopped())
    +
    286  return;
    +
    287 
    +
    288  Status status = FetchKeysInternal(kEnableKeyRotation,
    +
    289  first_crypto_period_index_,
    +
    290  false);
    +
    291  while (status.ok()) {
    +
    292  first_crypto_period_index_ += crypto_period_count_;
    +
    293  status = FetchKeysInternal(kEnableKeyRotation,
    +
    294  first_crypto_period_index_,
    +
    295  false);
    +
    296  }
    +
    297  common_encryption_request_status_ = status;
    +
    298  key_pool_->Stop();
    +
    299 }
    +
    300 
    +
    301 Status WidevineKeySource::FetchKeysInternal(bool enable_key_rotation,
    +
    302  uint32_t first_crypto_period_index,
    +
    303  bool widevine_classic) {
    +
    304  CommonEncryptionRequest request;
    +
    305  FillRequest(enable_key_rotation, first_crypto_period_index, &request);
    +
    306 
    +
    307  std::string message;
    +
    308  Status status = GenerateKeyMessage(request, &message);
    +
    309  if (!status.ok())
    +
    310  return status;
    +
    311  VLOG(1) << "Message: " << message;
    +
    312 
    +
    313  std::string raw_response;
    +
    314  int64_t sleep_duration = kFirstRetryDelayMilliseconds;
    +
    315 
    +
    316  // Perform client side retries if seeing server transient error to workaround
    +
    317  // server limitation.
    +
    318  for (int i = 0; i < kNumTransientErrorRetries; ++i) {
    +
    319  status = key_fetcher_->FetchKeys(server_url_, message, &raw_response);
    +
    320  if (status.ok()) {
    +
    321  VLOG(1) << "Retry [" << i << "] Response:" << raw_response;
    +
    322 
    +
    323  bool transient_error = false;
    +
    324  if (ExtractEncryptionKey(enable_key_rotation, widevine_classic,
    +
    325  raw_response, &transient_error))
    +
    326  return Status::OK;
    +
    327 
    +
    328  if (!transient_error) {
    +
    329  return Status(
    +
    330  error::SERVER_ERROR,
    +
    331  "Failed to extract encryption key from '" + raw_response + "'.");
    +
    332  }
    +
    333  } else if (status.error_code() != error::TIME_OUT) {
    +
    334  return status;
    +
    335  }
    +
    336 
    +
    337  // Exponential backoff.
    +
    338  if (i != kNumTransientErrorRetries - 1) {
    +
    339  base::PlatformThread::Sleep(
    +
    340  base::TimeDelta::FromMilliseconds(sleep_duration));
    +
    341  sleep_duration *= 2;
    +
    342  }
    +
    343  }
    +
    344  return Status(error::SERVER_ERROR,
    +
    345  "Failed to recover from server internal error.");
    +
    346 }
    +
    347 
    +
    348 void WidevineKeySource::FillRequest(bool enable_key_rotation,
    +
    349  uint32_t first_crypto_period_index,
    +
    350  CommonEncryptionRequest* request) {
    +
    351  DCHECK(common_encryption_request_);
    +
    352  DCHECK(request);
    +
    353  *request = *common_encryption_request_;
    +
    354 
    +
    355  request->add_tracks()->set_type("SD");
    +
    356  request->add_tracks()->set_type("HD");
    +
    357  request->add_tracks()->set_type("UHD1");
    +
    358  request->add_tracks()->set_type("UHD2");
    +
    359  request->add_tracks()->set_type("AUDIO");
    +
    360 
    +
    361  request->add_drm_types(ModularDrmType::WIDEVINE);
    +
    362 
    +
    363  if (enable_key_rotation) {
    +
    364  request->set_first_crypto_period_index(first_crypto_period_index);
    +
    365  request->set_crypto_period_count(crypto_period_count_);
    +
    366  request->set_crypto_period_seconds(crypto_period_duration_in_seconds_);
    +
    367  }
    +
    368 
    +
    369  if (!group_id_.empty())
    +
    370  request->set_group_id(group_id_.data(), group_id_.size());
    +
    371 
    +
    372  if (!FLAGS_video_feature.empty())
    +
    373  request->set_video_feature(FLAGS_video_feature);
    +
    374 }
    +
    375 
    +
    376 Status WidevineKeySource::GenerateKeyMessage(
    +
    377  const CommonEncryptionRequest& request,
    +
    378  std::string* message) {
    +
    379  DCHECK(message);
    +
    380 
    +
    381  SignedModularDrmRequest signed_request;
    +
    382  signed_request.set_request(MessageToJsonString(request));
    +
    383 
    +
    384  // Sign the request.
    +
    385  if (signer_) {
    +
    386  std::string signature;
    +
    387  if (!signer_->GenerateSignature(signed_request.request(), &signature))
    +
    388  return Status(error::INTERNAL_ERROR, "Signature generation failed.");
    +
    389 
    +
    390  signed_request.set_signature(signature);
    +
    391  signed_request.set_signer(signer_->signer_name());
    +
    392  }
    +
    393 
    +
    394  *message = MessageToJsonString(signed_request);
    +
    395  return Status::OK;
    +
    396 }
    +
    397 
    +
    398 bool WidevineKeySource::ExtractEncryptionKey(
    +
    399  bool enable_key_rotation,
    +
    400  bool widevine_classic,
    +
    401  const std::string& response,
    +
    402  bool* transient_error) {
    +
    403  DCHECK(transient_error);
    +
    404  *transient_error = false;
    +
    405 
    +
    406  SignedModularDrmResponse signed_response_proto;
    +
    407  if (!JsonStringToMessage(response, &signed_response_proto)) {
    +
    408  LOG(ERROR) << "Failed to convert JSON to proto: " << response;
    +
    409  return false;
    +
    410  }
    +
    411 
    +
    412  CommonEncryptionResponse response_proto;
    +
    413  if (!JsonStringToMessage(signed_response_proto.response(), &response_proto)) {
    +
    414  LOG(ERROR) << "Failed to convert JSON to proto: "
    +
    415  << signed_response_proto.response();
    +
    416  return false;
    +
    417  }
    +
    418 
    +
    419  if (response_proto.status() != CommonEncryptionResponse::OK) {
    +
    420  LOG(ERROR) << "Received non-OK license response: " << response;
    +
    421  // Server may return INTERNAL_ERROR intermittently, which is a transient
    +
    422  // error and the next client request may succeed without problem.
    +
    423  *transient_error =
    +
    424  (response_proto.status() == CommonEncryptionResponse::INTERNAL_ERROR);
    +
    425  return false;
    +
    426  }
    +
    427 
    +
    428  RCHECK(enable_key_rotation
    +
    429  ? response_proto.tracks_size() >= crypto_period_count_
    +
    430  : response_proto.tracks_size() >= 1);
    +
    431 
    +
    432  uint32_t current_crypto_period_index = first_crypto_period_index_;
    +
    433 
    +
    434  std::vector<std::vector<uint8_t>> key_ids;
    +
    435  for (const auto& track : response_proto.tracks()) {
    +
    436  if (!widevine_classic)
    +
    437  key_ids.emplace_back(track.key_id().begin(), track.key_id().end());
    +
    438  }
    +
    439 
    +
    440  EncryptionKeyMap encryption_key_map;
    +
    441  for (const auto& track : response_proto.tracks()) {
    +
    442  VLOG(2) << "track " << track.ShortDebugString();
    +
    443 
    +
    444  if (enable_key_rotation) {
    +
    445  if (track.crypto_period_index() != current_crypto_period_index) {
    +
    446  if (track.crypto_period_index() != current_crypto_period_index + 1) {
    +
    447  LOG(ERROR) << "Expecting crypto period index "
    +
    448  << current_crypto_period_index << " or "
    +
    449  << current_crypto_period_index + 1 << "; Seen "
    +
    450  << track.crypto_period_index();
    +
    451  return false;
    +
    452  }
    +
    453  if (!PushToKeyPool(&encryption_key_map))
    +
    454  return false;
    +
    455  ++current_crypto_period_index;
    +
    456  }
    +
    457  }
    +
    458 
    +
    459  const std::string& stream_label = track.type();
    +
    460  RCHECK(encryption_key_map.find(stream_label) == encryption_key_map.end());
    +
    461 
    +
    462  std::unique_ptr<EncryptionKey> encryption_key(new EncryptionKey());
    +
    463  encryption_key->key.assign(track.key().begin(), track.key().end());
    +
    464 
    +
    465  // Get key ID and PSSH data for CENC content only.
    +
    466  if (!widevine_classic) {
    +
    467  encryption_key->key_id.assign(track.key_id().begin(),
    +
    468  track.key_id().end());
    +
    469  encryption_key->iv.assign(track.iv().begin(), track.iv().end());
    +
    470  encryption_key->key_ids = key_ids;
    +
    471 
    +
    472  if (generate_widevine_protection_system_) {
    +
    473  if (track.pssh_size() != 1) {
    +
    474  LOG(ERROR) << "Expecting one and only one pssh, seeing "
    +
    475  << track.pssh_size();
    +
    476  return false;
    +
    477  }
    +
    478  encryption_key->key_system_info.push_back(
    +
    479  ProtectionSystemInfoFromPsshProto(track.pssh(0)));
    +
    480  }
    +
    481  }
    +
    482  encryption_key_map[stream_label] = std::move(encryption_key);
    +
    483  }
    +
    484 
    +
    485  DCHECK(!encryption_key_map.empty());
    +
    486  if (!enable_key_rotation) {
    +
    487  // Merge with previously requested keys.
    +
    488  for (auto& pair : encryption_key_map)
    +
    489  encryption_key_map_[pair.first] = std::move(pair.second);
    +
    490  return true;
    +
    491  }
    +
    492 
    +
    493  return PushToKeyPool(&encryption_key_map);
    +
    494 }
    +
    495 
    +
    496 bool WidevineKeySource::PushToKeyPool(
    +
    497  EncryptionKeyMap* encryption_key_map) {
    +
    498  DCHECK(key_pool_);
    +
    499  DCHECK(encryption_key_map);
    +
    500  auto encryption_key_map_shared = std::make_shared<EncryptionKeyMap>();
    +
    501  encryption_key_map_shared->swap(*encryption_key_map);
    +
    502  Status status = key_pool_->Push(encryption_key_map_shared, kInfiniteTimeout);
    +
    503  if (!status.ok()) {
    +
    504  DCHECK_EQ(error::STOPPED, status.error_code());
    +
    505  return false;
    +
    506  }
    +
    507  return true;
    +
    508 }
    +
    509 
    +
    510 } // namespace media
    +
    511 } // namespace shaka
    + + + +
    static std::unique_ptr< PsshBoxBuilder > ParseFromBox(const uint8_t *data, size_t data_size)
    + +
    void set_signer(std::unique_ptr< RequestSigner > signer)
    +
    void set_key_fetcher(std::unique_ptr< KeyFetcher > key_fetcher)
    +
    WidevineKeySource(const std::string &server_url, ProtectionSystem protection_systems, FourCC protection_scheme)
    +
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    +
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    +
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    +
    All the methods that are virtual are virtual for mocking.
    +
    ProtectionSystem
    Definition: crypto_params.h:31
    + +
    static bool ParseBoxes(const uint8_t *data, size_t data_size, std::vector< ProtectionSystemSpecificInfo > *pssh_boxes)
    diff --git a/docs/d5/d8c/structshaka_1_1media_1_1mp4_1_1CompositionOffset.html b/docs/d5/d8c/structshaka_1_1media_1_1mp4_1_1CompositionOffset.html index 71f322648e..f3f4b5ad35 100644 --- a/docs/d5/d8c/structshaka_1_1media_1_1mp4_1_1CompositionOffset.html +++ b/docs/d5/d8c/structshaka_1_1media_1_1mp4_1_1CompositionOffset.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CompositionOffset Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    sample_offset<

    Detailed Description

    -

    Definition at line 432 of file box_definitions.h.

    +

    Definition at line 445 of file box_definitions.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/d5/d8d/classshaka_1_1media_1_1SampleAesEc3Cryptor-members.html b/docs/d5/d8d/classshaka_1_1media_1_1SampleAesEc3Cryptor-members.html index 0a62d29e50..89fd8bbdfe 100644 --- a/docs/d5/d8d/classshaka_1_1media_1_1SampleAesEc3Cryptor-members.html +++ b/docs/d5/d8d/classshaka_1_1media_1_1SampleAesEc3Cryptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d5/d8f/webm__cluster__parser_8cc_source.html b/docs/d5/d8f/webm__cluster__parser_8cc_source.html index 5a886c6cb7..b4717c6a4c 100644 --- a/docs/d5/d8f/webm__cluster__parser_8cc_source.html +++ b/docs/d5/d8f/webm__cluster__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_cluster_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webm_cluster_parser.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/webm/webm_cluster_parser.h"
    6 
    7 #include <algorithm>
    8 #include <vector>
    9 
    10 #include "packager/base/logging.h"
    11 #include "packager/base/sys_byteorder.h"
    12 #include "packager/media/base/decrypt_config.h"
    13 #include "packager/media/base/timestamp.h"
    14 #include "packager/media/codecs/vp8_parser.h"
    15 #include "packager/media/codecs/vp9_parser.h"
    16 #include "packager/media/codecs/webvtt_util.h"
    17 #include "packager/media/formats/webm/webm_constants.h"
    18 #include "packager/media/formats/webm/webm_crypto_helpers.h"
    19 #include "packager/media/formats/webm/webm_webvtt_parser.h"
    20 
    21 namespace shaka {
    22 namespace media {
    23 namespace {
    24 
    25 const int64_t kMicrosecondsPerMillisecond = 1000;
    26 
    27 } // namespace
    28 
    30  int64_t timecode_scale,
    31  std::shared_ptr<AudioStreamInfo> audio_stream_info,
    32  std::shared_ptr<VideoStreamInfo> video_stream_info,
    33  const VPCodecConfigurationRecord& vp_config,
    34  int64_t audio_default_duration,
    35  int64_t video_default_duration,
    36  const WebMTracksParser::TextTracks& text_tracks,
    37  const std::set<int64_t>& ignored_tracks,
    38  const std::string& audio_encryption_key_id,
    39  const std::string& video_encryption_key_id,
    40  const MediaParser::NewSampleCB& new_sample_cb,
    41  const MediaParser::InitCB& init_cb,
    42  KeySource* decryption_key_source)
    43  : timecode_multiplier_(timecode_scale /
    44  static_cast<double>(kMicrosecondsPerMillisecond)),
    45  audio_stream_info_(audio_stream_info),
    46  video_stream_info_(video_stream_info),
    47  vp_config_(vp_config),
    48  ignored_tracks_(ignored_tracks),
    49  audio_encryption_key_id_(audio_encryption_key_id),
    50  video_encryption_key_id_(video_encryption_key_id),
    51  parser_(kWebMIdCluster, this),
    52  initialized_(false),
    53  init_cb_(init_cb),
    54  cluster_start_time_(kNoTimestamp),
    55  audio_(audio_stream_info ? audio_stream_info->track_id() : -1,
    56  false,
    57  audio_default_duration,
    58  new_sample_cb),
    59  video_(video_stream_info ? video_stream_info->track_id() : -1,
    60  true,
    61  video_default_duration,
    62  new_sample_cb) {
    63  if (decryption_key_source) {
    64  decryptor_source_.reset(new DecryptorSource(decryption_key_source));
    65  if (audio_stream_info_)
    66  audio_stream_info_->set_is_encrypted(false);
    67  if (video_stream_info_)
    68  video_stream_info_->set_is_encrypted(false);
    69  }
    70  for (WebMTracksParser::TextTracks::const_iterator it = text_tracks.begin();
    71  it != text_tracks.end();
    72  ++it) {
    73  text_track_map_.insert(std::make_pair(
    74  it->first, Track(it->first, false, kNoTimestamp, new_sample_cb)));
    75  }
    76 }
    77 
    78 WebMClusterParser::~WebMClusterParser() {}
    79 
    81  last_block_timecode_ = -1;
    82  cluster_timecode_ = -1;
    83  cluster_start_time_ = kNoTimestamp;
    84  cluster_ended_ = false;
    85  parser_.Reset();
    86  audio_.Reset();
    87  video_.Reset();
    88  ResetTextTracks();
    89 }
    90 
    92  // Estimate the duration of the last frame if necessary.
    93  bool audio_result = audio_.ApplyDurationEstimateIfNeeded();
    94  bool video_result = video_.ApplyDurationEstimateIfNeeded();
    95  Reset();
    96  return audio_result && video_result;
    97 }
    98 
    99 int WebMClusterParser::Parse(const uint8_t* buf, int size) {
    100  int result = parser_.Parse(buf, size);
    101 
    102  if (result < 0) {
    103  cluster_ended_ = false;
    104  return result;
    105  }
    106 
    107  cluster_ended_ = parser_.IsParsingComplete();
    108  if (cluster_ended_) {
    109  // If there were no buffers in this cluster, set the cluster start time to
    110  // be the |cluster_timecode_|.
    111  if (cluster_start_time_ == kNoTimestamp) {
    112  // If the cluster did not even have a |cluster_timecode_|, signal parse
    113  // error.
    114  if (cluster_timecode_ < 0)
    115  return -1;
    116 
    117  cluster_start_time_ = cluster_timecode_ * timecode_multiplier_;
    118  }
    119 
    120  // Reset the parser if we're done parsing so that
    121  // it is ready to accept another cluster on the next
    122  // call.
    123  parser_.Reset();
    124 
    125  last_block_timecode_ = -1;
    126  cluster_timecode_ = -1;
    127  }
    128 
    129  return result;
    130 }
    131 
    132 WebMParserClient* WebMClusterParser::OnListStart(int id) {
    133  if (id == kWebMIdCluster) {
    134  cluster_timecode_ = -1;
    135  cluster_start_time_ = kNoTimestamp;
    136  } else if (id == kWebMIdBlockGroup) {
    137  block_data_.reset();
    138  block_data_size_ = -1;
    139  block_duration_ = -1;
    140  discard_padding_ = -1;
    141  discard_padding_set_ = false;
    142  reference_block_set_ = false;
    143  } else if (id == kWebMIdBlockAdditions) {
    144  block_add_id_ = -1;
    145  block_additional_data_.reset();
    146  block_additional_data_size_ = 0;
    147  }
    148 
    149  return this;
    150 }
    151 
    152 bool WebMClusterParser::OnListEnd(int id) {
    153  if (id != kWebMIdBlockGroup)
    154  return true;
    155 
    156  // Make sure the BlockGroup actually had a Block.
    157  if (block_data_size_ == -1) {
    158  LOG(ERROR) << "Block missing from BlockGroup.";
    159  return false;
    160  }
    161 
    162  bool result = ParseBlock(
    163  false, block_data_.get(), block_data_size_, block_additional_data_.get(),
    164  block_additional_data_size_, block_duration_,
    165  discard_padding_set_ ? discard_padding_ : 0, reference_block_set_);
    166  block_data_.reset();
    167  block_data_size_ = -1;
    168  block_duration_ = -1;
    169  block_add_id_ = -1;
    170  block_additional_data_.reset();
    171  block_additional_data_size_ = 0;
    172  discard_padding_ = -1;
    173  discard_padding_set_ = false;
    174  reference_block_set_ = false;
    175  return result;
    176 }
    177 
    178 bool WebMClusterParser::OnUInt(int id, int64_t val) {
    179  int64_t* dst;
    180  switch (id) {
    181  case kWebMIdTimecode:
    182  dst = &cluster_timecode_;
    183  break;
    184  case kWebMIdBlockDuration:
    185  dst = &block_duration_;
    186  break;
    187  case kWebMIdBlockAddID:
    188  dst = &block_add_id_;
    189  break;
    190  default:
    191  return true;
    192  }
    193  if (*dst != -1)
    194  return false;
    195  *dst = val;
    196  return true;
    197 }
    198 
    199 bool WebMClusterParser::ParseBlock(bool is_simple_block,
    200  const uint8_t* buf,
    201  int size,
    202  const uint8_t* additional,
    203  int additional_size,
    204  int duration,
    205  int64_t discard_padding,
    206  bool reference_block_set) {
    207  if (size < 4)
    208  return false;
    209 
    210  // Return an error if the trackNum > 127. We just aren't
    211  // going to support large track numbers right now.
    212  if (!(buf[0] & 0x80)) {
    213  LOG(ERROR) << "TrackNumber over 127 not supported";
    214  return false;
    215  }
    216 
    217  int track_num = buf[0] & 0x7f;
    218  int timecode = buf[1] << 8 | buf[2];
    219  int flags = buf[3] & 0xff;
    220  int lacing = (flags >> 1) & 0x3;
    221 
    222  if (lacing) {
    223  LOG(ERROR) << "Lacing " << lacing << " is not supported yet.";
    224  return false;
    225  }
    226 
    227  // Sign extend negative timecode offsets.
    228  if (timecode & 0x8000)
    229  timecode |= ~0xffff;
    230 
    231  // The first bit of the flags is set when a SimpleBlock contains only
    232  // keyframes. If this is a Block, then keyframe is inferred by the absence of
    233  // the ReferenceBlock Element.
    234  // http://www.matroska.org/technical/specs/index.html
    235  bool is_key_frame =
    236  is_simple_block ? (flags & 0x80) != 0 : !reference_block_set;
    237 
    238  const uint8_t* frame_data = buf + 4;
    239  int frame_size = size - (frame_data - buf);
    240  return OnBlock(is_simple_block, track_num, timecode, duration, frame_data,
    241  frame_size, additional, additional_size, discard_padding,
    242  is_key_frame);
    243 }
    244 
    245 bool WebMClusterParser::OnBinary(int id, const uint8_t* data, int size) {
    246  switch (id) {
    247  case kWebMIdSimpleBlock:
    248  return ParseBlock(true, data, size, NULL, 0, -1, 0, false);
    249 
    250  case kWebMIdBlock:
    251  if (block_data_) {
    252  LOG(ERROR) << "More than 1 Block in a BlockGroup is not "
    253  "supported.";
    254  return false;
    255  }
    256  block_data_.reset(new uint8_t[size]);
    257  memcpy(block_data_.get(), data, size);
    258  block_data_size_ = size;
    259  return true;
    260 
    261  case kWebMIdBlockAdditional: {
    262  uint64_t block_add_id = base::HostToNet64(block_add_id_);
    263  if (block_additional_data_) {
    264  // TODO: Technically, more than 1 BlockAdditional is allowed as per
    265  // matroska spec. But for now we don't have a use case to support
    266  // parsing of such files. Take a look at this again when such a case
    267  // arises.
    268  LOG(ERROR) << "More than 1 BlockAdditional in a "
    269  "BlockGroup is not supported.";
    270  return false;
    271  }
    272  // First 8 bytes of side_data in DecoderBuffer is the BlockAddID
    273  // element's value in Big Endian format. This is done to mimic ffmpeg
    274  // demuxer's behavior.
    275  block_additional_data_size_ = size + sizeof(block_add_id);
    276  block_additional_data_.reset(new uint8_t[block_additional_data_size_]);
    277  memcpy(block_additional_data_.get(), &block_add_id,
    278  sizeof(block_add_id));
    279  memcpy(block_additional_data_.get() + 8, data, size);
    280  return true;
    281  }
    282  case kWebMIdDiscardPadding: {
    283  if (discard_padding_set_ || size <= 0 || size > 8)
    284  return false;
    285  discard_padding_set_ = true;
    286 
    287  // Read in the big-endian integer.
    288  discard_padding_ = static_cast<int8_t>(data[0]);
    289  for (int i = 1; i < size; ++i)
    290  discard_padding_ = (discard_padding_ << 8) | data[i];
    291 
    292  return true;
    293  }
    294  case kWebMIdReferenceBlock:
    295  // We use ReferenceBlock to determine whether the current Block contains a
    296  // keyframe or not. Other than that, we don't care about the value of the
    297  // ReferenceBlock element itself.
    298  reference_block_set_ = true;
    299  return true;
    300  default:
    301  return true;
    302  }
    303 }
    304 
    305 bool WebMClusterParser::OnBlock(bool is_simple_block,
    306  int track_num,
    307  int timecode,
    308  int block_duration,
    309  const uint8_t* data,
    310  int size,
    311  const uint8_t* additional,
    312  int additional_size,
    313  int64_t discard_padding,
    314  bool is_key_frame) {
    315  DCHECK_GE(size, 0);
    316  if (cluster_timecode_ == -1) {
    317  LOG(ERROR) << "Got a block before cluster timecode.";
    318  return false;
    319  }
    320 
    321  // TODO: Should relative negative timecode offsets be rejected? Or only when
    322  // the absolute timecode is negative? See http://crbug.com/271794
    323  if (timecode < 0) {
    324  LOG(ERROR) << "Got a block with negative timecode offset " << timecode;
    325  return false;
    326  }
    327 
    328  if (last_block_timecode_ != -1 && timecode < last_block_timecode_) {
    329  LOG(ERROR) << "Got a block with a timecode before the previous block.";
    330  return false;
    331  }
    332 
    333  Track* track = NULL;
    334  StreamType stream_type = kStreamUnknown;
    335  std::string encryption_key_id;
    336  if (track_num == audio_.track_num()) {
    337  track = &audio_;
    338  encryption_key_id = audio_encryption_key_id_;
    339  stream_type = kStreamAudio;
    340  } else if (track_num == video_.track_num()) {
    341  track = &video_;
    342  encryption_key_id = video_encryption_key_id_;
    343  stream_type = kStreamVideo;
    344  } else if (ignored_tracks_.find(track_num) != ignored_tracks_.end()) {
    345  return true;
    346  } else if (Track* const text_track = FindTextTrack(track_num)) {
    347  if (is_simple_block) // BlockGroup is required for WebVTT cues
    348  return false;
    349  if (block_duration < 0) // not specified
    350  return false;
    351  track = text_track;
    352  stream_type = kStreamText;
    353  } else {
    354  LOG(ERROR) << "Unexpected track number " << track_num;
    355  return false;
    356  }
    357  DCHECK_NE(stream_type, kStreamUnknown);
    358 
    359  last_block_timecode_ = timecode;
    360 
    361  int64_t timestamp = (cluster_timecode_ + timecode) * timecode_multiplier_;
    362 
    363  std::shared_ptr<MediaSample> buffer;
    364  if (stream_type != kStreamText) {
    365  // Every encrypted Block has a signal byte and IV prepended to it. Current
    366  // encrypted WebM request for comments specification is here
    367  // http://wiki.webmproject.org/encryption/webm-encryption-rfc
    368  std::unique_ptr<DecryptConfig> decrypt_config;
    369  int data_offset = 0;
    370  if (!encryption_key_id.empty() &&
    371  !WebMCreateDecryptConfig(
    372  data, size,
    373  reinterpret_cast<const uint8_t*>(encryption_key_id.data()),
    374  encryption_key_id.size(),
    375  &decrypt_config, &data_offset)) {
    376  return false;
    377  }
    378 
    379  const uint8_t* media_data = data + data_offset;
    380  const size_t media_data_size = size - data_offset;
    381  // Use a dummy data size of 0 to avoid copying overhead.
    382  // Actual media data is set later.
    383  const size_t kDummyDataSize = 0;
    384  buffer = MediaSample::CopyFrom(media_data, kDummyDataSize, additional,
    385  additional_size, is_key_frame);
    386 
    387  if (decrypt_config) {
    388  if (!decryptor_source_) {
    389  buffer->SetData(media_data, media_data_size);
    390  // If the demuxer does not have the decryptor_source_, store
    391  // decrypt_config so that the demuxed sample can be decrypted later.
    392  buffer->set_decrypt_config(std::move(decrypt_config));
    393  buffer->set_is_encrypted(true);
    394  } else {
    395  std::shared_ptr<uint8_t> decrypted_media_data(
    396  new uint8_t[media_data_size], std::default_delete<uint8_t[]>());
    397  if (!decryptor_source_->DecryptSampleBuffer(
    398  decrypt_config.get(), media_data, media_data_size,
    399  decrypted_media_data.get())) {
    400  LOG(ERROR) << "Cannot decrypt samples";
    401  return false;
    402  }
    403  buffer->TransferData(std::move(decrypted_media_data), media_data_size);
    404  }
    405  } else {
    406  buffer->SetData(media_data, media_data_size);
    407  }
    408  } else {
    409  std::string id, settings, content;
    410  WebMWebVTTParser::Parse(data, size, &id, &settings, &content);
    411 
    412  std::vector<uint8_t> side_data;
    413  MakeSideData(id.begin(), id.end(),
    414  settings.begin(), settings.end(),
    415  &side_data);
    416 
    417  buffer = MediaSample::CopyFrom(
    418  reinterpret_cast<const uint8_t*>(content.data()), content.length(),
    419  &side_data[0], side_data.size(), true);
    420  }
    421 
    422  buffer->set_dts(timestamp);
    423  buffer->set_pts(timestamp);
    424  if (cluster_start_time_ == kNoTimestamp)
    425  cluster_start_time_ = timestamp;
    426  buffer->set_duration(block_duration > 0
    427  ? (block_duration * timecode_multiplier_)
    428  : kNoTimestamp);
    429 
    430  if (!init_cb_.is_null() && !initialized_) {
    431  std::vector<std::shared_ptr<StreamInfo>> streams;
    432  if (audio_stream_info_)
    433  streams.push_back(audio_stream_info_);
    434  if (video_stream_info_) {
    435  if (stream_type == kStreamVideo) {
    436  // Setup codec string and codec config for VP8 and VP9.
    437  // Codec config for AV1 is already retrieved from WebM CodecPrivate
    438  // instead of extracted from the bit stream.
    439  if (video_stream_info_->codec() != kCodecAV1) {
    440  std::unique_ptr<VPxParser> vpx_parser;
    441  switch (video_stream_info_->codec()) {
    442  case kCodecVP8:
    443  vpx_parser.reset(new VP8Parser);
    444  break;
    445  case kCodecVP9:
    446  vpx_parser.reset(new VP9Parser);
    447  break;
    448  default:
    449  NOTIMPLEMENTED()
    450  << "Unsupported codec " << video_stream_info_->codec();
    451  return false;
    452  }
    453  std::vector<VPxFrameInfo> vpx_frames;
    454  if (!vpx_parser->Parse(buffer->data(), buffer->data_size(),
    455  &vpx_frames)) {
    456  LOG(ERROR) << "Failed to parse vpx frame.";
    457  return false;
    458  }
    459  if (vpx_frames.size() != 1u || !vpx_frames[0].is_keyframe) {
    460  LOG(ERROR) << "The first frame should be a key frame.";
    461  return false;
    462  }
    463 
    464  vp_config_.MergeFrom(vpx_parser->codec_config());
    465  video_stream_info_->set_codec_string(
    466  vp_config_.GetCodecString(video_stream_info_->codec()));
    467  std::vector<uint8_t> config_serialized;
    468  vp_config_.WriteMP4(&config_serialized);
    469  video_stream_info_->set_codec_config(config_serialized);
    470  }
    471 
    472  streams.push_back(video_stream_info_);
    473  init_cb_.Run(streams);
    474  initialized_ = true;
    475  }
    476  } else {
    477  init_cb_.Run(streams);
    478  initialized_ = true;
    479  }
    480  }
    481 
    482  return track->EmitBuffer(buffer);
    483 }
    484 
    485 WebMClusterParser::Track::Track(int track_num,
    486  bool is_video,
    487  int64_t default_duration,
    488  const MediaParser::NewSampleCB& new_sample_cb)
    489  : track_num_(track_num),
    490  is_video_(is_video),
    491  default_duration_(default_duration),
    492  estimated_next_frame_duration_(kNoTimestamp),
    493  new_sample_cb_(new_sample_cb) {
    494  DCHECK(default_duration_ == kNoTimestamp || default_duration_ > 0);
    495 }
    496 
    497 WebMClusterParser::Track::~Track() {}
    498 
    499 bool WebMClusterParser::Track::EmitBuffer(
    500  const std::shared_ptr<MediaSample>& buffer) {
    501  DVLOG(2) << "EmitBuffer() : " << track_num_
    502  << " ts " << buffer->pts()
    503  << " dur " << buffer->duration()
    504  << " kf " << buffer->is_key_frame()
    505  << " size " << buffer->data_size();
    506 
    507  if (last_added_buffer_missing_duration_.get()) {
    508  int64_t derived_duration =
    509  buffer->pts() - last_added_buffer_missing_duration_->pts();
    510  last_added_buffer_missing_duration_->set_duration(derived_duration);
    511 
    512  DVLOG(2) << "EmitBuffer() : applied derived duration to held-back buffer : "
    513  << " ts "
    514  << last_added_buffer_missing_duration_->pts()
    515  << " dur "
    516  << last_added_buffer_missing_duration_->duration()
    517  << " kf " << last_added_buffer_missing_duration_->is_key_frame()
    518  << " size " << last_added_buffer_missing_duration_->data_size();
    519  std::shared_ptr<MediaSample> updated_buffer =
    520  last_added_buffer_missing_duration_;
    521  last_added_buffer_missing_duration_ = NULL;
    522  if (!EmitBufferHelp(updated_buffer))
    523  return false;
    524  }
    525 
    526  if (buffer->duration() == kNoTimestamp) {
    527  last_added_buffer_missing_duration_ = buffer;
    528  DVLOG(2) << "EmitBuffer() : holding back buffer that is missing duration";
    529  return true;
    530  }
    531 
    532  return EmitBufferHelp(buffer);
    533 }
    534 
    535 bool WebMClusterParser::Track::ApplyDurationEstimateIfNeeded() {
    536  if (!last_added_buffer_missing_duration_.get())
    537  return true;
    538 
    539  int64_t estimated_duration = GetDurationEstimate();
    540  last_added_buffer_missing_duration_->set_duration(estimated_duration);
    541 
    542  VLOG(1) << "Track " << track_num_ << ": Estimating WebM block duration to be "
    543  << estimated_duration / 1000
    544  << "ms for the last (Simple)Block in the Cluster for this Track. Use "
    545  "BlockGroups with BlockDurations at the end of each Track in a "
    546  "Cluster to avoid estimation.";
    547 
    548  DVLOG(2) << " new dur : ts " << last_added_buffer_missing_duration_->pts()
    549  << " dur " << last_added_buffer_missing_duration_->duration()
    550  << " kf " << last_added_buffer_missing_duration_->is_key_frame()
    551  << " size " << last_added_buffer_missing_duration_->data_size();
    552 
    553  // Don't use the applied duration as a future estimation (don't use
    554  // EmitBufferHelp() here.)
    555  if (!new_sample_cb_.Run(track_num_, last_added_buffer_missing_duration_))
    556  return false;
    557  last_added_buffer_missing_duration_ = NULL;
    558  return true;
    559 }
    560 
    561 void WebMClusterParser::Track::Reset() {
    562  last_added_buffer_missing_duration_ = NULL;
    563 }
    564 
    565 bool WebMClusterParser::Track::EmitBufferHelp(
    566  const std::shared_ptr<MediaSample>& buffer) {
    567  DCHECK(!last_added_buffer_missing_duration_.get());
    568 
    569  int64_t duration = buffer->duration();
    570  if (duration < 0 || duration == kNoTimestamp) {
    571  LOG(ERROR) << "Invalid buffer duration: " << duration;
    572  return false;
    573  }
    574 
    575  // The estimated frame duration is the maximum non-zero duration since the
    576  // last initialization segment.
    577  if (duration > 0) {
    578  int64_t orig_duration_estimate = estimated_next_frame_duration_;
    579  if (estimated_next_frame_duration_ == kNoTimestamp) {
    580  estimated_next_frame_duration_ = duration;
    581  } else {
    582  estimated_next_frame_duration_ =
    583  std::max(duration, estimated_next_frame_duration_);
    584  }
    585 
    586  if (orig_duration_estimate != estimated_next_frame_duration_) {
    587  DVLOG(3) << "Updated duration estimate:"
    588  << orig_duration_estimate
    589  << " -> "
    590  << estimated_next_frame_duration_
    591  << " at timestamp: "
    592  << buffer->dts();
    593  }
    594  }
    595 
    596  return new_sample_cb_.Run(track_num_, buffer);
    597 }
    598 
    599 int64_t WebMClusterParser::Track::GetDurationEstimate() {
    600  int64_t duration = kNoTimestamp;
    601  if (default_duration_ != kNoTimestamp) {
    602  duration = default_duration_;
    603  DVLOG(3) << __FUNCTION__ << " : using track default duration " << duration;
    604  } else if (estimated_next_frame_duration_ != kNoTimestamp) {
    605  duration = estimated_next_frame_duration_;
    606  DVLOG(3) << __FUNCTION__ << " : using estimated duration " << duration;
    607  } else {
    608  if (is_video_) {
    609  duration = kDefaultVideoBufferDurationInMs * kMicrosecondsPerMillisecond;
    610  } else {
    611  duration = kDefaultAudioBufferDurationInMs * kMicrosecondsPerMillisecond;
    612  }
    613  DVLOG(3) << __FUNCTION__ << " : using hardcoded default duration "
    614  << duration;
    615  }
    616 
    617  DCHECK_GT(duration, 0);
    618  DCHECK_NE(duration, kNoTimestamp);
    619  return duration;
    620 }
    621 
    622 void WebMClusterParser::ResetTextTracks() {
    623  for (TextTrackMap::iterator it = text_track_map_.begin();
    624  it != text_track_map_.end();
    625  ++it) {
    626  it->second.Reset();
    627  }
    628 }
    629 
    630 WebMClusterParser::Track*
    631 WebMClusterParser::FindTextTrack(int track_num) {
    632  const TextTrackMap::iterator it = text_track_map_.find(track_num);
    633 
    634  if (it == text_track_map_.end())
    635  return NULL;
    636 
    637  return &it->second;
    638 }
    639 
    640 } // namespace media
    641 } // namespace shaka
    Class for parsing or writing VP codec configuration record.
    -
    WebMClusterParser(int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)
    -
    All the methods that are virtual are virtual for mocking.
    -
    int Parse(const uint8_t *buf, int size)
    -
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:34
    - - -
    base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
    Definition: media_parser.h:43
    -
    void Reset()
    Resets the state of the parser so it can start parsing a new list.
    Definition: webm_parser.cc:733
    -
    int Parse(const uint8_t *buf, int size)
    Definition: webm_parser.cc:738
    -
    Class to parse a vp9 bit stream.
    Definition: vp9_parser.h:20
    -
    bool Flush() WARN_UNUSED_RESULT
    -
    void WriteMP4(std::vector< uint8_t > *data) const
    -
    static void Parse(const uint8_t *payload, int payload_size, std::string *id, std::string *settings, std::string *content)
    Utility function to parse the WebVTT cue from a byte stream.
    - -
    void MergeFrom(const VPCodecConfigurationRecord &other)
    - -
    static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
    Definition: media_sample.cc:42
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    - -
    DecryptorSource wraps KeySource and is responsible for decryptor management.
    - -
    void Reset()
    Resets the parser state so it can accept a new cluster.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/webm/webm_cluster_parser.h"
    +
    6 
    +
    7 #include <algorithm>
    +
    8 #include <vector>
    +
    9 
    +
    10 #include "packager/base/logging.h"
    +
    11 #include "packager/base/sys_byteorder.h"
    +
    12 #include "packager/media/base/decrypt_config.h"
    +
    13 #include "packager/media/base/timestamp.h"
    +
    14 #include "packager/media/codecs/vp8_parser.h"
    +
    15 #include "packager/media/codecs/vp9_parser.h"
    +
    16 #include "packager/media/codecs/webvtt_util.h"
    +
    17 #include "packager/media/formats/webm/webm_constants.h"
    +
    18 #include "packager/media/formats/webm/webm_crypto_helpers.h"
    +
    19 #include "packager/media/formats/webm/webm_webvtt_parser.h"
    +
    20 
    +
    21 namespace shaka {
    +
    22 namespace media {
    +
    23 namespace {
    +
    24 
    +
    25 const int64_t kMicrosecondsPerMillisecond = 1000;
    +
    26 
    +
    27 } // namespace
    +
    28 
    + +
    30  int64_t timecode_scale,
    +
    31  std::shared_ptr<AudioStreamInfo> audio_stream_info,
    +
    32  std::shared_ptr<VideoStreamInfo> video_stream_info,
    +
    33  const VPCodecConfigurationRecord& vp_config,
    +
    34  int64_t audio_default_duration,
    +
    35  int64_t video_default_duration,
    +
    36  const WebMTracksParser::TextTracks& text_tracks,
    +
    37  const std::set<int64_t>& ignored_tracks,
    +
    38  const std::string& audio_encryption_key_id,
    +
    39  const std::string& video_encryption_key_id,
    +
    40  const MediaParser::NewMediaSampleCB& new_sample_cb,
    +
    41  const MediaParser::InitCB& init_cb,
    +
    42  KeySource* decryption_key_source)
    +
    43  : timecode_multiplier_(timecode_scale /
    +
    44  static_cast<double>(kMicrosecondsPerMillisecond)),
    +
    45  audio_stream_info_(audio_stream_info),
    +
    46  video_stream_info_(video_stream_info),
    +
    47  vp_config_(vp_config),
    +
    48  ignored_tracks_(ignored_tracks),
    +
    49  audio_encryption_key_id_(audio_encryption_key_id),
    +
    50  video_encryption_key_id_(video_encryption_key_id),
    +
    51  parser_(kWebMIdCluster, this),
    +
    52  initialized_(false),
    +
    53  init_cb_(init_cb),
    +
    54  cluster_start_time_(kNoTimestamp),
    +
    55  audio_(audio_stream_info ? audio_stream_info->track_id() : -1,
    +
    56  false,
    +
    57  audio_default_duration,
    +
    58  new_sample_cb),
    +
    59  video_(video_stream_info ? video_stream_info->track_id() : -1,
    +
    60  true,
    +
    61  video_default_duration,
    +
    62  new_sample_cb) {
    +
    63  if (decryption_key_source) {
    +
    64  decryptor_source_.reset(new DecryptorSource(decryption_key_source));
    +
    65  if (audio_stream_info_)
    +
    66  audio_stream_info_->set_is_encrypted(false);
    +
    67  if (video_stream_info_)
    +
    68  video_stream_info_->set_is_encrypted(false);
    +
    69  }
    +
    70  for (WebMTracksParser::TextTracks::const_iterator it = text_tracks.begin();
    +
    71  it != text_tracks.end();
    +
    72  ++it) {
    +
    73  text_track_map_.insert(std::make_pair(
    +
    74  it->first, Track(it->first, false, kNoTimestamp, new_sample_cb)));
    +
    75  }
    +
    76 }
    +
    77 
    +
    78 WebMClusterParser::~WebMClusterParser() {}
    +
    79 
    + +
    81  last_block_timecode_ = -1;
    +
    82  cluster_timecode_ = -1;
    +
    83  cluster_start_time_ = kNoTimestamp;
    +
    84  cluster_ended_ = false;
    +
    85  parser_.Reset();
    +
    86  audio_.Reset();
    +
    87  video_.Reset();
    +
    88  ResetTextTracks();
    +
    89 }
    +
    90 
    + +
    92  // Estimate the duration of the last frame if necessary.
    +
    93  bool audio_result = audio_.ApplyDurationEstimateIfNeeded();
    +
    94  bool video_result = video_.ApplyDurationEstimateIfNeeded();
    +
    95  Reset();
    +
    96  return audio_result && video_result;
    +
    97 }
    +
    98 
    +
    99 int WebMClusterParser::Parse(const uint8_t* buf, int size) {
    +
    100  int result = parser_.Parse(buf, size);
    +
    101 
    +
    102  if (result < 0) {
    +
    103  cluster_ended_ = false;
    +
    104  return result;
    +
    105  }
    +
    106 
    +
    107  cluster_ended_ = parser_.IsParsingComplete();
    +
    108  if (cluster_ended_) {
    +
    109  // If there were no buffers in this cluster, set the cluster start time to
    +
    110  // be the |cluster_timecode_|.
    +
    111  if (cluster_start_time_ == kNoTimestamp) {
    +
    112  // If the cluster did not even have a |cluster_timecode_|, signal parse
    +
    113  // error.
    +
    114  if (cluster_timecode_ < 0)
    +
    115  return -1;
    +
    116 
    +
    117  cluster_start_time_ = cluster_timecode_ * timecode_multiplier_;
    +
    118  }
    +
    119 
    +
    120  // Reset the parser if we're done parsing so that
    +
    121  // it is ready to accept another cluster on the next
    +
    122  // call.
    +
    123  parser_.Reset();
    +
    124 
    +
    125  last_block_timecode_ = -1;
    +
    126  cluster_timecode_ = -1;
    +
    127  }
    +
    128 
    +
    129  return result;
    +
    130 }
    +
    131 
    +
    132 WebMParserClient* WebMClusterParser::OnListStart(int id) {
    +
    133  if (id == kWebMIdCluster) {
    +
    134  cluster_timecode_ = -1;
    +
    135  cluster_start_time_ = kNoTimestamp;
    +
    136  } else if (id == kWebMIdBlockGroup) {
    +
    137  block_data_.reset();
    +
    138  block_data_size_ = -1;
    +
    139  block_duration_ = -1;
    +
    140  discard_padding_ = -1;
    +
    141  discard_padding_set_ = false;
    +
    142  reference_block_set_ = false;
    +
    143  } else if (id == kWebMIdBlockAdditions) {
    +
    144  block_add_id_ = -1;
    +
    145  block_additional_data_.reset();
    +
    146  block_additional_data_size_ = 0;
    +
    147  }
    +
    148 
    +
    149  return this;
    +
    150 }
    +
    151 
    +
    152 bool WebMClusterParser::OnListEnd(int id) {
    +
    153  if (id != kWebMIdBlockGroup)
    +
    154  return true;
    +
    155 
    +
    156  // Make sure the BlockGroup actually had a Block.
    +
    157  if (block_data_size_ == -1) {
    +
    158  LOG(ERROR) << "Block missing from BlockGroup.";
    +
    159  return false;
    +
    160  }
    +
    161 
    +
    162  bool result = ParseBlock(
    +
    163  false, block_data_.get(), block_data_size_, block_additional_data_.get(),
    +
    164  block_additional_data_size_, block_duration_,
    +
    165  discard_padding_set_ ? discard_padding_ : 0, reference_block_set_);
    +
    166  block_data_.reset();
    +
    167  block_data_size_ = -1;
    +
    168  block_duration_ = -1;
    +
    169  block_add_id_ = -1;
    +
    170  block_additional_data_.reset();
    +
    171  block_additional_data_size_ = 0;
    +
    172  discard_padding_ = -1;
    +
    173  discard_padding_set_ = false;
    +
    174  reference_block_set_ = false;
    +
    175  return result;
    +
    176 }
    +
    177 
    +
    178 bool WebMClusterParser::OnUInt(int id, int64_t val) {
    +
    179  int64_t* dst;
    +
    180  switch (id) {
    +
    181  case kWebMIdTimecode:
    +
    182  dst = &cluster_timecode_;
    +
    183  break;
    +
    184  case kWebMIdBlockDuration:
    +
    185  dst = &block_duration_;
    +
    186  break;
    +
    187  case kWebMIdBlockAddID:
    +
    188  dst = &block_add_id_;
    +
    189  break;
    +
    190  default:
    +
    191  return true;
    +
    192  }
    +
    193  if (*dst != -1)
    +
    194  return false;
    +
    195  *dst = val;
    +
    196  return true;
    +
    197 }
    +
    198 
    +
    199 bool WebMClusterParser::ParseBlock(bool is_simple_block,
    +
    200  const uint8_t* buf,
    +
    201  int size,
    +
    202  const uint8_t* additional,
    +
    203  int additional_size,
    +
    204  int duration,
    +
    205  int64_t discard_padding,
    +
    206  bool reference_block_set) {
    +
    207  if (size < 4)
    +
    208  return false;
    +
    209 
    +
    210  // Return an error if the trackNum > 127. We just aren't
    +
    211  // going to support large track numbers right now.
    +
    212  if (!(buf[0] & 0x80)) {
    +
    213  LOG(ERROR) << "TrackNumber over 127 not supported";
    +
    214  return false;
    +
    215  }
    +
    216 
    +
    217  int track_num = buf[0] & 0x7f;
    +
    218  int timecode = buf[1] << 8 | buf[2];
    +
    219  int flags = buf[3] & 0xff;
    +
    220  int lacing = (flags >> 1) & 0x3;
    +
    221 
    +
    222  if (lacing) {
    +
    223  LOG(ERROR) << "Lacing " << lacing << " is not supported yet.";
    +
    224  return false;
    +
    225  }
    +
    226 
    +
    227  // Sign extend negative timecode offsets.
    +
    228  if (timecode & 0x8000)
    +
    229  timecode |= ~0xffff;
    +
    230 
    +
    231  // The first bit of the flags is set when a SimpleBlock contains only
    +
    232  // keyframes. If this is a Block, then keyframe is inferred by the absence of
    +
    233  // the ReferenceBlock Element.
    +
    234  // http://www.matroska.org/technical/specs/index.html
    +
    235  bool is_key_frame =
    +
    236  is_simple_block ? (flags & 0x80) != 0 : !reference_block_set;
    +
    237 
    +
    238  const uint8_t* frame_data = buf + 4;
    +
    239  int frame_size = size - (frame_data - buf);
    +
    240  return OnBlock(is_simple_block, track_num, timecode, duration, frame_data,
    +
    241  frame_size, additional, additional_size, discard_padding,
    +
    242  is_key_frame);
    +
    243 }
    +
    244 
    +
    245 bool WebMClusterParser::OnBinary(int id, const uint8_t* data, int size) {
    +
    246  switch (id) {
    +
    247  case kWebMIdSimpleBlock:
    +
    248  return ParseBlock(true, data, size, NULL, 0, -1, 0, false);
    +
    249 
    +
    250  case kWebMIdBlock:
    +
    251  if (block_data_) {
    +
    252  LOG(ERROR) << "More than 1 Block in a BlockGroup is not "
    +
    253  "supported.";
    +
    254  return false;
    +
    255  }
    +
    256  block_data_.reset(new uint8_t[size]);
    +
    257  memcpy(block_data_.get(), data, size);
    +
    258  block_data_size_ = size;
    +
    259  return true;
    +
    260 
    +
    261  case kWebMIdBlockAdditional: {
    +
    262  uint64_t block_add_id = base::HostToNet64(block_add_id_);
    +
    263  if (block_additional_data_) {
    +
    264  // TODO: Technically, more than 1 BlockAdditional is allowed as per
    +
    265  // matroska spec. But for now we don't have a use case to support
    +
    266  // parsing of such files. Take a look at this again when such a case
    +
    267  // arises.
    +
    268  LOG(ERROR) << "More than 1 BlockAdditional in a "
    +
    269  "BlockGroup is not supported.";
    +
    270  return false;
    +
    271  }
    +
    272  // First 8 bytes of side_data in DecoderBuffer is the BlockAddID
    +
    273  // element's value in Big Endian format. This is done to mimic ffmpeg
    +
    274  // demuxer's behavior.
    +
    275  block_additional_data_size_ = size + sizeof(block_add_id);
    +
    276  block_additional_data_.reset(new uint8_t[block_additional_data_size_]);
    +
    277  memcpy(block_additional_data_.get(), &block_add_id,
    +
    278  sizeof(block_add_id));
    +
    279  memcpy(block_additional_data_.get() + 8, data, size);
    +
    280  return true;
    +
    281  }
    +
    282  case kWebMIdDiscardPadding: {
    +
    283  if (discard_padding_set_ || size <= 0 || size > 8)
    +
    284  return false;
    +
    285  discard_padding_set_ = true;
    +
    286 
    +
    287  // Read in the big-endian integer.
    +
    288  discard_padding_ = static_cast<int8_t>(data[0]);
    +
    289  for (int i = 1; i < size; ++i)
    +
    290  discard_padding_ = (discard_padding_ << 8) | data[i];
    +
    291 
    +
    292  return true;
    +
    293  }
    +
    294  case kWebMIdReferenceBlock:
    +
    295  // We use ReferenceBlock to determine whether the current Block contains a
    +
    296  // keyframe or not. Other than that, we don't care about the value of the
    +
    297  // ReferenceBlock element itself.
    +
    298  reference_block_set_ = true;
    +
    299  return true;
    +
    300  default:
    +
    301  return true;
    +
    302  }
    +
    303 }
    +
    304 
    +
    305 bool WebMClusterParser::OnBlock(bool is_simple_block,
    +
    306  int track_num,
    +
    307  int timecode,
    +
    308  int block_duration,
    +
    309  const uint8_t* data,
    +
    310  int size,
    +
    311  const uint8_t* additional,
    +
    312  int additional_size,
    +
    313  int64_t discard_padding,
    +
    314  bool is_key_frame) {
    +
    315  DCHECK_GE(size, 0);
    +
    316  if (cluster_timecode_ == -1) {
    +
    317  LOG(ERROR) << "Got a block before cluster timecode.";
    +
    318  return false;
    +
    319  }
    +
    320 
    +
    321  // TODO: Should relative negative timecode offsets be rejected? Or only when
    +
    322  // the absolute timecode is negative? See http://crbug.com/271794
    +
    323  if (timecode < 0) {
    +
    324  LOG(ERROR) << "Got a block with negative timecode offset " << timecode;
    +
    325  return false;
    +
    326  }
    +
    327 
    +
    328  if (last_block_timecode_ != -1 && timecode < last_block_timecode_) {
    +
    329  LOG(ERROR) << "Got a block with a timecode before the previous block.";
    +
    330  return false;
    +
    331  }
    +
    332 
    +
    333  Track* track = NULL;
    +
    334  StreamType stream_type = kStreamUnknown;
    +
    335  std::string encryption_key_id;
    +
    336  if (track_num == audio_.track_num()) {
    +
    337  track = &audio_;
    +
    338  encryption_key_id = audio_encryption_key_id_;
    +
    339  stream_type = kStreamAudio;
    +
    340  } else if (track_num == video_.track_num()) {
    +
    341  track = &video_;
    +
    342  encryption_key_id = video_encryption_key_id_;
    +
    343  stream_type = kStreamVideo;
    +
    344  } else if (ignored_tracks_.find(track_num) != ignored_tracks_.end()) {
    +
    345  return true;
    +
    346  } else if (Track* const text_track = FindTextTrack(track_num)) {
    +
    347  if (is_simple_block) // BlockGroup is required for WebVTT cues
    +
    348  return false;
    +
    349  if (block_duration < 0) // not specified
    +
    350  return false;
    +
    351  track = text_track;
    +
    352  stream_type = kStreamText;
    +
    353  } else {
    +
    354  LOG(ERROR) << "Unexpected track number " << track_num;
    +
    355  return false;
    +
    356  }
    +
    357  DCHECK_NE(stream_type, kStreamUnknown);
    +
    358 
    +
    359  last_block_timecode_ = timecode;
    +
    360 
    +
    361  int64_t timestamp = (cluster_timecode_ + timecode) * timecode_multiplier_;
    +
    362 
    +
    363  std::shared_ptr<MediaSample> buffer;
    +
    364  if (stream_type != kStreamText) {
    +
    365  // Every encrypted Block has a signal byte and IV prepended to it. Current
    +
    366  // encrypted WebM request for comments specification is here
    +
    367  // http://wiki.webmproject.org/encryption/webm-encryption-rfc
    +
    368  std::unique_ptr<DecryptConfig> decrypt_config;
    +
    369  int data_offset = 0;
    +
    370  if (!encryption_key_id.empty() &&
    +
    371  !WebMCreateDecryptConfig(
    +
    372  data, size,
    +
    373  reinterpret_cast<const uint8_t*>(encryption_key_id.data()),
    +
    374  encryption_key_id.size(),
    +
    375  &decrypt_config, &data_offset)) {
    +
    376  return false;
    +
    377  }
    +
    378 
    +
    379  const uint8_t* media_data = data + data_offset;
    +
    380  const size_t media_data_size = size - data_offset;
    +
    381  // Use a dummy data size of 0 to avoid copying overhead.
    +
    382  // Actual media data is set later.
    +
    383  const size_t kDummyDataSize = 0;
    +
    384  buffer = MediaSample::CopyFrom(media_data, kDummyDataSize, additional,
    +
    385  additional_size, is_key_frame);
    +
    386 
    +
    387  if (decrypt_config) {
    +
    388  if (!decryptor_source_) {
    +
    389  buffer->SetData(media_data, media_data_size);
    +
    390  // If the demuxer does not have the decryptor_source_, store
    +
    391  // decrypt_config so that the demuxed sample can be decrypted later.
    +
    392  buffer->set_decrypt_config(std::move(decrypt_config));
    +
    393  buffer->set_is_encrypted(true);
    +
    394  } else {
    +
    395  std::shared_ptr<uint8_t> decrypted_media_data(
    +
    396  new uint8_t[media_data_size], std::default_delete<uint8_t[]>());
    +
    397  if (!decryptor_source_->DecryptSampleBuffer(
    +
    398  decrypt_config.get(), media_data, media_data_size,
    +
    399  decrypted_media_data.get())) {
    +
    400  LOG(ERROR) << "Cannot decrypt samples";
    +
    401  return false;
    +
    402  }
    +
    403  buffer->TransferData(std::move(decrypted_media_data), media_data_size);
    +
    404  }
    +
    405  } else {
    +
    406  buffer->SetData(media_data, media_data_size);
    +
    407  }
    +
    408  } else {
    +
    409  std::string id, settings, content;
    +
    410  WebMWebVTTParser::Parse(data, size, &id, &settings, &content);
    +
    411 
    +
    412  std::vector<uint8_t> side_data;
    +
    413  MakeSideData(id.begin(), id.end(),
    +
    414  settings.begin(), settings.end(),
    +
    415  &side_data);
    +
    416 
    +
    417  buffer = MediaSample::CopyFrom(
    +
    418  reinterpret_cast<const uint8_t*>(content.data()), content.length(),
    +
    419  &side_data[0], side_data.size(), true);
    +
    420  }
    +
    421 
    +
    422  buffer->set_dts(timestamp);
    +
    423  buffer->set_pts(timestamp);
    +
    424  if (cluster_start_time_ == kNoTimestamp)
    +
    425  cluster_start_time_ = timestamp;
    +
    426  buffer->set_duration(block_duration > 0
    +
    427  ? (block_duration * timecode_multiplier_)
    +
    428  : kNoTimestamp);
    +
    429 
    +
    430  if (!init_cb_.is_null() && !initialized_) {
    +
    431  std::vector<std::shared_ptr<StreamInfo>> streams;
    +
    432  if (audio_stream_info_)
    +
    433  streams.push_back(audio_stream_info_);
    +
    434  if (video_stream_info_) {
    +
    435  if (stream_type == kStreamVideo) {
    +
    436  // Setup codec string and codec config for VP8 and VP9.
    +
    437  // Codec config for AV1 is already retrieved from WebM CodecPrivate
    +
    438  // instead of extracted from the bit stream.
    +
    439  if (video_stream_info_->codec() != kCodecAV1) {
    +
    440  std::unique_ptr<VPxParser> vpx_parser;
    +
    441  switch (video_stream_info_->codec()) {
    +
    442  case kCodecVP8:
    +
    443  vpx_parser.reset(new VP8Parser);
    +
    444  break;
    +
    445  case kCodecVP9:
    +
    446  vpx_parser.reset(new VP9Parser);
    +
    447  break;
    +
    448  default:
    +
    449  NOTIMPLEMENTED()
    +
    450  << "Unsupported codec " << video_stream_info_->codec();
    +
    451  return false;
    +
    452  }
    +
    453  std::vector<VPxFrameInfo> vpx_frames;
    +
    454  if (!vpx_parser->Parse(buffer->data(), buffer->data_size(),
    +
    455  &vpx_frames)) {
    +
    456  LOG(ERROR) << "Failed to parse vpx frame.";
    +
    457  return false;
    +
    458  }
    +
    459  if (vpx_frames.size() != 1u || !vpx_frames[0].is_keyframe) {
    +
    460  LOG(ERROR) << "The first frame should be a key frame.";
    +
    461  return false;
    +
    462  }
    +
    463 
    +
    464  vp_config_.MergeFrom(vpx_parser->codec_config());
    +
    465  video_stream_info_->set_codec_string(
    +
    466  vp_config_.GetCodecString(video_stream_info_->codec()));
    +
    467  std::vector<uint8_t> config_serialized;
    +
    468  vp_config_.WriteMP4(&config_serialized);
    +
    469  video_stream_info_->set_codec_config(config_serialized);
    +
    470  }
    +
    471 
    +
    472  streams.push_back(video_stream_info_);
    +
    473  init_cb_.Run(streams);
    +
    474  initialized_ = true;
    +
    475  }
    +
    476  } else {
    +
    477  init_cb_.Run(streams);
    +
    478  initialized_ = true;
    +
    479  }
    +
    480  }
    +
    481 
    +
    482  return track->EmitBuffer(buffer);
    +
    483 }
    +
    484 
    +
    485 WebMClusterParser::Track::Track(
    +
    486  int track_num,
    +
    487  bool is_video,
    +
    488  int64_t default_duration,
    +
    489  const MediaParser::NewMediaSampleCB& new_sample_cb)
    +
    490  : track_num_(track_num),
    +
    491  is_video_(is_video),
    +
    492  default_duration_(default_duration),
    +
    493  estimated_next_frame_duration_(kNoTimestamp),
    +
    494  new_sample_cb_(new_sample_cb) {
    +
    495  DCHECK(default_duration_ == kNoTimestamp || default_duration_ > 0);
    +
    496 }
    +
    497 
    +
    498 WebMClusterParser::Track::~Track() {}
    +
    499 
    +
    500 bool WebMClusterParser::Track::EmitBuffer(
    +
    501  const std::shared_ptr<MediaSample>& buffer) {
    +
    502  DVLOG(2) << "EmitBuffer() : " << track_num_
    +
    503  << " ts " << buffer->pts()
    +
    504  << " dur " << buffer->duration()
    +
    505  << " kf " << buffer->is_key_frame()
    +
    506  << " size " << buffer->data_size();
    +
    507 
    +
    508  if (last_added_buffer_missing_duration_.get()) {
    +
    509  int64_t derived_duration =
    +
    510  buffer->pts() - last_added_buffer_missing_duration_->pts();
    +
    511  last_added_buffer_missing_duration_->set_duration(derived_duration);
    +
    512 
    +
    513  DVLOG(2) << "EmitBuffer() : applied derived duration to held-back buffer : "
    +
    514  << " ts "
    +
    515  << last_added_buffer_missing_duration_->pts()
    +
    516  << " dur "
    +
    517  << last_added_buffer_missing_duration_->duration()
    +
    518  << " kf " << last_added_buffer_missing_duration_->is_key_frame()
    +
    519  << " size " << last_added_buffer_missing_duration_->data_size();
    +
    520  std::shared_ptr<MediaSample> updated_buffer =
    +
    521  last_added_buffer_missing_duration_;
    +
    522  last_added_buffer_missing_duration_ = NULL;
    +
    523  if (!EmitBufferHelp(updated_buffer))
    +
    524  return false;
    +
    525  }
    +
    526 
    +
    527  if (buffer->duration() == kNoTimestamp) {
    +
    528  last_added_buffer_missing_duration_ = buffer;
    +
    529  DVLOG(2) << "EmitBuffer() : holding back buffer that is missing duration";
    +
    530  return true;
    +
    531  }
    +
    532 
    +
    533  return EmitBufferHelp(buffer);
    +
    534 }
    +
    535 
    +
    536 bool WebMClusterParser::Track::ApplyDurationEstimateIfNeeded() {
    +
    537  if (!last_added_buffer_missing_duration_.get())
    +
    538  return true;
    +
    539 
    +
    540  int64_t estimated_duration = GetDurationEstimate();
    +
    541  last_added_buffer_missing_duration_->set_duration(estimated_duration);
    +
    542 
    +
    543  VLOG(1) << "Track " << track_num_ << ": Estimating WebM block duration to be "
    +
    544  << estimated_duration / 1000
    +
    545  << "ms for the last (Simple)Block in the Cluster for this Track. Use "
    +
    546  "BlockGroups with BlockDurations at the end of each Track in a "
    +
    547  "Cluster to avoid estimation.";
    +
    548 
    +
    549  DVLOG(2) << " new dur : ts " << last_added_buffer_missing_duration_->pts()
    +
    550  << " dur " << last_added_buffer_missing_duration_->duration()
    +
    551  << " kf " << last_added_buffer_missing_duration_->is_key_frame()
    +
    552  << " size " << last_added_buffer_missing_duration_->data_size();
    +
    553 
    +
    554  // Don't use the applied duration as a future estimation (don't use
    +
    555  // EmitBufferHelp() here.)
    +
    556  if (!new_sample_cb_.Run(track_num_, last_added_buffer_missing_duration_))
    +
    557  return false;
    +
    558  last_added_buffer_missing_duration_ = NULL;
    +
    559  return true;
    +
    560 }
    +
    561 
    +
    562 void WebMClusterParser::Track::Reset() {
    +
    563  last_added_buffer_missing_duration_ = NULL;
    +
    564 }
    +
    565 
    +
    566 bool WebMClusterParser::Track::EmitBufferHelp(
    +
    567  const std::shared_ptr<MediaSample>& buffer) {
    +
    568  DCHECK(!last_added_buffer_missing_duration_.get());
    +
    569 
    +
    570  int64_t duration = buffer->duration();
    +
    571  if (duration < 0 || duration == kNoTimestamp) {
    +
    572  LOG(ERROR) << "Invalid buffer duration: " << duration;
    +
    573  return false;
    +
    574  }
    +
    575 
    +
    576  // The estimated frame duration is the maximum non-zero duration since the
    +
    577  // last initialization segment.
    +
    578  if (duration > 0) {
    +
    579  int64_t orig_duration_estimate = estimated_next_frame_duration_;
    +
    580  if (estimated_next_frame_duration_ == kNoTimestamp) {
    +
    581  estimated_next_frame_duration_ = duration;
    +
    582  } else {
    +
    583  estimated_next_frame_duration_ =
    +
    584  std::max(duration, estimated_next_frame_duration_);
    +
    585  }
    +
    586 
    +
    587  if (orig_duration_estimate != estimated_next_frame_duration_) {
    +
    588  DVLOG(3) << "Updated duration estimate:"
    +
    589  << orig_duration_estimate
    +
    590  << " -> "
    +
    591  << estimated_next_frame_duration_
    +
    592  << " at timestamp: "
    +
    593  << buffer->dts();
    +
    594  }
    +
    595  }
    +
    596 
    +
    597  return new_sample_cb_.Run(track_num_, buffer);
    +
    598 }
    +
    599 
    +
    600 int64_t WebMClusterParser::Track::GetDurationEstimate() {
    +
    601  int64_t duration = kNoTimestamp;
    +
    602  if (default_duration_ != kNoTimestamp) {
    +
    603  duration = default_duration_;
    +
    604  DVLOG(3) << __FUNCTION__ << " : using track default duration " << duration;
    +
    605  } else if (estimated_next_frame_duration_ != kNoTimestamp) {
    +
    606  duration = estimated_next_frame_duration_;
    +
    607  DVLOG(3) << __FUNCTION__ << " : using estimated duration " << duration;
    +
    608  } else {
    +
    609  if (is_video_) {
    +
    610  duration = kDefaultVideoBufferDurationInMs * kMicrosecondsPerMillisecond;
    +
    611  } else {
    +
    612  duration = kDefaultAudioBufferDurationInMs * kMicrosecondsPerMillisecond;
    +
    613  }
    +
    614  DVLOG(3) << __FUNCTION__ << " : using hardcoded default duration "
    +
    615  << duration;
    +
    616  }
    +
    617 
    +
    618  DCHECK_GT(duration, 0);
    +
    619  DCHECK_NE(duration, kNoTimestamp);
    +
    620  return duration;
    +
    621 }
    +
    622 
    +
    623 void WebMClusterParser::ResetTextTracks() {
    +
    624  for (TextTrackMap::iterator it = text_track_map_.begin();
    +
    625  it != text_track_map_.end();
    +
    626  ++it) {
    +
    627  it->second.Reset();
    +
    628  }
    +
    629 }
    +
    630 
    +
    631 WebMClusterParser::Track*
    +
    632 WebMClusterParser::FindTextTrack(int track_num) {
    +
    633  const TextTrackMap::iterator it = text_track_map_.find(track_num);
    +
    634 
    +
    635  if (it == text_track_map_.end())
    +
    636  return NULL;
    +
    637 
    +
    638  return &it->second;
    +
    639 }
    +
    640 
    +
    641 } // namespace media
    +
    642 } // namespace shaka
    +
    DecryptorSource wraps KeySource and is responsible for decryptor management.
    +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    +
    static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
    Definition: media_sample.cc:42
    +
    Class for parsing or writing VP codec configuration record.
    +
    void WriteMP4(std::vector< uint8_t > *data) const
    +
    void MergeFrom(const VPCodecConfigurationRecord &other)
    + +
    WebMClusterParser(int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewMediaSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)
    +
    int Parse(const uint8_t *buf, int size)
    +
    void Reset()
    Resets the parser state so it can accept a new cluster.
    +
    bool Flush() WARN_UNUSED_RESULT
    +
    void Reset()
    Resets the state of the parser so it can start parsing a new list.
    Definition: webm_parser.cc:733
    +
    int Parse(const uint8_t *buf, int size)
    Definition: webm_parser.cc:738
    + + +
    static void Parse(const uint8_t *payload, int payload_size, std::string *id, std::string *settings, std::string *content)
    Utility function to parse the WebVTT cue from a byte stream.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d95/structshaka_1_1media_1_1mp4_1_1EditListEntry-members.html b/docs/d5/d95/structshaka_1_1media_1_1mp4_1_1EditListEntry-members.html index fe3d144ae6..d7837e3b5f 100644 --- a/docs/d5/d95/structshaka_1_1media_1_1mp4_1_1EditListEntry-members.html +++ b/docs/d5/d95/structshaka_1_1media_1_1mp4_1_1EditListEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d5/d98/encryptor_8cc_source.html b/docs/d5/d98/encryptor_8cc_source.html index 182d71618a..0cc772e3ad 100644 --- a/docs/d5/d98/encryptor_8cc_source.html +++ b/docs/d5/d98/encryptor_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/encryptor.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    encryptor.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/webm/encryptor.h"
    8 
    9 #include "packager/media/base/buffer_writer.h"
    10 #include "packager/media/base/media_sample.h"
    11 #include "packager/media/formats/webm/webm_constants.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace webm {
    16 namespace {
    17 void WriteEncryptedFrameHeader(const DecryptConfig* decrypt_config,
    18  BufferWriter* header_buffer) {
    19  if (decrypt_config) {
    20  const size_t iv_size = decrypt_config->iv().size();
    21  DCHECK_EQ(iv_size, kWebMIvSize);
    22  if (!decrypt_config->subsamples().empty()) {
    23  const auto& subsamples = decrypt_config->subsamples();
    24  // Use partitioned subsample encryption: | signal_byte(3) | iv
    25  // | num_partitions | partition_offset * n | enc_data |
    26  DCHECK_LT(subsamples.size(), kWebMMaxSubsamples);
    27  const size_t num_partitions =
    28  2 * subsamples.size() - 1 -
    29  (subsamples.back().cipher_bytes == 0 ? 1 : 0);
    30  const size_t header_size = kWebMSignalByteSize + iv_size +
    31  kWebMNumPartitionsSize +
    32  (kWebMPartitionOffsetSize * num_partitions);
    33 
    34  const uint8_t signal_byte = kWebMEncryptedSignal | kWebMPartitionedSignal;
    35  header_buffer->AppendInt(signal_byte);
    36  header_buffer->AppendVector(decrypt_config->iv());
    37  header_buffer->AppendInt(static_cast<uint8_t>(num_partitions));
    38 
    39  uint32_t partition_offset = 0;
    40  for (size_t i = 0; i < subsamples.size() - 1; ++i) {
    41  partition_offset += subsamples[i].clear_bytes;
    42  header_buffer->AppendInt(partition_offset);
    43  partition_offset += subsamples[i].cipher_bytes;
    44  header_buffer->AppendInt(partition_offset);
    45  }
    46  // Add another partition between the clear bytes and cipher bytes if
    47  // cipher bytes is not zero.
    48  if (subsamples.back().cipher_bytes != 0) {
    49  partition_offset += subsamples.back().clear_bytes;
    50  header_buffer->AppendInt(partition_offset);
    51  }
    52 
    53  DCHECK_EQ(header_size, header_buffer->Size());
    54  } else {
    55  // Use whole-frame encryption: | signal_byte(1) | iv | enc_data |
    56  const uint8_t signal_byte = kWebMEncryptedSignal;
    57  header_buffer->AppendInt(signal_byte);
    58  header_buffer->AppendVector(decrypt_config->iv());
    59  }
    60  } else {
    61  // Clear sample: | signal_byte(0) | data |
    62  const uint8_t signal_byte = 0x00;
    63  header_buffer->AppendInt(signal_byte);
    64  }
    65 }
    66 } // namespace
    67 
    68 Status UpdateTrackForEncryption(const std::vector<uint8_t>& key_id,
    69  mkvmuxer::Track* track) {
    70  DCHECK_EQ(track->content_encoding_entries_size(), 0u);
    71 
    72  if (!track->AddContentEncoding()) {
    73  return Status(error::INTERNAL_ERROR,
    74  "Could not add ContentEncoding to track.");
    75  }
    76 
    77  mkvmuxer::ContentEncoding* const encoding =
    78  track->GetContentEncodingByIndex(0);
    79  if (!encoding) {
    80  return Status(error::INTERNAL_ERROR,
    81  "Could not add ContentEncoding to track.");
    82  }
    83 
    84  mkvmuxer::ContentEncAESSettings* const aes = encoding->enc_aes_settings();
    85  if (!aes) {
    86  return Status(error::INTERNAL_ERROR,
    87  "Error getting ContentEncAESSettings.");
    88  }
    89  if (aes->cipher_mode() != mkvmuxer::ContentEncAESSettings::kCTR) {
    90  return Status(error::INTERNAL_ERROR, "Cipher Mode is not CTR.");
    91  }
    92 
    93  if (!encoding->SetEncryptionID(key_id.data(), key_id.size())) {
    94  return Status(error::INTERNAL_ERROR, "Error setting encryption ID.");
    95  }
    96  return Status::OK;
    97 }
    98 
    99 void UpdateFrameForEncryption(MediaSample* sample) {
    100  DCHECK(sample);
    101  BufferWriter header_buffer;
    102  WriteEncryptedFrameHeader(sample->decrypt_config(), &header_buffer);
    103 
    104  const size_t sample_size = header_buffer.Size() + sample->data_size();
    105  std::shared_ptr<uint8_t> new_sample_data(new uint8_t[sample_size],
    106  std::default_delete<uint8_t[]>());
    107  memcpy(new_sample_data.get(), header_buffer.Buffer(), header_buffer.Size());
    108  memcpy(&new_sample_data.get()[header_buffer.Size()], sample->data(),
    109  sample->data_size());
    110  sample->TransferData(std::move(new_sample_data), sample_size);
    111 }
    112 
    113 } // namespace webm
    114 } // namespace media
    115 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webm/encryptor.h"
    +
    8 
    +
    9 #include "packager/media/base/buffer_writer.h"
    +
    10 #include "packager/media/base/media_sample.h"
    +
    11 #include "packager/media/formats/webm/webm_constants.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace webm {
    +
    16 namespace {
    +
    17 void WriteEncryptedFrameHeader(const DecryptConfig* decrypt_config,
    +
    18  BufferWriter* header_buffer) {
    +
    19  if (decrypt_config) {
    +
    20  const size_t iv_size = decrypt_config->iv().size();
    +
    21  DCHECK_EQ(iv_size, kWebMIvSize);
    +
    22  if (!decrypt_config->subsamples().empty()) {
    +
    23  const auto& subsamples = decrypt_config->subsamples();
    +
    24  // Use partitioned subsample encryption: | signal_byte(3) | iv
    +
    25  // | num_partitions | partition_offset * n | enc_data |
    +
    26  DCHECK_LT(subsamples.size(), kWebMMaxSubsamples);
    +
    27  const size_t num_partitions =
    +
    28  2 * subsamples.size() - 1 -
    +
    29  (subsamples.back().cipher_bytes == 0 ? 1 : 0);
    +
    30  const size_t header_size = kWebMSignalByteSize + iv_size +
    +
    31  kWebMNumPartitionsSize +
    +
    32  (kWebMPartitionOffsetSize * num_partitions);
    +
    33 
    +
    34  const uint8_t signal_byte = kWebMEncryptedSignal | kWebMPartitionedSignal;
    +
    35  header_buffer->AppendInt(signal_byte);
    +
    36  header_buffer->AppendVector(decrypt_config->iv());
    +
    37  header_buffer->AppendInt(static_cast<uint8_t>(num_partitions));
    +
    38 
    +
    39  uint32_t partition_offset = 0;
    +
    40  for (size_t i = 0; i < subsamples.size() - 1; ++i) {
    +
    41  partition_offset += subsamples[i].clear_bytes;
    +
    42  header_buffer->AppendInt(partition_offset);
    +
    43  partition_offset += subsamples[i].cipher_bytes;
    +
    44  header_buffer->AppendInt(partition_offset);
    +
    45  }
    +
    46  // Add another partition between the clear bytes and cipher bytes if
    +
    47  // cipher bytes is not zero.
    +
    48  if (subsamples.back().cipher_bytes != 0) {
    +
    49  partition_offset += subsamples.back().clear_bytes;
    +
    50  header_buffer->AppendInt(partition_offset);
    +
    51  }
    +
    52 
    +
    53  DCHECK_EQ(header_size, header_buffer->Size());
    +
    54  } else {
    +
    55  // Use whole-frame encryption: | signal_byte(1) | iv | enc_data |
    +
    56  const uint8_t signal_byte = kWebMEncryptedSignal;
    +
    57  header_buffer->AppendInt(signal_byte);
    +
    58  header_buffer->AppendVector(decrypt_config->iv());
    +
    59  }
    +
    60  } else {
    +
    61  // Clear sample: | signal_byte(0) | data |
    +
    62  const uint8_t signal_byte = 0x00;
    +
    63  header_buffer->AppendInt(signal_byte);
    +
    64  }
    +
    65 }
    +
    66 } // namespace
    +
    67 
    +
    68 Status UpdateTrackForEncryption(const std::vector<uint8_t>& key_id,
    +
    69  mkvmuxer::Track* track) {
    +
    70  DCHECK_EQ(track->content_encoding_entries_size(), 0u);
    +
    71 
    +
    72  if (!track->AddContentEncoding()) {
    +
    73  return Status(error::INTERNAL_ERROR,
    +
    74  "Could not add ContentEncoding to track.");
    +
    75  }
    +
    76 
    +
    77  mkvmuxer::ContentEncoding* const encoding =
    +
    78  track->GetContentEncodingByIndex(0);
    +
    79  if (!encoding) {
    +
    80  return Status(error::INTERNAL_ERROR,
    +
    81  "Could not add ContentEncoding to track.");
    +
    82  }
    +
    83 
    +
    84  mkvmuxer::ContentEncAESSettings* const aes = encoding->enc_aes_settings();
    +
    85  if (!aes) {
    +
    86  return Status(error::INTERNAL_ERROR,
    +
    87  "Error getting ContentEncAESSettings.");
    +
    88  }
    +
    89  if (aes->cipher_mode() != mkvmuxer::ContentEncAESSettings::kCTR) {
    +
    90  return Status(error::INTERNAL_ERROR, "Cipher Mode is not CTR.");
    +
    91  }
    +
    92 
    +
    93  if (!encoding->SetEncryptionID(key_id.data(), key_id.size())) {
    +
    94  return Status(error::INTERNAL_ERROR, "Error setting encryption ID.");
    +
    95  }
    +
    96  return Status::OK;
    +
    97 }
    +
    98 
    +
    99 void UpdateFrameForEncryption(MediaSample* sample) {
    +
    100  DCHECK(sample);
    +
    101  BufferWriter header_buffer;
    +
    102  WriteEncryptedFrameHeader(sample->decrypt_config(), &header_buffer);
    +
    103 
    +
    104  const size_t sample_size = header_buffer.Size() + sample->data_size();
    +
    105  std::shared_ptr<uint8_t> new_sample_data(new uint8_t[sample_size],
    +
    106  std::default_delete<uint8_t[]>());
    +
    107  memcpy(new_sample_data.get(), header_buffer.Buffer(), header_buffer.Size());
    +
    108  memcpy(&new_sample_data.get()[header_buffer.Size()], sample->data(),
    +
    109  sample->data_size());
    +
    110  sample->TransferData(std::move(new_sample_data), sample_size);
    +
    111 }
    +
    112 
    +
    113 } // namespace webm
    +
    114 } // namespace media
    +
    115 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d9b/vp__codec__configuration__record_8h_source.html b/docs/d5/d9b/vp__codec__configuration__record_8h_source.html index 19a67e64f6..132a522dde 100644 --- a/docs/d5/d9b/vp__codec__configuration__record_8h_source.html +++ b/docs/d5/d9b/vp__codec__configuration__record_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/vp_codec_configuration_record.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    vp_codec_configuration_record.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_VP_CODEC_CONFIGURATION_RECORD_H_
    8 #define PACKAGER_MEDIA_CODECS_VP_CODEC_CONFIGURATION_RECORD_H_
    9 
    10 #include <stdint.h>
    11 #include <string>
    12 #include <vector>
    13 
    14 #include "packager/base/macros.h"
    15 #include "packager/base/optional.h"
    16 #include "packager/media/base/video_stream_info.h"
    17 
    18 namespace shaka {
    19 namespace media {
    20 
    23 enum AVColorPrimaries {
    24  AVCOL_PRI_RESERVED0 = 0,
    26  AVCOL_PRI_BT709 = 1,
    27  AVCOL_PRI_UNSPECIFIED = 2,
    28  AVCOL_PRI_RESERVED = 3,
    30  AVCOL_PRI_BT470M = 4,
    32  AVCOL_PRI_BT470BG = 5,
    34  AVCOL_PRI_SMPTE170M = 6,
    36  AVCOL_PRI_SMPTE240M = 7,
    38  AVCOL_PRI_FILM = 8,
    40  AVCOL_PRI_BT2020 = 9,
    42  AVCOL_PRI_SMPTE428 = 10,
    43  AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428,
    45  AVCOL_PRI_SMPTE431 = 11,
    47  AVCOL_PRI_SMPTE432 = 12,
    49  AVCOL_PRI_NB
    50 };
    51 
    53 enum AVColorTransferCharacteristic {
    54  AVCOL_TRC_RESERVED0 = 0,
    56  AVCOL_TRC_BT709 = 1,
    57  AVCOL_TRC_UNSPECIFIED = 2,
    58  AVCOL_TRC_RESERVED = 3,
    60  AVCOL_TRC_GAMMA22 = 4,
    62  AVCOL_TRC_GAMMA28 = 5,
    65  AVCOL_TRC_SMPTE170M = 6,
    66  AVCOL_TRC_SMPTE240M = 7,
    68  AVCOL_TRC_LINEAR = 8,
    70  AVCOL_TRC_LOG = 9,
    72  AVCOL_TRC_LOG_SQRT = 10,
    74  AVCOL_TRC_IEC61966_2_4 = 11,
    76  AVCOL_TRC_BT1361_ECG = 12,
    78  AVCOL_TRC_IEC61966_2_1 = 13,
    80  AVCOL_TRC_BT2020_10 = 14,
    82  AVCOL_TRC_BT2020_12 = 15,
    84  AVCOL_TRC_SMPTE2084 = 16,
    85  AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084,
    87  AVCOL_TRC_SMPTE428 = 17,
    88  AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428,
    90  AVCOL_TRC_ARIB_STD_B67 = 18,
    92  AVCOL_TRC_NB
    93 };
    94 
    96 enum AVColorSpace {
    98  AVCOL_SPC_RGB = 0,
    100  AVCOL_SPC_BT709 = 1,
    101  AVCOL_SPC_UNSPECIFIED = 2,
    102  AVCOL_SPC_RESERVED = 3,
    104  AVCOL_SPC_FCC = 4,
    107  AVCOL_SPC_BT470BG = 5,
    109  AVCOL_SPC_SMPTE170M = 6,
    111  AVCOL_SPC_SMPTE240M = 7,
    113  AVCOL_SPC_YCOCG = 8,
    115  AVCOL_SPC_BT2020_NCL = 9,
    117  AVCOL_SPC_BT2020_CL = 10,
    119  AVCOL_SPC_SMPTE2085 = 11,
    121  AVCOL_SPC_NB
    122 };
    123 
    137 enum AVChromaLocation {
    138  AVCHROMA_LOC_UNSPECIFIED = 0,
    140  AVCHROMA_LOC_LEFT = 1,
    142  AVCHROMA_LOC_CENTER = 2,
    144  AVCHROMA_LOC_TOPLEFT = 3,
    145  AVCHROMA_LOC_TOP = 4,
    146  AVCHROMA_LOC_BOTTOMLEFT = 5,
    147  AVCHROMA_LOC_BOTTOM = 6,
    149  AVCHROMA_LOC_NB
    150 };
    151 
    154  public:
    155  enum ChromaSubsampling {
    156  CHROMA_420_VERTICAL = 0,
    157  CHROMA_420_COLLOCATED_WITH_LUMA = 1,
    158  CHROMA_422 = 2,
    159  CHROMA_444 = 3,
    160  CHROMA_440 = 4,
    161  };
    162  enum ChromaSitingValues {
    163  kUnspecified = 0,
    164  kLeftCollocated = 1,
    165  kTopCollocated = kLeftCollocated,
    166  kHalf = 2,
    167  };
    168 
    171  uint8_t profile,
    172  uint8_t level,
    173  uint8_t bit_depth,
    174  uint8_t chroma_subsampling,
    175  bool video_full_range_flag,
    176  uint8_t color_primaries,
    177  uint8_t transfer_characteristics,
    178  uint8_t matrix_coefficients,
    179  const std::vector<uint8_t>& codec_initialization_data);
    181 
    184  bool ParseMP4(const std::vector<uint8_t>& data);
    185 
    188  bool ParseWebM(const std::vector<uint8_t>& data);
    189 
    191  void SetVP9Level(uint16_t width,
    192  uint16_t height,
    193  double sample_duration_seconds);
    194 
    197  void WriteMP4(std::vector<uint8_t>* data) const;
    198 
    201  void WriteWebM(std::vector<uint8_t>* data) const;
    202 
    204  std::string GetCodecString(Codec codec) const;
    205 
    208  void MergeFrom(const VPCodecConfigurationRecord& other);
    209 
    210  void SetChromaSubsampling(uint8_t subsampling_x, uint8_t subsampling_y);
    211  void SetChromaSubsampling(ChromaSubsampling chroma_subsampling);
    212  void SetChromaLocation(uint8_t chroma_siting_x, uint8_t chroma_siting_y);
    213 
    214  void set_profile(uint8_t profile) { profile_ = profile; }
    215  void set_level(uint8_t level) { level_ = level; }
    216  void set_bit_depth(uint8_t bit_depth) { bit_depth_ = bit_depth; }
    217  void set_video_full_range_flag(bool video_full_range_flag) {
    218  video_full_range_flag_ = video_full_range_flag;
    219  }
    220  void set_color_primaries(uint8_t color_primaries) {
    221  color_primaries_ = color_primaries;
    222  }
    223  void set_transfer_characteristics(uint8_t transfer_characteristics) {
    224  transfer_characteristics_ = transfer_characteristics;
    225  }
    226  void set_matrix_coefficients(uint8_t matrix_coefficients) {
    227  matrix_coefficients_ = matrix_coefficients;
    228  }
    229 
    230  bool is_profile_set() const { return static_cast<bool>(profile_); }
    231  bool is_level_set() const { return static_cast<bool>(level_); }
    232  bool is_bit_depth_set() const { return static_cast<bool>(bit_depth_); }
    233  bool is_chroma_subsampling_set() const {
    234  return static_cast<bool>(chroma_subsampling_);
    235  }
    236  bool is_video_full_range_flag_set() const {
    237  return static_cast<bool>(video_full_range_flag_);
    238  }
    239  bool is_color_primaries_set() const {
    240  return static_cast<bool>(color_primaries_);
    241  }
    242  bool is_transfer_characteristics_set() const {
    243  return static_cast<bool>(transfer_characteristics_);
    244  }
    245  bool is_matrix_coefficients_set() const {
    246  return static_cast<bool>(matrix_coefficients_);
    247  }
    248  bool is_chroma_location_set() const {
    249  return static_cast<bool>(chroma_location_);
    250  }
    251 
    252  uint8_t profile() const { return profile_.value_or(0); }
    253  uint8_t level() const { return level_.value_or(10); }
    254  uint8_t bit_depth() const { return bit_depth_.value_or(8); }
    255  uint8_t chroma_subsampling() const {
    256  return chroma_subsampling_.value_or(CHROMA_420_COLLOCATED_WITH_LUMA);
    257  }
    258  bool video_full_range_flag() const {
    259  return video_full_range_flag_.value_or(false);
    260  }
    261  uint8_t color_primaries() const {
    262  return color_primaries_.value_or(AVCOL_PRI_UNSPECIFIED);
    263  }
    264  uint8_t transfer_characteristics() const {
    265  return transfer_characteristics_.value_or(AVCOL_TRC_UNSPECIFIED);
    266  }
    267  uint8_t matrix_coefficients() const {
    268  return matrix_coefficients_.value_or(AVCOL_SPC_UNSPECIFIED);
    269  }
    270  uint8_t chroma_location() const {
    271  return chroma_location_ ? *chroma_location_ : AVCHROMA_LOC_UNSPECIFIED;
    272  }
    273 
    274  private:
    275  void UpdateChromaSubsamplingIfNeeded();
    276 
    277  base::Optional<uint8_t> profile_;
    278  base::Optional<uint8_t> level_;
    279  base::Optional<uint8_t> bit_depth_;
    280  base::Optional<uint8_t> chroma_subsampling_;
    281  base::Optional<bool> video_full_range_flag_;
    282  base::Optional<uint8_t> color_primaries_;
    283  base::Optional<uint8_t> transfer_characteristics_;
    284  base::Optional<uint8_t> matrix_coefficients_;
    285  std::vector<uint8_t> codec_initialization_data_;
    286 
    287  // Not in the decoder config. It is there to help determine chroma subsampling
    288  // format.
    289  base::Optional<uint8_t> chroma_location_;
    290  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
    291  // generated copy constructor and assignment operator. Since the internal data
    292  // is small, the performance impact is minimal.
    293 };
    294 
    295 } // namespace media
    296 } // namespace shaka
    297 
    298 #endif // PACKAGER_MEDIA_CODECS_VP_CODEC_CONFIGURATION_RECORD_H_
    void WriteWebM(std::vector< uint8_t > *data) const
    -
    Class for parsing or writing VP codec configuration record.
    -
    All the methods that are virtual are virtual for mocking.
    -
    void SetVP9Level(uint16_t width, uint16_t height, double sample_duration_seconds)
    Compute and set VP9 Level based on the input attributes.
    -
    void WriteMP4(std::vector< uint8_t > *data) const
    - -
    bool ParseMP4(const std::vector< uint8_t > &data)
    -
    void MergeFrom(const VPCodecConfigurationRecord &other)
    -
    bool ParseWebM(const std::vector< uint8_t > &data)
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_VP_CODEC_CONFIGURATION_RECORD_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_VP_CODEC_CONFIGURATION_RECORD_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <string>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/macros.h"
    +
    15 #include "packager/base/optional.h"
    +
    16 #include "packager/media/base/video_stream_info.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    +
    23 enum AVColorPrimaries {
    +
    24  AVCOL_PRI_RESERVED0 = 0,
    +
    26  AVCOL_PRI_BT709 = 1,
    +
    27  AVCOL_PRI_UNSPECIFIED = 2,
    +
    28  AVCOL_PRI_RESERVED = 3,
    +
    30  AVCOL_PRI_BT470M = 4,
    +
    32  AVCOL_PRI_BT470BG = 5,
    +
    34  AVCOL_PRI_SMPTE170M = 6,
    +
    36  AVCOL_PRI_SMPTE240M = 7,
    +
    38  AVCOL_PRI_FILM = 8,
    +
    40  AVCOL_PRI_BT2020 = 9,
    +
    42  AVCOL_PRI_SMPTE428 = 10,
    +
    43  AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428,
    +
    45  AVCOL_PRI_SMPTE431 = 11,
    +
    47  AVCOL_PRI_SMPTE432 = 12,
    +
    49  AVCOL_PRI_NB
    +
    50 };
    +
    51 
    +
    53 enum AVColorTransferCharacteristic {
    +
    54  AVCOL_TRC_RESERVED0 = 0,
    +
    56  AVCOL_TRC_BT709 = 1,
    +
    57  AVCOL_TRC_UNSPECIFIED = 2,
    +
    58  AVCOL_TRC_RESERVED = 3,
    +
    60  AVCOL_TRC_GAMMA22 = 4,
    +
    62  AVCOL_TRC_GAMMA28 = 5,
    +
    65  AVCOL_TRC_SMPTE170M = 6,
    +
    66  AVCOL_TRC_SMPTE240M = 7,
    +
    68  AVCOL_TRC_LINEAR = 8,
    +
    70  AVCOL_TRC_LOG = 9,
    +
    72  AVCOL_TRC_LOG_SQRT = 10,
    +
    74  AVCOL_TRC_IEC61966_2_4 = 11,
    +
    76  AVCOL_TRC_BT1361_ECG = 12,
    +
    78  AVCOL_TRC_IEC61966_2_1 = 13,
    +
    80  AVCOL_TRC_BT2020_10 = 14,
    +
    82  AVCOL_TRC_BT2020_12 = 15,
    +
    84  AVCOL_TRC_SMPTE2084 = 16,
    +
    85  AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084,
    +
    87  AVCOL_TRC_SMPTE428 = 17,
    +
    88  AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428,
    +
    90  AVCOL_TRC_ARIB_STD_B67 = 18,
    +
    92  AVCOL_TRC_NB
    +
    93 };
    +
    94 
    +
    96 enum AVColorSpace {
    +
    98  AVCOL_SPC_RGB = 0,
    +
    100  AVCOL_SPC_BT709 = 1,
    +
    101  AVCOL_SPC_UNSPECIFIED = 2,
    +
    102  AVCOL_SPC_RESERVED = 3,
    +
    104  AVCOL_SPC_FCC = 4,
    +
    107  AVCOL_SPC_BT470BG = 5,
    +
    109  AVCOL_SPC_SMPTE170M = 6,
    +
    111  AVCOL_SPC_SMPTE240M = 7,
    +
    113  AVCOL_SPC_YCOCG = 8,
    +
    115  AVCOL_SPC_BT2020_NCL = 9,
    +
    117  AVCOL_SPC_BT2020_CL = 10,
    +
    119  AVCOL_SPC_SMPTE2085 = 11,
    +
    121  AVCOL_SPC_NB
    +
    122 };
    +
    123 
    +
    137 enum AVChromaLocation {
    +
    138  AVCHROMA_LOC_UNSPECIFIED = 0,
    +
    140  AVCHROMA_LOC_LEFT = 1,
    +
    142  AVCHROMA_LOC_CENTER = 2,
    +
    144  AVCHROMA_LOC_TOPLEFT = 3,
    +
    145  AVCHROMA_LOC_TOP = 4,
    +
    146  AVCHROMA_LOC_BOTTOMLEFT = 5,
    +
    147  AVCHROMA_LOC_BOTTOM = 6,
    +
    149  AVCHROMA_LOC_NB
    +
    150 };
    +
    151 
    + +
    154  public:
    +
    155  enum ChromaSubsampling {
    +
    156  CHROMA_420_VERTICAL = 0,
    +
    157  CHROMA_420_COLLOCATED_WITH_LUMA = 1,
    +
    158  CHROMA_422 = 2,
    +
    159  CHROMA_444 = 3,
    +
    160  CHROMA_440 = 4,
    +
    161  };
    +
    162  enum ChromaSitingValues {
    +
    163  kUnspecified = 0,
    +
    164  kLeftCollocated = 1,
    +
    165  kTopCollocated = kLeftCollocated,
    +
    166  kHalf = 2,
    +
    167  };
    +
    168 
    + + +
    171  uint8_t profile,
    +
    172  uint8_t level,
    +
    173  uint8_t bit_depth,
    +
    174  uint8_t chroma_subsampling,
    +
    175  bool video_full_range_flag,
    +
    176  uint8_t color_primaries,
    +
    177  uint8_t transfer_characteristics,
    +
    178  uint8_t matrix_coefficients,
    +
    179  const std::vector<uint8_t>& codec_initialization_data);
    + +
    181 
    +
    184  bool ParseMP4(const std::vector<uint8_t>& data);
    +
    185 
    +
    188  bool ParseWebM(const std::vector<uint8_t>& data);
    +
    189 
    +
    191  void SetVP9Level(uint16_t width,
    +
    192  uint16_t height,
    +
    193  double sample_duration_seconds);
    +
    194 
    +
    197  void WriteMP4(std::vector<uint8_t>* data) const;
    +
    198 
    +
    201  void WriteWebM(std::vector<uint8_t>* data) const;
    +
    202 
    +
    204  std::string GetCodecString(Codec codec) const;
    +
    205 
    +
    208  void MergeFrom(const VPCodecConfigurationRecord& other);
    +
    209 
    +
    210  void SetChromaSubsampling(uint8_t subsampling_x, uint8_t subsampling_y);
    +
    211  void SetChromaSubsampling(ChromaSubsampling chroma_subsampling);
    +
    212  void SetChromaLocation(uint8_t chroma_siting_x, uint8_t chroma_siting_y);
    +
    213 
    +
    214  void set_profile(uint8_t profile) { profile_ = profile; }
    +
    215  void set_level(uint8_t level) { level_ = level; }
    +
    216  void set_bit_depth(uint8_t bit_depth) { bit_depth_ = bit_depth; }
    +
    217  void set_video_full_range_flag(bool video_full_range_flag) {
    +
    218  video_full_range_flag_ = video_full_range_flag;
    +
    219  }
    +
    220  void set_color_primaries(uint8_t color_primaries) {
    +
    221  color_primaries_ = color_primaries;
    +
    222  }
    +
    223  void set_transfer_characteristics(uint8_t transfer_characteristics) {
    +
    224  transfer_characteristics_ = transfer_characteristics;
    +
    225  }
    +
    226  void set_matrix_coefficients(uint8_t matrix_coefficients) {
    +
    227  matrix_coefficients_ = matrix_coefficients;
    +
    228  }
    +
    229 
    +
    230  bool is_profile_set() const { return static_cast<bool>(profile_); }
    +
    231  bool is_level_set() const { return static_cast<bool>(level_); }
    +
    232  bool is_bit_depth_set() const { return static_cast<bool>(bit_depth_); }
    +
    233  bool is_chroma_subsampling_set() const {
    +
    234  return static_cast<bool>(chroma_subsampling_);
    +
    235  }
    +
    236  bool is_video_full_range_flag_set() const {
    +
    237  return static_cast<bool>(video_full_range_flag_);
    +
    238  }
    +
    239  bool is_color_primaries_set() const {
    +
    240  return static_cast<bool>(color_primaries_);
    +
    241  }
    +
    242  bool is_transfer_characteristics_set() const {
    +
    243  return static_cast<bool>(transfer_characteristics_);
    +
    244  }
    +
    245  bool is_matrix_coefficients_set() const {
    +
    246  return static_cast<bool>(matrix_coefficients_);
    +
    247  }
    +
    248  bool is_chroma_location_set() const {
    +
    249  return static_cast<bool>(chroma_location_);
    +
    250  }
    +
    251 
    +
    252  uint8_t profile() const { return profile_.value_or(0); }
    +
    253  uint8_t level() const { return level_.value_or(10); }
    +
    254  uint8_t bit_depth() const { return bit_depth_.value_or(8); }
    +
    255  uint8_t chroma_subsampling() const {
    +
    256  return chroma_subsampling_.value_or(CHROMA_420_COLLOCATED_WITH_LUMA);
    +
    257  }
    +
    258  bool video_full_range_flag() const {
    +
    259  return video_full_range_flag_.value_or(false);
    +
    260  }
    +
    261  uint8_t color_primaries() const {
    +
    262  return color_primaries_.value_or(AVCOL_PRI_UNSPECIFIED);
    +
    263  }
    +
    264  uint8_t transfer_characteristics() const {
    +
    265  return transfer_characteristics_.value_or(AVCOL_TRC_UNSPECIFIED);
    +
    266  }
    +
    267  uint8_t matrix_coefficients() const {
    +
    268  return matrix_coefficients_.value_or(AVCOL_SPC_UNSPECIFIED);
    +
    269  }
    +
    270  uint8_t chroma_location() const {
    +
    271  return chroma_location_ ? *chroma_location_ : AVCHROMA_LOC_UNSPECIFIED;
    +
    272  }
    +
    273 
    +
    274  private:
    +
    275  void UpdateChromaSubsamplingIfNeeded();
    +
    276 
    +
    277  base::Optional<uint8_t> profile_;
    +
    278  base::Optional<uint8_t> level_;
    +
    279  base::Optional<uint8_t> bit_depth_;
    +
    280  base::Optional<uint8_t> chroma_subsampling_;
    +
    281  base::Optional<bool> video_full_range_flag_;
    +
    282  base::Optional<uint8_t> color_primaries_;
    +
    283  base::Optional<uint8_t> transfer_characteristics_;
    +
    284  base::Optional<uint8_t> matrix_coefficients_;
    +
    285  std::vector<uint8_t> codec_initialization_data_;
    +
    286 
    +
    287  // Not in the decoder config. It is there to help determine chroma subsampling
    +
    288  // format.
    +
    289  base::Optional<uint8_t> chroma_location_;
    +
    290  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
    +
    291  // generated copy constructor and assignment operator. Since the internal data
    +
    292  // is small, the performance impact is minimal.
    +
    293 };
    +
    294 
    +
    295 } // namespace media
    +
    296 } // namespace shaka
    +
    297 
    +
    298 #endif // PACKAGER_MEDIA_CODECS_VP_CODEC_CONFIGURATION_RECORD_H_
    +
    Class for parsing or writing VP codec configuration record.
    +
    void WriteMP4(std::vector< uint8_t > *data) const
    +
    void SetVP9Level(uint16_t width, uint16_t height, double sample_duration_seconds)
    Compute and set VP9 Level based on the input attributes.
    +
    void MergeFrom(const VPCodecConfigurationRecord &other)
    +
    bool ParseWebM(const std::vector< uint8_t > &data)
    + +
    void WriteWebM(std::vector< uint8_t > *data) const
    +
    bool ParseMP4(const std::vector< uint8_t > &data)
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d9d/structshaka_1_1media_1_1H265ReferencePictureListModifications.html b/docs/d5/d9d/structshaka_1_1media_1_1H265ReferencePictureListModifications.html index 3faff67f69..0189792a5c 100644 --- a/docs/d5/d9d/structshaka_1_1media_1_1H265ReferencePictureListModifications.html +++ b/docs/d5/d9d/structshaka_1_1media_1_1H265ReferencePictureListModifications.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265ReferencePictureListModifications Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    l
    diff --git a/docs/d5/da4/aes__encryptor_8cc_source.html b/docs/d5/da4/aes__encryptor_8cc_source.html index 2903a52a9d..4225e74469 100644 --- a/docs/d5/da4/aes__encryptor_8cc_source.html +++ b/docs/d5/da4/aes__encryptor_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/aes_encryptor.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    aes_encryptor.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/aes_encryptor.h"
    8 
    9 #include <openssl/aes.h>
    10 
    11 #include "packager/base/logging.h"
    12 
    13 namespace {
    14 
    15 // Increment an 8-byte counter by 1. Return true if overflowed.
    16 bool Increment64(uint8_t* counter) {
    17  DCHECK(counter);
    18  for (int i = 7; i >= 0; --i) {
    19  if (++counter[i] != 0)
    20  return false;
    21  }
    22  return true;
    23 }
    24 
    25 // AES defines three key sizes: 128, 192 and 256 bits.
    26 bool IsKeySizeValidForAes(size_t key_size) {
    27  return key_size == 16 || key_size == 24 || key_size == 32;
    28 }
    29 
    30 } // namespace
    31 
    32 namespace shaka {
    33 namespace media {
    34 
    35 AesEncryptor::AesEncryptor(ConstantIvFlag constant_iv_flag)
    36  : AesCryptor(constant_iv_flag) {}
    37 AesEncryptor::~AesEncryptor() {}
    38 
    39 bool AesEncryptor::InitializeWithIv(const std::vector<uint8_t>& key,
    40  const std::vector<uint8_t>& iv) {
    41  if (!IsKeySizeValidForAes(key.size())) {
    42  LOG(ERROR) << "Invalid AES key size: " << key.size();
    43  return false;
    44  }
    45 
    46  CHECK_EQ(AES_set_encrypt_key(key.data(), key.size() * 8, mutable_aes_key()),
    47  0);
    48  return SetIv(iv);
    49 }
    50 
    51 // We don't support constant iv for counter mode, as we don't have a use case
    52 // for that.
    53 AesCtrEncryptor::AesCtrEncryptor()
    54  : AesEncryptor(kDontUseConstantIv),
    55  block_offset_(0),
    56  encrypted_counter_(AES_BLOCK_SIZE, 0) {}
    57 
    58 AesCtrEncryptor::~AesCtrEncryptor() {}
    59 
    60 
    61 bool AesCtrEncryptor::CryptInternal(const uint8_t* plaintext,
    62  size_t plaintext_size,
    63  uint8_t* ciphertext,
    64  size_t* ciphertext_size) {
    65  DCHECK(plaintext);
    66  DCHECK(ciphertext);
    67  DCHECK(aes_key());
    68 
    69  // |ciphertext_size| is always the same as |plaintext_size| for counter mode.
    70  if (*ciphertext_size < plaintext_size) {
    71  LOG(ERROR) << "Expecting output size of at least " << plaintext_size
    72  << " bytes.";
    73  return false;
    74  }
    75  *ciphertext_size = plaintext_size;
    76 
    77  for (size_t i = 0; i < plaintext_size; ++i) {
    78  if (block_offset_ == 0) {
    79  AES_encrypt(&counter_[0], &encrypted_counter_[0], aes_key());
    80  // As mentioned in ISO/IEC 23001-7:2016 CENC spec, of the 16 byte counter
    81  // block, bytes 8 to 15 (i.e. the least significant bytes) are used as a
    82  // simple 64 bit unsigned integer that is incremented by one for each
    83  // subsequent block of sample data processed and is kept in network byte
    84  // order.
    85  Increment64(&counter_[8]);
    86  }
    87  ciphertext[i] = plaintext[i] ^ encrypted_counter_[block_offset_];
    88  block_offset_ = (block_offset_ + 1) % AES_BLOCK_SIZE;
    89  }
    90  return true;
    91 }
    92 
    93 void AesCtrEncryptor::SetIvInternal() {
    94  block_offset_ = 0;
    95  counter_ = iv();
    96  counter_.resize(AES_BLOCK_SIZE, 0);
    97 }
    98 
    99 AesCbcEncryptor::AesCbcEncryptor(CbcPaddingScheme padding_scheme)
    100  : AesCbcEncryptor(padding_scheme, kDontUseConstantIv) {}
    101 
    102 AesCbcEncryptor::AesCbcEncryptor(CbcPaddingScheme padding_scheme,
    103  ConstantIvFlag constant_iv_flag)
    104  : AesEncryptor(constant_iv_flag), padding_scheme_(padding_scheme) {
    105  if (padding_scheme_ != kNoPadding) {
    106  CHECK_EQ(constant_iv_flag, kUseConstantIv)
    107  << "non-constant iv (cipher block chain across calls) only makes sense "
    108  "if the padding_scheme is kNoPadding.";
    109  }
    110 }
    111 
    112 AesCbcEncryptor::~AesCbcEncryptor() {}
    113 
    114 bool AesCbcEncryptor::CryptInternal(const uint8_t* plaintext,
    115  size_t plaintext_size,
    116  uint8_t* ciphertext,
    117  size_t* ciphertext_size) {
    118  DCHECK(aes_key());
    119 
    120  const size_t residual_block_size = plaintext_size % AES_BLOCK_SIZE;
    121  const size_t num_padding_bytes = NumPaddingBytes(plaintext_size);
    122  const size_t required_ciphertext_size = plaintext_size + num_padding_bytes;
    123  if (*ciphertext_size < required_ciphertext_size) {
    124  LOG(ERROR) << "Expecting output size of at least "
    125  << required_ciphertext_size << " bytes.";
    126  return false;
    127  }
    128  *ciphertext_size = required_ciphertext_size;
    129 
    130  // Encrypt everything but the residual block using CBC.
    131  const size_t cbc_size = plaintext_size - residual_block_size;
    132  if (cbc_size != 0) {
    133  AES_cbc_encrypt(plaintext, ciphertext, cbc_size, aes_key(),
    134  internal_iv_.data(), AES_ENCRYPT);
    135  } else if (padding_scheme_ == kCtsPadding) {
    136  // Don't have a full block, leave unencrypted.
    137  memcpy(ciphertext, plaintext, plaintext_size);
    138  return true;
    139  }
    140  if (residual_block_size == 0 && padding_scheme_ != kPkcs5Padding) {
    141  // No residual block. No need to do padding.
    142  return true;
    143  }
    144 
    145  if (padding_scheme_ == kNoPadding) {
    146  // The residual block is left unencrypted.
    147  memcpy(ciphertext + cbc_size, plaintext + cbc_size, residual_block_size);
    148  return true;
    149  }
    150 
    151  std::vector<uint8_t> residual_block(plaintext + cbc_size,
    152  plaintext + plaintext_size);
    153  DCHECK_EQ(residual_block.size(), residual_block_size);
    154  uint8_t* residual_ciphertext_block = ciphertext + cbc_size;
    155 
    156  if (padding_scheme_ == kPkcs5Padding) {
    157  DCHECK_EQ(num_padding_bytes, AES_BLOCK_SIZE - residual_block_size);
    158 
    159  // Pad residue block with PKCS5 padding.
    160  residual_block.resize(AES_BLOCK_SIZE, static_cast<char>(num_padding_bytes));
    161  AES_cbc_encrypt(residual_block.data(), residual_ciphertext_block,
    162  AES_BLOCK_SIZE, aes_key(), internal_iv_.data(),
    163  AES_ENCRYPT);
    164  } else {
    165  DCHECK_EQ(num_padding_bytes, 0u);
    166  DCHECK_EQ(padding_scheme_, kCtsPadding);
    167 
    168  // Zero-pad the residual block and encrypt using CBC.
    169  residual_block.resize(AES_BLOCK_SIZE, 0);
    170  AES_cbc_encrypt(residual_block.data(), residual_block.data(),
    171  AES_BLOCK_SIZE, aes_key(), internal_iv_.data(),
    172  AES_ENCRYPT);
    173 
    174  // Replace the last full block with the zero-padded, encrypted residual
    175  // block, and replace the residual block with the equivalent portion of the
    176  // last full encrypted block. It may appear that some encrypted bits of the
    177  // last full block are lost, but they are not, as they were used as the IV
    178  // when encrypting the zero-padded residual block.
    179  memcpy(residual_ciphertext_block,
    180  residual_ciphertext_block - AES_BLOCK_SIZE, residual_block_size);
    181  memcpy(residual_ciphertext_block - AES_BLOCK_SIZE, residual_block.data(),
    182  AES_BLOCK_SIZE);
    183  }
    184  return true;
    185 }
    186 
    187 void AesCbcEncryptor::SetIvInternal() {
    188  internal_iv_ = iv();
    189  internal_iv_.resize(AES_BLOCK_SIZE, 0);
    190 }
    191 
    192 size_t AesCbcEncryptor::NumPaddingBytes(size_t size) const {
    193  return (padding_scheme_ == kPkcs5Padding)
    194  ? (AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE))
    195  : 0;
    196 }
    197 
    198 } // namespace media
    199 } // namespace shaka
    -
    AesCbcEncryptor(CbcPaddingScheme padding_scheme)
    -
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    -
    All the methods that are virtual are virtual for mocking.
    -
    AesEncryptor(ConstantIvFlag constant_iv_flag)
    - -
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    -
    bool SetIv(const std::vector< uint8_t > &iv)
    Definition: aes_cryptor.cc:70
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/aes_encryptor.h"
    +
    8 
    +
    9 #include <openssl/aes.h>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 
    +
    13 namespace {
    +
    14 
    +
    15 // Increment an 8-byte counter by 1. Return true if overflowed.
    +
    16 bool Increment64(uint8_t* counter) {
    +
    17  DCHECK(counter);
    +
    18  for (int i = 7; i >= 0; --i) {
    +
    19  if (++counter[i] != 0)
    +
    20  return false;
    +
    21  }
    +
    22  return true;
    +
    23 }
    +
    24 
    +
    25 // AES defines three key sizes: 128, 192 and 256 bits.
    +
    26 bool IsKeySizeValidForAes(size_t key_size) {
    +
    27  return key_size == 16 || key_size == 24 || key_size == 32;
    +
    28 }
    +
    29 
    +
    30 } // namespace
    +
    31 
    +
    32 namespace shaka {
    +
    33 namespace media {
    +
    34 
    +
    35 AesEncryptor::AesEncryptor(ConstantIvFlag constant_iv_flag)
    +
    36  : AesCryptor(constant_iv_flag) {}
    +
    37 AesEncryptor::~AesEncryptor() {}
    +
    38 
    +
    39 bool AesEncryptor::InitializeWithIv(const std::vector<uint8_t>& key,
    +
    40  const std::vector<uint8_t>& iv) {
    +
    41  if (!IsKeySizeValidForAes(key.size())) {
    +
    42  LOG(ERROR) << "Invalid AES key size: " << key.size();
    +
    43  return false;
    +
    44  }
    +
    45 
    +
    46  CHECK_EQ(AES_set_encrypt_key(key.data(), key.size() * 8, mutable_aes_key()),
    +
    47  0);
    +
    48  return SetIv(iv);
    +
    49 }
    +
    50 
    +
    51 // We don't support constant iv for counter mode, as we don't have a use case
    +
    52 // for that.
    +
    53 AesCtrEncryptor::AesCtrEncryptor()
    +
    54  : AesEncryptor(kDontUseConstantIv),
    +
    55  block_offset_(0),
    +
    56  encrypted_counter_(AES_BLOCK_SIZE, 0) {}
    +
    57 
    +
    58 AesCtrEncryptor::~AesCtrEncryptor() {}
    +
    59 
    +
    60 
    +
    61 bool AesCtrEncryptor::CryptInternal(const uint8_t* plaintext,
    +
    62  size_t plaintext_size,
    +
    63  uint8_t* ciphertext,
    +
    64  size_t* ciphertext_size) {
    +
    65  DCHECK(plaintext);
    +
    66  DCHECK(ciphertext);
    +
    67  DCHECK(aes_key());
    +
    68 
    +
    69  // |ciphertext_size| is always the same as |plaintext_size| for counter mode.
    +
    70  if (*ciphertext_size < plaintext_size) {
    +
    71  LOG(ERROR) << "Expecting output size of at least " << plaintext_size
    +
    72  << " bytes.";
    +
    73  return false;
    +
    74  }
    +
    75  *ciphertext_size = plaintext_size;
    +
    76 
    +
    77  for (size_t i = 0; i < plaintext_size; ++i) {
    +
    78  if (block_offset_ == 0) {
    +
    79  AES_encrypt(&counter_[0], &encrypted_counter_[0], aes_key());
    +
    80  // As mentioned in ISO/IEC 23001-7:2016 CENC spec, of the 16 byte counter
    +
    81  // block, bytes 8 to 15 (i.e. the least significant bytes) are used as a
    +
    82  // simple 64 bit unsigned integer that is incremented by one for each
    +
    83  // subsequent block of sample data processed and is kept in network byte
    +
    84  // order.
    +
    85  Increment64(&counter_[8]);
    +
    86  }
    +
    87  ciphertext[i] = plaintext[i] ^ encrypted_counter_[block_offset_];
    +
    88  block_offset_ = (block_offset_ + 1) % AES_BLOCK_SIZE;
    +
    89  }
    +
    90  return true;
    +
    91 }
    +
    92 
    +
    93 void AesCtrEncryptor::SetIvInternal() {
    +
    94  block_offset_ = 0;
    +
    95  counter_ = iv();
    +
    96  counter_.resize(AES_BLOCK_SIZE, 0);
    +
    97 }
    +
    98 
    +
    99 AesCbcEncryptor::AesCbcEncryptor(CbcPaddingScheme padding_scheme)
    +
    100  : AesCbcEncryptor(padding_scheme, kDontUseConstantIv) {}
    +
    101 
    +
    102 AesCbcEncryptor::AesCbcEncryptor(CbcPaddingScheme padding_scheme,
    +
    103  ConstantIvFlag constant_iv_flag)
    +
    104  : AesEncryptor(constant_iv_flag), padding_scheme_(padding_scheme) {
    +
    105  if (padding_scheme_ != kNoPadding) {
    +
    106  CHECK_EQ(constant_iv_flag, kUseConstantIv)
    +
    107  << "non-constant iv (cipher block chain across calls) only makes sense "
    +
    108  "if the padding_scheme is kNoPadding.";
    +
    109  }
    +
    110 }
    +
    111 
    +
    112 AesCbcEncryptor::~AesCbcEncryptor() {}
    +
    113 
    +
    114 bool AesCbcEncryptor::CryptInternal(const uint8_t* plaintext,
    +
    115  size_t plaintext_size,
    +
    116  uint8_t* ciphertext,
    +
    117  size_t* ciphertext_size) {
    +
    118  DCHECK(aes_key());
    +
    119 
    +
    120  const size_t residual_block_size = plaintext_size % AES_BLOCK_SIZE;
    +
    121  const size_t num_padding_bytes = NumPaddingBytes(plaintext_size);
    +
    122  const size_t required_ciphertext_size = plaintext_size + num_padding_bytes;
    +
    123  if (*ciphertext_size < required_ciphertext_size) {
    +
    124  LOG(ERROR) << "Expecting output size of at least "
    +
    125  << required_ciphertext_size << " bytes.";
    +
    126  return false;
    +
    127  }
    +
    128  *ciphertext_size = required_ciphertext_size;
    +
    129 
    +
    130  // Encrypt everything but the residual block using CBC.
    +
    131  const size_t cbc_size = plaintext_size - residual_block_size;
    +
    132  if (cbc_size != 0) {
    +
    133  AES_cbc_encrypt(plaintext, ciphertext, cbc_size, aes_key(),
    +
    134  internal_iv_.data(), AES_ENCRYPT);
    +
    135  } else if (padding_scheme_ == kCtsPadding) {
    +
    136  // Don't have a full block, leave unencrypted.
    +
    137  memcpy(ciphertext, plaintext, plaintext_size);
    +
    138  return true;
    +
    139  }
    +
    140  if (residual_block_size == 0 && padding_scheme_ != kPkcs5Padding) {
    +
    141  // No residual block. No need to do padding.
    +
    142  return true;
    +
    143  }
    +
    144 
    +
    145  if (padding_scheme_ == kNoPadding) {
    +
    146  // The residual block is left unencrypted.
    +
    147  memcpy(ciphertext + cbc_size, plaintext + cbc_size, residual_block_size);
    +
    148  return true;
    +
    149  }
    +
    150 
    +
    151  std::vector<uint8_t> residual_block(plaintext + cbc_size,
    +
    152  plaintext + plaintext_size);
    +
    153  DCHECK_EQ(residual_block.size(), residual_block_size);
    +
    154  uint8_t* residual_ciphertext_block = ciphertext + cbc_size;
    +
    155 
    +
    156  if (padding_scheme_ == kPkcs5Padding) {
    +
    157  DCHECK_EQ(num_padding_bytes, AES_BLOCK_SIZE - residual_block_size);
    +
    158 
    +
    159  // Pad residue block with PKCS5 padding.
    +
    160  residual_block.resize(AES_BLOCK_SIZE, static_cast<char>(num_padding_bytes));
    +
    161  AES_cbc_encrypt(residual_block.data(), residual_ciphertext_block,
    +
    162  AES_BLOCK_SIZE, aes_key(), internal_iv_.data(),
    +
    163  AES_ENCRYPT);
    +
    164  } else {
    +
    165  DCHECK_EQ(num_padding_bytes, 0u);
    +
    166  DCHECK_EQ(padding_scheme_, kCtsPadding);
    +
    167 
    +
    168  // Zero-pad the residual block and encrypt using CBC.
    +
    169  residual_block.resize(AES_BLOCK_SIZE, 0);
    +
    170  AES_cbc_encrypt(residual_block.data(), residual_block.data(),
    +
    171  AES_BLOCK_SIZE, aes_key(), internal_iv_.data(),
    +
    172  AES_ENCRYPT);
    +
    173 
    +
    174  // Replace the last full block with the zero-padded, encrypted residual
    +
    175  // block, and replace the residual block with the equivalent portion of the
    +
    176  // last full encrypted block. It may appear that some encrypted bits of the
    +
    177  // last full block are lost, but they are not, as they were used as the IV
    +
    178  // when encrypting the zero-padded residual block.
    +
    179  memcpy(residual_ciphertext_block,
    +
    180  residual_ciphertext_block - AES_BLOCK_SIZE, residual_block_size);
    +
    181  memcpy(residual_ciphertext_block - AES_BLOCK_SIZE, residual_block.data(),
    +
    182  AES_BLOCK_SIZE);
    +
    183  }
    +
    184  return true;
    +
    185 }
    +
    186 
    +
    187 void AesCbcEncryptor::SetIvInternal() {
    +
    188  internal_iv_ = iv();
    +
    189  internal_iv_.resize(AES_BLOCK_SIZE, 0);
    +
    190 }
    +
    191 
    +
    192 size_t AesCbcEncryptor::NumPaddingBytes(size_t size) const {
    +
    193  return (padding_scheme_ == kPkcs5Padding)
    +
    194  ? (AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE))
    +
    195  : 0;
    +
    196 }
    +
    197 
    +
    198 } // namespace media
    +
    199 } // namespace shaka
    + +
    AesCbcEncryptor(CbcPaddingScheme padding_scheme)
    + +
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    +
    bool SetIv(const std::vector< uint8_t > &iv)
    Definition: aes_cryptor.cc:70
    + +
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    +
    AesEncryptor(ConstantIvFlag constant_iv_flag)
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/dad/structshaka_1_1media_1_1H265ReferencePictureSet.html b/docs/d5/dad/structshaka_1_1media_1_1H265ReferencePictureSet.html index 0eb4a6dfa3..8a40fedc2a 100644 --- a/docs/d5/dad/structshaka_1_1media_1_1H265ReferencePictureSet.html +++ b/docs/d5/dad/structshaka_1_1media_1_1H265ReferencePictureSet.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265ReferencePictureSet Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    num_delta_pocs diff --git a/docs/d5/db1/classshaka_1_1media_1_1StreamInfo.html b/docs/d5/db1/classshaka_1_1media_1_1StreamInfo.html index 3b71bd09c9..bb4f0a9cd1 100644 --- a/docs/d5/db1/classshaka_1_1media_1_1StreamInfo.html +++ b/docs/d5/db1/classshaka_1_1media_1_1StreamInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::StreamInfo Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::media::AudioStreamInfo +shaka::media::AudioStreamInfo shaka::media::TextStreamInfo -shaka::media::VideoStreamInfo - -
    +shaka::media::VideoStreamInfo + + @@ -158,7 +161,7 @@ void 

    Public Member Functions

    set_encryption_config

    Detailed Description

    Abstract class holds stream information.

    -

    Definition at line 62 of file stream_info.h.

    +

    Definition at line 65 of file stream_info.h.

    Member Function Documentation

    ◆ Clone()

    @@ -240,9 +243,9 @@ void 
    set_encryption_config
    Returns
    A human-readable string describing the stream info.
    -

    Reimplemented in shaka::media::VideoStreamInfo, and shaka::media::AudioStreamInfo.

    +

    Reimplemented in shaka::media::VideoStreamInfo, shaka::media::TextStreamInfo, and shaka::media::AudioStreamInfo.

    -

    Definition at line 58 of file stream_info.cc.

    +

    Definition at line 59 of file stream_info.cc.

    @@ -253,9 +256,7 @@ void 
    set_encryption_config diff --git a/docs/d5/db8/text__muxer_8cc_source.html b/docs/d5/db8/text__muxer_8cc_source.html new file mode 100644 index 0000000000..8a4fb02c50 --- /dev/null +++ b/docs/d5/db8/text__muxer_8cc_source.html @@ -0,0 +1,172 @@ + + + + + + + +Shaka Packager SDK: packager/media/base/text_muxer.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    text_muxer.cc
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/text_muxer.h"
    +
    8 
    +
    9 #include "packager/media/base/muxer_util.h"
    +
    10 #include "packager/status_macros.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    15 TextMuxer::TextMuxer(const MuxerOptions& options) : Muxer(options) {}
    +
    16 TextMuxer::~TextMuxer() {}
    +
    17 
    +
    18 Status TextMuxer::InitializeMuxer() {
    +
    19  if (streams().size() != 1 || streams()[0]->stream_type() != kStreamText) {
    +
    20  return Status(error::MUXER_FAILURE,
    +
    21  "Incorrect streams given to WebVTT muxer");
    +
    22  }
    +
    23 
    +
    24  auto copy = streams()[0]->Clone();
    +
    25  RETURN_IF_ERROR(InitializeStream(static_cast<TextStreamInfo*>(copy.get())));
    +
    26 
    +
    27  muxer_listener()->OnMediaStart(options(), *copy, copy->time_scale(),
    +
    28  MuxerListener::kContainerText);
    +
    29 
    +
    30  last_cue_ms_ = 0;
    +
    31  return Status::OK;
    +
    32 }
    +
    33 
    +
    34 Status TextMuxer::Finalize() {
    +
    35  const float duration_ms = static_cast<float>(total_duration_ms_);
    +
    36  float duration_seconds = duration_ms / 1000;
    +
    37 
    +
    38  // If we haven't seen any segments, this is a single-file. In this case,
    +
    39  // flush the single segment.
    +
    40  MuxerListener::MediaRanges ranges;
    +
    41  if (duration_seconds == 0 && last_cue_ms_ != 0) {
    +
    42  DCHECK(options().segment_template.empty());
    +
    43  duration_seconds = static_cast<float>(last_cue_ms_) / 1000;
    +
    44 
    +
    45  uint64_t size;
    +
    46  RETURN_IF_ERROR(WriteToFile(options().output_file_name, &size));
    +
    47  // Insert a dummy value so the HLS generator will generate a segment list.
    +
    48  ranges.subsegment_ranges.emplace_back();
    +
    49 
    +
    50  muxer_listener()->OnNewSegment(
    +
    51  options().output_file_name, 0,
    +
    52  duration_seconds * streams()[0]->time_scale(), size);
    +
    53  }
    +
    54 
    +
    55  muxer_listener()->OnMediaEnd(ranges, duration_seconds);
    +
    56 
    +
    57  return Status::OK;
    +
    58 }
    +
    59 
    +
    60 Status TextMuxer::AddTextSample(size_t stream_id, const TextSample& sample) {
    +
    61  // Ignore sync samples.
    +
    62  if (sample.body().is_empty()) {
    +
    63  return Status::OK;
    +
    64  }
    +
    65 
    +
    66  RETURN_IF_ERROR(AddTextSampleInternal(sample));
    +
    67 
    +
    68  last_cue_ms_ = sample.EndTime();
    +
    69  return Status::OK;
    +
    70 }
    +
    71 
    +
    72 Status TextMuxer::FinalizeSegment(size_t stream_id,
    +
    73  const SegmentInfo& segment_info) {
    +
    74  total_duration_ms_ += segment_info.duration;
    +
    75 
    +
    76  const std::string& segment_template = options().segment_template;
    +
    77  DCHECK(!segment_template.empty());
    +
    78  const uint32_t index = segment_index_++;
    +
    79  const uint64_t start = segment_info.start_timestamp;
    +
    80  const uint64_t duration = segment_info.duration;
    +
    81  const uint32_t bandwidth = options().bandwidth;
    +
    82 
    +
    83  const std::string filename =
    +
    84  GetSegmentName(segment_template, start, index, bandwidth);
    +
    85  uint64_t size;
    +
    86  RETURN_IF_ERROR(WriteToFile(filename, &size));
    +
    87 
    +
    88  muxer_listener()->OnNewSegment(filename, start, duration, size);
    +
    89  return Status::OK;
    +
    90 }
    +
    91 
    +
    92 } // namespace media
    +
    93 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/d5/db9/classshaka_1_1media_1_1mp2t_1_1EsParserH264.html b/docs/d5/db9/classshaka_1_1media_1_1mp2t_1_1EsParserH264.html index 81662b6129..57ff34cc0a 100644 --- a/docs/d5/db9/classshaka_1_1media_1_1mp2t_1_1EsParserH264.html +++ b/docs/d5/db9/classshaka_1_1media_1_1mp2t_1_1EsParserH264.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::EsParserH264 Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp2t::EsParserH26x shaka::media::mp2t::EsParser - -
    + + @@ -95,9 +98,9 @@ void  - - + + @@ -112,12 +115,15 @@ uint32_t  - - - - + + + + + + @@ -133,9 +139,7 @@ const diff --git a/docs/d5/dba/ts__packet_8cc_source.html b/docs/d5/dba/ts__packet_8cc_source.html index 00fd98cf17..93163762cd 100644 --- a/docs/d5/dba/ts__packet_8cc_source.html +++ b/docs/d5/dba/ts__packet_8cc_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/formats/mp2t/ts_packet.cc Source File @@ -29,18 +29,21 @@

    Public Member Functions

    Reset () override
    bool Parse (const uint8_t *buf, int size, int64_t pts, int64_t dts) override
     
    -void Flush () override
     
    +bool Flush () override
     
    void Reset () override
     
    pid ()

    Additional Inherited Members

    - Public Types inherited from shaka::media::mp2t::EsParser
    -typedef base::Callback< void(const std::shared_ptr< StreamInfo > &)> NewStreamInfoCB
     
    -typedef base::Callback< void(uint32_t, const std::shared_ptr< MediaSample > &)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< StreamInfo >)> NewStreamInfoCB
     
    +typedef base::Callback< void(std::shared_ptr< MediaSample >)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< TextSample >)> EmitTextSampleCB
     
    - Protected Member Functions inherited from shaka::media::mp2t::EsParserH26x
    const H26xByteToUnitStreamConverterstream_converter () const
    - + +/* @license-end */
    ts_packet.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/mp2t/ts_packet.h"
    6 
    7 #include <memory>
    8 #include "packager/media/base/bit_reader.h"
    9 #include "packager/media/formats/mp2t/mp2t_common.h"
    10 
    11 namespace shaka {
    12 namespace media {
    13 namespace mp2t {
    14 
    15 static const uint8_t kTsHeaderSyncword = 0x47;
    16 
    17 // static
    18 int TsPacket::Sync(const uint8_t* buf, int size) {
    19  int k = 0;
    20  for (; k < size; k++) {
    21  // Verify that we have 4 syncwords in a row when possible,
    22  // this should improve synchronization robustness.
    23  bool is_header = true;
    24  for (int i = 0; i < 4; i++) {
    25  int idx = k + i * kPacketSize;
    26  if (idx >= size)
    27  break;
    28  if (buf[idx] != kTsHeaderSyncword) {
    29  DVLOG(LOG_LEVEL_TS)
    30  << "ByteSync" << idx << ": "
    31  << std::hex << static_cast<int>(buf[idx]) << std::dec;
    32  is_header = false;
    33  break;
    34  }
    35  }
    36  if (is_header)
    37  break;
    38  }
    39 
    40  DVLOG_IF(1, k != 0) << "SYNC: nbytes_skipped=" << k;
    41  return k;
    42 }
    43 
    44 // static
    45 TsPacket* TsPacket::Parse(const uint8_t* buf, int size) {
    46  if (size < kPacketSize) {
    47  DVLOG(1) << "Buffer does not hold one full TS packet:"
    48  << " buffer_size=" << size;
    49  return NULL;
    50  }
    51 
    52  DCHECK_EQ(buf[0], kTsHeaderSyncword);
    53  if (buf[0] != kTsHeaderSyncword) {
    54  DVLOG(1) << "Not on a TS syncword:"
    55  << " buf[0]="
    56  << std::hex << static_cast<int>(buf[0]) << std::dec;
    57  return NULL;
    58  }
    59 
    60  std::unique_ptr<TsPacket> ts_packet(new TsPacket());
    61  bool status = ts_packet->ParseHeader(buf);
    62  if (!status) {
    63  DVLOG(1) << "Parsing header failed";
    64  return NULL;
    65  }
    66  return ts_packet.release();
    67 }
    68 
    69 TsPacket::TsPacket() {
    70 }
    71 
    72 TsPacket::~TsPacket() {
    73 }
    74 
    75 bool TsPacket::ParseHeader(const uint8_t* buf) {
    76  BitReader bit_reader(buf, kPacketSize);
    77  payload_ = buf;
    78  payload_size_ = kPacketSize;
    79 
    80  // Read the TS header: 4 bytes.
    81  int syncword;
    82  int transport_error_indicator;
    83  int payload_unit_start_indicator;
    84  int transport_priority;
    85  int transport_scrambling_control;
    86  int adaptation_field_control;
    87  RCHECK(bit_reader.ReadBits(8, &syncword));
    88  RCHECK(bit_reader.ReadBits(1, &transport_error_indicator));
    89  RCHECK(bit_reader.ReadBits(1, &payload_unit_start_indicator));
    90  RCHECK(bit_reader.ReadBits(1, &transport_priority));
    91  RCHECK(bit_reader.ReadBits(13, &pid_));
    92  RCHECK(bit_reader.ReadBits(2, &transport_scrambling_control));
    93  RCHECK(bit_reader.ReadBits(2, &adaptation_field_control));
    94  RCHECK(bit_reader.ReadBits(4, &continuity_counter_));
    95  payload_unit_start_indicator_ = (payload_unit_start_indicator != 0);
    96  payload_ += 4;
    97  payload_size_ -= 4;
    98 
    99  // Default values when no adaptation field.
    100  discontinuity_indicator_ = false;
    101  random_access_indicator_ = false;
    102 
    103  // Done since no adaptation field.
    104  if ((adaptation_field_control & 0x2) == 0)
    105  return true;
    106 
    107  // Read the adaptation field if needed.
    108  int adaptation_field_length;
    109  RCHECK(bit_reader.ReadBits(8, &adaptation_field_length));
    110  DVLOG(LOG_LEVEL_TS) << "adaptation_field_length=" << adaptation_field_length;
    111  payload_ += 1;
    112  payload_size_ -= 1;
    113  if ((adaptation_field_control & 0x1) == 0 &&
    114  adaptation_field_length != 183) {
    115  DVLOG(1) << "adaptation_field_length=" << adaptation_field_length;
    116  return false;
    117  }
    118  if ((adaptation_field_control & 0x1) == 1 &&
    119  adaptation_field_length > 182) {
    120  DVLOG(1) << "adaptation_field_length=" << adaptation_field_length;
    121  // This is not allowed by the spec.
    122  // However, some badly encoded streams are using
    123  // adaptation_field_length = 183
    124  return false;
    125  }
    126 
    127  // adaptation_field_length = '0' is used to insert a single stuffing byte
    128  // in the adaptation field of a transport stream packet.
    129  if (adaptation_field_length == 0)
    130  return true;
    131 
    132  bool status = ParseAdaptationField(&bit_reader, adaptation_field_length);
    133  payload_ += adaptation_field_length;
    134  payload_size_ -= adaptation_field_length;
    135  return status;
    136 }
    137 
    138 bool TsPacket::ParseAdaptationField(BitReader* bit_reader,
    139  int adaptation_field_length) {
    140  DCHECK_GT(adaptation_field_length, 0);
    141  int adaptation_field_start_marker =
    142  static_cast<int>(bit_reader->bits_available()) / 8;
    143 
    144  int discontinuity_indicator;
    145  int random_access_indicator;
    146  int elementary_stream_priority_indicator;
    147  int pcr_flag;
    148  int opcr_flag;
    149  int splicing_point_flag;
    150  int transport_private_data_flag;
    151  int adaptation_field_extension_flag;
    152  RCHECK(bit_reader->ReadBits(1, &discontinuity_indicator));
    153  RCHECK(bit_reader->ReadBits(1, &random_access_indicator));
    154  RCHECK(bit_reader->ReadBits(1, &elementary_stream_priority_indicator));
    155  RCHECK(bit_reader->ReadBits(1, &pcr_flag));
    156  RCHECK(bit_reader->ReadBits(1, &opcr_flag));
    157  RCHECK(bit_reader->ReadBits(1, &splicing_point_flag));
    158  RCHECK(bit_reader->ReadBits(1, &transport_private_data_flag));
    159  RCHECK(bit_reader->ReadBits(1, &adaptation_field_extension_flag));
    160  discontinuity_indicator_ = (discontinuity_indicator != 0);
    161  random_access_indicator_ = (random_access_indicator != 0);
    162 
    163  if (pcr_flag) {
    164  int64_t program_clock_reference_base;
    165  int reserved;
    166  int program_clock_reference_extension;
    167  RCHECK(bit_reader->ReadBits(33, &program_clock_reference_base));
    168  RCHECK(bit_reader->ReadBits(6, &reserved));
    169  RCHECK(bit_reader->ReadBits(9, &program_clock_reference_extension));
    170  }
    171 
    172  if (opcr_flag) {
    173  int64_t original_program_clock_reference_base;
    174  int reserved;
    175  int original_program_clock_reference_extension;
    176  RCHECK(bit_reader->ReadBits(33, &original_program_clock_reference_base));
    177  RCHECK(bit_reader->ReadBits(6, &reserved));
    178  RCHECK(
    179  bit_reader->ReadBits(9, &original_program_clock_reference_extension));
    180  }
    181 
    182  if (splicing_point_flag) {
    183  int splice_countdown;
    184  RCHECK(bit_reader->ReadBits(8, &splice_countdown));
    185  }
    186 
    187  if (transport_private_data_flag) {
    188  int transport_private_data_length;
    189  RCHECK(bit_reader->ReadBits(8, &transport_private_data_length));
    190  RCHECK(bit_reader->SkipBits(8 * transport_private_data_length));
    191  }
    192 
    193  if (adaptation_field_extension_flag) {
    194  int adaptation_field_extension_length;
    195  RCHECK(bit_reader->ReadBits(8, &adaptation_field_extension_length));
    196  RCHECK(bit_reader->SkipBits(8 * adaptation_field_extension_length));
    197  }
    198 
    199  // The rest of the adaptation field should be stuffing bytes.
    200  int adaptation_field_remaining_size =
    201  adaptation_field_length -
    202  (adaptation_field_start_marker -
    203  static_cast<int>(bit_reader->bits_available()) / 8);
    204  RCHECK(adaptation_field_remaining_size >= 0);
    205  for (int k = 0; k < adaptation_field_remaining_size; k++) {
    206  int stuffing_byte;
    207  RCHECK(bit_reader->ReadBits(8, &stuffing_byte));
    208  RCHECK(stuffing_byte == 0xff);
    209  }
    210 
    211  DVLOG(LOG_LEVEL_TS) << "random_access_indicator=" << random_access_indicator_;
    212  return true;
    213 }
    214 
    215 } // namespace mp2t
    216 } // namespace media
    217 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/mp2t/ts_packet.h"
    +
    6 
    +
    7 #include <memory>
    +
    8 #include "packager/media/base/bit_reader.h"
    +
    9 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 namespace media {
    +
    13 namespace mp2t {
    +
    14 
    +
    15 static const uint8_t kTsHeaderSyncword = 0x47;
    +
    16 
    +
    17 // static
    +
    18 int TsPacket::Sync(const uint8_t* buf, int size) {
    +
    19  int k = 0;
    +
    20  for (; k < size; k++) {
    +
    21  // Verify that we have 4 syncwords in a row when possible,
    +
    22  // this should improve synchronization robustness.
    +
    23  bool is_header = true;
    +
    24  for (int i = 0; i < 4; i++) {
    +
    25  int idx = k + i * kPacketSize;
    +
    26  if (idx >= size)
    +
    27  break;
    +
    28  if (buf[idx] != kTsHeaderSyncword) {
    +
    29  DVLOG(LOG_LEVEL_TS)
    +
    30  << "ByteSync" << idx << ": "
    +
    31  << std::hex << static_cast<int>(buf[idx]) << std::dec;
    +
    32  is_header = false;
    +
    33  break;
    +
    34  }
    +
    35  }
    +
    36  if (is_header)
    +
    37  break;
    +
    38  }
    +
    39 
    +
    40  DVLOG_IF(1, k != 0) << "SYNC: nbytes_skipped=" << k;
    +
    41  return k;
    +
    42 }
    +
    43 
    +
    44 // static
    +
    45 TsPacket* TsPacket::Parse(const uint8_t* buf, int size) {
    +
    46  if (size < kPacketSize) {
    +
    47  DVLOG(1) << "Buffer does not hold one full TS packet:"
    +
    48  << " buffer_size=" << size;
    +
    49  return NULL;
    +
    50  }
    +
    51 
    +
    52  DCHECK_EQ(buf[0], kTsHeaderSyncword);
    +
    53  if (buf[0] != kTsHeaderSyncword) {
    +
    54  DVLOG(1) << "Not on a TS syncword:"
    +
    55  << " buf[0]="
    +
    56  << std::hex << static_cast<int>(buf[0]) << std::dec;
    +
    57  return NULL;
    +
    58  }
    +
    59 
    +
    60  std::unique_ptr<TsPacket> ts_packet(new TsPacket());
    +
    61  bool status = ts_packet->ParseHeader(buf);
    +
    62  if (!status) {
    +
    63  DVLOG(1) << "Parsing header failed";
    +
    64  return NULL;
    +
    65  }
    +
    66  return ts_packet.release();
    +
    67 }
    +
    68 
    +
    69 TsPacket::TsPacket() {
    +
    70 }
    +
    71 
    +
    72 TsPacket::~TsPacket() {
    +
    73 }
    +
    74 
    +
    75 bool TsPacket::ParseHeader(const uint8_t* buf) {
    +
    76  BitReader bit_reader(buf, kPacketSize);
    +
    77  payload_ = buf;
    +
    78  payload_size_ = kPacketSize;
    +
    79 
    +
    80  // Read the TS header: 4 bytes.
    +
    81  int syncword;
    +
    82  int transport_error_indicator;
    +
    83  int payload_unit_start_indicator;
    +
    84  int transport_priority;
    +
    85  int transport_scrambling_control;
    +
    86  int adaptation_field_control;
    +
    87  RCHECK(bit_reader.ReadBits(8, &syncword));
    +
    88  RCHECK(bit_reader.ReadBits(1, &transport_error_indicator));
    +
    89  RCHECK(bit_reader.ReadBits(1, &payload_unit_start_indicator));
    +
    90  RCHECK(bit_reader.ReadBits(1, &transport_priority));
    +
    91  RCHECK(bit_reader.ReadBits(13, &pid_));
    +
    92  RCHECK(bit_reader.ReadBits(2, &transport_scrambling_control));
    +
    93  RCHECK(bit_reader.ReadBits(2, &adaptation_field_control));
    +
    94  RCHECK(bit_reader.ReadBits(4, &continuity_counter_));
    +
    95  payload_unit_start_indicator_ = (payload_unit_start_indicator != 0);
    +
    96  payload_ += 4;
    +
    97  payload_size_ -= 4;
    +
    98 
    +
    99  // Default values when no adaptation field.
    +
    100  discontinuity_indicator_ = false;
    +
    101  random_access_indicator_ = false;
    +
    102 
    +
    103  // Done since no adaptation field.
    +
    104  if ((adaptation_field_control & 0x2) == 0)
    +
    105  return true;
    +
    106 
    +
    107  // Read the adaptation field if needed.
    +
    108  int adaptation_field_length;
    +
    109  RCHECK(bit_reader.ReadBits(8, &adaptation_field_length));
    +
    110  DVLOG(LOG_LEVEL_TS) << "adaptation_field_length=" << adaptation_field_length;
    +
    111  payload_ += 1;
    +
    112  payload_size_ -= 1;
    +
    113  if ((adaptation_field_control & 0x1) == 0 &&
    +
    114  adaptation_field_length != 183) {
    +
    115  DVLOG(1) << "adaptation_field_length=" << adaptation_field_length;
    +
    116  return false;
    +
    117  }
    +
    118  if ((adaptation_field_control & 0x1) == 1 &&
    +
    119  adaptation_field_length > 182) {
    +
    120  DVLOG(1) << "adaptation_field_length=" << adaptation_field_length;
    +
    121  // This is not allowed by the spec.
    +
    122  // However, some badly encoded streams are using
    +
    123  // adaptation_field_length = 183
    +
    124  return false;
    +
    125  }
    +
    126 
    +
    127  // adaptation_field_length = '0' is used to insert a single stuffing byte
    +
    128  // in the adaptation field of a transport stream packet.
    +
    129  if (adaptation_field_length == 0)
    +
    130  return true;
    +
    131 
    +
    132  bool status = ParseAdaptationField(&bit_reader, adaptation_field_length);
    +
    133  payload_ += adaptation_field_length;
    +
    134  payload_size_ -= adaptation_field_length;
    +
    135  return status;
    +
    136 }
    +
    137 
    +
    138 bool TsPacket::ParseAdaptationField(BitReader* bit_reader,
    +
    139  int adaptation_field_length) {
    +
    140  DCHECK_GT(adaptation_field_length, 0);
    +
    141  int adaptation_field_start_marker =
    +
    142  static_cast<int>(bit_reader->bits_available()) / 8;
    +
    143 
    +
    144  int discontinuity_indicator;
    +
    145  int random_access_indicator;
    +
    146  int elementary_stream_priority_indicator;
    +
    147  int pcr_flag;
    +
    148  int opcr_flag;
    +
    149  int splicing_point_flag;
    +
    150  int transport_private_data_flag;
    +
    151  int adaptation_field_extension_flag;
    +
    152  RCHECK(bit_reader->ReadBits(1, &discontinuity_indicator));
    +
    153  RCHECK(bit_reader->ReadBits(1, &random_access_indicator));
    +
    154  RCHECK(bit_reader->ReadBits(1, &elementary_stream_priority_indicator));
    +
    155  RCHECK(bit_reader->ReadBits(1, &pcr_flag));
    +
    156  RCHECK(bit_reader->ReadBits(1, &opcr_flag));
    +
    157  RCHECK(bit_reader->ReadBits(1, &splicing_point_flag));
    +
    158  RCHECK(bit_reader->ReadBits(1, &transport_private_data_flag));
    +
    159  RCHECK(bit_reader->ReadBits(1, &adaptation_field_extension_flag));
    +
    160  discontinuity_indicator_ = (discontinuity_indicator != 0);
    +
    161  random_access_indicator_ = (random_access_indicator != 0);
    +
    162 
    +
    163  if (pcr_flag) {
    +
    164  int64_t program_clock_reference_base;
    +
    165  int reserved;
    +
    166  int program_clock_reference_extension;
    +
    167  RCHECK(bit_reader->ReadBits(33, &program_clock_reference_base));
    +
    168  RCHECK(bit_reader->ReadBits(6, &reserved));
    +
    169  RCHECK(bit_reader->ReadBits(9, &program_clock_reference_extension));
    +
    170  }
    +
    171 
    +
    172  if (opcr_flag) {
    +
    173  int64_t original_program_clock_reference_base;
    +
    174  int reserved;
    +
    175  int original_program_clock_reference_extension;
    +
    176  RCHECK(bit_reader->ReadBits(33, &original_program_clock_reference_base));
    +
    177  RCHECK(bit_reader->ReadBits(6, &reserved));
    +
    178  RCHECK(
    +
    179  bit_reader->ReadBits(9, &original_program_clock_reference_extension));
    +
    180  }
    +
    181 
    +
    182  if (splicing_point_flag) {
    +
    183  int splice_countdown;
    +
    184  RCHECK(bit_reader->ReadBits(8, &splice_countdown));
    +
    185  }
    +
    186 
    +
    187  if (transport_private_data_flag) {
    +
    188  int transport_private_data_length;
    +
    189  RCHECK(bit_reader->ReadBits(8, &transport_private_data_length));
    +
    190  RCHECK(bit_reader->SkipBits(8 * transport_private_data_length));
    +
    191  }
    +
    192 
    +
    193  if (adaptation_field_extension_flag) {
    +
    194  int adaptation_field_extension_length;
    +
    195  RCHECK(bit_reader->ReadBits(8, &adaptation_field_extension_length));
    +
    196  RCHECK(bit_reader->SkipBits(8 * adaptation_field_extension_length));
    +
    197  }
    +
    198 
    +
    199  // The rest of the adaptation field should be stuffing bytes.
    +
    200  int adaptation_field_remaining_size =
    +
    201  adaptation_field_length -
    +
    202  (adaptation_field_start_marker -
    +
    203  static_cast<int>(bit_reader->bits_available()) / 8);
    +
    204  RCHECK(adaptation_field_remaining_size >= 0);
    +
    205  for (int k = 0; k < adaptation_field_remaining_size; k++) {
    +
    206  int stuffing_byte;
    +
    207  RCHECK(bit_reader->ReadBits(8, &stuffing_byte));
    +
    208  RCHECK(stuffing_byte == 0xff);
    +
    209  }
    +
    210 
    +
    211  DVLOG(LOG_LEVEL_TS) << "random_access_indicator=" << random_access_indicator_;
    +
    212  return true;
    +
    213 }
    +
    214 
    +
    215 } // namespace mp2t
    +
    216 } // namespace media
    +
    217 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d5/d78/classshaka_1_1media_1_1FileReader-members.html b/docs/d5/dc0/structshaka_1_1media_1_1TextSubStreamInfo-members.html similarity index 65% rename from docs/d5/d78/classshaka_1_1media_1_1FileReader-members.html rename to docs/d5/dc0/structshaka_1_1media_1_1TextSubStreamInfo-members.html index afe9e02fee..790f9e901b 100644 --- a/docs/d5/d78/classshaka_1_1media_1_1FileReader-members.html +++ b/docs/d5/dc0/structshaka_1_1media_1_1TextSubStreamInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
-
shaka::media::FileReader Member List
+
shaka::media::TextSubStreamInfo Member List
-

This is the complete list of members for shaka::media::FileReader, including all inherited members.

+

This is the complete list of members for shaka::media::TextSubStreamInfo, including all inherited members.

- - +
Next(char *out)shaka::media::FileReader
Open(const std::string &filename, std::unique_ptr< FileReader > *out)shaka::media::FileReaderstatic
language (defined in shaka::media::TextSubStreamInfo)shaka::media::TextSubStreamInfo
diff --git a/docs/d5/dc1/webm__webvtt__parser_8cc_source.html b/docs/d5/dc1/webm__webvtt__parser_8cc_source.html index 463ca93674..4b0dbc4661 100644 --- a/docs/d5/dc1/webm__webvtt__parser_8cc_source.html +++ b/docs/d5/dc1/webm__webvtt__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_webvtt_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webm_webvtt_parser.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/webm/webm_webvtt_parser.h"
6 
7 namespace shaka {
8 namespace media {
9 
10 void WebMWebVTTParser::Parse(const uint8_t* payload,
11  int payload_size,
12  std::string* id,
13  std::string* settings,
14  std::string* content) {
15  WebMWebVTTParser parser(payload, payload_size);
16  parser.Parse(id, settings, content);
17 }
18 
19 WebMWebVTTParser::WebMWebVTTParser(const uint8_t* payload, int payload_size)
20  : ptr_(payload), ptr_end_(payload + payload_size) {}
21 
22 void WebMWebVTTParser::Parse(std::string* id,
23  std::string* settings,
24  std::string* content) {
25  ParseLine(id);
26  ParseLine(settings);
27  content->assign(ptr_, ptr_end_);
28 }
29 
30 bool WebMWebVTTParser::GetByte(uint8_t* byte) {
31  if (ptr_ >= ptr_end_)
32  return false; // indicates end-of-stream
33 
34  *byte = *ptr_++;
35  return true;
36 }
37 
38 void WebMWebVTTParser::UngetByte() {
39  --ptr_;
40 }
41 
42 void WebMWebVTTParser::ParseLine(std::string* line) {
43  line->clear();
44 
45  // Consume characters from the stream, until we reach end-of-line.
46 
47  // The WebVTT spec states that lines may be terminated in any of the following
48  // three ways:
49  // LF
50  // CR
51  // CR LF
52 
53  // The spec is here:
54  // http://wiki.webmproject.org/webm-metadata/temporal-metadata/webvtt-in-webm
55 
56  enum {
57  kLF = '\x0A',
58  kCR = '\x0D'
59  };
60 
61  for (;;) {
62  uint8_t byte;
63 
64  if (!GetByte(&byte) || byte == kLF)
65  return;
66 
67  if (byte == kCR) {
68  if (GetByte(&byte) && byte != kLF)
69  UngetByte();
70 
71  return;
72  }
73 
74  line->push_back(byte);
75  }
76 }
77 
78 } // namespace media
79 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
static void Parse(const uint8_t *payload, int payload_size, std::string *id, std::string *settings, std::string *content)
Utility function to parse the WebVTT cue from a byte stream.
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/webm/webm_webvtt_parser.h"
+
6 
+
7 namespace shaka {
+
8 namespace media {
+
9 
+
10 void WebMWebVTTParser::Parse(const uint8_t* payload,
+
11  int payload_size,
+
12  std::string* id,
+
13  std::string* settings,
+
14  std::string* content) {
+
15  WebMWebVTTParser parser(payload, payload_size);
+
16  parser.Parse(id, settings, content);
+
17 }
+
18 
+
19 WebMWebVTTParser::WebMWebVTTParser(const uint8_t* payload, int payload_size)
+
20  : ptr_(payload), ptr_end_(payload + payload_size) {}
+
21 
+
22 void WebMWebVTTParser::Parse(std::string* id,
+
23  std::string* settings,
+
24  std::string* content) {
+
25  ParseLine(id);
+
26  ParseLine(settings);
+
27  content->assign(ptr_, ptr_end_);
+
28 }
+
29 
+
30 bool WebMWebVTTParser::GetByte(uint8_t* byte) {
+
31  if (ptr_ >= ptr_end_)
+
32  return false; // indicates end-of-stream
+
33 
+
34  *byte = *ptr_++;
+
35  return true;
+
36 }
+
37 
+
38 void WebMWebVTTParser::UngetByte() {
+
39  --ptr_;
+
40 }
+
41 
+
42 void WebMWebVTTParser::ParseLine(std::string* line) {
+
43  line->clear();
+
44 
+
45  // Consume characters from the stream, until we reach end-of-line.
+
46 
+
47  // The WebVTT spec states that lines may be terminated in any of the following
+
48  // three ways:
+
49  // LF
+
50  // CR
+
51  // CR LF
+
52 
+
53  // The spec is here:
+
54  // http://wiki.webmproject.org/webm-metadata/temporal-metadata/webvtt-in-webm
+
55 
+
56  enum {
+
57  kLF = '\x0A',
+
58  kCR = '\x0D'
+
59  };
+
60 
+
61  for (;;) {
+
62  uint8_t byte;
+
63 
+
64  if (!GetByte(&byte) || byte == kLF)
+
65  return;
+
66 
+
67  if (byte == kCR) {
+
68  if (GetByte(&byte) && byte != kLF)
+
69  UngetByte();
+
70 
+
71  return;
+
72  }
+
73 
+
74  line->push_back(byte);
+
75  }
+
76 }
+
77 
+
78 } // namespace media
+
79 } // namespace shaka
+ +
static void Parse(const uint8_t *payload, int payload_size, std::string *id, std::string *settings, std::string *content)
Utility function to parse the WebVTT cue from a byte stream.
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d5/dc8/structshaka_1_1media_1_1mp4_1_1TrackFragment-members.html b/docs/d5/dc8/structshaka_1_1media_1_1mp4_1_1TrackFragment-members.html index aa82e22cb0..38d962ad7e 100644 --- a/docs/d5/dc8/structshaka_1_1media_1_1mp4_1_1TrackFragment-members.html +++ b/docs/d5/dc8/structshaka_1_1media_1_1mp4_1_1TrackFragment-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d5/dca/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationOffset.html b/docs/d5/dca/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationOffset.html index 6e0f697b68..1a673dbfb0 100644 --- a/docs/d5/dca/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationOffset.html +++ b/docs/d5/dca/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationOffset.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleAuxiliaryInformationOffset Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -121,7 +124,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 64 of file box_definitions.h.

+

Definition at line 65 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -149,7 +152,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 188 of file box_definitions.cc.

+

Definition at line 200 of file box_definitions.cc.

@@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/d5/dcb/raw__key__encryption__flags_8h_source.html b/docs/d5/dcb/raw__key__encryption__flags_8h_source.html index 5d3c241ab8..c39d9fe8be 100644 --- a/docs/d5/dcb/raw__key__encryption__flags_8h_source.html +++ b/docs/d5/dcb/raw__key__encryption__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/raw_key_encryption_flags.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
raw_key_encryption_flags.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines command line flags for raw key encryption.
8 
9 #ifndef PACKAGER_APP_RAW_KEY_ENCRYPTION_FLAGS_H_
10 #define PACKAGER_APP_RAW_KEY_ENCRYPTION_FLAGS_H_
11 
12 #include <gflags/gflags.h>
13 
14 #include "packager/app/gflags_hex_bytes.h"
15 
16 DECLARE_bool(enable_raw_key_encryption);
17 DECLARE_bool(enable_raw_key_decryption);
18 DECLARE_hex_bytes(key_id);
19 DECLARE_hex_bytes(key);
20 DECLARE_string(keys);
21 DECLARE_hex_bytes(iv);
22 DECLARE_hex_bytes(pssh);
23 
24 namespace shaka {
25 
29 
30 } // namespace shaka
31 
32 #endif // PACKAGER_APP_RAW_KEY_ENCRYPTION_FLAGS_H_
bool ValidateRawKeyCryptoFlags()
-
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines command line flags for raw key encryption.
+
8 
+
9 #ifndef PACKAGER_APP_RAW_KEY_ENCRYPTION_FLAGS_H_
+
10 #define PACKAGER_APP_RAW_KEY_ENCRYPTION_FLAGS_H_
+
11 
+
12 #include <gflags/gflags.h>
+
13 
+
14 #include "packager/app/gflags_hex_bytes.h"
+
15 
+
16 DECLARE_bool(enable_raw_key_encryption);
+
17 DECLARE_bool(enable_raw_key_decryption);
+
18 DECLARE_hex_bytes(key_id);
+
19 DECLARE_hex_bytes(key);
+
20 DECLARE_string(keys);
+
21 DECLARE_hex_bytes(iv);
+
22 DECLARE_hex_bytes(pssh);
+
23 
+
24 namespace shaka {
+
25 
+ +
29 
+
30 } // namespace shaka
+
31 
+
32 #endif // PACKAGER_APP_RAW_KEY_ENCRYPTION_FLAGS_H_
+
All the methods that are virtual are virtual for mocking.
+
bool ValidateRawKeyCryptoFlags()
diff --git a/docs/d5/dcf/rsa__key_8h_source.html b/docs/d5/dcf/rsa__key_8h_source.html index 3f70123823..513b06af66 100644 --- a/docs/d5/dcf/rsa__key_8h_source.html +++ b/docs/d5/dcf/rsa__key_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/rsa_key.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
rsa_key.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Declaration of classes representing RSA private and public keys used
8 // for message signing, signature verification, encryption and decryption.
9 
10 #ifndef PACKAGER_MEDIA_BASE_RSA_KEY_H_
11 #define PACKAGER_MEDIA_BASE_RSA_KEY_H_
12 
13 #include <string>
14 
15 #include "packager/base/macros.h"
16 
17 struct rsa_st;
18 typedef struct rsa_st RSA;
19 
20 namespace shaka {
21 namespace media {
22 
25  public:
26  ~RsaPrivateKey();
27 
30  static RsaPrivateKey* Create(const std::string& serialized_key);
31 
35  bool Decrypt(const std::string& encrypted_message,
36  std::string* decrypted_message);
37 
41  bool GenerateSignature(const std::string& message, std::string* signature);
42 
43  private:
44  // RsaPrivateKey takes owership of |rsa_key|.
45  explicit RsaPrivateKey(RSA* rsa_key);
46 
47  RSA* rsa_key_; // owned
48 
49  DISALLOW_COPY_AND_ASSIGN(RsaPrivateKey);
50 };
51 
53 class RsaPublicKey {
54  public:
55  ~RsaPublicKey();
56 
59  static RsaPublicKey* Create(const std::string& serialized_key);
60 
64  bool Encrypt(const std::string& clear_message,
65  std::string* encrypted_message);
66 
69  bool VerifySignature(const std::string& message,
70  const std::string& signature);
71 
72  private:
73  // RsaPublicKey takes owership of |rsa_key|.
74  explicit RsaPublicKey(RSA* rsa_key);
75 
76  RSA* rsa_key_; // owned
77 
78  DISALLOW_COPY_AND_ASSIGN(RsaPublicKey);
79 };
80 
81 } // namespace media
82 } // namespace shaka
83 
84 #endif // PACKAGER_MEDIA_BASE_RSA_KEY_H_
Rsa public key, used for signature verification and encryption.
Definition: rsa_key.h:53
-
All the methods that are virtual are virtual for mocking.
-
bool Decrypt(const std::string &encrypted_message, std::string *decrypted_message)
Definition: rsa_key.cc:101
-
Rsa private key, used for message signing and decryption.
Definition: rsa_key.h:24
-
bool GenerateSignature(const std::string &message, std::string *signature)
Definition: rsa_key.cc:127
-
static RsaPrivateKey * Create(const std::string &serialized_key)
Definition: rsa_key.cc:96
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Declaration of classes representing RSA private and public keys used
+
8 // for message signing, signature verification, encryption and decryption.
+
9 
+
10 #ifndef PACKAGER_MEDIA_BASE_RSA_KEY_H_
+
11 #define PACKAGER_MEDIA_BASE_RSA_KEY_H_
+
12 
+
13 #include <string>
+
14 
+
15 #include "packager/base/macros.h"
+
16 
+
17 struct rsa_st;
+
18 typedef struct rsa_st RSA;
+
19 
+
20 namespace shaka {
+
21 namespace media {
+
22 
+ +
25  public:
+
26  ~RsaPrivateKey();
+
27 
+
30  static RsaPrivateKey* Create(const std::string& serialized_key);
+
31 
+
35  bool Decrypt(const std::string& encrypted_message,
+
36  std::string* decrypted_message);
+
37 
+
41  bool GenerateSignature(const std::string& message, std::string* signature);
+
42 
+
43  private:
+
44  // RsaPrivateKey takes owership of |rsa_key|.
+
45  explicit RsaPrivateKey(RSA* rsa_key);
+
46 
+
47  RSA* rsa_key_; // owned
+
48 
+
49  DISALLOW_COPY_AND_ASSIGN(RsaPrivateKey);
+
50 };
+
51 
+
53 class RsaPublicKey {
+
54  public:
+
55  ~RsaPublicKey();
+
56 
+
59  static RsaPublicKey* Create(const std::string& serialized_key);
+
60 
+
64  bool Encrypt(const std::string& clear_message,
+
65  std::string* encrypted_message);
+
66 
+
69  bool VerifySignature(const std::string& message,
+
70  const std::string& signature);
+
71 
+
72  private:
+
73  // RsaPublicKey takes owership of |rsa_key|.
+
74  explicit RsaPublicKey(RSA* rsa_key);
+
75 
+
76  RSA* rsa_key_; // owned
+
77 
+
78  DISALLOW_COPY_AND_ASSIGN(RsaPublicKey);
+
79 };
+
80 
+
81 } // namespace media
+
82 } // namespace shaka
+
83 
+
84 #endif // PACKAGER_MEDIA_BASE_RSA_KEY_H_
+
Rsa private key, used for message signing and decryption.
Definition: rsa_key.h:24
+
bool Decrypt(const std::string &encrypted_message, std::string *decrypted_message)
Definition: rsa_key.cc:101
+
bool GenerateSignature(const std::string &message, std::string *signature)
Definition: rsa_key.cc:127
+
static RsaPrivateKey * Create(const std::string &serialized_key)
Definition: rsa_key.cc:96
+
Rsa public key, used for signature verification and encryption.
Definition: rsa_key.h:53
+
bool VerifySignature(const std::string &message, const std::string &signature)
Definition: rsa_key.cc:200
+
static RsaPublicKey * Create(const std::string &serialized_key)
Definition: rsa_key.cc:171
+
bool Encrypt(const std::string &clear_message, std::string *encrypted_message)
Definition: rsa_key.cc:176
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d5/dd2/structshaka_1_1media_1_1TextNumber-members.html b/docs/d5/dd2/structshaka_1_1media_1_1TextNumber-members.html new file mode 100644 index 0000000000..13cd31768d --- /dev/null +++ b/docs/d5/dd2/structshaka_1_1media_1_1TextNumber-members.html @@ -0,0 +1,84 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::TextNumber Member List
+
+
+ +

This is the complete list of members for shaka::media::TextNumber, including all inherited members.

+ + + + +
TextNumber(float value, TextUnitType type) (defined in shaka::media::TextNumber)shaka::media::TextNumberinline
type (defined in shaka::media::TextNumber)shaka::media::TextNumber
value (defined in shaka::media::TextNumber)shaka::media::TextNumber
+ + + + diff --git a/docs/d5/dda/ts__section__psi_8h_source.html b/docs/d5/dda/ts__section__psi_8h_source.html index 4738e2d7ad..ad425e8077 100644 --- a/docs/d5/dda/ts__section__psi_8h_source.html +++ b/docs/d5/dda/ts__section__psi_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section_psi.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
ts_section_psi.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PSI_H_
6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PSI_H_
7 
8 #include "packager/base/compiler_specific.h"
9 #include "packager/media/base/byte_queue.h"
10 #include "packager/media/formats/mp2t/ts_section.h"
11 
12 namespace shaka {
13 namespace media {
14 
15 class BitReader;
16 
17 namespace mp2t {
18 
19 class TsSectionPsi : public TsSection {
20  public:
21  TsSectionPsi();
22  ~TsSectionPsi() override;
23 
24  // TsSection implementation.
25  bool Parse(bool payload_unit_start_indicator,
26  const uint8_t* buf,
27  int size) override;
28  void Flush() override;
29  void Reset() override;
30 
31  // Parse the content of the PSI section.
32  virtual bool ParsePsiSection(BitReader* bit_reader) = 0;
33 
34  // Reset the state of the PSI section.
35  virtual void ResetPsiSection() = 0;
36 
37  private:
38  void ResetPsiState();
39 
40  // Bytes of the current PSI.
41  ByteQueue psi_byte_queue_;
42 
43  // Do not start parsing before getting a unit start indicator.
44  bool wait_for_pusi_;
45 
46  // Number of leading bytes to discard (pointer field).
47  int leading_bytes_to_discard_;
48 
49  DISALLOW_COPY_AND_ASSIGN(TsSectionPsi);
50 };
51 
52 } // namespace mp2t
53 } // namespace media
54 } // namespace shaka
55 
56 #endif
57 
A class to read bit streams.
Definition: bit_reader.h:17
-
All the methods that are virtual are virtual for mocking.
- - - +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PSI_H_
+
6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PSI_H_
+
7 
+
8 #include "packager/base/compiler_specific.h"
+
9 #include "packager/media/base/byte_queue.h"
+
10 #include "packager/media/formats/mp2t/ts_section.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+
15 class BitReader;
+
16 
+
17 namespace mp2t {
+
18 
+
19 class TsSectionPsi : public TsSection {
+
20  public:
+
21  TsSectionPsi();
+
22  ~TsSectionPsi() override;
+
23 
+
24  // TsSection implementation.
+
25  bool Parse(bool payload_unit_start_indicator,
+
26  const uint8_t* buf,
+
27  int size) override;
+
28  bool Flush() override;
+
29  void Reset() override;
+
30 
+
31  // Parse the content of the PSI section.
+
32  virtual bool ParsePsiSection(BitReader* bit_reader) = 0;
+
33 
+
34  // Reset the state of the PSI section.
+
35  virtual void ResetPsiSection() = 0;
+
36 
+
37  private:
+
38  void ResetPsiState();
+
39 
+
40  // Bytes of the current PSI.
+
41  ByteQueue psi_byte_queue_;
+
42 
+
43  // Do not start parsing before getting a unit start indicator.
+
44  bool wait_for_pusi_;
+
45 
+
46  // Number of leading bytes to discard (pointer field).
+
47  int leading_bytes_to_discard_;
+
48 
+
49  DISALLOW_COPY_AND_ASSIGN(TsSectionPsi);
+
50 };
+
51 
+
52 } // namespace mp2t
+
53 } // namespace media
+
54 } // namespace shaka
+
55 
+
56 #endif
+
57 
+
A class to read bit streams.
Definition: bit_reader.h:17
+ + + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d5/ddb/webvtt__text__output__handler_8cc_source.html b/docs/d5/ddb/webvtt__text__output__handler_8cc_source.html deleted file mode 100644 index 9c4f496980..0000000000 --- a/docs/d5/ddb/webvtt__text__output__handler_8cc_source.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - -Shaka Packager SDK: packager/media/formats/webvtt/webvtt_text_output_handler.cc Source File - - - - - - - - - -
-
- - - - - - -
-
Shaka Packager SDK -
-
-
- - - - - - - - -
-
- - -
- -
- - -
-
-
-
webvtt_text_output_handler.cc
-
-
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webvtt/webvtt_text_output_handler.h"
8 
9 #include <algorithm> // needed for min and max
10 
11 #include "packager/base/logging.h"
12 #include "packager/file/file.h"
13 #include "packager/file/file_closer.h"
14 #include "packager/media/base/muxer_util.h"
15 #include "packager/status_macros.h"
16 
17 namespace shaka {
18 namespace media {
19 namespace {
20 double kMillisecondsToSeconds = 1000.0;
21 
22 std::string ToString(const std::vector<uint8_t>& v) {
23  return std::string(v.begin(), v.end());
24 }
25 } // namespace
26 
27 WebVttTextOutputHandler::WebVttTextOutputHandler(
28  const MuxerOptions& muxer_options,
29  std::unique_ptr<MuxerListener> muxer_listener)
30  : muxer_options_(muxer_options),
31  muxer_listener_(std::move(muxer_listener)) {}
32 
33 Status WebVttTextOutputHandler::InitializeInternal() {
34  return Status::OK;
35 }
36 
37 Status WebVttTextOutputHandler::Process(
38  std::unique_ptr<StreamData> stream_data) {
39  switch (stream_data->stream_data_type) {
40  case StreamDataType::kStreamInfo:
41  return OnStreamInfo(*stream_data->stream_info);
42  case StreamDataType::kSegmentInfo:
43  return OnSegmentInfo(*stream_data->segment_info);
44  case StreamDataType::kCueEvent:
45  return OnCueEvent(*stream_data->cue_event);
46  case StreamDataType::kTextSample:
47  OnTextSample(*stream_data->text_sample);
48  return Status::OK;
49  default:
50  return Status(error::INTERNAL_ERROR,
51  "Invalid stream data type for this handler");
52  }
53 }
54 
55 Status WebVttTextOutputHandler::OnFlushRequest(size_t input_stream_index) {
56  if (!buffer_) {
57  LOG(INFO) << "Skip stream '" << muxer_options_.segment_template
58  << "' which does not contain any sample.";
59  return Status::OK;
60  }
61 
62  DCHECK_EQ(buffer_->sample_count(), 0u)
63  << "There should have been a segment info before flushing that would "
64  "have cleared out all the samples.";
65 
66  const float duration_ms = static_cast<float>(total_duration_ms_);
67  const float duration_seconds = duration_ms / 1000.0f;
68 
69  MuxerListener::MediaRanges empty_ranges;
70  muxer_listener_->OnMediaEnd(empty_ranges, duration_seconds);
71 
72  return Status::OK;
73 }
74 
75 Status WebVttTextOutputHandler::OnStreamInfo(const StreamInfo& info) {
76  buffer_.reset(
77  new WebVttFileBuffer(muxer_options_.transport_stream_timestamp_offset_ms,
78  ToString(info.codec_config())));
79  muxer_listener_->OnMediaStart(muxer_options_, info, info.time_scale(),
80  MuxerListener::kContainerText);
81  return Status::OK;
82 }
83 
84 Status WebVttTextOutputHandler::OnSegmentInfo(const SegmentInfo& info) {
85  total_duration_ms_ += info.duration;
86 
87  const std::string& segment_template = muxer_options_.segment_template;
88  const uint32_t index = segment_index_++;
89  const uint64_t start = info.start_timestamp;
90  const uint64_t duration = info.duration;
91  const uint32_t bandwidth = muxer_options_.bandwidth;
92 
93  const std::string filename =
94  GetSegmentName(segment_template, start, index, bandwidth);
95 
96  // Write everything to the file before telling the manifest so that the
97  // file will exist on disk.
98  std::unique_ptr<File, FileCloser> file(File::Open(filename.c_str(), "w"));
99 
100  if (!file) {
101  return Status(error::FILE_FAILURE, "Failed to open " + filename);
102  }
103 
104  buffer_->WriteTo(file.get());
105  buffer_->Reset();
106 
107  if (!file.release()->Close()) {
108  return Status(error::FILE_FAILURE, "Failed to close " + filename);
109  }
110 
111  // Update the manifest with our new file.
112  const uint64_t size = File::GetFileSize(filename.c_str());
113  muxer_listener_->OnNewSegment(filename, start, duration, size);
114 
115  return Status::OK;
116 }
117 
118 Status WebVttTextOutputHandler::OnCueEvent(const CueEvent& event) {
119  double timestamp_seconds = event.time_in_seconds;
120  double timestamp_ms = timestamp_seconds * kMillisecondsToSeconds;
121  uint64_t timestamp = static_cast<uint64_t>(timestamp_ms);
122  muxer_listener_->OnCueEvent(timestamp, event.cue_data);
123  return Status::OK;
124 }
125 
126 void WebVttTextOutputHandler::OnTextSample(const TextSample& sample) {
127  // Skip empty samples. It is normal to see empty samples as earlier in the
128  // pipeline we pad the stream to remove gaps.
129  if (sample.payload().size()) {
130  buffer_->Append(sample);
131  }
132 }
133 } // namespace media
134 } // namespace shaka
STL namespace.
-
All the methods that are virtual are virtual for mocking.
-
static int64_t GetFileSize(const char *file_name)
Definition: file.cc:207
-
virtual bool Open()=0
Internal open. Should not be used directly.
-
- - - - diff --git a/docs/d5/ddf/structshaka_1_1media_1_1RgbaColor-members.html b/docs/d5/ddf/structshaka_1_1media_1_1RgbaColor-members.html new file mode 100644 index 0000000000..f01a7c40cd --- /dev/null +++ b/docs/d5/ddf/structshaka_1_1media_1_1RgbaColor-members.html @@ -0,0 +1,87 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::RgbaColor Member List
+
+
+ +

This is the complete list of members for shaka::media::RgbaColor, including all inherited members.

+ + + + + + + +
a (defined in shaka::media::RgbaColor)shaka::media::RgbaColor
b (defined in shaka::media::RgbaColor)shaka::media::RgbaColor
g (defined in shaka::media::RgbaColor)shaka::media::RgbaColor
operator!=(const RgbaColor &other) const (defined in shaka::media::RgbaColor)shaka::media::RgbaColorinline
operator==(const RgbaColor &other) const (defined in shaka::media::RgbaColor)shaka::media::RgbaColorinline
r (defined in shaka::media::RgbaColor)shaka::media::RgbaColor
+ + + + diff --git a/docs/d5/de0/bit__reader_8cc_source.html b/docs/d5/de0/bit__reader_8cc_source.html index 5f40b9be21..7e5dc3e1db 100644 --- a/docs/d5/de0/bit__reader_8cc_source.html +++ b/docs/d5/de0/bit__reader_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/bit_reader.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
bit_reader.cc
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/base/bit_reader.h"
6 
7 #include <algorithm>
8 
9 namespace shaka {
10 namespace media {
11 
12 BitReader::BitReader(const uint8_t* data, size_t size)
13  : data_(data),
14  initial_size_(size),
15  bytes_left_(size),
16  num_remaining_bits_in_curr_byte_(0) {
17  DCHECK(data_ != NULL && bytes_left_ > 0);
18 
19  UpdateCurrByte();
20 }
21 
22 BitReader::~BitReader() {}
23 
24 bool BitReader::SkipBits(size_t num_bits) {
25  // Skip any bits in the current byte waiting to be processed, then
26  // process full bytes until less than 8 bits remaining.
27  if (num_bits > num_remaining_bits_in_curr_byte_) {
28  num_bits -= num_remaining_bits_in_curr_byte_;
29  num_remaining_bits_in_curr_byte_ = 0;
30 
31  size_t num_bytes = num_bits / 8;
32  num_bits %= 8;
33  if (bytes_left_ < num_bytes) {
34  bytes_left_ = 0;
35  return false;
36  }
37  bytes_left_ -= num_bytes;
38  data_ += num_bytes;
39  UpdateCurrByte();
40 
41  // If there is no more data remaining, only return true if we
42  // skipped all that were requested.
43  if (num_remaining_bits_in_curr_byte_ == 0)
44  return (num_bits == 0);
45  }
46 
47  // Less than 8 bits remaining to skip. Use ReadBitsInternal to verify
48  // that the remaining bits we need exist, and adjust them as necessary
49  // for subsequent operations.
50  uint64_t not_needed;
51  return ReadBitsInternal(num_bits, &not_needed);
52 }
53 
55  // Already aligned.
56  if (num_remaining_bits_in_curr_byte_ == 8)
57  return;
58 
59  num_remaining_bits_in_curr_byte_ = 0;
60  UpdateCurrByte();
61 }
62 
63 bool BitReader::SkipBytes(size_t num_bytes) {
64  if (num_remaining_bits_in_curr_byte_ != 8)
65  return false;
66  if (num_bytes == 0)
67  return true;
68 
69  data_ += num_bytes - 1; // One additional byte in curr_byte_.
70  if (num_bytes > bytes_left_ + 1)
71  return false;
72  bytes_left_ -= num_bytes - 1;
73  num_remaining_bits_in_curr_byte_ = 0;
74  UpdateCurrByte();
75  return true;
76 }
77 
78 bool BitReader::ReadBitsInternal(size_t num_bits, uint64_t* out) {
79  DCHECK_LE(num_bits, 64u);
80 
81  *out = 0;
82 
83  while (num_remaining_bits_in_curr_byte_ != 0 && num_bits != 0) {
84  size_t bits_to_take = std::min(num_remaining_bits_in_curr_byte_, num_bits);
85 
86  *out <<= bits_to_take;
87  *out += curr_byte_ >> (num_remaining_bits_in_curr_byte_ - bits_to_take);
88  num_bits -= bits_to_take;
89  num_remaining_bits_in_curr_byte_ -= bits_to_take;
90  curr_byte_ &= (1 << num_remaining_bits_in_curr_byte_) - 1;
91 
92  if (num_remaining_bits_in_curr_byte_ == 0)
93  UpdateCurrByte();
94  }
95 
96  return num_bits == 0;
97 }
98 
99 void BitReader::UpdateCurrByte() {
100  DCHECK_EQ(num_remaining_bits_in_curr_byte_, 0u);
101 
102  if (bytes_left_ == 0)
103  return;
104 
105  // Load a new byte and advance pointers.
106  curr_byte_ = *data_;
107  ++data_;
108  --bytes_left_;
109  num_remaining_bits_in_curr_byte_ = 8;
110 }
111 
112 } // namespace media
113 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
- -
BitReader(const uint8_t *data, size_t size)
Definition: bit_reader.cc:12
-
bool SkipBytes(size_t num_bytes)
Definition: bit_reader.cc:63
+
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/base/bit_reader.h"
+
6 
+
7 #include <algorithm>
+
8 
+
9 namespace shaka {
+
10 namespace media {
+
11 
+
12 BitReader::BitReader(const uint8_t* data, size_t size)
+
13  : data_(data),
+
14  initial_size_(size),
+
15  bytes_left_(size),
+
16  num_remaining_bits_in_curr_byte_(0) {
+
17  DCHECK(data_ != NULL && bytes_left_ > 0);
+
18 
+
19  UpdateCurrByte();
+
20 }
+
21 
+
22 BitReader::~BitReader() {}
+
23 
+
24 bool BitReader::SkipBits(size_t num_bits) {
+
25  // Skip any bits in the current byte waiting to be processed, then
+
26  // process full bytes until less than 8 bits remaining.
+
27  if (num_bits > num_remaining_bits_in_curr_byte_) {
+
28  num_bits -= num_remaining_bits_in_curr_byte_;
+
29  num_remaining_bits_in_curr_byte_ = 0;
+
30 
+
31  size_t num_bytes = num_bits / 8;
+
32  num_bits %= 8;
+
33  if (bytes_left_ < num_bytes) {
+
34  bytes_left_ = 0;
+
35  return false;
+
36  }
+
37  bytes_left_ -= num_bytes;
+
38  data_ += num_bytes;
+
39  UpdateCurrByte();
+
40 
+
41  // If there is no more data remaining, only return true if we
+
42  // skipped all that were requested.
+
43  if (num_remaining_bits_in_curr_byte_ == 0)
+
44  return (num_bits == 0);
+
45  }
+
46 
+
47  // Less than 8 bits remaining to skip. Use ReadBitsInternal to verify
+
48  // that the remaining bits we need exist, and adjust them as necessary
+
49  // for subsequent operations.
+
50  uint64_t not_needed;
+
51  return ReadBitsInternal(num_bits, &not_needed);
+
52 }
+
53 
+ +
55  // Already aligned.
+
56  if (num_remaining_bits_in_curr_byte_ == 8)
+
57  return;
+
58 
+
59  num_remaining_bits_in_curr_byte_ = 0;
+
60  UpdateCurrByte();
+
61 }
+
62 
+
63 bool BitReader::SkipBytes(size_t num_bytes) {
+
64  if (num_bytes == 0)
+
65  return true;
+
66  if (num_remaining_bits_in_curr_byte_ != 8)
+
67  return false;
+
68 
+
69  data_ += num_bytes - 1; // One additional byte in curr_byte_.
+
70  if (num_bytes > bytes_left_ + 1)
+
71  return false;
+
72  bytes_left_ -= num_bytes - 1;
+
73  num_remaining_bits_in_curr_byte_ = 0;
+
74  UpdateCurrByte();
+
75  return true;
+
76 }
+
77 
+
78 bool BitReader::ReadBitsInternal(size_t num_bits, uint64_t* out) {
+
79  DCHECK_LE(num_bits, 64u);
+
80 
+
81  *out = 0;
+
82 
+
83  while (num_remaining_bits_in_curr_byte_ != 0 && num_bits != 0) {
+
84  size_t bits_to_take = std::min(num_remaining_bits_in_curr_byte_, num_bits);
+
85 
+
86  *out <<= bits_to_take;
+
87  *out += curr_byte_ >> (num_remaining_bits_in_curr_byte_ - bits_to_take);
+
88  num_bits -= bits_to_take;
+
89  num_remaining_bits_in_curr_byte_ -= bits_to_take;
+
90  curr_byte_ &= (1 << num_remaining_bits_in_curr_byte_) - 1;
+
91 
+
92  if (num_remaining_bits_in_curr_byte_ == 0)
+
93  UpdateCurrByte();
+
94  }
+
95 
+
96  return num_bits == 0;
+
97 }
+
98 
+
99 void BitReader::UpdateCurrByte() {
+
100  DCHECK_EQ(num_remaining_bits_in_curr_byte_, 0u);
+
101 
+
102  if (bytes_left_ == 0)
+
103  return;
+
104 
+
105  // Load a new byte and advance pointers.
+
106  curr_byte_ = *data_;
+
107  ++data_;
+
108  --bytes_left_;
+
109  num_remaining_bits_in_curr_byte_ = 8;
+
110 }
+
111 
+
112 } // namespace media
+
113 } // namespace shaka
+
BitReader(const uint8_t *data, size_t size)
Definition: bit_reader.cc:12
+
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
+
bool SkipBytes(size_t num_bytes)
Definition: bit_reader.cc:63
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d5/de0/classshaka_1_1media_1_1mp2t_1_1PesPacketGenerator.html b/docs/d5/de0/classshaka_1_1media_1_1mp2t_1_1PesPacketGenerator.html index 2892ae11e2..8502d98e17 100644 --- a/docs/d5/de0/classshaka_1_1media_1_1mp2t_1_1PesPacketGenerator.html +++ b/docs/d5/de0/classshaka_1_1media_1_1mp2t_1_1PesPacketGenerator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::PesPacketGenerator Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
PesPacketGeneratorTe

Flush the object. This may increase NumberOfReadyPesPackets().

Returns
true on success, false otherwise.
-

Definition at line 152 of file pes_packet_generator.cc.

+

Definition at line 153 of file pes_packet_generator.cc.

@@ -186,7 +189,7 @@ class PesPacketGeneratorTe

Removes the next PES packet from the stream and returns it. Must have at least one packet ready.

Returns
Next PES packet that is ready.
-

Definition at line 145 of file pes_packet_generator.cc.

+

Definition at line 146 of file pes_packet_generator.cc.

@@ -249,7 +252,7 @@ class PesPacketGeneratorTe
Returns
The number of PES packets that are ready to be consumed.
-

Definition at line 141 of file pes_packet_generator.cc.

+

Definition at line 142 of file pes_packet_generator.cc.

@@ -278,7 +281,7 @@ class PesPacketGeneratorTe

Add a sample to the generator. This does not necessarily increase NumberOfReadyPesPackets(). If this returns false, the object may end up in an undefined state.

Returns
true on success, false otherwise.
-

Definition at line 80 of file pes_packet_generator.cc.

+

Definition at line 81 of file pes_packet_generator.cc.

@@ -289,9 +292,7 @@ class PesPacketGeneratorTe diff --git a/docs/d5/de2/structshaka_1_1media_1_1MuxerListenerFactory_1_1StreamData-members.html b/docs/d5/de2/structshaka_1_1media_1_1MuxerListenerFactory_1_1StreamData-members.html index fbd97f6c57..d57d1fbeee 100644 --- a/docs/d5/de2/structshaka_1_1media_1_1MuxerListenerFactory_1_1StreamData-members.html +++ b/docs/d5/de2/structshaka_1_1media_1_1MuxerListenerFactory_1_1StreamData-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
This is the complete list of members for shaka::media::MuxerListenerFactory::StreamData, including all inherited members.

- - - - - + + + + + + +
dash_accessiblities (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
dash_roles (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_characteristics (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_group_id (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_iframe_playlist_name (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_name (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
dash_only (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
dash_roles (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_characteristics (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_group_id (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_iframe_playlist_name (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_name (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_only (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
hls_playlist_name (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
media_info_output (defined in shaka::media::MuxerListenerFactory::StreamData)shaka::media::MuxerListenerFactory::StreamData
diff --git a/docs/d5/de3/structshaka_1_1PackagingParams.html b/docs/d5/de3/structshaka_1_1PackagingParams.html index ce2809c579..06135f7fec 100644 --- a/docs/d5/de3/structshaka_1_1PackagingParams.html +++ b/docs/d5/de3/structshaka_1_1PackagingParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::PackagingParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
  bool output_media_info = false   +bool single_threaded = false +  MpdParams mpd_params  DASH MPD related parameters.
@@ -140,6 +145,23 @@ std::string Definition at line 55 of file packager.h.

+
+ + +

◆ single_threaded

+ +
+
+ + + + +
bool shaka::PackagingParams::single_threaded = false
+
+

Only use a single thread to generate output. This is useful in tests to avoid non-deterministic outputs.

+ +

Definition at line 58 of file packager.h.

+
@@ -165,9 +187,7 @@ std::string  diff --git a/docs/d5/de9/replicator_8cc_source.html b/docs/d5/de9/replicator_8cc_source.html index 4a23bdc549..6130cae0dd 100644 --- a/docs/d5/de9/replicator_8cc_source.html +++ b/docs/d5/de9/replicator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/replicator/replicator.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
replicator.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/replicator/replicator.h"
8 
9 namespace shaka {
10 namespace media {
11 
12 Status Replicator::InitializeInternal() {
13  return Status::OK;
14 }
15 
16 Status Replicator::Process(std::unique_ptr<StreamData> stream_data) {
17  Status status;
18 
19  for (auto& out : output_handlers()) {
20  std::unique_ptr<StreamData> copy(new StreamData(*stream_data));
21  copy->stream_index = out.first;
22 
23  status.Update(Dispatch(std::move(copy)));
24  }
25 
26  return status;
27 }
28 
29 bool Replicator::ValidateOutputStreamIndex(size_t stream_index) const {
30  return true;
31 }
32 
33 Status Replicator::OnFlushRequest(size_t input_stream_index) {
34  DCHECK_EQ(input_stream_index, 0u);
35  return FlushAllDownstreams();
36 }
37 
38 } // namespace media
39 } // namespace shaka
Status Dispatch(std::unique_ptr< StreamData > stream_data) const
-
All the methods that are virtual are virtual for mocking.
-
Status FlushAllDownstreams()
Flush all connected downstream handlers.
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/replicator/replicator.h"
+
8 
+
9 namespace shaka {
+
10 namespace media {
+
11 
+
12 Status Replicator::InitializeInternal() {
+
13  return Status::OK;
+
14 }
+
15 
+
16 Status Replicator::Process(std::unique_ptr<StreamData> stream_data) {
+
17  Status status;
+
18 
+
19  for (auto& out : output_handlers()) {
+
20  std::unique_ptr<StreamData> copy(new StreamData(*stream_data));
+
21  copy->stream_index = out.first;
+
22 
+
23  status.Update(Dispatch(std::move(copy)));
+
24  }
+
25 
+
26  return status;
+
27 }
+
28 
+
29 bool Replicator::ValidateOutputStreamIndex(size_t stream_index) const {
+
30  return true;
+
31 }
+
32 
+
33 Status Replicator::OnFlushRequest(size_t input_stream_index) {
+
34  DCHECK_EQ(input_stream_index, 0u);
+
35  return FlushAllDownstreams();
+
36 }
+
37 
+
38 } // namespace media
+
39 } // namespace shaka
+
Status FlushAllDownstreams()
Flush all connected downstream handlers.
+
Status Dispatch(std::unique_ptr< StreamData > stream_data) const
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d5/dec/classshaka_1_1media_1_1WebMParserClient.html b/docs/d5/dec/classshaka_1_1media_1_1WebMParserClient.html index 331196d3cc..f2944b75b1 100644 --- a/docs/d5/dec/classshaka_1_1media_1_1WebMParserClient.html +++ b/docs/d5/dec/classshaka_1_1media_1_1WebMParserClient.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMParserClient Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::SegmentTestBase::ClusterParser -shaka::media::WebMAudioClient +shaka::media::WebMAudioClient shaka::media::WebMClusterParser -shaka::media::WebMContentEncodingsClient -shaka::media::WebMInfoParser -shaka::media::WebMTracksParser -shaka::media::WebMVideoClient - -
+shaka::media::WebMContentEncodingsClient +shaka::media::WebMInfoParser +shaka::media::WebMTracksParser +shaka::media::WebMVideoClient + + @@ -127,9 +130,7 @@ Protected Member Functions diff --git a/docs/d5/dec/decoder__configuration__record_8cc_source.html b/docs/d5/dec/decoder__configuration__record_8cc_source.html index dfcfa9e1b5..55933091cf 100644 --- a/docs/d5/dec/decoder__configuration__record_8cc_source.html +++ b/docs/d5/dec/decoder__configuration__record_8cc_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/codecs/decoder_configuration_record.cc Source File @@ -29,18 +29,21 @@

Public Member Functions

- + +/* @license-end */
decoder_configuration_record.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/decoder_configuration_record.h"
8 
9 namespace shaka {
10 namespace media {
11 
12 DecoderConfigurationRecord::DecoderConfigurationRecord() = default;
13 DecoderConfigurationRecord::~DecoderConfigurationRecord() = default;
14 
15 bool DecoderConfigurationRecord::Parse(const uint8_t* data, size_t data_size) {
16  data_.assign(data, data + data_size);
17  nalu_.clear();
18  return ParseInternal();
19 }
20 
22  nalu_.push_back(nalu);
23 }
24 
25 } // namespace media
26 } // namespace shaka
void AddNalu(const Nalu &nalu)
Adds the given Nalu to the configuration.
-
All the methods that are virtual are virtual for mocking.
-
bool Parse(const std::vector< uint8_t > &data)
- - +
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/decoder_configuration_record.h"
+
8 
+
9 namespace shaka {
+
10 namespace media {
+
11 
+
12 DecoderConfigurationRecord::DecoderConfigurationRecord() = default;
+
13 DecoderConfigurationRecord::~DecoderConfigurationRecord() = default;
+
14 
+
15 bool DecoderConfigurationRecord::Parse(const uint8_t* data, size_t data_size) {
+
16  data_.assign(data, data + data_size);
+
17  nalu_.clear();
+
18  return ParseInternal();
+
19 }
+
20 
+ +
22  nalu_.push_back(nalu);
+
23 }
+
24 
+
25 } // namespace media
+
26 } // namespace shaka
+ +
void AddNalu(const Nalu &nalu)
Adds the given Nalu to the configuration.
+
bool Parse(const std::vector< uint8_t > &data)
+ + + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d5/dec/structshaka_1_1media_1_1mp4_1_1WebVTTConfigurationBox-members.html b/docs/d5/dec/structshaka_1_1media_1_1mp4_1_1WebVTTConfigurationBox-members.html index 621ff1e5b7..df31c3c7c6 100644 --- a/docs/d5/dec/structshaka_1_1media_1_1mp4_1_1WebVTTConfigurationBox-members.html +++ b/docs/d5/dec/structshaka_1_1media_1_1mp4_1_1WebVTTConfigurationBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d5/def/ts__section__pmt_8h_source.html b/docs/d5/def/ts__section__pmt_8h_source.html index 3af0c511b5..21202ca3c6 100644 --- a/docs/d5/def/ts__section__pmt_8h_source.html +++ b/docs/d5/def/ts__section__pmt_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section_pmt.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
ts_section_pmt.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PMT_H_
6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PMT_H_
7 
8 #include "packager/base/callback.h"
9 #include "packager/base/compiler_specific.h"
10 #include "packager/media/formats/mp2t/ts_section_psi.h"
11 
12 namespace shaka {
13 namespace media {
14 namespace mp2t {
15 
16 class TsSectionPmt : public TsSectionPsi {
17  public:
18  // RegisterPesCb::Run(int pes_pid, int stream_type);
19  // Stream type is defined in
20  // "Table 2-34 – Stream type assignments" in H.222
21  typedef base::Callback<void(int, int)> RegisterPesCb;
22 
23  explicit TsSectionPmt(const RegisterPesCb& register_pes_cb);
24  ~TsSectionPmt() override;
25 
26  // Mpeg2TsPsiParser implementation.
27  bool ParsePsiSection(BitReader* bit_reader) override;
28  void ResetPsiSection() override;
29 
30  private:
31  RegisterPesCb register_pes_cb_;
32 
33  DISALLOW_COPY_AND_ASSIGN(TsSectionPmt);
34 };
35 
36 } // namespace mp2t
37 } // namespace media
38 } // namespace shaka
39 
40 #endif
-
A class to read bit streams.
Definition: bit_reader.h:17
-
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PMT_H_
+
6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PMT_H_
+
7 
+
8 #include "packager/base/callback.h"
+
9 #include "packager/base/compiler_specific.h"
+
10 #include "packager/media/formats/mp2t/ts_section_psi.h"
+
11 #include "packager/media/formats/mp2t/ts_stream_type.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 namespace mp2t {
+
16 
+
17 class TsSectionPmt : public TsSectionPsi {
+
18  public:
+
19  // RegisterPesCb::Run(int pes_pid, int stream_type);
+
20  // Stream type is defined in
+
21  // "Table 2-34 – Stream type assignments" in H.222
+
22  typedef base::Callback<void(int, TsStreamType, const uint8_t*, size_t)>
+
23  RegisterPesCb;
+
24 
+
25  explicit TsSectionPmt(const RegisterPesCb& register_pes_cb);
+
26  ~TsSectionPmt() override;
+
27 
+
28  // Mpeg2TsPsiParser implementation.
+
29  bool ParsePsiSection(BitReader* bit_reader) override;
+
30  void ResetPsiSection() override;
+
31 
+
32  private:
+
33  RegisterPesCb register_pes_cb_;
+
34 
+
35  DISALLOW_COPY_AND_ASSIGN(TsSectionPmt);
+
36 };
+
37 
+
38 } // namespace mp2t
+
39 } // namespace media
+
40 } // namespace shaka
+
41 
+
42 #endif
+
A class to read bit streams.
Definition: bit_reader.h:17
+ + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d5/df2/media__playlist_8cc_source.html b/docs/d5/df2/media__playlist_8cc_source.html index 0aa77f439f..6b3fd976df 100644 --- a/docs/d5/df2/media__playlist_8cc_source.html +++ b/docs/d5/df2/media__playlist_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/media_playlist.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
media_playlist.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/hls/base/media_playlist.h"
8 
9 #include <inttypes.h>
10 
11 #include <algorithm>
12 #include <cmath>
13 #include <memory>
14 
15 #include "packager/base/logging.h"
16 #include "packager/base/strings/string_number_conversions.h"
17 #include "packager/base/strings/stringprintf.h"
18 #include "packager/file/file.h"
19 #include "packager/hls/base/tag.h"
20 #include "packager/media/base/language_utils.h"
21 #include "packager/media/base/muxer_util.h"
22 #include "packager/version/version.h"
23 
24 namespace shaka {
25 namespace hls {
26 
27 namespace {
28 uint32_t GetTimeScale(const MediaInfo& media_info) {
29  if (media_info.has_reference_time_scale())
30  return media_info.reference_time_scale();
31 
32  if (media_info.has_video_info())
33  return media_info.video_info().time_scale();
34 
35  if (media_info.has_audio_info())
36  return media_info.audio_info().time_scale();
37  return 0u;
38 }
39 
40 std::string AdjustVideoCodec(const std::string& codec) {
41  // Apple does not like video formats with the parameter sets stored in the
42  // samples. It also fails mediastreamvalidator checks and some Apple devices /
43  // platforms refused to play.
44  // See https://apple.co/30n90DC 1.10 and
45  // https://github.com/google/shaka-packager/issues/587#issuecomment-489182182.
46  // Replaced with the corresponding formats with the parameter sets stored in
47  // the sample descriptions instead.
48  std::string adjusted_codec = codec;
49  std::string fourcc = codec.substr(0, 4);
50  if (fourcc == "avc3")
51  adjusted_codec = "avc1" + codec.substr(4);
52  else if (fourcc == "hev1")
53  adjusted_codec = "hvc1" + codec.substr(4);
54  else if (fourcc == "dvhe")
55  adjusted_codec = "dvh1" + codec.substr(4);
56  if (adjusted_codec != codec) {
57  VLOG(1) << "Adusting video codec string from " << codec << " to "
58  << adjusted_codec;
59  }
60  return adjusted_codec;
61 }
62 
63 // Duplicated from MpdUtils because:
64 // 1. MpdUtils header depends on libxml header, which is not in the deps here
65 // 2. GetLanguage depends on MediaInfo from packager/mpd/
66 // 3. Moving GetLanguage to LanguageUtils would create a a media => mpd dep.
67 // TODO(https://github.com/google/shaka-packager/issues/373): Fix this
68 // dependency situation and factor this out to a common location.
69 std::string GetLanguage(const MediaInfo& media_info) {
70  std::string lang;
71  if (media_info.has_audio_info()) {
72  lang = media_info.audio_info().language();
73  } else if (media_info.has_text_info()) {
74  lang = media_info.text_info().language();
75  }
76  return LanguageToShortestForm(lang);
77 }
78 
79 void AppendExtXMap(const MediaInfo& media_info, std::string* out) {
80  if (media_info.has_init_segment_url()) {
81  Tag tag("#EXT-X-MAP", out);
82  tag.AddQuotedString("URI", media_info.init_segment_url().data());
83  out->append("\n");
84  } else if (media_info.has_media_file_url() && media_info.has_init_range()) {
85  // It only makes sense for single segment media to have EXT-X-MAP if
86  // there is init_range.
87  Tag tag("#EXT-X-MAP", out);
88  tag.AddQuotedString("URI", media_info.media_file_url().data());
89 
90  if (media_info.has_init_range()) {
91  const uint64_t begin = media_info.init_range().begin();
92  const uint64_t end = media_info.init_range().end();
93  const uint64_t length = end - begin + 1;
94 
95  tag.AddQuotedNumberPair("BYTERANGE", length, '@', begin);
96  }
97 
98  out->append("\n");
99  } else {
100  // This media info does not need an ext-x-map tag.
101  }
102 }
103 
104 std::string CreatePlaylistHeader(
105  const MediaInfo& media_info,
106  uint32_t target_duration,
107  HlsPlaylistType type,
108  MediaPlaylist::MediaPlaylistStreamType stream_type,
109  int media_sequence_number,
110  int discontinuity_sequence_number) {
111  const std::string version = GetPackagerVersion();
112  std::string version_line;
113  if (!version.empty()) {
114  version_line =
115  base::StringPrintf("## Generated with %s version %s\n",
116  GetPackagerProjectUrl().c_str(), version.c_str());
117  }
118 
119  // 6 is required for EXT-X-MAP without EXT-X-I-FRAMES-ONLY.
120  std::string header = base::StringPrintf(
121  "#EXTM3U\n"
122  "#EXT-X-VERSION:6\n"
123  "%s"
124  "#EXT-X-TARGETDURATION:%d\n",
125  version_line.c_str(), target_duration);
126 
127  switch (type) {
128  case HlsPlaylistType::kVod:
129  header += "#EXT-X-PLAYLIST-TYPE:VOD\n";
130  break;
131  case HlsPlaylistType::kEvent:
132  header += "#EXT-X-PLAYLIST-TYPE:EVENT\n";
133  break;
134  case HlsPlaylistType::kLive:
135  if (media_sequence_number > 0) {
136  base::StringAppendF(&header, "#EXT-X-MEDIA-SEQUENCE:%d\n",
137  media_sequence_number);
138  }
139  if (discontinuity_sequence_number > 0) {
140  base::StringAppendF(&header, "#EXT-X-DISCONTINUITY-SEQUENCE:%d\n",
141  discontinuity_sequence_number);
142  }
143  break;
144  default:
145  NOTREACHED() << "Unexpected MediaPlaylistType " << static_cast<int>(type);
146  }
147  if (stream_type ==
148  MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly) {
149  base::StringAppendF(&header, "#EXT-X-I-FRAMES-ONLY\n");
150  }
151 
152  // Put EXT-X-MAP at the end since the rest of the playlist is about the
153  // segment and key info.
154  AppendExtXMap(media_info, &header);
155 
156  return header;
157 }
158 
159 class SegmentInfoEntry : public HlsEntry {
160  public:
161  // If |use_byte_range| true then this will append EXT-X-BYTERANGE
162  // after EXTINF.
163  // It uses |previous_segment_end_offset| to determine if it has to also
164  // specify the start byte offset in the tag.
165  // |start_time| is in timescale.
166  // |duration_seconds| is duration in seconds.
167  SegmentInfoEntry(const std::string& file_name,
168  int64_t start_time,
169  double duration_seconds,
170  bool use_byte_range,
171  uint64_t start_byte_offset,
172  uint64_t segment_file_size,
173  uint64_t previous_segment_end_offset);
174 
175  std::string ToString() override;
176  int64_t start_time() const { return start_time_; }
177  double duration_seconds() const { return duration_seconds_; }
178  void set_duration_seconds(double duration_seconds) {
179  duration_seconds_ = duration_seconds;
180  }
181 
182  private:
183  SegmentInfoEntry(const SegmentInfoEntry&) = delete;
184  SegmentInfoEntry& operator=(const SegmentInfoEntry&) = delete;
185 
186  const std::string file_name_;
187  const int64_t start_time_;
188  double duration_seconds_;
189  const bool use_byte_range_;
190  const uint64_t start_byte_offset_;
191  const uint64_t segment_file_size_;
192  const uint64_t previous_segment_end_offset_;
193 };
194 
195 SegmentInfoEntry::SegmentInfoEntry(const std::string& file_name,
196  int64_t start_time,
197  double duration_seconds,
198  bool use_byte_range,
199  uint64_t start_byte_offset,
200  uint64_t segment_file_size,
201  uint64_t previous_segment_end_offset)
202  : HlsEntry(HlsEntry::EntryType::kExtInf),
203  file_name_(file_name),
204  start_time_(start_time),
205  duration_seconds_(duration_seconds),
206  use_byte_range_(use_byte_range),
207  start_byte_offset_(start_byte_offset),
208  segment_file_size_(segment_file_size),
209  previous_segment_end_offset_(previous_segment_end_offset) {}
210 
211 std::string SegmentInfoEntry::ToString() {
212  std::string result = base::StringPrintf("#EXTINF:%.3f,", duration_seconds_);
213 
214  if (use_byte_range_) {
215  base::StringAppendF(&result, "\n#EXT-X-BYTERANGE:%" PRIu64,
216  segment_file_size_);
217  if (previous_segment_end_offset_ + 1 != start_byte_offset_) {
218  base::StringAppendF(&result, "@%" PRIu64, start_byte_offset_);
219  }
220  }
221 
222  base::StringAppendF(&result, "\n%s", file_name_.c_str());
223 
224  return result;
225 }
226 
227 class EncryptionInfoEntry : public HlsEntry {
228  public:
229  EncryptionInfoEntry(MediaPlaylist::EncryptionMethod method,
230  const std::string& url,
231  const std::string& key_id,
232  const std::string& iv,
233  const std::string& key_format,
234  const std::string& key_format_versions);
235 
236  std::string ToString() override;
237 
238  private:
239  EncryptionInfoEntry(const EncryptionInfoEntry&) = delete;
240  EncryptionInfoEntry& operator=(const EncryptionInfoEntry&) = delete;
241 
242  const MediaPlaylist::EncryptionMethod method_;
243  const std::string url_;
244  const std::string key_id_;
245  const std::string iv_;
246  const std::string key_format_;
247  const std::string key_format_versions_;
248 };
249 
250 EncryptionInfoEntry::EncryptionInfoEntry(MediaPlaylist::EncryptionMethod method,
251  const std::string& url,
252  const std::string& key_id,
253  const std::string& iv,
254  const std::string& key_format,
255  const std::string& key_format_versions)
256  : HlsEntry(HlsEntry::EntryType::kExtKey),
257  method_(method),
258  url_(url),
259  key_id_(key_id),
260  iv_(iv),
261  key_format_(key_format),
262  key_format_versions_(key_format_versions) {}
263 
264 std::string EncryptionInfoEntry::ToString() {
265  std::string tag_string;
266  Tag tag("#EXT-X-KEY", &tag_string);
267 
268  if (method_ == MediaPlaylist::EncryptionMethod::kSampleAes) {
269  tag.AddString("METHOD", "SAMPLE-AES");
270  } else if (method_ == MediaPlaylist::EncryptionMethod::kAes128) {
271  tag.AddString("METHOD", "AES-128");
272  } else if (method_ == MediaPlaylist::EncryptionMethod::kSampleAesCenc) {
273  tag.AddString("METHOD", "SAMPLE-AES-CTR");
274  } else {
275  DCHECK(method_ == MediaPlaylist::EncryptionMethod::kNone);
276  tag.AddString("METHOD", "NONE");
277  }
278 
279  tag.AddQuotedString("URI", url_);
280 
281  if (!key_id_.empty()) {
282  tag.AddString("KEYID", key_id_);
283  }
284  if (!iv_.empty()) {
285  tag.AddString("IV", iv_);
286  }
287  if (!key_format_versions_.empty()) {
288  tag.AddQuotedString("KEYFORMATVERSIONS", key_format_versions_);
289  }
290  if (!key_format_.empty()) {
291  tag.AddQuotedString("KEYFORMAT", key_format_);
292  }
293 
294  return tag_string;
295 }
296 
297 class DiscontinuityEntry : public HlsEntry {
298  public:
299  DiscontinuityEntry();
300 
301  std::string ToString() override;
302 
303  private:
304  DiscontinuityEntry(const DiscontinuityEntry&) = delete;
305  DiscontinuityEntry& operator=(const DiscontinuityEntry&) = delete;
306 };
307 
308 DiscontinuityEntry::DiscontinuityEntry()
309  : HlsEntry(HlsEntry::EntryType::kExtDiscontinuity) {}
310 
311 std::string DiscontinuityEntry::ToString() {
312  return "#EXT-X-DISCONTINUITY";
313 }
314 
315 class PlacementOpportunityEntry : public HlsEntry {
316  public:
317  PlacementOpportunityEntry();
318 
319  std::string ToString() override;
320 
321  private:
322  PlacementOpportunityEntry(const PlacementOpportunityEntry&) = delete;
323  PlacementOpportunityEntry& operator=(const PlacementOpportunityEntry&) =
324  delete;
325 };
326 
327 PlacementOpportunityEntry::PlacementOpportunityEntry()
328  : HlsEntry(HlsEntry::EntryType::kExtPlacementOpportunity) {}
329 
330 std::string PlacementOpportunityEntry::ToString() {
331  return "#EXT-X-PLACEMENT-OPPORTUNITY";
332 }
333 
334 } // namespace
335 
336 HlsEntry::HlsEntry(HlsEntry::EntryType type) : type_(type) {}
337 HlsEntry::~HlsEntry() {}
338 
340  const std::string& file_name,
341  const std::string& name,
342  const std::string& group_id)
343  : hls_params_(hls_params),
344  file_name_(file_name),
345  name_(name),
346  group_id_(group_id) {}
347 
348 MediaPlaylist::~MediaPlaylist() {}
349 
351  MediaPlaylistStreamType stream_type) {
352  stream_type_ = stream_type;
353 }
354 
355 void MediaPlaylist::SetCodecForTesting(const std::string& codec) {
356  codec_ = codec;
357 }
358 
360  language_ = language;
361 }
362 
364  const std::vector<std::string>& characteristics) {
365  characteristics_ = characteristics;
366 }
367 
368 bool MediaPlaylist::SetMediaInfo(const MediaInfo& media_info) {
369  const uint32_t time_scale = GetTimeScale(media_info);
370  if (time_scale == 0) {
371  LOG(ERROR) << "MediaInfo does not contain a valid timescale.";
372  return false;
373  }
374 
375  if (media_info.has_video_info()) {
376  stream_type_ = MediaPlaylistStreamType::kVideo;
377  codec_ = AdjustVideoCodec(media_info.video_info().codec());
378  } else if (media_info.has_audio_info()) {
379  stream_type_ = MediaPlaylistStreamType::kAudio;
380  codec_ = media_info.audio_info().codec();
381  } else {
382  stream_type_ = MediaPlaylistStreamType::kSubtitle;
383  codec_ = media_info.text_info().codec();
384  }
385 
386  time_scale_ = time_scale;
387  media_info_ = media_info;
388  language_ = GetLanguage(media_info);
389  use_byte_range_ = !media_info_.has_segment_template_url();
390  characteristics_ =
391  std::vector<std::string>(media_info_.hls_characteristics().begin(),
392  media_info_.hls_characteristics().end());
393  return true;
394 }
395 
396 void MediaPlaylist::SetSampleDuration(uint32_t sample_duration) {
397  if (media_info_.has_video_info())
398  media_info_.mutable_video_info()->set_frame_duration(sample_duration);
399 }
400 
401 void MediaPlaylist::AddSegment(const std::string& file_name,
402  int64_t start_time,
403  int64_t duration,
404  uint64_t start_byte_offset,
405  uint64_t size) {
406  if (stream_type_ == MediaPlaylistStreamType::kVideoIFramesOnly) {
407  if (key_frames_.empty())
408  return;
409 
410  AdjustLastSegmentInfoEntryDuration(key_frames_.front().timestamp);
411 
412  for (auto iter = key_frames_.begin(); iter != key_frames_.end(); ++iter) {
413  // Last entry duration may be adjusted later when the next iframe becomes
414  // available.
415  const int64_t next_timestamp = std::next(iter) == key_frames_.end()
416  ? (start_time + duration)
417  : std::next(iter)->timestamp;
418  AddSegmentInfoEntry(file_name, iter->timestamp,
419  next_timestamp - iter->timestamp,
420  iter->start_byte_offset, iter->size);
421  }
422  key_frames_.clear();
423  return;
424  }
425  return AddSegmentInfoEntry(file_name, start_time, duration, start_byte_offset,
426  size);
427 }
428 
429 void MediaPlaylist::AddKeyFrame(int64_t timestamp,
430  uint64_t start_byte_offset,
431  uint64_t size) {
432  if (stream_type_ != MediaPlaylistStreamType::kVideoIFramesOnly) {
433  if (stream_type_ != MediaPlaylistStreamType::kVideo) {
434  LOG(WARNING)
435  << "I-Frames Only playlist applies to video renditions only.";
436  return;
437  }
438  stream_type_ = MediaPlaylistStreamType::kVideoIFramesOnly;
439  use_byte_range_ = true;
440  }
441  key_frames_.push_back({timestamp, start_byte_offset, size});
442 }
443 
444 void MediaPlaylist::AddEncryptionInfo(MediaPlaylist::EncryptionMethod method,
445  const std::string& url,
446  const std::string& key_id,
447  const std::string& iv,
448  const std::string& key_format,
449  const std::string& key_format_versions) {
450  if (!inserted_discontinuity_tag_) {
451  // Insert discontinuity tag only for the first EXT-X-KEY, only if there
452  // are non-encrypted media segments.
453  if (!entries_.empty())
454  entries_.emplace_back(new DiscontinuityEntry());
455  inserted_discontinuity_tag_ = true;
456  }
457  entries_.emplace_back(new EncryptionInfoEntry(
458  method, url, key_id, iv, key_format, key_format_versions));
459 }
460 
462  entries_.emplace_back(new PlacementOpportunityEntry());
463 }
464 
465 bool MediaPlaylist::WriteToFile(const std::string& file_path) {
466  if (!target_duration_set_) {
468  }
469 
470  std::string content = CreatePlaylistHeader(
471  media_info_, target_duration_, hls_params_.playlist_type, stream_type_,
472  media_sequence_number_, discontinuity_sequence_number_);
473 
474  for (const auto& entry : entries_)
475  base::StringAppendF(&content, "%s\n", entry->ToString().c_str());
476 
477  if (hls_params_.playlist_type == HlsPlaylistType::kVod) {
478  content += "#EXT-X-ENDLIST\n";
479  }
480 
481  if (!File::WriteFileAtomically(file_path.c_str(), content)) {
482  LOG(ERROR) << "Failed to write playlist to: " << file_path;
483  return false;
484  }
485  return true;
486 }
487 
488 uint64_t MediaPlaylist::MaxBitrate() const {
489  if (media_info_.has_bandwidth())
490  return media_info_.bandwidth();
491  return bandwidth_estimator_.Max();
492 }
493 
494 uint64_t MediaPlaylist::AvgBitrate() const {
495  return bandwidth_estimator_.Estimate();
496 }
497 
499  return longest_segment_duration_seconds_;
500 }
501 
502 void MediaPlaylist::SetTargetDuration(uint32_t target_duration) {
503  if (target_duration_set_) {
504  if (target_duration_ == target_duration)
505  return;
506  VLOG(1) << "Updating target duration from " << target_duration << " to "
507  << target_duration_;
508  }
509  target_duration_ = target_duration;
510  target_duration_set_ = true;
511 }
512 
514  return media_info_.audio_info().num_channels();
515 }
516 
518  uint32_t* height) const {
519  DCHECK(width);
520  DCHECK(height);
521  if (media_info_.has_video_info()) {
522  const double pixel_aspect_ratio =
523  media_info_.video_info().pixel_height() > 0
524  ? static_cast<double>(media_info_.video_info().pixel_width()) /
525  media_info_.video_info().pixel_height()
526  : 1.0;
527  *width = static_cast<uint32_t>(media_info_.video_info().width() *
528  pixel_aspect_ratio);
529  *height = media_info_.video_info().height();
530  return true;
531  }
532  return false;
533 }
534 
535 std::string MediaPlaylist::GetVideoRange() const {
536  // Dolby Vision (dvh1 or dvhe) is always HDR.
537  if (codec_.find("dvh") == 0)
538  return "PQ";
539 
540  // HLS specification:
541  // https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-02#section-4.4.4.2
542  switch (media_info_.video_info().transfer_characteristics()) {
543  case 1:
544  return "SDR";
545  case 16:
546  case 18:
547  return "PQ";
548  default:
549  // Leave it empty if we do not have the transfer characteristics
550  // information.
551  return "";
552  }
553 }
554 
556  if (media_info_.video_info().frame_duration() == 0)
557  return 0;
558  return static_cast<double>(time_scale_) /
559  media_info_.video_info().frame_duration();
560 }
561 
562 void MediaPlaylist::AddSegmentInfoEntry(const std::string& segment_file_name,
563  int64_t start_time,
564  int64_t duration,
565  uint64_t start_byte_offset,
566  uint64_t size) {
567  if (time_scale_ == 0) {
568  LOG(WARNING) << "Timescale is not set and the duration for " << duration
569  << " cannot be calculated. The output will be wrong.";
570 
571  entries_.emplace_back(new SegmentInfoEntry(
572  segment_file_name, 0.0, 0.0, use_byte_range_, start_byte_offset, size,
573  previous_segment_end_offset_));
574  return;
575  }
576 
577  // In order for the oldest segment to be accessible for at least
578  // |time_shift_buffer_depth| seconds, the latest segment should not be in the
579  // sliding window since the player could be playing any part of the latest
580  // segment. So the current segment duration is added to the sum of segment
581  // durations (in the manifest/playlist) after sliding the window.
582  SlideWindow();
583 
584  const double segment_duration_seconds =
585  static_cast<double>(duration) / time_scale_;
586  longest_segment_duration_seconds_ =
587  std::max(longest_segment_duration_seconds_, segment_duration_seconds);
588  bandwidth_estimator_.AddBlock(size, segment_duration_seconds);
589  current_buffer_depth_ += segment_duration_seconds;
590 
591  if (!entries_.empty() &&
592  entries_.back()->type() == HlsEntry::EntryType::kExtInf) {
593  const SegmentInfoEntry* segment_info =
594  static_cast<SegmentInfoEntry*>(entries_.back().get());
595  if (segment_info->start_time() > start_time) {
596  LOG(WARNING)
597  << "Insert a discontinuity tag after the segment with start time "
598  << segment_info->start_time() << " as the next segment starts at "
599  << start_time << ".";
600  entries_.emplace_back(new DiscontinuityEntry());
601  }
602  }
603 
604  entries_.emplace_back(new SegmentInfoEntry(
605  segment_file_name, start_time, segment_duration_seconds, use_byte_range_,
606  start_byte_offset, size, previous_segment_end_offset_));
607  previous_segment_end_offset_ = start_byte_offset + size - 1;
608 }
609 
610 void MediaPlaylist::AdjustLastSegmentInfoEntryDuration(int64_t next_timestamp) {
611  if (time_scale_ == 0)
612  return;
613 
614  const double next_timestamp_seconds =
615  static_cast<double>(next_timestamp) / time_scale_;
616 
617  for (auto iter = entries_.rbegin(); iter != entries_.rend(); ++iter) {
618  if (iter->get()->type() == HlsEntry::EntryType::kExtInf) {
619  SegmentInfoEntry* segment_info =
620  reinterpret_cast<SegmentInfoEntry*>(iter->get());
621 
622  const double segment_duration_seconds =
623  next_timestamp_seconds -
624  static_cast<double>(segment_info->start_time()) / time_scale_;
625  // It could be negative if timestamp messed up.
626  if (segment_duration_seconds > 0)
627  segment_info->set_duration_seconds(segment_duration_seconds);
628  longest_segment_duration_seconds_ =
629  std::max(longest_segment_duration_seconds_, segment_duration_seconds);
630  break;
631  }
632  }
633 }
634 
635 // TODO(kqyang): Right now this class manages the segments including the
636 // deletion of segments when it is no longer needed. However, this class does
637 // not have access to the segment file paths, which is already translated to
638 // segment URLs by HlsNotifier. We have to re-generate segment file paths from
639 // segment template here in order to delete the old segments.
640 // To make the pipeline cleaner, we should move all file manipulations including
641 // segment management to an intermediate layer between HlsNotifier and
642 // MediaPlaylist.
643 void MediaPlaylist::SlideWindow() {
644  if (hls_params_.time_shift_buffer_depth <= 0.0 ||
645  hls_params_.playlist_type != HlsPlaylistType::kLive) {
646  return;
647  }
648  DCHECK_GT(time_scale_, 0u);
649 
650  if (current_buffer_depth_ <= hls_params_.time_shift_buffer_depth)
651  return;
652 
653  // Temporary list to hold the EXT-X-KEYs. For example, this allows us to
654  // remove <3> without removing <1> and <2> below (<1> and <2> are moved to the
655  // temporary list and added back later).
656  // #EXT-X-KEY <1>
657  // #EXT-X-KEY <2>
658  // #EXTINF <3>
659  // #EXTINF <4>
660  std::list<std::unique_ptr<HlsEntry>> ext_x_keys;
661  // Consecutive key entries are either fully removed or not removed at all.
662  // Keep track of entry types so we know if it is consecutive key entries.
663  HlsEntry::EntryType prev_entry_type = HlsEntry::EntryType::kExtInf;
664 
665  std::list<std::unique_ptr<HlsEntry>>::iterator last = entries_.begin();
666  for (; last != entries_.end(); ++last) {
667  HlsEntry::EntryType entry_type = last->get()->type();
668  if (entry_type == HlsEntry::EntryType::kExtKey) {
669  if (prev_entry_type != HlsEntry::EntryType::kExtKey)
670  ext_x_keys.clear();
671  ext_x_keys.push_back(std::move(*last));
672  } else if (entry_type == HlsEntry::EntryType::kExtDiscontinuity) {
673  ++discontinuity_sequence_number_;
674  } else {
675  DCHECK_EQ(entry_type, HlsEntry::EntryType::kExtInf);
676 
677  const SegmentInfoEntry& segment_info =
678  *reinterpret_cast<SegmentInfoEntry*>(last->get());
679  // Remove the current segment only if it falls completely out of time
680  // shift buffer range.
681  const bool segment_within_time_shift_buffer =
682  current_buffer_depth_ - segment_info.duration_seconds() <
683  hls_params_.time_shift_buffer_depth;
684  if (segment_within_time_shift_buffer)
685  break;
686  current_buffer_depth_ -= segment_info.duration_seconds();
687  RemoveOldSegment(segment_info.start_time());
688  media_sequence_number_++;
689  }
690  prev_entry_type = entry_type;
691  }
692  entries_.erase(entries_.begin(), last);
693  // Add key entries back.
694  entries_.insert(entries_.begin(), std::make_move_iterator(ext_x_keys.begin()),
695  std::make_move_iterator(ext_x_keys.end()));
696 }
697 
698 void MediaPlaylist::RemoveOldSegment(int64_t start_time) {
699  if (hls_params_.preserved_segments_outside_live_window == 0)
700  return;
701  if (stream_type_ == MediaPlaylistStreamType::kVideoIFramesOnly)
702  return;
703 
704  segments_to_be_removed_.push_back(
705  media::GetSegmentName(media_info_.segment_template(), start_time,
706  media_sequence_number_, media_info_.bandwidth()));
707  while (segments_to_be_removed_.size() >
709  VLOG(2) << "Deleting " << segments_to_be_removed_.front();
710  if (!File::Delete(segments_to_be_removed_.front().c_str())) {
711  LOG(WARNING) << "Failed to delete " << segments_to_be_removed_.front()
712  << "; Will retry later.";
713  break;
714  }
715  segments_to_be_removed_.pop_front();
716  }
717 }
718 
719 } // namespace hls
720 } // namespace shaka
void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type)
For testing only.
-
static bool Delete(const char *file_name)
Definition: file.cc:198
-
HlsPlaylistType
Definition: hls_params.h:16
-
virtual void AddKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
-
virtual uint64_t MaxBitrate() const
-
HLS related parameters.
Definition: hls_params.h:23
-
size_t preserved_segments_outside_live_window
Definition: hls_params.h:40
-
std::string LanguageToShortestForm(const std::string &language)
-
virtual void SetTargetDuration(uint32_t target_duration)
-
const std::string & language() const
-
All the methods that are virtual are virtual for mocking.
-
virtual bool SetMediaInfo(const MediaInfo &media_info)
-
MediaPlaylist(const HlsParams &hls_params, const std::string &file_name, const std::string &name, const std::string &group_id)
-
void AddBlock(uint64_t size_in_bytes, double duration)
-
double time_shift_buffer_depth
Definition: hls_params.h:33
- -
virtual void AddSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t start_byte_offset, uint64_t size)
-
void SetLanguageForTesting(const std::string &language)
For testing only.
-
virtual double GetLongestSegmentDuration() const
-
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:262
-
virtual double GetFrameRate() const
-
virtual void AddPlacementOpportunity()
-
virtual void AddEncryptionInfo(EncryptionMethod method, const std::string &url, const std::string &key_id, const std::string &iv, const std::string &key_format, const std::string &key_format_versions)
-
virtual bool GetDisplayResolution(uint32_t *width, uint32_t *height) const
- -
virtual bool WriteToFile(const std::string &file_path)
-
void SetCodecForTesting(const std::string &codec)
For testing only.
-
virtual std::string GetVideoRange() const
-
virtual int GetNumChannels() const
-
virtual void SetSampleDuration(uint32_t sample_duration)
-
void SetCharacteristicsForTesting(const std::vector< std::string > &characteristics)
For testing only.
-
virtual uint64_t AvgBitrate() const
-
HlsPlaylistType playlist_type
HLS playlist type. See HLS specification for details.
Definition: hls_params.h:25
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/hls/base/media_playlist.h"
+
8 
+
9 #include <inttypes.h>
+
10 
+
11 #include <algorithm>
+
12 #include <cmath>
+
13 #include <memory>
+
14 
+
15 #include "packager/base/logging.h"
+
16 #include "packager/base/strings/string_number_conversions.h"
+
17 #include "packager/base/strings/stringprintf.h"
+
18 #include "packager/file/file.h"
+
19 #include "packager/hls/base/tag.h"
+
20 #include "packager/media/base/language_utils.h"
+
21 #include "packager/media/base/muxer_util.h"
+
22 #include "packager/version/version.h"
+
23 
+
24 namespace shaka {
+
25 namespace hls {
+
26 
+
27 namespace {
+
28 uint32_t GetTimeScale(const MediaInfo& media_info) {
+
29  if (media_info.has_reference_time_scale())
+
30  return media_info.reference_time_scale();
+
31 
+
32  if (media_info.has_video_info())
+
33  return media_info.video_info().time_scale();
+
34 
+
35  if (media_info.has_audio_info())
+
36  return media_info.audio_info().time_scale();
+
37  return 0u;
+
38 }
+
39 
+
40 std::string AdjustVideoCodec(const std::string& codec) {
+
41  // Apple does not like video formats with the parameter sets stored in the
+
42  // samples. It also fails mediastreamvalidator checks and some Apple devices /
+
43  // platforms refused to play.
+
44  // See https://apple.co/30n90DC 1.10 and
+
45  // https://github.com/google/shaka-packager/issues/587#issuecomment-489182182.
+
46  // Replaced with the corresponding formats with the parameter sets stored in
+
47  // the sample descriptions instead.
+
48  std::string adjusted_codec = codec;
+
49  std::string fourcc = codec.substr(0, 4);
+
50  if (fourcc == "avc3")
+
51  adjusted_codec = "avc1" + codec.substr(4);
+
52  else if (fourcc == "hev1")
+
53  adjusted_codec = "hvc1" + codec.substr(4);
+
54  else if (fourcc == "dvhe")
+
55  adjusted_codec = "dvh1" + codec.substr(4);
+
56  if (adjusted_codec != codec) {
+
57  VLOG(1) << "Adusting video codec string from " << codec << " to "
+
58  << adjusted_codec;
+
59  }
+
60  return adjusted_codec;
+
61 }
+
62 
+
63 // Duplicated from MpdUtils because:
+
64 // 1. MpdUtils header depends on libxml header, which is not in the deps here
+
65 // 2. GetLanguage depends on MediaInfo from packager/mpd/
+
66 // 3. Moving GetLanguage to LanguageUtils would create a a media => mpd dep.
+
67 // TODO(https://github.com/google/shaka-packager/issues/373): Fix this
+
68 // dependency situation and factor this out to a common location.
+
69 std::string GetLanguage(const MediaInfo& media_info) {
+
70  std::string lang;
+
71  if (media_info.has_audio_info()) {
+
72  lang = media_info.audio_info().language();
+
73  } else if (media_info.has_text_info()) {
+
74  lang = media_info.text_info().language();
+
75  }
+
76  return LanguageToShortestForm(lang);
+
77 }
+
78 
+
79 void AppendExtXMap(const MediaInfo& media_info, std::string* out) {
+
80  if (media_info.has_init_segment_url()) {
+
81  Tag tag("#EXT-X-MAP", out);
+
82  tag.AddQuotedString("URI", media_info.init_segment_url().data());
+
83  out->append("\n");
+
84  } else if (media_info.has_media_file_url() && media_info.has_init_range()) {
+
85  // It only makes sense for single segment media to have EXT-X-MAP if
+
86  // there is init_range.
+
87  Tag tag("#EXT-X-MAP", out);
+
88  tag.AddQuotedString("URI", media_info.media_file_url().data());
+
89 
+
90  if (media_info.has_init_range()) {
+
91  const uint64_t begin = media_info.init_range().begin();
+
92  const uint64_t end = media_info.init_range().end();
+
93  const uint64_t length = end - begin + 1;
+
94 
+
95  tag.AddQuotedNumberPair("BYTERANGE", length, '@', begin);
+
96  }
+
97 
+
98  out->append("\n");
+
99  } else {
+
100  // This media info does not need an ext-x-map tag.
+
101  }
+
102 }
+
103 
+
104 std::string CreatePlaylistHeader(
+
105  const MediaInfo& media_info,
+
106  uint32_t target_duration,
+
107  HlsPlaylistType type,
+
108  MediaPlaylist::MediaPlaylistStreamType stream_type,
+
109  uint32_t media_sequence_number,
+
110  int discontinuity_sequence_number) {
+
111  const std::string version = GetPackagerVersion();
+
112  std::string version_line;
+
113  if (!version.empty()) {
+
114  version_line =
+
115  base::StringPrintf("## Generated with %s version %s\n",
+
116  GetPackagerProjectUrl().c_str(), version.c_str());
+
117  }
+
118 
+
119  // 6 is required for EXT-X-MAP without EXT-X-I-FRAMES-ONLY.
+
120  std::string header = base::StringPrintf(
+
121  "#EXTM3U\n"
+
122  "#EXT-X-VERSION:6\n"
+
123  "%s"
+
124  "#EXT-X-TARGETDURATION:%d\n",
+
125  version_line.c_str(), target_duration);
+
126 
+
127  switch (type) {
+
128  case HlsPlaylistType::kVod:
+
129  header += "#EXT-X-PLAYLIST-TYPE:VOD\n";
+
130  break;
+
131  case HlsPlaylistType::kEvent:
+
132  header += "#EXT-X-PLAYLIST-TYPE:EVENT\n";
+
133  break;
+
134  case HlsPlaylistType::kLive:
+
135  if (media_sequence_number > 0) {
+
136  base::StringAppendF(&header, "#EXT-X-MEDIA-SEQUENCE:%d\n",
+
137  media_sequence_number);
+
138  }
+
139  if (discontinuity_sequence_number > 0) {
+
140  base::StringAppendF(&header, "#EXT-X-DISCONTINUITY-SEQUENCE:%d\n",
+
141  discontinuity_sequence_number);
+
142  }
+
143  break;
+
144  default:
+
145  NOTREACHED() << "Unexpected MediaPlaylistType " << static_cast<int>(type);
+
146  }
+
147  if (stream_type ==
+
148  MediaPlaylist::MediaPlaylistStreamType::kVideoIFramesOnly) {
+
149  base::StringAppendF(&header, "#EXT-X-I-FRAMES-ONLY\n");
+
150  }
+
151 
+
152  // Put EXT-X-MAP at the end since the rest of the playlist is about the
+
153  // segment and key info.
+
154  AppendExtXMap(media_info, &header);
+
155 
+
156  return header;
+
157 }
+
158 
+
159 class SegmentInfoEntry : public HlsEntry {
+
160  public:
+
161  // If |use_byte_range| true then this will append EXT-X-BYTERANGE
+
162  // after EXTINF.
+
163  // It uses |previous_segment_end_offset| to determine if it has to also
+
164  // specify the start byte offset in the tag.
+
165  // |start_time| is in timescale.
+
166  // |duration_seconds| is duration in seconds.
+
167  SegmentInfoEntry(const std::string& file_name,
+
168  int64_t start_time,
+
169  double duration_seconds,
+
170  bool use_byte_range,
+
171  uint64_t start_byte_offset,
+
172  uint64_t segment_file_size,
+
173  uint64_t previous_segment_end_offset);
+
174 
+
175  std::string ToString() override;
+
176  int64_t start_time() const { return start_time_; }
+
177  double duration_seconds() const { return duration_seconds_; }
+
178  void set_duration_seconds(double duration_seconds) {
+
179  duration_seconds_ = duration_seconds;
+
180  }
+
181 
+
182  private:
+
183  SegmentInfoEntry(const SegmentInfoEntry&) = delete;
+
184  SegmentInfoEntry& operator=(const SegmentInfoEntry&) = delete;
+
185 
+
186  const std::string file_name_;
+
187  const int64_t start_time_;
+
188  double duration_seconds_;
+
189  const bool use_byte_range_;
+
190  const uint64_t start_byte_offset_;
+
191  const uint64_t segment_file_size_;
+
192  const uint64_t previous_segment_end_offset_;
+
193 };
+
194 
+
195 SegmentInfoEntry::SegmentInfoEntry(const std::string& file_name,
+
196  int64_t start_time,
+
197  double duration_seconds,
+
198  bool use_byte_range,
+
199  uint64_t start_byte_offset,
+
200  uint64_t segment_file_size,
+
201  uint64_t previous_segment_end_offset)
+
202  : HlsEntry(HlsEntry::EntryType::kExtInf),
+
203  file_name_(file_name),
+
204  start_time_(start_time),
+
205  duration_seconds_(duration_seconds),
+
206  use_byte_range_(use_byte_range),
+
207  start_byte_offset_(start_byte_offset),
+
208  segment_file_size_(segment_file_size),
+
209  previous_segment_end_offset_(previous_segment_end_offset) {}
+
210 
+
211 std::string SegmentInfoEntry::ToString() {
+
212  std::string result = base::StringPrintf("#EXTINF:%.3f,", duration_seconds_);
+
213 
+
214  if (use_byte_range_) {
+
215  base::StringAppendF(&result, "\n#EXT-X-BYTERANGE:%" PRIu64,
+
216  segment_file_size_);
+
217  if (previous_segment_end_offset_ + 1 != start_byte_offset_) {
+
218  base::StringAppendF(&result, "@%" PRIu64, start_byte_offset_);
+
219  }
+
220  }
+
221 
+
222  base::StringAppendF(&result, "\n%s", file_name_.c_str());
+
223 
+
224  return result;
+
225 }
+
226 
+
227 class EncryptionInfoEntry : public HlsEntry {
+
228  public:
+
229  EncryptionInfoEntry(MediaPlaylist::EncryptionMethod method,
+
230  const std::string& url,
+
231  const std::string& key_id,
+
232  const std::string& iv,
+
233  const std::string& key_format,
+
234  const std::string& key_format_versions);
+
235 
+
236  std::string ToString() override;
+
237 
+
238  private:
+
239  EncryptionInfoEntry(const EncryptionInfoEntry&) = delete;
+
240  EncryptionInfoEntry& operator=(const EncryptionInfoEntry&) = delete;
+
241 
+
242  const MediaPlaylist::EncryptionMethod method_;
+
243  const std::string url_;
+
244  const std::string key_id_;
+
245  const std::string iv_;
+
246  const std::string key_format_;
+
247  const std::string key_format_versions_;
+
248 };
+
249 
+
250 EncryptionInfoEntry::EncryptionInfoEntry(MediaPlaylist::EncryptionMethod method,
+
251  const std::string& url,
+
252  const std::string& key_id,
+
253  const std::string& iv,
+
254  const std::string& key_format,
+
255  const std::string& key_format_versions)
+
256  : HlsEntry(HlsEntry::EntryType::kExtKey),
+
257  method_(method),
+
258  url_(url),
+
259  key_id_(key_id),
+
260  iv_(iv),
+
261  key_format_(key_format),
+
262  key_format_versions_(key_format_versions) {}
+
263 
+
264 std::string EncryptionInfoEntry::ToString() {
+
265  std::string tag_string;
+
266  Tag tag("#EXT-X-KEY", &tag_string);
+
267 
+
268  if (method_ == MediaPlaylist::EncryptionMethod::kSampleAes) {
+
269  tag.AddString("METHOD", "SAMPLE-AES");
+
270  } else if (method_ == MediaPlaylist::EncryptionMethod::kAes128) {
+
271  tag.AddString("METHOD", "AES-128");
+
272  } else if (method_ == MediaPlaylist::EncryptionMethod::kSampleAesCenc) {
+
273  tag.AddString("METHOD", "SAMPLE-AES-CTR");
+
274  } else {
+
275  DCHECK(method_ == MediaPlaylist::EncryptionMethod::kNone);
+
276  tag.AddString("METHOD", "NONE");
+
277  }
+
278 
+
279  tag.AddQuotedString("URI", url_);
+
280 
+
281  if (!key_id_.empty()) {
+
282  tag.AddString("KEYID", key_id_);
+
283  }
+
284  if (!iv_.empty()) {
+
285  tag.AddString("IV", iv_);
+
286  }
+
287  if (!key_format_versions_.empty()) {
+
288  tag.AddQuotedString("KEYFORMATVERSIONS", key_format_versions_);
+
289  }
+
290  if (!key_format_.empty()) {
+
291  tag.AddQuotedString("KEYFORMAT", key_format_);
+
292  }
+
293 
+
294  return tag_string;
+
295 }
+
296 
+
297 class DiscontinuityEntry : public HlsEntry {
+
298  public:
+
299  DiscontinuityEntry();
+
300 
+
301  std::string ToString() override;
+
302 
+
303  private:
+
304  DiscontinuityEntry(const DiscontinuityEntry&) = delete;
+
305  DiscontinuityEntry& operator=(const DiscontinuityEntry&) = delete;
+
306 };
+
307 
+
308 DiscontinuityEntry::DiscontinuityEntry()
+
309  : HlsEntry(HlsEntry::EntryType::kExtDiscontinuity) {}
+
310 
+
311 std::string DiscontinuityEntry::ToString() {
+
312  return "#EXT-X-DISCONTINUITY";
+
313 }
+
314 
+
315 class PlacementOpportunityEntry : public HlsEntry {
+
316  public:
+
317  PlacementOpportunityEntry();
+
318 
+
319  std::string ToString() override;
+
320 
+
321  private:
+
322  PlacementOpportunityEntry(const PlacementOpportunityEntry&) = delete;
+
323  PlacementOpportunityEntry& operator=(const PlacementOpportunityEntry&) =
+
324  delete;
+
325 };
+
326 
+
327 PlacementOpportunityEntry::PlacementOpportunityEntry()
+
328  : HlsEntry(HlsEntry::EntryType::kExtPlacementOpportunity) {}
+
329 
+
330 std::string PlacementOpportunityEntry::ToString() {
+
331  return "#EXT-X-PLACEMENT-OPPORTUNITY";
+
332 }
+
333 
+
334 } // namespace
+
335 
+
336 HlsEntry::HlsEntry(HlsEntry::EntryType type) : type_(type) {}
+
337 HlsEntry::~HlsEntry() {}
+
338 
+
339 MediaPlaylist::MediaPlaylist(const HlsParams& hls_params,
+
340  const std::string& file_name,
+
341  const std::string& name,
+
342  const std::string& group_id)
+
343  : hls_params_(hls_params),
+
344  file_name_(file_name),
+
345  name_(name),
+
346  group_id_(group_id),
+
347  media_sequence_number_(hls_params_.media_sequence_number) {
+
348  // When there's a forced media_sequence_number, start with discontinuity
+
349  if (media_sequence_number_ > 0)
+
350  entries_.emplace_back(new DiscontinuityEntry());
+
351  }
+
352 
+
353 MediaPlaylist::~MediaPlaylist() {}
+
354 
+ +
356  MediaPlaylistStreamType stream_type) {
+
357  stream_type_ = stream_type;
+
358 }
+
359 
+
360 void MediaPlaylist::SetCodecForTesting(const std::string& codec) {
+
361  codec_ = codec;
+
362 }
+
363 
+
364 void MediaPlaylist::SetLanguageForTesting(const std::string& language) {
+
365  language_ = language;
+
366 }
+
367 
+ +
369  const std::vector<std::string>& characteristics) {
+
370  characteristics_ = characteristics;
+
371 }
+
372 
+
373 bool MediaPlaylist::SetMediaInfo(const MediaInfo& media_info) {
+
374  const uint32_t time_scale = GetTimeScale(media_info);
+
375  if (time_scale == 0) {
+
376  LOG(ERROR) << "MediaInfo does not contain a valid timescale.";
+
377  return false;
+
378  }
+
379 
+
380  if (media_info.has_video_info()) {
+
381  stream_type_ = MediaPlaylistStreamType::kVideo;
+
382  codec_ = AdjustVideoCodec(media_info.video_info().codec());
+
383  } else if (media_info.has_audio_info()) {
+
384  stream_type_ = MediaPlaylistStreamType::kAudio;
+
385  codec_ = media_info.audio_info().codec();
+
386  } else {
+
387  stream_type_ = MediaPlaylistStreamType::kSubtitle;
+
388  codec_ = media_info.text_info().codec();
+
389  }
+
390 
+
391  time_scale_ = time_scale;
+
392  media_info_ = media_info;
+
393  language_ = GetLanguage(media_info);
+
394  use_byte_range_ = !media_info_.has_segment_template_url() &&
+
395  media_info_.container_type() != MediaInfo::CONTAINER_TEXT;
+
396  characteristics_ =
+
397  std::vector<std::string>(media_info_.hls_characteristics().begin(),
+
398  media_info_.hls_characteristics().end());
+
399 
+
400  return true;
+
401 }
+
402 
+
403 void MediaPlaylist::SetSampleDuration(uint32_t sample_duration) {
+
404  if (media_info_.has_video_info())
+
405  media_info_.mutable_video_info()->set_frame_duration(sample_duration);
+
406 }
+
407 
+
408 void MediaPlaylist::AddSegment(const std::string& file_name,
+
409  int64_t start_time,
+
410  int64_t duration,
+
411  uint64_t start_byte_offset,
+
412  uint64_t size) {
+
413  if (stream_type_ == MediaPlaylistStreamType::kVideoIFramesOnly) {
+
414  if (key_frames_.empty())
+
415  return;
+
416 
+
417  AdjustLastSegmentInfoEntryDuration(key_frames_.front().timestamp);
+
418 
+
419  for (auto iter = key_frames_.begin(); iter != key_frames_.end(); ++iter) {
+
420  // Last entry duration may be adjusted later when the next iframe becomes
+
421  // available.
+
422  const int64_t next_timestamp = std::next(iter) == key_frames_.end()
+
423  ? (start_time + duration)
+
424  : std::next(iter)->timestamp;
+
425  AddSegmentInfoEntry(file_name, iter->timestamp,
+
426  next_timestamp - iter->timestamp,
+
427  iter->start_byte_offset, iter->size);
+
428  }
+
429  key_frames_.clear();
+
430  return;
+
431  }
+
432  return AddSegmentInfoEntry(file_name, start_time, duration, start_byte_offset,
+
433  size);
+
434 }
+
435 
+
436 void MediaPlaylist::AddKeyFrame(int64_t timestamp,
+
437  uint64_t start_byte_offset,
+
438  uint64_t size) {
+
439  if (stream_type_ != MediaPlaylistStreamType::kVideoIFramesOnly) {
+
440  if (stream_type_ != MediaPlaylistStreamType::kVideo) {
+
441  LOG(WARNING)
+
442  << "I-Frames Only playlist applies to video renditions only.";
+
443  return;
+
444  }
+
445  stream_type_ = MediaPlaylistStreamType::kVideoIFramesOnly;
+
446  use_byte_range_ = true;
+
447  }
+
448  key_frames_.push_back({timestamp, start_byte_offset, size});
+
449 }
+
450 
+
451 void MediaPlaylist::AddEncryptionInfo(MediaPlaylist::EncryptionMethod method,
+
452  const std::string& url,
+
453  const std::string& key_id,
+
454  const std::string& iv,
+
455  const std::string& key_format,
+
456  const std::string& key_format_versions) {
+
457  if (!inserted_discontinuity_tag_) {
+
458  // Insert discontinuity tag only for the first EXT-X-KEY, only if there
+
459  // are non-encrypted media segments.
+
460  if (!entries_.empty())
+
461  entries_.emplace_back(new DiscontinuityEntry());
+
462  inserted_discontinuity_tag_ = true;
+
463  }
+
464  entries_.emplace_back(new EncryptionInfoEntry(
+
465  method, url, key_id, iv, key_format, key_format_versions));
+
466 }
+
467 
+ +
469  entries_.emplace_back(new PlacementOpportunityEntry());
+
470 }
+
471 
+
472 bool MediaPlaylist::WriteToFile(const std::string& file_path) {
+
473  if (!target_duration_set_) {
+ +
475  }
+
476 
+
477  std::string content = CreatePlaylistHeader(
+
478  media_info_, target_duration_, hls_params_.playlist_type, stream_type_,
+
479  media_sequence_number_, discontinuity_sequence_number_);
+
480 
+
481  for (const auto& entry : entries_)
+
482  base::StringAppendF(&content, "%s\n", entry->ToString().c_str());
+
483 
+
484  if (hls_params_.playlist_type == HlsPlaylistType::kVod) {
+
485  content += "#EXT-X-ENDLIST\n";
+
486  }
+
487 
+
488  if (!File::WriteFileAtomically(file_path.c_str(), content)) {
+
489  LOG(ERROR) << "Failed to write playlist to: " << file_path;
+
490  return false;
+
491  }
+
492  return true;
+
493 }
+
494 
+
495 uint64_t MediaPlaylist::MaxBitrate() const {
+
496  if (media_info_.has_bandwidth())
+
497  return media_info_.bandwidth();
+
498  return bandwidth_estimator_.Max();
+
499 }
+
500 
+
501 uint64_t MediaPlaylist::AvgBitrate() const {
+
502  return bandwidth_estimator_.Estimate();
+
503 }
+
504 
+ +
506  return longest_segment_duration_seconds_;
+
507 }
+
508 
+
509 void MediaPlaylist::SetTargetDuration(uint32_t target_duration) {
+
510  if (target_duration_set_) {
+
511  if (target_duration_ == target_duration)
+
512  return;
+
513  VLOG(1) << "Updating target duration from " << target_duration << " to "
+
514  << target_duration_;
+
515  }
+
516  target_duration_ = target_duration;
+
517  target_duration_set_ = true;
+
518 }
+
519 
+ +
521  return media_info_.audio_info().num_channels();
+
522 }
+
523 
+ +
525  return media_info_.audio_info().codec_specific_data().ec3_joc_complexity();
+
526 }
+
527 
+ +
529  return media_info_.audio_info().codec_specific_data().ac4_ims_flag();
+
530 }
+
531 
+ +
533  return media_info_.audio_info().codec_specific_data().ac4_cbi_flag();
+
534 }
+
535 
+ +
537  uint32_t* height) const {
+
538  DCHECK(width);
+
539  DCHECK(height);
+
540  if (media_info_.has_video_info()) {
+
541  const double pixel_aspect_ratio =
+
542  media_info_.video_info().pixel_height() > 0
+
543  ? static_cast<double>(media_info_.video_info().pixel_width()) /
+
544  media_info_.video_info().pixel_height()
+
545  : 1.0;
+
546  *width = static_cast<uint32_t>(media_info_.video_info().width() *
+
547  pixel_aspect_ratio);
+
548  *height = media_info_.video_info().height();
+
549  return true;
+
550  }
+
551  return false;
+
552 }
+
553 
+
554 std::string MediaPlaylist::GetVideoRange() const {
+
555  // Dolby Vision (dvh1 or dvhe) is always HDR.
+
556  if (codec_.find("dvh") == 0)
+
557  return "PQ";
+
558 
+
559  // HLS specification:
+
560  // https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-02#section-4.4.4.2
+
561  switch (media_info_.video_info().transfer_characteristics()) {
+
562  case 1:
+
563  return "SDR";
+
564  case 16:
+
565  case 18:
+
566  return "PQ";
+
567  default:
+
568  // Leave it empty if we do not have the transfer characteristics
+
569  // information.
+
570  return "";
+
571  }
+
572 }
+
573 
+ +
575  if (media_info_.video_info().frame_duration() == 0)
+
576  return 0;
+
577  return static_cast<double>(time_scale_) /
+
578  media_info_.video_info().frame_duration();
+
579 }
+
580 
+
581 void MediaPlaylist::AddSegmentInfoEntry(const std::string& segment_file_name,
+
582  int64_t start_time,
+
583  int64_t duration,
+
584  uint64_t start_byte_offset,
+
585  uint64_t size) {
+
586  if (time_scale_ == 0) {
+
587  LOG(WARNING) << "Timescale is not set and the duration for " << duration
+
588  << " cannot be calculated. The output will be wrong.";
+
589 
+
590  entries_.emplace_back(new SegmentInfoEntry(
+
591  segment_file_name, 0.0, 0.0, use_byte_range_, start_byte_offset, size,
+
592  previous_segment_end_offset_));
+
593  return;
+
594  }
+
595 
+
596  // In order for the oldest segment to be accessible for at least
+
597  // |time_shift_buffer_depth| seconds, the latest segment should not be in the
+
598  // sliding window since the player could be playing any part of the latest
+
599  // segment. So the current segment duration is added to the sum of segment
+
600  // durations (in the manifest/playlist) after sliding the window.
+
601  SlideWindow();
+
602 
+
603  const double segment_duration_seconds =
+
604  static_cast<double>(duration) / time_scale_;
+
605  longest_segment_duration_seconds_ =
+
606  std::max(longest_segment_duration_seconds_, segment_duration_seconds);
+
607  bandwidth_estimator_.AddBlock(size, segment_duration_seconds);
+
608  current_buffer_depth_ += segment_duration_seconds;
+
609 
+
610  if (!entries_.empty() &&
+
611  entries_.back()->type() == HlsEntry::EntryType::kExtInf) {
+
612  const SegmentInfoEntry* segment_info =
+
613  static_cast<SegmentInfoEntry*>(entries_.back().get());
+
614  if (segment_info->start_time() > start_time) {
+
615  LOG(WARNING)
+
616  << "Insert a discontinuity tag after the segment with start time "
+
617  << segment_info->start_time() << " as the next segment starts at "
+
618  << start_time << ".";
+
619  entries_.emplace_back(new DiscontinuityEntry());
+
620  }
+
621  }
+
622 
+
623  entries_.emplace_back(new SegmentInfoEntry(
+
624  segment_file_name, start_time, segment_duration_seconds, use_byte_range_,
+
625  start_byte_offset, size, previous_segment_end_offset_));
+
626  previous_segment_end_offset_ = start_byte_offset + size - 1;
+
627 }
+
628 
+
629 void MediaPlaylist::AdjustLastSegmentInfoEntryDuration(int64_t next_timestamp) {
+
630  if (time_scale_ == 0)
+
631  return;
+
632 
+
633  const double next_timestamp_seconds =
+
634  static_cast<double>(next_timestamp) / time_scale_;
+
635 
+
636  for (auto iter = entries_.rbegin(); iter != entries_.rend(); ++iter) {
+
637  if (iter->get()->type() == HlsEntry::EntryType::kExtInf) {
+
638  SegmentInfoEntry* segment_info =
+
639  reinterpret_cast<SegmentInfoEntry*>(iter->get());
+
640 
+
641  const double segment_duration_seconds =
+
642  next_timestamp_seconds -
+
643  static_cast<double>(segment_info->start_time()) / time_scale_;
+
644  // It could be negative if timestamp messed up.
+
645  if (segment_duration_seconds > 0)
+
646  segment_info->set_duration_seconds(segment_duration_seconds);
+
647  longest_segment_duration_seconds_ =
+
648  std::max(longest_segment_duration_seconds_, segment_duration_seconds);
+
649  break;
+
650  }
+
651  }
+
652 }
+
653 
+
654 // TODO(kqyang): Right now this class manages the segments including the
+
655 // deletion of segments when it is no longer needed. However, this class does
+
656 // not have access to the segment file paths, which is already translated to
+
657 // segment URLs by HlsNotifier. We have to re-generate segment file paths from
+
658 // segment template here in order to delete the old segments.
+
659 // To make the pipeline cleaner, we should move all file manipulations including
+
660 // segment management to an intermediate layer between HlsNotifier and
+
661 // MediaPlaylist.
+
662 void MediaPlaylist::SlideWindow() {
+
663  if (hls_params_.time_shift_buffer_depth <= 0.0 ||
+
664  hls_params_.playlist_type != HlsPlaylistType::kLive) {
+
665  return;
+
666  }
+
667  DCHECK_GT(time_scale_, 0u);
+
668 
+
669  if (current_buffer_depth_ <= hls_params_.time_shift_buffer_depth)
+
670  return;
+
671 
+
672  // Temporary list to hold the EXT-X-KEYs. For example, this allows us to
+
673  // remove <3> without removing <1> and <2> below (<1> and <2> are moved to the
+
674  // temporary list and added back later).
+
675  // #EXT-X-KEY <1>
+
676  // #EXT-X-KEY <2>
+
677  // #EXTINF <3>
+
678  // #EXTINF <4>
+
679  std::list<std::unique_ptr<HlsEntry>> ext_x_keys;
+
680  // Consecutive key entries are either fully removed or not removed at all.
+
681  // Keep track of entry types so we know if it is consecutive key entries.
+
682  HlsEntry::EntryType prev_entry_type = HlsEntry::EntryType::kExtInf;
+
683 
+
684  std::list<std::unique_ptr<HlsEntry>>::iterator last = entries_.begin();
+
685  for (; last != entries_.end(); ++last) {
+
686  HlsEntry::EntryType entry_type = last->get()->type();
+
687  if (entry_type == HlsEntry::EntryType::kExtKey) {
+
688  if (prev_entry_type != HlsEntry::EntryType::kExtKey)
+
689  ext_x_keys.clear();
+
690  ext_x_keys.push_back(std::move(*last));
+
691  } else if (entry_type == HlsEntry::EntryType::kExtDiscontinuity) {
+
692  ++discontinuity_sequence_number_;
+
693  } else {
+
694  DCHECK_EQ(entry_type, HlsEntry::EntryType::kExtInf);
+
695 
+
696  const SegmentInfoEntry& segment_info =
+
697  *reinterpret_cast<SegmentInfoEntry*>(last->get());
+
698  // Remove the current segment only if it falls completely out of time
+
699  // shift buffer range.
+
700  const bool segment_within_time_shift_buffer =
+
701  current_buffer_depth_ - segment_info.duration_seconds() <
+
702  hls_params_.time_shift_buffer_depth;
+
703  if (segment_within_time_shift_buffer)
+
704  break;
+
705  current_buffer_depth_ -= segment_info.duration_seconds();
+
706  RemoveOldSegment(segment_info.start_time());
+
707  media_sequence_number_++;
+
708  }
+
709  prev_entry_type = entry_type;
+
710  }
+
711  entries_.erase(entries_.begin(), last);
+
712  // Add key entries back.
+
713  entries_.insert(entries_.begin(), std::make_move_iterator(ext_x_keys.begin()),
+
714  std::make_move_iterator(ext_x_keys.end()));
+
715 }
+
716 
+
717 void MediaPlaylist::RemoveOldSegment(int64_t start_time) {
+
718  if (hls_params_.preserved_segments_outside_live_window == 0)
+
719  return;
+
720  if (stream_type_ == MediaPlaylistStreamType::kVideoIFramesOnly)
+
721  return;
+
722 
+
723  segments_to_be_removed_.push_back(
+
724  media::GetSegmentName(media_info_.segment_template(), start_time,
+
725  media_sequence_number_, media_info_.bandwidth()));
+
726  while (segments_to_be_removed_.size() >
+ +
728  VLOG(2) << "Deleting " << segments_to_be_removed_.front();
+
729  if (!File::Delete(segments_to_be_removed_.front().c_str())) {
+
730  LOG(WARNING) << "Failed to delete " << segments_to_be_removed_.front()
+
731  << "; Will retry later.";
+
732  break;
+
733  }
+
734  segments_to_be_removed_.pop_front();
+
735  }
+
736 }
+
737 
+
738 } // namespace hls
+
739 } // namespace shaka
+ +
void AddBlock(uint64_t size_in_bytes, double duration)
+ +
static bool Delete(const char *file_name)
Definition: file.cc:212
+
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:277
+
virtual bool WriteToFile(const std::string &file_path)
+
virtual bool GetAC4ImsFlag() const
+
void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type)
For testing only.
+
virtual void SetSampleDuration(uint32_t sample_duration)
+
const std::string & language() const
+
virtual void AddEncryptionInfo(EncryptionMethod method, const std::string &url, const std::string &key_id, const std::string &iv, const std::string &key_format, const std::string &key_format_versions)
+
void SetCharacteristicsForTesting(const std::vector< std::string > &characteristics)
For testing only.
+
virtual void AddKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
+
virtual double GetFrameRate() const
+
virtual uint64_t AvgBitrate() const
+
virtual bool GetDisplayResolution(uint32_t *width, uint32_t *height) const
+
virtual double GetLongestSegmentDuration() const
+
virtual int GetEC3JocComplexity() const
+
virtual uint64_t MaxBitrate() const
+
void SetLanguageForTesting(const std::string &language)
For testing only.
+
virtual int GetNumChannels() const
+
virtual std::string GetVideoRange() const
+
void SetCodecForTesting(const std::string &codec)
For testing only.
+
virtual void AddPlacementOpportunity()
+
virtual bool SetMediaInfo(const MediaInfo &media_info)
+
virtual bool GetAC4CbiFlag() const
+
virtual void SetTargetDuration(uint32_t target_duration)
+
virtual void AddSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t start_byte_offset, uint64_t size)
+
All the methods that are virtual are virtual for mocking.
+
std::string LanguageToShortestForm(const std::string &language)
+
HlsPlaylistType
Definition: hls_params.h:16
+
HLS related parameters.
Definition: hls_params.h:23
+
HlsPlaylistType playlist_type
HLS playlist type. See HLS specification for details.
Definition: hls_params.h:25
+
size_t preserved_segments_outside_live_window
Definition: hls_params.h:40
+
double time_shift_buffer_depth
Definition: hls_params.h:33
diff --git a/docs/d5/df3/common__pssh__generator_8cc_source.html b/docs/d5/df3/common__pssh__generator_8cc_source.html index 5a27ad2279..4b44639066 100644 --- a/docs/d5/df3/common__pssh__generator_8cc_source.html +++ b/docs/d5/df3/common__pssh__generator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/common_pssh_generator.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
common_pssh_generator.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/common_pssh_generator.h"
8 
9 #include "packager/media/base/protection_system_ids.h"
10 
11 namespace shaka {
12 namespace media {
13 namespace {
14 const uint8_t kCommonSystemPsshBoxVersion = 1;
15 } // namespace
16 
17 CommonPsshGenerator::CommonPsshGenerator()
18  : PsshGenerator(std::vector<uint8_t>(std::begin(kCommonSystemId),
19  std::end(kCommonSystemId)),
20  kCommonSystemPsshBoxVersion) {}
21 
22 CommonPsshGenerator::~CommonPsshGenerator() = default;
23 
25  return true;
26 }
27 
28 base::Optional<std::vector<uint8_t>>
29 CommonPsshGenerator::GeneratePsshDataFromKeyIdAndKey(
30  const std::vector<uint8_t>& key_id,
31  const std::vector<uint8_t>& key) const {
32  NOTIMPLEMENTED();
33  return base::nullopt;
34 }
35 
36 base::Optional<std::vector<uint8_t>>
37 CommonPsshGenerator::GeneratePsshDataFromKeyIds(
38  const std::vector<std::vector<uint8_t>>& key_ids) const {
39  // Intentionally empty PSSH data for RawKey.
40  return std::vector<uint8_t>();
41 }
42 
43 } // namespace media
44 } // namespace shaka
STL namespace.
-
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/common_pssh_generator.h"
+
8 
+
9 #include "packager/media/base/protection_system_ids.h"
+
10 
+
11 namespace shaka {
+
12 namespace media {
+
13 namespace {
+
14 const uint8_t kCommonSystemPsshBoxVersion = 1;
+
15 } // namespace
+
16 
+
17 CommonPsshGenerator::CommonPsshGenerator()
+
18  : PsshGenerator(std::vector<uint8_t>(std::begin(kCommonSystemId),
+
19  std::end(kCommonSystemId)),
+
20  kCommonSystemPsshBoxVersion) {}
+
21 
+
22 CommonPsshGenerator::~CommonPsshGenerator() = default;
+
23 
+
24 bool CommonPsshGenerator::SupportMultipleKeys() {
+
25  return true;
+
26 }
+
27 
+
28 base::Optional<std::vector<uint8_t>>
+
29 CommonPsshGenerator::GeneratePsshDataFromKeyIdAndKey(
+
30  const std::vector<uint8_t>& key_id,
+
31  const std::vector<uint8_t>& key) const {
+
32  NOTIMPLEMENTED();
+
33  return base::nullopt;
+
34 }
+
35 
+
36 base::Optional<std::vector<uint8_t>>
+
37 CommonPsshGenerator::GeneratePsshDataFromKeyIds(
+
38  const std::vector<std::vector<uint8_t>>& key_ids) const {
+
39  // Intentionally empty PSSH data for RawKey.
+
40  return std::vector<uint8_t>();
+
41 }
+
42 
+
43 } // namespace media
+
44 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d5/dfa/classshaka_1_1media_1_1HlsNotifyMuxerListener.html b/docs/d5/dfa/classshaka_1_1media_1_1HlsNotifyMuxerListener.html index 1634afaa42..ca2e0900b5 100644 --- a/docs/d5/dfa/classshaka_1_1media_1_1HlsNotifyMuxerListener.html +++ b/docs/d5/dfa/classshaka_1_1media_1_1HlsNotifyMuxerListener.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::HlsNotifyMuxerListener Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::MuxerListener - -
+ + @@ -110,13 +113,13 @@ Public Member Functions Additional Inherited Members @@ -482,7 +485,7 @@ Additional Inherited Members

Public Member Functions

- Public Types inherited from shaka::media::MuxerListener
enum  ContainerType {
-  kContainerUnknown = 0, -kContainerMp4, -kContainerMpeg2ts, -kContainerWebM, -
-  kContainerText, -kContainerPackedAudio +  kContainerUnknown = 0 +, kContainerMp4 +, kContainerMpeg2ts +, kContainerWebM +,
+  kContainerText +, kContainerPackedAudio
}
 
-

Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

Parameters
+

Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

Parameters
@@ -602,9 +605,7 @@ Additional Inherited Members diff --git a/docs/d5/dfa/classshaka_1_1media_1_1MediaParser-members.html b/docs/d5/dfa/classshaka_1_1media_1_1MediaParser-members.html index 81811c1096..77a78cd137 100644 --- a/docs/d5/dfa/classshaka_1_1media_1_1MediaParser-members.html +++ b/docs/d5/dfa/classshaka_1_1media_1_1MediaParser-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
muxer_optionsis the options for Muxer.
stream_infois the information of this media.
- + +/* @license-end */
This is the complete list of members for shaka::media::MediaParser, including all inherited members.

- + - - - + + + +
Flush() WARN_UNUSED_RESULT=0shaka::media::MediaParserpure virtual
Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source)=0shaka::media::MediaParserpure virtual
Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source)=0shaka::media::MediaParserpure virtual
InitCB typedefshaka::media::MediaParser
MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinline
NewSampleCB typedefshaka::media::MediaParser
Parse(const uint8_t *buf, int size) WARN_UNUSED_RESULT=0shaka::media::MediaParserpure virtual
~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
NewMediaSampleCB typedefshaka::media::MediaParser
NewTextSampleCB typedefshaka::media::MediaParser
Parse(const uint8_t *buf, int size) WARN_UNUSED_RESULT=0shaka::media::MediaParserpure virtual
~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
diff --git a/docs/d5/dfc/file_8cc_source.html b/docs/d5/dfc/file_8cc_source.html index 5ce1f452d0..0f8e55ddf3 100644 --- a/docs/d5/dfc/file_8cc_source.html +++ b/docs/d5/dfc/file_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/file.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
file.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/file/file.h"
8 
9 #include <gflags/gflags.h>
10 #include <inttypes.h>
11 #include <algorithm>
12 #include <memory>
13 #include "packager/base/files/file_util.h"
14 #include "packager/base/logging.h"
15 #include "packager/base/strings/string_number_conversions.h"
16 #include "packager/base/strings/string_piece.h"
17 #include "packager/base/strings/stringprintf.h"
18 #include "packager/file/callback_file.h"
19 #include "packager/file/file_util.h"
20 #include "packager/file/local_file.h"
21 #include "packager/file/memory_file.h"
22 #include "packager/file/threaded_io_file.h"
23 #include "packager/file/udp_file.h"
24 
25 DEFINE_uint64(io_cache_size,
26  32ULL << 20,
27  "Size of the threaded I/O cache, in bytes. Specify 0 to disable "
28  "threaded I/O.");
29 DEFINE_uint64(io_block_size,
30  1ULL << 16,
31  "Size of the block size used for threaded I/O, in bytes.");
32 
33 // Needed for Windows weirdness which somewhere defines CopyFile as CopyFileW.
34 #ifdef CopyFile
35 #undef CopyFile
36 #endif // CopyFile
37 
38 namespace shaka {
39 
40 const char* kCallbackFilePrefix = "callback://";
41 const char* kLocalFilePrefix = "file://";
42 const char* kMemoryFilePrefix = "memory://";
43 const char* kUdpFilePrefix = "udp://";
44 
45 namespace {
46 
47 typedef File* (*FileFactoryFunction)(const char* file_name, const char* mode);
48 typedef bool (*FileDeleteFunction)(const char* file_name);
49 typedef bool (*FileAtomicWriteFunction)(const char* file_name,
50  const std::string& contents);
51 
52 struct FileTypeInfo {
53  const char* type;
54  const FileFactoryFunction factory_function;
55  const FileDeleteFunction delete_function;
56  const FileAtomicWriteFunction atomic_write_function;
57 };
58 
59 File* CreateCallbackFile(const char* file_name, const char* mode) {
60  return new CallbackFile(file_name, mode);
61 }
62 
63 File* CreateLocalFile(const char* file_name, const char* mode) {
64  return new LocalFile(file_name, mode);
65 }
66 
67 bool DeleteLocalFile(const char* file_name) {
68  return LocalFile::Delete(file_name);
69 }
70 
71 bool WriteLocalFileAtomically(const char* file_name,
72  const std::string& contents) {
73  const base::FilePath file_path = base::FilePath::FromUTF8Unsafe(file_name);
74  const std::string dir_name = file_path.DirName().AsUTF8Unsafe();
75  std::string temp_file_name;
76  if (!TempFilePath(dir_name, &temp_file_name))
77  return false;
78  if (!File::WriteStringToFile(temp_file_name.c_str(), contents))
79  return false;
80  base::File::Error replace_file_error = base::File::FILE_OK;
81  if (!base::ReplaceFile(base::FilePath::FromUTF8Unsafe(temp_file_name),
82  file_path, &replace_file_error)) {
83  LOG(ERROR) << "Failed to replace file '" << file_name << "' with '"
84  << temp_file_name << "', error: " << replace_file_error;
85  return false;
86  }
87  return true;
88 }
89 
90 File* CreateUdpFile(const char* file_name, const char* mode) {
91  if (strcmp(mode, "r")) {
92  NOTIMPLEMENTED() << "UdpFile only supports read (receive) mode.";
93  return NULL;
94  }
95  return new UdpFile(file_name);
96 }
97 
98 File* CreateMemoryFile(const char* file_name, const char* mode) {
99  return new MemoryFile(file_name, mode);
100 }
101 
102 bool DeleteMemoryFile(const char* file_name) {
103  MemoryFile::Delete(file_name);
104  return true;
105 }
106 
107 static const FileTypeInfo kFileTypeInfo[] = {
108  {
109  kLocalFilePrefix,
110  &CreateLocalFile,
111  &DeleteLocalFile,
112  &WriteLocalFileAtomically,
113  },
114  {kUdpFilePrefix, &CreateUdpFile, nullptr, nullptr},
115  {kMemoryFilePrefix, &CreateMemoryFile, &DeleteMemoryFile, nullptr},
116  {kCallbackFilePrefix, &CreateCallbackFile, nullptr, nullptr},
117 };
118 
119 base::StringPiece GetFileTypePrefix(base::StringPiece file_name) {
120  size_t pos = file_name.find("://");
121  return (pos == std::string::npos) ? "" : file_name.substr(0, pos + 3);
122 }
123 
124 const FileTypeInfo* GetFileTypeInfo(base::StringPiece file_name,
125  base::StringPiece* real_file_name) {
126  base::StringPiece file_type_prefix = GetFileTypePrefix(file_name);
127  for (const FileTypeInfo& file_type : kFileTypeInfo) {
128  if (file_type_prefix == file_type.type) {
129  *real_file_name = file_name.substr(file_type_prefix.size());
130  return &file_type;
131  }
132  }
133  // Otherwise we default to the first file type, which is LocalFile.
134  *real_file_name = file_name;
135  return &kFileTypeInfo[0];
136 }
137 
138 } // namespace
139 
140 File* File::Create(const char* file_name, const char* mode) {
141  std::unique_ptr<File, FileCloser> internal_file(
142  CreateInternalFile(file_name, mode));
143 
144  base::StringPiece file_type_prefix = GetFileTypePrefix(file_name);
145  if (file_type_prefix == kMemoryFilePrefix ||
146  file_type_prefix == kCallbackFilePrefix) {
147  // Disable caching for memory and callback files.
148  return internal_file.release();
149  }
150 
151  if (FLAGS_io_cache_size) {
152  // Enable threaded I/O for "r", "w", and "a" modes only.
153  if (!strcmp(mode, "r")) {
154  return new ThreadedIoFile(std::move(internal_file),
155  ThreadedIoFile::kInputMode, FLAGS_io_cache_size,
156  FLAGS_io_block_size);
157  } else if (!strcmp(mode, "w") || !strcmp(mode, "a")) {
158  return new ThreadedIoFile(std::move(internal_file),
159  ThreadedIoFile::kOutputMode,
160  FLAGS_io_cache_size, FLAGS_io_block_size);
161  }
162  }
163 
164  // Threaded I/O is disabled.
165  DLOG(WARNING) << "Threaded I/O is disabled. Performance may be decreased.";
166  return internal_file.release();
167 }
168 
169 File* File::CreateInternalFile(const char* file_name, const char* mode) {
170  base::StringPiece real_file_name;
171  const FileTypeInfo* file_type = GetFileTypeInfo(file_name, &real_file_name);
172  DCHECK(file_type);
173  return file_type->factory_function(real_file_name.data(), mode);
174 }
175 
176 File* File::Open(const char* file_name, const char* mode) {
177  File* file = File::Create(file_name, mode);
178  if (!file)
179  return NULL;
180  if (!file->Open()) {
181  delete file;
182  return NULL;
183  }
184  return file;
185 }
186 
187 File* File::OpenWithNoBuffering(const char* file_name, const char* mode) {
188  File* file = File::CreateInternalFile(file_name, mode);
189  if (!file)
190  return NULL;
191  if (!file->Open()) {
192  delete file;
193  return NULL;
194  }
195  return file;
196 }
197 
198 bool File::Delete(const char* file_name) {
199  base::StringPiece real_file_name;
200  const FileTypeInfo* file_type = GetFileTypeInfo(file_name, &real_file_name);
201  DCHECK(file_type);
202  return file_type->delete_function
203  ? file_type->delete_function(real_file_name.data())
204  : false;
205 }
206 
207 int64_t File::GetFileSize(const char* file_name) {
208  File* file = File::Open(file_name, "r");
209  if (!file)
210  return -1;
211  int64_t res = file->Size();
212  file->Close();
213  return res;
214 }
215 
216 bool File::ReadFileToString(const char* file_name, std::string* contents) {
217  DCHECK(contents);
218 
219  File* file = File::Open(file_name, "r");
220  if (!file)
221  return false;
222 
223  const size_t kBufferSize = 0x40000; // 256KB.
224  std::unique_ptr<char[]> buf(new char[kBufferSize]);
225 
226  int64_t len;
227  while ((len = file->Read(buf.get(), kBufferSize)) > 0)
228  contents->append(buf.get(), len);
229 
230  file->Close();
231  return len == 0;
232 }
233 
234 bool File::WriteStringToFile(const char* file_name,
235  const std::string& contents) {
236  std::unique_ptr<File, FileCloser> file(File::Open(file_name, "w"));
237  if (!file) {
238  LOG(ERROR) << "Failed to open file " << file_name;
239  return false;
240  }
241  int64_t bytes_written = file->Write(contents.data(), contents.size());
242  if (bytes_written < 0) {
243  LOG(ERROR) << "Failed to write to file '" << file_name << "' ("
244  << bytes_written << ").";
245  return false;
246  }
247  if (static_cast<size_t>(bytes_written) != contents.size()) {
248  LOG(ERROR) << "Failed to write the whole file to " << file_name
249  << ". Wrote " << bytes_written << " but expecting "
250  << contents.size() << " bytes.";
251  return false;
252  }
253  if (!file.release()->Close()) {
254  LOG(ERROR)
255  << "Failed to close file '" << file_name
256  << "', possibly file permission issue or running out of disk space.";
257  return false;
258  }
259  return true;
260 }
261 
262 bool File::WriteFileAtomically(const char* file_name,
263  const std::string& contents) {
264  base::StringPiece real_file_name;
265  const FileTypeInfo* file_type = GetFileTypeInfo(file_name, &real_file_name);
266  DCHECK(file_type);
267  if (file_type->atomic_write_function)
268  return file_type->atomic_write_function(real_file_name.data(), contents);
269 
270  // Provide a default implementation which may not be atomic unfortunately.
271 
272  // Skip the warning message for memory files, which is meant for testing
273  // anyway..
274  if (strncmp(file_name, kMemoryFilePrefix, strlen(kMemoryFilePrefix)) != 0) {
275  LOG(WARNING) << "Writing to " << file_name
276  << " is not guaranteed to be atomic.";
277  }
278  return WriteStringToFile(file_name, contents);
279 }
280 
281 bool File::Copy(const char* from_file_name, const char* to_file_name) {
282  std::string content;
283  if (!ReadFileToString(from_file_name, &content)) {
284  LOG(ERROR) << "Failed to open file " << from_file_name;
285  return false;
286  }
287 
288  std::unique_ptr<File, FileCloser> output_file(File::Open(to_file_name, "w"));
289  if (!output_file) {
290  LOG(ERROR) << "Failed to write to " << to_file_name;
291  return false;
292  }
293 
294  uint64_t bytes_left = content.size();
295  uint64_t total_bytes_written = 0;
296  const char* content_cstr = content.c_str();
297  while (bytes_left > total_bytes_written) {
298  const int64_t bytes_written =
299  output_file->Write(content_cstr + total_bytes_written, bytes_left);
300  if (bytes_written < 0) {
301  LOG(ERROR) << "Failure while writing to " << to_file_name;
302  return false;
303  }
304 
305  total_bytes_written += bytes_written;
306  }
307  if (!output_file.release()->Close()) {
308  LOG(ERROR)
309  << "Failed to close file '" << to_file_name
310  << "', possibly file permission issue or running out of disk space.";
311  return false;
312  }
313  return true;
314 }
315 
316 int64_t File::CopyFile(File* source, File* destination) {
317  return CopyFile(source, destination, kWholeFile);
318 }
319 
320 int64_t File::CopyFile(File* source, File* destination, int64_t max_copy) {
321  DCHECK(source);
322  DCHECK(destination);
323  if (max_copy < 0)
324  max_copy = std::numeric_limits<int64_t>::max();
325 
326  const int64_t kBufferSize = 0x40000; // 256KB.
327  std::unique_ptr<uint8_t[]> buffer(new uint8_t[kBufferSize]);
328  int64_t bytes_copied = 0;
329  while (bytes_copied < max_copy) {
330  const int64_t size = std::min(kBufferSize, max_copy - bytes_copied);
331  const int64_t bytes_read = source->Read(buffer.get(), size);
332  if (bytes_read < 0)
333  return bytes_read;
334  if (bytes_read == 0)
335  break;
336 
337  int64_t total_bytes_written = 0;
338  while (total_bytes_written < bytes_read) {
339  const int64_t bytes_written = destination->Write(
340  buffer.get() + total_bytes_written, bytes_read - total_bytes_written);
341  if (bytes_written < 0)
342  return bytes_written;
343 
344  total_bytes_written += bytes_written;
345  }
346 
347  DCHECK_EQ(total_bytes_written, bytes_read);
348  bytes_copied += bytes_read;
349  }
350 
351  return bytes_copied;
352 }
353 
354 bool File::IsLocalRegularFile(const char* file_name) {
355  base::StringPiece real_file_name;
356  const FileTypeInfo* file_type = GetFileTypeInfo(file_name, &real_file_name);
357  DCHECK(file_type);
358  if (file_type->type != kLocalFilePrefix)
359  return false;
360 #if defined(OS_WIN)
361  const base::FilePath file_path(
362  base::FilePath::FromUTF8Unsafe(real_file_name));
363  const DWORD fileattr = GetFileAttributes(file_path.value().c_str());
364  if (fileattr == INVALID_FILE_ATTRIBUTES) {
365  LOG(ERROR) << "Failed to GetFileAttributes of " << file_path.value();
366  return false;
367  }
368  return (fileattr & FILE_ATTRIBUTE_DIRECTORY) == 0;
369 #else
370  struct stat info;
371  if (stat(real_file_name.data(), &info) != 0) {
372  LOG(ERROR) << "Failed to run stat on " << real_file_name;
373  return false;
374  }
375  return S_ISREG(info.st_mode);
376 #endif
377 }
378 
380  const BufferCallbackParams& callback_params,
381  const std::string& name) {
382  if (name.empty())
383  return "";
384  return base::StringPrintf("%s%" PRIdPTR "/%s", kCallbackFilePrefix,
385  reinterpret_cast<intptr_t>(&callback_params),
386  name.c_str());
387 }
388 
389 bool File::ParseCallbackFileName(const std::string& callback_file_name,
390  const BufferCallbackParams** callback_params,
391  std::string* name) {
392  size_t pos = callback_file_name.find("/");
393  int64_t callback_address = 0;
394  if (pos == std::string::npos ||
395  !base::StringToInt64(callback_file_name.substr(0, pos),
396  &callback_address)) {
397  LOG(ERROR) << "Expecting CallbackFile with name like "
398  "'<callback address>/<entity name>', but seeing "
399  << callback_file_name;
400  return false;
401  }
402  *callback_params = reinterpret_cast<BufferCallbackParams*>(callback_address);
403  *name = callback_file_name.substr(pos + 1);
404  return true;
405 }
406 
407 } // namespace shaka
virtual int64_t Write(const void *buffer, uint64_t length)=0
-
static void Delete(const std::string &file_name)
Definition: memory_file.cc:190
-
static File * Open(const char *file_name, const char *mode)
Definition: file.cc:176
-
static bool Delete(const char *file_name)
Definition: file.cc:198
-
Define an abstract file interface.
Definition: file.h:26
-
static bool IsLocalRegularFile(const char *file_name)
Definition: file.cc:354
-
static bool Copy(const char *from_file_name, const char *to_file_name)
Definition: file.cc:281
-
static int64_t CopyFile(File *source, File *destination)
Definition: file.cc:316
-
static bool ReadFileToString(const char *file_name, std::string *contents)
Definition: file.cc:216
-
virtual int64_t Read(void *buffer, uint64_t length)=0
-
bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
Definition: file_util.cc:38
-
All the methods that are virtual are virtual for mocking.
-
static int64_t GetFileSize(const char *file_name)
Definition: file.cc:207
-
virtual bool Close()=0
-
virtual int64_t Size()=0
-
static bool WriteStringToFile(const char *file_name, const std::string &contents)
Definition: file.cc:234
-
static std::string MakeCallbackFileName(const BufferCallbackParams &callback_params, const std::string &name)
Definition: file.cc:379
-
static bool Delete(const char *file_name)
Definition: local_file.cc:199
-
static File * OpenWithNoBuffering(const char *file_name, const char *mode)
Definition: file.cc:187
-
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:262
-
static bool ParseCallbackFileName(const std::string &callback_file_name, const BufferCallbackParams **callback_params, std::string *name)
Definition: file.cc:389
-
virtual bool Open()=0
Internal open. Should not be used directly.
-
Buffer callback params.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/file/file.h"
+
8 
+
9 #include <gflags/gflags.h>
+
10 #include <inttypes.h>
+
11 #include <algorithm>
+
12 #include <memory>
+
13 #include "packager/base/files/file_util.h"
+
14 #include "packager/base/logging.h"
+
15 #include "packager/base/strings/string_number_conversions.h"
+
16 #include "packager/base/strings/string_piece.h"
+
17 #include "packager/base/strings/stringprintf.h"
+
18 #include "packager/file/callback_file.h"
+
19 #include "packager/file/file_util.h"
+
20 #include "packager/file/local_file.h"
+
21 #include "packager/file/memory_file.h"
+
22 #include "packager/file/threaded_io_file.h"
+
23 #include "packager/file/udp_file.h"
+
24 #include "packager/file/http_file.h"
+
25 
+
26 DEFINE_uint64(io_cache_size,
+
27  32ULL << 20,
+
28  "Size of the threaded I/O cache, in bytes. Specify 0 to disable "
+
29  "threaded I/O.");
+
30 DEFINE_uint64(io_block_size,
+
31  1ULL << 16,
+
32  "Size of the block size used for threaded I/O, in bytes.");
+
33 
+
34 // Needed for Windows weirdness which somewhere defines CopyFile as CopyFileW.
+
35 #ifdef CopyFile
+
36 #undef CopyFile
+
37 #endif // CopyFile
+
38 
+
39 namespace shaka {
+
40 
+
41 const char* kCallbackFilePrefix = "callback://";
+
42 const char* kLocalFilePrefix = "file://";
+
43 const char* kMemoryFilePrefix = "memory://";
+
44 const char* kUdpFilePrefix = "udp://";
+
45 const char* kHttpFilePrefix = "http://";
+
46 const char* kHttpsFilePrefix = "https://";
+
47 
+
48 
+
49 namespace {
+
50 
+
51 typedef File* (*FileFactoryFunction)(const char* file_name, const char* mode);
+
52 typedef bool (*FileDeleteFunction)(const char* file_name);
+
53 typedef bool (*FileAtomicWriteFunction)(const char* file_name,
+
54  const std::string& contents);
+
55 
+
56 struct FileTypeInfo {
+
57  const char* type;
+
58  const FileFactoryFunction factory_function;
+
59  const FileDeleteFunction delete_function;
+
60  const FileAtomicWriteFunction atomic_write_function;
+
61 };
+
62 
+
63 File* CreateCallbackFile(const char* file_name, const char* mode) {
+
64  return new CallbackFile(file_name, mode);
+
65 }
+
66 
+
67 File* CreateLocalFile(const char* file_name, const char* mode) {
+
68  return new LocalFile(file_name, mode);
+
69 }
+
70 
+
71 bool DeleteLocalFile(const char* file_name) {
+
72  return LocalFile::Delete(file_name);
+
73 }
+
74 
+
75 bool WriteLocalFileAtomically(const char* file_name,
+
76  const std::string& contents) {
+
77  const base::FilePath file_path = base::FilePath::FromUTF8Unsafe(file_name);
+
78  const std::string dir_name = file_path.DirName().AsUTF8Unsafe();
+
79  std::string temp_file_name;
+
80  if (!TempFilePath(dir_name, &temp_file_name))
+
81  return false;
+
82  if (!File::WriteStringToFile(temp_file_name.c_str(), contents))
+
83  return false;
+
84  base::File::Error replace_file_error = base::File::FILE_OK;
+
85  if (!base::ReplaceFile(base::FilePath::FromUTF8Unsafe(temp_file_name),
+
86  file_path, &replace_file_error)) {
+
87  LOG(ERROR) << "Failed to replace file '" << file_name << "' with '"
+
88  << temp_file_name << "', error: " << replace_file_error;
+
89  return false;
+
90  }
+
91  return true;
+
92 }
+
93 
+
94 File* CreateUdpFile(const char* file_name, const char* mode) {
+
95  if (strcmp(mode, "r")) {
+
96  NOTIMPLEMENTED() << "UdpFile only supports read (receive) mode.";
+
97  return NULL;
+
98  }
+
99  return new UdpFile(file_name);
+
100 }
+
101 
+
102 File* CreateHttpsFile(const char* file_name, const char* mode) {
+
103  return new HttpFile(HttpMethod::kPut, std::string("https://") + file_name);
+
104 }
+
105 
+
106 File* CreateHttpFile(const char* file_name, const char* mode) {
+
107  return new HttpFile(HttpMethod::kPut, std::string("http://") + file_name);
+
108 }
+
109 
+
110 File* CreateMemoryFile(const char* file_name, const char* mode) {
+
111  return new MemoryFile(file_name, mode);
+
112 }
+
113 
+
114 bool DeleteMemoryFile(const char* file_name) {
+
115  MemoryFile::Delete(file_name);
+
116  return true;
+
117 }
+
118 
+
119 static const FileTypeInfo kFileTypeInfo[] = {
+
120  {
+
121  kLocalFilePrefix,
+
122  &CreateLocalFile,
+
123  &DeleteLocalFile,
+
124  &WriteLocalFileAtomically,
+
125  },
+
126  {kUdpFilePrefix, &CreateUdpFile, nullptr, nullptr},
+
127  {kMemoryFilePrefix, &CreateMemoryFile, &DeleteMemoryFile, nullptr},
+
128  {kCallbackFilePrefix, &CreateCallbackFile, nullptr, nullptr},
+
129  {kHttpFilePrefix, &CreateHttpFile, nullptr, nullptr},
+
130  {kHttpsFilePrefix, &CreateHttpsFile, nullptr, nullptr},
+
131 };
+
132 
+
133 base::StringPiece GetFileTypePrefix(base::StringPiece file_name) {
+
134  size_t pos = file_name.find("://");
+
135  return (pos == std::string::npos) ? "" : file_name.substr(0, pos + 3);
+
136 }
+
137 
+
138 const FileTypeInfo* GetFileTypeInfo(base::StringPiece file_name,
+
139  base::StringPiece* real_file_name) {
+
140  base::StringPiece file_type_prefix = GetFileTypePrefix(file_name);
+
141  for (const FileTypeInfo& file_type : kFileTypeInfo) {
+
142  if (file_type_prefix == file_type.type) {
+
143  *real_file_name = file_name.substr(file_type_prefix.size());
+
144  return &file_type;
+
145  }
+
146  }
+
147  // Otherwise we default to the first file type, which is LocalFile.
+
148  *real_file_name = file_name;
+
149  return &kFileTypeInfo[0];
+
150 }
+
151 
+
152 } // namespace
+
153 
+
154 File* File::Create(const char* file_name, const char* mode) {
+
155  std::unique_ptr<File, FileCloser> internal_file(
+
156  CreateInternalFile(file_name, mode));
+
157 
+
158  base::StringPiece file_type_prefix = GetFileTypePrefix(file_name);
+
159  if (file_type_prefix == kMemoryFilePrefix ||
+
160  file_type_prefix == kCallbackFilePrefix) {
+
161  // Disable caching for memory and callback files.
+
162  return internal_file.release();
+
163  }
+
164 
+
165  if (FLAGS_io_cache_size) {
+
166  // Enable threaded I/O for "r", "w", and "a" modes only.
+
167  if (!strcmp(mode, "r")) {
+
168  return new ThreadedIoFile(std::move(internal_file),
+
169  ThreadedIoFile::kInputMode, FLAGS_io_cache_size,
+
170  FLAGS_io_block_size);
+
171  } else if (!strcmp(mode, "w") || !strcmp(mode, "a")) {
+
172  return new ThreadedIoFile(std::move(internal_file),
+
173  ThreadedIoFile::kOutputMode,
+
174  FLAGS_io_cache_size, FLAGS_io_block_size);
+
175  }
+
176  }
+
177 
+
178  // Threaded I/O is disabled.
+
179  DLOG(WARNING) << "Threaded I/O is disabled. Performance may be decreased.";
+
180  return internal_file.release();
+
181 }
+
182 
+
183 File* File::CreateInternalFile(const char* file_name, const char* mode) {
+
184  base::StringPiece real_file_name;
+
185  const FileTypeInfo* file_type = GetFileTypeInfo(file_name, &real_file_name);
+
186  DCHECK(file_type);
+
187  return file_type->factory_function(real_file_name.data(), mode);
+
188 }
+
189 
+
190 File* File::Open(const char* file_name, const char* mode) {
+
191  File* file = File::Create(file_name, mode);
+
192  if (!file)
+
193  return NULL;
+
194  if (!file->Open()) {
+
195  delete file;
+
196  return NULL;
+
197  }
+
198  return file;
+
199 }
+
200 
+
201 File* File::OpenWithNoBuffering(const char* file_name, const char* mode) {
+
202  File* file = File::CreateInternalFile(file_name, mode);
+
203  if (!file)
+
204  return NULL;
+
205  if (!file->Open()) {
+
206  delete file;
+
207  return NULL;
+
208  }
+
209  return file;
+
210 }
+
211 
+
212 bool File::Delete(const char* file_name) {
+
213  base::StringPiece real_file_name;
+
214  const FileTypeInfo* file_type = GetFileTypeInfo(file_name, &real_file_name);
+
215  DCHECK(file_type);
+
216  return file_type->delete_function
+
217  ? file_type->delete_function(real_file_name.data())
+
218  : false;
+
219 }
+
220 
+
221 int64_t File::GetFileSize(const char* file_name) {
+
222  File* file = File::Open(file_name, "r");
+
223  if (!file)
+
224  return -1;
+
225  int64_t res = file->Size();
+
226  file->Close();
+
227  return res;
+
228 }
+
229 
+
230 bool File::ReadFileToString(const char* file_name, std::string* contents) {
+
231  DCHECK(contents);
+
232 
+
233  File* file = File::Open(file_name, "r");
+
234  if (!file)
+
235  return false;
+
236 
+
237  const size_t kBufferSize = 0x40000; // 256KB.
+
238  std::unique_ptr<char[]> buf(new char[kBufferSize]);
+
239 
+
240  int64_t len;
+
241  while ((len = file->Read(buf.get(), kBufferSize)) > 0)
+
242  contents->append(buf.get(), len);
+
243 
+
244  file->Close();
+
245  return len == 0;
+
246 }
+
247 
+
248 bool File::WriteStringToFile(const char* file_name,
+
249  const std::string& contents) {
+
250  VLOG(2) << "File::WriteStringToFile: " << file_name;
+
251  std::unique_ptr<File, FileCloser> file(File::Open(file_name, "w"));
+
252  if (!file) {
+
253  LOG(ERROR) << "Failed to open file " << file_name;
+
254  return false;
+
255  }
+
256  int64_t bytes_written = file->Write(contents.data(), contents.size());
+
257  if (bytes_written < 0) {
+
258  LOG(ERROR) << "Failed to write to file '" << file_name << "' ("
+
259  << bytes_written << ").";
+
260  return false;
+
261  }
+
262  if (static_cast<size_t>(bytes_written) != contents.size()) {
+
263  LOG(ERROR) << "Failed to write the whole file to " << file_name
+
264  << ". Wrote " << bytes_written << " but expecting "
+
265  << contents.size() << " bytes.";
+
266  return false;
+
267  }
+
268  if (!file.release()->Close()) {
+
269  LOG(ERROR)
+
270  << "Failed to close file '" << file_name
+
271  << "', possibly file permission issue or running out of disk space.";
+
272  return false;
+
273  }
+
274  return true;
+
275 }
+
276 
+
277 bool File::WriteFileAtomically(const char* file_name,
+
278  const std::string& contents) {
+
279  VLOG(2) << "File::WriteFileAtomically: " << file_name;
+
280  base::StringPiece real_file_name;
+
281  const FileTypeInfo* file_type = GetFileTypeInfo(file_name, &real_file_name);
+
282  DCHECK(file_type);
+
283  if (file_type->atomic_write_function)
+
284  return file_type->atomic_write_function(real_file_name.data(), contents);
+
285 
+
286  // Provide a default implementation which may not be atomic unfortunately.
+
287 
+
288  // Skip the warning message for memory files, which is meant for testing
+
289  // anyway..
+
290  if (strncmp(file_name, kMemoryFilePrefix, strlen(kMemoryFilePrefix)) != 0) {
+
291  LOG(WARNING) << "Writing to " << file_name
+
292  << " is not guaranteed to be atomic.";
+
293  }
+
294  return WriteStringToFile(file_name, contents);
+
295 }
+
296 
+
297 bool File::Copy(const char* from_file_name, const char* to_file_name) {
+
298  std::string content;
+
299  VLOG(2) << "File::Copy from " << from_file_name << " to " << to_file_name;
+
300  if (!ReadFileToString(from_file_name, &content)) {
+
301  LOG(ERROR) << "Failed to open file " << from_file_name;
+
302  return false;
+
303  }
+
304 
+
305  std::unique_ptr<File, FileCloser> output_file(File::Open(to_file_name, "w"));
+
306  if (!output_file) {
+
307  LOG(ERROR) << "Failed to write to " << to_file_name;
+
308  return false;
+
309  }
+
310 
+
311  uint64_t bytes_left = content.size();
+
312  uint64_t total_bytes_written = 0;
+
313  const char* content_cstr = content.c_str();
+
314  while (bytes_left > total_bytes_written) {
+
315  const int64_t bytes_written =
+
316  output_file->Write(content_cstr + total_bytes_written, bytes_left);
+
317  if (bytes_written < 0) {
+
318  LOG(ERROR) << "Failure while writing to " << to_file_name;
+
319  return false;
+
320  }
+
321 
+
322  total_bytes_written += bytes_written;
+
323  }
+
324  if (!output_file.release()->Close()) {
+
325  LOG(ERROR)
+
326  << "Failed to close file '" << to_file_name
+
327  << "', possibly file permission issue or running out of disk space.";
+
328  return false;
+
329  }
+
330  return true;
+
331 }
+
332 
+
333 int64_t File::CopyFile(File* source, File* destination) {
+
334  return CopyFile(source, destination, kWholeFile);
+
335 }
+
336 
+
337 int64_t File::CopyFile(File* source, File* destination, int64_t max_copy) {
+
338  DCHECK(source);
+
339  DCHECK(destination);
+
340  if (max_copy < 0)
+
341  max_copy = std::numeric_limits<int64_t>::max();
+
342 
+
343  VLOG(2) << "File::CopyFile from " << source->file_name() << " to "
+
344  << destination->file_name();
+
345 
+
346  const int64_t kBufferSize = 0x40000; // 256KB.
+
347  std::unique_ptr<uint8_t[]> buffer(new uint8_t[kBufferSize]);
+
348  int64_t bytes_copied = 0;
+
349  while (bytes_copied < max_copy) {
+
350  const int64_t size = std::min(kBufferSize, max_copy - bytes_copied);
+
351  const int64_t bytes_read = source->Read(buffer.get(), size);
+
352  if (bytes_read < 0)
+
353  return bytes_read;
+
354  if (bytes_read == 0)
+
355  break;
+
356 
+
357  int64_t total_bytes_written = 0;
+
358  while (total_bytes_written < bytes_read) {
+
359  const int64_t bytes_written = destination->Write(
+
360  buffer.get() + total_bytes_written, bytes_read - total_bytes_written);
+
361  if (bytes_written < 0)
+
362  return bytes_written;
+
363 
+
364  total_bytes_written += bytes_written;
+
365  }
+
366 
+
367  DCHECK_EQ(total_bytes_written, bytes_read);
+
368  bytes_copied += bytes_read;
+
369  }
+
370 
+
371  return bytes_copied;
+
372 }
+
373 
+
374 bool File::IsLocalRegularFile(const char* file_name) {
+
375  base::StringPiece real_file_name;
+
376  const FileTypeInfo* file_type = GetFileTypeInfo(file_name, &real_file_name);
+
377  DCHECK(file_type);
+
378  if (file_type->type != kLocalFilePrefix)
+
379  return false;
+
380 #if defined(OS_WIN)
+
381  const base::FilePath file_path(
+
382  base::FilePath::FromUTF8Unsafe(real_file_name));
+
383  const DWORD fileattr = GetFileAttributes(file_path.value().c_str());
+
384  if (fileattr == INVALID_FILE_ATTRIBUTES) {
+
385  LOG(ERROR) << "Failed to GetFileAttributes of " << file_path.value();
+
386  return false;
+
387  }
+
388  return (fileattr & FILE_ATTRIBUTE_DIRECTORY) == 0;
+
389 #else
+
390  struct stat info;
+
391  if (stat(real_file_name.data(), &info) != 0) {
+
392  LOG(ERROR) << "Failed to run stat on " << real_file_name;
+
393  return false;
+
394  }
+
395  return S_ISREG(info.st_mode);
+
396 #endif
+
397 }
+
398 
+ +
400  const BufferCallbackParams& callback_params,
+
401  const std::string& name) {
+
402  if (name.empty())
+
403  return "";
+
404  return base::StringPrintf("%s%" PRIdPTR "/%s", kCallbackFilePrefix,
+
405  reinterpret_cast<intptr_t>(&callback_params),
+
406  name.c_str());
+
407 }
+
408 
+
409 bool File::ParseCallbackFileName(const std::string& callback_file_name,
+
410  const BufferCallbackParams** callback_params,
+
411  std::string* name) {
+
412  size_t pos = callback_file_name.find("/");
+
413  int64_t callback_address = 0;
+
414  if (pos == std::string::npos ||
+
415  !base::StringToInt64(callback_file_name.substr(0, pos),
+
416  &callback_address)) {
+
417  LOG(ERROR) << "Expecting CallbackFile with name like "
+
418  "'<callback address>/<entity name>', but seeing "
+
419  << callback_file_name;
+
420  return false;
+
421  }
+
422  *callback_params = reinterpret_cast<BufferCallbackParams*>(callback_address);
+
423  *name = callback_file_name.substr(pos + 1);
+
424  return true;
+
425 }
+
426 
+
427 } // namespace shaka
+
Define an abstract file interface.
Definition: file.h:27
+
static File * OpenWithNoBuffering(const char *file_name, const char *mode)
Definition: file.cc:201
+
static bool Delete(const char *file_name)
Definition: file.cc:212
+
static bool WriteStringToFile(const char *file_name, const std::string &contents)
Definition: file.cc:248
+
const std::string & file_name() const
Definition: file.h:95
+
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:277
+
virtual bool Open()=0
Internal open. Should not be used directly.
+
virtual int64_t Read(void *buffer, uint64_t length)=0
+
static std::string MakeCallbackFileName(const BufferCallbackParams &callback_params, const std::string &name)
Definition: file.cc:399
+
static int64_t CopyFile(File *source, File *destination)
Definition: file.cc:333
+
virtual int64_t Write(const void *buffer, uint64_t length)=0
+
static bool IsLocalRegularFile(const char *file_name)
Definition: file.cc:374
+
virtual bool Close()=0
+
static File * Open(const char *file_name, const char *mode)
Definition: file.cc:190
+
static int64_t GetFileSize(const char *file_name)
Definition: file.cc:221
+
static bool ReadFileToString(const char *file_name, std::string *contents)
Definition: file.cc:230
+
static bool ParseCallbackFileName(const std::string &callback_file_name, const BufferCallbackParams **callback_params, std::string *name)
Definition: file.cc:409
+
virtual int64_t Size()=0
+
static bool Copy(const char *from_file_name, const char *to_file_name)
Definition: file.cc:297
+
static bool Delete(const char *file_name)
Definition: local_file.cc:199
+
static void Delete(const std::string &file_name)
Definition: memory_file.cc:190
+
All the methods that are virtual are virtual for mocking.
+
bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
Definition: file_util.cc:38
+
diff --git a/docs/d5/dfe/classshaka_1_1File-members.html b/docs/d5/dfe/classshaka_1_1File-members.html index b5e766072c..effef5ac8b 100644 --- a/docs/d5/dfe/classshaka_1_1File-members.html +++ b/docs/d5/dfe/classshaka_1_1File-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/d02/playready__key__encryption__flags_8h_source.html b/docs/d6/d02/playready__key__encryption__flags_8h_source.html index 8486272e23..4c665ce880 100644 --- a/docs/d6/d02/playready__key__encryption__flags_8h_source.html +++ b/docs/d6/d02/playready__key__encryption__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/playready_key_encryption_flags.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
playready_key_encryption_flags.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines command line flags for PlayReady encryption.
8 
9 #ifndef APP_PLAYREADY_KEY_ENCRYPTION_FLAGS_H_
10 #define APP_PLAYREADY_KEY_ENCRYPTION_FLAGS_H_
11 
12 #include <gflags/gflags.h>
13 
14 #include "packager/app/gflags_hex_bytes.h"
15 
16 DECLARE_bool(enable_playready_encryption);
17 DECLARE_string(playready_server_url);
18 DECLARE_string(program_identifier);
19 DECLARE_string(ca_file);
20 DECLARE_string(client_cert_file);
21 DECLARE_string(client_cert_private_key_file);
22 DECLARE_string(client_cert_private_key_password);
23 
24 namespace shaka {
25 
29 
30 } // namespace shaka
31 
32 #endif // APP_PLAYREADY_KEY_ENCRYPTION_FLAGS_H_
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines command line flags for PlayReady encryption.
+
8 
+
9 #ifndef APP_PLAYREADY_KEY_ENCRYPTION_FLAGS_H_
+
10 #define APP_PLAYREADY_KEY_ENCRYPTION_FLAGS_H_
+
11 
+
12 #include <gflags/gflags.h>
+
13 
+
14 #include "packager/app/gflags_hex_bytes.h"
+
15 
+
16 DECLARE_bool(enable_playready_encryption);
+
17 DECLARE_string(playready_server_url);
+
18 DECLARE_string(program_identifier);
+
19 
+
20 namespace shaka {
+
21 
+ +
25 
+
26 } // namespace shaka
+
27 
+
28 #endif // APP_PLAYREADY_KEY_ENCRYPTION_FLAGS_H_
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d6/d03/classshaka_1_1media_1_1AesCbcDecryptor-members.html b/docs/d6/d03/classshaka_1_1media_1_1AesCbcDecryptor-members.html index d6605616d6..ba546b0fec 100644 --- a/docs/d6/d03/classshaka_1_1media_1_1AesCbcDecryptor-members.html +++ b/docs/d6/d03/classshaka_1_1media_1_1AesCbcDecryptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/d09/aes__pattern__cryptor_8h_source.html b/docs/d6/d09/aes__pattern__cryptor_8h_source.html index 1dab9e4e34..5fdd9b6423 100644 --- a/docs/d6/d09/aes__pattern__cryptor_8h_source.html +++ b/docs/d6/d09/aes__pattern__cryptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/aes_pattern_cryptor.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
aes_pattern_cryptor.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/aes_cryptor.h"
8 
9 #include <memory>
10 
11 #include "packager/base/macros.h"
12 
13 namespace shaka {
14 namespace media {
15 
17 class AesPatternCryptor : public AesCryptor {
18  public:
34  };
35 
51  AesPatternCryptor(uint8_t crypt_byte_block,
52  uint8_t skip_byte_block,
53  PatternEncryptionMode encryption_mode,
54  ConstantIvFlag constant_iv_flag,
55  std::unique_ptr<AesCryptor> cryptor);
56  ~AesPatternCryptor() override;
57 
60  bool InitializeWithIv(const std::vector<uint8_t>& key,
61  const std::vector<uint8_t>& iv) override;
63 
64  private:
65  bool CryptInternal(const uint8_t* text,
66  size_t text_size,
67  uint8_t* crypt_text,
68  size_t* crypt_text_size) override;
69  void SetIvInternal() override;
70 
71  uint8_t crypt_byte_block_;
72  const uint8_t skip_byte_block_;
73  const PatternEncryptionMode encryption_mode_;
74  std::unique_ptr<AesCryptor> cryptor_;
75 
76  DISALLOW_COPY_AND_ASSIGN(AesPatternCryptor);
77 };
78 
79 } // namespace media
80 } // namespace shaka
bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
- - -
All the methods that are virtual are virtual for mocking.
- - -
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
-
Implements pattern-based encryption/decryption.
-
AesPatternCryptor(uint8_t crypt_byte_block, uint8_t skip_byte_block, PatternEncryptionMode encryption_mode, ConstantIvFlag constant_iv_flag, std::unique_ptr< AesCryptor > cryptor)
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/aes_cryptor.h"
+
8 
+
9 #include <memory>
+
10 
+
11 #include "packager/base/macros.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
17 class AesPatternCryptor : public AesCryptor {
+
18  public:
+ + + +
34  };
+
35 
+
51  AesPatternCryptor(uint8_t crypt_byte_block,
+
52  uint8_t skip_byte_block,
+
53  PatternEncryptionMode encryption_mode,
+
54  ConstantIvFlag constant_iv_flag,
+
55  std::unique_ptr<AesCryptor> cryptor);
+
56  ~AesPatternCryptor() override;
+
57 
+
60  bool InitializeWithIv(const std::vector<uint8_t>& key,
+
61  const std::vector<uint8_t>& iv) override;
+
63 
+
64  private:
+
65  bool CryptInternal(const uint8_t* text,
+
66  size_t text_size,
+
67  uint8_t* crypt_text,
+
68  size_t* crypt_text_size) override;
+
69  void SetIvInternal() override;
+
70 
+
71  uint8_t crypt_byte_block_;
+
72  const uint8_t skip_byte_block_;
+
73  const PatternEncryptionMode encryption_mode_;
+
74  std::unique_ptr<AesCryptor> cryptor_;
+
75 
+
76  DISALLOW_COPY_AND_ASSIGN(AesPatternCryptor);
+
77 };
+
78 
+
79 } // namespace media
+
80 } // namespace shaka
+ +
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
+
Implements pattern-based encryption/decryption.
+ + + +
AesPatternCryptor(uint8_t crypt_byte_block, uint8_t skip_byte_block, PatternEncryptionMode encryption_mode, ConstantIvFlag constant_iv_flag, std::unique_ptr< AesCryptor > cryptor)
+
bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d16/text__stream__info_8cc_source.html b/docs/d6/d16/text__stream__info_8cc_source.html index 9465afb9d2..33e1aa11ec 100644 --- a/docs/d6/d16/text__stream__info_8cc_source.html +++ b/docs/d6/d16/text__stream__info_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/text_stream_info.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
text_stream_info.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/text_stream_info.h"
8 
9 namespace shaka {
10 namespace media {
11 
12 TextStreamInfo::TextStreamInfo(int track_id, uint32_t time_scale,
13  uint64_t duration,
14  Codec codec,
15  const std::string& codec_string,
16  const std::string& codec_config, uint16_t width,
17  uint16_t height, const std::string& language)
18  : StreamInfo(kStreamText, track_id, time_scale, duration, codec,
19  codec_string,
20  reinterpret_cast<const uint8_t*>(codec_config.data()),
21  codec_config.size(), language, false),
22  width_(width),
23  height_(height) {}
24 
25 TextStreamInfo::~TextStreamInfo() {}
26 
28  return true;
29 }
30 
31 std::unique_ptr<StreamInfo> TextStreamInfo::Clone() const {
32  return std::unique_ptr<StreamInfo>(new TextStreamInfo(*this));
33 }
34 
35 } // namespace media
36 } // namespace shaka
Abstract class holds stream information.
Definition: stream_info.h:62
-
All the methods that are virtual are virtual for mocking.
-
TextStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const std::string &codec_config, uint16_t width, uint16_t height, const std::string &language)
-
bool IsValidConfig() const override
-
std::unique_ptr< StreamInfo > Clone() const override
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/text_stream_info.h"
+
8 
+
9 #include "packager/base/strings/stringprintf.h"
+
10 
+
11 namespace shaka {
+
12 namespace media {
+
13 
+
14 TextStreamInfo::TextStreamInfo(int track_id, uint32_t time_scale,
+
15  uint64_t duration,
+
16  Codec codec,
+
17  const std::string& codec_string,
+
18  const std::string& codec_config, uint16_t width,
+
19  uint16_t height, const std::string& language)
+
20  : StreamInfo(kStreamText, track_id, time_scale, duration, codec,
+
21  codec_string,
+
22  reinterpret_cast<const uint8_t*>(codec_config.data()),
+
23  codec_config.size(), language, false),
+
24  width_(width),
+
25  height_(height) {}
+
26 
+
27 TextStreamInfo::~TextStreamInfo() {}
+
28 
+ +
30  return true;
+
31 }
+
32 
+
33 std::string TextStreamInfo::ToString() const {
+
34  std::string ret = StreamInfo::ToString();
+
35  if (!sub_streams_.empty()) {
+
36  ret += " Sub Streams:";
+
37  for (auto& pair : sub_streams_) {
+
38  ret += base::StringPrintf("\n ID: %u, Lang: %s", pair.first,
+
39  pair.second.language.c_str());
+
40  }
+
41  }
+
42  return ret + "\n";
+
43 }
+
44 
+
45 std::unique_ptr<StreamInfo> TextStreamInfo::Clone() const {
+
46  return std::unique_ptr<StreamInfo>(new TextStreamInfo(*this));
+
47 }
+
48 
+
49 } // namespace media
+
50 } // namespace shaka
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
virtual std::string ToString() const
Definition: stream_info.cc:59
+
TextStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const std::string &codec_config, uint16_t width, uint16_t height, const std::string &language)
+
std::string ToString() const override
+
std::unique_ptr< StreamInfo > Clone() const override
+
bool IsValidConfig() const override
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d17/es__parser__h264_8cc_source.html b/docs/d6/d17/es__parser__h264_8cc_source.html index f7b0885bca..eae4ff12ef 100644 --- a/docs/d6/d17/es__parser__h264_8cc_source.html +++ b/docs/d6/d17/es__parser__h264_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser_h264.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
es_parser_h264.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/mp2t/es_parser_h264.h"
6 
7 #include <stdint.h>
8 
9 #include "packager/base/logging.h"
10 #include "packager/media/base/media_sample.h"
11 #include "packager/media/base/timestamp.h"
12 #include "packager/media/base/video_stream_info.h"
13 #include "packager/media/codecs/avc_decoder_configuration_record.h"
14 #include "packager/media/codecs/h264_byte_to_unit_stream_converter.h"
15 #include "packager/media/codecs/h264_parser.h"
16 #include "packager/media/formats/mp2t/mp2t_common.h"
17 
18 namespace shaka {
19 namespace media {
20 namespace mp2t {
21 
22 EsParserH264::EsParserH264(uint32_t pid,
23  const NewStreamInfoCB& new_stream_info_cb,
24  const EmitSampleCB& emit_sample_cb)
25  : EsParserH26x(Nalu::kH264,
26  std::unique_ptr<H26xByteToUnitStreamConverter>(
27  new H264ByteToUnitStreamConverter()),
28  pid,
29  emit_sample_cb),
30  new_stream_info_cb_(new_stream_info_cb),
31  decoder_config_check_pending_(false),
32  h264_parser_(new H264Parser()) {}
33 
34 EsParserH264::~EsParserH264() {}
35 
36 void EsParserH264::Reset() {
37  DVLOG(1) << "EsParserH264::Reset";
38  h264_parser_.reset(new H264Parser());
39  last_video_decoder_config_ = std::shared_ptr<StreamInfo>();
40  decoder_config_check_pending_ = false;
41  EsParserH26x::Reset();
42 }
43 
44 bool EsParserH264::ProcessNalu(const Nalu& nalu,
45  VideoSliceInfo* video_slice_info) {
46  video_slice_info->valid = false;
47  switch (nalu.type()) {
48  case Nalu::H264_AUD: {
49  DVLOG(LOG_LEVEL_ES) << "Nalu: AUD";
50  break;
51  }
52  case Nalu::H264_SPS: {
53  DVLOG(LOG_LEVEL_ES) << "Nalu: SPS";
54  int sps_id;
55  if (h264_parser_->ParseSps(nalu, &sps_id) != H264Parser::kOk)
56  return false;
57  decoder_config_check_pending_ = true;
58  break;
59  }
60  case Nalu::H264_PPS: {
61  DVLOG(LOG_LEVEL_ES) << "Nalu: PPS";
62  int pps_id;
63  if (h264_parser_->ParsePps(nalu, &pps_id) != H264Parser::kOk) {
64  // Allow PPS parsing to fail if waiting for SPS.
65  if (last_video_decoder_config_)
66  return false;
67  } else {
68  decoder_config_check_pending_ = true;
69  }
70  break;
71  }
72  case Nalu::H264_IDRSlice:
73  case Nalu::H264_NonIDRSlice: {
74  const bool is_key_frame = (nalu.type() == Nalu::H264_IDRSlice);
75  DVLOG(LOG_LEVEL_ES) << "Nalu: slice IDR=" << is_key_frame;
76  H264SliceHeader shdr;
77  if (h264_parser_->ParseSliceHeader(nalu, &shdr) != H264Parser::kOk) {
78  // Only accept an invalid SPS/PPS at the beginning when the stream
79  // does not necessarily start with an SPS/PPS/IDR.
80  if (last_video_decoder_config_)
81  return false;
82  } else {
83  video_slice_info->valid = true;
84  video_slice_info->is_key_frame = is_key_frame;
85  video_slice_info->frame_num = shdr.frame_num;
86  video_slice_info->pps_id = shdr.pic_parameter_set_id;
87  }
88  break;
89  }
90  default: {
91  DVLOG(LOG_LEVEL_ES) << "Nalu: " << nalu.type();
92  }
93  }
94 
95  return true;
96 }
97 
98 bool EsParserH264::UpdateVideoDecoderConfig(int pps_id) {
99  // Update the video decoder configuration if needed.
100  if (!decoder_config_check_pending_)
101  return true;
102 
103  const H264Pps* pps = h264_parser_->GetPps(pps_id);
104  const H264Sps* sps;
105  if (!pps) {
106  // Only accept an invalid PPS at the beginning when the stream
107  // does not necessarily start with an SPS/PPS/IDR.
108  // In this case, the initial frames are conveyed to the upper layer with
109  // an invalid VideoDecoderConfig and it's up to the upper layer
110  // to process this kind of frame accordingly.
111  return last_video_decoder_config_ == nullptr;
112  } else {
113  sps = h264_parser_->GetSps(pps->seq_parameter_set_id);
114  if (!sps)
115  return false;
116  decoder_config_check_pending_ = false;
117  }
118 
119  std::vector<uint8_t> decoder_config_record;
120  if (!stream_converter()->GetDecoderConfigurationRecord(
121  &decoder_config_record)) {
122  DLOG(ERROR) << "Failure to construct an AVCDecoderConfigurationRecord";
123  return false;
124  }
125 
126  if (last_video_decoder_config_) {
127  if (last_video_decoder_config_->codec_config() != decoder_config_record) {
128  // Video configuration has changed. Issue warning.
129  // TODO(tinskip): Check the nature of the configuration change. Only
130  // minor configuration changes (such as frame ordering) can be handled
131  // gracefully by decoders without notification. Major changes (such as
132  // video resolution changes) should be treated as errors.
133  LOG(WARNING) << "H.264 decoder configuration has changed.";
134  last_video_decoder_config_->set_codec_config(decoder_config_record);
135  }
136  return true;
137  }
138 
139  uint32_t coded_width = 0;
140  uint32_t coded_height = 0;
141  uint32_t pixel_width = 0;
142  uint32_t pixel_height = 0;
143  if (!ExtractResolutionFromSps(*sps, &coded_width, &coded_height, &pixel_width,
144  &pixel_height)) {
145  LOG(ERROR) << "Failed to parse SPS.";
146  return false;
147  }
148 
149  const uint8_t nalu_length_size =
150  H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize;
151  const H26xStreamFormat stream_format = stream_converter()->stream_format();
152  const FourCC codec_fourcc =
153  stream_format == H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
154  ? FOURCC_avc3
155  : FOURCC_avc1;
156  last_video_decoder_config_ = std::make_shared<VideoStreamInfo>(
157  pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH264, stream_format,
159  codec_fourcc, decoder_config_record[1], decoder_config_record[2],
160  decoder_config_record[3]),
161  decoder_config_record.data(), decoder_config_record.size(), coded_width,
162  coded_height, pixel_width, pixel_height, sps->transfer_characteristics, 0,
163  nalu_length_size, std::string(), false);
164  DVLOG(1) << "Profile IDC: " << sps->profile_idc;
165  DVLOG(1) << "Level IDC: " << sps->level_idc;
166  DVLOG(1) << "log2_max_frame_num_minus4: " << sps->log2_max_frame_num_minus4;
167 
168  // Video config notification.
169  new_stream_info_cb_.Run(last_video_decoder_config_);
170 
171  return true;
172 }
173 
174 } // namespace mp2t
175 } // namespace media
176 } // namespace shaka
STL namespace.
-
All the methods that are virtual are virtual for mocking.
-
std::string GetCodecString(FourCC codec_fourcc) const
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/mp2t/es_parser_h264.h"
+
6 
+
7 #include <stdint.h>
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/media/base/media_sample.h"
+
11 #include "packager/media/base/timestamp.h"
+
12 #include "packager/media/base/video_stream_info.h"
+
13 #include "packager/media/codecs/avc_decoder_configuration_record.h"
+
14 #include "packager/media/codecs/h264_byte_to_unit_stream_converter.h"
+
15 #include "packager/media/codecs/h264_parser.h"
+
16 #include "packager/media/formats/mp2t/mp2t_common.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 namespace mp2t {
+
21 
+
22 EsParserH264::EsParserH264(uint32_t pid,
+
23  const NewStreamInfoCB& new_stream_info_cb,
+
24  const EmitSampleCB& emit_sample_cb)
+
25  : EsParserH26x(Nalu::kH264,
+
26  std::unique_ptr<H26xByteToUnitStreamConverter>(
+
27  new H264ByteToUnitStreamConverter()),
+
28  pid,
+
29  emit_sample_cb),
+
30  new_stream_info_cb_(new_stream_info_cb),
+
31  decoder_config_check_pending_(false),
+
32  h264_parser_(new H264Parser()) {}
+
33 
+
34 EsParserH264::~EsParserH264() {}
+
35 
+
36 void EsParserH264::Reset() {
+
37  DVLOG(1) << "EsParserH264::Reset";
+
38  h264_parser_.reset(new H264Parser());
+
39  last_video_decoder_config_ = std::shared_ptr<StreamInfo>();
+
40  decoder_config_check_pending_ = false;
+
41  EsParserH26x::Reset();
+
42 }
+
43 
+
44 bool EsParserH264::ProcessNalu(const Nalu& nalu,
+
45  VideoSliceInfo* video_slice_info) {
+
46  video_slice_info->valid = false;
+
47  switch (nalu.type()) {
+
48  case Nalu::H264_AUD: {
+
49  DVLOG(LOG_LEVEL_ES) << "Nalu: AUD";
+
50  break;
+
51  }
+
52  case Nalu::H264_SPS: {
+
53  DVLOG(LOG_LEVEL_ES) << "Nalu: SPS";
+
54  int sps_id;
+
55  auto status = h264_parser_->ParseSps(nalu, &sps_id);
+
56  if (status == H264Parser::kOk)
+
57  decoder_config_check_pending_ = true;
+
58  else if (status == H264Parser::kUnsupportedStream)
+
59  // Indicate the stream can't be parsed.
+
60  new_stream_info_cb_.Run(nullptr);
+
61  else
+
62  return false;
+
63  break;
+
64  }
+
65  case Nalu::H264_PPS: {
+
66  DVLOG(LOG_LEVEL_ES) << "Nalu: PPS";
+
67  int pps_id;
+
68  auto status = h264_parser_->ParsePps(nalu, &pps_id);
+
69  if (status == H264Parser::kOk) {
+
70  decoder_config_check_pending_ = true;
+
71  } else if (status == H264Parser::kUnsupportedStream) {
+
72  // Indicate the stream can't be parsed.
+
73  new_stream_info_cb_.Run(nullptr);
+
74  } else {
+
75  // Allow PPS parsing to fail if waiting for SPS.
+
76  if (last_video_decoder_config_)
+
77  return false;
+
78  }
+
79  break;
+
80  }
+
81  case Nalu::H264_IDRSlice:
+
82  case Nalu::H264_NonIDRSlice: {
+
83  const bool is_key_frame = (nalu.type() == Nalu::H264_IDRSlice);
+
84  DVLOG(LOG_LEVEL_ES) << "Nalu: slice IDR=" << is_key_frame;
+
85  H264SliceHeader shdr;
+
86  auto status = h264_parser_->ParseSliceHeader(nalu, &shdr);
+
87  if (status == H264Parser::kOk) {
+
88  video_slice_info->valid = true;
+
89  video_slice_info->is_key_frame = is_key_frame;
+
90  video_slice_info->frame_num = shdr.frame_num;
+
91  video_slice_info->pps_id = shdr.pic_parameter_set_id;
+
92  } else if (status == H264Parser::kUnsupportedStream) {
+
93  // Indicate the stream can't be parsed.
+
94  new_stream_info_cb_.Run(nullptr);
+
95  } else {
+
96  // Only accept an invalid SPS/PPS at the beginning when the stream
+
97  // does not necessarily start with an SPS/PPS/IDR.
+
98  if (last_video_decoder_config_)
+
99  return false;
+
100  }
+
101  break;
+
102  }
+
103  default: {
+
104  DVLOG(LOG_LEVEL_ES) << "Nalu: " << nalu.type();
+
105  }
+
106  }
+
107 
+
108  return true;
+
109 }
+
110 
+
111 bool EsParserH264::UpdateVideoDecoderConfig(int pps_id) {
+
112  // Update the video decoder configuration if needed.
+
113  if (!decoder_config_check_pending_)
+
114  return true;
+
115 
+
116  const H264Pps* pps = h264_parser_->GetPps(pps_id);
+
117  const H264Sps* sps;
+
118  if (!pps) {
+
119  // Only accept an invalid PPS at the beginning when the stream
+
120  // does not necessarily start with an SPS/PPS/IDR.
+
121  // In this case, the initial frames are conveyed to the upper layer with
+
122  // an invalid VideoDecoderConfig and it's up to the upper layer
+
123  // to process this kind of frame accordingly.
+
124  return last_video_decoder_config_ == nullptr;
+
125  } else {
+
126  sps = h264_parser_->GetSps(pps->seq_parameter_set_id);
+
127  if (!sps)
+
128  return false;
+
129  decoder_config_check_pending_ = false;
+
130  }
+
131 
+
132  std::vector<uint8_t> decoder_config_record;
+
133  if (!stream_converter()->GetDecoderConfigurationRecord(
+
134  &decoder_config_record)) {
+
135  DLOG(ERROR) << "Failure to construct an AVCDecoderConfigurationRecord";
+
136  return false;
+
137  }
+
138 
+
139  if (last_video_decoder_config_) {
+
140  if (last_video_decoder_config_->codec_config() != decoder_config_record) {
+
141  // Video configuration has changed. Issue warning.
+
142  // TODO(tinskip): Check the nature of the configuration change. Only
+
143  // minor configuration changes (such as frame ordering) can be handled
+
144  // gracefully by decoders without notification. Major changes (such as
+
145  // video resolution changes) should be treated as errors.
+
146  LOG(WARNING) << "H.264 decoder configuration has changed.";
+
147  last_video_decoder_config_->set_codec_config(decoder_config_record);
+
148  }
+
149  return true;
+
150  }
+
151 
+
152  uint32_t coded_width = 0;
+
153  uint32_t coded_height = 0;
+
154  uint32_t pixel_width = 0;
+
155  uint32_t pixel_height = 0;
+
156  if (!ExtractResolutionFromSps(*sps, &coded_width, &coded_height, &pixel_width,
+
157  &pixel_height)) {
+
158  LOG(ERROR) << "Failed to parse SPS.";
+
159  return false;
+
160  }
+
161 
+
162  const uint8_t nalu_length_size =
+
163  H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize;
+
164  const H26xStreamFormat stream_format = stream_converter()->stream_format();
+
165  const FourCC codec_fourcc =
+
166  stream_format == H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
+
167  ? FOURCC_avc3
+
168  : FOURCC_avc1;
+
169  last_video_decoder_config_ = std::make_shared<VideoStreamInfo>(
+
170  pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH264, stream_format,
+
171  AVCDecoderConfigurationRecord::GetCodecString(
+
172  codec_fourcc, decoder_config_record[1], decoder_config_record[2],
+
173  decoder_config_record[3]),
+
174  decoder_config_record.data(), decoder_config_record.size(), coded_width,
+
175  coded_height, pixel_width, pixel_height, sps->transfer_characteristics, 0,
+
176  nalu_length_size, std::string(), false);
+
177  DVLOG(1) << "Profile IDC: " << sps->profile_idc;
+
178  DVLOG(1) << "Level IDC: " << sps->level_idc;
+
179  DVLOG(1) << "log2_max_frame_num_minus4: " << sps->log2_max_frame_num_minus4;
+
180 
+
181  // Video config notification.
+
182  new_stream_info_cb_.Run(last_video_decoder_config_);
+
183 
+
184  return true;
+
185 }
+
186 
+
187 } // namespace mp2t
+
188 } // namespace media
+
189 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d1a/classshaka_1_1media_1_1AV1CodecConfigurationRecord-members.html b/docs/d6/d1a/classshaka_1_1media_1_1AV1CodecConfigurationRecord-members.html index b23c6f925b..7bfaa35e44 100644 --- a/docs/d6/d1a/classshaka_1_1media_1_1AV1CodecConfigurationRecord-members.html +++ b/docs/d6/d1a/classshaka_1_1media_1_1AV1CodecConfigurationRecord-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/d1a/structshaka_1_1media_1_1mp4_1_1MovieHeader.html b/docs/d6/d1a/structshaka_1_1media_1_1mp4_1_1MovieHeader.html index 2d4958af0e..cf617ba8e5 100644 --- a/docs/d6/d1a/structshaka_1_1media_1_1mp4_1_1MovieHeader.html +++ b/docs/d6/d1a/structshaka_1_1media_1_1mp4_1_1MovieHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MovieHeader Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -139,7 +142,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 174 of file box_definitions.h.

+

Definition at line 175 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -167,7 +170,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 532 of file box_definitions.cc.

+

Definition at line 544 of file box_definitions.cc.

@@ -178,9 +181,7 @@ Additional Inherited Members diff --git a/docs/d6/d1a/ts__packet__writer__util_8cc_source.html b/docs/d6/d1a/ts__packet__writer__util_8cc_source.html index 359c00276d..0a75b6a306 100644 --- a/docs/d6/d1a/ts__packet__writer__util_8cc_source.html +++ b/docs/d6/d1a/ts__packet__writer__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_packet_writer_util.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
ts_packet_writer_util.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp2t/ts_packet_writer_util.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/media/base/buffer_writer.h"
11 #include "packager/media/formats/mp2t/continuity_counter.h"
12 
13 namespace shaka {
14 namespace media {
15 namespace mp2t {
16 
17 namespace {
18 
19 const int kPcrFieldsSize = 6;
20 const uint8_t kSyncByte = 0x47;
21 
22 // This is the size of the first few fields in a TS packet, i.e. TS packet size
23 // without adaptation field or the payload.
24 const int kTsPacketHeaderSize = 4;
25 const int kTsPacketSize = 188;
26 const int kTsPacketMaximumPayloadSize =
27  kTsPacketSize - kTsPacketHeaderSize;
28 
29 // Used for adaptation field padding bytes.
30 const uint8_t kPaddingBytes[] = {
31  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
33  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
34  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
35  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
36  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
37  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
38  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
39  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
40  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
41  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
42  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
43  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
44  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
45  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
46  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
47  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
48  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
49  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
50  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
51  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
52  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
53  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
54  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
55 };
56 static_assert(arraysize(kPaddingBytes) >= kTsPacketMaximumPayloadSize,
57  "Padding array is not big enough.");
58 
59 // |remaining_data_size| is the amount of data that has to be written. This may
60 // be bigger than a TS packet size.
61 // |remaining_data_size| matters if it is short and requires padding.
62 void WriteAdaptationField(bool has_pcr,
63  uint64_t pcr_base,
64  size_t remaining_data_size,
65  BufferWriter* writer) {
66  // Special case where a TS packet requires 1 byte padding.
67  if (!has_pcr && remaining_data_size == kTsPacketMaximumPayloadSize - 1) {
68  writer->AppendInt(static_cast<uint8_t>(0));
69  return;
70  }
71 
72  // The size of the field itself.
73  const int kAdaptationFieldLengthSize = 1;
74 
75  // The size of all leading flags (not including the adaptation_field_length).
76  const int kAdaptationFieldHeaderSize = 1;
77  size_t adaptation_field_length =
78  kAdaptationFieldHeaderSize + (has_pcr ? kPcrFieldsSize : 0);
79  if (remaining_data_size < kTsPacketMaximumPayloadSize) {
80  const size_t current_ts_size = kTsPacketHeaderSize + remaining_data_size +
81  adaptation_field_length +
82  kAdaptationFieldLengthSize;
83  if (current_ts_size < kTsPacketSize) {
84  adaptation_field_length += kTsPacketSize - current_ts_size;
85  }
86  }
87 
88  writer->AppendInt(static_cast<uint8_t>(adaptation_field_length));
89  int remaining_bytes = static_cast<int>(adaptation_field_length);
90  writer->AppendInt(static_cast<uint8_t>(
91  // All flags except PCR_flag are 0.
92  static_cast<uint8_t>(has_pcr) << 4));
93  remaining_bytes -= 1;
94 
95  if (has_pcr) {
96  // program_clock_reference_extension = 0.
97  const uint32_t most_significant_32bits_pcr =
98  static_cast<uint32_t>(pcr_base >> 1);
99  const uint16_t pcr_last_bit_reserved_and_pcr_extension =
100  ((pcr_base & 1) << 15);
101  writer->AppendInt(most_significant_32bits_pcr);
102  writer->AppendInt(pcr_last_bit_reserved_and_pcr_extension);
103  remaining_bytes -= kPcrFieldsSize;
104  }
105  DCHECK_GE(remaining_bytes, 0);
106  if (remaining_bytes == 0)
107  return;
108 
109  DCHECK_GE(static_cast<int>(arraysize(kPaddingBytes)), remaining_bytes);
110  writer->AppendArray(kPaddingBytes, remaining_bytes);
111 }
112 
113 } // namespace
114 
115 void WritePayloadToBufferWriter(const uint8_t* payload,
116  size_t payload_size,
117  bool payload_unit_start_indicator,
118  int pid,
119  bool has_pcr,
120  uint64_t pcr_base,
121  ContinuityCounter* continuity_counter,
122  BufferWriter* writer) {
123  size_t payload_bytes_written = 0;
124 
125  do {
126  const bool must_write_adaptation_header = has_pcr;
127  const size_t bytes_left = payload_size - payload_bytes_written;
128  const bool has_adaptation_field = must_write_adaptation_header ||
129  bytes_left < kTsPacketMaximumPayloadSize;
130 
131  writer->AppendInt(kSyncByte);
132  writer->AppendInt(static_cast<uint16_t>(
133  // transport_error_indicator and transport_priority are both '0'.
134  static_cast<int>(payload_unit_start_indicator) << 14 | pid));
135 
136  const uint8_t adaptation_field_control =
137  ((has_adaptation_field ? 1 : 0) << 1) | ((bytes_left != 0) ? 1 : 0);
138  // transport_scrambling_control is '00'.
139  writer->AppendInt(static_cast<uint8_t>(adaptation_field_control << 4 |
140  continuity_counter->GetNext()));
141 
142  if (has_adaptation_field) {
143  const size_t before = writer->Size();
144  WriteAdaptationField(has_pcr, pcr_base, bytes_left, writer);
145  const size_t bytes_for_adaptation_field = writer->Size() - before;
146 
147  const size_t write_bytes =
148  kTsPacketMaximumPayloadSize - bytes_for_adaptation_field;
149  writer->AppendArray(payload + payload_bytes_written, write_bytes);
150  payload_bytes_written += write_bytes;
151  } else {
152  writer->AppendArray(payload + payload_bytes_written,
153  kTsPacketMaximumPayloadSize);
154  payload_bytes_written += kTsPacketMaximumPayloadSize;
155  }
156 
157  // Once written, not needed for this payload.
158  has_pcr = false;
159  payload_unit_start_indicator = false;
160  } while (payload_bytes_written < payload_size);
161 }
162 
163 } // namespace mp2t
164 } // namespace media
165 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp2t/ts_packet_writer_util.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/media/base/buffer_writer.h"
+
11 #include "packager/media/formats/mp2t/continuity_counter.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 namespace mp2t {
+
16 
+
17 namespace {
+
18 
+
19 const int kPcrFieldsSize = 6;
+
20 const uint8_t kSyncByte = 0x47;
+
21 
+
22 // This is the size of the first few fields in a TS packet, i.e. TS packet size
+
23 // without adaptation field or the payload.
+
24 const int kTsPacketHeaderSize = 4;
+
25 const int kTsPacketSize = 188;
+
26 const int kTsPacketMaximumPayloadSize =
+
27  kTsPacketSize - kTsPacketHeaderSize;
+
28 
+
29 // Used for adaptation field padding bytes.
+
30 const uint8_t kPaddingBytes[] = {
+
31  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
32  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
33  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
34  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
35  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
36  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
37  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
38  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
39  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
40  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
41  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
42  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
43  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
44  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
45  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
46  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
47  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
48  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
49  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
50  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
51  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
52  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
53  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
54  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+
55 };
+
56 static_assert(arraysize(kPaddingBytes) >= kTsPacketMaximumPayloadSize,
+
57  "Padding array is not big enough.");
+
58 
+
59 // |remaining_data_size| is the amount of data that has to be written. This may
+
60 // be bigger than a TS packet size.
+
61 // |remaining_data_size| matters if it is short and requires padding.
+
62 void WriteAdaptationField(bool has_pcr,
+
63  uint64_t pcr_base,
+
64  size_t remaining_data_size,
+
65  BufferWriter* writer) {
+
66  // Special case where a TS packet requires 1 byte padding.
+
67  if (!has_pcr && remaining_data_size == kTsPacketMaximumPayloadSize - 1) {
+
68  writer->AppendInt(static_cast<uint8_t>(0));
+
69  return;
+
70  }
+
71 
+
72  // The size of the field itself.
+
73  const int kAdaptationFieldLengthSize = 1;
+
74 
+
75  // The size of all leading flags (not including the adaptation_field_length).
+
76  const int kAdaptationFieldHeaderSize = 1;
+
77  size_t adaptation_field_length =
+
78  kAdaptationFieldHeaderSize + (has_pcr ? kPcrFieldsSize : 0);
+
79  if (remaining_data_size < kTsPacketMaximumPayloadSize) {
+
80  const size_t current_ts_size = kTsPacketHeaderSize + remaining_data_size +
+
81  adaptation_field_length +
+
82  kAdaptationFieldLengthSize;
+
83  if (current_ts_size < kTsPacketSize) {
+
84  adaptation_field_length += kTsPacketSize - current_ts_size;
+
85  }
+
86  }
+
87 
+
88  writer->AppendInt(static_cast<uint8_t>(adaptation_field_length));
+
89  int remaining_bytes = static_cast<int>(adaptation_field_length);
+
90  writer->AppendInt(static_cast<uint8_t>(
+
91  // All flags except PCR_flag are 0.
+
92  static_cast<uint8_t>(has_pcr) << 4));
+
93  remaining_bytes -= 1;
+
94 
+
95  if (has_pcr) {
+
96  // program_clock_reference_extension = 0.
+
97  const uint32_t most_significant_32bits_pcr =
+
98  static_cast<uint32_t>(pcr_base >> 1);
+
99  const uint16_t pcr_last_bit_reserved_and_pcr_extension =
+
100  ((pcr_base & 1) << 15) | 0x7e00; // Set the 6 reserved bits to '1'
+
101  writer->AppendInt(most_significant_32bits_pcr);
+
102  writer->AppendInt(pcr_last_bit_reserved_and_pcr_extension);
+
103  remaining_bytes -= kPcrFieldsSize;
+
104  }
+
105  DCHECK_GE(remaining_bytes, 0);
+
106  if (remaining_bytes == 0)
+
107  return;
+
108 
+
109  DCHECK_GE(static_cast<int>(arraysize(kPaddingBytes)), remaining_bytes);
+
110  writer->AppendArray(kPaddingBytes, remaining_bytes);
+
111 }
+
112 
+
113 } // namespace
+
114 
+
115 void WritePayloadToBufferWriter(const uint8_t* payload,
+
116  size_t payload_size,
+
117  bool payload_unit_start_indicator,
+
118  int pid,
+
119  bool has_pcr,
+
120  uint64_t pcr_base,
+
121  ContinuityCounter* continuity_counter,
+
122  BufferWriter* writer) {
+
123  size_t payload_bytes_written = 0;
+
124 
+
125  do {
+
126  const bool must_write_adaptation_header = has_pcr;
+
127  const size_t bytes_left = payload_size - payload_bytes_written;
+
128  const bool has_adaptation_field = must_write_adaptation_header ||
+
129  bytes_left < kTsPacketMaximumPayloadSize;
+
130 
+
131  writer->AppendInt(kSyncByte);
+
132  writer->AppendInt(static_cast<uint16_t>(
+
133  // transport_error_indicator and transport_priority are both '0'.
+
134  static_cast<int>(payload_unit_start_indicator) << 14 | pid));
+
135 
+
136  const uint8_t adaptation_field_control =
+
137  ((has_adaptation_field ? 1 : 0) << 1) | ((bytes_left != 0) ? 1 : 0);
+
138  // transport_scrambling_control is '00'.
+
139  writer->AppendInt(static_cast<uint8_t>(adaptation_field_control << 4 |
+
140  continuity_counter->GetNext()));
+
141 
+
142  if (has_adaptation_field) {
+
143  const size_t before = writer->Size();
+
144  WriteAdaptationField(has_pcr, pcr_base, bytes_left, writer);
+
145  const size_t bytes_for_adaptation_field = writer->Size() - before;
+
146 
+
147  const size_t write_bytes =
+
148  kTsPacketMaximumPayloadSize - bytes_for_adaptation_field;
+
149  writer->AppendArray(payload + payload_bytes_written, write_bytes);
+
150  payload_bytes_written += write_bytes;
+
151  } else {
+
152  writer->AppendArray(payload + payload_bytes_written,
+
153  kTsPacketMaximumPayloadSize);
+
154  payload_bytes_written += kTsPacketMaximumPayloadSize;
+
155  }
+
156 
+
157  // Once written, not needed for this payload.
+
158  has_pcr = false;
+
159  payload_unit_start_indicator = false;
+
160  } while (payload_bytes_written < payload_size);
+
161 }
+
162 
+
163 } // namespace mp2t
+
164 } // namespace media
+
165 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d22/classshaka_1_1media_1_1DvbImageColorSpace-members.html b/docs/d6/d22/classshaka_1_1media_1_1DvbImageColorSpace-members.html new file mode 100644 index 0000000000..1403017ae1 --- /dev/null +++ b/docs/d6/d22/classshaka_1_1media_1_1DvbImageColorSpace-members.html @@ -0,0 +1,90 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::DvbImageColorSpace Member List
+
+
+ +

This is the complete list of members for shaka::media::DvbImageColorSpace, including all inherited members.

+ + + + + + + + + + +
DvbImageColorSpace() (defined in shaka::media::DvbImageColorSpace)shaka::media::DvbImageColorSpace
DvbImageColorSpace(const DvbImageColorSpace &)=delete (defined in shaka::media::DvbImageColorSpace)shaka::media::DvbImageColorSpace
GetColor(BitDepth bit_depth, uint8_t entry_id) const (defined in shaka::media::DvbImageColorSpace)shaka::media::DvbImageColorSpace
operator=(const DvbImageColorSpace &)=delete (defined in shaka::media::DvbImageColorSpace)shaka::media::DvbImageColorSpace
Set2To4BitDepthMap(const uint8_t *map)shaka::media::DvbImageColorSpace
Set2To8BitDepthMap(const uint8_t *map)shaka::media::DvbImageColorSpace
Set4To8BitDepthMap(const uint8_t *map)shaka::media::DvbImageColorSpace
SetColor(BitDepth bit_depth, uint8_t entry_id, RgbaColor color) (defined in shaka::media::DvbImageColorSpace)shaka::media::DvbImageColorSpace
~DvbImageColorSpace() (defined in shaka::media::DvbImageColorSpace)shaka::media::DvbImageColorSpace
+ + + + diff --git a/docs/d6/d26/structshaka_1_1media_1_1VideoStreamInfoParameters.html b/docs/d6/d26/structshaka_1_1media_1_1VideoStreamInfoParameters.html index cf598de4c0..8f42d21fdb 100644 --- a/docs/d6/d26/structshaka_1_1media_1_1VideoStreamInfoParameters.html +++ b/docs/d6/d26/structshaka_1_1media_1_1VideoStreamInfoParameters.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::VideoStreamInfoParameters Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
is_encrypted
diff --git a/docs/d6/d2a/classshaka_1_1media_1_1WebVttTextOutputHandler.png b/docs/d6/d2a/classshaka_1_1media_1_1WebVttTextOutputHandler.png deleted file mode 100644 index 70706d4b6967d1d9c61d55f11aa691538055d6f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 826 zcmeAS@N?(olHy`uVBq!ia0vp^uYov#gBeJkzgZLrq$C1-LR|m<{|{uoc=NTi|Ih>= z3ycpOIKbL@M;^%KC<*clW&kPzfvcxNj2IZ0PI|gHhEy=VoqK!IV+9`8*^gKK{O=!k zpMmrA%pK1*?LIKY|CoT{N=J?LI;S`BD2aJWIZY0o^y_lU)FuDEOfdCa)i3WEwBqWT zt!Ey0@3$)4)2hhSKIzNMy3Wu^)t5X!9lC!%n${gl;<&aIn2ac1IP z!!>IvYaSQKdtXYgn*H^|{>t+ci>7$hO3X+(WLow#+j;ZcZ_)YJ#oASlRvn7kStO>~ zRl74K#{1k1);0GEY`4BWADX*6)lA;AYVC2;m{ZF)U7K=;QC@A`mAyB!ox=|+zJB?E zJ>u}$y>Hf9U*C2>dh_+R=~8{?zB;zo)WtV9d|&hMYf<^bleK$`e{h?|_;2O0$+%+n zHZdxGW1@)8tHYDNw8{P3=XI%m^+_$yznPo7g6e0jnRI17TXO8QR7q!s{p9kKdt;Lty74Fga))0gEZxh~9C({=!A!!K~4Uu)?UHbKq=4&Shb ze)AEG?ed~)^Ri=;wpVO7SDRg%k@m!Pe%zdF1=_GIbpn2qO!kH$}~ zo*ZaeT6cZ|>y;-lJU#0R&VD@`VJdglo$0s5wc7@Hr_^395--m!yy@_C!5eSs%j)Up z_TOFQA9?y@>zeS2;+xLR&y-@bcFd_u-CBF-P3+3uQHF}EjdcWVv-MuMui4g?Z?2re zD;rnk6OeXR?_SA_>ua{3yPvps+KkUdse8*S&P(0v>$rO7x|(}-@;0Ri$++XYU)4n% zHqDZ(xUk~&OtZJuIWH%bZgVTC{W0g9_@giJzc$R>PWrRM diff --git a/docs/d6/d2c/ts__stream__type_8h_source.html b/docs/d6/d2c/ts__stream__type_8h_source.html index 1dd07b9af5..eeb0a5b43b 100644 --- a/docs/d6/d2c/ts__stream__type_8h_source.html +++ b/docs/d6/d2c/ts__stream__type_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_stream_type.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
ts_stream_type.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_STREAM_TYPE_H_
8 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_STREAM_TYPE_H_
9 
10 #include <stdint.h>
11 
12 namespace shaka {
13 namespace media {
14 namespace mp2t {
15 
16 enum class TsStreamType {
17  // ISO-13818.1 / ITU H.222 Table 2-34 "Stream type assignments"
18  kMpeg1Video = 0x01, // ISO/IEC 11172-2 Video
19  kMpeg2Video = 0x02, // ITU-T H.262 | ISO/IEC 13818-2 Video |
20  // ISO/IEC 11172-2 constrained parameter video stream
21  kMpeg1Audio = 0x03, // ISO/IEC 11172-3 Audio
22  kMpeg2Audio = 0x04, // ISO/IEC 13818-3 Audio
23  kPesPrivateData =
24  0x06, // ISO/IEC 13818-1 PES packets containing private data. It is also
25  // used by DVB (TS 101 154 DVB specification ...) to carry AC3 in
26  // TS (while ATSC uses 0x81 defined below).
27  kAdtsAac = 0x0F,
28  kAvc = 0x1B,
29  kHevc = 0x24,
30  // Below are extensions defined in other specifications.
31  // AC3 and E-AC3 are defined in ATSC Standard A/52.
32  // Cannot find specification for DTS-HD and DTS. They are extracted from
33  // https://sno.phy.queensu.ca/~phil/exiftool/TagNames/M2TS.html.
34  kAc3 = 0x81,
35  kDtsHd = 0x86,
36  kEac3 = 0x87,
37  kDts = 0x8A,
38  // MPEG-2 Stream Encryption Format for HTTP Live Streaming:
39  // https://goo.gl/N7Tvqi.
40  kEncryptedAc3 = 0xC1,
41  kEncryptedEac3 = 0xC2,
42  kEncryptedAdtsAac = 0xCF,
43  kEncryptedAvc = 0xDB,
44 };
45 
46 } // namespace mp2t
47 } // namespace media
48 } // namespace shaka
49 
50 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_STREAM_TYPE_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_STREAM_TYPE_H_
+
8 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_STREAM_TYPE_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 namespace mp2t {
+
15 
+
16 enum class TsStreamType {
+
17  // ISO-13818.1 / ITU H.222 Table 2-34 "Stream type assignments"
+
18  kMpeg1Video = 0x01, // ISO/IEC 11172-2 Video
+
19  kMpeg2Video = 0x02, // ITU-T H.262 | ISO/IEC 13818-2 Video |
+
20  // ISO/IEC 11172-2 constrained parameter video stream
+
21  kMpeg1Audio = 0x03, // ISO/IEC 11172-3 Audio
+
22  kMpeg2Audio = 0x04, // ISO/IEC 13818-3 Audio
+
23  kPesPrivateData =
+
24  0x06, // ISO/IEC 13818-1 PES packets containing private data. It is also
+
25  // used by DVB (TS 101 154 DVB specification ...) to carry AC3 in
+
26  // TS (while ATSC uses 0x81 defined below).
+
27  kAdtsAac = 0x0F,
+
28  kAvc = 0x1B,
+
29  kHevc = 0x24,
+
30  // Below are extensions defined in other specifications.
+
31  // AC3 and E-AC3 are defined in ATSC Standard A/52.
+
32  // Cannot find specification for DTS-HD and DTS. They are extracted from
+
33  // https://sno.phy.queensu.ca/~phil/exiftool/TagNames/M2TS.html.
+
34  kAc3 = 0x81,
+
35  kDtsHd = 0x86,
+
36  kEac3 = 0x87,
+
37  kDts = 0x8A,
+
38  // MPEG-2 Stream Encryption Format for HTTP Live Streaming:
+
39  // https://goo.gl/N7Tvqi.
+
40  kEncryptedAc3 = 0xC1,
+
41  kEncryptedEac3 = 0xC2,
+
42  kEncryptedAdtsAac = 0xCF,
+
43  kEncryptedAvc = 0xDB,
+
44 
+
45  // Below are internal values used to select other stream types based on other
+
46  // info in headers.
+
47  kDvbSubtitles = 0x100,
+
48 };
+
49 
+
50 } // namespace mp2t
+
51 } // namespace media
+
52 } // namespace shaka
+
53 
+
54 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_STREAM_TYPE_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d2e/mpd__notifier__util_8cc_source.html b/docs/d6/d2e/mpd__notifier__util_8cc_source.html index 4bd7276b6b..16fe5e8cf8 100644 --- a/docs/d6/d2e/mpd__notifier__util_8cc_source.html +++ b/docs/d6/d2e/mpd__notifier__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mpd_notifier_util.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mpd_notifier_util.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/mpd/base/mpd_notifier_util.h"
8 
9 #include "packager/base/strings/string_number_conversions.h"
10 #include "packager/base/strings/string_util.h"
11 #include "packager/file/file.h"
12 #include "packager/mpd/base/mpd_utils.h"
13 
14 namespace shaka {
15 
16 bool WriteMpdToFile(const std::string& output_path, MpdBuilder* mpd_builder) {
17  CHECK(!output_path.empty());
18 
19  std::string mpd;
20  if (!mpd_builder->ToString(&mpd)) {
21  LOG(ERROR) << "Failed to write MPD to string.";
22  return false;
23  }
24 
25  if (!File::WriteFileAtomically(output_path.c_str(), mpd)) {
26  LOG(ERROR) << "Failed to write mpd to: " << output_path;
27  return false;
28  }
29  return true;
30 }
31 
32 ContentType GetContentType(const MediaInfo& media_info) {
33  const bool has_video = media_info.has_video_info();
34  const bool has_audio = media_info.has_audio_info();
35  const bool has_text = media_info.has_text_info();
36 
37  if (MoreThanOneTrue(has_video, has_audio, has_text)) {
38  NOTIMPLEMENTED() << "MediaInfo with more than one stream is not supported.";
39  return kContentTypeUnknown;
40  }
41  if (!AtLeastOneTrue(has_video, has_audio, has_text)) {
42  LOG(ERROR) << "MediaInfo should contain one audio, video, or text stream.";
43  return kContentTypeUnknown;
44  }
45  return has_video ? kContentTypeVideo
46  : (has_audio ? kContentTypeAudio : kContentTypeText);
47 }
48 
49 std::string Uint8VectorToBase64(const std::vector<uint8_t>& input) {
50  std::string output;
51  std::string input_in_string(input.begin(), input.end());
52  base::Base64Encode(input_in_string, &output);
53  return output;
54 }
55 
56 } // namespace shaka
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:37
-
All the methods that are virtual are virtual for mocking.
-
std::string Uint8VectorToBase64(const std::vector< uint8_t > &input)
Converts uint8 vector into base64 encoded string.
-
virtual bool ToString(std::string *output)
Definition: mpd_builder.cc:157
-
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:262
-
ContentType GetContentType(const MediaInfo &media_info)
-
bool WriteMpdToFile(const std::string &output_path, MpdBuilder *mpd_builder)
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/mpd/base/mpd_notifier_util.h"
+
8 
+
9 #include "packager/base/strings/string_number_conversions.h"
+
10 #include "packager/base/strings/string_util.h"
+
11 #include "packager/file/file.h"
+
12 #include "packager/mpd/base/mpd_utils.h"
+
13 
+
14 namespace shaka {
+
15 
+
16 bool WriteMpdToFile(const std::string& output_path, MpdBuilder* mpd_builder) {
+
17  CHECK(!output_path.empty());
+
18 
+
19  std::string mpd;
+
20  if (!mpd_builder->ToString(&mpd)) {
+
21  LOG(ERROR) << "Failed to write MPD to string.";
+
22  return false;
+
23  }
+
24 
+
25  if (!File::WriteFileAtomically(output_path.c_str(), mpd)) {
+
26  LOG(ERROR) << "Failed to write mpd to: " << output_path;
+
27  return false;
+
28  }
+
29  return true;
+
30 }
+
31 
+
32 ContentType GetContentType(const MediaInfo& media_info) {
+
33  const bool has_video = media_info.has_video_info();
+
34  const bool has_audio = media_info.has_audio_info();
+
35  const bool has_text = media_info.has_text_info();
+
36 
+
37  if (MoreThanOneTrue(has_video, has_audio, has_text)) {
+
38  NOTIMPLEMENTED() << "MediaInfo with more than one stream is not supported.";
+
39  return kContentTypeUnknown;
+
40  }
+
41  if (!AtLeastOneTrue(has_video, has_audio, has_text)) {
+
42  LOG(ERROR) << "MediaInfo should contain one audio, video, or text stream.";
+
43  return kContentTypeUnknown;
+
44  }
+
45  return has_video ? kContentTypeVideo
+
46  : (has_audio ? kContentTypeAudio : kContentTypeText);
+
47 }
+
48 
+
49 std::string Uint8VectorToBase64(const std::vector<uint8_t>& input) {
+
50  std::string output;
+
51  std::string input_in_string(input.begin(), input.end());
+
52  base::Base64Encode(input_in_string, &output);
+
53  return output;
+
54 }
+
55 
+
56 } // namespace shaka
+
static bool WriteFileAtomically(const char *file_name, const std::string &contents)
Definition: file.cc:277
+
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:36
+
virtual bool ToString(std::string *output) WARN_UNUSED_RESULT
Definition: mpd_builder.cc:159
+
All the methods that are virtual are virtual for mocking.
+
std::string Uint8VectorToBase64(const std::vector< uint8_t > &input)
Converts uint8 vector into base64 encoded string.
+
ContentType GetContentType(const MediaInfo &media_info)
+
bool WriteMpdToFile(const std::string &output_path, MpdBuilder *mpd_builder)
diff --git a/docs/d6/d32/classshaka_1_1media_1_1TextTrack-members.html b/docs/d6/d32/classshaka_1_1media_1_1TextTrack-members.html index a7f348093a..723aaa1b3b 100644 --- a/docs/d6/d32/classshaka_1_1media_1_1TextTrack-members.html +++ b/docs/d6/d32/classshaka_1_1media_1_1TextTrack-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/d35/webm__content__encodings_8cc_source.html b/docs/d6/d35/webm__content__encodings_8cc_source.html index c826129153..ed8800cc93 100644 --- a/docs/d6/d35/webm__content__encodings_8cc_source.html +++ b/docs/d6/d35/webm__content__encodings_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_content_encodings.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webm_content_encodings.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/base/logging.h"
6 #include "packager/media/formats/webm/webm_content_encodings.h"
7 
8 namespace shaka {
9 namespace media {
10 
11 ContentEncoding::ContentEncoding()
12  : order_(kOrderInvalid),
13  scope_(kScopeInvalid),
14  type_(kTypeInvalid),
15  encryption_algo_(kEncAlgoInvalid),
16  cipher_mode_(kCipherModeInvalid) {
17 }
18 
19 ContentEncoding::~ContentEncoding() {}
20 
21 void ContentEncoding::SetEncryptionKeyId(const uint8_t* encryption_key_id,
22  int size) {
23  DCHECK(encryption_key_id);
24  DCHECK_GT(size, 0);
25  encryption_key_id_.assign(reinterpret_cast<const char*>(encryption_key_id),
26  size);
27 }
28 
29 } // namespace media
30 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/base/logging.h"
+
6 #include "packager/media/formats/webm/webm_content_encodings.h"
+
7 
+
8 namespace shaka {
+
9 namespace media {
+
10 
+
11 ContentEncoding::ContentEncoding()
+
12  : order_(kOrderInvalid),
+
13  scope_(kScopeInvalid),
+
14  type_(kTypeInvalid),
+
15  encryption_algo_(kEncAlgoInvalid),
+
16  cipher_mode_(kCipherModeInvalid) {
+
17 }
+
18 
+
19 ContentEncoding::~ContentEncoding() {}
+
20 
+
21 void ContentEncoding::SetEncryptionKeyId(const uint8_t* encryption_key_id,
+
22  int size) {
+
23  DCHECK(encryption_key_id);
+
24  DCHECK_GT(size, 0);
+
25  encryption_key_id_.assign(reinterpret_cast<const char*>(encryption_key_id),
+
26  size);
+
27 }
+
28 
+
29 } // namespace media
+
30 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d37/combined__muxer__listener_8cc_source.html b/docs/d6/d37/combined__muxer__listener_8cc_source.html index db48d14a95..40c85b5166 100644 --- a/docs/d6/d37/combined__muxer__listener_8cc_source.html +++ b/docs/d6/d37/combined__muxer__listener_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/combined_muxer_listener.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
combined_muxer_listener.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/event/combined_muxer_listener.h"
8 
9 namespace shaka {
10 namespace media {
11 
12 void CombinedMuxerListener::AddListener(
13  std::unique_ptr<MuxerListener> listener) {
14  muxer_listeners_.push_back(std::move(listener));
15 }
16 
18  bool is_initial_encryption_info,
19  FourCC protection_scheme,
20  const std::vector<uint8_t>& key_id,
21  const std::vector<uint8_t>& iv,
22  const std::vector<ProtectionSystemSpecificInfo>& key_system_info) {
23  for (auto& listener : muxer_listeners_) {
24  listener->OnEncryptionInfoReady(is_initial_encryption_info,
25  protection_scheme, key_id, iv,
26  key_system_info);
27  }
28 }
29 
31  for (auto& listener : muxer_listeners_) {
32  listener->OnEncryptionStart();
33  }
34 }
35 
37  const StreamInfo& stream_info,
38  uint32_t time_scale,
39  ContainerType container_type) {
40  for (auto& listener : muxer_listeners_) {
41  listener->OnMediaStart(muxer_options, stream_info, time_scale,
42  container_type);
43  }
44 }
45 
46 void CombinedMuxerListener::OnSampleDurationReady(uint32_t sample_duration) {
47  for (auto& listener : muxer_listeners_) {
48  listener->OnSampleDurationReady(sample_duration);
49  }
50 }
51 
53  float duration_seconds) {
54  for (auto& listener : muxer_listeners_) {
55  listener->OnMediaEnd(media_ranges, duration_seconds);
56  }
57 }
58 
59 void CombinedMuxerListener::OnNewSegment(const std::string& file_name,
60  int64_t start_time,
61  int64_t duration,
62  uint64_t segment_file_size) {
63  for (auto& listener : muxer_listeners_) {
64  listener->OnNewSegment(file_name, start_time, duration, segment_file_size);
65  }
66 }
67 
68 void CombinedMuxerListener::OnKeyFrame(int64_t timestamp,
69  uint64_t start_byte_offset,
70  uint64_t size) {
71  for (auto& listener : muxer_listeners_) {
72  listener->OnKeyFrame(timestamp, start_byte_offset, size);
73  }
74 }
75 
76 void CombinedMuxerListener::OnCueEvent(int64_t timestamp,
77  const std::string& cue_data) {
78  for (auto& listener : muxer_listeners_) {
79  listener->OnCueEvent(timestamp, cue_data);
80  }
81 }
82 
83 } // namespace media
84 } // namespace shaka
Abstract class holds stream information.
Definition: stream_info.h:62
-
void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
-
void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
- -
All the methods that are virtual are virtual for mocking.
-
void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
-
void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
-
void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
- -
void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
-
void OnSampleDurationReady(uint32_t sample_duration) override
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/event/combined_muxer_listener.h"
+
8 
+
9 namespace shaka {
+
10 namespace media {
+
11 
+
12 void CombinedMuxerListener::AddListener(
+
13  std::unique_ptr<MuxerListener> listener) {
+
14  muxer_listeners_.push_back(std::move(listener));
+
15 }
+
16 
+ +
18  bool is_initial_encryption_info,
+
19  FourCC protection_scheme,
+
20  const std::vector<uint8_t>& key_id,
+
21  const std::vector<uint8_t>& iv,
+
22  const std::vector<ProtectionSystemSpecificInfo>& key_system_info) {
+
23  for (auto& listener : muxer_listeners_) {
+
24  listener->OnEncryptionInfoReady(is_initial_encryption_info,
+
25  protection_scheme, key_id, iv,
+
26  key_system_info);
+
27  }
+
28 }
+
29 
+ +
31  for (auto& listener : muxer_listeners_) {
+
32  listener->OnEncryptionStart();
+
33  }
+
34 }
+
35 
+ +
37  const StreamInfo& stream_info,
+
38  uint32_t time_scale,
+
39  ContainerType container_type) {
+
40  for (auto& listener : muxer_listeners_) {
+
41  listener->OnMediaStart(muxer_options, stream_info, time_scale,
+
42  container_type);
+
43  }
+
44 }
+
45 
+
46 void CombinedMuxerListener::OnSampleDurationReady(uint32_t sample_duration) {
+
47  for (auto& listener : muxer_listeners_) {
+
48  listener->OnSampleDurationReady(sample_duration);
+
49  }
+
50 }
+
51 
+ +
53  float duration_seconds) {
+
54  for (auto& listener : muxer_listeners_) {
+
55  listener->OnMediaEnd(media_ranges, duration_seconds);
+
56  }
+
57 }
+
58 
+
59 void CombinedMuxerListener::OnNewSegment(const std::string& file_name,
+
60  int64_t start_time,
+
61  int64_t duration,
+
62  uint64_t segment_file_size) {
+
63  for (auto& listener : muxer_listeners_) {
+
64  listener->OnNewSegment(file_name, start_time, duration, segment_file_size);
+
65  }
+
66 }
+
67 
+
68 void CombinedMuxerListener::OnKeyFrame(int64_t timestamp,
+
69  uint64_t start_byte_offset,
+
70  uint64_t size) {
+
71  for (auto& listener : muxer_listeners_) {
+
72  listener->OnKeyFrame(timestamp, start_byte_offset, size);
+
73  }
+
74 }
+
75 
+
76 void CombinedMuxerListener::OnCueEvent(int64_t timestamp,
+
77  const std::string& cue_data) {
+
78  for (auto& listener : muxer_listeners_) {
+
79  listener->OnCueEvent(timestamp, cue_data);
+
80  }
+
81 }
+
82 
+
83 } // namespace media
+
84 } // namespace shaka
+
void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
+
void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
+ +
void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
+
void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
+
void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
+
void OnSampleDurationReady(uint32_t sample_duration) override
+
void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
All the methods that are virtual are virtual for mocking.
+ +
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
diff --git a/docs/d6/d3b/chunk__info__iterator_8cc_source.html b/docs/d6/d3b/chunk__info__iterator_8cc_source.html index 8444d8b4c6..7d27e83fa7 100644 --- a/docs/d6/d3b/chunk__info__iterator_8cc_source.html +++ b/docs/d6/d3b/chunk__info__iterator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/chunk_info_iterator.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
chunk_info_iterator.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp4/chunk_info_iterator.h"
8 
9 #include <algorithm>
10 #include <limits>
11 
12 #include "packager/base/logging.h"
13 
14 namespace shaka {
15 namespace media {
16 namespace mp4 {
17 
19  : chunk_sample_index_(0),
20  current_chunk_(0),
21  chunk_info_table_(sample_to_chunk.chunk_info),
22  iterator_(chunk_info_table_.begin()) {
23  if (iterator_ != chunk_info_table_.end())
24  current_chunk_ = iterator_->first_chunk;
25 }
26 ChunkInfoIterator::~ChunkInfoIterator() {}
27 
29  ++current_chunk_;
30  if (iterator_ + 1 != chunk_info_table_.end()) {
31  if (current_chunk_ >= (iterator_ + 1)->first_chunk)
32  ++iterator_;
33  }
34  chunk_sample_index_ = 0;
35  return true;
36 }
37 
39  ++chunk_sample_index_;
40  if (chunk_sample_index_ >= iterator_->samples_per_chunk)
41  AdvanceChunk();
42  return true;
43 }
44 
46  return iterator_ != chunk_info_table_.end() &&
47  chunk_sample_index_ < iterator_->samples_per_chunk;
48 }
49 
50 uint32_t ChunkInfoIterator::NumSamples(uint32_t start_chunk,
51  uint32_t end_chunk) const {
52  DCHECK_LE(start_chunk, end_chunk);
53 
54  uint32_t last_chunk = 0;
55  uint32_t num_samples = 0;
56  for (std::vector<ChunkInfo>::const_iterator it = chunk_info_table_.begin();
57  it != chunk_info_table_.end();
58  ++it) {
59  last_chunk = (it + 1 == chunk_info_table_.end())
60  ? std::numeric_limits<uint32_t>::max()
61  : (it + 1)->first_chunk - 1;
62  if (last_chunk >= start_chunk) {
63  num_samples += (std::min(end_chunk, last_chunk) -
64  std::max(start_chunk, it->first_chunk) + 1) *
65  it->samples_per_chunk;
66  if (last_chunk >= end_chunk)
67  break;
68  }
69  }
70  return num_samples;
71 }
72 
73 } // namespace mp4
74 } // namespace media
75 } // namespace shaka
- -
All the methods that are virtual are virtual for mocking.
- - -
uint32_t NumSamples(uint32_t start_chunk, uint32_t end_chunk) const
-
ChunkInfoIterator(const SampleToChunk &sample_to_chunk)
Create ChunkInfoIterator from sample to chunk box.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp4/chunk_info_iterator.h"
+
8 
+
9 #include <algorithm>
+
10 #include <limits>
+
11 
+
12 #include "packager/base/logging.h"
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 namespace mp4 {
+
17 
+ +
19  : chunk_sample_index_(0),
+
20  current_chunk_(0),
+
21  chunk_info_table_(sample_to_chunk.chunk_info),
+
22  iterator_(chunk_info_table_.begin()) {
+
23  if (iterator_ != chunk_info_table_.end())
+
24  current_chunk_ = iterator_->first_chunk;
+
25 }
+
26 ChunkInfoIterator::~ChunkInfoIterator() {}
+
27 
+ +
29  ++current_chunk_;
+
30  if (iterator_ + 1 != chunk_info_table_.end()) {
+
31  if (current_chunk_ >= (iterator_ + 1)->first_chunk)
+
32  ++iterator_;
+
33  }
+
34  chunk_sample_index_ = 0;
+
35  return true;
+
36 }
+
37 
+ +
39  ++chunk_sample_index_;
+
40  if (chunk_sample_index_ >= iterator_->samples_per_chunk)
+
41  AdvanceChunk();
+
42  return true;
+
43 }
+
44 
+ +
46  return iterator_ != chunk_info_table_.end() &&
+
47  chunk_sample_index_ < iterator_->samples_per_chunk;
+
48 }
+
49 
+
50 uint32_t ChunkInfoIterator::NumSamples(uint32_t start_chunk,
+
51  uint32_t end_chunk) const {
+
52  DCHECK_LE(start_chunk, end_chunk);
+
53 
+
54  uint32_t last_chunk = 0;
+
55  uint32_t num_samples = 0;
+
56  for (std::vector<ChunkInfo>::const_iterator it = chunk_info_table_.begin();
+
57  it != chunk_info_table_.end();
+
58  ++it) {
+
59  last_chunk = (it + 1 == chunk_info_table_.end())
+
60  ? std::numeric_limits<uint32_t>::max()
+
61  : (it + 1)->first_chunk - 1;
+
62  if (last_chunk >= start_chunk) {
+
63  num_samples += (std::min(end_chunk, last_chunk) -
+
64  std::max(start_chunk, it->first_chunk) + 1) *
+
65  it->samples_per_chunk;
+
66  if (last_chunk >= end_chunk)
+
67  break;
+
68  }
+
69  }
+
70  return num_samples;
+
71 }
+
72 
+
73 } // namespace mp4
+
74 } // namespace media
+
75 } // namespace shaka
+ + +
uint32_t NumSamples(uint32_t start_chunk, uint32_t end_chunk) const
+ +
ChunkInfoIterator(const SampleToChunk &sample_to_chunk)
Create ChunkInfoIterator from sample to chunk box.
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d6/d3e/pssh__generator__util_8h_source.html b/docs/d6/d3e/pssh__generator__util_8h_source.html index 643461811a..ecd138bd36 100644 --- a/docs/d6/d3e/pssh__generator__util_8h_source.html +++ b/docs/d6/d3e/pssh__generator__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/pssh_generator_util.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
pssh_generator_util.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_PSSH_GENERATOR_UTIL_H_
8 #define PACKAGER_MEDIA_BASE_PSSH_GENERATOR_UTIL_H_
9 
10 #include <iostream>
11 #include <memory>
12 #include <set>
13 #include <vector>
14 
15 namespace shaka {
16 namespace media {
17 
18 std::vector<uint8_t> GenerateWidevinePsshDataFromKeyIds(
19  const std::vector<std::vector<uint8_t>>& key_ids);
20 
21 } // namespace media
22 } // namespace shaka
23 
24 #endif // PACKAGER_MEDIA_BASE_PSSH_GENERATOR_UTIL_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_PSSH_GENERATOR_UTIL_H_
+
8 #define PACKAGER_MEDIA_BASE_PSSH_GENERATOR_UTIL_H_
+
9 
+
10 #include <iostream>
+
11 #include <memory>
+
12 #include <set>
+
13 #include <vector>
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 
+
18 std::vector<uint8_t> GenerateWidevinePsshDataFromKeyIds(
+
19  const std::vector<std::vector<uint8_t>>& key_ids);
+
20 
+
21 } // namespace media
+
22 } // namespace shaka
+
23 
+
24 #endif // PACKAGER_MEDIA_BASE_PSSH_GENERATOR_UTIL_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d46/structshaka_1_1media_1_1CueEventInfo.html b/docs/d6/d46/structshaka_1_1media_1_1CueEventInfo.html index f2ee8ff7dc..2dd3dcb60a 100644 --- a/docs/d6/d46/structshaka_1_1media_1_1CueEventInfo.html +++ b/docs/d6/d46/structshaka_1_1media_1_1CueEventInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::CueEventInfo Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
timestamp
diff --git a/docs/d6/d47/hls__params_8h_source.html b/docs/d6/d47/hls__params_8h_source.html index 189babc94c..ec5eeeecca 100644 --- a/docs/d6/d47/hls__params_8h_source.html +++ b/docs/d6/d47/hls__params_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/public/hls_params.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
hls_params.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_HLS_PUBLIC_HLS_PARAMS_H_
8 #define PACKAGER_HLS_PUBLIC_HLS_PARAMS_H_
9 
10 #include <string>
11 
12 namespace shaka {
13 
16 enum class HlsPlaylistType {
17  kVod,
18  kEvent,
19  kLive,
20 };
21 
23 struct HlsParams {
25  HlsPlaylistType playlist_type = HlsPlaylistType::kVod;
30  std::string base_url;
33  double time_shift_buffer_depth = 0;
40  size_t preserved_segments_outside_live_window = 0;
44  std::string key_uri;
50  std::string default_language;
53  std::string default_text_language;
58  double target_segment_duration = 0;
59 };
60 
61 } // namespace shaka
62 
63 #endif // PACKAGER_HLS_PUBLIC_HLS_PARAMS_H_
std::string master_playlist_output
HLS master playlist output path.
Definition: hls_params.h:27
-
HlsPlaylistType
Definition: hls_params.h:16
-
std::string default_text_language
Definition: hls_params.h:53
-
HLS related parameters.
Definition: hls_params.h:23
-
All the methods that are virtual are virtual for mocking.
-
std::string default_language
Definition: hls_params.h:50
-
std::string base_url
Definition: hls_params.h:30
-
std::string key_uri
Definition: hls_params.h:44
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_HLS_PUBLIC_HLS_PARAMS_H_
+
8 #define PACKAGER_HLS_PUBLIC_HLS_PARAMS_H_
+
9 
+
10 #include <string>
+
11 
+
12 namespace shaka {
+
13 
+
16 enum class HlsPlaylistType {
+
17  kVod,
+
18  kEvent,
+
19  kLive,
+
20 };
+
21 
+
23 struct HlsParams {
+
25  HlsPlaylistType playlist_type = HlsPlaylistType::kVod;
+ +
30  std::string base_url;
+ + +
44  std::string key_uri;
+
50  std::string default_language;
+
53  std::string default_text_language;
+
54  // Indicates that all media samples in the media segments can be decoded
+
55  // without information from other segments.
+
56  bool is_independent_segments;
+ +
64  uint32_t media_sequence_number = 0;
+
65 };
+
66 
+
67 } // namespace shaka
+
68 
+
69 #endif // PACKAGER_HLS_PUBLIC_HLS_PARAMS_H_
+
All the methods that are virtual are virtual for mocking.
+
HlsPlaylistType
Definition: hls_params.h:16
+
HLS related parameters.
Definition: hls_params.h:23
+
uint32_t media_sequence_number
Definition: hls_params.h:64
+
std::string base_url
Definition: hls_params.h:30
+
std::string key_uri
Definition: hls_params.h:44
+
std::string default_text_language
Definition: hls_params.h:53
+
HlsPlaylistType playlist_type
HLS playlist type. See HLS specification for details.
Definition: hls_params.h:25
+
size_t preserved_segments_outside_live_window
Definition: hls_params.h:40
+
double target_segment_duration
Definition: hls_params.h:61
+
std::string default_language
Definition: hls_params.h:50
+
double time_shift_buffer_depth
Definition: hls_params.h:33
+
std::string master_playlist_output
HLS master playlist output path.
Definition: hls_params.h:27
diff --git a/docs/d6/d48/classshaka_1_1media_1_1PackedAudioWriter.html b/docs/d6/d48/classshaka_1_1media_1_1PackedAudioWriter.html index d6e2412026..f7d668d287 100644 --- a/docs/d6/d48/classshaka_1_1media_1_1PackedAudioWriter.html +++ b/docs/d6/d48/classshaka_1_1media_1_1PackedAudioWriter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::PackedAudioWriter Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::Muxer shaka::media::MediaHandler - -
+ + - + - - + + @@ -216,9 +219,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html b/docs/d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html index a8bcd1f49f..e140c5ba18 100644 --- a/docs/d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html +++ b/docs/d6/d4c/classshaka_1_1media_1_1EncryptionHandler.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::EncryptionHandler Class Reference @@ -29,18 +29,21 @@

Public Member Functions

 PackedAudioWriter (const MuxerOptions &muxer_options)
 Create a MP4Muxer object from MuxerOptions.
 Create a MP4Muxer object from MuxerOptions.
 
- Public Member Functions inherited from shaka::media::Muxer
@@ -129,9 +132,9 @@ class PackedAudioWriterTes

Additional Inherited Members

- Static Public Member Functions inherited from shaka::media::MediaHandler
-static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
 
+static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
 
- Protected Member Functions inherited from shaka::media::Muxer
const MuxerOptionsoptions () const
- + +/* @license-end */
shaka::media::MediaHandler - -
+ + @@ -173,9 +176,9 @@ class  - - + +

Public Member Functions

EncryptionHandlerTes

Additional Inherited Members

- Static Public Member Functions inherited from shaka::media::MediaHandler
-static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
 
+static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
 

Detailed Description

@@ -207,7 +210,7 @@ static Status

Implements shaka::media::MediaHandler.

-

Definition at line 82 of file encryption_handler.cc.

+

Definition at line 175 of file encryption_handler.cc.

@@ -238,7 +241,7 @@ static Status

Implements shaka::media::MediaHandler.

-

Definition at line 93 of file encryption_handler.cc.

+

Definition at line 186 of file encryption_handler.cc.

@@ -249,9 +252,7 @@ static Status diff --git a/docs/d6/d4e/webm_2multi__segment__segmenter_8cc_source.html b/docs/d6/d4e/webm_2multi__segment__segmenter_8cc_source.html index 8a832fd70d..d989623a1e 100644 --- a/docs/d6/d4e/webm_2multi__segment__segmenter_8cc_source.html +++ b/docs/d6/d4e/webm_2multi__segment__segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/multi_segment_segmenter.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
multi_segment_segmenter.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webm/multi_segment_segmenter.h"
8 
9 #include "packager/media/base/muxer_options.h"
10 #include "packager/media/base/muxer_util.h"
11 #include "packager/media/base/stream_info.h"
12 #include "packager/media/event/muxer_listener.h"
13 #include "packager/status_macros.h"
14 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
15 
16 namespace shaka {
17 namespace media {
18 namespace webm {
19 
20 MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options)
21  : Segmenter(options), num_segment_(0) {}
22 
23 MultiSegmentSegmenter::~MultiSegmentSegmenter() {}
24 
26  uint64_t duration_timestamp,
27  bool is_subsegment) {
28  CHECK(cluster());
29  RETURN_IF_ERROR(Segmenter::FinalizeSegment(
30  start_timestamp, duration_timestamp, is_subsegment));
31  if (!cluster()->Finalize())
32  return Status(error::FILE_FAILURE, "Error finalizing segment.");
33 
34  if (!is_subsegment) {
35  const std::string segment_name = writer_->file()->file_name();
36  // Close the file, which also does flushing, to make sure the file is
37  // written before manifest is updated.
38  RETURN_IF_ERROR(writer_->Close());
39 
40  if (muxer_listener()) {
41  const uint64_t size = cluster()->Size();
42  muxer_listener()->OnNewSegment(segment_name, start_timestamp,
43  duration_timestamp, size);
44  }
45  VLOG(1) << "WEBM file '" << writer_->file()->file_name() << "' finalized.";
46  }
47  return Status::OK;
48 }
49 
50 bool MultiSegmentSegmenter::GetInitRangeStartAndEnd(uint64_t* start,
51  uint64_t* end) {
52  return false;
53 }
54 
55 bool MultiSegmentSegmenter::GetIndexRangeStartAndEnd(uint64_t* start,
56  uint64_t* end) {
57  return false;
58 }
59 
60 std::vector<Range> MultiSegmentSegmenter::GetSegmentRanges() {
61  return std::vector<Range>();
62 }
63 
64 Status MultiSegmentSegmenter::DoInitialize() {
65  std::unique_ptr<MkvWriter> writer(new MkvWriter);
66  Status status = writer->Open(options().output_file_name);
67  if (!status.ok())
68  return status;
69  writer_ = std::move(writer);
70  return WriteSegmentHeader(0, writer_.get());
71 }
72 
73 Status MultiSegmentSegmenter::DoFinalize() {
74  return Status::OK;
75 }
76 
77 Status MultiSegmentSegmenter::NewSegment(uint64_t start_timestamp,
78  bool is_subsegment) {
79  if (!is_subsegment) {
80  // Create a new file for the new segment.
81  std::string segment_name =
82  GetSegmentName(options().segment_template, start_timestamp,
83  num_segment_, options().bandwidth);
84  writer_.reset(new MkvWriter);
85  Status status = writer_->Open(segment_name);
86  if (!status.ok())
87  return status;
88  num_segment_++;
89  }
90 
91  const uint64_t start_timecode = FromBmffTimestamp(start_timestamp);
92  return SetCluster(start_timecode, 0, writer_.get());
93 }
94 
95 } // namespace webm
96 } // namespace media
97 } // namespace shaka
All the methods that are virtual are virtual for mocking.
- -
An implementation of IMkvWriter using our File type.
Definition: mkv_writer.h:21
-
virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
- -
Status FinalizeSegment(size_t stream_id, const SegmentInfo &segment_info)
Definition: segmenter.cc:147
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/webm/multi_segment_segmenter.h"
+
8 
+
9 #include "packager/media/base/muxer_options.h"
+
10 #include "packager/media/base/muxer_util.h"
+
11 #include "packager/media/base/stream_info.h"
+
12 #include "packager/media/event/muxer_listener.h"
+
13 #include "packager/status_macros.h"
+
14 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 namespace webm {
+
19 
+
20 MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options)
+
21  : Segmenter(options), num_segment_(0) {}
+
22 
+
23 MultiSegmentSegmenter::~MultiSegmentSegmenter() {}
+
24 
+
25 Status MultiSegmentSegmenter::FinalizeSegment(uint64_t start_timestamp,
+
26  uint64_t duration_timestamp,
+
27  bool is_subsegment) {
+
28  CHECK(cluster());
+
29  RETURN_IF_ERROR(Segmenter::FinalizeSegment(
+
30  start_timestamp, duration_timestamp, is_subsegment));
+
31  if (!cluster()->Finalize())
+
32  return Status(error::FILE_FAILURE, "Error finalizing segment.");
+
33 
+
34  if (!is_subsegment) {
+
35  std::string segment_name =
+
36  GetSegmentName(options().segment_template, start_timestamp,
+
37  num_segment_, options().bandwidth);
+
38 
+
39  // Close the file, which also does flushing, to make sure the file is
+
40  // written before manifest is updated.
+
41  RETURN_IF_ERROR(writer_->Close());
+
42 
+
43  if (!File::Copy(temp_file_name_.c_str(), segment_name.c_str()))
+
44  return Status(error::FILE_FAILURE, "Failure to copy memory file.");
+
45 
+
46  if (!File::Delete(temp_file_name_.c_str()))
+
47  return Status(error::FILE_FAILURE, "Failure to delete memory file.");
+
48 
+
49  num_segment_++;
+
50 
+
51  if (muxer_listener()) {
+
52  const uint64_t size = cluster()->Size();
+
53  muxer_listener()->OnNewSegment(segment_name, start_timestamp,
+
54  duration_timestamp, size);
+
55  }
+
56  VLOG(1) << "WEBM file '" << segment_name << "' finalized.";
+
57  }
+
58  return Status::OK;
+
59 }
+
60 
+
61 bool MultiSegmentSegmenter::GetInitRangeStartAndEnd(uint64_t* start,
+
62  uint64_t* end) {
+
63  return false;
+
64 }
+
65 
+
66 bool MultiSegmentSegmenter::GetIndexRangeStartAndEnd(uint64_t* start,
+
67  uint64_t* end) {
+
68  return false;
+
69 }
+
70 
+
71 std::vector<Range> MultiSegmentSegmenter::GetSegmentRanges() {
+
72  return std::vector<Range>();
+
73 }
+
74 
+
75 Status MultiSegmentSegmenter::DoInitialize() {
+
76  std::unique_ptr<MkvWriter> writer(new MkvWriter);
+
77  Status status = writer->Open(options().output_file_name);
+
78  if (!status.ok())
+
79  return status;
+
80  writer_ = std::move(writer);
+
81  return WriteSegmentHeader(0, writer_.get());
+
82 }
+
83 
+
84 Status MultiSegmentSegmenter::DoFinalize() {
+
85  return Status::OK;
+
86 }
+
87 
+
88 Status MultiSegmentSegmenter::NewSegment(uint64_t start_timestamp,
+
89  bool is_subsegment) {
+
90  if (!is_subsegment) {
+
91  temp_file_name_ =
+
92  "memory://" + GetSegmentName(options().segment_template,
+
93  start_timestamp, num_segment_,
+
94  options().bandwidth);
+
95 
+
96  writer_.reset(new MkvWriter);
+
97  Status status = writer_->Open(temp_file_name_);
+
98 
+
99  if (!status.ok())
+
100  return status;
+
101  }
+
102 
+
103  const uint64_t start_timecode = FromBmffTimestamp(start_timestamp);
+
104  return SetCluster(start_timecode, 0, writer_.get());
+
105 }
+
106 
+
107 } // namespace webm
+
108 } // namespace media
+
109 } // namespace shaka
+ +
An implementation of IMkvWriter using our File type.
Definition: mkv_writer.h:21
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d55/aes__cryptor_8cc_source.html b/docs/d6/d55/aes__cryptor_8cc_source.html index 54f3a45690..f4c95ac92f 100644 --- a/docs/d6/d55/aes__cryptor_8cc_source.html +++ b/docs/d6/d55/aes__cryptor_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/aes_cryptor.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
aes_cryptor.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/aes_cryptor.h"
8 
9 #include <openssl/aes.h>
10 #include <openssl/crypto.h>
11 #include <openssl/err.h>
12 #include <openssl/rand.h>
13 
14 #include <string>
15 #include <vector>
16 
17 #include "packager/base/logging.h"
18 
19 namespace {
20 
21 // According to ISO/IEC 23001-7:2016 CENC spec, IV should be either
22 // 64-bit (8-byte) or 128-bit (16-byte).
23 bool IsIvSizeValid(size_t iv_size) {
24  return iv_size == 8 || iv_size == 16;
25 }
26 
27 } // namespace
28 
29 namespace shaka {
30 namespace media {
31 
32 AesCryptor::AesCryptor(ConstantIvFlag constant_iv_flag)
33  : aes_key_(new AES_KEY),
34  constant_iv_flag_(constant_iv_flag),
35  num_crypt_bytes_(0) {
36  CRYPTO_library_init();
37 }
38 
39 AesCryptor::~AesCryptor() {}
40 
41 bool AesCryptor::Crypt(const std::vector<uint8_t>& text,
42  std::vector<uint8_t>* crypt_text) {
43  // Save text size to make it work for in-place conversion, since the
44  // next statement will update the text size.
45  const size_t text_size = text.size();
46  crypt_text->resize(text_size + NumPaddingBytes(text_size));
47  size_t crypt_text_size = crypt_text->size();
48  if (!Crypt(text.data(), text_size, crypt_text->data(), &crypt_text_size)) {
49  return false;
50  }
51  DCHECK_LE(crypt_text_size, crypt_text->size());
52  crypt_text->resize(crypt_text_size);
53  return true;
54 }
55 
56 bool AesCryptor::Crypt(const std::string& text, std::string* crypt_text) {
57  // Save text size to make it work for in-place conversion, since the
58  // next statement will update the text size.
59  const size_t text_size = text.size();
60  crypt_text->resize(text_size + NumPaddingBytes(text_size));
61  size_t crypt_text_size = crypt_text->size();
62  if (!Crypt(reinterpret_cast<const uint8_t*>(text.data()), text_size,
63  reinterpret_cast<uint8_t*>(&(*crypt_text)[0]), &crypt_text_size))
64  return false;
65  DCHECK_LE(crypt_text_size, crypt_text->size());
66  crypt_text->resize(crypt_text_size);
67  return true;
68 }
69 
70 bool AesCryptor::SetIv(const std::vector<uint8_t>& iv) {
71  if (!IsIvSizeValid(iv.size())) {
72  LOG(ERROR) << "Invalid IV size: " << iv.size();
73  return false;
74  }
75  iv_ = iv;
76  num_crypt_bytes_ = 0;
77  SetIvInternal();
78  return true;
79 }
80 
82  if (constant_iv_flag_ == kUseConstantIv)
83  return;
84 
85  uint64_t increment = 0;
86  // As recommended in ISO/IEC 23001-7:2016 CENC spec, for 64-bit (8-byte)
87  // IV_Sizes, initialization vectors for subsequent samples can be created by
88  // incrementing the initialization vector of the previous sample.
89  // For 128-bit (16-byte) IV_Sizes, initialization vectors for subsequent
90  // samples should be created by adding the block count of the previous sample
91  // to the initialization vector of the previous sample.
92  // There is no official recommendation of how IV for next sample should be
93  // generated for CBC mode. We use the same generation algorithm as CTR here.
94  if (iv_.size() == 8) {
95  increment = 1;
96  } else {
97  DCHECK_EQ(16u, iv_.size());
98  increment = (num_crypt_bytes_ + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE;
99  }
100 
101  for (int i = iv_.size() - 1; increment > 0 && i >= 0; --i) {
102  increment += iv_[i];
103  iv_[i] = increment & 0xFF;
104  increment >>= 8;
105  }
106  num_crypt_bytes_ = 0;
107  SetIvInternal();
108 }
109 
110 bool AesCryptor::GenerateRandomIv(FourCC protection_scheme,
111  std::vector<uint8_t>* iv) {
112  // ISO/IEC 23001-7:2016 10.1 and 10.3 For 'cenc' and 'cens'
113  // default_Per_Sample_IV_Size and Per_Sample_IV_Size SHOULD be 8-bytes.
114  // There is no official guideline on the iv size for 'cbc1' and 'cbcs',
115  // but 16-byte provides better security.
116  const size_t iv_size =
117  (protection_scheme == FOURCC_cenc || protection_scheme == FOURCC_cens)
118  ? 8
119  : 16;
120  iv->resize(iv_size);
121  if (RAND_bytes(iv->data(), iv_size) != 1) {
122  LOG(ERROR) << "RAND_bytes failed with error: "
123  << ERR_error_string(ERR_get_error(), NULL);
124  return false;
125  }
126  return true;
127 }
128 
129 size_t AesCryptor::NumPaddingBytes(size_t size) const {
130  // No padding by default.
131  return 0;
132 }
133 
134 } // namespace media
135 } // namespace shaka
-
AesCryptor(ConstantIvFlag constant_iv_flag)
Definition: aes_cryptor.cc:32
-
All the methods that are virtual are virtual for mocking.
-
static bool GenerateRandomIv(FourCC protection_scheme, std::vector< uint8_t > *iv)
Definition: aes_cryptor.cc:110
-
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
-
bool SetIv(const std::vector< uint8_t > &iv)
Definition: aes_cryptor.cc:70
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/aes_cryptor.h"
+
8 
+
9 #include <openssl/aes.h>
+
10 #include <openssl/crypto.h>
+
11 #include <openssl/err.h>
+
12 #include <openssl/rand.h>
+
13 
+
14 #include <string>
+
15 #include <vector>
+
16 
+
17 #include "packager/base/logging.h"
+
18 
+
19 namespace {
+
20 
+
21 // According to ISO/IEC 23001-7:2016 CENC spec, IV should be either
+
22 // 64-bit (8-byte) or 128-bit (16-byte).
+
23 bool IsIvSizeValid(size_t iv_size) {
+
24  return iv_size == 8 || iv_size == 16;
+
25 }
+
26 
+
27 } // namespace
+
28 
+
29 namespace shaka {
+
30 namespace media {
+
31 
+
32 AesCryptor::AesCryptor(ConstantIvFlag constant_iv_flag)
+
33  : aes_key_(new AES_KEY),
+
34  constant_iv_flag_(constant_iv_flag),
+
35  num_crypt_bytes_(0) {
+
36  CRYPTO_library_init();
+
37 }
+
38 
+
39 AesCryptor::~AesCryptor() {}
+
40 
+
41 bool AesCryptor::Crypt(const std::vector<uint8_t>& text,
+
42  std::vector<uint8_t>* crypt_text) {
+
43  // Save text size to make it work for in-place conversion, since the
+
44  // next statement will update the text size.
+
45  const size_t text_size = text.size();
+
46  crypt_text->resize(text_size + NumPaddingBytes(text_size));
+
47  size_t crypt_text_size = crypt_text->size();
+
48  if (!Crypt(text.data(), text_size, crypt_text->data(), &crypt_text_size)) {
+
49  return false;
+
50  }
+
51  DCHECK_LE(crypt_text_size, crypt_text->size());
+
52  crypt_text->resize(crypt_text_size);
+
53  return true;
+
54 }
+
55 
+
56 bool AesCryptor::Crypt(const std::string& text, std::string* crypt_text) {
+
57  // Save text size to make it work for in-place conversion, since the
+
58  // next statement will update the text size.
+
59  const size_t text_size = text.size();
+
60  crypt_text->resize(text_size + NumPaddingBytes(text_size));
+
61  size_t crypt_text_size = crypt_text->size();
+
62  if (!Crypt(reinterpret_cast<const uint8_t*>(text.data()), text_size,
+
63  reinterpret_cast<uint8_t*>(&(*crypt_text)[0]), &crypt_text_size))
+
64  return false;
+
65  DCHECK_LE(crypt_text_size, crypt_text->size());
+
66  crypt_text->resize(crypt_text_size);
+
67  return true;
+
68 }
+
69 
+
70 bool AesCryptor::SetIv(const std::vector<uint8_t>& iv) {
+
71  if (!IsIvSizeValid(iv.size())) {
+
72  LOG(ERROR) << "Invalid IV size: " << iv.size();
+
73  return false;
+
74  }
+
75  iv_ = iv;
+
76  num_crypt_bytes_ = 0;
+
77  SetIvInternal();
+
78  return true;
+
79 }
+
80 
+ +
82  if (constant_iv_flag_ == kUseConstantIv)
+
83  return;
+
84 
+
85  uint64_t increment = 0;
+
86  // As recommended in ISO/IEC 23001-7:2016 CENC spec, for 64-bit (8-byte)
+
87  // IV_Sizes, initialization vectors for subsequent samples can be created by
+
88  // incrementing the initialization vector of the previous sample.
+
89  // For 128-bit (16-byte) IV_Sizes, initialization vectors for subsequent
+
90  // samples should be created by adding the block count of the previous sample
+
91  // to the initialization vector of the previous sample.
+
92  // There is no official recommendation of how IV for next sample should be
+
93  // generated for CBC mode. We use the same generation algorithm as CTR here.
+
94  if (iv_.size() == 8) {
+
95  increment = 1;
+
96  } else {
+
97  DCHECK_EQ(16u, iv_.size());
+
98  increment = (num_crypt_bytes_ + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE;
+
99  }
+
100 
+
101  for (int i = iv_.size() - 1; increment > 0 && i >= 0; --i) {
+
102  increment += iv_[i];
+
103  iv_[i] = increment & 0xFF;
+
104  increment >>= 8;
+
105  }
+
106  num_crypt_bytes_ = 0;
+
107  SetIvInternal();
+
108 }
+
109 
+
110 bool AesCryptor::GenerateRandomIv(FourCC protection_scheme,
+
111  std::vector<uint8_t>* iv) {
+
112  // ISO/IEC 23001-7:2016 10.1 and 10.3 For 'cenc' and 'cens'
+
113  // default_Per_Sample_IV_Size and Per_Sample_IV_Size SHOULD be 8-bytes.
+
114  // There is no official guideline on the iv size for 'cbc1' and 'cbcs',
+
115  // but 16-byte provides better security.
+
116  const size_t iv_size =
+
117  (protection_scheme == FOURCC_cenc || protection_scheme == FOURCC_cens)
+
118  ? 8
+
119  : 16;
+
120  iv->resize(iv_size);
+
121  if (RAND_bytes(iv->data(), iv_size) != 1) {
+
122  LOG(ERROR) << "RAND_bytes failed with error: "
+
123  << ERR_error_string(ERR_get_error(), NULL);
+
124  return false;
+
125  }
+
126  return true;
+
127 }
+
128 
+
129 size_t AesCryptor::NumPaddingBytes(size_t size) const {
+
130  // No padding by default.
+
131  return 0;
+
132 }
+
133 
+
134 } // namespace media
+
135 } // namespace shaka
+
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
+
static bool GenerateRandomIv(FourCC protection_scheme, std::vector< uint8_t > *iv)
Definition: aes_cryptor.cc:110
+
AesCryptor(ConstantIvFlag constant_iv_flag)
Definition: aes_cryptor.cc:32
+
bool SetIv(const std::vector< uint8_t > &iv)
Definition: aes_cryptor.cc:70
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d57/classshaka_1_1media_1_1AVCDecoderConfigurationRecord.html b/docs/d6/d57/classshaka_1_1media_1_1AVCDecoderConfigurationRecord.html index a25c68afcf..ab47fb6ad5 100644 --- a/docs/d6/d57/classshaka_1_1media_1_1AVCDecoderConfigurationRecord.html +++ b/docs/d6/d57/classshaka_1_1media_1_1AVCDecoderConfigurationRecord.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AVCDecoderConfigurationRecord Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::DecoderConfigurationRecord - -
+ + @@ -113,6 +116,15 @@ uint32_t  + + + + + + @@ -174,7 +186,7 @@ void 

Public Member Functions

pixel_width (
uint32_t pixel_height () const
 
+uint8_t chroma_format () const
 
+uint8_t bit_depth_luma_minus8 () const
 
+uint8_t bit_depth_chroma_minus8 () const
 
- Public Member Functions inherited from shaka::media::DecoderConfigurationRecord
bool Parse (const std::vector< uint8_t > &data)
 
Returns
The codec string.
-

Definition at line 92 of file avc_decoder_configuration_record.cc.

+

Definition at line 112 of file avc_decoder_configuration_record.cc.

@@ -225,7 +237,7 @@ void 

Static version of GetCodecString.

Returns
The codec string.
-

Definition at line 98 of file avc_decoder_configuration_record.cc.

+

Definition at line 118 of file avc_decoder_configuration_record.cc.

@@ -236,9 +248,7 @@ void 
diff --git a/docs/d6/d59/protection__system__specific__info_8h_source.html b/docs/d6/d59/protection__system__specific__info_8h_source.html index 90e5d95db3..7bd04b7900 100644 --- a/docs/d6/d59/protection__system__specific__info_8h_source.html +++ b/docs/d6/d59/protection__system__specific__info_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/protection_system_specific_info.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
protection_system_specific_info.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_SPECIFIC_INFO_H_
8 #define PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_SPECIFIC_INFO_H_
9 
10 #include <stdint.h>
11 #include <memory>
12 #include <vector>
13 
14 #include "packager/base/logging.h"
15 
16 #define NO_PROTECTION_SYSTEM_FLAG 0x00
17 #define COMMON_PROTECTION_SYSTEM_FLAG 0x01
18 #define PLAYREADY_PROTECTION_SYSTEM_FLAG 0x02
19 #define WIDEVINE_PROTECTION_SYSTEM_FLAG 0x04
20 #define FAIRPLAY_PROTECTION_SYSTEM_FLAG 0x08
21 #define MARLIN_PROTECTION_SYSTEM_FLAG 0x10
22 
23 namespace shaka {
24 namespace media {
25 
27  std::vector<uint8_t> system_id;
28  std::vector<uint8_t> psshs;
29 
33  static bool ParseBoxes(
34  const uint8_t* data,
35  size_t data_size,
36  std::vector<ProtectionSystemSpecificInfo>* pssh_boxes);
37 };
38 
40  public:
41  PsshBoxBuilder() = default;
42  ~PsshBoxBuilder() = default;
43 
46  static std::unique_ptr<PsshBoxBuilder> ParseFromBox(const uint8_t* data,
47  size_t data_size);
48 
50  std::vector<uint8_t> CreateBox() const;
51 
52  uint8_t pssh_box_version() const { return version_; }
53  const std::vector<uint8_t>& system_id() const { return system_id_; }
54  const std::vector<std::vector<uint8_t>>& key_ids() const { return key_ids_; }
55  const std::vector<uint8_t>& pssh_data() const { return pssh_data_; }
56 
57  void set_pssh_box_version(uint8_t version) {
58  DCHECK_LT(version, 2);
59  version_ = version;
60  }
61  void set_system_id(const uint8_t* system_id, size_t system_id_size) {
62  DCHECK_EQ(16u, system_id_size);
63  system_id_.assign(system_id, system_id + system_id_size);
64  }
65  void add_key_id(const std::vector<uint8_t>& key_id) {
66  key_ids_.push_back(key_id);
67  }
68  void clear_key_ids() { key_ids_.clear(); }
69  void set_pssh_data(const std::vector<uint8_t>& pssh_data) {
70  pssh_data_ = pssh_data;
71  }
72 
73  private:
74  PsshBoxBuilder(const PsshBoxBuilder&) = delete;
75  PsshBoxBuilder& operator=(const PsshBoxBuilder&) = delete;
76 
77  uint8_t version_ = 0;
78  std::vector<uint8_t> system_id_;
79  std::vector<std::vector<uint8_t>> key_ids_;
80  std::vector<uint8_t> pssh_data_;
81 };
82 
83 } // namespace media
84 } // namespace shaka
85 
86 #endif // PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_SPECIFIC_INFO_H_
All the methods that are virtual are virtual for mocking.
- - -
static bool ParseBoxes(const uint8_t *data, size_t data_size, std::vector< ProtectionSystemSpecificInfo > *pssh_boxes)
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_SPECIFIC_INFO_H_
+
8 #define PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_SPECIFIC_INFO_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <memory>
+
12 #include <vector>
+
13 
+
14 #include "packager/base/logging.h"
+
15 #include "packager/media/public/crypto_params.h"
+
16 
+
17 namespace shaka {
+
18 namespace media {
+
19 
+ +
21  std::vector<uint8_t> system_id;
+
22  std::vector<uint8_t> psshs;
+
23 
+
27  static bool ParseBoxes(
+
28  const uint8_t* data,
+
29  size_t data_size,
+
30  std::vector<ProtectionSystemSpecificInfo>* pssh_boxes);
+
31 };
+
32 
+ +
34  public:
+
35  PsshBoxBuilder() = default;
+
36  ~PsshBoxBuilder() = default;
+
37 
+
40  static std::unique_ptr<PsshBoxBuilder> ParseFromBox(const uint8_t* data,
+
41  size_t data_size);
+
42 
+
44  std::vector<uint8_t> CreateBox() const;
+
45 
+
46  uint8_t pssh_box_version() const { return version_; }
+
47  const std::vector<uint8_t>& system_id() const { return system_id_; }
+
48  const std::vector<std::vector<uint8_t>>& key_ids() const { return key_ids_; }
+
49  const std::vector<uint8_t>& pssh_data() const { return pssh_data_; }
+
50 
+
51  void set_pssh_box_version(uint8_t version) {
+
52  DCHECK_LT(version, 2);
+
53  version_ = version;
+
54  }
+
55  void set_system_id(const uint8_t* system_id, size_t system_id_size) {
+
56  DCHECK_EQ(16u, system_id_size);
+
57  system_id_.assign(system_id, system_id + system_id_size);
+
58  }
+
59  void add_key_id(const std::vector<uint8_t>& key_id) {
+
60  key_ids_.push_back(key_id);
+
61  }
+
62  void clear_key_ids() { key_ids_.clear(); }
+
63  void set_pssh_data(const std::vector<uint8_t>& pssh_data) {
+
64  pssh_data_ = pssh_data;
+
65  }
+
66 
+
67  private:
+
68  PsshBoxBuilder(const PsshBoxBuilder&) = delete;
+
69  PsshBoxBuilder& operator=(const PsshBoxBuilder&) = delete;
+
70 
+
71  uint8_t version_ = 0;
+
72  std::vector<uint8_t> system_id_;
+
73  std::vector<std::vector<uint8_t>> key_ids_;
+
74  std::vector<uint8_t> pssh_data_;
+
75 };
+
76 
+
77 } // namespace media
+
78 } // namespace shaka
+
79 
+
80 #endif // PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_SPECIFIC_INFO_H_
+ +
std::vector< uint8_t > CreateBox() const
Creates a PSSH box for the current data.
+
static std::unique_ptr< PsshBoxBuilder > ParseFromBox(const uint8_t *data, size_t data_size)
+
All the methods that are virtual are virtual for mocking.
+ +
static bool ParseBoxes(const uint8_t *data, size_t data_size, std::vector< ProtectionSystemSpecificInfo > *pssh_boxes)
diff --git a/docs/d6/d5b/classshaka_1_1Status-members.html b/docs/d6/d5b/classshaka_1_1Status-members.html index aaa689ea0f..f1edbec2ad 100644 --- a/docs/d6/d5b/classshaka_1_1Status-members.html +++ b/docs/d6/d5b/classshaka_1_1Status-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/d60/classshaka_1_1media_1_1VPCodecConfigurationRecord-members.html b/docs/d6/d60/classshaka_1_1media_1_1VPCodecConfigurationRecord-members.html index bdc6c58b7e..babd7f4a45 100644 --- a/docs/d6/d60/classshaka_1_1media_1_1VPCodecConfigurationRecord-members.html +++ b/docs/d6/d60/classshaka_1_1media_1_1VPCodecConfigurationRecord-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/d62/structshaka_1_1TestParams.html b/docs/d6/d62/structshaka_1_1TestParams.html index aca1d964a3..09fc485e28 100644 --- a/docs/d6/d62/structshaka_1_1TestParams.html +++ b/docs/d6/d62/structshaka_1_1TestParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::TestParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/d66/structshaka_1_1RawKeyParams_1_1KeyInfo-members.html b/docs/d6/d66/structshaka_1_1RawKeyParams_1_1KeyInfo-members.html index 49dbd0f898..51407b3cf7 100644 --- a/docs/d6/d66/structshaka_1_1RawKeyParams_1_1KeyInfo-members.html +++ b/docs/d6/d66/structshaka_1_1RawKeyParams_1_1KeyInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */ diff --git a/docs/d6/d6b/classshaka_1_1media_1_1RawKeySource-members.html b/docs/d6/d6b/classshaka_1_1media_1_1RawKeySource-members.html index 3976f0345d..ba08d7f4df 100644 --- a/docs/d6/d6b/classshaka_1_1media_1_1RawKeySource-members.html +++ b/docs/d6/d6b/classshaka_1_1media_1_1RawKeySource-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
This is the complete list of members for shaka::media::RawKeySource, including all inherited members.

- + - + - - - + +
Create(const RawKeyParams &raw_key, int protection_system_flags, FourCC protection_scheme)shaka::media::RawKeySourcestatic
Create(const RawKeyParams &raw_key)shaka::media::RawKeySourcestatic
FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) overrideshaka::media::RawKeySourcevirtual
GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) overrideshaka::media::RawKeySourcevirtual
GetKey(const std::string &stream_label, EncryptionKey *key) overrideshaka::media::RawKeySourcevirtual
GetKey(const std::vector< uint8_t > &key_id, EncryptionKey *key) overrideshaka::media::RawKeySourcevirtual
KeySource(int protection_systems_flags, FourCC protection_scheme) (defined in shaka::media::KeySource)shaka::media::KeySource
KeySource() (defined in shaka::media::KeySource)shaka::media::KeySource
RawKeySource() (defined in shaka::media::RawKeySource)shaka::media::RawKeySourceprotected
UpdateProtectionSystemInfo(EncryptionKeyMap *encryption_key_map)shaka::media::KeySourceprotected
~KeySource() (defined in shaka::media::KeySource)shaka::media::KeySourcevirtual
~RawKeySource() override (defined in shaka::media::RawKeySource)shaka::media::RawKeySource
~KeySource() (defined in shaka::media::KeySource)shaka::media::KeySourcevirtual
~RawKeySource() override (defined in shaka::media::RawKeySource)shaka::media::RawKeySource
diff --git a/docs/d6/d6c/h26x__bit__reader_8cc_source.html b/docs/d6/d6c/h26x__bit__reader_8cc_source.html index 04ae330670..c04f71069f 100644 --- a/docs/d6/d6c/h26x__bit__reader_8cc_source.html +++ b/docs/d6/d6c/h26x__bit__reader_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h26x_bit_reader.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
h26x_bit_reader.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/base/logging.h"
6 #include "packager/media/codecs/h26x_bit_reader.h"
7 
8 namespace shaka {
9 namespace media {
10 namespace {
11 
12 // Check if any bits in the least significant |valid_bits| are set to 1.
13 bool CheckAnyBitsSet(int byte, int valid_bits) {
14  return (byte & ((1 << valid_bits) - 1)) != 0;
15 }
16 
17 } // namespace
18 
19 H26xBitReader::H26xBitReader()
20  : data_(NULL),
21  bytes_left_(0),
22  curr_byte_(0),
23  num_remaining_bits_in_curr_byte_(0),
24  prev_two_bytes_(0),
25  emulation_prevention_bytes_(0) {}
26 
27 H26xBitReader::~H26xBitReader() {}
28 
29 bool H26xBitReader::Initialize(const uint8_t* data, off_t size) {
30  DCHECK(data);
31 
32  if (size < 1)
33  return false;
34 
35  data_ = data;
36  bytes_left_ = size;
37  num_remaining_bits_in_curr_byte_ = 0;
38  // Initially set to 0xffff to accept all initial two-byte sequences.
39  prev_two_bytes_ = 0xffff;
40  emulation_prevention_bytes_ = 0;
41 
42  return true;
43 }
44 
45 bool H26xBitReader::UpdateCurrByte() {
46  if (bytes_left_ < 1)
47  return false;
48 
49  // Emulation prevention three-byte detection.
50  // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03).
51  if (*data_ == 0x03 && (prev_two_bytes_ & 0xffff) == 0) {
52  // Detected 0x000003, skip last byte.
53  ++data_;
54  --bytes_left_;
55  ++emulation_prevention_bytes_;
56  // Need another full three bytes before we can detect the sequence again.
57  prev_two_bytes_ = 0xffff;
58 
59  if (bytes_left_ < 1)
60  return false;
61  }
62 
63  // Load a new byte and advance pointers.
64  curr_byte_ = *data_++ & 0xff;
65  --bytes_left_;
66  num_remaining_bits_in_curr_byte_ = 8;
67 
68  prev_two_bytes_ = (prev_two_bytes_ << 8) | curr_byte_;
69 
70  return true;
71 }
72 
73 // Read |num_bits| (1 to 31 inclusive) from the stream and return them
74 // in |out|, with first bit in the stream as MSB in |out| at position
75 // (|num_bits| - 1).
76 bool H26xBitReader::ReadBits(int num_bits, int* out) {
77  int bits_left = num_bits;
78  *out = 0;
79  DCHECK(num_bits <= 31);
80 
81  while (num_remaining_bits_in_curr_byte_ < bits_left) {
82  // Take all that's left in current byte, shift to make space for the rest.
83  *out |= (curr_byte_ << (bits_left - num_remaining_bits_in_curr_byte_));
84  bits_left -= num_remaining_bits_in_curr_byte_;
85 
86  if (!UpdateCurrByte())
87  return false;
88  }
89 
90  *out |= (curr_byte_ >> (num_remaining_bits_in_curr_byte_ - bits_left));
91  *out &= ((1 << num_bits) - 1);
92  num_remaining_bits_in_curr_byte_ -= bits_left;
93 
94  return true;
95 }
96 
97 bool H26xBitReader::SkipBits(int num_bits) {
98  int bits_left = num_bits;
99  while (num_remaining_bits_in_curr_byte_ < bits_left) {
100  bits_left -= num_remaining_bits_in_curr_byte_;
101  if (!UpdateCurrByte())
102  return false;
103  }
104 
105  num_remaining_bits_in_curr_byte_ -= bits_left;
106  return true;
107 }
108 
109 bool H26xBitReader::ReadUE(int* val) {
110  int num_bits = -1;
111  int bit;
112  int rest;
113 
114  // Count the number of contiguous zero bits.
115  do {
116  if (!ReadBits(1, &bit))
117  return false;
118  num_bits++;
119  } while (bit == 0);
120 
121  if (num_bits > 31)
122  return false;
123 
124  // Calculate exp-Golomb code value of size num_bits.
125  *val = (1 << num_bits) - 1;
126 
127  if (num_bits > 0) {
128  if (!ReadBits(num_bits, &rest))
129  return false;
130  *val += rest;
131  }
132 
133  return true;
134 }
135 
136 bool H26xBitReader::ReadSE(int* val) {
137  int ue;
138 
139  // See Chapter 9 in the spec.
140  if (!ReadUE(&ue))
141  return false;
142 
143  if (ue % 2 == 0)
144  *val = -(ue / 2);
145  else
146  *val = ue / 2 + 1;
147 
148  return true;
149 }
150 
151 off_t H26xBitReader::NumBitsLeft() {
152  return (num_remaining_bits_in_curr_byte_ + bytes_left_ * 8);
153 }
154 
155 bool H26xBitReader::HasMoreRBSPData() {
156  // Make sure we have more bits, if we are at 0 bits in current byte and
157  // updating current byte fails, we don't have more data anyway.
158  if (num_remaining_bits_in_curr_byte_ == 0 && !UpdateCurrByte())
159  return false;
160 
161  // If there is no more RBSP data, then the remaining bits is the stop bit
162  // followed by zero paddings. So if there are 1s in the remaining bits
163  // excluding the current bit, then the current bit is not a stop bit,
164  // regardless of whether it is 1 or not. Therefore there is more data.
165  if (CheckAnyBitsSet(curr_byte_, num_remaining_bits_in_curr_byte_ - 1))
166  return true;
167 
168  // While the spec disallows it (7.4.1: "The last byte of the NAL unit shall
169  // not be equal to 0x00"), some streams have trailing null bytes anyway. We
170  // don't handle emulation prevention sequences because HasMoreRBSPData() is
171  // not used when parsing slices (where cabac_zero_word elements are legal).
172  for (off_t i = 0; i < bytes_left_; i++) {
173  if (data_[i] != 0)
174  return true;
175  }
176 
177  bytes_left_ = 0;
178  return false;
179 }
180 
181 size_t H26xBitReader::NumEmulationPreventionBytesRead() {
182  return emulation_prevention_bytes_;
183 }
184 
185 } // namespace media
186 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/base/logging.h"
+
6 #include "packager/media/codecs/h26x_bit_reader.h"
+
7 
+
8 namespace shaka {
+
9 namespace media {
+
10 namespace {
+
11 
+
12 // Check if any bits in the least significant |valid_bits| are set to 1.
+
13 bool CheckAnyBitsSet(int byte, int valid_bits) {
+
14  return (byte & ((1 << valid_bits) - 1)) != 0;
+
15 }
+
16 
+
17 } // namespace
+
18 
+
19 H26xBitReader::H26xBitReader()
+
20  : data_(NULL),
+
21  bytes_left_(0),
+
22  curr_byte_(0),
+
23  num_remaining_bits_in_curr_byte_(0),
+
24  prev_two_bytes_(0),
+
25  emulation_prevention_bytes_(0) {}
+
26 
+
27 H26xBitReader::~H26xBitReader() {}
+
28 
+
29 bool H26xBitReader::Initialize(const uint8_t* data, off_t size) {
+
30  DCHECK(data);
+
31 
+
32  if (size < 1)
+
33  return false;
+
34 
+
35  data_ = data;
+
36  bytes_left_ = size;
+
37  num_remaining_bits_in_curr_byte_ = 0;
+
38  // Initially set to 0xffff to accept all initial two-byte sequences.
+
39  prev_two_bytes_ = 0xffff;
+
40  emulation_prevention_bytes_ = 0;
+
41 
+
42  return true;
+
43 }
+
44 
+
45 bool H26xBitReader::UpdateCurrByte() {
+
46  if (bytes_left_ < 1)
+
47  return false;
+
48 
+
49  // Emulation prevention three-byte detection.
+
50  // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03).
+
51  if (*data_ == 0x03 && (prev_two_bytes_ & 0xffff) == 0) {
+
52  // Detected 0x000003, skip last byte.
+
53  ++data_;
+
54  --bytes_left_;
+
55  ++emulation_prevention_bytes_;
+
56  // Need another full three bytes before we can detect the sequence again.
+
57  prev_two_bytes_ = 0xffff;
+
58 
+
59  if (bytes_left_ < 1)
+
60  return false;
+
61  }
+
62 
+
63  // Load a new byte and advance pointers.
+
64  curr_byte_ = *data_++ & 0xff;
+
65  --bytes_left_;
+
66  num_remaining_bits_in_curr_byte_ = 8;
+
67 
+
68  prev_two_bytes_ = (prev_two_bytes_ << 8) | curr_byte_;
+
69 
+
70  return true;
+
71 }
+
72 
+
73 // Read |num_bits| (1 to 31 inclusive) from the stream and return them
+
74 // in |out|, with first bit in the stream as MSB in |out| at position
+
75 // (|num_bits| - 1).
+
76 bool H26xBitReader::ReadBits(int num_bits, int* out) {
+
77  int bits_left = num_bits;
+
78  *out = 0;
+
79  DCHECK(num_bits <= 31);
+
80 
+
81  while (num_remaining_bits_in_curr_byte_ < bits_left) {
+
82  // Take all that's left in current byte, shift to make space for the rest.
+
83  *out |= (curr_byte_ << (bits_left - num_remaining_bits_in_curr_byte_));
+
84  bits_left -= num_remaining_bits_in_curr_byte_;
+
85 
+
86  if (!UpdateCurrByte())
+
87  return false;
+
88  }
+
89 
+
90  *out |= (curr_byte_ >> (num_remaining_bits_in_curr_byte_ - bits_left));
+
91  *out &= ((1 << num_bits) - 1);
+
92  num_remaining_bits_in_curr_byte_ -= bits_left;
+
93 
+
94  return true;
+
95 }
+
96 
+
97 bool H26xBitReader::SkipBits(int num_bits) {
+
98  int bits_left = num_bits;
+
99  while (num_remaining_bits_in_curr_byte_ < bits_left) {
+
100  bits_left -= num_remaining_bits_in_curr_byte_;
+
101  if (!UpdateCurrByte())
+
102  return false;
+
103  }
+
104 
+
105  num_remaining_bits_in_curr_byte_ -= bits_left;
+
106  return true;
+
107 }
+
108 
+
109 bool H26xBitReader::ReadUE(int* val) {
+
110  int num_bits = -1;
+
111  int bit;
+
112  int rest;
+
113 
+
114  // Count the number of contiguous zero bits.
+
115  do {
+
116  if (!ReadBits(1, &bit))
+
117  return false;
+
118  num_bits++;
+
119  } while (bit == 0);
+
120 
+
121  if (num_bits > 31)
+
122  return false;
+
123 
+
124  // Calculate exp-Golomb code value of size num_bits.
+
125  *val = (1 << num_bits) - 1;
+
126 
+
127  if (num_bits > 0) {
+
128  if (!ReadBits(num_bits, &rest))
+
129  return false;
+
130  *val += rest;
+
131  }
+
132 
+
133  return true;
+
134 }
+
135 
+
136 bool H26xBitReader::ReadSE(int* val) {
+
137  int ue;
+
138 
+
139  // See Chapter 9 in the spec.
+
140  if (!ReadUE(&ue))
+
141  return false;
+
142 
+
143  if (ue % 2 == 0)
+
144  *val = -(ue / 2);
+
145  else
+
146  *val = ue / 2 + 1;
+
147 
+
148  return true;
+
149 }
+
150 
+
151 off_t H26xBitReader::NumBitsLeft() {
+
152  return (num_remaining_bits_in_curr_byte_ + bytes_left_ * 8);
+
153 }
+
154 
+
155 bool H26xBitReader::HasMoreRBSPData() {
+
156  // Make sure we have more bits, if we are at 0 bits in current byte and
+
157  // updating current byte fails, we don't have more data anyway.
+
158  if (num_remaining_bits_in_curr_byte_ == 0 && !UpdateCurrByte())
+
159  return false;
+
160 
+
161  // If there is no more RBSP data, then the remaining bits is the stop bit
+
162  // followed by zero paddings. So if there are 1s in the remaining bits
+
163  // excluding the current bit, then the current bit is not a stop bit,
+
164  // regardless of whether it is 1 or not. Therefore there is more data.
+
165  if (CheckAnyBitsSet(curr_byte_, num_remaining_bits_in_curr_byte_ - 1))
+
166  return true;
+
167 
+
168  // While the spec disallows it (7.4.1: "The last byte of the NAL unit shall
+
169  // not be equal to 0x00"), some streams have trailing null bytes anyway. We
+
170  // don't handle emulation prevention sequences because HasMoreRBSPData() is
+
171  // not used when parsing slices (where cabac_zero_word elements are legal).
+
172  for (off_t i = 0; i < bytes_left_; i++) {
+
173  if (data_[i] != 0)
+
174  return true;
+
175  }
+
176 
+
177  bytes_left_ = 0;
+
178  return false;
+
179 }
+
180 
+
181 size_t H26xBitReader::NumEmulationPreventionBytesRead() {
+
182  return emulation_prevention_bytes_;
+
183 }
+
184 
+
185 } // namespace media
+
186 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d6e/ts__section__pes_8cc_source.html b/docs/d6/d6e/ts__section__pes_8cc_source.html index eedda798cd..d430edb2a9 100644 --- a/docs/d6/d6e/ts__section__pes_8cc_source.html +++ b/docs/d6/d6e/ts__section__pes_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section_pes.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
ts_section_pes.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/mp2t/ts_section_pes.h"
6 
7 #include "packager/base/logging.h"
8 #include "packager/base/strings/string_number_conversions.h"
9 #include "packager/media/base/bit_reader.h"
10 #include "packager/media/base/timestamp.h"
11 #include "packager/media/formats/mp2t/es_parser.h"
12 #include "packager/media/formats/mp2t/mp2t_common.h"
13 
14 static const int kPesStartCode = 0x000001;
15 
16 // Given that |time| is coded using 33 bits,
17 // UnrollTimestamp returns the corresponding unrolled timestamp.
18 // The unrolled timestamp is defined by:
19 // |time| + k * (2 ^ 33)
20 // where k is estimated so that the unrolled timestamp
21 // is as close as possible to |previous_unrolled_time|.
22 static int64_t UnrollTimestamp(int64_t previous_unrolled_time, int64_t time) {
23  // Mpeg2 TS timestamps have an accuracy of 33 bits.
24  const int nbits = 33;
25 
26  // |timestamp| has a precision of |nbits|
27  // so make sure the highest bits are set to 0.
28  DCHECK_EQ((time >> nbits), 0);
29 
30  // Consider 3 possibilities to estimate the missing high bits of |time|.
31  int64_t previous_unrolled_time_high = (previous_unrolled_time >> nbits);
32  int64_t time0 = ((previous_unrolled_time_high - 1) << nbits) | time;
33  int64_t time1 = ((previous_unrolled_time_high + 0) << nbits) | time;
34  int64_t time2 = ((previous_unrolled_time_high + 1) << nbits) | time;
35 
36  // Select the min absolute difference with the current time
37  // so as to ensure time continuity.
38  int64_t diff0 = time0 - previous_unrolled_time;
39  int64_t diff1 = time1 - previous_unrolled_time;
40  int64_t diff2 = time2 - previous_unrolled_time;
41  if (diff0 < 0)
42  diff0 = -diff0;
43  if (diff1 < 0)
44  diff1 = -diff1;
45  if (diff2 < 0)
46  diff2 = -diff2;
47 
48  int64_t unrolled_time;
49  int64_t min_diff;
50  if (diff1 < diff0) {
51  unrolled_time = time1;
52  min_diff = diff1;
53  } else {
54  unrolled_time = time0;
55  min_diff = diff0;
56  }
57  if (diff2 < min_diff)
58  unrolled_time = time2;
59 
60  return unrolled_time;
61 }
62 
63 static bool IsTimestampSectionValid(int64_t timestamp_section) {
64  // |pts_section| has 40 bits:
65  // - starting with either '0010' or '0011' or '0001'
66  // - and ending with a marker bit.
67  // See ITU H.222 standard - PES section.
68 
69  // Verify that all the marker bits are set to one.
70  return ((timestamp_section & 0x1) != 0) &&
71  ((timestamp_section & 0x10000) != 0) &&
72  ((timestamp_section & 0x100000000LL) != 0);
73 }
74 
75 static int64_t ConvertTimestampSectionToTimestamp(int64_t timestamp_section) {
76  return (((timestamp_section >> 33) & 0x7) << 30) |
77  (((timestamp_section >> 17) & 0x7fff) << 15) |
78  (((timestamp_section >> 1) & 0x7fff) << 0);
79 }
80 
81 namespace shaka {
82 namespace media {
83 namespace mp2t {
84 
85 TsSectionPes::TsSectionPes(std::unique_ptr<EsParser> es_parser)
86  : es_parser_(es_parser.release()),
87  wait_for_pusi_(true),
88  previous_pts_valid_(false),
89  previous_pts_(0),
90  previous_dts_valid_(false),
91  previous_dts_(0) {
92  DCHECK(es_parser_);
93 }
94 
95 TsSectionPes::~TsSectionPes() {
96 }
97 
98 bool TsSectionPes::Parse(bool payload_unit_start_indicator,
99  const uint8_t* buf,
100  int size) {
101  // Ignore partial PES.
102  if (wait_for_pusi_ && !payload_unit_start_indicator)
103  return true;
104 
105  bool parse_result = true;
106  if (payload_unit_start_indicator) {
107  // Try emitting a packet since we might have a pending PES packet
108  // with an undefined size.
109  // In this case, a unit is emitted when the next unit is coming.
110  int raw_pes_size;
111  const uint8_t* raw_pes;
112  pes_byte_queue_.Peek(&raw_pes, &raw_pes_size);
113  if (raw_pes_size > 0)
114  parse_result = Emit(true);
115 
116  // Reset the state.
117  ResetPesState();
118 
119  // Update the state.
120  wait_for_pusi_ = false;
121  }
122 
123  // Add the data to the parser state.
124  if (size > 0)
125  pes_byte_queue_.Push(buf, size);
126 
127  // Try emitting the current PES packet.
128  return (parse_result && Emit(false));
129 }
130 
131 void TsSectionPes::Flush() {
132  // Try emitting a packet since we might have a pending PES packet
133  // with an undefined size.
134  Emit(true);
135 
136  // Flush the underlying ES parser.
137  es_parser_->Flush();
138 }
139 
140 void TsSectionPes::Reset() {
141  ResetPesState();
142 
143  previous_pts_valid_ = false;
144  previous_pts_ = 0;
145  previous_dts_valid_ = false;
146  previous_dts_ = 0;
147 
148  es_parser_->Reset();
149 }
150 
151 bool TsSectionPes::Emit(bool emit_for_unknown_size) {
152  int raw_pes_size;
153  const uint8_t* raw_pes;
154  pes_byte_queue_.Peek(&raw_pes, &raw_pes_size);
155 
156  // A PES should be at least 6 bytes.
157  // Wait for more data to come if not enough bytes.
158  if (raw_pes_size < 6)
159  return true;
160 
161  // Check whether we have enough data to start parsing.
162  int pes_packet_length =
163  (static_cast<int>(raw_pes[4]) << 8) |
164  (static_cast<int>(raw_pes[5]));
165  if ((pes_packet_length == 0 && !emit_for_unknown_size) ||
166  (pes_packet_length != 0 && raw_pes_size < pes_packet_length + 6)) {
167  // Wait for more data to come either because:
168  // - there are not enough bytes,
169  // - or the PES size is unknown and the "force emit" flag is not set.
170  // (PES size might be unknown for video PES packet).
171  return true;
172  }
173  DVLOG(LOG_LEVEL_PES) << "pes_packet_length=" << pes_packet_length;
174 
175  // Parse the packet.
176  bool parse_result = ParseInternal(raw_pes, raw_pes_size);
177 
178  // Reset the state.
179  ResetPesState();
180 
181  return parse_result;
182 }
183 
184 bool TsSectionPes::ParseInternal(const uint8_t* raw_pes, int raw_pes_size) {
185  BitReader bit_reader(raw_pes, raw_pes_size);
186 
187  // Read up to the pes_packet_length (6 bytes).
188  int packet_start_code_prefix;
189  int stream_id;
190  int pes_packet_length;
191  RCHECK(bit_reader.ReadBits(24, &packet_start_code_prefix));
192  RCHECK(bit_reader.ReadBits(8, &stream_id));
193  RCHECK(bit_reader.ReadBits(16, &pes_packet_length));
194 
195  RCHECK(packet_start_code_prefix == kPesStartCode);
196  DVLOG(LOG_LEVEL_PES) << "stream_id=" << std::hex << stream_id << std::dec;
197  if (pes_packet_length == 0)
198  pes_packet_length = static_cast<int>(bit_reader.bits_available()) / 8;
199 
200  // Ignore the PES for unknown stream IDs.
201  // ATSC Standard A/52:2012 3. GENERIC IDENTIFICATION OF AN AC-3 STREAM.
202  // AC3/E-AC3 stream uses private stream id.
203  const int kPrivateStream1 = 0xBD;
204  // See ITU H.222 Table 2-22 "Stream_id assignments"
205  bool is_audio_stream_id =
206  ((stream_id & 0xe0) == 0xc0) || stream_id == kPrivateStream1;
207  bool is_video_stream_id = ((stream_id & 0xf0) == 0xe0);
208  if (!is_audio_stream_id && !is_video_stream_id)
209  return true;
210 
211  // Read up to "pes_header_data_length".
212  int dummy_2;
213  int PES_scrambling_control;
214  int PES_priority;
215  int data_alignment_indicator;
216  int copyright;
217  int original_or_copy;
218  int pts_dts_flags;
219  int escr_flag;
220  int es_rate_flag;
221  int dsm_trick_mode_flag;
222  int additional_copy_info_flag;
223  int pes_crc_flag;
224  int pes_extension_flag;
225  int pes_header_data_length;
226  RCHECK(bit_reader.ReadBits(2, &dummy_2));
227  RCHECK(dummy_2 == 0x2);
228  RCHECK(bit_reader.ReadBits(2, &PES_scrambling_control));
229  RCHECK(bit_reader.ReadBits(1, &PES_priority));
230  RCHECK(bit_reader.ReadBits(1, &data_alignment_indicator));
231  RCHECK(bit_reader.ReadBits(1, &copyright));
232  RCHECK(bit_reader.ReadBits(1, &original_or_copy));
233  RCHECK(bit_reader.ReadBits(2, &pts_dts_flags));
234  RCHECK(bit_reader.ReadBits(1, &escr_flag));
235  RCHECK(bit_reader.ReadBits(1, &es_rate_flag));
236  RCHECK(bit_reader.ReadBits(1, &dsm_trick_mode_flag));
237  RCHECK(bit_reader.ReadBits(1, &additional_copy_info_flag));
238  RCHECK(bit_reader.ReadBits(1, &pes_crc_flag));
239  RCHECK(bit_reader.ReadBits(1, &pes_extension_flag));
240  RCHECK(bit_reader.ReadBits(8, &pes_header_data_length));
241  int pes_header_start_size = static_cast<int>(bit_reader.bits_available()) / 8;
242 
243  // Compute the size and the offset of the ES payload.
244  // "6" for the 6 bytes read before and including |pes_packet_length|.
245  // "3" for the 3 bytes read before and including |pes_header_data_length|.
246  int es_size = pes_packet_length - 3 - pes_header_data_length;
247  int es_offset = 6 + 3 + pes_header_data_length;
248  RCHECK(es_size >= 0);
249  RCHECK(es_offset + es_size <= raw_pes_size);
250 
251  // Read the timing information section.
252  bool is_pts_valid = false;
253  bool is_dts_valid = false;
254  int64_t pts_section = 0;
255  int64_t dts_section = 0;
256  if (pts_dts_flags == 0x2) {
257  RCHECK(bit_reader.ReadBits(40, &pts_section));
258  RCHECK((((pts_section >> 36) & 0xf) == 0x2) &&
259  IsTimestampSectionValid(pts_section));
260  is_pts_valid = true;
261  }
262  if (pts_dts_flags == 0x3) {
263  RCHECK(bit_reader.ReadBits(40, &pts_section));
264  RCHECK(bit_reader.ReadBits(40, &dts_section));
265  RCHECK((((pts_section >> 36) & 0xf) == 0x3) &&
266  IsTimestampSectionValid(pts_section));
267  RCHECK((((dts_section >> 36) & 0xf) == 0x1) &&
268  IsTimestampSectionValid(dts_section));
269  is_pts_valid = true;
270  is_dts_valid = true;
271  }
272 
273  // Convert and unroll the timestamps.
274  int64_t media_pts(kNoTimestamp);
275  int64_t media_dts(kNoTimestamp);
276  if (is_pts_valid) {
277  int64_t pts = ConvertTimestampSectionToTimestamp(pts_section);
278  if (previous_pts_valid_)
279  pts = UnrollTimestamp(previous_pts_, pts);
280  previous_pts_ = pts;
281  previous_pts_valid_ = true;
282  media_pts = pts;
283  }
284  if (is_dts_valid) {
285  int64_t dts = ConvertTimestampSectionToTimestamp(dts_section);
286  if (previous_dts_valid_)
287  dts = UnrollTimestamp(previous_dts_, dts);
288  previous_dts_ = dts;
289  previous_dts_valid_ = true;
290  media_dts = dts;
291  }
292 
293  // Discard the rest of the PES packet header.
294  DCHECK_EQ(bit_reader.bits_available() % 8, 0u);
295  int pes_header_remaining_size =
296  pes_header_data_length -
297  (pes_header_start_size -
298  static_cast<int>(bit_reader.bits_available()) / 8);
299  RCHECK(pes_header_remaining_size >= 0);
300 
301  // Read the PES packet.
302  DVLOG(LOG_LEVEL_PES)
303  << "Emit a reassembled PES:"
304  << " size=" << es_size
305  << " pts=" << media_pts
306  << " dts=" << media_dts
307  << " data_alignment_indicator=" << data_alignment_indicator;
308  return es_parser_->Parse(&raw_pes[es_offset], es_size, media_pts, media_dts);
309 }
310 
311 void TsSectionPes::ResetPesState() {
312  pes_byte_queue_.Reset();
313  wait_for_pusi_ = true;
314 }
315 
316 } // namespace mp2t
317 } // namespace media
318 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/mp2t/ts_section_pes.h"
+
6 
+
7 #include "packager/base/logging.h"
+
8 #include "packager/base/strings/string_number_conversions.h"
+
9 #include "packager/media/base/bit_reader.h"
+
10 #include "packager/media/base/timestamp.h"
+
11 #include "packager/media/formats/mp2t/es_parser.h"
+
12 #include "packager/media/formats/mp2t/mp2t_common.h"
+
13 
+
14 static const int kPesStartCode = 0x000001;
+
15 
+
16 // Given that |time| is coded using 33 bits,
+
17 // UnrollTimestamp returns the corresponding unrolled timestamp.
+
18 // The unrolled timestamp is defined by:
+
19 // |time| + k * (2 ^ 33)
+
20 // where k is estimated so that the unrolled timestamp
+
21 // is as close as possible to |previous_unrolled_time|.
+
22 static int64_t UnrollTimestamp(int64_t previous_unrolled_time, int64_t time) {
+
23  // Mpeg2 TS timestamps have an accuracy of 33 bits.
+
24  const int nbits = 33;
+
25 
+
26  // |timestamp| has a precision of |nbits|
+
27  // so make sure the highest bits are set to 0.
+
28  DCHECK_EQ((time >> nbits), 0);
+
29 
+
30  // Consider 3 possibilities to estimate the missing high bits of |time|.
+
31  int64_t previous_unrolled_time_high = (previous_unrolled_time >> nbits);
+
32  int64_t time0 = ((previous_unrolled_time_high - 1) << nbits) | time;
+
33  int64_t time1 = ((previous_unrolled_time_high + 0) << nbits) | time;
+
34  int64_t time2 = ((previous_unrolled_time_high + 1) << nbits) | time;
+
35 
+
36  // Select the min absolute difference with the current time
+
37  // so as to ensure time continuity.
+
38  int64_t diff0 = time0 - previous_unrolled_time;
+
39  int64_t diff1 = time1 - previous_unrolled_time;
+
40  int64_t diff2 = time2 - previous_unrolled_time;
+
41  if (diff0 < 0)
+
42  diff0 = -diff0;
+
43  if (diff1 < 0)
+
44  diff1 = -diff1;
+
45  if (diff2 < 0)
+
46  diff2 = -diff2;
+
47 
+
48  int64_t unrolled_time;
+
49  int64_t min_diff;
+
50  if (diff1 < diff0) {
+
51  unrolled_time = time1;
+
52  min_diff = diff1;
+
53  } else {
+
54  unrolled_time = time0;
+
55  min_diff = diff0;
+
56  }
+
57  if (diff2 < min_diff)
+
58  unrolled_time = time2;
+
59 
+
60  return unrolled_time;
+
61 }
+
62 
+
63 static bool IsTimestampSectionValid(int64_t timestamp_section) {
+
64  // |pts_section| has 40 bits:
+
65  // - starting with either '0010' or '0011' or '0001'
+
66  // - and ending with a marker bit.
+
67  // See ITU H.222 standard - PES section.
+
68 
+
69  // Verify that all the marker bits are set to one.
+
70  return ((timestamp_section & 0x1) != 0) &&
+
71  ((timestamp_section & 0x10000) != 0) &&
+
72  ((timestamp_section & 0x100000000LL) != 0);
+
73 }
+
74 
+
75 static int64_t ConvertTimestampSectionToTimestamp(int64_t timestamp_section) {
+
76  return (((timestamp_section >> 33) & 0x7) << 30) |
+
77  (((timestamp_section >> 17) & 0x7fff) << 15) |
+
78  (((timestamp_section >> 1) & 0x7fff) << 0);
+
79 }
+
80 
+
81 namespace shaka {
+
82 namespace media {
+
83 namespace mp2t {
+
84 
+
85 TsSectionPes::TsSectionPes(std::unique_ptr<EsParser> es_parser)
+
86  : es_parser_(es_parser.release()),
+
87  wait_for_pusi_(true),
+
88  previous_pts_valid_(false),
+
89  previous_pts_(0),
+
90  previous_dts_valid_(false),
+
91  previous_dts_(0) {
+
92  DCHECK(es_parser_);
+
93 }
+
94 
+
95 TsSectionPes::~TsSectionPes() {
+
96 }
+
97 
+
98 bool TsSectionPes::Parse(bool payload_unit_start_indicator,
+
99  const uint8_t* buf,
+
100  int size) {
+
101  // Ignore partial PES.
+
102  if (wait_for_pusi_ && !payload_unit_start_indicator)
+
103  return true;
+
104 
+
105  bool parse_result = true;
+
106  if (payload_unit_start_indicator) {
+
107  // Try emitting a packet since we might have a pending PES packet
+
108  // with an undefined size.
+
109  // In this case, a unit is emitted when the next unit is coming.
+
110  int raw_pes_size;
+
111  const uint8_t* raw_pes;
+
112  pes_byte_queue_.Peek(&raw_pes, &raw_pes_size);
+
113  if (raw_pes_size > 0)
+
114  parse_result = Emit(true);
+
115 
+
116  // Reset the state.
+
117  ResetPesState();
+
118 
+
119  // Update the state.
+
120  wait_for_pusi_ = false;
+
121  }
+
122 
+
123  // Add the data to the parser state.
+
124  if (size > 0)
+
125  pes_byte_queue_.Push(buf, size);
+
126 
+
127  // Try emitting the current PES packet.
+
128  return (parse_result && Emit(false));
+
129 }
+
130 
+
131 bool TsSectionPes::Flush() {
+
132  // Try emitting a packet since we might have a pending PES packet
+
133  // with an undefined size.
+
134  RCHECK(Emit(true));
+
135 
+
136  // Flush the underlying ES parser.
+
137  return es_parser_->Flush();
+
138 }
+
139 
+
140 void TsSectionPes::Reset() {
+
141  ResetPesState();
+
142 
+
143  previous_pts_valid_ = false;
+
144  previous_pts_ = 0;
+
145  previous_dts_valid_ = false;
+
146  previous_dts_ = 0;
+
147 
+
148  es_parser_->Reset();
+
149 }
+
150 
+
151 bool TsSectionPes::Emit(bool emit_for_unknown_size) {
+
152  int raw_pes_size;
+
153  const uint8_t* raw_pes;
+
154  pes_byte_queue_.Peek(&raw_pes, &raw_pes_size);
+
155 
+
156  // A PES should be at least 6 bytes.
+
157  // Wait for more data to come if not enough bytes.
+
158  if (raw_pes_size < 6)
+
159  return true;
+
160 
+
161  // Check whether we have enough data to start parsing.
+
162  int pes_packet_length =
+
163  (static_cast<int>(raw_pes[4]) << 8) |
+
164  (static_cast<int>(raw_pes[5]));
+
165  if ((pes_packet_length == 0 && !emit_for_unknown_size) ||
+
166  (pes_packet_length != 0 && raw_pes_size < pes_packet_length + 6)) {
+
167  // Wait for more data to come either because:
+
168  // - there are not enough bytes,
+
169  // - or the PES size is unknown and the "force emit" flag is not set.
+
170  // (PES size might be unknown for video PES packet).
+
171  return true;
+
172  }
+
173  DVLOG(LOG_LEVEL_PES) << "pes_packet_length=" << pes_packet_length;
+
174 
+
175  // Parse the packet.
+
176  bool parse_result = ParseInternal(raw_pes, raw_pes_size);
+
177 
+
178  // Reset the state.
+
179  ResetPesState();
+
180 
+
181  return parse_result;
+
182 }
+
183 
+
184 bool TsSectionPes::ParseInternal(const uint8_t* raw_pes, int raw_pes_size) {
+
185  BitReader bit_reader(raw_pes, raw_pes_size);
+
186 
+
187  // Read up to the pes_packet_length (6 bytes).
+
188  int packet_start_code_prefix;
+
189  int stream_id;
+
190  int pes_packet_length;
+
191  RCHECK(bit_reader.ReadBits(24, &packet_start_code_prefix));
+
192  RCHECK(bit_reader.ReadBits(8, &stream_id));
+
193  RCHECK(bit_reader.ReadBits(16, &pes_packet_length));
+
194 
+
195  RCHECK(packet_start_code_prefix == kPesStartCode);
+
196  DVLOG(LOG_LEVEL_PES) << "stream_id=" << std::hex << stream_id << std::dec;
+
197  if (pes_packet_length == 0)
+
198  pes_packet_length = static_cast<int>(bit_reader.bits_available()) / 8;
+
199 
+
200  // Ignore the PES for unknown stream IDs.
+
201  // ATSC Standard A/52:2012 3. GENERIC IDENTIFICATION OF AN AC-3 STREAM.
+
202  // AC3/E-AC3 stream uses private stream id.
+
203  const int kPrivateStream1 = 0xBD;
+
204  // See ITU H.222 Table 2-22 "Stream_id assignments"
+
205  bool is_audio_stream_id =
+
206  ((stream_id & 0xe0) == 0xc0) || stream_id == kPrivateStream1;
+
207  bool is_video_stream_id = ((stream_id & 0xf0) == 0xe0);
+
208  if (!is_audio_stream_id && !is_video_stream_id)
+
209  return true;
+
210 
+
211  // Read up to "pes_header_data_length".
+
212  int dummy_2;
+
213  int PES_scrambling_control;
+
214  int PES_priority;
+
215  int data_alignment_indicator;
+
216  int copyright;
+
217  int original_or_copy;
+
218  int pts_dts_flags;
+
219  int escr_flag;
+
220  int es_rate_flag;
+
221  int dsm_trick_mode_flag;
+
222  int additional_copy_info_flag;
+
223  int pes_crc_flag;
+
224  int pes_extension_flag;
+
225  int pes_header_data_length;
+
226  RCHECK(bit_reader.ReadBits(2, &dummy_2));
+
227  RCHECK(dummy_2 == 0x2);
+
228  RCHECK(bit_reader.ReadBits(2, &PES_scrambling_control));
+
229  RCHECK(bit_reader.ReadBits(1, &PES_priority));
+
230  RCHECK(bit_reader.ReadBits(1, &data_alignment_indicator));
+
231  RCHECK(bit_reader.ReadBits(1, &copyright));
+
232  RCHECK(bit_reader.ReadBits(1, &original_or_copy));
+
233  RCHECK(bit_reader.ReadBits(2, &pts_dts_flags));
+
234  RCHECK(bit_reader.ReadBits(1, &escr_flag));
+
235  RCHECK(bit_reader.ReadBits(1, &es_rate_flag));
+
236  RCHECK(bit_reader.ReadBits(1, &dsm_trick_mode_flag));
+
237  RCHECK(bit_reader.ReadBits(1, &additional_copy_info_flag));
+
238  RCHECK(bit_reader.ReadBits(1, &pes_crc_flag));
+
239  RCHECK(bit_reader.ReadBits(1, &pes_extension_flag));
+
240  RCHECK(bit_reader.ReadBits(8, &pes_header_data_length));
+
241  int pes_header_start_size = static_cast<int>(bit_reader.bits_available()) / 8;
+
242 
+
243  // Compute the size and the offset of the ES payload.
+
244  // "6" for the 6 bytes read before and including |pes_packet_length|.
+
245  // "3" for the 3 bytes read before and including |pes_header_data_length|.
+
246  int es_size = pes_packet_length - 3 - pes_header_data_length;
+
247  int es_offset = 6 + 3 + pes_header_data_length;
+
248  RCHECK(es_size >= 0);
+
249  RCHECK(es_offset + es_size <= raw_pes_size);
+
250 
+
251  // Read the timing information section.
+
252  bool is_pts_valid = false;
+
253  bool is_dts_valid = false;
+
254  int64_t pts_section = 0;
+
255  int64_t dts_section = 0;
+
256  if (pts_dts_flags == 0x2) {
+
257  RCHECK(bit_reader.ReadBits(40, &pts_section));
+
258  RCHECK((((pts_section >> 36) & 0xf) == 0x2) &&
+
259  IsTimestampSectionValid(pts_section));
+
260  is_pts_valid = true;
+
261  }
+
262  if (pts_dts_flags == 0x3) {
+
263  RCHECK(bit_reader.ReadBits(40, &pts_section));
+
264  RCHECK(bit_reader.ReadBits(40, &dts_section));
+
265  RCHECK((((pts_section >> 36) & 0xf) == 0x3) &&
+
266  IsTimestampSectionValid(pts_section));
+
267  RCHECK((((dts_section >> 36) & 0xf) == 0x1) &&
+
268  IsTimestampSectionValid(dts_section));
+
269  is_pts_valid = true;
+
270  is_dts_valid = true;
+
271  }
+
272 
+
273  // Convert and unroll the timestamps.
+
274  int64_t media_pts(kNoTimestamp);
+
275  int64_t media_dts(kNoTimestamp);
+
276  if (is_pts_valid) {
+
277  int64_t pts = ConvertTimestampSectionToTimestamp(pts_section);
+
278  if (previous_pts_valid_)
+
279  pts = UnrollTimestamp(previous_pts_, pts);
+
280  previous_pts_ = pts;
+
281  previous_pts_valid_ = true;
+
282  media_pts = pts;
+
283  }
+
284  if (is_dts_valid) {
+
285  int64_t dts = ConvertTimestampSectionToTimestamp(dts_section);
+
286  if (previous_dts_valid_)
+
287  dts = UnrollTimestamp(previous_dts_, dts);
+
288  previous_dts_ = dts;
+
289  previous_dts_valid_ = true;
+
290  media_dts = dts;
+
291  }
+
292 
+
293  // Discard the rest of the PES packet header.
+
294  DCHECK_EQ(bit_reader.bits_available() % 8, 0u);
+
295  int pes_header_remaining_size =
+
296  pes_header_data_length -
+
297  (pes_header_start_size -
+
298  static_cast<int>(bit_reader.bits_available()) / 8);
+
299  RCHECK(pes_header_remaining_size >= 0);
+
300 
+
301  // Read the PES packet.
+
302  DVLOG(LOG_LEVEL_PES)
+
303  << "Emit a reassembled PES:"
+
304  << " size=" << es_size
+
305  << " pts=" << media_pts
+
306  << " dts=" << media_dts
+
307  << " data_alignment_indicator=" << data_alignment_indicator;
+
308  return es_parser_->Parse(&raw_pes[es_offset], es_size, media_pts, media_dts);
+
309 }
+
310 
+
311 void TsSectionPes::ResetPesState() {
+
312  pes_byte_queue_.Reset();
+
313  wait_for_pusi_ = true;
+
314 }
+
315 
+
316 } // namespace mp2t
+
317 } // namespace media
+
318 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d71/scoped__xml__ptr_8h_source.html b/docs/d6/d71/scoped__xml__ptr_8h_source.html index 565eb74f4d..59953a56c5 100644 --- a/docs/d6/d71/scoped__xml__ptr_8h_source.html +++ b/docs/d6/d71/scoped__xml__ptr_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/xml/scoped_xml_ptr.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
scoped_xml_ptr.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // unique_ptr alias for libxml2 objects. Deleters for the objects are also
8 // defined in this file.
9 
10 #ifndef MPD_BASE_XML_SCOPED_XML_PTR_H_
11 #define MPD_BASE_XML_SCOPED_XML_PTR_H_
12 
13 #include <libxml/tree.h>
14 #include <libxml/xmlschemas.h>
15 
16 #include <memory>
17 
18 namespace shaka {
19 namespace xml {
20 
23 struct XmlDeleter {
24  // Called by std::unique_ptr.
25  inline void operator()(xmlSchemaParserCtxtPtr ptr) const {
26  xmlSchemaFreeParserCtxt(ptr);
27  }
28  inline void operator()(xmlSchemaValidCtxtPtr ptr) const {
29  xmlSchemaFreeValidCtxt(ptr);
30  }
31  inline void operator()(xmlSchemaPtr ptr) const { xmlSchemaFree(ptr); }
32  inline void operator()(xmlNodePtr ptr) const { xmlFreeNode(ptr); }
33  inline void operator()(xmlDocPtr ptr) const { xmlFreeDoc(ptr); }
34  inline void operator()(xmlChar* ptr) const { xmlFree(ptr); }
35 };
36 
37 template <typename XmlType>
38 using scoped_xml_ptr = std::unique_ptr<XmlType, XmlDeleter>;
39 
40 } // namespace xml
41 } // namespace shaka
42 
43 #endif // MPD_BASE_XML_SCOPED_XML_PTR_H_
-
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // unique_ptr alias for libxml2 objects. Deleters for the objects are also
+
8 // defined in this file.
+
9 
+
10 #ifndef MPD_BASE_XML_SCOPED_XML_PTR_H_
+
11 #define MPD_BASE_XML_SCOPED_XML_PTR_H_
+
12 
+
13 #include <libxml/tree.h>
+
14 #include <libxml/xmlschemas.h>
+
15 
+
16 #include <memory>
+
17 
+
18 namespace shaka {
+
19 namespace xml {
+
20 
+
23 struct XmlDeleter {
+
24  // Called by std::unique_ptr.
+
25  inline void operator()(xmlSchemaParserCtxtPtr ptr) const {
+
26  xmlSchemaFreeParserCtxt(ptr);
+
27  }
+
28  inline void operator()(xmlSchemaValidCtxtPtr ptr) const {
+
29  xmlSchemaFreeValidCtxt(ptr);
+
30  }
+
31  inline void operator()(xmlOutputBufferPtr ptr) const {
+
32  xmlOutputBufferClose(ptr);
+
33  }
+
34  inline void operator()(xmlSchemaPtr ptr) const { xmlSchemaFree(ptr); }
+
35  inline void operator()(xmlNodePtr ptr) const { xmlFreeNode(ptr); }
+
36  inline void operator()(xmlDocPtr ptr) const { xmlFreeDoc(ptr); }
+
37  inline void operator()(xmlChar* ptr) const { xmlFree(ptr); }
+
38 };
+
39 
+
40 template <typename XmlType>
+
41 using scoped_xml_ptr = std::unique_ptr<XmlType, XmlDeleter>;
+
42 
+
43 } // namespace xml
+
44 } // namespace shaka
+
45 
+
46 #endif // MPD_BASE_XML_SCOPED_XML_PTR_H_
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d6/d74/classshaka_1_1UdpOptions-members.html b/docs/d6/d74/classshaka_1_1UdpOptions-members.html index 5bd22413c5..cf96989135 100644 --- a/docs/d6/d74/classshaka_1_1UdpOptions-members.html +++ b/docs/d6/d74/classshaka_1_1UdpOptions-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/d79/structshaka_1_1media_1_1mp4_1_1VTTAdditionalTextBox.html b/docs/d6/d79/structshaka_1_1media_1_1mp4_1_1VTTAdditionalTextBox.html index 40c5461f55..961823d516 100644 --- a/docs/d6/d79/structshaka_1_1media_1_1mp4_1_1VTTAdditionalTextBox.html +++ b/docs/d6/d79/structshaka_1_1media_1_1mp4_1_1VTTAdditionalTextBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::VTTAdditionalTextBox Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 838 of file box_definitions.h.

+

Definition at line 856 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2827 of file box_definitions.cc.

+

Definition at line 2931 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d6/d7b/webm__tracks__parser_8h_source.html b/docs/d6/d7b/webm__tracks__parser_8h_source.html index 93d2c76a15..4942075075 100644 --- a/docs/d6/d7b/webm__tracks__parser_8h_source.html +++ b/docs/d6/d7b/webm__tracks__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_tracks_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webm_tracks_parser.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_TRACKS_PARSER_H_
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_TRACKS_PARSER_H_
7 
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <vector>
13 
14 #include "packager/base/time/time.h"
15 #include "packager/media/base/audio_stream_info.h"
16 #include "packager/media/base/text_track_config.h"
17 #include "packager/media/base/video_stream_info.h"
18 #include "packager/media/formats/webm/webm_audio_client.h"
19 #include "packager/media/formats/webm/webm_content_encodings_client.h"
20 #include "packager/media/formats/webm/webm_parser.h"
21 #include "packager/media/formats/webm/webm_video_client.h"
22 
23 namespace shaka {
24 namespace media {
25 
28  public:
29  explicit WebMTracksParser(bool ignore_text_tracks);
30  ~WebMTracksParser() override;
31 
36  int Parse(const uint8_t* buf, int size);
37 
38  int64_t audio_track_num() const { return audio_track_num_; }
39  int64_t video_track_num() const { return video_track_num_; }
40 
45  int64_t GetAudioDefaultDuration(const double timecode_scale_in_us) const;
46  int64_t GetVideoDefaultDuration(const double timecode_scale_in_us) const;
47 
48  const std::set<int64_t>& ignored_tracks() const { return ignored_tracks_; }
49 
50  const std::string& audio_encryption_key_id() const {
51  return audio_encryption_key_id_;
52  }
53 
54  std::shared_ptr<AudioStreamInfo> audio_stream_info() {
55  return audio_stream_info_;
56  }
57 
58  const std::string& video_encryption_key_id() const {
59  return video_encryption_key_id_;
60  }
61 
62  std::shared_ptr<VideoStreamInfo> video_stream_info() {
63  return video_stream_info_;
64  }
65 
66  typedef std::map<int, TextTrackConfig> TextTracks;
67 
68  const TextTracks& text_tracks() const {
69  return text_tracks_;
70  }
71 
72  const VPCodecConfigurationRecord& vp_config() const { return vp_config_; }
73 
74  private:
75  // WebMParserClient implementation.
76  WebMParserClient* OnListStart(int id) override;
77  bool OnListEnd(int id) override;
78  bool OnUInt(int id, int64_t val) override;
79  bool OnFloat(int id, double val) override;
80  bool OnBinary(int id, const uint8_t* data, int size) override;
81  bool OnString(int id, const std::string& str) override;
82 
83  int64_t track_type_;
84  int64_t track_num_;
85  std::string track_name_;
86  std::string track_language_;
87  std::string codec_id_;
88  std::vector<uint8_t> codec_private_;
89  int64_t seek_preroll_;
90  int64_t codec_delay_;
91  int64_t default_duration_;
92  std::unique_ptr<WebMContentEncodingsClient> track_content_encodings_client_;
93 
94  int64_t audio_track_num_;
95  int64_t audio_default_duration_;
96  int64_t video_track_num_;
97  int64_t video_default_duration_;
98  bool ignore_text_tracks_;
99  TextTracks text_tracks_;
100  std::set<int64_t> ignored_tracks_;
101  std::string audio_encryption_key_id_;
102  std::string video_encryption_key_id_;
103 
104  WebMAudioClient audio_client_;
105  std::shared_ptr<AudioStreamInfo> audio_stream_info_;
106 
107  WebMVideoClient video_client_;
108  VPCodecConfigurationRecord vp_config_;
109  std::shared_ptr<VideoStreamInfo> video_stream_info_;
110 
111  DISALLOW_COPY_AND_ASSIGN(WebMTracksParser);
112 };
113 
114 } // namespace media
115 } // namespace shaka
116 
117 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_TRACKS_PARSER_H_
Class for parsing or writing VP codec configuration record.
-
Parser for WebM Tracks element.
-
All the methods that are virtual are virtual for mocking.
-
Helper class used to parse a Video element inside a TrackEntry element.
-
int64_t GetAudioDefaultDuration(const double timecode_scale_in_us) const
-
int Parse(const uint8_t *buf, int size)
- -
Helper class used to parse an Audio element inside a TrackEntry element.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_TRACKS_PARSER_H_
+
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_TRACKS_PARSER_H_
+
7 
+
8 #include <map>
+
9 #include <memory>
+
10 #include <set>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/base/time/time.h"
+
15 #include "packager/media/base/audio_stream_info.h"
+
16 #include "packager/media/base/text_track_config.h"
+
17 #include "packager/media/base/video_stream_info.h"
+
18 #include "packager/media/formats/webm/webm_audio_client.h"
+
19 #include "packager/media/formats/webm/webm_content_encodings_client.h"
+
20 #include "packager/media/formats/webm/webm_parser.h"
+
21 #include "packager/media/formats/webm/webm_video_client.h"
+
22 
+
23 namespace shaka {
+
24 namespace media {
+
25 
+ +
28  public:
+
29  explicit WebMTracksParser(bool ignore_text_tracks);
+
30  ~WebMTracksParser() override;
+
31 
+
36  int Parse(const uint8_t* buf, int size);
+
37 
+
38  int64_t audio_track_num() const { return audio_track_num_; }
+
39  int64_t video_track_num() const { return video_track_num_; }
+
40 
+
45  int64_t GetAudioDefaultDuration(const double timecode_scale_in_us) const;
+
46  int64_t GetVideoDefaultDuration(const double timecode_scale_in_us) const;
+
47 
+
48  const std::set<int64_t>& ignored_tracks() const { return ignored_tracks_; }
+
49 
+
50  const std::string& audio_encryption_key_id() const {
+
51  return audio_encryption_key_id_;
+
52  }
+
53 
+
54  std::shared_ptr<AudioStreamInfo> audio_stream_info() {
+
55  return audio_stream_info_;
+
56  }
+
57 
+
58  const std::string& video_encryption_key_id() const {
+
59  return video_encryption_key_id_;
+
60  }
+
61 
+
62  std::shared_ptr<VideoStreamInfo> video_stream_info() {
+
63  return video_stream_info_;
+
64  }
+
65 
+
66  typedef std::map<int, TextTrackConfig> TextTracks;
+
67 
+
68  const TextTracks& text_tracks() const {
+
69  return text_tracks_;
+
70  }
+
71 
+
72  const VPCodecConfigurationRecord& vp_config() const { return vp_config_; }
+
73 
+
74  private:
+
75  // WebMParserClient implementation.
+
76  WebMParserClient* OnListStart(int id) override;
+
77  bool OnListEnd(int id) override;
+
78  bool OnUInt(int id, int64_t val) override;
+
79  bool OnFloat(int id, double val) override;
+
80  bool OnBinary(int id, const uint8_t* data, int size) override;
+
81  bool OnString(int id, const std::string& str) override;
+
82 
+
83  int64_t track_type_;
+
84  int64_t track_num_;
+
85  std::string track_name_;
+
86  std::string track_language_;
+
87  std::string codec_id_;
+
88  std::vector<uint8_t> codec_private_;
+
89  int64_t seek_preroll_;
+
90  int64_t codec_delay_;
+
91  int64_t default_duration_;
+
92  std::unique_ptr<WebMContentEncodingsClient> track_content_encodings_client_;
+
93 
+
94  int64_t audio_track_num_;
+
95  int64_t audio_default_duration_;
+
96  int64_t video_track_num_;
+
97  int64_t video_default_duration_;
+
98  bool ignore_text_tracks_;
+
99  TextTracks text_tracks_;
+
100  std::set<int64_t> ignored_tracks_;
+
101  std::string audio_encryption_key_id_;
+
102  std::string video_encryption_key_id_;
+
103 
+
104  WebMAudioClient audio_client_;
+
105  std::shared_ptr<AudioStreamInfo> audio_stream_info_;
+
106 
+
107  WebMVideoClient video_client_;
+
108  VPCodecConfigurationRecord vp_config_;
+
109  std::shared_ptr<VideoStreamInfo> video_stream_info_;
+
110 
+
111  DISALLOW_COPY_AND_ASSIGN(WebMTracksParser);
+
112 };
+
113 
+
114 } // namespace media
+
115 } // namespace shaka
+
116 
+
117 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_TRACKS_PARSER_H_
+
Class for parsing or writing VP codec configuration record.
+
Helper class used to parse an Audio element inside a TrackEntry element.
+ +
Parser for WebM Tracks element.
+
int64_t GetAudioDefaultDuration(const double timecode_scale_in_us) const
+
int Parse(const uint8_t *buf, int size)
+
Helper class used to parse a Video element inside a TrackEntry element.
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d7c/structshaka_1_1media_1_1mp4_1_1AC3Specific-members.html b/docs/d6/d7c/structshaka_1_1media_1_1mp4_1_1AC3Specific-members.html index 8e94efc976..3853722467 100644 --- a/docs/d6/d7c/structshaka_1_1media_1_1mp4_1_1AC3Specific-members.html +++ b/docs/d6/d7c/structshaka_1_1media_1_1mp4_1_1AC3Specific-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/d84/multi__codec__muxer__listener_8cc_source.html b/docs/d6/d84/multi__codec__muxer__listener_8cc_source.html new file mode 100644 index 0000000000..5826127088 --- /dev/null +++ b/docs/d6/d84/multi__codec__muxer__listener_8cc_source.html @@ -0,0 +1,126 @@ + + + + + + + +Shaka Packager SDK: packager/media/event/multi_codec_muxer_listener.cc Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
multi_codec_muxer_listener.cc
+
+
+
1 // Copyright 2019 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/event/multi_codec_muxer_listener.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/base/strings/string_split.h"
+
11 #include "packager/media/base/stream_info.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+ +
17  const StreamInfo& stream_info,
+
18  uint32_t time_scale,
+
19  ContainerType container_type) {
+
20  size_t num_codecs = 0;
+
21  for (const std::string& codec_string :
+
22  base::SplitString(stream_info.codec_string(), ";", base::KEEP_WHITESPACE,
+
23  base::SPLIT_WANT_NONEMPTY)) {
+
24  std::unique_ptr<StreamInfo> current_stream_info = stream_info.Clone();
+
25  current_stream_info->set_codec_string(codec_string);
+
26  MuxerListener* current_muxer_listener = MuxerListenerAt(num_codecs++);
+
27  if (!current_muxer_listener) {
+
28  LOG(WARNING) << "'" << codec_string << "' is not handled.";
+
29  continue;
+
30  }
+
31  current_muxer_listener->OnMediaStart(muxer_options, *current_stream_info,
+
32  time_scale, container_type);
+
33  }
+
34  // We only need |num_codecs| MuxerListeners.
+
35  LimitNumOfMuxerListners(num_codecs);
+
36 }
+
37 
+
38 } // namespace media
+
39 } // namespace shaka
+ +
MuxerListener * MuxerListenerAt(size_t index)
+
void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
+ +
virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
virtual std::unique_ptr< StreamInfo > Clone() const =0
+
All the methods that are virtual are virtual for mocking.
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+
+ + + + diff --git a/docs/d6/d86/bandwidth__estimator_8cc_source.html b/docs/d6/d86/bandwidth__estimator_8cc_source.html index 9dbc33104b..d366b525bb 100644 --- a/docs/d6/d86/bandwidth__estimator_8cc_source.html +++ b/docs/d6/d86/bandwidth__estimator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/bandwidth_estimator.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
bandwidth_estimator.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/mpd/base/bandwidth_estimator.h"
8 
9 #include <algorithm>
10 #include <cmath>
11 #include <numeric>
12 
13 #include "packager/base/logging.h"
14 
15 namespace shaka {
16 
17 BandwidthEstimator::BandwidthEstimator() = default;
18 
19 BandwidthEstimator::~BandwidthEstimator() = default;
20 
21 void BandwidthEstimator::AddBlock(uint64_t size_in_bytes, double duration) {
22  if (size_in_bytes == 0 || duration == 0) {
23  LOG(WARNING) << "Ignore block with size=" << size_in_bytes
24  << ", duration=" << duration;
25  return;
26  }
27 
28  const int kBitsInByte = 8;
29  const uint64_t size_in_bits = size_in_bytes * kBitsInByte;
30  total_size_in_bits_ += size_in_bits;
31  total_duration_ += duration;
32 
33  const size_t kTargetDurationThreshold = 10;
34  if (initial_blocks_.size() < kTargetDurationThreshold) {
35  initial_blocks_.push_back({size_in_bits, duration});
36  return;
37  }
38 
39  if (target_block_duration_ == 0) {
40  // Use the average duration as the target block duration. It will be used
41  // to filter small blocks from bandwidth calculation.
42  target_block_duration_ = GetAverageBlockDuration();
43  for (const Block& block : initial_blocks_) {
44  max_bitrate_ =
45  std::max(max_bitrate_, GetBitrate(block, target_block_duration_));
46  }
47  return;
48  }
49  max_bitrate_ = std::max(max_bitrate_, GetBitrate({size_in_bits, duration},
50  target_block_duration_));
51 }
52 
53 uint64_t BandwidthEstimator::Estimate() const {
54  if (total_duration_ == 0)
55  return 0;
56  return static_cast<uint64_t>(ceil(total_size_in_bits_ / total_duration_));
57 }
58 
59 uint64_t BandwidthEstimator::Max() const {
60  if (max_bitrate_ != 0)
61  return max_bitrate_;
62 
63  // We don't have the |target_block_duration_| yet. Calculate a target
64  // duration from the current available blocks.
65  DCHECK(target_block_duration_ == 0);
66  const double target_block_duration = GetAverageBlockDuration();
67 
68  // Calculate maximum bitrate with the target duration calculated above.
69  uint64_t max_bitrate = 0;
70  for (const Block& block : initial_blocks_) {
71  max_bitrate =
72  std::max(max_bitrate, GetBitrate(block, target_block_duration));
73  }
74  return max_bitrate;
75 }
76 
77 double BandwidthEstimator::GetAverageBlockDuration() const {
78  if (initial_blocks_.empty())
79  return 0.0;
80  const double sum =
81  std::accumulate(initial_blocks_.begin(), initial_blocks_.end(), 0.0,
82  [](double duration, const Block& block) {
83  return duration + block.duration;
84  });
85  return sum / initial_blocks_.size();
86 }
87 
88 uint64_t BandwidthEstimator::GetBitrate(const Block& block,
89  double target_block_duration) const {
90  if (block.duration < 0.5 * target_block_duration) {
91  // https://tools.ietf.org/html/rfc8216#section-4.1
92  // The peak segment bit rate of a Media Playlist is the largest bit rate of
93  // any continuous set of segments whose total duration is between 0.5
94  // and 1.5 times the target duration.
95  // Only the short segments are excluded here as our media playlist generator
96  // sets the target duration in the playlist to the largest segment duration.
97  // So although the segment duration could be 1.5 times the user provided
98  // segment duration, it will never be larger than the actual target
99  // duration.
100  //
101  // We also apply the same exclusion to the bandwidth computation for DASH as
102  // the bitrate for the short segment is not a good signal for peak
103  // bandwidth.
104  // See https://github.com/google/shaka-packager/issues/498 for details.
105  VLOG(1) << "Exclude short segment (duration " << block.duration
106  << ", target_duration " << target_block_duration
107  << ") in peak bandwidth computation.";
108  return 0.0;
109  }
110  return static_cast<uint64_t>(ceil(block.size_in_bits / block.duration));
111 }
112 
113 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
void AddBlock(uint64_t size_in_bytes, double duration)
- - +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/mpd/base/bandwidth_estimator.h"
+
8 
+
9 #include <algorithm>
+
10 #include <cmath>
+
11 #include <numeric>
+
12 
+
13 #include "packager/base/logging.h"
+
14 
+
15 namespace shaka {
+
16 
+
17 BandwidthEstimator::BandwidthEstimator() = default;
+
18 
+
19 BandwidthEstimator::~BandwidthEstimator() = default;
+
20 
+
21 void BandwidthEstimator::AddBlock(uint64_t size_in_bytes, double duration) {
+
22  if (size_in_bytes == 0 || duration == 0) {
+
23  LOG(WARNING) << "Ignore block with size=" << size_in_bytes
+
24  << ", duration=" << duration;
+
25  return;
+
26  }
+
27 
+
28  const int kBitsInByte = 8;
+
29  const uint64_t size_in_bits = size_in_bytes * kBitsInByte;
+
30  total_size_in_bits_ += size_in_bits;
+
31  total_duration_ += duration;
+
32 
+
33  const size_t kTargetDurationThreshold = 10;
+
34  if (initial_blocks_.size() < kTargetDurationThreshold) {
+
35  initial_blocks_.push_back({size_in_bits, duration});
+
36  return;
+
37  }
+
38 
+
39  if (target_block_duration_ == 0) {
+
40  // Use the average duration as the target block duration. It will be used
+
41  // to filter small blocks from bandwidth calculation.
+
42  target_block_duration_ = GetAverageBlockDuration();
+
43  for (const Block& block : initial_blocks_) {
+
44  max_bitrate_ =
+
45  std::max(max_bitrate_, GetBitrate(block, target_block_duration_));
+
46  }
+
47  return;
+
48  }
+
49  max_bitrate_ = std::max(max_bitrate_, GetBitrate({size_in_bits, duration},
+
50  target_block_duration_));
+
51 }
+
52 
+
53 uint64_t BandwidthEstimator::Estimate() const {
+
54  if (total_duration_ == 0)
+
55  return 0;
+
56  return static_cast<uint64_t>(ceil(total_size_in_bits_ / total_duration_));
+
57 }
+
58 
+
59 uint64_t BandwidthEstimator::Max() const {
+
60  if (max_bitrate_ != 0)
+
61  return max_bitrate_;
+
62 
+
63  // We don't have the |target_block_duration_| yet. Calculate a target
+
64  // duration from the current available blocks.
+
65  DCHECK(target_block_duration_ == 0);
+
66  const double target_block_duration = GetAverageBlockDuration();
+
67 
+
68  // Calculate maximum bitrate with the target duration calculated above.
+
69  uint64_t max_bitrate = 0;
+
70  for (const Block& block : initial_blocks_) {
+
71  max_bitrate =
+
72  std::max(max_bitrate, GetBitrate(block, target_block_duration));
+
73  }
+
74  return max_bitrate;
+
75 }
+
76 
+
77 double BandwidthEstimator::GetAverageBlockDuration() const {
+
78  if (initial_blocks_.empty())
+
79  return 0.0;
+
80  const double sum =
+
81  std::accumulate(initial_blocks_.begin(), initial_blocks_.end(), 0.0,
+
82  [](double duration, const Block& block) {
+
83  return duration + block.duration;
+
84  });
+
85  return sum / initial_blocks_.size();
+
86 }
+
87 
+
88 uint64_t BandwidthEstimator::GetBitrate(const Block& block,
+
89  double target_block_duration) const {
+
90  if (block.duration < 0.5 * target_block_duration) {
+
91  // https://tools.ietf.org/html/rfc8216#section-4.1
+
92  // The peak segment bit rate of a Media Playlist is the largest bit rate of
+
93  // any continuous set of segments whose total duration is between 0.5
+
94  // and 1.5 times the target duration.
+
95  // Only the short segments are excluded here as our media playlist generator
+
96  // sets the target duration in the playlist to the largest segment duration.
+
97  // So although the segment duration could be 1.5 times the user provided
+
98  // segment duration, it will never be larger than the actual target
+
99  // duration.
+
100  //
+
101  // We also apply the same exclusion to the bandwidth computation for DASH as
+
102  // the bitrate for the short segment is not a good signal for peak
+
103  // bandwidth.
+
104  // See https://github.com/google/shaka-packager/issues/498 for details.
+
105  VLOG(1) << "Exclude short segment (duration " << block.duration
+
106  << ", target_duration " << target_block_duration
+
107  << ") in peak bandwidth computation.";
+
108  return 0.0;
+
109  }
+
110  return static_cast<uint64_t>(ceil(block.size_in_bits / block.duration));
+
111 }
+
112 
+
113 } // namespace shaka
+ +
void AddBlock(uint64_t size_in_bytes, double duration)
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d8a/vp9__parser_8cc_source.html b/docs/d6/d8a/vp9__parser_8cc_source.html index d12b7fc3d6..13efbc1f6e 100644 --- a/docs/d6/d8a/vp9__parser_8cc_source.html +++ b/docs/d6/d8a/vp9__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/vp9_parser.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
vp9_parser.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/vp9_parser.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/base/rcheck.h"
12 
13 namespace shaka {
14 namespace media {
15 namespace {
16 
17 const uint32_t VP9_FRAME_MARKER = 2;
18 const uint32_t VP9_SYNC_CODE = 0x498342;
19 const uint32_t REFS_PER_FRAME = 3;
20 const uint32_t REF_FRAMES_LOG2 = 3;
21 const uint32_t REF_FRAMES = (1 << REF_FRAMES_LOG2);
22 const uint32_t FRAME_CONTEXTS_LOG2 = 2;
23 const uint32_t MAX_REF_LF_DELTAS = 4;
24 const uint32_t MAX_MODE_LF_DELTAS = 2;
25 const uint32_t QINDEX_BITS = 8;
26 const uint32_t MAX_SEGMENTS = 8;
27 const uint32_t SEG_TREE_PROBS = (MAX_SEGMENTS - 1);
28 const uint32_t PREDICTION_PROBS = 3;
29 const uint32_t SEG_LVL_MAX = 4;
30 const uint32_t MI_SIZE_LOG2 = 3;
31 const uint32_t MI_BLOCK_SIZE_LOG2 = (6 - MI_SIZE_LOG2); // 64 = 2^6
32 const uint32_t MIN_TILE_WIDTH_B64 = 4;
33 const uint32_t MAX_TILE_WIDTH_B64 = 64;
34 
35 const bool SEG_FEATURE_DATA_SIGNED[SEG_LVL_MAX] = {true, true, false, false};
36 const uint32_t SEG_FEATURE_DATA_MAX_BITS[SEG_LVL_MAX] = {8, 6, 2, 0};
37 
38 enum VpxColorSpace {
39  VPX_COLOR_SPACE_UNKNOWN = 0,
40  VPX_COLOR_SPACE_BT_601 = 1,
41  VPX_COLOR_SPACE_BT_709 = 2,
42  VPX_COLOR_SPACE_SMPTE_170 = 3,
43  VPX_COLOR_SPACE_SMPTE_240 = 4,
44  VPX_COLOR_SPACE_BT_2020 = 5,
45  VPX_COLOR_SPACE_RESERVED = 6,
46  VPX_COLOR_SPACE_SRGB = 7,
47 };
48 
49 uint32_t RoundupShift(uint32_t value, uint32_t n) {
50  return (value + (1 << n) - 1) >> n;
51 }
52 
53 // Number of MI-units (8*8).
54 uint32_t GetNumMiUnits(uint32_t pixels) {
55  return RoundupShift(pixels, MI_SIZE_LOG2);
56 }
57 
58 // Number of sb64 (64x64) blocks per mi_units.
59 uint32_t GetNumBlocks(uint32_t mi_units) {
60  return RoundupShift(mi_units, MI_BLOCK_SIZE_LOG2);
61 }
62 
63 uint32_t GetMinLog2TileCols(uint32_t sb64_cols) {
64  uint32_t min_log2 = 0;
65  while ((MAX_TILE_WIDTH_B64 << min_log2) < sb64_cols)
66  ++min_log2;
67  return min_log2;
68 }
69 
70 uint32_t GetMaxLog2TileCols(uint32_t sb64_cols) {
71  uint32_t max_log2 = 1;
72  while ((sb64_cols >> max_log2) >= MIN_TILE_WIDTH_B64)
73  ++max_log2;
74  return max_log2 - 1;
75 }
76 
77 void GetTileNBits(uint32_t mi_cols,
78  uint32_t* min_log2_tile_cols,
79  uint32_t* max_log2_tile_cols) {
80  const uint32_t sb64_cols = GetNumBlocks(mi_cols);
81  *min_log2_tile_cols = GetMinLog2TileCols(sb64_cols);
82  *max_log2_tile_cols = GetMaxLog2TileCols(sb64_cols);
83  CHECK_LE(*min_log2_tile_cols, *max_log2_tile_cols);
84 }
85 
86 // Parse superframe index if it is a superframe. Fill |vpx_frames| with the
87 // frames information, which contains the sizes of the frames indicated in
88 // superframe index if it is a superframe; otherwise it should contain one
89 // single frame with |data_size| as frame size.
90 bool ParseIfSuperframeIndex(const uint8_t* data,
91  size_t data_size,
92  std::vector<VPxFrameInfo>* vpx_frames) {
93  vpx_frames->clear();
94  uint8_t superframe_marker = data[data_size - 1];
95  VPxFrameInfo vpx_frame;
96  if ((superframe_marker & 0xe0) != 0xc0) {
97  // This is not a super frame. There should be only one frame.
98  vpx_frame.frame_size = data_size;
99  vpx_frames->push_back(vpx_frame);
100  return true;
101  }
102 
103  const size_t num_frames = (superframe_marker & 0x07) + 1;
104  const size_t frame_size_length = ((superframe_marker >> 3) & 0x03) + 1;
105  // Two maker bytes + frame sizes.
106  const size_t index_size = 2 + num_frames * frame_size_length;
107 
108  if (data_size < index_size) {
109  LOG(ERROR) << "This chunk is marked as having a superframe index but "
110  "doesn't have enough data for it.";
111  return false;
112  }
113  const uint8_t superframe_marker2 = data[data_size - index_size];
114  if (superframe_marker2 != superframe_marker) {
115  LOG(ERROR) << "This chunk is marked as having a superframe index but "
116  "doesn't have the matching marker byte at the front of the "
117  "index.";
118  return false;
119  }
120  VLOG(3) << "Superframe num_frames=" << num_frames
121  << " frame_size_length=" << frame_size_length;
122 
123  data += data_size - index_size + 1;
124  size_t total_frame_sizes = 0;
125  for (size_t i = 0; i < num_frames; ++i) {
126  vpx_frame.frame_size = 0;
127  for (size_t i = 0; i < frame_size_length; ++i) {
128  vpx_frame.frame_size |= *data << (i * 8);
129  ++data;
130  }
131  total_frame_sizes += vpx_frame.frame_size;
132  vpx_frames->push_back(vpx_frame);
133  }
134  if (total_frame_sizes + index_size != data_size) {
135  LOG(ERROR) << "Data size (" << data_size
136  << ") does not match with sum of frame sizes ("
137  << total_frame_sizes << ") + index_size (" << index_size << ")";
138  return false;
139  }
140  return true;
141 }
142 
143 bool ReadProfile(BitReader* reader, VPCodecConfigurationRecord* codec_config) {
144  uint8_t bit[2];
145  RCHECK(reader->ReadBits(1, &bit[0]));
146  RCHECK(reader->ReadBits(1, &bit[1]));
147  uint8_t profile = bit[0] | (bit[1] << 1);
148  if (profile == 3) {
149  bool reserved;
150  RCHECK(reader->ReadBits(1, &reserved));
151  RCHECK(!reserved);
152  }
153  codec_config->set_profile(profile);
154  return true;
155 }
156 
157 bool ReadSyncCode(BitReader* reader) {
158  uint32_t sync_code;
159  RCHECK(reader->ReadBits(24, &sync_code));
160  return sync_code == VP9_SYNC_CODE;
161 }
162 
163 void SetColorAttributes(uint8_t bit_depth,
164  uint8_t color_space,
165  VPCodecConfigurationRecord* codec_config) {
166  switch (color_space) {
167  case VPX_COLOR_SPACE_UNKNOWN:
168  codec_config->set_color_primaries(AVCOL_PRI_UNSPECIFIED);
169  codec_config->set_matrix_coefficients(AVCOL_SPC_UNSPECIFIED);
170  codec_config->set_transfer_characteristics(AVCOL_TRC_UNSPECIFIED);
171  break;
172  case VPX_COLOR_SPACE_BT_601:
173  // Don't know if it is 525 line or 625 line.
174  codec_config->set_color_primaries(AVCOL_PRI_UNSPECIFIED);
175  codec_config->set_matrix_coefficients(AVCOL_SPC_UNSPECIFIED);
176  codec_config->set_transfer_characteristics(AVCOL_TRC_SMPTE170M);
177  break;
178  case VPX_COLOR_SPACE_BT_709:
179  codec_config->set_color_primaries(AVCOL_PRI_BT709);
180  codec_config->set_matrix_coefficients(AVCOL_SPC_BT709);
181  codec_config->set_transfer_characteristics(AVCOL_TRC_BT709);
182  break;
183  case VPX_COLOR_SPACE_SMPTE_170:
184  codec_config->set_color_primaries(AVCOL_PRI_SMPTE170M);
185  codec_config->set_matrix_coefficients(AVCOL_SPC_SMPTE170M);
186  codec_config->set_transfer_characteristics(AVCOL_TRC_SMPTE170M);
187  break;
188  case VPX_COLOR_SPACE_SMPTE_240:
189  codec_config->set_color_primaries(AVCOL_PRI_SMPTE240M);
190  codec_config->set_matrix_coefficients(AVCOL_SPC_SMPTE240M);
191  codec_config->set_transfer_characteristics(AVCOL_TRC_SMPTE240M);
192  break;
193  case VPX_COLOR_SPACE_BT_2020:
194  codec_config->set_color_primaries(AVCOL_PRI_BT2020);
195  // VP9 does not specify if it is in the form of “constant luminance” or
196  // “non-constant luminance”. As such, application should rely on the
197  // signaling outside of VP9 bitstream. If there is no such signaling,
198  // application may assume non-constant luminance for BT.2020.
199  codec_config->set_matrix_coefficients(AVCOL_SPC_BT2020_NCL);
200  switch (bit_depth) {
201  case 10:
202  codec_config->set_transfer_characteristics(AVCOL_TRC_BT2020_10);
203  break;
204  case 12:
205  codec_config->set_transfer_characteristics(AVCOL_TRC_BT2020_12);
206  break;
207  default:
208  codec_config->set_transfer_characteristics(AVCOL_TRC_UNSPECIFIED);
209  break;
210  }
211  break;
212  case VPX_COLOR_SPACE_SRGB:
213  codec_config->set_color_primaries(AVCOL_PRI_UNSPECIFIED);
214  codec_config->set_matrix_coefficients(AVCOL_SPC_RGB);
215  codec_config->set_transfer_characteristics(AVCOL_TRC_UNSPECIFIED);
216  break;
217  default:
218  LOG(WARNING) << "Unknown color space: " << static_cast<int>(color_space);
219  codec_config->set_color_primaries(AVCOL_PRI_UNSPECIFIED);
220  codec_config->set_matrix_coefficients(AVCOL_SPC_UNSPECIFIED);
221  codec_config->set_transfer_characteristics(AVCOL_TRC_UNSPECIFIED);
222  break;
223  }
224 }
225 
226 VPCodecConfigurationRecord::ChromaSubsampling GetChromaSubsampling(
227  uint8_t subsampling) {
228  switch (subsampling) {
229  case 0:
230  return VPCodecConfigurationRecord::CHROMA_444;
231  case 1:
232  return VPCodecConfigurationRecord::CHROMA_440;
233  case 2:
234  return VPCodecConfigurationRecord::CHROMA_422;
235  case 3:
236  // VP9 assumes that chrome samples are collocated with luma samples if
237  // there is no explicit signaling outside of VP9 bitstream.
238  return VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA;
239  default:
240  LOG(WARNING) << "Unexpected chroma subsampling value: "
241  << static_cast<int>(subsampling);
242  return VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA;
243  }
244 }
245 
246 bool ReadBitDepthAndColorSpace(BitReader* reader,
247  VPCodecConfigurationRecord* codec_config) {
248  uint8_t bit_depth = 8;
249  if (codec_config->profile() >= 2) {
250  bool use_vpx_bits_12;
251  RCHECK(reader->ReadBits(1, &use_vpx_bits_12));
252  bit_depth = use_vpx_bits_12 ? 12 : 10;
253  }
254  codec_config->set_bit_depth(bit_depth);
255 
256  uint8_t color_space;
257  RCHECK(reader->ReadBits(3, &color_space));
258  SetColorAttributes(bit_depth, color_space, codec_config);
259 
260  bool yuv_full_range = false;
261  auto chroma_subsampling = VPCodecConfigurationRecord::CHROMA_444;
262  if (color_space != VPX_COLOR_SPACE_SRGB) {
263  RCHECK(reader->ReadBits(1, &yuv_full_range));
264 
265  if (codec_config->profile() & 1) {
266  uint8_t subsampling;
267  RCHECK(reader->ReadBits(2, &subsampling));
268  chroma_subsampling = GetChromaSubsampling(subsampling);
269  if (chroma_subsampling ==
270  VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA) {
271  LOG(ERROR) << "4:2:0 color not supported in profile "
272  << static_cast<int>(codec_config->profile());
273  return false;
274  }
275 
276  bool reserved;
277  RCHECK(reader->ReadBits(1, &reserved));
278  RCHECK(!reserved);
279  } else {
280  chroma_subsampling =
281  VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA;
282  }
283  } else {
284  // Assume 4:4:4 for colorspace SRGB.
285  chroma_subsampling = VPCodecConfigurationRecord::CHROMA_444;
286  if (codec_config->profile() & 1) {
287  bool reserved;
288  RCHECK(reader->ReadBits(1, &reserved));
289  RCHECK(!reserved);
290  } else {
291  LOG(ERROR) << "4:4:4 color not supported in profile 0 or 2.";
292  return false;
293  }
294  }
295  codec_config->set_video_full_range_flag(yuv_full_range);
296  codec_config->SetChromaSubsampling(chroma_subsampling);
297 
298  VLOG(3) << "\n profile " << static_cast<int>(codec_config->profile())
299  << "\n bit depth " << static_cast<int>(codec_config->bit_depth())
300  << "\n matrix coefficients "
301  << static_cast<int>(codec_config->matrix_coefficients())
302  << "\n full_range "
303  << static_cast<int>(codec_config->video_full_range_flag())
304  << "\n chroma subsampling "
305  << static_cast<int>(codec_config->chroma_subsampling());
306  return true;
307 }
308 
309 bool ReadFrameSize(BitReader* reader, uint32_t* width, uint32_t* height) {
310  RCHECK(reader->ReadBits(16, width));
311  *width += 1; // Off by 1.
312  RCHECK(reader->ReadBits(16, height));
313  *height += 1; // Off by 1.
314  return true;
315 }
316 
317 bool ReadDisplayFrameSize(BitReader* reader,
318  uint32_t* display_width,
319  uint32_t* display_height) {
320  bool has_display_size;
321  RCHECK(reader->ReadBits(1, &has_display_size));
322  if (has_display_size)
323  RCHECK(ReadFrameSize(reader, display_width, display_height));
324  return true;
325 }
326 
327 bool ReadFrameSizes(BitReader* reader, uint32_t* width, uint32_t* height) {
328  uint32_t new_width;
329  uint32_t new_height;
330  RCHECK(ReadFrameSize(reader, &new_width, &new_height));
331  if (new_width != *width) {
332  VLOG(1) << "Width updates from " << *width << " to " << new_width;
333  *width = new_width;
334  }
335  if (new_height != *height) {
336  VLOG(1) << "Height updates from " << *height << " to " << new_height;
337  *height = new_height;
338  }
339 
340  uint32_t display_width = *width;
341  uint32_t display_height = *height;
342  RCHECK(ReadDisplayFrameSize(reader, &display_width, &display_height));
343  return true;
344 }
345 
346 bool ReadFrameSizesWithRefs(BitReader* reader,
347  uint32_t* width,
348  uint32_t* height) {
349  bool found = false;
350  for (uint32_t i = 0; i < REFS_PER_FRAME; ++i) {
351  RCHECK(reader->ReadBits(1, &found));
352  if (found)
353  break;
354  }
355  if (!found) {
356  RCHECK(ReadFrameSizes(reader, width, height));
357  } else {
358  uint32_t display_width;
359  uint32_t display_height;
360  RCHECK(ReadDisplayFrameSize(reader, &display_width, &display_height));
361  }
362  return true;
363 }
364 
365 bool ReadLoopFilter(BitReader* reader) {
366  RCHECK(reader->SkipBits(9)); // filter_evel, sharness_level
367  bool mode_ref_delta_enabled;
368  RCHECK(reader->ReadBits(1, &mode_ref_delta_enabled));
369  if (!mode_ref_delta_enabled)
370  return true;
371  bool mode_ref_delta_update;
372  RCHECK(reader->ReadBits(1, &mode_ref_delta_update));
373  if (!mode_ref_delta_update)
374  return true;
375 
376  for (uint32_t i = 0; i < MAX_REF_LF_DELTAS + MAX_MODE_LF_DELTAS; ++i)
377  RCHECK(reader->SkipBitsConditional(true, 6 + 1));
378  return true;
379 }
380 
381 bool ReadQuantization(BitReader* reader) {
382  RCHECK(reader->SkipBits(QINDEX_BITS));
383  // Skip delta_q bits.
384  for (uint32_t i = 0; i < 3; ++i)
385  RCHECK(reader->SkipBitsConditional(true, 4 + 1));
386  return true;
387 }
388 
389 bool ReadSegmentation(BitReader* reader) {
390  bool enabled;
391  RCHECK(reader->ReadBits(1, &enabled));
392  if (!enabled)
393  return true;
394 
395  bool update_map;
396  RCHECK(reader->ReadBits(1, &update_map));
397  if (update_map) {
398  for (uint32_t i = 0; i < SEG_TREE_PROBS; ++i)
399  RCHECK(reader->SkipBitsConditional(true, 8));
400 
401  bool temporal_update;
402  RCHECK(reader->ReadBits(1, &temporal_update));
403  if (temporal_update) {
404  for (uint32_t j = 0; j < PREDICTION_PROBS; ++j)
405  RCHECK(reader->SkipBitsConditional(true, 8));
406  }
407  }
408 
409  bool update_data;
410  RCHECK(reader->ReadBits(1, &update_data));
411  if (update_data) {
412  RCHECK(reader->SkipBits(1)); // abs_delta
413  for (uint32_t i = 0; i < MAX_SEGMENTS; ++i) {
414  for (uint32_t j = 0; j < SEG_LVL_MAX; ++j) {
415  bool feature_enabled;
416  RCHECK(reader->ReadBits(1, &feature_enabled));
417  if (feature_enabled) {
418  RCHECK(reader->SkipBits(SEG_FEATURE_DATA_MAX_BITS[j]));
419  if (SEG_FEATURE_DATA_SIGNED[j])
420  RCHECK(reader->SkipBits(1)); // signness
421  }
422  }
423  }
424  }
425  return true;
426 }
427 
428 bool ReadTileInfo(uint32_t width, BitReader* reader) {
429  uint32_t mi_cols = GetNumMiUnits(width);
430 
431  uint32_t min_log2_tile_cols;
432  uint32_t max_log2_tile_cols;
433  GetTileNBits(mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
434  uint32_t max_ones = max_log2_tile_cols - min_log2_tile_cols;
435 
436  uint32_t log2_tile_cols = min_log2_tile_cols;
437  while (max_ones--) {
438  bool has_more;
439  RCHECK(reader->ReadBits(1, &has_more));
440  if (!has_more)
441  break;
442  ++log2_tile_cols;
443  }
444  RCHECK(log2_tile_cols <= 6);
445 
446  RCHECK(reader->SkipBitsConditional(true, 1)); // log2_tile_rows
447  return true;
448 }
449 
450 } // namespace
451 
452 VP9Parser::VP9Parser() : width_(0), height_(0) {}
453 VP9Parser::~VP9Parser() {}
454 
455 bool VP9Parser::Parse(const uint8_t* data,
456  size_t data_size,
457  std::vector<VPxFrameInfo>* vpx_frames) {
458  DCHECK(data);
459  DCHECK(vpx_frames);
460  RCHECK(ParseIfSuperframeIndex(data, data_size, vpx_frames));
461 
462  for (auto& vpx_frame : *vpx_frames) {
463  VLOG(4) << "process frame with size " << vpx_frame.frame_size;
464  BitReader reader(data, vpx_frame.frame_size);
465  uint8_t frame_marker;
466  RCHECK(reader.ReadBits(2, &frame_marker));
467  RCHECK(frame_marker == VP9_FRAME_MARKER);
468 
469  RCHECK(ReadProfile(&reader, writable_codec_config()));
470 
471  bool show_existing_frame;
472  RCHECK(reader.ReadBits(1, &show_existing_frame));
473  if (show_existing_frame) {
474  RCHECK(reader.SkipBits(3)); // ref_frame_index
475  // End of current frame data. There should be no more bytes available.
476  RCHECK(reader.bits_available() < 8);
477 
478  vpx_frame.is_keyframe = false;
479  vpx_frame.uncompressed_header_size = vpx_frame.frame_size;
480  vpx_frame.width = width_;
481  vpx_frame.height = height_;
482  continue;
483  }
484 
485  bool is_interframe;
486  RCHECK(reader.ReadBits(1, &is_interframe));
487  vpx_frame.is_keyframe = !is_interframe;
488 
489  bool show_frame;
490  RCHECK(reader.ReadBits(1, &show_frame));
491  bool error_resilient_mode;
492  RCHECK(reader.ReadBits(1, &error_resilient_mode));
493 
494  if (vpx_frame.is_keyframe) {
495  RCHECK(ReadSyncCode(&reader));
496  RCHECK(ReadBitDepthAndColorSpace(&reader, writable_codec_config()));
497  RCHECK(ReadFrameSizes(&reader, &width_, &height_));
498  } else {
499  bool intra_only = false;
500  if (!show_frame)
501  RCHECK(reader.ReadBits(1, &intra_only));
502  if (!error_resilient_mode)
503  RCHECK(reader.SkipBits(2)); // reset_frame_context
504 
505  if (intra_only) {
506  RCHECK(ReadSyncCode(&reader));
507  if (codec_config().profile() > 0) {
508  RCHECK(ReadBitDepthAndColorSpace(&reader, writable_codec_config()));
509  } else {
510  // NOTE: The intra-only frame header does not include the
511  // specification of either the color format or color sub-sampling in
512  // profile 0. VP9 specifies that the default color format should be
513  // YUV 4:2:0 in this case (normative).
514  writable_codec_config()->SetChromaSubsampling(
515  VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA);
516  writable_codec_config()->set_bit_depth(8);
517  }
518 
519  RCHECK(reader.SkipBits(REF_FRAMES)); // refresh_frame_flags
520  RCHECK(ReadFrameSizes(&reader, &width_, &height_));
521  } else {
522  RCHECK(reader.SkipBits(REF_FRAMES)); // refresh_frame_flags
523  RCHECK(reader.SkipBits(REFS_PER_FRAME * (REF_FRAMES_LOG2 + 1)));
524 
525  // TODO(kqyang): We may need to actually build the refs to extract the
526  // correct width and height for the current frame. The width will be
527  // used later in ReadTileInfo.
528  RCHECK(ReadFrameSizesWithRefs(&reader, &width_, &height_));
529 
530  RCHECK(reader.SkipBits(1)); // allow_high_precision_mv
531 
532  bool interp_filter;
533  RCHECK(reader.ReadBits(1, &interp_filter));
534  if (!interp_filter)
535  RCHECK(reader.SkipBits(2)); // more interp_filter
536  }
537  }
538 
539  if (!error_resilient_mode) {
540  RCHECK(reader.SkipBits(1)); // refresh_frame_context
541  RCHECK(reader.SkipBits(1)); // frame_parallel_decoding_mode
542  }
543  RCHECK(reader.SkipBits(FRAME_CONTEXTS_LOG2)); // frame_context_idx
544 
545  VLOG(4) << "bits read before ReadLoopFilter: " << reader.bit_position();
546  RCHECK(ReadLoopFilter(&reader));
547  RCHECK(ReadQuantization(&reader));
548  RCHECK(ReadSegmentation(&reader));
549  RCHECK(ReadTileInfo(width_, &reader));
550 
551  uint16_t header_size;
552  RCHECK(reader.ReadBits(16, &header_size));
553  vpx_frame.uncompressed_header_size =
554  vpx_frame.frame_size - reader.bits_available() / 8;
555  vpx_frame.width = width_;
556  vpx_frame.height = height_;
557 
558  VLOG(3) << "\n frame_size: " << vpx_frame.frame_size
559  << "\n uncompressed_header_size: "
560  << vpx_frame.uncompressed_header_size
561  << "\n bits read: " << reader.bit_position()
562  << "\n header_size: " << header_size;
563 
564  RCHECK(header_size > 0);
565  RCHECK(header_size * 8u <= reader.bits_available());
566 
567  data += vpx_frame.frame_size;
568  }
569  return true;
570 }
571 
572 bool VP9Parser::IsKeyframe(const uint8_t* data, size_t data_size) {
573  BitReader reader(data, data_size);
574  uint8_t frame_marker;
575  RCHECK(reader.ReadBits(2, &frame_marker));
576  RCHECK(frame_marker == VP9_FRAME_MARKER);
577 
579  RCHECK(ReadProfile(&reader, &codec_config));
580 
581  bool show_existing_frame;
582  RCHECK(reader.ReadBits(1, &show_existing_frame));
583  if (show_existing_frame)
584  return false;
585 
586  bool is_interframe;
587  RCHECK(reader.ReadBits(1, &is_interframe));
588  if (is_interframe)
589  return false;
590 
591  RCHECK(reader.SkipBits(2)); // show_frame, error_resilient_mode.
592 
593  RCHECK(ReadSyncCode(&reader));
594  return true;
595 }
596 
597 } // namespace media
598 } // namespace shaka
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:35
-
Class for parsing or writing VP codec configuration record.
-
static bool IsKeyframe(const uint8_t *data, size_t data_size)
Definition: vp9_parser.cc:572
-
A class to read bit streams.
Definition: bit_reader.h:17
-
bool Parse(const uint8_t *data, size_t data_size, std::vector< VPxFrameInfo > *vpx_frames) override
Definition: vp9_parser.cc:455
-
All the methods that are virtual are virtual for mocking.
-
size_t bit_position() const
Definition: bit_reader.h:94
-
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
-
const VPCodecConfigurationRecord & codec_config() const
Definition: vpx_parser.h:44
-
size_t bits_available() const
Definition: bit_reader.h:89
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/vp9_parser.h"
+
8 
+
9 #include "packager/base/logging.h"
+
10 #include "packager/media/base/bit_reader.h"
+
11 #include "packager/media/base/rcheck.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 namespace {
+
16 
+
17 const uint32_t VP9_FRAME_MARKER = 2;
+
18 const uint32_t VP9_SYNC_CODE = 0x498342;
+
19 const uint32_t REFS_PER_FRAME = 3;
+
20 const uint32_t REF_FRAMES_LOG2 = 3;
+
21 const uint32_t REF_FRAMES = (1 << REF_FRAMES_LOG2);
+
22 const uint32_t FRAME_CONTEXTS_LOG2 = 2;
+
23 const uint32_t MAX_REF_LF_DELTAS = 4;
+
24 const uint32_t MAX_MODE_LF_DELTAS = 2;
+
25 const uint32_t QINDEX_BITS = 8;
+
26 const uint32_t MAX_SEGMENTS = 8;
+
27 const uint32_t SEG_TREE_PROBS = (MAX_SEGMENTS - 1);
+
28 const uint32_t PREDICTION_PROBS = 3;
+
29 const uint32_t SEG_LVL_MAX = 4;
+
30 const uint32_t MI_SIZE_LOG2 = 3;
+
31 const uint32_t MI_BLOCK_SIZE_LOG2 = (6 - MI_SIZE_LOG2); // 64 = 2^6
+
32 const uint32_t MIN_TILE_WIDTH_B64 = 4;
+
33 const uint32_t MAX_TILE_WIDTH_B64 = 64;
+
34 
+
35 const bool SEG_FEATURE_DATA_SIGNED[SEG_LVL_MAX] = {true, true, false, false};
+
36 const uint32_t SEG_FEATURE_DATA_MAX_BITS[SEG_LVL_MAX] = {8, 6, 2, 0};
+
37 
+
38 enum VpxColorSpace {
+
39  VPX_COLOR_SPACE_UNKNOWN = 0,
+
40  VPX_COLOR_SPACE_BT_601 = 1,
+
41  VPX_COLOR_SPACE_BT_709 = 2,
+
42  VPX_COLOR_SPACE_SMPTE_170 = 3,
+
43  VPX_COLOR_SPACE_SMPTE_240 = 4,
+
44  VPX_COLOR_SPACE_BT_2020 = 5,
+
45  VPX_COLOR_SPACE_RESERVED = 6,
+
46  VPX_COLOR_SPACE_SRGB = 7,
+
47 };
+
48 
+
49 uint32_t RoundupShift(uint32_t value, uint32_t n) {
+
50  return (value + (1 << n) - 1) >> n;
+
51 }
+
52 
+
53 // Number of MI-units (8*8).
+
54 uint32_t GetNumMiUnits(uint32_t pixels) {
+
55  return RoundupShift(pixels, MI_SIZE_LOG2);
+
56 }
+
57 
+
58 // Number of sb64 (64x64) blocks per mi_units.
+
59 uint32_t GetNumBlocks(uint32_t mi_units) {
+
60  return RoundupShift(mi_units, MI_BLOCK_SIZE_LOG2);
+
61 }
+
62 
+
63 uint32_t GetMinLog2TileCols(uint32_t sb64_cols) {
+
64  uint32_t min_log2 = 0;
+
65  while ((MAX_TILE_WIDTH_B64 << min_log2) < sb64_cols)
+
66  ++min_log2;
+
67  return min_log2;
+
68 }
+
69 
+
70 uint32_t GetMaxLog2TileCols(uint32_t sb64_cols) {
+
71  uint32_t max_log2 = 1;
+
72  while ((sb64_cols >> max_log2) >= MIN_TILE_WIDTH_B64)
+
73  ++max_log2;
+
74  return max_log2 - 1;
+
75 }
+
76 
+
77 void GetTileNBits(uint32_t mi_cols,
+
78  uint32_t* min_log2_tile_cols,
+
79  uint32_t* max_log2_tile_cols) {
+
80  const uint32_t sb64_cols = GetNumBlocks(mi_cols);
+
81  *min_log2_tile_cols = GetMinLog2TileCols(sb64_cols);
+
82  *max_log2_tile_cols = GetMaxLog2TileCols(sb64_cols);
+
83  CHECK_LE(*min_log2_tile_cols, *max_log2_tile_cols);
+
84 }
+
85 
+
86 // Parse superframe index if it is a superframe. Fill |vpx_frames| with the
+
87 // frames information, which contains the sizes of the frames indicated in
+
88 // superframe index if it is a superframe; otherwise it should contain one
+
89 // single frame with |data_size| as frame size.
+
90 bool ParseIfSuperframeIndex(const uint8_t* data,
+
91  size_t data_size,
+
92  std::vector<VPxFrameInfo>* vpx_frames) {
+
93  vpx_frames->clear();
+
94  uint8_t superframe_marker = data[data_size - 1];
+
95  VPxFrameInfo vpx_frame;
+
96  if ((superframe_marker & 0xe0) != 0xc0) {
+
97  // This is not a super frame. There should be only one frame.
+
98  vpx_frame.frame_size = data_size;
+
99  vpx_frames->push_back(vpx_frame);
+
100  return true;
+
101  }
+
102 
+
103  const size_t num_frames = (superframe_marker & 0x07) + 1;
+
104  const size_t frame_size_length = ((superframe_marker >> 3) & 0x03) + 1;
+
105  // Two maker bytes + frame sizes.
+
106  const size_t index_size = 2 + num_frames * frame_size_length;
+
107 
+
108  if (data_size < index_size) {
+
109  LOG(ERROR) << "This chunk is marked as having a superframe index but "
+
110  "doesn't have enough data for it.";
+
111  return false;
+
112  }
+
113  const uint8_t superframe_marker2 = data[data_size - index_size];
+
114  if (superframe_marker2 != superframe_marker) {
+
115  LOG(ERROR) << "This chunk is marked as having a superframe index but "
+
116  "doesn't have the matching marker byte at the front of the "
+
117  "index.";
+
118  return false;
+
119  }
+
120  VLOG(3) << "Superframe num_frames=" << num_frames
+
121  << " frame_size_length=" << frame_size_length;
+
122 
+
123  data += data_size - index_size + 1;
+
124  size_t total_frame_sizes = 0;
+
125  for (size_t i = 0; i < num_frames; ++i) {
+
126  vpx_frame.frame_size = 0;
+
127  for (size_t i = 0; i < frame_size_length; ++i) {
+
128  vpx_frame.frame_size |= *data << (i * 8);
+
129  ++data;
+
130  }
+
131  total_frame_sizes += vpx_frame.frame_size;
+
132  vpx_frames->push_back(vpx_frame);
+
133  }
+
134  if (total_frame_sizes + index_size != data_size) {
+
135  LOG(ERROR) << "Data size (" << data_size
+
136  << ") does not match with sum of frame sizes ("
+
137  << total_frame_sizes << ") + index_size (" << index_size << ")";
+
138  return false;
+
139  }
+
140  return true;
+
141 }
+
142 
+
143 bool ReadProfile(BitReader* reader, VPCodecConfigurationRecord* codec_config) {
+
144  uint8_t bit[2];
+
145  RCHECK(reader->ReadBits(1, &bit[0]));
+
146  RCHECK(reader->ReadBits(1, &bit[1]));
+
147  uint8_t profile = bit[0] | (bit[1] << 1);
+
148  if (profile == 3) {
+
149  bool reserved;
+
150  RCHECK(reader->ReadBits(1, &reserved));
+
151  RCHECK(!reserved);
+
152  }
+
153  codec_config->set_profile(profile);
+
154  return true;
+
155 }
+
156 
+
157 bool ReadSyncCode(BitReader* reader) {
+
158  uint32_t sync_code;
+
159  RCHECK(reader->ReadBits(24, &sync_code));
+
160  return sync_code == VP9_SYNC_CODE;
+
161 }
+
162 
+
163 void SetColorAttributes(uint8_t bit_depth,
+
164  uint8_t color_space,
+
165  VPCodecConfigurationRecord* codec_config) {
+
166  switch (color_space) {
+
167  case VPX_COLOR_SPACE_UNKNOWN:
+
168  codec_config->set_color_primaries(AVCOL_PRI_UNSPECIFIED);
+
169  codec_config->set_matrix_coefficients(AVCOL_SPC_UNSPECIFIED);
+
170  codec_config->set_transfer_characteristics(AVCOL_TRC_UNSPECIFIED);
+
171  break;
+
172  case VPX_COLOR_SPACE_BT_601:
+
173  // Don't know if it is 525 line or 625 line.
+
174  codec_config->set_color_primaries(AVCOL_PRI_UNSPECIFIED);
+
175  codec_config->set_matrix_coefficients(AVCOL_SPC_UNSPECIFIED);
+
176  codec_config->set_transfer_characteristics(AVCOL_TRC_SMPTE170M);
+
177  break;
+
178  case VPX_COLOR_SPACE_BT_709:
+
179  codec_config->set_color_primaries(AVCOL_PRI_BT709);
+
180  codec_config->set_matrix_coefficients(AVCOL_SPC_BT709);
+
181  codec_config->set_transfer_characteristics(AVCOL_TRC_BT709);
+
182  break;
+
183  case VPX_COLOR_SPACE_SMPTE_170:
+
184  codec_config->set_color_primaries(AVCOL_PRI_SMPTE170M);
+
185  codec_config->set_matrix_coefficients(AVCOL_SPC_SMPTE170M);
+
186  codec_config->set_transfer_characteristics(AVCOL_TRC_SMPTE170M);
+
187  break;
+
188  case VPX_COLOR_SPACE_SMPTE_240:
+
189  codec_config->set_color_primaries(AVCOL_PRI_SMPTE240M);
+
190  codec_config->set_matrix_coefficients(AVCOL_SPC_SMPTE240M);
+
191  codec_config->set_transfer_characteristics(AVCOL_TRC_SMPTE240M);
+
192  break;
+
193  case VPX_COLOR_SPACE_BT_2020:
+
194  codec_config->set_color_primaries(AVCOL_PRI_BT2020);
+
195  // VP9 does not specify if it is in the form of “constant luminance” or
+
196  // “non-constant luminance”. As such, application should rely on the
+
197  // signaling outside of VP9 bitstream. If there is no such signaling,
+
198  // application may assume non-constant luminance for BT.2020.
+
199  codec_config->set_matrix_coefficients(AVCOL_SPC_BT2020_NCL);
+
200  switch (bit_depth) {
+
201  case 10:
+
202  codec_config->set_transfer_characteristics(AVCOL_TRC_BT2020_10);
+
203  break;
+
204  case 12:
+
205  codec_config->set_transfer_characteristics(AVCOL_TRC_BT2020_12);
+
206  break;
+
207  default:
+
208  codec_config->set_transfer_characteristics(AVCOL_TRC_UNSPECIFIED);
+
209  break;
+
210  }
+
211  break;
+
212  case VPX_COLOR_SPACE_SRGB:
+
213  codec_config->set_color_primaries(AVCOL_PRI_UNSPECIFIED);
+
214  codec_config->set_matrix_coefficients(AVCOL_SPC_RGB);
+
215  codec_config->set_transfer_characteristics(AVCOL_TRC_UNSPECIFIED);
+
216  break;
+
217  default:
+
218  LOG(WARNING) << "Unknown color space: " << static_cast<int>(color_space);
+
219  codec_config->set_color_primaries(AVCOL_PRI_UNSPECIFIED);
+
220  codec_config->set_matrix_coefficients(AVCOL_SPC_UNSPECIFIED);
+
221  codec_config->set_transfer_characteristics(AVCOL_TRC_UNSPECIFIED);
+
222  break;
+
223  }
+
224 }
+
225 
+
226 VPCodecConfigurationRecord::ChromaSubsampling GetChromaSubsampling(
+
227  uint8_t subsampling) {
+
228  switch (subsampling) {
+
229  case 0:
+
230  return VPCodecConfigurationRecord::CHROMA_444;
+
231  case 1:
+
232  return VPCodecConfigurationRecord::CHROMA_440;
+
233  case 2:
+
234  return VPCodecConfigurationRecord::CHROMA_422;
+
235  case 3:
+
236  // VP9 assumes that chrome samples are collocated with luma samples if
+
237  // there is no explicit signaling outside of VP9 bitstream.
+
238  return VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA;
+
239  default:
+
240  LOG(WARNING) << "Unexpected chroma subsampling value: "
+
241  << static_cast<int>(subsampling);
+
242  return VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA;
+
243  }
+
244 }
+
245 
+
246 bool ReadBitDepthAndColorSpace(BitReader* reader,
+
247  VPCodecConfigurationRecord* codec_config) {
+
248  uint8_t bit_depth = 8;
+
249  if (codec_config->profile() >= 2) {
+
250  bool use_vpx_bits_12;
+
251  RCHECK(reader->ReadBits(1, &use_vpx_bits_12));
+
252  bit_depth = use_vpx_bits_12 ? 12 : 10;
+
253  }
+
254  codec_config->set_bit_depth(bit_depth);
+
255 
+
256  uint8_t color_space;
+
257  RCHECK(reader->ReadBits(3, &color_space));
+
258  SetColorAttributes(bit_depth, color_space, codec_config);
+
259 
+
260  bool yuv_full_range = false;
+
261  auto chroma_subsampling = VPCodecConfigurationRecord::CHROMA_444;
+
262  if (color_space != VPX_COLOR_SPACE_SRGB) {
+
263  RCHECK(reader->ReadBits(1, &yuv_full_range));
+
264 
+
265  if (codec_config->profile() & 1) {
+
266  uint8_t subsampling;
+
267  RCHECK(reader->ReadBits(2, &subsampling));
+
268  chroma_subsampling = GetChromaSubsampling(subsampling);
+
269  if (chroma_subsampling ==
+
270  VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA) {
+
271  LOG(ERROR) << "4:2:0 color not supported in profile "
+
272  << static_cast<int>(codec_config->profile());
+
273  return false;
+
274  }
+
275 
+
276  bool reserved;
+
277  RCHECK(reader->ReadBits(1, &reserved));
+
278  RCHECK(!reserved);
+
279  } else {
+
280  chroma_subsampling =
+
281  VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA;
+
282  }
+
283  } else {
+
284  // Assume 4:4:4 for colorspace SRGB.
+
285  chroma_subsampling = VPCodecConfigurationRecord::CHROMA_444;
+
286  if (codec_config->profile() & 1) {
+
287  bool reserved;
+
288  RCHECK(reader->ReadBits(1, &reserved));
+
289  RCHECK(!reserved);
+
290  } else {
+
291  LOG(ERROR) << "4:4:4 color not supported in profile 0 or 2.";
+
292  return false;
+
293  }
+
294  }
+
295  codec_config->set_video_full_range_flag(yuv_full_range);
+
296  codec_config->SetChromaSubsampling(chroma_subsampling);
+
297 
+
298  VLOG(3) << "\n profile " << static_cast<int>(codec_config->profile())
+
299  << "\n bit depth " << static_cast<int>(codec_config->bit_depth())
+
300  << "\n matrix coefficients "
+
301  << static_cast<int>(codec_config->matrix_coefficients())
+
302  << "\n full_range "
+
303  << static_cast<int>(codec_config->video_full_range_flag())
+
304  << "\n chroma subsampling "
+
305  << static_cast<int>(codec_config->chroma_subsampling());
+
306  return true;
+
307 }
+
308 
+
309 bool ReadFrameSize(BitReader* reader, uint32_t* width, uint32_t* height) {
+
310  RCHECK(reader->ReadBits(16, width));
+
311  *width += 1; // Off by 1.
+
312  RCHECK(reader->ReadBits(16, height));
+
313  *height += 1; // Off by 1.
+
314  return true;
+
315 }
+
316 
+
317 bool ReadDisplayFrameSize(BitReader* reader,
+
318  uint32_t* display_width,
+
319  uint32_t* display_height) {
+
320  bool has_display_size;
+
321  RCHECK(reader->ReadBits(1, &has_display_size));
+
322  if (has_display_size)
+
323  RCHECK(ReadFrameSize(reader, display_width, display_height));
+
324  return true;
+
325 }
+
326 
+
327 bool ReadFrameSizes(BitReader* reader, uint32_t* width, uint32_t* height) {
+
328  uint32_t new_width;
+
329  uint32_t new_height;
+
330  RCHECK(ReadFrameSize(reader, &new_width, &new_height));
+
331  if (new_width != *width) {
+
332  VLOG(1) << "Width updates from " << *width << " to " << new_width;
+
333  *width = new_width;
+
334  }
+
335  if (new_height != *height) {
+
336  VLOG(1) << "Height updates from " << *height << " to " << new_height;
+
337  *height = new_height;
+
338  }
+
339 
+
340  uint32_t display_width = *width;
+
341  uint32_t display_height = *height;
+
342  RCHECK(ReadDisplayFrameSize(reader, &display_width, &display_height));
+
343  return true;
+
344 }
+
345 
+
346 bool ReadFrameSizesWithRefs(BitReader* reader,
+
347  uint32_t* width,
+
348  uint32_t* height) {
+
349  bool found = false;
+
350  for (uint32_t i = 0; i < REFS_PER_FRAME; ++i) {
+
351  RCHECK(reader->ReadBits(1, &found));
+
352  if (found)
+
353  break;
+
354  }
+
355  if (!found) {
+
356  RCHECK(ReadFrameSizes(reader, width, height));
+
357  } else {
+
358  uint32_t display_width;
+
359  uint32_t display_height;
+
360  RCHECK(ReadDisplayFrameSize(reader, &display_width, &display_height));
+
361  }
+
362  return true;
+
363 }
+
364 
+
365 bool ReadLoopFilter(BitReader* reader) {
+
366  RCHECK(reader->SkipBits(9)); // filter_evel, sharness_level
+
367  bool mode_ref_delta_enabled;
+
368  RCHECK(reader->ReadBits(1, &mode_ref_delta_enabled));
+
369  if (!mode_ref_delta_enabled)
+
370  return true;
+
371  bool mode_ref_delta_update;
+
372  RCHECK(reader->ReadBits(1, &mode_ref_delta_update));
+
373  if (!mode_ref_delta_update)
+
374  return true;
+
375 
+
376  for (uint32_t i = 0; i < MAX_REF_LF_DELTAS + MAX_MODE_LF_DELTAS; ++i)
+
377  RCHECK(reader->SkipBitsConditional(true, 6 + 1));
+
378  return true;
+
379 }
+
380 
+
381 bool ReadQuantization(BitReader* reader) {
+
382  RCHECK(reader->SkipBits(QINDEX_BITS));
+
383  // Skip delta_q bits.
+
384  for (uint32_t i = 0; i < 3; ++i)
+
385  RCHECK(reader->SkipBitsConditional(true, 4 + 1));
+
386  return true;
+
387 }
+
388 
+
389 bool ReadSegmentation(BitReader* reader) {
+
390  bool enabled;
+
391  RCHECK(reader->ReadBits(1, &enabled));
+
392  if (!enabled)
+
393  return true;
+
394 
+
395  bool update_map;
+
396  RCHECK(reader->ReadBits(1, &update_map));
+
397  if (update_map) {
+
398  for (uint32_t i = 0; i < SEG_TREE_PROBS; ++i)
+
399  RCHECK(reader->SkipBitsConditional(true, 8));
+
400 
+
401  bool temporal_update;
+
402  RCHECK(reader->ReadBits(1, &temporal_update));
+
403  if (temporal_update) {
+
404  for (uint32_t j = 0; j < PREDICTION_PROBS; ++j)
+
405  RCHECK(reader->SkipBitsConditional(true, 8));
+
406  }
+
407  }
+
408 
+
409  bool update_data;
+
410  RCHECK(reader->ReadBits(1, &update_data));
+
411  if (update_data) {
+
412  RCHECK(reader->SkipBits(1)); // abs_delta
+
413  for (uint32_t i = 0; i < MAX_SEGMENTS; ++i) {
+
414  for (uint32_t j = 0; j < SEG_LVL_MAX; ++j) {
+
415  bool feature_enabled;
+
416  RCHECK(reader->ReadBits(1, &feature_enabled));
+
417  if (feature_enabled) {
+
418  RCHECK(reader->SkipBits(SEG_FEATURE_DATA_MAX_BITS[j]));
+
419  if (SEG_FEATURE_DATA_SIGNED[j])
+
420  RCHECK(reader->SkipBits(1)); // signness
+
421  }
+
422  }
+
423  }
+
424  }
+
425  return true;
+
426 }
+
427 
+
428 bool ReadTileInfo(uint32_t width, BitReader* reader) {
+
429  uint32_t mi_cols = GetNumMiUnits(width);
+
430 
+
431  uint32_t min_log2_tile_cols;
+
432  uint32_t max_log2_tile_cols;
+
433  GetTileNBits(mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
+
434  uint32_t max_ones = max_log2_tile_cols - min_log2_tile_cols;
+
435 
+
436  uint32_t log2_tile_cols = min_log2_tile_cols;
+
437  while (max_ones--) {
+
438  bool has_more;
+
439  RCHECK(reader->ReadBits(1, &has_more));
+
440  if (!has_more)
+
441  break;
+
442  ++log2_tile_cols;
+
443  }
+
444  RCHECK(log2_tile_cols <= 6);
+
445 
+
446  RCHECK(reader->SkipBitsConditional(true, 1)); // log2_tile_rows
+
447  return true;
+
448 }
+
449 
+
450 } // namespace
+
451 
+
452 VP9Parser::VP9Parser() : width_(0), height_(0) {}
+
453 VP9Parser::~VP9Parser() {}
+
454 
+
455 bool VP9Parser::Parse(const uint8_t* data,
+
456  size_t data_size,
+
457  std::vector<VPxFrameInfo>* vpx_frames) {
+
458  DCHECK(data);
+
459  DCHECK(vpx_frames);
+
460  RCHECK(ParseIfSuperframeIndex(data, data_size, vpx_frames));
+
461 
+
462  for (auto& vpx_frame : *vpx_frames) {
+
463  VLOG(4) << "process frame with size " << vpx_frame.frame_size;
+
464  BitReader reader(data, vpx_frame.frame_size);
+
465  uint8_t frame_marker;
+
466  RCHECK(reader.ReadBits(2, &frame_marker));
+
467  RCHECK(frame_marker == VP9_FRAME_MARKER);
+
468 
+
469  RCHECK(ReadProfile(&reader, writable_codec_config()));
+
470 
+
471  bool show_existing_frame;
+
472  RCHECK(reader.ReadBits(1, &show_existing_frame));
+
473  if (show_existing_frame) {
+
474  RCHECK(reader.SkipBits(3)); // ref_frame_index
+
475  // End of current frame data. There should be no more bytes available.
+
476  RCHECK(reader.bits_available() < 8);
+
477 
+
478  vpx_frame.is_keyframe = false;
+
479  vpx_frame.uncompressed_header_size = vpx_frame.frame_size;
+
480  vpx_frame.width = width_;
+
481  vpx_frame.height = height_;
+
482  continue;
+
483  }
+
484 
+
485  bool is_interframe;
+
486  RCHECK(reader.ReadBits(1, &is_interframe));
+
487  vpx_frame.is_keyframe = !is_interframe;
+
488 
+
489  bool show_frame;
+
490  RCHECK(reader.ReadBits(1, &show_frame));
+
491  bool error_resilient_mode;
+
492  RCHECK(reader.ReadBits(1, &error_resilient_mode));
+
493 
+
494  if (vpx_frame.is_keyframe) {
+
495  RCHECK(ReadSyncCode(&reader));
+
496  RCHECK(ReadBitDepthAndColorSpace(&reader, writable_codec_config()));
+
497  RCHECK(ReadFrameSizes(&reader, &width_, &height_));
+
498  } else {
+
499  bool intra_only = false;
+
500  if (!show_frame)
+
501  RCHECK(reader.ReadBits(1, &intra_only));
+
502  if (!error_resilient_mode)
+
503  RCHECK(reader.SkipBits(2)); // reset_frame_context
+
504 
+
505  if (intra_only) {
+
506  RCHECK(ReadSyncCode(&reader));
+
507  if (codec_config().profile() > 0) {
+
508  RCHECK(ReadBitDepthAndColorSpace(&reader, writable_codec_config()));
+
509  } else {
+
510  // NOTE: The intra-only frame header does not include the
+
511  // specification of either the color format or color sub-sampling in
+
512  // profile 0. VP9 specifies that the default color format should be
+
513  // YUV 4:2:0 in this case (normative).
+
514  writable_codec_config()->SetChromaSubsampling(
+
515  VPCodecConfigurationRecord::CHROMA_420_COLLOCATED_WITH_LUMA);
+
516  writable_codec_config()->set_bit_depth(8);
+
517  }
+
518 
+
519  RCHECK(reader.SkipBits(REF_FRAMES)); // refresh_frame_flags
+
520  RCHECK(ReadFrameSizes(&reader, &width_, &height_));
+
521  } else {
+
522  RCHECK(reader.SkipBits(REF_FRAMES)); // refresh_frame_flags
+
523  RCHECK(reader.SkipBits(REFS_PER_FRAME * (REF_FRAMES_LOG2 + 1)));
+
524 
+
525  // TODO(kqyang): We may need to actually build the refs to extract the
+
526  // correct width and height for the current frame. The width will be
+
527  // used later in ReadTileInfo.
+
528  RCHECK(ReadFrameSizesWithRefs(&reader, &width_, &height_));
+
529 
+
530  RCHECK(reader.SkipBits(1)); // allow_high_precision_mv
+
531 
+
532  bool interp_filter;
+
533  RCHECK(reader.ReadBits(1, &interp_filter));
+
534  if (!interp_filter)
+
535  RCHECK(reader.SkipBits(2)); // more interp_filter
+
536  }
+
537  }
+
538 
+
539  if (!error_resilient_mode) {
+
540  RCHECK(reader.SkipBits(1)); // refresh_frame_context
+
541  RCHECK(reader.SkipBits(1)); // frame_parallel_decoding_mode
+
542  }
+
543  RCHECK(reader.SkipBits(FRAME_CONTEXTS_LOG2)); // frame_context_idx
+
544 
+
545  VLOG(4) << "bits read before ReadLoopFilter: " << reader.bit_position();
+
546  RCHECK(ReadLoopFilter(&reader));
+
547  RCHECK(ReadQuantization(&reader));
+
548  RCHECK(ReadSegmentation(&reader));
+
549  RCHECK(ReadTileInfo(width_, &reader));
+
550 
+
551  uint16_t header_size;
+
552  RCHECK(reader.ReadBits(16, &header_size));
+
553  vpx_frame.uncompressed_header_size =
+
554  vpx_frame.frame_size - reader.bits_available() / 8;
+
555  vpx_frame.width = width_;
+
556  vpx_frame.height = height_;
+
557 
+
558  VLOG(3) << "\n frame_size: " << vpx_frame.frame_size
+
559  << "\n uncompressed_header_size: "
+
560  << vpx_frame.uncompressed_header_size
+
561  << "\n bits read: " << reader.bit_position()
+
562  << "\n header_size: " << header_size;
+
563 
+
564  RCHECK(header_size > 0);
+
565  RCHECK(header_size * 8u <= reader.bits_available());
+
566 
+
567  data += vpx_frame.frame_size;
+
568  }
+
569  return true;
+
570 }
+
571 
+
572 bool VP9Parser::IsKeyframe(const uint8_t* data, size_t data_size) {
+
573  BitReader reader(data, data_size);
+
574  uint8_t frame_marker;
+
575  RCHECK(reader.ReadBits(2, &frame_marker));
+
576  RCHECK(frame_marker == VP9_FRAME_MARKER);
+
577 
+
578  VPCodecConfigurationRecord codec_config;
+
579  RCHECK(ReadProfile(&reader, &codec_config));
+
580 
+
581  bool show_existing_frame;
+
582  RCHECK(reader.ReadBits(1, &show_existing_frame));
+
583  if (show_existing_frame)
+
584  return false;
+
585 
+
586  bool is_interframe;
+
587  RCHECK(reader.ReadBits(1, &is_interframe));
+
588  if (is_interframe)
+
589  return false;
+
590 
+
591  RCHECK(reader.SkipBits(2)); // show_frame, error_resilient_mode.
+
592 
+
593  RCHECK(ReadSyncCode(&reader));
+
594  return true;
+
595 }
+
596 
+
597 } // namespace media
+
598 } // namespace shaka
+
A class to read bit streams.
Definition: bit_reader.h:17
+
size_t bit_position() const
Definition: bit_reader.h:94
+
bool SkipBits(size_t num_bits)
Definition: bit_reader.cc:24
+
size_t bits_available() const
Definition: bit_reader.h:89
+
bool ReadBits(size_t num_bits, T *out)
Definition: bit_reader.h:35
+
Class for parsing or writing VP codec configuration record.
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/d8f/classshaka_1_1xml_1_1RepresentationBaseXmlNode-members.html b/docs/d6/d8f/classshaka_1_1xml_1_1RepresentationBaseXmlNode-members.html index 2df8dc0e51..875aa4eca8 100644 --- a/docs/d6/d8f/classshaka_1_1xml_1_1RepresentationBaseXmlNode-members.html +++ b/docs/d6/d8f/classshaka_1_1xml_1_1RepresentationBaseXmlNode-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::xml::RepresentationBaseXmlNode, including all inherited members.

- - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + + + +
AddChild(scoped_xml_ptr< xmlNode > child)shaka::xml::XmlNode
AddContentProtectionElements(const std::list< ContentProtectionElement > &content_protection_elements) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNodeprotected
AddElements(const std::vector< Element > &elements)shaka::xml::XmlNode
AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNode
AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNode
ExtractReferencedNamespaces()shaka::xml::XmlNode
GetRawPtr()shaka::xml::XmlNode
PassScopedPtr()shaka::xml::XmlNode
Release()shaka::xml::XmlNode
RepresentationBaseXmlNode(const char *name) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNodeexplicitprotected
AddChild(XmlNode child) WARN_UNUSED_RESULTshaka::xml::XmlNode
AddContent(const std::string &content)shaka::xml::XmlNode
AddContentProtectionElements(const std::list< ContentProtectionElement > &content_protection_elements) WARN_UNUSED_RESULT (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNodeprotected
AddElements(const std::vector< Element > &elements) WARN_UNUSED_RESULTshaka::xml::XmlNode
AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNode
AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNode
ExtractReferencedNamespaces() constshaka::xml::XmlNode
GetAttribute(const std::string &name, std::string *value) constshaka::xml::XmlNode
operator=(XmlNode &&) (defined in shaka::xml::XmlNode)shaka::xml::XmlNode
RepresentationBaseXmlNode(const std::string &name) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNodeexplicitprotected
SetContent(const std::string &content)shaka::xml::XmlNode
SetFloatingPointAttribute(const char *attribute_name, double number)shaka::xml::XmlNode
SetId(uint32_t id)shaka::xml::XmlNode
SetIntegerAttribute(const char *attribute_name, uint64_t number)shaka::xml::XmlNode
SetStringAttribute(const char *attribute_name, const std::string &attribute)shaka::xml::XmlNode
XmlNode(const char *name)shaka::xml::XmlNodeexplicit
SetFloatingPointAttribute(const std::string &attribute_name, double number) WARN_UNUSED_RESULTshaka::xml::XmlNode
SetId(uint32_t id) WARN_UNUSED_RESULTshaka::xml::XmlNode
SetIntegerAttribute(const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULTshaka::xml::XmlNode
SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULTshaka::xml::XmlNode
ToString(const std::string &comment) constshaka::xml::XmlNode
XmlNode(const std::string &name)shaka::xml::XmlNodeexplicit
XmlNode(XmlNode &&) (defined in shaka::xml::XmlNode)shaka::xml::XmlNode
~RepresentationBaseXmlNode() override (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
~XmlNode() (defined in shaka::xml::XmlNode)shaka::xml::XmlNodevirtual
diff --git a/docs/de/da9/classshaka_1_1media_1_1WebVttTextOutputHandler-members.html b/docs/d6/d97/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler-members.html similarity index 71% rename from docs/de/da9/classshaka_1_1media_1_1WebVttTextOutputHandler-members.html rename to docs/d6/d97/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler-members.html index b0b9752845..1534c4bb5d 100644 --- a/docs/de/da9/classshaka_1_1media_1_1WebVttTextOutputHandler-members.html +++ b/docs/d6/d97/classshaka_1_1media_1_1ttml_1_1TtmlToMp4Handler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
-
shaka::media::WebVttTextOutputHandler Member List
+
shaka::media::ttml::TtmlToMp4Handler Member List
-

This is the complete list of members for shaka::media::WebVttTextOutputHandler, including all inherited members.

+

This is the complete list of members for shaka::media::ttml::TtmlToMp4Handler, including all inherited members.

- + @@ -86,18 +89,17 @@ $(function() { - - + + + + - - - + +
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandler
next_output_stream_index() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
num_input_streams() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
output_handlers() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandler
OnFlushRequest(size_t input_stream_index)shaka::media::MediaHandlerprotectedvirtual
output_handlers() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandler
TtmlToMp4Handler()=default (defined in shaka::media::ttml::TtmlToMp4Handler)shaka::media::ttml::TtmlToMp4Handler
ValidateOutputStreamIndex(size_t stream_index) constshaka::media::MediaHandlerprotectedvirtual
WebVttTextOutputHandler(const MuxerOptions &muxer_options, std::unique_ptr< MuxerListener > muxer_listener) (defined in shaka::media::WebVttTextOutputHandler)shaka::media::WebVttTextOutputHandler
~MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandlervirtual
~WebVttTextOutputHandler()=default (defined in shaka::media::WebVttTextOutputHandler)shaka::media::WebVttTextOutputHandlervirtual
~MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandlervirtual
~TtmlToMp4Handler() override=default (defined in shaka::media::ttml::TtmlToMp4Handler)shaka::media::ttml::TtmlToMp4Handler
diff --git a/docs/d6/d9b/h264__parser_8h_source.html b/docs/d6/d9b/h264__parser_8h_source.html index 16531c2f88..3a60796bc5 100644 --- a/docs/d6/d9b/h264__parser_8h_source.html +++ b/docs/d6/d9b/h264__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h264_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
h264_parser.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // This file contains an implementation of an H264 Annex-B video stream parser.
6 
7 #ifndef PACKAGER_MEDIA_CODECS_H264_PARSER_H_
8 #define PACKAGER_MEDIA_CODECS_H264_PARSER_H_
9 
10 #include <stdint.h>
11 #include <stdlib.h>
12 
13 #include <map>
14 #include <memory>
15 
16 #include "packager/media/codecs/h26x_bit_reader.h"
17 #include "packager/media/codecs/nalu_reader.h"
18 
19 namespace shaka {
20 namespace media {
21 
22 // On success, |coded_width| and |coded_height| contains coded resolution after
23 // cropping; |pixel_width:pixel_height| contains pixel aspect ratio, 1:1 is
24 // assigned if it is not present in SPS.
25 struct H264Sps;
26 bool ExtractResolutionFromSps(const H264Sps& sps,
27  uint32_t* coded_width,
28  uint32_t* coded_height,
29  uint32_t* pixel_width,
30  uint32_t* pixel_height);
31 
32 enum {
33  kH264ScalingList4x4Length = 16,
34  kH264ScalingList8x8Length = 64,
35 };
36 
37 struct H264Sps {
38  H264Sps();
39 
40  int profile_idc;
41  bool constraint_set0_flag;
42  bool constraint_set1_flag;
43  bool constraint_set2_flag;
44  bool constraint_set3_flag;
45  bool constraint_set4_flag;
46  bool constraint_set5_flag;
47  int level_idc;
48  int seq_parameter_set_id;
49 
50  int chroma_format_idc;
51  bool separate_colour_plane_flag;
52  int bit_depth_luma_minus8;
53  int bit_depth_chroma_minus8;
54  bool qpprime_y_zero_transform_bypass_flag;
55 
56  bool seq_scaling_matrix_present_flag;
57  int scaling_list4x4[6][kH264ScalingList4x4Length];
58  int scaling_list8x8[6][kH264ScalingList8x8Length];
59 
60  int log2_max_frame_num_minus4;
61  int pic_order_cnt_type;
62  int log2_max_pic_order_cnt_lsb_minus4;
63  bool delta_pic_order_always_zero_flag;
64  int offset_for_non_ref_pic;
65  int offset_for_top_to_bottom_field;
66  int num_ref_frames_in_pic_order_cnt_cycle;
67  int expected_delta_per_pic_order_cnt_cycle; // calculated
68  int offset_for_ref_frame[255];
69  int max_num_ref_frames;
70  bool gaps_in_frame_num_value_allowed_flag;
71  int pic_width_in_mbs_minus1;
72  int pic_height_in_map_units_minus1;
73  bool frame_mbs_only_flag;
74  bool mb_adaptive_frame_field_flag;
75  bool direct_8x8_inference_flag;
76  bool frame_cropping_flag;
77  int frame_crop_left_offset;
78  int frame_crop_right_offset;
79  int frame_crop_top_offset;
80  int frame_crop_bottom_offset;
81 
82  bool vui_parameters_present_flag;
83  int sar_width; // Set to 0 when not specified.
84  int sar_height; // Set to 0 when not specified.
85  int transfer_characteristics;
86 
87  bool bitstream_restriction_flag;
88  int max_num_reorder_frames;
89  int max_dec_frame_buffering;
90 
91  int chroma_array_type;
92 };
93 
94 struct H264Pps {
95  H264Pps();
96 
97  int pic_parameter_set_id;
98  int seq_parameter_set_id;
99  bool entropy_coding_mode_flag;
100  bool bottom_field_pic_order_in_frame_present_flag;
101  int num_slice_groups_minus1;
102  int num_ref_idx_l0_default_active_minus1;
103  int num_ref_idx_l1_default_active_minus1;
104  bool weighted_pred_flag;
105  int weighted_bipred_idc;
106  int pic_init_qp_minus26;
107  int pic_init_qs_minus26;
108  int chroma_qp_index_offset;
109  bool deblocking_filter_control_present_flag;
110  bool constrained_intra_pred_flag;
111  bool redundant_pic_cnt_present_flag;
112  bool transform_8x8_mode_flag;
113 
114  bool pic_scaling_matrix_present_flag;
115  int scaling_list4x4[6][kH264ScalingList4x4Length];
116  int scaling_list8x8[6][kH264ScalingList8x8Length];
117 
118  int second_chroma_qp_index_offset;
119 };
120 
122  int modification_of_pic_nums_idc;
123  union {
124  int abs_diff_pic_num_minus1;
125  int long_term_pic_num;
126  };
127 };
128 
130  bool luma_weight_flag[32];
131  bool chroma_weight_flag[32];
132  int luma_weight[32];
133  int luma_offset[32];
134  int chroma_weight[32][2];
135  int chroma_offset[32][2];
136 };
137 
139  int memory_mgmnt_control_operation;
140  int difference_of_pic_nums_minus1;
141  int long_term_pic_num;
142  int long_term_frame_idx;
143  int max_long_term_frame_idx_plus1;
144 };
145 
147  H264SliceHeader();
148 
149  enum {
150  kRefListSize = 32,
151  kRefListModSize = kRefListSize
152  };
153 
154  enum Type {
155  kPSlice = 0,
156  kBSlice = 1,
157  kISlice = 2,
158  kSPSlice = 3,
159  kSISlice = 4,
160  };
161 
162  bool IsPSlice() const;
163  bool IsBSlice() const;
164  bool IsISlice() const;
165  bool IsSPSlice() const;
166  bool IsSISlice() const;
167 
168  bool idr_pic_flag; // from NAL header
169  int nal_ref_idc; // from NAL header
170  // Points to the beginning of the nal unit.
171  const uint8_t* nalu_data;
172 
173  // Size of whole nalu unit.
174  size_t nalu_size;
175 
176  // This is the size of the slice header not including the nalu header byte.
177  // Sturcture: |NALU Header| Slice Header | Slice Data |
178  // Size: |<- 8bits ->|<- header_bit_size ->|<- Rest of nalu ->|
179  // Note that this is not a field in the H.264 spec.
180  size_t header_bit_size;
181 
182  int first_mb_in_slice;
183  int slice_type;
184  int pic_parameter_set_id;
185  int colour_plane_id;
186  int frame_num;
187  bool field_pic_flag;
188  bool bottom_field_flag;
189  int idr_pic_id;
190  int pic_order_cnt_lsb;
191  int delta_pic_order_cnt_bottom;
192  int delta_pic_order_cnt[2];
193  int redundant_pic_cnt;
194  bool direct_spatial_mv_pred_flag;
195 
196  bool num_ref_idx_active_override_flag;
197  int num_ref_idx_l0_active_minus1;
198  int num_ref_idx_l1_active_minus1;
199  bool ref_pic_list_modification_flag_l0;
200  bool ref_pic_list_modification_flag_l1;
201  H264ModificationOfPicNum ref_list_l0_modifications[kRefListModSize];
202  H264ModificationOfPicNum ref_list_l1_modifications[kRefListModSize];
203 
204  int luma_log2_weight_denom;
205  int chroma_log2_weight_denom;
206 
207  H264WeightingFactors pred_weight_table_l0;
208  H264WeightingFactors pred_weight_table_l1;
209 
210  bool no_output_of_prior_pics_flag;
211  bool long_term_reference_flag;
212 
213  bool adaptive_ref_pic_marking_mode_flag;
214  H264DecRefPicMarking ref_pic_marking[kRefListSize];
215 
216  int cabac_init_idc;
217  int slice_qp_delta;
218  bool sp_for_switch_flag;
219  int slice_qs_delta;
220  int disable_deblocking_filter_idc;
221  int slice_alpha_c0_offset_div2;
222  int slice_beta_offset_div2;
223 };
224 
226  int recovery_frame_cnt;
227  bool exact_match_flag;
228  bool broken_link_flag;
229  int changing_slice_group_idc;
230 };
231 
233  H264SEIMessage();
234 
235  enum Type {
236  kSEIRecoveryPoint = 6,
237  };
238 
239  int type;
240  int payload_size;
241  union {
242  // Placeholder; in future more supported types will contribute to more
243  // union members here.
244  H264SEIRecoveryPoint recovery_point;
245  };
246 };
247 
248 // Class to parse an Annex-B H.264 stream,
249 // as specified in chapters 7 and Annex B of the H.264 spec.
250 class H264Parser {
251  public:
252  enum Result {
253  kOk,
254  kInvalidStream, // error in stream
255  kUnsupportedStream, // stream not supported by the parser
256  kEOStream, // end of stream
257  };
258 
259  H264Parser();
260  ~H264Parser();
261 
262  // NALU-specific parsing functions.
263 
264  // SPSes and PPSes are owned by the parser class and the memory for their
265  // structures is managed here, not by the caller, as they are reused
266  // across NALUs.
267  //
268  // Parse an SPS/PPS NALU and save their data in the parser, returning id
269  // of the parsed structure in |*pps_id|/|*sps_id|.
270  // To get a pointer to a given SPS/PPS structure, use GetSps()/GetPps(),
271  // passing the returned |*sps_id|/|*pps_id| as parameter.
272  Result ParseSps(const Nalu& nalu, int* sps_id);
273  Result ParsePps(const Nalu& nalu, int* pps_id);
274 
275  // Return a pointer to SPS/PPS with given |sps_id|/|pps_id| or NULL if not
276  // present.
277  const H264Sps* GetSps(int sps_id);
278  const H264Pps* GetPps(int pps_id);
279 
280  // Slice headers and SEI messages are not used across NALUs by the parser
281  // and can be discarded after current NALU, so the parser does not store
282  // them, nor does it manage their memory.
283  // The caller has to provide and manage it instead.
284 
285  // Parse a slice header, returning it in |*shdr|. |*nalu| must be set to
286  // the NALU returned from AdvanceToNextNALU() and corresponding to |*shdr|.
287  Result ParseSliceHeader(const Nalu& nalu, H264SliceHeader* shdr);
288 
289  // Parse a SEI message, returning it in |*sei_msg|, provided and managed
290  // by the caller.
291  Result ParseSEI(const Nalu& nalu, H264SEIMessage* sei_msg);
292 
293  private:
294  // Parse scaling lists (see spec).
295  Result ParseScalingList(H26xBitReader* br,
296  int size,
297  int* scaling_list,
298  bool* use_default);
299  Result ParseSpsScalingLists(H26xBitReader* br, H264Sps* sps);
300  Result ParsePpsScalingLists(H26xBitReader* br,
301  const H264Sps& sps,
302  H264Pps* pps);
303 
304  // Parse optional VUI parameters in SPS (see spec).
305  Result ParseVUIParameters(H26xBitReader* br, H264Sps* sps);
306  // Set |hrd_parameters_present| to true only if they are present.
307  Result ParseAndIgnoreHRDParameters(H26xBitReader* br,
308  bool* hrd_parameters_present);
309 
310  // Parse reference picture lists' modifications (see spec).
311  Result ParseRefPicListModifications(H26xBitReader* br, H264SliceHeader* shdr);
312  Result ParseRefPicListModification(H26xBitReader* br,
313  int num_ref_idx_active_minus1,
314  H264ModificationOfPicNum* ref_list_mods);
315 
316  // Parse prediction weight table (see spec).
317  Result ParsePredWeightTable(H26xBitReader* br,
318  const H264Sps& sps,
319  H264SliceHeader* shdr);
320 
321  // Parse weighting factors (see spec).
322  Result ParseWeightingFactors(H26xBitReader* br,
323  int num_ref_idx_active_minus1,
324  int chroma_array_type,
325  int luma_log2_weight_denom,
326  int chroma_log2_weight_denom,
327  H264WeightingFactors* w_facts);
328 
329  // Parse decoded reference picture marking information (see spec).
330  Result ParseDecRefPicMarking(H26xBitReader* br, H264SliceHeader* shdr);
331 
332  // PPSes and SPSes stored for future reference.
333  typedef std::map<int, std::unique_ptr<H264Sps>> SpsById;
334  typedef std::map<int, std::unique_ptr<H264Pps>> PpsById;
335  SpsById active_SPSes_;
336  PpsById active_PPSes_;
337 
338  DISALLOW_COPY_AND_ASSIGN(H264Parser);
339 };
340 
341 } // namespace media
342 } // namespace shaka
343 
344 #endif // PACKAGER_MEDIA_CODECS_H264_PARSER_H_
- - - - - -
All the methods that are virtual are virtual for mocking.
- - - - - +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 //
+
5 // This file contains an implementation of an H264 Annex-B video stream parser.
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_H264_PARSER_H_
+
8 #define PACKAGER_MEDIA_CODECS_H264_PARSER_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <stdlib.h>
+
12 
+
13 #include <map>
+
14 #include <memory>
+
15 
+
16 #include "packager/media/codecs/h26x_bit_reader.h"
+
17 #include "packager/media/codecs/nalu_reader.h"
+
18 
+
19 namespace shaka {
+
20 namespace media {
+
21 
+
22 // On success, |coded_width| and |coded_height| contains coded resolution after
+
23 // cropping; |pixel_width:pixel_height| contains pixel aspect ratio, 1:1 is
+
24 // assigned if it is not present in SPS.
+
25 struct H264Sps;
+
26 bool ExtractResolutionFromSps(const H264Sps& sps,
+
27  uint32_t* coded_width,
+
28  uint32_t* coded_height,
+
29  uint32_t* pixel_width,
+
30  uint32_t* pixel_height);
+
31 
+
32 enum {
+
33  kH264ScalingList4x4Length = 16,
+
34  kH264ScalingList8x8Length = 64,
+
35 };
+
36 
+
37 struct H264Sps {
+
38  int profile_idc;
+
39  bool constraint_set0_flag;
+
40  bool constraint_set1_flag;
+
41  bool constraint_set2_flag;
+
42  bool constraint_set3_flag;
+
43  bool constraint_set4_flag;
+
44  bool constraint_set5_flag;
+
45  int level_idc;
+
46  int seq_parameter_set_id;
+
47 
+
48  int chroma_format_idc;
+
49  bool separate_colour_plane_flag;
+
50  int bit_depth_luma_minus8;
+
51  int bit_depth_chroma_minus8;
+
52  bool qpprime_y_zero_transform_bypass_flag;
+
53 
+
54  bool seq_scaling_matrix_present_flag;
+
55  int scaling_list4x4[6][kH264ScalingList4x4Length];
+
56  int scaling_list8x8[6][kH264ScalingList8x8Length];
+
57 
+
58  int log2_max_frame_num_minus4;
+
59  int pic_order_cnt_type;
+
60  int log2_max_pic_order_cnt_lsb_minus4;
+
61  bool delta_pic_order_always_zero_flag;
+
62  int offset_for_non_ref_pic;
+
63  int offset_for_top_to_bottom_field;
+
64  int num_ref_frames_in_pic_order_cnt_cycle;
+
65  int expected_delta_per_pic_order_cnt_cycle; // calculated
+
66  int offset_for_ref_frame[255];
+
67  int max_num_ref_frames;
+
68  bool gaps_in_frame_num_value_allowed_flag;
+
69  int pic_width_in_mbs_minus1;
+
70  int pic_height_in_map_units_minus1;
+
71  bool frame_mbs_only_flag;
+
72  bool mb_adaptive_frame_field_flag;
+
73  bool direct_8x8_inference_flag;
+
74  bool frame_cropping_flag;
+
75  int frame_crop_left_offset;
+
76  int frame_crop_right_offset;
+
77  int frame_crop_top_offset;
+
78  int frame_crop_bottom_offset;
+
79 
+
80  bool vui_parameters_present_flag;
+
81  int sar_width; // Set to 0 when not specified.
+
82  int sar_height; // Set to 0 when not specified.
+
83  int transfer_characteristics;
+
84 
+
85  bool bitstream_restriction_flag;
+
86  int max_num_reorder_frames;
+
87  int max_dec_frame_buffering;
+
88 
+
89  int chroma_array_type;
+
90 };
+
91 
+
92 struct H264Pps {
+
93  int pic_parameter_set_id;
+
94  int seq_parameter_set_id;
+
95  bool entropy_coding_mode_flag;
+
96  bool bottom_field_pic_order_in_frame_present_flag;
+
97  int num_slice_groups_minus1;
+
98  int num_ref_idx_l0_default_active_minus1;
+
99  int num_ref_idx_l1_default_active_minus1;
+
100  bool weighted_pred_flag;
+
101  int weighted_bipred_idc;
+
102  int pic_init_qp_minus26;
+
103  int pic_init_qs_minus26;
+
104  int chroma_qp_index_offset;
+
105  bool deblocking_filter_control_present_flag;
+
106  bool constrained_intra_pred_flag;
+
107  bool redundant_pic_cnt_present_flag;
+
108  bool transform_8x8_mode_flag;
+
109 
+
110  bool pic_scaling_matrix_present_flag;
+
111  int scaling_list4x4[6][kH264ScalingList4x4Length];
+
112  int scaling_list8x8[6][kH264ScalingList8x8Length];
+
113 
+
114  int second_chroma_qp_index_offset;
+
115 };
+
116 
+ +
118  int modification_of_pic_nums_idc;
+
119  union {
+
120  int abs_diff_pic_num_minus1;
+
121  int long_term_pic_num;
+
122  };
+
123 };
+
124 
+ +
126  bool luma_weight_flag[32];
+
127  bool chroma_weight_flag[32];
+
128  int luma_weight[32];
+
129  int luma_offset[32];
+
130  int chroma_weight[32][2];
+
131  int chroma_offset[32][2];
+
132 };
+
133 
+ +
135  int memory_mgmnt_control_operation;
+
136  int difference_of_pic_nums_minus1;
+
137  int long_term_pic_num;
+
138  int long_term_frame_idx;
+
139  int max_long_term_frame_idx_plus1;
+
140 };
+
141 
+ +
143  enum {
+
144  kRefListSize = 32,
+
145  kRefListModSize = kRefListSize
+
146  };
+
147 
+
148  enum Type {
+
149  kPSlice = 0,
+
150  kBSlice = 1,
+
151  kISlice = 2,
+
152  kSPSlice = 3,
+
153  kSISlice = 4,
+
154  };
+
155 
+
156  bool IsPSlice() const;
+
157  bool IsBSlice() const;
+
158  bool IsISlice() const;
+
159  bool IsSPSlice() const;
+
160  bool IsSISlice() const;
+
161 
+
162  bool idr_pic_flag; // from NAL header
+
163  int nal_ref_idc; // from NAL header
+
164  // Points to the beginning of the nal unit.
+
165  const uint8_t* nalu_data;
+
166 
+
167  // Size of whole nalu unit.
+
168  size_t nalu_size;
+
169 
+
170  // This is the size of the slice header not including the nalu header byte.
+
171  // Sturcture: |NALU Header| Slice Header | Slice Data |
+
172  // Size: |<- 8bits ->|<- header_bit_size ->|<- Rest of nalu ->|
+
173  // Note that this is not a field in the H.264 spec.
+
174  size_t header_bit_size;
+
175 
+
176  int first_mb_in_slice;
+
177  int slice_type;
+
178  int pic_parameter_set_id;
+
179  int colour_plane_id;
+
180  int frame_num;
+
181  bool field_pic_flag;
+
182  bool bottom_field_flag;
+
183  int idr_pic_id;
+
184  int pic_order_cnt_lsb;
+
185  int delta_pic_order_cnt_bottom;
+
186  int delta_pic_order_cnt[2];
+
187  int redundant_pic_cnt;
+
188  bool direct_spatial_mv_pred_flag;
+
189 
+
190  bool num_ref_idx_active_override_flag;
+
191  int num_ref_idx_l0_active_minus1;
+
192  int num_ref_idx_l1_active_minus1;
+
193  bool ref_pic_list_modification_flag_l0;
+
194  bool ref_pic_list_modification_flag_l1;
+
195  H264ModificationOfPicNum ref_list_l0_modifications[kRefListModSize];
+
196  H264ModificationOfPicNum ref_list_l1_modifications[kRefListModSize];
+
197 
+
198  int luma_log2_weight_denom;
+
199  int chroma_log2_weight_denom;
+
200 
+
201  H264WeightingFactors pred_weight_table_l0;
+
202  H264WeightingFactors pred_weight_table_l1;
+
203 
+
204  bool no_output_of_prior_pics_flag;
+
205  bool long_term_reference_flag;
+
206 
+
207  bool adaptive_ref_pic_marking_mode_flag;
+
208  H264DecRefPicMarking ref_pic_marking[kRefListSize];
+
209 
+
210  int cabac_init_idc;
+
211  int slice_qp_delta;
+
212  bool sp_for_switch_flag;
+
213  int slice_qs_delta;
+
214  int disable_deblocking_filter_idc;
+
215  int slice_alpha_c0_offset_div2;
+
216  int slice_beta_offset_div2;
+
217 };
+
218 
+ +
220  int recovery_frame_cnt;
+
221  bool exact_match_flag;
+
222  bool broken_link_flag;
+
223  int changing_slice_group_idc;
+
224 };
+
225 
+ +
227  enum Type {
+
228  kSEIRecoveryPoint = 6,
+
229  };
+
230 
+
231  int type;
+
232  int payload_size;
+
233  union {
+
234  // Placeholder; in future more supported types will contribute to more
+
235  // union members here.
+
236  H264SEIRecoveryPoint recovery_point;
+
237  };
+
238 };
+
239 
+
240 // Class to parse an Annex-B H.264 stream,
+
241 // as specified in chapters 7 and Annex B of the H.264 spec.
+
242 class H264Parser {
+
243  public:
+
244  enum Result {
+
245  kOk,
+
246  kInvalidStream, // error in stream
+
247  kUnsupportedStream, // stream not supported by the parser
+
248  kEOStream, // end of stream
+
249  };
+
250 
+
251  H264Parser();
+
252  ~H264Parser();
+
253 
+
254  // NALU-specific parsing functions.
+
255 
+
256  // SPSes and PPSes are owned by the parser class and the memory for their
+
257  // structures is managed here, not by the caller, as they are reused
+
258  // across NALUs.
+
259  //
+
260  // Parse an SPS/PPS NALU and save their data in the parser, returning id
+
261  // of the parsed structure in |*pps_id|/|*sps_id|.
+
262  // To get a pointer to a given SPS/PPS structure, use GetSps()/GetPps(),
+
263  // passing the returned |*sps_id|/|*pps_id| as parameter.
+
264  Result ParseSps(const Nalu& nalu, int* sps_id);
+
265  Result ParsePps(const Nalu& nalu, int* pps_id);
+
266 
+
267  // Return a pointer to SPS/PPS with given |sps_id|/|pps_id| or NULL if not
+
268  // present.
+
269  const H264Sps* GetSps(int sps_id);
+
270  const H264Pps* GetPps(int pps_id);
+
271 
+
272  // Slice headers and SEI messages are not used across NALUs by the parser
+
273  // and can be discarded after current NALU, so the parser does not store
+
274  // them, nor does it manage their memory.
+
275  // The caller has to provide and manage it instead.
+
276 
+
277  // Parse a slice header, returning it in |*shdr|. |*nalu| must be set to
+
278  // the NALU returned from AdvanceToNextNALU() and corresponding to |*shdr|.
+
279  Result ParseSliceHeader(const Nalu& nalu, H264SliceHeader* shdr);
+
280 
+
281  // Parse a SEI message, returning it in |*sei_msg|, provided and managed
+
282  // by the caller.
+
283  Result ParseSEI(const Nalu& nalu, H264SEIMessage* sei_msg);
+
284 
+
285  private:
+
286  // Parse scaling lists (see spec).
+
287  Result ParseScalingList(H26xBitReader* br,
+
288  int size,
+
289  int* scaling_list,
+
290  bool* use_default);
+
291  Result ParseSpsScalingLists(H26xBitReader* br, H264Sps* sps);
+
292  Result ParsePpsScalingLists(H26xBitReader* br,
+
293  const H264Sps& sps,
+
294  H264Pps* pps);
+
295 
+
296  // Parse optional VUI parameters in SPS (see spec).
+
297  Result ParseVUIParameters(H26xBitReader* br, H264Sps* sps);
+
298  // Set |hrd_parameters_present| to true only if they are present.
+
299  Result ParseAndIgnoreHRDParameters(H26xBitReader* br,
+
300  bool* hrd_parameters_present);
+
301 
+
302  // Parse reference picture lists' modifications (see spec).
+
303  Result ParseRefPicListModifications(H26xBitReader* br, H264SliceHeader* shdr);
+
304  Result ParseRefPicListModification(H26xBitReader* br,
+
305  int num_ref_idx_active_minus1,
+
306  H264ModificationOfPicNum* ref_list_mods);
+
307 
+
308  // Parse prediction weight table (see spec).
+
309  Result ParsePredWeightTable(H26xBitReader* br,
+
310  const H264Sps& sps,
+
311  H264SliceHeader* shdr);
+
312 
+
313  // Parse weighting factors (see spec).
+
314  Result ParseWeightingFactors(H26xBitReader* br,
+
315  int num_ref_idx_active_minus1,
+
316  int chroma_array_type,
+
317  int luma_log2_weight_denom,
+
318  int chroma_log2_weight_denom,
+
319  H264WeightingFactors* w_facts);
+
320 
+
321  // Parse decoded reference picture marking information (see spec).
+
322  Result ParseDecRefPicMarking(H26xBitReader* br, H264SliceHeader* shdr);
+
323 
+
324  // PPSes and SPSes stored for future reference.
+
325  typedef std::map<int, std::unique_ptr<H264Sps>> SpsById;
+
326  typedef std::map<int, std::unique_ptr<H264Pps>> PpsById;
+
327  SpsById active_SPSes_;
+
328  PpsById active_PPSes_;
+
329 
+
330  DISALLOW_COPY_AND_ASSIGN(H264Parser);
+
331 };
+
332 
+
333 } // namespace media
+
334 } // namespace shaka
+
335 
+
336 #endif // PACKAGER_MEDIA_CODECS_H264_PARSER_H_
+ + + +
All the methods that are virtual are virtual for mocking.
+ + + + + + + +
diff --git a/docs/d6/d9f/hls__flags_8cc_source.html b/docs/d6/d9f/hls__flags_8cc_source.html index 308aa69bed..f2ee42f98a 100644 --- a/docs/d6/d9f/hls__flags_8cc_source.html +++ b/docs/d6/d9f/hls__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/hls_flags.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
hls_flags.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/hls_flags.h"
8 
9 DEFINE_string(hls_master_playlist_output,
10  "",
11  "Output path for the master playlist for HLS. This flag must be"
12  "used to output HLS.");
13 DEFINE_string(hls_base_url,
14  "",
15  "The base URL for the Media Playlists and media files listed in "
16  "the playlists. This is the prefix for the files.");
17 DEFINE_string(hls_key_uri,
18  "",
19  "The key uri for 'identity' and 'com.apple.streamingkeydelivery' "
20  "key formats. Ignored if the playlist is not encrypted or not "
21  "using the above key formats.");
22 DEFINE_string(hls_playlist_type,
23  "VOD",
24  "VOD, EVENT, or LIVE. This defines the EXT-X-PLAYLIST-TYPE in "
25  "the HLS specification. For hls_playlist_type of LIVE, "
26  "EXT-X-PLAYLIST-TYPE tag is omitted.");
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/app/hls_flags.h"
+
8 
+
9 DEFINE_string(hls_master_playlist_output,
+
10  "",
+
11  "Output path for the master playlist for HLS. This flag must be"
+
12  "used to output HLS.");
+
13 DEFINE_string(hls_base_url,
+
14  "",
+
15  "The base URL for the Media Playlists and media files listed in "
+
16  "the playlists. This is the prefix for the files.");
+
17 DEFINE_string(hls_key_uri,
+
18  "",
+
19  "The key uri for 'identity' and 'com.apple.streamingkeydelivery' "
+
20  "key formats. Ignored if the playlist is not encrypted or not "
+
21  "using the above key formats.");
+
22 DEFINE_string(hls_playlist_type,
+
23  "VOD",
+
24  "VOD, EVENT, or LIVE. This defines the EXT-X-PLAYLIST-TYPE in "
+
25  "the HLS specification. For hls_playlist_type of LIVE, "
+
26  "EXT-X-PLAYLIST-TYPE tag is omitted.");
+
27 DEFINE_int32(hls_media_sequence_number,
+
28  0,
+
29  "Number. This HLS-only parameter defines the initial "
+
30  "EXT-X-MEDIA-SEQUENCE value, which allows continuous media "
+
31  "sequence across packager restarts. See #691 for more "
+
32  "information about the reasoning of this and its use cases.");
+
diff --git a/docs/d6/d9f/webvtt__to__mp4__handler_8cc_source.html b/docs/d6/d9f/webvtt__to__mp4__handler_8cc_source.html index 2911dde13d..110571d587 100644 --- a/docs/d6/d9f/webvtt__to__mp4__handler_8cc_source.html +++ b/docs/d6/d9f/webvtt__to__mp4__handler_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/webvtt_to_mp4_handler.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webvtt_to_mp4_handler.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webvtt/webvtt_to_mp4_handler.h"
8 
9 #include <algorithm>
10 #include <map>
11 
12 #include "packager/media/base/buffer_writer.h"
13 #include "packager/media/formats/mp4/box_buffer.h"
14 #include "packager/media/formats/mp4/box_definitions.h"
15 #include "packager/status_macros.h"
16 
17 namespace shaka {
18 namespace media {
19 namespace {
20 size_t kTrackId = 0;
21 
22 enum class DisplayActionType { ADD, REMOVE };
23 
24 struct DisplayAction {
25  DisplayActionType type;
26  const TextSample* sample;
27 };
28 
29 std::multimap<int64_t, DisplayAction> CreateActionList(
30  int64_t segment_start,
31  int64_t segment_end,
32  const std::list<std::shared_ptr<const TextSample>>& samples) {
33  std::multimap<int64_t, DisplayAction> actions;
34 
35  for (const auto& sample : samples) {
36  DCHECK(sample);
37 
38  // The add action should occur either in this segment or in a previous
39  // segment.
40  DCHECK_LT(sample->start_time(), segment_end);
41  actions.insert(
42  {sample->start_time(), {DisplayActionType::ADD, sample.get()}});
43 
44  // If the remove happens in a later segment, then we don't want to include
45  // that action.
46  if (sample->EndTime() < segment_end) {
47  actions.insert(
48  {sample->EndTime(), {DisplayActionType::REMOVE, sample.get()}});
49  }
50  }
51 
52  return actions;
53 }
54 
55 void WriteSample(const TextSample& sample, BufferWriter* out) {
56  mp4::VTTCueBox box;
57 
58  if (sample.id().length()) {
59  box.cue_id.cue_id = sample.id();
60  }
61  if (sample.settings().length()) {
62  box.cue_settings.settings = sample.settings();
63  }
64  if (sample.payload().length()) {
65  box.cue_payload.cue_text = sample.payload();
66  }
67 
68  // If there is internal timing, i.e. WebVTT cue timestamp, then
69  // cue_current_time should be populated
70  // "which gives the VTT timestamp associated with the start time of sample."
71  // TODO(rkuroiwa): Reuse TimestampToMilliseconds() to check if there is an
72  // internal timestamp in the payload to set CueTimeBox.cue_current_time.
73  box.Write(out);
74 }
75 
76 void WriteSamples(const std::list<const TextSample*>& samples,
77  BufferWriter* writer) {
78  DCHECK_GE(samples.size(), 0u);
79 
80  for (const auto& sample : samples) {
81  WriteSample(*sample, writer);
82  }
83 }
84 
85 void WriteEmptySample(BufferWriter* writer) {
86  mp4::VTTEmptyCueBox box;
87  box.Write(writer);
88 }
89 
90 std::shared_ptr<MediaSample> CreateMediaSample(const BufferWriter& buffer,
91  int64_t start_time,
92  int64_t end_time) {
93  DCHECK_GE(start_time, 0);
94  DCHECK_GT(end_time, start_time);
95 
96  const bool kIsKeyFrame = true;
97 
98  std::shared_ptr<MediaSample> sample =
99  MediaSample::CopyFrom(buffer.Buffer(), buffer.Size(), kIsKeyFrame);
100  sample->set_pts(start_time);
101  sample->set_dts(start_time);
102  sample->set_duration(end_time - start_time);
103 
104  return sample;
105 }
106 } // namespace
107 
108 Status WebVttToMp4Handler::InitializeInternal() {
109  return Status::OK;
110 }
111 
112 Status WebVttToMp4Handler::Process(std::unique_ptr<StreamData> stream_data) {
113  switch (stream_data->stream_data_type) {
114  case StreamDataType::kStreamInfo:
115  return OnStreamInfo(std::move(stream_data));
116  case StreamDataType::kCueEvent:
117  return OnCueEvent(std::move(stream_data));
118  case StreamDataType::kSegmentInfo:
119  return OnSegmentInfo(std::move(stream_data));
120  case StreamDataType::kTextSample:
121  return OnTextSample(std::move(stream_data));
122  default:
123  return Status(error::INTERNAL_ERROR,
124  "Invalid stream data type (" +
125  StreamDataTypeToString(stream_data->stream_data_type) +
126  ") for this WebVttToMp4 handler");
127  }
128 }
129 
130 Status WebVttToMp4Handler::OnStreamInfo(
131  std::unique_ptr<StreamData> stream_data) {
132  DCHECK(stream_data);
133  DCHECK(stream_data->stream_info);
134 
135  return Dispatch(std::move(stream_data));
136 }
137 
138 Status WebVttToMp4Handler::OnCueEvent(std::unique_ptr<StreamData> stream_data) {
139  DCHECK(stream_data);
140  DCHECK(stream_data->cue_event);
141 
142  if (current_segment_.size()) {
143  return Status(error::INTERNAL_ERROR,
144  "Cue Events should come right after segment info.");
145  }
146 
147  return Dispatch(std::move(stream_data));
148 }
149 
150 Status WebVttToMp4Handler::OnSegmentInfo(
151  std::unique_ptr<StreamData> stream_data) {
152  DCHECK(stream_data);
153  DCHECK(stream_data->segment_info);
154 
155  const auto& segment = stream_data->segment_info;
156 
157  int64_t segment_start = segment->start_timestamp;
158  int64_t segment_duration = segment->duration;
159  int64_t segment_end = segment_start + segment_duration;
160 
161  RETURN_IF_ERROR(DispatchCurrentSegment(segment_start, segment_end));
162  current_segment_.clear();
163 
164  return Dispatch(std::move(stream_data));
165 }
166 
167 Status WebVttToMp4Handler::OnTextSample(
168  std::unique_ptr<StreamData> stream_data) {
169  DCHECK(stream_data);
170  DCHECK(stream_data->text_sample);
171 
172  auto& sample = stream_data->text_sample;
173 
174  // Ignore empty samples. This will create gaps, but we will handle that
175  // later.
176  if (sample->payload().empty()) {
177  return Status::OK;
178  }
179 
180  // Add the new text sample to the cache of samples that belong in the
181  // current segment.
182  current_segment_.push_back(std::move(stream_data->text_sample));
183  return Status::OK;
184 }
185 
186 Status WebVttToMp4Handler::DispatchCurrentSegment(int64_t segment_start,
187  int64_t segment_end) {
188  // Active will hold all the samples that are "on screen" for the current
189  // section of time.
190  std::list<const TextSample*> active;
191 
192  // Move through the segment, jumping between each change to the current state.
193  // A change is defined as a group of one or more DisplayActions.
194  int section_start = segment_start;
195 
196  // |actions| is a map of [time] -> [action].
197  auto actions = CreateActionList(segment_start, segment_end, current_segment_);
198  auto front = actions.begin();
199 
200  // As it is possible to have a segment with no samples, we can't base this
201  // loop on the number of actions. So we need to keep iterating until we
202  // have written enough sections to get to the end of the segment.
203  while (section_start < segment_end) {
204  // Apply all actions that occur at the start of this part of the segment.
205  // Normally we would only want "== section_start" but as it is possible for
206  // samples to span multiple segments, their start time will be before the
207  // segment's start time. So we want to apply them too if they come before
208  // the segment. Thus why we use "<=".
209  while (front != actions.end() && front->first <= section_start) {
210  auto& action = front->second;
211 
212  switch (action.type) {
213  case DisplayActionType::ADD: {
214  active.push_back(action.sample);
215  break;
216  }
217  case DisplayActionType::REMOVE: {
218  auto found = std::find(active.begin(), active.end(), action.sample);
219  DCHECK(found != active.end());
220  active.erase(found);
221  break;
222  }
223  default: {
224  NOTREACHED() << "Unsupported DisplayActionType "
225  << static_cast<int>(action.type);
226  break;
227  }
228  }
229 
230  // We have "consumed" the action at the front. We can move on.
231  front++;
232  }
233 
234  // The end of the section will either be the start of the next section or
235  // the end of the segment.
236  int64_t section_end = front == actions.end() ? segment_end : front->first;
237  DCHECK_GT(section_end, section_start);
238  DCHECK_LE(section_end, segment_end);
239  RETURN_IF_ERROR(MergeDispatchSamples(section_start, section_end, active));
240 
241  section_start = section_end;
242  }
243 
244  DCHECK(front == actions.end()) << "We should have processed all actions.";
245 
246  return Status::OK;
247 }
248 
249 Status WebVttToMp4Handler::MergeDispatchSamples(
250  int64_t start_time,
251  int64_t end_time,
252  const std::list<const TextSample*>& state) {
253  DCHECK_GT(end_time, start_time);
254 
255  box_writer_.Clear();
256 
257  if (state.size()) {
258  WriteSamples(state, &box_writer_);
259  } else {
260  WriteEmptySample(&box_writer_);
261  }
262 
263  return DispatchMediaSample(
264  kTrackId, CreateMediaSample(box_writer_, start_time, end_time));
265 }
266 } // namespace media
267 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
Definition: media_sample.cc:42
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/webvtt/webvtt_to_mp4_handler.h"
+
8 
+
9 #include <algorithm>
+
10 #include <map>
+
11 
+
12 #include "packager/media/base/buffer_writer.h"
+
13 #include "packager/media/formats/mp4/box_buffer.h"
+
14 #include "packager/media/formats/mp4/box_definitions.h"
+
15 #include "packager/media/formats/webvtt/webvtt_utils.h"
+
16 #include "packager/status_macros.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 namespace {
+
21 size_t kTrackId = 0;
+
22 
+
23 enum class DisplayActionType { ADD, REMOVE };
+
24 
+
25 struct DisplayAction {
+
26  DisplayActionType type;
+
27  const TextSample* sample;
+
28 };
+
29 
+
30 std::multimap<int64_t, DisplayAction> CreateActionList(
+
31  int64_t segment_start,
+
32  int64_t segment_end,
+
33  const std::list<std::shared_ptr<const TextSample>>& samples) {
+
34  std::multimap<int64_t, DisplayAction> actions;
+
35 
+
36  for (const auto& sample : samples) {
+
37  DCHECK(sample);
+
38 
+
39  // The add action should occur either in this segment or in a previous
+
40  // segment.
+
41  DCHECK_LT(sample->start_time(), segment_end);
+
42  actions.insert(
+
43  {sample->start_time(), {DisplayActionType::ADD, sample.get()}});
+
44 
+
45  // If the remove happens in a later segment, then we don't want to include
+
46  // that action.
+
47  if (sample->EndTime() < segment_end) {
+
48  actions.insert(
+
49  {sample->EndTime(), {DisplayActionType::REMOVE, sample.get()}});
+
50  }
+
51  }
+
52 
+
53  return actions;
+
54 }
+
55 
+
56 void WriteSample(const TextSample& sample, BufferWriter* out) {
+
57  mp4::VTTCueBox box;
+
58 
+
59  if (sample.id().length()) {
+
60  box.cue_id.cue_id = sample.id();
+
61  }
+
62  box.cue_settings.settings = WebVttSettingsToString(sample.settings());
+
63  box.cue_payload.cue_text = WebVttFragmentToString(sample.body());
+
64 
+
65  // If there is internal timing, i.e. WebVTT cue timestamp, then
+
66  // cue_current_time should be populated
+
67  // "which gives the VTT timestamp associated with the start time of sample."
+
68  // TODO(rkuroiwa): Reuse TimestampToMilliseconds() to check if there is an
+
69  // internal timestamp in the payload to set CueTimeBox.cue_current_time.
+
70  box.Write(out);
+
71 }
+
72 
+
73 void WriteSamples(const std::list<const TextSample*>& samples,
+
74  BufferWriter* writer) {
+
75  DCHECK_GE(samples.size(), 0u);
+
76 
+
77  for (const auto& sample : samples) {
+
78  WriteSample(*sample, writer);
+
79  }
+
80 }
+
81 
+
82 void WriteEmptySample(BufferWriter* writer) {
+
83  mp4::VTTEmptyCueBox box;
+
84  box.Write(writer);
+
85 }
+
86 
+
87 std::shared_ptr<MediaSample> CreateMediaSample(const BufferWriter& buffer,
+
88  int64_t start_time,
+
89  int64_t end_time) {
+
90  DCHECK_GE(start_time, 0);
+
91  DCHECK_GT(end_time, start_time);
+
92 
+
93  const bool kIsKeyFrame = true;
+
94 
+
95  std::shared_ptr<MediaSample> sample =
+
96  MediaSample::CopyFrom(buffer.Buffer(), buffer.Size(), kIsKeyFrame);
+
97  sample->set_pts(start_time);
+
98  sample->set_dts(start_time);
+
99  sample->set_duration(end_time - start_time);
+
100 
+
101  return sample;
+
102 }
+
103 } // namespace
+
104 
+
105 Status WebVttToMp4Handler::InitializeInternal() {
+
106  return Status::OK;
+
107 }
+
108 
+
109 Status WebVttToMp4Handler::Process(std::unique_ptr<StreamData> stream_data) {
+
110  switch (stream_data->stream_data_type) {
+
111  case StreamDataType::kStreamInfo:
+
112  return OnStreamInfo(std::move(stream_data));
+
113  case StreamDataType::kCueEvent:
+
114  return OnCueEvent(std::move(stream_data));
+
115  case StreamDataType::kSegmentInfo:
+
116  return OnSegmentInfo(std::move(stream_data));
+
117  case StreamDataType::kTextSample:
+
118  return OnTextSample(std::move(stream_data));
+
119  default:
+
120  return Status(error::INTERNAL_ERROR,
+
121  "Invalid stream data type (" +
+
122  StreamDataTypeToString(stream_data->stream_data_type) +
+
123  ") for this WebVttToMp4 handler");
+
124  }
+
125 }
+
126 
+
127 Status WebVttToMp4Handler::OnStreamInfo(
+
128  std::unique_ptr<StreamData> stream_data) {
+
129  DCHECK(stream_data);
+
130  DCHECK(stream_data->stream_info);
+
131 
+
132  return Dispatch(std::move(stream_data));
+
133 }
+
134 
+
135 Status WebVttToMp4Handler::OnCueEvent(std::unique_ptr<StreamData> stream_data) {
+
136  DCHECK(stream_data);
+
137  DCHECK(stream_data->cue_event);
+
138 
+
139  if (current_segment_.size()) {
+
140  return Status(error::INTERNAL_ERROR,
+
141  "Cue Events should come right after segment info.");
+
142  }
+
143 
+
144  return Dispatch(std::move(stream_data));
+
145 }
+
146 
+
147 Status WebVttToMp4Handler::OnSegmentInfo(
+
148  std::unique_ptr<StreamData> stream_data) {
+
149  DCHECK(stream_data);
+
150  DCHECK(stream_data->segment_info);
+
151 
+
152  const auto& segment = stream_data->segment_info;
+
153 
+
154  int64_t segment_start = segment->start_timestamp;
+
155  int64_t segment_duration = segment->duration;
+
156  int64_t segment_end = segment_start + segment_duration;
+
157 
+
158  RETURN_IF_ERROR(DispatchCurrentSegment(segment_start, segment_end));
+
159  current_segment_.clear();
+
160 
+
161  return Dispatch(std::move(stream_data));
+
162 }
+
163 
+
164 Status WebVttToMp4Handler::OnTextSample(
+
165  std::unique_ptr<StreamData> stream_data) {
+
166  DCHECK(stream_data);
+
167  DCHECK(stream_data->text_sample);
+
168 
+
169  auto& sample = stream_data->text_sample;
+
170 
+
171  // Ignore empty samples. This will create gaps, but we will handle that
+
172  // later.
+
173  if (sample->body().is_empty()) {
+
174  return Status::OK;
+
175  }
+
176 
+
177  // Add the new text sample to the cache of samples that belong in the
+
178  // current segment.
+
179  current_segment_.push_back(std::move(stream_data->text_sample));
+
180  return Status::OK;
+
181 }
+
182 
+
183 Status WebVttToMp4Handler::DispatchCurrentSegment(int64_t segment_start,
+
184  int64_t segment_end) {
+
185  // Active will hold all the samples that are "on screen" for the current
+
186  // section of time.
+
187  std::list<const TextSample*> active;
+
188 
+
189  // Move through the segment, jumping between each change to the current state.
+
190  // A change is defined as a group of one or more DisplayActions.
+
191  int section_start = segment_start;
+
192 
+
193  // |actions| is a map of [time] -> [action].
+
194  auto actions = CreateActionList(segment_start, segment_end, current_segment_);
+
195  auto front = actions.begin();
+
196 
+
197  // As it is possible to have a segment with no samples, we can't base this
+
198  // loop on the number of actions. So we need to keep iterating until we
+
199  // have written enough sections to get to the end of the segment.
+
200  while (section_start < segment_end) {
+
201  // Apply all actions that occur at the start of this part of the segment.
+
202  // Normally we would only want "== section_start" but as it is possible for
+
203  // samples to span multiple segments, their start time will be before the
+
204  // segment's start time. So we want to apply them too if they come before
+
205  // the segment. Thus why we use "<=".
+
206  while (front != actions.end() && front->first <= section_start) {
+
207  auto& action = front->second;
+
208 
+
209  switch (action.type) {
+
210  case DisplayActionType::ADD: {
+
211  active.push_back(action.sample);
+
212  break;
+
213  }
+
214  case DisplayActionType::REMOVE: {
+
215  auto found = std::find(active.begin(), active.end(), action.sample);
+
216  DCHECK(found != active.end());
+
217  active.erase(found);
+
218  break;
+
219  }
+
220  default: {
+
221  NOTREACHED() << "Unsupported DisplayActionType "
+
222  << static_cast<int>(action.type);
+
223  break;
+
224  }
+
225  }
+
226 
+
227  // We have "consumed" the action at the front. We can move on.
+
228  front++;
+
229  }
+
230 
+
231  // The end of the section will either be the start of the next section or
+
232  // the end of the segment.
+
233  int64_t section_end = front == actions.end() ? segment_end : front->first;
+
234  DCHECK_GT(section_end, section_start);
+
235  DCHECK_LE(section_end, segment_end);
+
236  RETURN_IF_ERROR(MergeDispatchSamples(section_start, section_end, active));
+
237 
+
238  section_start = section_end;
+
239  }
+
240 
+
241  DCHECK(front == actions.end()) << "We should have processed all actions.";
+
242 
+
243  return Status::OK;
+
244 }
+
245 
+
246 Status WebVttToMp4Handler::MergeDispatchSamples(
+
247  int64_t start_time,
+
248  int64_t end_time,
+
249  const std::list<const TextSample*>& state) {
+
250  DCHECK_GT(end_time, start_time);
+
251 
+
252  box_writer_.Clear();
+
253 
+
254  if (state.size()) {
+
255  WriteSamples(state, &box_writer_);
+
256  } else {
+
257  WriteEmptySample(&box_writer_);
+
258  }
+
259 
+
260  return DispatchMediaSample(
+
261  kTrackId, CreateMediaSample(box_writer_, start_time, end_time));
+
262 }
+
263 } // namespace media
+
264 } // namespace shaka
+
Status DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
Dispatch the media sample to downstream handlers.
+
Status Dispatch(std::unique_ptr< StreamData > stream_data) const
+
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
Definition: media_sample.cc:42
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/da0/ts__section__pat_8h_source.html b/docs/d6/da0/ts__section__pat_8h_source.html index 9bba9ecad1..b2453d3ee0 100644 --- a/docs/d6/da0/ts__section__pat_8h_source.html +++ b/docs/d6/da0/ts__section__pat_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section_pat.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
ts_section_pat.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PAT_H_
6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PAT_H_
7 
8 #include "packager/base/callback.h"
9 #include "packager/base/compiler_specific.h"
10 #include "packager/media/formats/mp2t/ts_section_psi.h"
11 
12 namespace shaka {
13 namespace media {
14 namespace mp2t {
15 
16 class TsSectionPat : public TsSectionPsi {
17  public:
18  // RegisterPmtCb::Run(int program_number, int pmt_pid);
19  typedef base::Callback<void(int, int)> RegisterPmtCb;
20 
21  explicit TsSectionPat(const RegisterPmtCb& register_pmt_cb);
22  ~TsSectionPat() override;
23 
24  // TsSectionPsi implementation.
25  bool ParsePsiSection(BitReader* bit_reader) override;
26  void ResetPsiSection() override;
27 
28  private:
29  RegisterPmtCb register_pmt_cb_;
30 
31  // Parameters from the PAT.
32  int version_number_;
33 
34  DISALLOW_COPY_AND_ASSIGN(TsSectionPat);
35 };
36 
37 } // namespace mp2t
38 } // namespace media
39 } // namespace shaka
40 
41 #endif
42 
A class to read bit streams.
Definition: bit_reader.h:17
-
All the methods that are virtual are virtual for mocking.
- - +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PAT_H_
+
6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SECTION_PAT_H_
+
7 
+
8 #include "packager/base/callback.h"
+
9 #include "packager/base/compiler_specific.h"
+
10 #include "packager/media/formats/mp2t/ts_section_psi.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 namespace mp2t {
+
15 
+
16 class TsSectionPat : public TsSectionPsi {
+
17  public:
+
18  // RegisterPmtCb::Run(int program_number, int pmt_pid);
+
19  typedef base::Callback<void(int, int)> RegisterPmtCb;
+
20 
+
21  explicit TsSectionPat(const RegisterPmtCb& register_pmt_cb);
+
22  ~TsSectionPat() override;
+
23 
+
24  // TsSectionPsi implementation.
+
25  bool ParsePsiSection(BitReader* bit_reader) override;
+
26  void ResetPsiSection() override;
+
27 
+
28  private:
+
29  RegisterPmtCb register_pmt_cb_;
+
30 
+
31  // Parameters from the PAT.
+
32  int version_number_;
+
33 
+
34  DISALLOW_COPY_AND_ASSIGN(TsSectionPat);
+
35 };
+
36 
+
37 } // namespace mp2t
+
38 } // namespace media
+
39 } // namespace shaka
+
40 
+
41 #endif
+
42 
+
A class to read bit streams.
Definition: bit_reader.h:17
+ + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/da2/structshaka_1_1media_1_1mp4_1_1AC4Specific.html b/docs/d6/da2/structshaka_1_1media_1_1mp4_1_1AC4Specific.html new file mode 100644 index 0000000000..22ff634fae --- /dev/null +++ b/docs/d6/da2/structshaka_1_1media_1_1mp4_1_1AC4Specific.html @@ -0,0 +1,160 @@ + + + + + + + +Shaka Packager SDK: shaka::media::mp4::AC4Specific Struct Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::mp4::AC4Specific Struct Reference
+
+
+
+Inheritance diagram for shaka::media::mp4::AC4Specific:
+
+
+ + +shaka::media::mp4::Box + +
+ + + + + + + + + + + + + + + + + +

+Public Member Functions

FourCC BoxType () const override
 
- Public Member Functions inherited from shaka::media::mp4::Box
bool Parse (BoxReader *reader)
 
void Write (BufferWriter *writer)
 
void WriteHeader (BufferWriter *writer)
 
uint32_t ComputeSize ()
 
virtual uint32_t HeaderSize () const
 
uint32_t box_size ()
 
+ + + +

+Public Attributes

+std::vector< uint8_t > data
 
+ + + + +

+Additional Inherited Members

- Protected Member Functions inherited from shaka::media::mp4::Box
virtual bool ReadWriteHeaderInternal (BoxBuffer *buffer)
 
+

Detailed Description

+
+

Definition at line 337 of file box_definitions.h.

+

Member Function Documentation

+ +

◆ BoxType()

+ +
+
+ + + + + +
+ + + + + + + +
FourCC shaka::media::mp4::AC4Specific::BoxType () const
+
+overridevirtual
+
+
Returns
box type.
+ +

Implements shaka::media::mp4::Box.

+ +

Definition at line 1793 of file box_definitions.cc.

+ +
+
+
The documentation for this struct was generated from the following files: +
+ + + + diff --git a/docs/d6/da2/structshaka_1_1media_1_1mp4_1_1AC4Specific.png b/docs/d6/da2/structshaka_1_1media_1_1mp4_1_1AC4Specific.png new file mode 100644 index 0000000000000000000000000000000000000000..5d8757d70b7767526e35d88f127279c4a52fc039 GIT binary patch literal 742 zcmeAS@N?(olHy`uVBq!ia0vp^`+zurgBeIpcw!$5q$C1-LR|m<{|{uoc=NTi|Ih@G z90(scaDcV*jy#abQ4-`A%m7pb0#{Fk7%?y~m3q23hEy=Vo%^uwvlb6)yYR~Q|4(f9 zWxCP02H+c`vIB0e*ep+heGtq99v#SnFUlPbw<0-Xt_YcpYzh9L-U%kpK zJG^PulI#5{cdxDgsQNOBt)li<$A7keuk7F6&UtwAa8~kHlM}zwPkV2EbivL3e`NR_ z%QMw~&R%@Ce#3kI%Cg0#IeSg-t&ux?Zo9V1%aH9Kw6ng&-?`PUy!Ph*Q)|}#U9`Qm zWPgQMl=i;8nQHq~zizEK_rW*B=VOiNe(B)qCDUFP1#C-?z#PZ05Vj@HsC z&qO&B!dUGNXn?Tnhrf||^WK1hZ1?$FHm_z|v3#iVHJSU&`v=4IqL|9-y*qubD>|$$ zTlMHY-?rRs8gCM}Dn`ETJt;RK7#MtS_xAIB6FnLzGUMz1`zv?cO)G0YG;i*->-tfL zuSGvT`^wPArsq%PwWxQ{F_q*MawM=rg`;Cn+=6~pAmp6ESd;beDe^39T z+r>{E+5YU(x|ffB2Rz@pEaKMUAG-G*mnT;Vsmte!Kewx6`_{Sb@A8IuOTS3{-*ac( zj$60#C#AgJ6utcI2mY=1Mf!Ko47UuZ5hS^SULg;67ONqe*zFi|piy85}Sb4q9e0A?0`H~;_u literal 0 HcmV?d00001 diff --git a/docs/d6/da3/mpd__builder_8h_source.html b/docs/d6/da3/mpd__builder_8h_source.html index bc55ea57cf..1ab134e13b 100644 --- a/docs/d6/da3/mpd__builder_8h_source.html +++ b/docs/d6/da3/mpd__builder_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mpd_builder.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mpd_builder.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
10 
11 #ifndef MPD_BASE_MPD_BUILDER_H_
12 #define MPD_BASE_MPD_BUILDER_H_
13 
14 #include <libxml/tree.h>
15 
16 #include <list>
17 #include <memory>
18 #include <string>
19 
20 #include "packager/base/time/clock.h"
21 #include "packager/mpd/base/mpd_options.h"
22 
23 // TODO(rkuroiwa): For classes with |id_|, consider removing the field and let
24 // the MPD (XML) generation functions take care of assigning an ID to each
25 // element.
26 namespace shaka {
27 
28 class AdaptationSet;
29 class MediaInfo;
30 class Period;
31 
32 namespace xml {
33 class XmlNode;
34 } // namespace xml
35 
37 class MpdBuilder {
38  public:
41  explicit MpdBuilder(const MpdOptions& mpd_options);
42  virtual ~MpdBuilder();
43 
46  void AddBaseUrl(const std::string& base_url);
47 
54  virtual Period* GetOrCreatePeriod(double start_time_in_seconds);
55 
59  // TODO(kqyang): Handle file IO in this class as in HLS media_playlist?
60  virtual bool ToString(std::string* output);
61 
67  static void MakePathsRelativeToMpd(const std::string& mpd_path,
68  MediaInfo* media_info);
69 
70  // Inject a |clock| that returns the current time.
72  void InjectClockForTesting(std::unique_ptr<base::Clock> clock) {
73  clock_ = std::move(clock);
74  }
75 
76  private:
77  MpdBuilder(const MpdBuilder&) = delete;
78  MpdBuilder& operator=(const MpdBuilder&) = delete;
79 
80  // LiveMpdBuilderTest needs to set availabilityStartTime so that the test
81  // doesn't need to depend on current time.
82  friend class LiveMpdBuilderTest;
83  template <DashProfile profile>
84  friend class MpdBuilderTest;
85 
86  // Returns the document pointer to the MPD. This must be freed by the caller
87  // using appropriate xmlDocPtr freeing function.
88  // On failure, this returns NULL.
89  xmlDocPtr GenerateMpd();
90 
91  // Set MPD attributes common to all profiles. Uses non-zero |mpd_options_| to
92  // set attributes for the MPD.
93  void AddCommonMpdInfo(xml::XmlNode* mpd_node);
94 
95  // Adds 'static' MPD attributes and elements to |mpd_node|. This assumes that
96  // the first child element is a Period element.
97  void AddStaticMpdInfo(xml::XmlNode* mpd_node);
98 
99  // Same as AddStaticMpdInfo() but for 'dynamic' MPDs.
100  void AddDynamicMpdInfo(xml::XmlNode* mpd_node);
101 
102  // Add UTCTiming element if utc timing is provided.
103  void AddUtcTiming(xml::XmlNode* mpd_node);
104 
105  float GetStaticMpdDuration();
106 
107  // Set MPD attributes for dynamic profile MPD. Uses non-zero |mpd_options_| as
108  // well as various calculations to set attributes for the MPD.
109  void SetDynamicMpdAttributes(xml::XmlNode* mpd_node);
110 
111  // Gets the earliest, normalized segment timestamp. Returns true if
112  // successful, false otherwise.
113  bool GetEarliestTimestamp(double* timestamp_seconds);
114 
115  // Update Period durations and presentation timestamps.
116  void UpdatePeriodDurationAndPresentationTimestamp();
117 
118  MpdOptions mpd_options_;
119  std::list<std::unique_ptr<Period>> periods_;
120 
121  std::list<std::string> base_urls_;
122  std::string availability_start_time_;
123 
124  uint32_t period_counter_ = 0;
125  uint32_t representation_counter_ = 0;
126 
127  // By default, this returns the current time. This can be injected for
128  // testing.
129  std::unique_ptr<base::Clock> clock_;
130 };
131 
132 } // namespace shaka
133 
134 #endif // MPD_BASE_MPD_BUILDER_H_
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:37
- -
All the methods that are virtual are virtual for mocking.
-
Defines Mpd Options.
Definition: mpd_options.h:25
-
void InjectClockForTesting(std::unique_ptr< base::Clock > clock)
This is for testing.
Definition: mpd_builder.h:72
- +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
10 
+
11 #ifndef MPD_BASE_MPD_BUILDER_H_
+
12 #define MPD_BASE_MPD_BUILDER_H_
+
13 
+
14 #include <libxml/tree.h>
+
15 
+
16 #include <list>
+
17 #include <memory>
+
18 #include <string>
+
19 
+
20 #include "packager/base/compiler_specific.h"
+
21 #include "packager/base/optional.h"
+
22 #include "packager/base/time/clock.h"
+
23 #include "packager/mpd/base/mpd_options.h"
+
24 #include "packager/mpd/base/xml/xml_node.h"
+
25 
+
26 // TODO(rkuroiwa): For classes with |id_|, consider removing the field and let
+
27 // the MPD (XML) generation functions take care of assigning an ID to each
+
28 // element.
+
29 namespace shaka {
+
30 
+
31 class AdaptationSet;
+
32 class MediaInfo;
+
33 class Period;
+
34 
+
36 class MpdBuilder {
+
37  public:
+
40  explicit MpdBuilder(const MpdOptions& mpd_options);
+
41  virtual ~MpdBuilder();
+
42 
+
45  void AddBaseUrl(const std::string& base_url);
+
46 
+
53  virtual Period* GetOrCreatePeriod(double start_time_in_seconds);
+
54 
+
58  // TODO(kqyang): Handle file IO in this class as in HLS media_playlist?
+
59  virtual bool ToString(std::string* output) WARN_UNUSED_RESULT;
+
60 
+
66  static void MakePathsRelativeToMpd(const std::string& mpd_path,
+
67  MediaInfo* media_info);
+
68 
+
69  // Inject a |clock| that returns the current time.
+
71  void InjectClockForTesting(std::unique_ptr<base::Clock> clock) {
+
72  clock_ = std::move(clock);
+
73  }
+
74 
+
75  private:
+
76  MpdBuilder(const MpdBuilder&) = delete;
+
77  MpdBuilder& operator=(const MpdBuilder&) = delete;
+
78 
+
79  // LiveMpdBuilderTest needs to set availabilityStartTime so that the test
+
80  // doesn't need to depend on current time.
+
81  friend class LiveMpdBuilderTest;
+
82  template <DashProfile profile>
+
83  friend class MpdBuilderTest;
+
84 
+
85  // Returns the document pointer to the MPD. This must be freed by the caller
+
86  // using appropriate xmlDocPtr freeing function.
+
87  // On failure, this returns NULL.
+
88  base::Optional<xml::XmlNode> GenerateMpd();
+
89 
+
90  // Set MPD attributes common to all profiles. Uses non-zero |mpd_options_| to
+
91  // set attributes for the MPD.
+
92  bool AddCommonMpdInfo(xml::XmlNode* mpd_node) WARN_UNUSED_RESULT;
+
93 
+
94  // Adds 'static' MPD attributes and elements to |mpd_node|. This assumes that
+
95  // the first child element is a Period element.
+
96  bool AddStaticMpdInfo(xml::XmlNode* mpd_node) WARN_UNUSED_RESULT;
+
97 
+
98  // Same as AddStaticMpdInfo() but for 'dynamic' MPDs.
+
99  bool AddDynamicMpdInfo(xml::XmlNode* mpd_node) WARN_UNUSED_RESULT;
+
100 
+
101  // Add UTCTiming element if utc timing is provided.
+
102  bool AddUtcTiming(xml::XmlNode* mpd_node) WARN_UNUSED_RESULT;
+
103 
+
104  float GetStaticMpdDuration();
+
105 
+
106  // Set MPD attributes for dynamic profile MPD. Uses non-zero |mpd_options_| as
+
107  // well as various calculations to set attributes for the MPD.
+
108  void SetDynamicMpdAttributes(xml::XmlNode* mpd_node);
+
109 
+
110  // Gets the earliest, normalized segment timestamp. Returns true if
+
111  // successful, false otherwise.
+
112  bool GetEarliestTimestamp(double* timestamp_seconds) WARN_UNUSED_RESULT;
+
113 
+
114  // Update Period durations and presentation timestamps.
+
115  void UpdatePeriodDurationAndPresentationTimestamp();
+
116 
+
117  MpdOptions mpd_options_;
+
118  std::list<std::unique_ptr<Period>> periods_;
+
119 
+
120  std::list<std::string> base_urls_;
+
121  std::string availability_start_time_;
+
122 
+
123  uint32_t period_counter_ = 0;
+
124  uint32_t representation_counter_ = 0;
+
125 
+
126  // By default, this returns the current time. This can be injected for
+
127  // testing.
+
128  std::unique_ptr<base::Clock> clock_;
+
129 };
+
130 
+
131 } // namespace shaka
+
132 
+
133 #endif // MPD_BASE_MPD_BUILDER_H_
+
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:36
+
virtual bool ToString(std::string *output) WARN_UNUSED_RESULT
Definition: mpd_builder.cc:159
+
static void MakePathsRelativeToMpd(const std::string &mpd_path, MediaInfo *media_info)
Definition: mpd_builder.cc:415
+
void InjectClockForTesting(std::unique_ptr< base::Clock > clock)
This is for testing.
Definition: mpd_builder.h:71
+
MpdBuilder(const MpdOptions &mpd_options)
Definition: mpd_builder.cc:136
+
void AddBaseUrl(const std::string &base_url)
Definition: mpd_builder.cc:141
+
virtual Period * GetOrCreatePeriod(double start_time_in_seconds)
Definition: mpd_builder.cc:145
+ + +
All the methods that are virtual are virtual for mocking.
+
Defines Mpd Options.
Definition: mpd_options.h:25
diff --git a/docs/d6/da4/classshaka_1_1media_1_1AVCDecoderConfigurationRecord-members.html b/docs/d6/da4/classshaka_1_1media_1_1AVCDecoderConfigurationRecord-members.html index 29f9ca5ed7..652d67245c 100644 --- a/docs/d6/da4/classshaka_1_1media_1_1AVCDecoderConfigurationRecord-members.html +++ b/docs/d6/da4/classshaka_1_1media_1_1AVCDecoderConfigurationRecord-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
AddNalu(const Nalu &nalu)shaka::media::DecoderConfigurationRecordprotected avc_level() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline AVCDecoderConfigurationRecord() (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecord - coded_height() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline - coded_width() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline - data() constshaka::media::DecoderConfigurationRecordinlineprotected - data_size() constshaka::media::DecoderConfigurationRecordinlineprotected - DecoderConfigurationRecord() (defined in shaka::media::DecoderConfigurationRecord)shaka::media::DecoderConfigurationRecordprotected - GetCodecString(FourCC codec_fourcc) constshaka::media::AVCDecoderConfigurationRecord - GetCodecString(FourCC codec_fourcc, uint8_t profile_indication, uint8_t profile_compatibility, uint8_t avc_level)shaka::media::AVCDecoderConfigurationRecordstatic - nalu(size_t i) constshaka::media::DecoderConfigurationRecordinline - nalu_count() constshaka::media::DecoderConfigurationRecordinline - nalu_length_size() constshaka::media::DecoderConfigurationRecordinline - Parse(const std::vector< uint8_t > &data)shaka::media::DecoderConfigurationRecordinline - Parse(const uint8_t *data, size_t data_size)shaka::media::DecoderConfigurationRecord - pixel_height() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline - pixel_width() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline - profile_compatibility() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline - profile_indication() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline - set_nalu_length_size(uint8_t nalu_length_size)shaka::media::DecoderConfigurationRecordinlineprotected - set_transfer_characteristics(uint8_t transfer_characteristics)shaka::media::DecoderConfigurationRecordinlineprotected - transfer_characteristics() constshaka::media::DecoderConfigurationRecordinline - version() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline - ~AVCDecoderConfigurationRecord() override (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecord - ~DecoderConfigurationRecord() (defined in shaka::media::DecoderConfigurationRecord)shaka::media::DecoderConfigurationRecordvirtual + bit_depth_chroma_minus8() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + bit_depth_luma_minus8() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + chroma_format() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + coded_height() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + coded_width() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + data() constshaka::media::DecoderConfigurationRecordinlineprotected + data_size() constshaka::media::DecoderConfigurationRecordinlineprotected + DecoderConfigurationRecord() (defined in shaka::media::DecoderConfigurationRecord)shaka::media::DecoderConfigurationRecordprotected + GetCodecString(FourCC codec_fourcc) constshaka::media::AVCDecoderConfigurationRecord + GetCodecString(FourCC codec_fourcc, uint8_t profile_indication, uint8_t profile_compatibility, uint8_t avc_level)shaka::media::AVCDecoderConfigurationRecordstatic + nalu(size_t i) constshaka::media::DecoderConfigurationRecordinline + nalu_count() constshaka::media::DecoderConfigurationRecordinline + nalu_length_size() constshaka::media::DecoderConfigurationRecordinline + Parse(const std::vector< uint8_t > &data)shaka::media::DecoderConfigurationRecordinline + Parse(const uint8_t *data, size_t data_size)shaka::media::DecoderConfigurationRecord + pixel_height() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + pixel_width() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + profile_compatibility() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + profile_indication() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + set_nalu_length_size(uint8_t nalu_length_size)shaka::media::DecoderConfigurationRecordinlineprotected + set_transfer_characteristics(uint8_t transfer_characteristics)shaka::media::DecoderConfigurationRecordinlineprotected + transfer_characteristics() constshaka::media::DecoderConfigurationRecordinline + version() const (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecordinline + ~AVCDecoderConfigurationRecord() override (defined in shaka::media::AVCDecoderConfigurationRecord)shaka::media::AVCDecoderConfigurationRecord + ~DecoderConfigurationRecord() (defined in shaka::media::DecoderConfigurationRecord)shaka::media::DecoderConfigurationRecordvirtual
diff --git a/docs/d6/da6/structshaka_1_1media_1_1H265SliceHeader_1_1LongTermPicsInfo-members.html b/docs/d6/da6/structshaka_1_1media_1_1H265SliceHeader_1_1LongTermPicsInfo-members.html index 5ff09db7f0..79960e0f8e 100644 --- a/docs/d6/da6/structshaka_1_1media_1_1H265SliceHeader_1_1LongTermPicsInfo-members.html +++ b/docs/d6/da6/structshaka_1_1media_1_1H265SliceHeader_1_1LongTermPicsInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/da9/classshaka_1_1media_1_1BitReader.html b/docs/d6/da9/classshaka_1_1media_1_1BitReader.html index b52104dd11..77079fc41c 100644 --- a/docs/d6/da9/classshaka_1_1media_1_1BitReader.html +++ b/docs/d6/da9/classshaka_1_1media_1_1BitReader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::BitReader Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
ReadBits (size_t   size_t bit_position () const   +const uint8_t * current_byte_ptr () const + 

Detailed Description

A class to read bit streams.

@@ -128,7 +133,7 @@ bool ReadBits (size_t
-

Initialize the BitReader object to read a data buffer.

Parameters
+

Initialize the BitReader object to read a data buffer.

Parameters
@@ -195,6 +200,34 @@ bool 
datapoints to the beginning of the buffer.
sizeis the buffer size in bytes.
ReadBits (size_t

Definition at line 89 of file bit_reader.h.

+ + + +

◆ current_byte_ptr()

+ +
+
+ + + + + +
+ + + + + + + +
const uint8_t* shaka::media::BitReader::current_byte_ptr () const
+
+inline
+
+
Returns
A pointer to the current byte.
+ +

Definition at line 97 of file bit_reader.h.

+
@@ -372,9 +405,7 @@ template<typename T > diff --git a/docs/d6/daa/structshaka_1_1media_1_1mp4_1_1VTTCueBox.html b/docs/d6/daa/structshaka_1_1media_1_1mp4_1_1VTTCueBox.html index d9ea12842a..9e341af620 100644 --- a/docs/d6/daa/structshaka_1_1media_1_1mp4_1_1VTTCueBox.html +++ b/docs/d6/daa/structshaka_1_1media_1_1mp4_1_1VTTCueBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::VTTCueBox Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -124,7 +127,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 844 of file box_definitions.h.

+

Definition at line 862 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -152,7 +155,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2845 of file box_definitions.cc.

+

Definition at line 2949 of file box_definitions.cc.

@@ -163,9 +166,7 @@ Additional Inherited Members diff --git a/docs/d6/db0/widevine__pssh__generator_8cc_source.html b/docs/d6/db0/widevine__pssh__generator_8cc_source.html index afe14cf874..2f76b3a350 100644 --- a/docs/d6/db0/widevine__pssh__generator_8cc_source.html +++ b/docs/d6/db0/widevine__pssh__generator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/widevine_pssh_generator.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
widevine_pssh_generator.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/widevine_pssh_generator.h"
8 
9 #include "packager/media/base/protection_system_ids.h"
10 #include "packager/media/base/widevine_pssh_data.pb.h"
11 
12 namespace shaka {
13 namespace media {
14 namespace {
15 // Use version 0 for backward compatibility.
16 const uint8_t kWidevinePsshBoxVersion = 0;
17 
18 std::vector<uint8_t> StringToBytes(const std::string& string) {
19  return std::vector<uint8_t>(string.begin(), string.end());
20 }
21 } // namespace
22 
23 WidevinePsshGenerator::WidevinePsshGenerator(FourCC protection_scheme)
24  : PsshGenerator(std::vector<uint8_t>(std::begin(kWidevineSystemId),
25  std::end(kWidevineSystemId)),
26  kWidevinePsshBoxVersion),
27  protection_scheme_(protection_scheme) {}
28 
29 WidevinePsshGenerator::~WidevinePsshGenerator() {}
30 
32  return true;
33 }
34 
35 base::Optional<std::vector<uint8_t>>
36 WidevinePsshGenerator::GeneratePsshDataFromKeyIds(
37  const std::vector<std::vector<uint8_t>>& key_ids) const {
38  media::WidevinePsshData widevine_pssh_data;
39  for (const std::vector<uint8_t>& key_id : key_ids)
40  widevine_pssh_data.add_key_id(key_id.data(), key_id.size());
41  if (protection_scheme_ != FOURCC_NULL)
42  widevine_pssh_data.set_protection_scheme(protection_scheme_);
43  return StringToBytes(widevine_pssh_data.SerializeAsString());
44 }
45 
46 base::Optional<std::vector<uint8_t>>
47 WidevinePsshGenerator::GeneratePsshDataFromKeyIdAndKey(
48  const std::vector<uint8_t>& key_id,
49  const std::vector<uint8_t>& key) const {
50  NOTIMPLEMENTED();
51  return base::nullopt;
52 }
53 
54 } // namespace media
55 } // namespace shaka
STL namespace.
-
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/widevine_pssh_generator.h"
+
8 
+
9 #include "packager/media/base/protection_system_ids.h"
+
10 #include "packager/media/base/widevine_pssh_data.pb.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 namespace {
+
15 // Use version 0 for backward compatibility.
+
16 const uint8_t kWidevinePsshBoxVersion = 0;
+
17 
+
18 std::vector<uint8_t> StringToBytes(const std::string& string) {
+
19  return std::vector<uint8_t>(string.begin(), string.end());
+
20 }
+
21 } // namespace
+
22 
+
23 WidevinePsshGenerator::WidevinePsshGenerator(FourCC protection_scheme)
+
24  : PsshGenerator(std::vector<uint8_t>(std::begin(kWidevineSystemId),
+
25  std::end(kWidevineSystemId)),
+
26  kWidevinePsshBoxVersion),
+
27  protection_scheme_(protection_scheme) {}
+
28 
+
29 WidevinePsshGenerator::~WidevinePsshGenerator() {}
+
30 
+
31 bool WidevinePsshGenerator::SupportMultipleKeys() {
+
32  return true;
+
33 }
+
34 
+
35 base::Optional<std::vector<uint8_t>>
+
36 WidevinePsshGenerator::GeneratePsshDataFromKeyIds(
+
37  const std::vector<std::vector<uint8_t>>& key_ids) const {
+
38  media::WidevinePsshData widevine_pssh_data;
+
39  for (const std::vector<uint8_t>& key_id : key_ids)
+
40  widevine_pssh_data.add_key_id(key_id.data(), key_id.size());
+
41  if (protection_scheme_ != FOURCC_NULL)
+
42  widevine_pssh_data.set_protection_scheme(protection_scheme_);
+
43  return StringToBytes(widevine_pssh_data.SerializeAsString());
+
44 }
+
45 
+
46 base::Optional<std::vector<uint8_t>>
+
47 WidevinePsshGenerator::GeneratePsshDataFromKeyIdAndKey(
+
48  const std::vector<uint8_t>& key_id,
+
49  const std::vector<uint8_t>& key) const {
+
50  NOTIMPLEMENTED();
+
51  return base::nullopt;
+
52 }
+
53 
+
54 } // namespace media
+
55 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/db1/classshaka_1_1media_1_1VideoStreamInfo.html b/docs/d6/db1/classshaka_1_1media_1_1VideoStreamInfo.html index ef59aafcdb..fda3445a44 100644 --- a/docs/d6/db1/classshaka_1_1media_1_1VideoStreamInfo.html +++ b/docs/d6/db1/classshaka_1_1media_1_1VideoStreamInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::VideoStreamInfo Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
-shaka::media::StreamInfo - -
+shaka::media::StreamInfo + + @@ -501,9 +504,7 @@ void 

Public Member Functions

set_encryption_config diff --git a/docs/d6/db1/structshaka_1_1media_1_1VideoStreamInfoParameters-members.html b/docs/d6/db1/structshaka_1_1media_1_1VideoStreamInfoParameters-members.html index ed49bc1864..9b300ea4a2 100644 --- a/docs/d6/db1/structshaka_1_1media_1_1VideoStreamInfoParameters-members.html +++ b/docs/d6/db1/structshaka_1_1media_1_1VideoStreamInfoParameters-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/db8/classshaka_1_1media_1_1FileReader.html b/docs/d6/db8/classshaka_1_1media_1_1FileReader.html deleted file mode 100644 index f9cbc62856..0000000000 --- a/docs/d6/db8/classshaka_1_1media_1_1FileReader.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - -Shaka Packager SDK: shaka::media::FileReader Class Reference - - - - - - - - - -
-
- - - - - - -
-
Shaka Packager SDK -
-
-
- - - - - - - - -
-
- - -
- -
- - -
-
- -
-
shaka::media::FileReader Class Reference
-
-
- -

Class to read character-by-character from a file. - More...

- -

#include <text_readers.h>

- - - - -

-Public Member Functions

bool Next (char *out)
 
- - - -

-Static Public Member Functions

static Status Open (const std::string &filename, std::unique_ptr< FileReader > *out)
 
-

Detailed Description

-

Class to read character-by-character from a file.

- -

Definition at line 23 of file text_readers.h.

-

Member Function Documentation

- -

◆ Next()

- -
-
- - - - - - - - -
bool shaka::media::FileReader::Next (char * out)
-
-

Read the next character from the file. If there is a next character, |out| will be set and true will be returned. If there is no next character false will be returned.

- -

Definition at line 32 of file text_readers.cc.

- -
-
- -

◆ Open()

- -
-
- - - - - -
- - - - - - - - - - - - - - - - - - -
Status shaka::media::FileReader::Open (const std::string & filename,
std::unique_ptr< FileReader > * out 
)
-
-static
-
-

Create a new file reader by opening a file. If the file fails to open (in readonly mode) a non-ok status will be returned. If the file successfully opens, |out| will be set to a new FileReader and an ok status will be returned.

- -

Definition at line 15 of file text_readers.cc.

- -
-
-
The documentation for this class was generated from the following files: -
- - - - diff --git a/docs/d6/dbe/mp4__output__params_8h_source.html b/docs/d6/dbe/mp4__output__params_8h_source.html index f823bebdc5..c3260307c7 100644 --- a/docs/d6/dbe/mp4__output__params_8h_source.html +++ b/docs/d6/dbe/mp4__output__params_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/public/mp4_output_params.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
mp4_output_params.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_
8 #define PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_
9 
10 namespace shaka {
11 
23 };
24 
25 } // namespace shaka
26 
27 #endif // PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_
-
All the methods that are virtual are virtual for mocking.
-
MP4 (ISO-BMFF) output related parameters.
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_
+
8 #define PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_
+
9 
+
10 namespace shaka {
+
11 
+ + + +
23 };
+
24 
+
25 } // namespace shaka
+
26 
+
27 #endif // PACKAGER_MEDIA_PUBLIC_MP4_OUTPUT_PARAMS_H_
+
All the methods that are virtual are virtual for mocking.
+
MP4 (ISO-BMFF) output related parameters.
+ +
diff --git a/docs/d6/dc0/classshaka_1_1hls_1_1HlsEntry-members.html b/docs/d6/dc0/classshaka_1_1hls_1_1HlsEntry-members.html index ad996b928c..6fffe71348 100644 --- a/docs/d6/dc0/classshaka_1_1hls_1_1HlsEntry-members.html +++ b/docs/d6/dc0/classshaka_1_1hls_1_1HlsEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/dc6/structshaka_1_1media_1_1mp2t_1_1EsParserH26x_1_1VideoSliceInfo-members.html b/docs/d6/dc6/structshaka_1_1media_1_1mp2t_1_1EsParserH26x_1_1VideoSliceInfo-members.html index 192e214702..2f75d8ccd4 100644 --- a/docs/d6/dc6/structshaka_1_1media_1_1mp2t_1_1EsParserH26x_1_1VideoSliceInfo-members.html +++ b/docs/d6/dc6/structshaka_1_1media_1_1mp2t_1_1EsParserH26x_1_1VideoSliceInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/dc7/classshaka_1_1media_1_1mp2t_1_1EsParserH26x-members.html b/docs/d6/dc7/classshaka_1_1media_1_1mp2t_1_1EsParserH26x-members.html index a55878b823..baa4f181ab 100644 --- a/docs/d6/dc7/classshaka_1_1media_1_1mp2t_1_1EsParserH26x-members.html +++ b/docs/d6/dc7/classshaka_1_1media_1_1mp2t_1_1EsParserH26x-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
This is the complete list of members for shaka::media::mp2t::EsParserH26x, including all inherited members.

- - - - - - - - - - + + + + + + + + + + +
EmitSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
EsParserH26x(Nalu::CodecType type, std::unique_ptr< H26xByteToUnitStreamConverter > stream_converter, uint32_t pid, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
Flush() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
Reset() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
stream_converter() const (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xinlineprotected
~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
~EsParserH26x() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
EmitTextSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
EsParserH26x(Nalu::CodecType type, std::unique_ptr< H26xByteToUnitStreamConverter > stream_converter, uint32_t pid, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
Flush() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
Reset() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
stream_converter() const (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xinlineprotected
~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
~EsParserH26x() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
diff --git a/docs/d6/dc8/mkv__writer_8cc_source.html b/docs/d6/dc8/mkv__writer_8cc_source.html index 22caf314ea..bc6d857e7f 100644 --- a/docs/d6/dc8/mkv__writer_8cc_source.html +++ b/docs/d6/dc8/mkv__writer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/mkv_writer.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
mkv_writer.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webm/mkv_writer.h"
8 
9 namespace shaka {
10 namespace media {
11 
12 MkvWriter::MkvWriter() : position_(0) {}
13 
14 MkvWriter::~MkvWriter() {}
15 
16 Status MkvWriter::Open(const std::string& name) {
17  DCHECK(!file_);
18  file_.reset(File::Open(name.c_str(), "w"));
19  if (!file_)
20  return Status(error::FILE_FAILURE, "Unable to open file for writing.");
21 
22  // This may produce an error message; however there isn't a seekable method
23  // on File.
24  seekable_ = file_->Seek(0);
25  position_ = 0;
26  return Status::OK;
27 }
28 
30  const std::string file_name = file_->file_name();
31  if (!file_.release()->Close()) {
32  return Status(
33  error::FILE_FAILURE,
34  "Cannot close file " + file_name +
35  ", possibly file permission issue or running out of disk space.");
36  }
37  return Status::OK;
38 }
39 
40 mkvmuxer::int32 MkvWriter::Write(const void* buf, mkvmuxer::uint32 len) {
41  DCHECK(file_);
42 
43  const char* data = reinterpret_cast<const char*>(buf);
44  int64_t total_bytes_written = 0;
45  while (total_bytes_written < len) {
46  const int64_t written =
47  file_->Write(data + total_bytes_written, len - total_bytes_written);
48  if (written < 0)
49  return written;
50 
51  total_bytes_written += written;
52  }
53 
54  DCHECK_EQ(total_bytes_written, len);
55  position_ += len;
56  return 0;
57 }
58 
59 int64_t MkvWriter::WriteFromFile(File* source) {
60  return WriteFromFile(source, kWholeFile);
61 }
62 
63 int64_t MkvWriter::WriteFromFile(File* source, int64_t max_copy) {
64  DCHECK(file_);
65 
66  const int64_t size = File::CopyFile(source, file_.get(), max_copy);
67  if (size < 0)
68  return size;
69 
70  position_ += size;
71  return size;
72 }
73 
74 mkvmuxer::int64 MkvWriter::Position() const {
75  return position_;
76 }
77 
78 mkvmuxer::int32 MkvWriter::Position(mkvmuxer::int64 position) {
79  DCHECK(file_);
80 
81  if (file_->Seek(position)) {
82  position_ = position;
83  return 0;
84  } else {
85  return -1;
86  }
87 }
88 
89 bool MkvWriter::Seekable() const {
90  return seekable_;
91 }
92 
93 void MkvWriter::ElementStartNotify(mkvmuxer::uint64 element_id,
94  mkvmuxer::int64 position) {}
95 
96 } // namespace media
97 } // namespace shaka
Define an abstract file interface.
Definition: file.h:26
-
static int64_t CopyFile(File *source, File *destination)
Definition: file.cc:316
-
All the methods that are virtual are virtual for mocking.
-
int64_t WriteFromFile(File *source)
Definition: mkv_writer.cc:59
- -
void ElementStartNotify(mkvmuxer::uint64 element_id, mkvmuxer::int64 position) override
Definition: mkv_writer.cc:93
-
mkvmuxer::int64 Position() const override
Definition: mkv_writer.cc:74
-
virtual bool Open()=0
Internal open. Should not be used directly.
-
bool Seekable() const override
Definition: mkv_writer.cc:89
-
Status Open(const std::string &name)
Definition: mkv_writer.cc:16
-
Status Close()
Closes the file. MUST call Open before calling any other methods.
Definition: mkv_writer.cc:29
-
mkvmuxer::int32 Write(const void *buf, mkvmuxer::uint32 len) override
Definition: mkv_writer.cc:40
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/webm/mkv_writer.h"
+
8 
+
9 namespace shaka {
+
10 namespace media {
+
11 
+
12 MkvWriter::MkvWriter() : position_(0) {}
+
13 
+
14 MkvWriter::~MkvWriter() {}
+
15 
+
16 Status MkvWriter::Open(const std::string& name) {
+
17  DCHECK(!file_);
+
18  file_.reset(File::Open(name.c_str(), "w"));
+
19  if (!file_)
+
20  return Status(error::FILE_FAILURE, "Unable to open file for writing.");
+
21 
+
22  // This may produce an error message; however there isn't a seekable method
+
23  // on File.
+
24  seekable_ = file_->Seek(0);
+
25  position_ = 0;
+
26  return Status::OK;
+
27 }
+
28 
+
29 Status MkvWriter::Close() {
+
30  const std::string file_name = file_->file_name();
+
31  if (!file_.release()->Close()) {
+
32  return Status(
+
33  error::FILE_FAILURE,
+
34  "Cannot close file " + file_name +
+
35  ", possibly file permission issue or running out of disk space.");
+
36  }
+
37  return Status::OK;
+
38 }
+
39 
+
40 mkvmuxer::int32 MkvWriter::Write(const void* buf, mkvmuxer::uint32 len) {
+
41  DCHECK(file_);
+
42 
+
43  const char* data = reinterpret_cast<const char*>(buf);
+
44  int64_t total_bytes_written = 0;
+
45  while (total_bytes_written < len) {
+
46  const int64_t written =
+
47  file_->Write(data + total_bytes_written, len - total_bytes_written);
+
48  if (written < 0)
+
49  return written;
+
50 
+
51  total_bytes_written += written;
+
52  }
+
53 
+
54  DCHECK_EQ(total_bytes_written, len);
+
55  position_ += len;
+
56  return 0;
+
57 }
+
58 
+
59 int64_t MkvWriter::WriteFromFile(File* source) {
+
60  return WriteFromFile(source, kWholeFile);
+
61 }
+
62 
+
63 int64_t MkvWriter::WriteFromFile(File* source, int64_t max_copy) {
+
64  DCHECK(file_);
+
65 
+
66  const int64_t size = File::CopyFile(source, file_.get(), max_copy);
+
67  if (size < 0)
+
68  return size;
+
69 
+
70  position_ += size;
+
71  return size;
+
72 }
+
73 
+
74 mkvmuxer::int64 MkvWriter::Position() const {
+
75  return position_;
+
76 }
+
77 
+
78 mkvmuxer::int32 MkvWriter::Position(mkvmuxer::int64 position) {
+
79  DCHECK(file_);
+
80 
+
81  if (file_->Seek(position)) {
+
82  position_ = position;
+
83  return 0;
+
84  } else {
+
85  return -1;
+
86  }
+
87 }
+
88 
+
89 bool MkvWriter::Seekable() const {
+
90  return seekable_;
+
91 }
+
92 
+
93 void MkvWriter::ElementStartNotify(mkvmuxer::uint64 element_id,
+
94  mkvmuxer::int64 position) {}
+
95 
+
96 } // namespace media
+
97 } // namespace shaka
+
Define an abstract file interface.
Definition: file.h:27
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/dcb/structshaka_1_1media_1_1mp4_1_1SampleEncryptionEntry.html b/docs/d6/dcb/structshaka_1_1media_1_1mp4_1_1SampleEncryptionEntry.html index a66dfacad6..dab1b9ba55 100644 --- a/docs/d6/dcb/structshaka_1_1media_1_1mp4_1_1SampleEncryptionEntry.html +++ b/docs/d6/dcb/structshaka_1_1media_1_1mp4_1_1SampleEncryptionEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleEncryptionEntry Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */

Detailed Description

-

Definition at line 78 of file box_definitions.h.

+

Definition at line 79 of file box_definitions.h.

Member Function Documentation

◆ ComputeSize()

@@ -111,7 +114,7 @@ std::vector<
Returns
The size of the structure in bytes when it is stored.
-

Definition at line 292 of file box_definitions.cc.

+

Definition at line 304 of file box_definitions.cc.

@@ -131,7 +134,7 @@ std::vector<
Returns
The accumulated size of subsamples. Returns 0 if there is no subsamples.
-

Definition at line 302 of file box_definitions.cc.

+

Definition at line 314 of file box_definitions.cc.

@@ -176,7 +179,7 @@ std::vector<
Returns
true on success, false otherwise.
-

Definition at line 267 of file box_definitions.cc.

+

Definition at line 279 of file box_definitions.cc.

@@ -221,7 +224,7 @@ std::vector<
Returns
true on success, false otherwise.
-

Definition at line 243 of file box_definitions.cc.

+

Definition at line 255 of file box_definitions.cc.

@@ -232,9 +235,7 @@ std::vector< diff --git a/docs/d6/dcc/classshaka_1_1media_1_1VP9Parser-members.html b/docs/d6/dcc/classshaka_1_1media_1_1VP9Parser-members.html index 46c424c9cd..0b94377dd0 100644 --- a/docs/d6/dcc/classshaka_1_1media_1_1VP9Parser-members.html +++ b/docs/d6/dcc/classshaka_1_1media_1_1VP9Parser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/dce/structshaka_1_1media_1_1mp4_1_1SegmentReference-members.html b/docs/d6/dce/structshaka_1_1media_1_1mp4_1_1SegmentReference-members.html index 114919580f..139263f7c4 100644 --- a/docs/d6/dce/structshaka_1_1media_1_1mp4_1_1SegmentReference-members.html +++ b/docs/d6/dce/structshaka_1_1media_1_1mp4_1_1SegmentReference-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/dd0/structshaka_1_1media_1_1H264SEIMessage.html b/docs/d6/dd0/structshaka_1_1media_1_1H264SEIMessage.html index 117c3f94af..6349edbbe3 100644 --- a/docs/d6/dd0/structshaka_1_1media_1_1H264SEIMessage.html +++ b/docs/d6/dd0/structshaka_1_1media_1_1H264SEIMessage.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264SEIMessage Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Detailed Description

-

Definition at line 232 of file h264_parser.h.

-

The documentation for this struct was generated from the following files:

The documentation for this struct was generated from the following file: diff --git a/docs/d6/dd5/classshaka_1_1media_1_1DecoderSpecificInfoDescriptor-members.html b/docs/d6/dd5/classshaka_1_1media_1_1DecoderSpecificInfoDescriptor-members.html index aa87bc1596..e7e28ccccd 100644 --- a/docs/d6/dd5/classshaka_1_1media_1_1DecoderSpecificInfoDescriptor-members.html +++ b/docs/d6/dd5/classshaka_1_1media_1_1DecoderSpecificInfoDescriptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/dd7/structshaka_1_1Mp4OutputParams-members.html b/docs/d6/dd7/structshaka_1_1Mp4OutputParams-members.html index 04155a31b3..be8ed604b0 100644 --- a/docs/d6/dd7/structshaka_1_1Mp4OutputParams-members.html +++ b/docs/d6/dd7/structshaka_1_1Mp4OutputParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/dda/classshaka_1_1media_1_1WebVttFileBuffer.html b/docs/d6/dda/classshaka_1_1media_1_1WebVttFileBuffer.html index 415d7c0217..b98d8c9004 100644 --- a/docs/d6/dda/classshaka_1_1media_1_1WebVttFileBuffer.html +++ b/docs/d6/dda/classshaka_1_1media_1_1WebVttFileBuffer.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebVttFileBuffer Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
Reset () void Append (const TextSample &sample)   - -bool WriteTo (File *file) -  + +bool WriteTo (File *file, uint64_t *size) +  size_t sample_count () const   @@ -98,9 +101,7 @@ size_t sample_count ()
diff --git a/docs/d6/dde/structshaka_1_1media_1_1H265VuiParameters-members.html b/docs/d6/dde/structshaka_1_1media_1_1H265VuiParameters-members.html index 3ac79f15f7..64b708ebdf 100644 --- a/docs/d6/dde/structshaka_1_1media_1_1H265VuiParameters-members.html +++ b/docs/d6/dde/structshaka_1_1media_1_1H265VuiParameters-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/de2/structshaka_1_1media_1_1mp4_1_1KeyFrameInfo.html b/docs/d6/de2/structshaka_1_1media_1_1mp4_1_1KeyFrameInfo.html index 9b9b7e9b81..047f3d4b74 100644 --- a/docs/d6/de2/structshaka_1_1media_1_1mp4_1_1KeyFrameInfo.html +++ b/docs/d6/de2/structshaka_1_1media_1_1mp4_1_1KeyFrameInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::KeyFrameInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
size diff --git a/docs/d6/de4/structshaka_1_1media_1_1mp4_1_1CueTimeBox-members.html b/docs/d6/de4/structshaka_1_1media_1_1mp4_1_1CueTimeBox-members.html index 50cfc2b274..c33b5be0c0 100644 --- a/docs/d6/de4/structshaka_1_1media_1_1mp4_1_1CueTimeBox-members.html +++ b/docs/d6/de4/structshaka_1_1media_1_1mp4_1_1CueTimeBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d6/de7/structshaka_1_1media_1_1VPxFrameInfo-members.html b/docs/d6/de7/structshaka_1_1media_1_1VPxFrameInfo-members.html index d45dd4131d..9ab79e15a2 100644 --- a/docs/d6/de7/structshaka_1_1media_1_1VPxFrameInfo-members.html +++ b/docs/d6/de7/structshaka_1_1media_1_1VPxFrameInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/de8/local__file_8cc_source.html b/docs/d6/de8/local__file_8cc_source.html index f18c92fd02..0529f42b00 100644 --- a/docs/d6/de8/local__file_8cc_source.html +++ b/docs/d6/de8/local__file_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/local_file.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
local_file.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/file/local_file.h"
8 
9 #include <stdio.h>
10 #if defined(OS_WIN)
11 #include <windows.h>
12 #else
13 #include <sys/stat.h>
14 #endif // defined(OS_WIN)
15 #include "packager/base/files/file_path.h"
16 #include "packager/base/files/file_util.h"
17 #include "packager/base/logging.h"
18 
19 namespace shaka {
20 namespace {
21 
22 // Check if the directory |path| exists. Returns false if it does not exist or
23 // it is not a directory. On non-Windows, |mode| will be filled with the file
24 // permission bits on success.
25 bool DirectoryExists(const base::FilePath& path, int* mode) {
26 #if defined(OS_WIN)
27  DWORD fileattr = GetFileAttributes(path.value().c_str());
28  if (fileattr != INVALID_FILE_ATTRIBUTES)
29  return (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0;
30 #else
31  struct stat info;
32  if (stat(path.value().c_str(), &info) != 0)
33  return false;
34  if (S_ISDIR(info.st_mode)) {
35  const int FILE_PERMISSION_MASK = S_IRWXU | S_IRWXG | S_IRWXO;
36  if (mode)
37  *mode = info.st_mode & FILE_PERMISSION_MASK;
38  return true;
39  }
40 #endif
41  return false;
42 }
43 
44 // Create all the inexistent directories in the path. Returns true on success or
45 // if the directory already exists.
46 bool CreateDirectory(const base::FilePath& full_path) {
47  std::vector<base::FilePath> subpaths;
48 
49  // Collect a list of all parent directories.
50  base::FilePath last_path = full_path;
51  subpaths.push_back(full_path);
52  for (base::FilePath path = full_path.DirName();
53  path.value() != last_path.value(); path = path.DirName()) {
54  subpaths.push_back(path);
55  last_path = path;
56  }
57 
58  // For non-Windows only. File permission for the new directories.
59  // The file permission will be inherited from the last existing directory in
60  // the file path. If none of the directory exists in the path, it is set to
61  // 0755 by default.
62  int mode = 0755;
63 
64  // Iterate through the parents and create the missing ones.
65  for (auto i = subpaths.rbegin(); i != subpaths.rend(); ++i) {
66  if (DirectoryExists(*i, &mode)) {
67  continue;
68  }
69 #if defined(OS_WIN)
70  if (::CreateDirectory(i->value().c_str(), nullptr)) {
71  continue;
72  }
73 #else
74  if (mkdir(i->value().c_str(), mode) == 0) {
75  continue;
76  }
77 #endif
78 
79  // Mkdir failed, but it might have failed with EEXIST, or some other error
80  // due to the the directory appearing out of thin air. This can occur if
81  // two processes are trying to create the same file system tree at the same
82  // time. Check to see if it exists and make sure it is a directory.
83  const auto saved_error_code = ::logging::GetLastSystemErrorCode();
84  if (!DirectoryExists(*i, nullptr)) {
85  LOG(ERROR) << "Failed to create directory " << i->value().c_str()
86  << " ErrorCode " << saved_error_code;
87  return false;
88  }
89  }
90  return true;
91 }
92 
93 } // namespace
94 
95 // Always open files in binary mode.
96 const char kAdditionalFileMode[] = "b";
97 
98 LocalFile::LocalFile(const char* file_name, const char* mode)
99  : File(file_name), file_mode_(mode), internal_file_(NULL) {
100  if (file_mode_.find(kAdditionalFileMode) == std::string::npos)
101  file_mode_ += kAdditionalFileMode;
102 }
103 
105  bool result = true;
106  if (internal_file_) {
107  result = base::CloseFile(internal_file_);
108  internal_file_ = NULL;
109  }
110  delete this;
111  return result;
112 }
113 
114 int64_t LocalFile::Read(void* buffer, uint64_t length) {
115  DCHECK(buffer != NULL);
116  DCHECK(internal_file_ != NULL);
117  size_t bytes_read = fread(buffer, sizeof(char), length, internal_file_);
118  VLOG(2) << "Read " << length << " return " << bytes_read << " error "
119  << ferror(internal_file_);
120  if (bytes_read == 0 && ferror(internal_file_) != 0) {
121  return -1;
122  }
123  return bytes_read;
124 }
125 
126 int64_t LocalFile::Write(const void* buffer, uint64_t length) {
127  DCHECK(buffer != NULL);
128  DCHECK(internal_file_ != NULL);
129  size_t bytes_written = fwrite(buffer, sizeof(char), length, internal_file_);
130  VLOG(2) << "Write " << length << " return " << bytes_written << " error "
131  << ferror(internal_file_);
132  if (bytes_written == 0 && ferror(internal_file_) != 0) {
133  return -1;
134  }
135  return bytes_written;
136 }
137 
138 int64_t LocalFile::Size() {
139  DCHECK(internal_file_ != NULL);
140 
141  // Flush any buffered data, so we get the true file size.
142  if (!Flush()) {
143  LOG(ERROR) << "Cannot flush file.";
144  return -1;
145  }
146 
147  int64_t file_size;
148  if (!base::GetFileSize(base::FilePath::FromUTF8Unsafe(file_name()),
149  &file_size)) {
150  LOG(ERROR) << "Cannot get file size.";
151  return -1;
152  }
153  return file_size;
154 }
155 
157  DCHECK(internal_file_ != NULL);
158  return ((fflush(internal_file_) == 0) && !ferror(internal_file_));
159 }
160 
161 bool LocalFile::Seek(uint64_t position) {
162 #if defined(OS_WIN)
163  return _fseeki64(internal_file_, static_cast<__int64>(position), SEEK_SET) ==
164  0;
165 #else
166  return fseeko(internal_file_, position, SEEK_SET) >= 0;
167 #endif // !defined(OS_WIN)
168 }
169 
170 bool LocalFile::Tell(uint64_t* position) {
171 #if defined(OS_WIN)
172  __int64 offset = _ftelli64(internal_file_);
173 #else
174  off_t offset = ftello(internal_file_);
175 #endif // !defined(OS_WIN)
176  if (offset < 0)
177  return false;
178  *position = static_cast<uint64_t>(offset);
179  return true;
180 }
181 
182 LocalFile::~LocalFile() {}
183 
185  base::FilePath file_path(base::FilePath::FromUTF8Unsafe(file_name()));
186 
187  // Create upper level directories for write mode.
188  if (file_mode_.find("w") != std::string::npos) {
189  // The function returns true if the directories already exist.
190  if (!shaka::CreateDirectory(file_path.DirName())) {
191  return false;
192  }
193  }
194 
195  internal_file_ = base::OpenFile(file_path, file_mode_.c_str());
196  return (internal_file_ != NULL);
197 }
198 
199 bool LocalFile::Delete(const char* file_name) {
200  return base::DeleteFile(base::FilePath::FromUTF8Unsafe(file_name), false);
201 }
202 
203 } // namespace shaka
bool Close() override
Definition: local_file.cc:104
-
bool Seek(uint64_t position) override
Definition: local_file.cc:161
-
bool Flush() override
Definition: local_file.cc:156
-
Define an abstract file interface.
Definition: file.h:26
-
const std::string & file_name() const
Definition: file.h:94
-
All the methods that are virtual are virtual for mocking.
-
int64_t Size() override
Definition: local_file.cc:138
-
static bool Delete(const char *file_name)
Definition: local_file.cc:199
-
int64_t Read(void *buffer, uint64_t length) override
Definition: local_file.cc:114
-
bool Open() override
Internal open. Should not be used directly.
Definition: local_file.cc:184
-
int64_t Write(const void *buffer, uint64_t length) override
Definition: local_file.cc:126
-
bool Tell(uint64_t *position) override
Definition: local_file.cc:170
-
LocalFile(const char *file_name, const char *mode)
Definition: local_file.cc:98
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/file/local_file.h"
+
8 
+
9 #include <stdio.h>
+
10 #if defined(OS_WIN)
+
11 #include <windows.h>
+
12 #else
+
13 #include <sys/stat.h>
+
14 #endif // defined(OS_WIN)
+
15 #include "packager/base/files/file_path.h"
+
16 #include "packager/base/files/file_util.h"
+
17 #include "packager/base/logging.h"
+
18 
+
19 namespace shaka {
+
20 namespace {
+
21 
+
22 // Check if the directory |path| exists. Returns false if it does not exist or
+
23 // it is not a directory. On non-Windows, |mode| will be filled with the file
+
24 // permission bits on success.
+
25 bool DirectoryExists(const base::FilePath& path, int* mode) {
+
26 #if defined(OS_WIN)
+
27  DWORD fileattr = GetFileAttributes(path.value().c_str());
+
28  if (fileattr != INVALID_FILE_ATTRIBUTES)
+
29  return (fileattr & FILE_ATTRIBUTE_DIRECTORY) != 0;
+
30 #else
+
31  struct stat info;
+
32  if (stat(path.value().c_str(), &info) != 0)
+
33  return false;
+
34  if (S_ISDIR(info.st_mode)) {
+
35  const int FILE_PERMISSION_MASK = S_IRWXU | S_IRWXG | S_IRWXO;
+
36  if (mode)
+
37  *mode = info.st_mode & FILE_PERMISSION_MASK;
+
38  return true;
+
39  }
+
40 #endif
+
41  return false;
+
42 }
+
43 
+
44 // Create all the inexistent directories in the path. Returns true on success or
+
45 // if the directory already exists.
+
46 bool CreateDirectory(const base::FilePath& full_path) {
+
47  std::vector<base::FilePath> subpaths;
+
48 
+
49  // Collect a list of all parent directories.
+
50  base::FilePath last_path = full_path;
+
51  subpaths.push_back(full_path);
+
52  for (base::FilePath path = full_path.DirName();
+
53  path.value() != last_path.value(); path = path.DirName()) {
+
54  subpaths.push_back(path);
+
55  last_path = path;
+
56  }
+
57 
+
58  // For non-Windows only. File permission for the new directories.
+
59  // The file permission will be inherited from the last existing directory in
+
60  // the file path. If none of the directory exists in the path, it is set to
+
61  // 0755 by default.
+
62  int mode = 0755;
+
63 
+
64  // Iterate through the parents and create the missing ones.
+
65  for (auto i = subpaths.rbegin(); i != subpaths.rend(); ++i) {
+
66  if (DirectoryExists(*i, &mode)) {
+
67  continue;
+
68  }
+
69 #if defined(OS_WIN)
+
70  if (::CreateDirectory(i->value().c_str(), nullptr)) {
+
71  continue;
+
72  }
+
73 #else
+
74  if (mkdir(i->value().c_str(), mode) == 0) {
+
75  continue;
+
76  }
+
77 #endif
+
78 
+
79  // Mkdir failed, but it might have failed with EEXIST, or some other error
+
80  // due to the the directory appearing out of thin air. This can occur if
+
81  // two processes are trying to create the same file system tree at the same
+
82  // time. Check to see if it exists and make sure it is a directory.
+
83  const auto saved_error_code = ::logging::GetLastSystemErrorCode();
+
84  if (!DirectoryExists(*i, nullptr)) {
+
85  LOG(ERROR) << "Failed to create directory " << i->value().c_str()
+
86  << " ErrorCode " << saved_error_code;
+
87  return false;
+
88  }
+
89  }
+
90  return true;
+
91 }
+
92 
+
93 } // namespace
+
94 
+
95 // Always open files in binary mode.
+
96 const char kAdditionalFileMode[] = "b";
+
97 
+
98 LocalFile::LocalFile(const char* file_name, const char* mode)
+
99  : File(file_name), file_mode_(mode), internal_file_(NULL) {
+
100  if (file_mode_.find(kAdditionalFileMode) == std::string::npos)
+
101  file_mode_ += kAdditionalFileMode;
+
102 }
+
103 
+ +
105  bool result = true;
+
106  if (internal_file_) {
+
107  result = base::CloseFile(internal_file_);
+
108  internal_file_ = NULL;
+
109  }
+
110  delete this;
+
111  return result;
+
112 }
+
113 
+
114 int64_t LocalFile::Read(void* buffer, uint64_t length) {
+
115  DCHECK(buffer != NULL);
+
116  DCHECK(internal_file_ != NULL);
+
117  size_t bytes_read = fread(buffer, sizeof(char), length, internal_file_);
+
118  VLOG(2) << "Read " << length << " return " << bytes_read << " error "
+
119  << ferror(internal_file_);
+
120  if (bytes_read == 0 && ferror(internal_file_) != 0) {
+
121  return -1;
+
122  }
+
123  return bytes_read;
+
124 }
+
125 
+
126 int64_t LocalFile::Write(const void* buffer, uint64_t length) {
+
127  DCHECK(buffer != NULL);
+
128  DCHECK(internal_file_ != NULL);
+
129  size_t bytes_written = fwrite(buffer, sizeof(char), length, internal_file_);
+
130  VLOG(2) << "Write " << length << " return " << bytes_written << " error "
+
131  << ferror(internal_file_);
+
132  if (bytes_written == 0 && ferror(internal_file_) != 0) {
+
133  return -1;
+
134  }
+
135  return bytes_written;
+
136 }
+
137 
+
138 int64_t LocalFile::Size() {
+
139  DCHECK(internal_file_ != NULL);
+
140 
+
141  // Flush any buffered data, so we get the true file size.
+
142  if (!Flush()) {
+
143  LOG(ERROR) << "Cannot flush file.";
+
144  return -1;
+
145  }
+
146 
+
147  int64_t file_size;
+
148  if (!base::GetFileSize(base::FilePath::FromUTF8Unsafe(file_name()),
+
149  &file_size)) {
+
150  LOG(ERROR) << "Cannot get file size.";
+
151  return -1;
+
152  }
+
153  return file_size;
+
154 }
+
155 
+ +
157  DCHECK(internal_file_ != NULL);
+
158  return ((fflush(internal_file_) == 0) && !ferror(internal_file_));
+
159 }
+
160 
+
161 bool LocalFile::Seek(uint64_t position) {
+
162 #if defined(OS_WIN)
+
163  return _fseeki64(internal_file_, static_cast<__int64>(position), SEEK_SET) ==
+
164  0;
+
165 #else
+
166  return fseeko(internal_file_, position, SEEK_SET) >= 0;
+
167 #endif // !defined(OS_WIN)
+
168 }
+
169 
+
170 bool LocalFile::Tell(uint64_t* position) {
+
171 #if defined(OS_WIN)
+
172  __int64 offset = _ftelli64(internal_file_);
+
173 #else
+
174  off_t offset = ftello(internal_file_);
+
175 #endif // !defined(OS_WIN)
+
176  if (offset < 0)
+
177  return false;
+
178  *position = static_cast<uint64_t>(offset);
+
179  return true;
+
180 }
+
181 
+
182 LocalFile::~LocalFile() {}
+
183 
+ +
185  base::FilePath file_path(base::FilePath::FromUTF8Unsafe(file_name()));
+
186 
+
187  // Create upper level directories for write mode.
+
188  if (file_mode_.find("w") != std::string::npos) {
+
189  // The function returns true if the directories already exist.
+
190  if (!shaka::CreateDirectory(file_path.DirName())) {
+
191  return false;
+
192  }
+
193  }
+
194 
+
195  internal_file_ = base::OpenFile(file_path, file_mode_.c_str());
+
196  return (internal_file_ != NULL);
+
197 }
+
198 
+
199 bool LocalFile::Delete(const char* file_name) {
+
200  return base::DeleteFile(base::FilePath::FromUTF8Unsafe(file_name), false);
+
201 }
+
202 
+
203 } // namespace shaka
+
Define an abstract file interface.
Definition: file.h:27
+
const std::string & file_name() const
Definition: file.h:95
+
bool Flush() override
Definition: local_file.cc:156
+
bool Seek(uint64_t position) override
Definition: local_file.cc:161
+
int64_t Read(void *buffer, uint64_t length) override
Definition: local_file.cc:114
+
LocalFile(const char *file_name, const char *mode)
Definition: local_file.cc:98
+
bool Close() override
Definition: local_file.cc:104
+
static bool Delete(const char *file_name)
Definition: local_file.cc:199
+
bool Open() override
Internal open. Should not be used directly.
Definition: local_file.cc:184
+
int64_t Size() override
Definition: local_file.cc:138
+
int64_t Write(const void *buffer, uint64_t length) override
Definition: local_file.cc:126
+
bool Tell(uint64_t *position) override
Definition: local_file.cc:170
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/de8/network__util_8h_source.html b/docs/d6/de8/network__util_8h_source.html index 1da26f2fe6..9417970e61 100644 --- a/docs/d6/de8/network__util_8h_source.html +++ b/docs/d6/de8/network__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/network_util.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
network_util.h
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_BASE_NETWORK_UTIL_H_
6 #define PACKAGER_MEDIA_BASE_NETWORK_UTIL_H_
7 
8 #include <stdint.h>
9 
10 namespace shaka {
11 namespace media {
12 
13 uint32_t ntohlFromBuffer(const unsigned char* buf);
14 uint16_t ntohsFromBuffer(const unsigned char* buf);
15 uint64_t ntohllFromBuffer(const unsigned char* buf);
16 
17 } // namespace media
18 } // namespace shaka
19 
20 #endif // PACKAGER_MEDIA_BASE_NETWORK_UTIL_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_BASE_NETWORK_UTIL_H_
+
6 #define PACKAGER_MEDIA_BASE_NETWORK_UTIL_H_
+
7 
+
8 #include <stdint.h>
+
9 
+
10 namespace shaka {
+
11 namespace media {
+
12 
+
13 uint32_t ntohlFromBuffer(const unsigned char* buf);
+
14 uint16_t ntohsFromBuffer(const unsigned char* buf);
+
15 uint64_t ntohllFromBuffer(const unsigned char* buf);
+
16 
+
17 } // namespace media
+
18 } // namespace shaka
+
19 
+
20 #endif // PACKAGER_MEDIA_BASE_NETWORK_UTIL_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/de9/ts__segmenter_8cc_source.html b/docs/d6/de9/ts__segmenter_8cc_source.html index 77e96ad30e..e82083d00d 100644 --- a/docs/d6/de9/ts__segmenter_8cc_source.html +++ b/docs/d6/de9/ts__segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_segmenter.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
ts_segmenter.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp2t/ts_segmenter.h"
8 
9 #include <memory>
10 
11 #include "packager/media/base/audio_stream_info.h"
12 #include "packager/media/base/muxer_util.h"
13 #include "packager/media/base/video_stream_info.h"
14 #include "packager/media/event/muxer_listener.h"
15 #include "packager/media/formats/mp2t/pes_packet.h"
16 #include "packager/media/formats/mp2t/program_map_table_writer.h"
17 #include "packager/status.h"
18 
19 namespace shaka {
20 namespace media {
21 namespace mp2t {
22 
23 namespace {
24 const double kTsTimescale = 90000;
25 
26 bool IsAudioCodec(Codec codec) {
27  return codec >= kCodecAudio && codec < kCodecAudioMaxPlusOne;
28 }
29 
30 bool IsVideoCodec(Codec codec) {
31  return codec >= kCodecVideo && codec < kCodecVideoMaxPlusOne;
32 }
33 
34 } // namespace
35 
37  : muxer_options_(options),
38  listener_(listener),
39  transport_stream_timestamp_offset_(
40  options.transport_stream_timestamp_offset_ms * kTsTimescale / 1000),
41  pes_packet_generator_(
42  new PesPacketGenerator(transport_stream_timestamp_offset_)) {}
43 
44 TsSegmenter::~TsSegmenter() {}
45 
47  if (muxer_options_.segment_template.empty())
48  return Status(error::MUXER_FAILURE, "Segment template not specified.");
49  if (!pes_packet_generator_->Initialize(stream_info)) {
50  return Status(error::MUXER_FAILURE,
51  "Failed to initialize PesPacketGenerator.");
52  }
53 
54  const StreamType stream_type = stream_info.stream_type();
55  if (stream_type != StreamType::kStreamVideo &&
56  stream_type != StreamType::kStreamAudio) {
57  LOG(ERROR) << "TsWriter cannot handle stream type " << stream_type
58  << " yet.";
59  return Status(error::MUXER_FAILURE, "Unsupported stream type.");
60  }
61 
62  codec_ = stream_info.codec();
63  if (stream_type == StreamType::kStreamAudio)
64  audio_codec_config_ = stream_info.codec_config();
65 
66  timescale_scale_ = kTsTimescale / stream_info.time_scale();
67  return Status::OK;
68 }
69 
71  return Status::OK;
72 }
73 
75  if (!ts_writer_) {
76  std::unique_ptr<ProgramMapTableWriter> pmt_writer;
77  if (codec_ == kCodecAC3) {
78  // https://goo.gl/N7Tvqi MPEG-2 Stream Encryption Format for HTTP Live
79  // Streaming 2.3.2.2 AC-3 Setup: For AC-3, the setup_data in the
80  // audio_setup_information is the first 10 bytes of the audio data (the
81  // syncframe()).
82  // For unencrypted AC3, the setup_data is not used, so what is in there
83  // does not matter.
84  const size_t kSetupDataSize = 10u;
85  if (sample.data_size() < kSetupDataSize) {
86  LOG(ERROR) << "Sample is too small for AC3: " << sample.data_size();
87  return Status(error::MUXER_FAILURE, "Sample is too small for AC3.");
88  }
89  const std::vector<uint8_t> setup_data(sample.data(),
90  sample.data() + kSetupDataSize);
91  pmt_writer.reset(new AudioProgramMapTableWriter(codec_, setup_data));
92  } else if (IsAudioCodec(codec_)) {
93  pmt_writer.reset(
94  new AudioProgramMapTableWriter(codec_, audio_codec_config_));
95  } else {
96  DCHECK(IsVideoCodec(codec_));
97  pmt_writer.reset(new VideoProgramMapTableWriter(codec_));
98  }
99  ts_writer_.reset(new TsWriter(std::move(pmt_writer)));
100  }
101 
102  if (sample.is_encrypted())
103  ts_writer_->SignalEncrypted();
104 
105  if (!ts_writer_file_opened_ && !sample.is_key_frame())
106  LOG(WARNING) << "A segment will start with a non key frame.";
107 
108  if (!pes_packet_generator_->PushSample(sample)) {
109  return Status(error::MUXER_FAILURE,
110  "Failed to add sample to PesPacketGenerator.");
111  }
112  return WritePesPacketsToFile();
113 }
114 
115 void TsSegmenter::InjectTsWriterForTesting(std::unique_ptr<TsWriter> writer) {
116  ts_writer_ = std::move(writer);
117 }
118 
120  std::unique_ptr<PesPacketGenerator> generator) {
121  pes_packet_generator_ = std::move(generator);
122 }
123 
125  ts_writer_file_opened_ = value;
126 }
127 
128 Status TsSegmenter::OpenNewSegmentIfClosed(uint32_t next_pts) {
129  if (ts_writer_file_opened_)
130  return Status::OK;
131  const std::string segment_name =
132  GetSegmentName(muxer_options_.segment_template, next_pts,
133  segment_number_++, muxer_options_.bandwidth);
134  if (!ts_writer_->NewSegment(segment_name))
135  return Status(error::MUXER_FAILURE, "Failed to initilize TsPacketWriter.");
136  current_segment_path_ = segment_name;
137  ts_writer_file_opened_ = true;
138  return Status::OK;
139 }
140 
141 Status TsSegmenter::WritePesPacketsToFile() {
142  while (pes_packet_generator_->NumberOfReadyPesPackets() > 0u) {
143  std::unique_ptr<PesPacket> pes_packet =
144  pes_packet_generator_->GetNextPesPacket();
145 
146  Status status = OpenNewSegmentIfClosed(pes_packet->pts());
147  if (!status.ok())
148  return status;
149 
150  if (listener_ && IsVideoCodec(codec_) && pes_packet->is_key_frame()) {
151  base::Optional<uint64_t> start_pos = ts_writer_->GetFilePosition();
152 
153  const int64_t timestamp = pes_packet->pts();
154  if (!ts_writer_->AddPesPacket(std::move(pes_packet)))
155  return Status(error::MUXER_FAILURE, "Failed to add PES packet.");
156 
157  base::Optional<uint64_t> end_pos = ts_writer_->GetFilePosition();
158  if (!start_pos || !end_pos) {
159  return Status(error::MUXER_FAILURE,
160  "Failed to get file position in WritePesPacketsToFile.");
161  }
162  listener_->OnKeyFrame(timestamp, *start_pos, *end_pos - *start_pos);
163  } else {
164  if (!ts_writer_->AddPesPacket(std::move(pes_packet)))
165  return Status(error::MUXER_FAILURE, "Failed to add PES packet.");
166  }
167  }
168  return Status::OK;
169 }
170 
171 Status TsSegmenter::FinalizeSegment(uint64_t start_timestamp,
172  uint64_t duration) {
173  if (!pes_packet_generator_->Flush()) {
174  return Status(error::MUXER_FAILURE,
175  "Failed to flush PesPacketGenerator.");
176  }
177  Status status = WritePesPacketsToFile();
178  if (!status.ok())
179  return status;
180 
181  // This method may be called from Finalize() so ts_writer_file_opened_ could
182  // be false.
183  if (ts_writer_file_opened_) {
184  if (!ts_writer_->FinalizeSegment()) {
185  return Status(error::MUXER_FAILURE, "Failed to finalize TsWriter.");
186  }
187  if (listener_) {
188  const int64_t file_size =
189  File::GetFileSize(current_segment_path_.c_str());
190  listener_->OnNewSegment(current_segment_path_,
191  start_timestamp * timescale_scale_ +
192  transport_stream_timestamp_offset_,
193  duration * timescale_scale_, file_size);
194  }
195  ts_writer_file_opened_ = false;
196  }
197  current_segment_path_.clear();
198  return Status::OK;
199 }
200 
201 } // namespace mp2t
202 } // namespace media
203 } // namespace shaka
-
Abstract class holds stream information.
Definition: stream_info.h:62
-
ProgramMapTableWriter for video codecs.
- -
Status Initialize(const StreamInfo &stream_info)
Definition: ts_segmenter.cc:46
-
All the methods that are virtual are virtual for mocking.
-
static int64_t GetFileSize(const char *file_name)
Definition: file.cc:207
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
-
Status AddSample(const MediaSample &sample)
Definition: ts_segmenter.cc:74
- -
ProgramMapTableWriter for video codecs.
-
TsSegmenter(const MuxerOptions &options, MuxerListener *listener)
Definition: ts_segmenter.cc:36
-
void InjectPesPacketGeneratorForTesting(std::unique_ptr< PesPacketGenerator > generator)
Only for testing.
-
void SetTsWriterFileOpenedForTesting(bool value)
Only for testing.
-
void InjectTsWriterForTesting(std::unique_ptr< TsWriter > writer)
Only for testing.
-
virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
-
Class to hold a media sample.
Definition: media_sample.h:22
- -
Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration)
- - -
virtual void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
- +
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp2t/ts_segmenter.h"
+
8 
+
9 #include <memory>
+
10 
+
11 #include "packager/media/base/audio_stream_info.h"
+
12 #include "packager/media/base/muxer_util.h"
+
13 #include "packager/media/base/video_stream_info.h"
+
14 #include "packager/media/event/muxer_listener.h"
+
15 #include "packager/media/formats/mp2t/pes_packet.h"
+
16 #include "packager/media/formats/mp2t/program_map_table_writer.h"
+
17 #include "packager/status.h"
+
18 #include "packager/status_macros.h"
+
19 
+
20 namespace shaka {
+
21 namespace media {
+
22 namespace mp2t {
+
23 
+
24 namespace {
+
25 const double kTsTimescale = 90000;
+
26 
+
27 bool IsAudioCodec(Codec codec) {
+
28  return codec >= kCodecAudio && codec < kCodecAudioMaxPlusOne;
+
29 }
+
30 
+
31 bool IsVideoCodec(Codec codec) {
+
32  return codec >= kCodecVideo && codec < kCodecVideoMaxPlusOne;
+
33 }
+
34 
+
35 } // namespace
+
36 
+ +
38  : muxer_options_(options),
+
39  listener_(listener),
+
40  transport_stream_timestamp_offset_(
+
41  options.transport_stream_timestamp_offset_ms * kTsTimescale / 1000),
+
42  pes_packet_generator_(
+
43  new PesPacketGenerator(transport_stream_timestamp_offset_)) {}
+
44 
+
45 TsSegmenter::~TsSegmenter() {}
+
46 
+ +
48  if (muxer_options_.segment_template.empty())
+
49  return Status(error::MUXER_FAILURE, "Segment template not specified.");
+
50  if (!pes_packet_generator_->Initialize(stream_info)) {
+
51  return Status(error::MUXER_FAILURE,
+
52  "Failed to initialize PesPacketGenerator.");
+
53  }
+
54 
+
55  const StreamType stream_type = stream_info.stream_type();
+
56  if (stream_type != StreamType::kStreamVideo &&
+
57  stream_type != StreamType::kStreamAudio) {
+
58  LOG(ERROR) << "TsWriter cannot handle stream type " << stream_type
+
59  << " yet.";
+
60  return Status(error::MUXER_FAILURE, "Unsupported stream type.");
+
61  }
+
62 
+
63  codec_ = stream_info.codec();
+
64  if (stream_type == StreamType::kStreamAudio)
+
65  audio_codec_config_ = stream_info.codec_config();
+
66 
+
67  timescale_scale_ = kTsTimescale / stream_info.time_scale();
+
68  return Status::OK;
+
69 }
+
70 
+ +
72  return Status::OK;
+
73 }
+
74 
+ +
76  if (!ts_writer_) {
+
77  std::unique_ptr<ProgramMapTableWriter> pmt_writer;
+
78  if (codec_ == kCodecAC3) {
+
79  // https://goo.gl/N7Tvqi MPEG-2 Stream Encryption Format for HTTP Live
+
80  // Streaming 2.3.2.2 AC-3 Setup: For AC-3, the setup_data in the
+
81  // audio_setup_information is the first 10 bytes of the audio data (the
+
82  // syncframe()).
+
83  // For unencrypted AC3, the setup_data is not used, so what is in there
+
84  // does not matter.
+
85  const size_t kSetupDataSize = 10u;
+
86  if (sample.data_size() < kSetupDataSize) {
+
87  LOG(ERROR) << "Sample is too small for AC3: " << sample.data_size();
+
88  return Status(error::MUXER_FAILURE, "Sample is too small for AC3.");
+
89  }
+
90  const std::vector<uint8_t> setup_data(sample.data(),
+
91  sample.data() + kSetupDataSize);
+
92  pmt_writer.reset(new AudioProgramMapTableWriter(codec_, setup_data));
+
93  } else if (IsAudioCodec(codec_)) {
+
94  pmt_writer.reset(
+
95  new AudioProgramMapTableWriter(codec_, audio_codec_config_));
+
96  } else {
+
97  DCHECK(IsVideoCodec(codec_));
+
98  pmt_writer.reset(new VideoProgramMapTableWriter(codec_));
+
99  }
+
100  ts_writer_.reset(new TsWriter(std::move(pmt_writer)));
+
101  }
+
102 
+
103  if (sample.is_encrypted())
+
104  ts_writer_->SignalEncrypted();
+
105 
+
106  if (!segment_started_ && !sample.is_key_frame())
+
107  LOG(WARNING) << "A segment will start with a non key frame.";
+
108 
+
109  if (!pes_packet_generator_->PushSample(sample)) {
+
110  return Status(error::MUXER_FAILURE,
+
111  "Failed to add sample to PesPacketGenerator.");
+
112  }
+
113  return WritePesPackets();
+
114 }
+
115 
+
116 void TsSegmenter::InjectTsWriterForTesting(std::unique_ptr<TsWriter> writer) {
+
117  ts_writer_ = std::move(writer);
+
118 }
+
119 
+ +
121  std::unique_ptr<PesPacketGenerator> generator) {
+
122  pes_packet_generator_ = std::move(generator);
+
123 }
+
124 
+ +
126  segment_started_ = value;
+
127 }
+
128 
+
129 Status TsSegmenter::StartSegmentIfNeeded(int64_t next_pts) {
+
130  if (segment_started_)
+
131  return Status::OK;
+
132  segment_start_timestamp_ = next_pts;
+
133  if (!ts_writer_->NewSegment(&segment_buffer_))
+
134  return Status(error::MUXER_FAILURE, "Failed to initialize new segment.");
+
135  segment_started_ = true;
+
136  return Status::OK;
+
137 }
+
138 
+
139 Status TsSegmenter::WritePesPackets() {
+
140  while (pes_packet_generator_->NumberOfReadyPesPackets() > 0u) {
+
141  std::unique_ptr<PesPacket> pes_packet =
+
142  pes_packet_generator_->GetNextPesPacket();
+
143 
+
144  Status status = StartSegmentIfNeeded(pes_packet->pts());
+
145  if (!status.ok())
+
146  return status;
+
147 
+
148  if (listener_ && IsVideoCodec(codec_) && pes_packet->is_key_frame()) {
+
149 
+
150  uint64_t start_pos = segment_buffer_.Size();
+
151  const int64_t timestamp = pes_packet->pts();
+
152  if (!ts_writer_->AddPesPacket(std::move(pes_packet), &segment_buffer_))
+
153  return Status(error::MUXER_FAILURE, "Failed to add PES packet.");
+
154 
+
155  uint64_t end_pos = segment_buffer_.Size();
+
156 
+
157  listener_->OnKeyFrame(timestamp, start_pos, end_pos - start_pos);
+
158  } else {
+
159  if (!ts_writer_->AddPesPacket(std::move(pes_packet), &segment_buffer_))
+
160  return Status(error::MUXER_FAILURE, "Failed to add PES packet.");
+
161  }
+
162  }
+
163  return Status::OK;
+
164 }
+
165 
+
166 Status TsSegmenter::FinalizeSegment(uint64_t start_timestamp,
+
167  uint64_t duration) {
+
168  if (!pes_packet_generator_->Flush()) {
+
169  return Status(error::MUXER_FAILURE, "Failed to flush PesPacketGenerator.");
+
170  }
+
171  Status status = WritePesPackets();
+
172  if (!status.ok())
+
173  return status;
+
174 
+
175  // This method may be called from Finalize() so segment_started_ could
+
176  // be false.
+
177  if (!segment_started_)
+
178  return Status::OK;
+
179  std::string segment_path =
+
180  GetSegmentName(muxer_options_.segment_template, segment_start_timestamp_,
+
181  segment_number_++, muxer_options_.bandwidth);
+
182 
+
183  const int64_t file_size = segment_buffer_.Size();
+
184  std::unique_ptr<File, FileCloser> segment_file;
+
185  segment_file.reset(File::Open(segment_path.c_str(), "w"));
+
186  if (!segment_file) {
+
187  return Status(error::FILE_FAILURE,
+
188  "Cannot open file for write " + segment_path);
+
189  }
+
190 
+
191  RETURN_IF_ERROR(segment_buffer_.WriteToFile(segment_file.get()));
+
192 
+
193  if (!segment_file.release()->Close()) {
+
194  return Status(
+
195  error::FILE_FAILURE,
+
196  "Cannot close file " + segment_path +
+
197  ", possibly file permission issue or running out of disk space.");
+
198  }
+
199 
+
200  if (listener_) {
+
201  listener_->OnNewSegment(segment_path,
+
202  start_timestamp * timescale_scale_ +
+
203  transport_stream_timestamp_offset_,
+
204  duration * timescale_scale_, file_size);
+
205  }
+
206  segment_started_ = false;
+
207 
+
208  return Status::OK;
+
209 }
+
210 
+
211 } // namespace mp2t
+
212 } // namespace media
+
213 } // namespace shaka
+
virtual bool Open()=0
Internal open. Should not be used directly.
+ +
Status WriteToFile(File *file)
+
Class to hold a media sample.
Definition: media_sample.h:22
+ +
virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
+
virtual void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
ProgramMapTableWriter for video codecs.
+ +
void SetSegmentStartedForTesting(bool value)
Only for testing.
+
Status Initialize(const StreamInfo &stream_info)
Definition: ts_segmenter.cc:47
+
void InjectPesPacketGeneratorForTesting(std::unique_ptr< PesPacketGenerator > generator)
Only for testing.
+
Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration)
+ +
Status AddSample(const MediaSample &sample)
Definition: ts_segmenter.cc:75
+
void InjectTsWriterForTesting(std::unique_ptr< TsWriter > writer)
Only for testing.
+
TsSegmenter(const MuxerOptions &options, MuxerListener *listener)
Definition: ts_segmenter.cc:37
+ +
ProgramMapTableWriter for video codecs.
+
All the methods that are virtual are virtual for mocking.
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+ +
diff --git a/docs/d6/ded/ts__packet_8h_source.html b/docs/d6/ded/ts__packet_8h_source.html index 6289cc5390..c1c34a750e 100644 --- a/docs/d6/ded/ts__packet_8h_source.html +++ b/docs/d6/ded/ts__packet_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_packet.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
ts_packet.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_PACKET_H_
6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_PACKET_H_
7 
8 #include <stdint.h>
9 
10 #include "packager/base/macros.h"
11 
12 namespace shaka {
13 namespace media {
14 
15 class BitReader;
16 
17 namespace mp2t {
18 
19 class TsPacket {
20  public:
21  static const int kPacketSize = 188;
22 
23  // Return the number of bytes to discard
24  // to be synchronized on a TS syncword.
25  static int Sync(const uint8_t* buf, int size);
26 
27  // Parse a TS packet.
28  // Return a TsPacket only when parsing was successful.
29  // Return NULL otherwise.
30  static TsPacket* Parse(const uint8_t* buf, int size);
31 
32  ~TsPacket();
33 
34  // TS header accessors.
35  bool payload_unit_start_indicator() const {
36  return payload_unit_start_indicator_;
37  }
38  int pid() const { return pid_; }
39  int continuity_counter() const { return continuity_counter_; }
40  bool discontinuity_indicator() const { return discontinuity_indicator_; }
41  bool random_access_indicator() const { return random_access_indicator_; }
42 
43  // Return the offset and the size of the payload.
44  const uint8_t* payload() const { return payload_; }
45  int payload_size() const { return payload_size_; }
46 
47  private:
48  TsPacket();
49 
50  // Parse an Mpeg2 TS header.
51  // The buffer size should be at least |kPacketSize|
52  bool ParseHeader(const uint8_t* buf);
53  bool ParseAdaptationField(BitReader* bit_reader,
54  int adaptation_field_length);
55 
56  // Size of the payload.
57  const uint8_t* payload_;
58  int payload_size_;
59 
60  // TS header.
61  bool payload_unit_start_indicator_;
62  int pid_;
63  int continuity_counter_;
64 
65  // Params from the adaptation field.
66  bool discontinuity_indicator_;
67  bool random_access_indicator_;
68 
69  DISALLOW_COPY_AND_ASSIGN(TsPacket);
70 };
71 
72 } // namespace mp2t
73 } // namespace media
74 } // namespace shaka
75 
76 #endif
77 
-
A class to read bit streams.
Definition: bit_reader.h:17
-
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_PACKET_H_
+
6 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_PACKET_H_
+
7 
+
8 #include <stdint.h>
+
9 
+
10 #include "packager/base/macros.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+
15 class BitReader;
+
16 
+
17 namespace mp2t {
+
18 
+
19 class TsPacket {
+
20  public:
+
21  static const int kPacketSize = 188;
+
22 
+
23  // Return the number of bytes to discard
+
24  // to be synchronized on a TS syncword.
+
25  static int Sync(const uint8_t* buf, int size);
+
26 
+
27  // Parse a TS packet.
+
28  // Return a TsPacket only when parsing was successful.
+
29  // Return NULL otherwise.
+
30  static TsPacket* Parse(const uint8_t* buf, int size);
+
31 
+
32  ~TsPacket();
+
33 
+
34  // TS header accessors.
+
35  bool payload_unit_start_indicator() const {
+
36  return payload_unit_start_indicator_;
+
37  }
+
38  int pid() const { return pid_; }
+
39  int continuity_counter() const { return continuity_counter_; }
+
40  bool discontinuity_indicator() const { return discontinuity_indicator_; }
+
41  bool random_access_indicator() const { return random_access_indicator_; }
+
42 
+
43  // Return the offset and the size of the payload.
+
44  const uint8_t* payload() const { return payload_; }
+
45  int payload_size() const { return payload_size_; }
+
46 
+
47  private:
+
48  TsPacket();
+
49 
+
50  // Parse an Mpeg2 TS header.
+
51  // The buffer size should be at least |kPacketSize|
+
52  bool ParseHeader(const uint8_t* buf);
+
53  bool ParseAdaptationField(BitReader* bit_reader,
+
54  int adaptation_field_length);
+
55 
+
56  // Size of the payload.
+
57  const uint8_t* payload_;
+
58  int payload_size_;
+
59 
+
60  // TS header.
+
61  bool payload_unit_start_indicator_;
+
62  int pid_;
+
63  int continuity_counter_;
+
64 
+
65  // Params from the adaptation field.
+
66  bool discontinuity_indicator_;
+
67  bool random_access_indicator_;
+
68 
+
69  DISALLOW_COPY_AND_ASSIGN(TsPacket);
+
70 };
+
71 
+
72 } // namespace mp2t
+
73 } // namespace media
+
74 } // namespace shaka
+
75 
+
76 #endif
+
77 
+
A class to read bit streams.
Definition: bit_reader.h:17
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d6/def/sync__sample__iterator_8cc_source.html b/docs/d6/def/sync__sample__iterator_8cc_source.html index 444d630bc3..6e6c5b8790 100644 --- a/docs/d6/def/sync__sample__iterator_8cc_source.html +++ b/docs/d6/def/sync__sample__iterator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/sync_sample_iterator.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
sync_sample_iterator.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp4/sync_sample_iterator.h"
8 
9 #include <algorithm>
10 
11 namespace shaka {
12 namespace media {
13 namespace mp4 {
14 
16  : sample_number_(1),
17  sync_sample_vector_(sync_sample.sample_number),
18  iterator_(sync_sample_vector_.begin()),
19  is_empty_(iterator_ == sync_sample_vector_.end()) {}
20 SyncSampleIterator::~SyncSampleIterator() {}
21 
23  if (iterator_ != sync_sample_vector_.end() && sample_number_ == *iterator_)
24  ++iterator_;
25  ++sample_number_;
26  return true;
27 }
28 
30  // If the sync sample box is not present, every sample is a sync sample.
31  if (is_empty_)
32  return true;
33  return iterator_ != sync_sample_vector_.end() && sample_number_ == *iterator_;
34 }
35 
36 bool SyncSampleIterator::IsSyncSample(uint32_t sample) const {
37  // If the sync sample box is not present, every sample is a sync sample.
38  if (is_empty_)
39  return true;
40  return std::binary_search(
41  sync_sample_vector_.begin(), sync_sample_vector_.end(), sample);
42 }
43 
44 } // namespace mp4
45 } // namespace media
46 } // namespace shaka
-
SyncSampleIterator(const SyncSample &sync_sample)
Create a new SyncSampleIterator from sync sample box.
- -
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp4/sync_sample_iterator.h"
+
8 
+
9 #include <algorithm>
+
10 
+
11 namespace shaka {
+
12 namespace media {
+
13 namespace mp4 {
+
14 
+ +
16  : sample_number_(1),
+
17  sync_sample_vector_(sync_sample.sample_number),
+
18  iterator_(sync_sample_vector_.begin()),
+
19  is_empty_(iterator_ == sync_sample_vector_.end()) {}
+
20 SyncSampleIterator::~SyncSampleIterator() {}
+
21 
+ +
23  if (iterator_ != sync_sample_vector_.end() && sample_number_ == *iterator_)
+
24  ++iterator_;
+
25  ++sample_number_;
+
26  return true;
+
27 }
+
28 
+ +
30  // If the sync sample box is not present, every sample is a sync sample.
+
31  if (is_empty_)
+
32  return true;
+
33  return iterator_ != sync_sample_vector_.end() && sample_number_ == *iterator_;
+
34 }
+
35 
+
36 bool SyncSampleIterator::IsSyncSample(uint32_t sample) const {
+
37  // If the sync sample box is not present, every sample is a sync sample.
+
38  if (is_empty_)
+
39  return true;
+
40  return std::binary_search(
+
41  sync_sample_vector_.begin(), sync_sample_vector_.end(), sample);
+
42 }
+
43 
+
44 } // namespace mp4
+
45 } // namespace media
+
46 } // namespace shaka
+ + +
SyncSampleIterator(const SyncSample &sync_sample)
Create a new SyncSampleIterator from sync sample box.
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d6/df8/structshaka_1_1StreamDescriptor-members.html b/docs/d6/df8/structshaka_1_1StreamDescriptor-members.html index 6a1ca84226..8fee7bc9b2 100644 --- a/docs/d6/df8/structshaka_1_1StreamDescriptor-members.html +++ b/docs/d6/df8/structshaka_1_1StreamDescriptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */ diff --git a/docs/d6/dfd/classshaka_1_1media_1_1mp2t_1_1AudioHeader-members.html b/docs/d6/dfd/classshaka_1_1media_1_1mp2t_1_1AudioHeader-members.html index 62d2d71a1a..44bcb8031f 100644 --- a/docs/d6/dfd/classshaka_1_1media_1_1mp2t_1_1AudioHeader-members.html +++ b/docs/d6/dfd/classshaka_1_1media_1_1mp2t_1_1AudioHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d6/dff/classshaka_1_1media_1_1Nalu.html b/docs/d6/dff/classshaka_1_1media_1_1Nalu.html index ac71bcb587..5f1b15116c 100644 --- a/docs/d6/dff/classshaka_1_1media_1_1Nalu.html +++ b/docs/d6/dff/classshaka_1_1media_1_1Nalu.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::Nalu Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Public Types

enum  H264NaluType {
-  H264_Unspecified = 0, -H264_NonIDRSlice = 1, -H264_IDRSlice = 5, -H264_SEIMessage = 6, -
-  H264_SPS = 7, -H264_PPS = 8, -H264_AUD = 9, -H264_EOSeq = 10, -
-  H264_FillerData = 12, -H264_SPSExtension = 13, -H264_PrefixNALUnit = 14, -H264_SubsetSPS = 15, -
-  H264_DepthParameterSet = 16, -H264_Reserved17 = 17, -H264_Reserved18 = 18, -H264_CodedSliceExtension = 20, -
+  H264_Unspecified = 0 +, H264_NonIDRSlice = 1 +, H264_IDRSlice = 5 +, H264_SEIMessage = 6 +,
+  H264_SPS = 7 +, H264_PPS = 8 +, H264_AUD = 9 +, H264_EOSeq = 10 +,
+  H264_FillerData = 12 +, H264_SPSExtension = 13 +, H264_PrefixNALUnit = 14 +, H264_SubsetSPS = 15 +,
+  H264_DepthParameterSet = 16 +, H264_Reserved17 = 17 +, H264_Reserved18 = 18 +, H264_CodedSliceExtension = 20 +,
  H264_Reserved22 = 22
}   enum  H265NaluType {
-  H265_TRAIL_N = 0, -H265_TRAIL_R = 1, -H265_TSA_N = 2, -H265_TSA_R = 3, -
-  H265_STSA_N = 4, -H265_STSA_R = 5, -H265_RASL_R = 9, -H265_RSV_VCL_N10 = 10, -
-  H265_RSV_VCL_R15 = 15, -H265_BLA_W_LP = 16, -H265_IDR_W_RADL = 19, -H265_IDR_N_LP = 20, -
-  H265_CRA_NUT = 21, -H265_RSV_IRAP_VCL22 = 22, -H265_RSV_IRAP_VCL23 = 23, -H265_RSV_VCL31 = 31, -
-  H265_VPS = 32, -H265_SPS = 33, -H265_PPS = 34, -H265_AUD = 35, -
-  H265_EOS = 36, -H265_EOB = 37, -H265_FD = 38, -H265_PREFIX_SEI = 39, -
-  H265_RSV_NVCL41 = 41, -H265_RSV_NVCL44 = 44, -H265_UNSPEC48 = 48, -H265_UNSPEC55 = 55 +  H265_TRAIL_N = 0 +, H265_TRAIL_R = 1 +, H265_TSA_N = 2 +, H265_TSA_R = 3 +,
+  H265_STSA_N = 4 +, H265_STSA_R = 5 +, H265_RASL_R = 9 +, H265_RSV_VCL_N10 = 10 +,
+  H265_RSV_VCL_R15 = 15 +, H265_BLA_W_LP = 16 +, H265_IDR_W_RADL = 19 +, H265_IDR_N_LP = 20 +,
+  H265_CRA_NUT = 21 +, H265_RSV_IRAP_VCL22 = 22 +, H265_RSV_IRAP_VCL23 = 23 +, H265_RSV_VCL31 = 31 +,
+  H265_VPS = 32 +, H265_SPS = 33 +, H265_PPS = 34 +, H265_AUD = 35 +,
+  H265_EOS = 36 +, H265_EOB = 37 +, H265_FD = 38 +, H265_PREFIX_SEI = 39 +,
+  H265_RSV_NVCL41 = 41 +, H265_RSV_NVCL44 = 44 +, H265_UNSPEC48 = 48 +, H265_UNSPEC55 = 55
}   -enum  CodecType { kH264, -kH265 +enum  CodecType { kH264 +, kH265 }   @@ -158,7 +161,7 @@ uint64_t  - + @@ -225,9 +228,7 @@ bool 
 
uint64_t payload_size () const
 Size of this Nalu minus header_size().
 Size of this Nalu minus header_size().
 
int ref_idc () const
can_start_access_unit diff --git a/docs/d7/d01/classshaka_1_1media_1_1MuxerFactory-members.html b/docs/d7/d01/classshaka_1_1media_1_1MuxerFactory-members.html index c56560cae2..1617357725 100644 --- a/docs/d7/d01/classshaka_1_1media_1_1MuxerFactory-members.html +++ b/docs/d7/d01/classshaka_1_1media_1_1MuxerFactory-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
CreateMuxer(MediaContainerName output_format, const StreamDescriptor &stream)shaka::media::MuxerFactory MuxerFactory(const PackagingParams &packaging_params) (defined in shaka::media::MuxerFactory)shaka::media::MuxerFactory OverrideClock(base::Clock *clock)shaka::media::MuxerFactory + SetTsStreamOffset(uint32_t offset_ms) (defined in shaka::media::MuxerFactory)shaka::media::MuxerFactoryinline
diff --git a/docs/d7/d01/structshaka_1_1media_1_1mp4_1_1SampleGroupDescription.html b/docs/d7/d01/structshaka_1_1media_1_1mp4_1_1SampleGroupDescription.html index bd8d07d1d8..645dd92669 100644 --- a/docs/d7/d01/structshaka_1_1media_1_1mp4_1_1SampleGroupDescription.html +++ b/docs/d7/d01/structshaka_1_1media_1_1mp4_1_1SampleGroupDescription.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleGroupDescription Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -131,7 +134,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 519 of file box_definitions.h.

+

Definition at line 532 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -159,7 +162,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 1016 of file box_definitions.cc.

+

Definition at line 1029 of file box_definitions.cc.

@@ -170,9 +173,7 @@ Additional Inherited Members diff --git a/docs/d7/d07/structshaka_1_1media_1_1mp4_1_1SoundMediaHeader.html b/docs/d7/d07/structshaka_1_1media_1_1mp4_1_1SoundMediaHeader.html index bdc404261c..c581f7fafd 100644 --- a/docs/d7/d07/structshaka_1_1media_1_1mp4_1_1SoundMediaHeader.html +++ b/docs/d7/d07/structshaka_1_1media_1_1mp4_1_1SoundMediaHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SoundMediaHeader Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -121,7 +124,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 587 of file box_definitions.h.

+

Definition at line 600 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -149,7 +152,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2034 of file box_definitions.cc.

+

Definition at line 2094 of file box_definitions.cc.

@@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/d7/d0b/muxer__listener__test__helper_8h_source.html b/docs/d7/d0b/muxer__listener__test__helper_8h_source.html index fc5a633ee6..346ef81d69 100644 --- a/docs/d7/d0b/muxer__listener__test__helper_8h_source.html +++ b/docs/d7/d0b/muxer__listener__test__helper_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/muxer_listener_test_helper.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
muxer_listener_test_helper.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_EVENT_MUXER_LISTENER_TEST_HELPER_H_
8 #define PACKAGER_MEDIA_EVENT_MUXER_LISTENER_TEST_HELPER_H_
9 
10 #include <stdint.h>
11 #include <vector>
12 
13 #include "packager/media/base/key_source.h"
14 #include "packager/media/base/muxer_options.h"
15 #include "packager/media/base/stream_info.h"
16 #include "packager/media/base/video_stream_info.h"
17 #include "packager/media/event/muxer_listener.h"
18 #include "packager/mpd/base/media_info.pb.h"
19 
20 namespace shaka {
21 
22 namespace media {
23 
24 const char kExpectedDefaultPsshBox[] = "expected_pssh_box";
25 const char kExpectedDefaultMediaInfo[] =
26  "video_info {\n"
27  " codec: 'avc1.010101'\n"
28  " width: 720\n"
29  " height: 480\n"
30  " time_scale: 10\n"
31  " pixel_width: 1\n"
32  " pixel_height: 1\n"
33  "}\n"
34  "init_range {\n"
35  " begin: 0\n"
36  " end: 120\n"
37  "}\n"
38  "index_range {\n"
39  " begin: 121\n"
40  " end: 221\n"
41  "}\n"
42  "reference_time_scale: 1000\n"
43  "container_type: 1\n"
44  "media_file_name: 'test_output_file_name.mp4'\n"
45  "media_duration_seconds: 10.5\n";
46 const uint32_t kDefaultReferenceTimeScale = 1000u;
47 
48 // Struct that gets passed for to CreateVideoStreamInfo() to create a
49 // StreamInfo instance. Useful for generating multiple VideoStreamInfo with
50 // slightly different parameters.
54  int track_id;
55  uint32_t time_scale;
56  uint64_t duration;
57  Codec codec;
58  std::string codec_string;
59  std::string language;
60  uint16_t width;
61  uint16_t height;
62  uint32_t pixel_width;
63  uint32_t pixel_height;
64  uint8_t nalu_length_size;
65  std::vector<uint8_t> codec_config;
66  bool is_encrypted;
67 };
68 
70  std::string file_name;
71  uint64_t start_time;
72  uint64_t duration;
73  uint64_t segment_file_size;
74 };
75 
76 // Note that this does not have vector of StreamInfo pointer.
78  MuxerListener::MediaRanges media_ranges;
79  float duration_seconds;
80 };
81 
82 // Creates StreamInfo instance from VideoStreamInfoParameters.
83 std::shared_ptr<VideoStreamInfo> CreateVideoStreamInfo(
84  const VideoStreamInfoParameters& param);
85 
86 // Returns the "default" VideoStreamInfoParameters for testing.
87 VideoStreamInfoParameters GetDefaultVideoStreamInfoParams();
88 
89 // Returns the "default" values for OnMediaEnd().
90 OnMediaEndParameters GetDefaultOnMediaEndParams();
91 
92 // Returns the "default" ProtectionSystemSpecificInfo for testing.
93 std::vector<ProtectionSystemSpecificInfo> GetDefaultKeySystemInfo();
94 
95 // Sets "default" values for muxer_options for testing.
96 void SetDefaultMuxerOptions(MuxerOptions* muxer_options);
97 
98 } // namespace media
99 
100 } // namespace shaka
101 
102 #endif // PACKAGER_MEDIA_EVENT_MUXER_LISTENER_TEST_HELPER_H_
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
- - - - +
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_EVENT_MUXER_LISTENER_TEST_HELPER_H_
+
8 #define PACKAGER_MEDIA_EVENT_MUXER_LISTENER_TEST_HELPER_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <vector>
+
12 
+
13 #include "packager/media/base/key_source.h"
+
14 #include "packager/media/base/muxer_options.h"
+
15 #include "packager/media/base/stream_info.h"
+
16 #include "packager/media/base/video_stream_info.h"
+
17 #include "packager/media/event/muxer_listener.h"
+
18 #include "packager/mpd/base/media_info.pb.h"
+
19 
+
20 namespace shaka {
+
21 
+
22 namespace media {
+
23 
+
24 const char kExpectedDefaultPsshBox[] = "expected_pssh_box";
+
25 const char kExpectedDefaultMediaInfo[] =
+
26  "video_info {\n"
+
27  " codec: 'avc1.010101'\n"
+
28  " width: 720\n"
+
29  " height: 480\n"
+
30  " time_scale: 10\n"
+
31  " pixel_width: 1\n"
+
32  " pixel_height: 1\n"
+
33  "}\n"
+
34  "init_range {\n"
+
35  " begin: 0\n"
+
36  " end: 120\n"
+
37  "}\n"
+
38  "index_range {\n"
+
39  " begin: 121\n"
+
40  " end: 221\n"
+
41  "}\n"
+
42  "reference_time_scale: 1000\n"
+
43  "container_type: 1\n"
+
44  "media_file_name: 'test_output_file_name.mp4'\n"
+
45  "media_duration_seconds: 10.5\n";
+
46 const uint32_t kDefaultReferenceTimeScale = 1000u;
+
47 
+
48 // Struct that gets passed for to CreateVideoStreamInfo() to create a
+
49 // StreamInfo instance. Useful for generating multiple VideoStreamInfo with
+
50 // slightly different parameters.
+ + + +
54  int track_id;
+
55  uint32_t time_scale;
+
56  uint64_t duration;
+
57  Codec codec;
+
58  std::string codec_string;
+
59  std::string language;
+
60  uint16_t width;
+
61  uint16_t height;
+
62  uint32_t pixel_width;
+
63  uint32_t pixel_height;
+
64  uint8_t nalu_length_size;
+
65  std::vector<uint8_t> codec_config;
+
66  bool is_encrypted;
+
67 };
+
68 
+ +
70  std::string file_name;
+
71  uint64_t start_time;
+
72  uint64_t duration;
+
73  uint64_t segment_file_size;
+
74 };
+
75 
+
76 // Note that this does not have vector of StreamInfo pointer.
+ +
78  MuxerListener::MediaRanges media_ranges;
+
79  float duration_seconds;
+
80 };
+
81 
+
82 // Creates StreamInfo instance from VideoStreamInfoParameters.
+
83 std::shared_ptr<VideoStreamInfo> CreateVideoStreamInfo(
+
84  const VideoStreamInfoParameters& param);
+
85 
+
86 // Returns the "default" VideoStreamInfoParameters for testing.
+
87 VideoStreamInfoParameters GetDefaultVideoStreamInfoParams();
+
88 
+
89 // Returns the "default" values for OnMediaEnd().
+
90 OnMediaEndParameters GetDefaultOnMediaEndParams();
+
91 
+
92 // Returns the "default" ProtectionSystemSpecificInfo for testing.
+
93 std::vector<ProtectionSystemSpecificInfo> GetDefaultKeySystemInfo();
+
94 
+
95 // Sets "default" values for muxer_options for testing.
+
96 void SetDefaultMuxerOptions(MuxerOptions* muxer_options);
+
97 
+
98 } // namespace media
+
99 
+
100 } // namespace shaka
+
101 
+
102 #endif // PACKAGER_MEDIA_EVENT_MUXER_LISTENER_TEST_HELPER_H_
+
All the methods that are virtual are virtual for mocking.
+ +
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
+ + +
diff --git a/docs/d7/d12/media__parser_8h_source.html b/docs/d7/d12/media__parser_8h_source.html index d0b263e910..611b850fdc 100644 --- a/docs/d7/d12/media__parser_8h_source.html +++ b/docs/d7/d12/media__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/media_parser.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
media_parser.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_MEDIA_PARSER_H_
8 #define PACKAGER_MEDIA_BASE_MEDIA_PARSER_H_
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 #include "packager/base/callback.h"
14 #include "packager/base/compiler_specific.h"
15 #include "packager/media/base/container_names.h"
16 
17 namespace shaka {
18 namespace media {
19 
20 class KeySource;
21 class MediaSample;
22 class StreamInfo;
23 
24 class MediaParser {
25  public:
26  MediaParser() {}
27  virtual ~MediaParser() {}
28 
32  typedef base::Callback<void(
33  const std::vector<std::shared_ptr<StreamInfo> >& stream_info)>
35 
41  typedef base::Callback<bool(uint32_t track_id,
42  const std::shared_ptr<MediaSample>& media_sample)>
44 
52  virtual void Init(const InitCB& init_cb,
53  const NewSampleCB& new_sample_cb,
54  KeySource* decryption_key_source) = 0;
55 
59  virtual bool Flush() WARN_UNUSED_RESULT = 0;
60 
63  virtual bool Parse(const uint8_t* buf, int size) WARN_UNUSED_RESULT = 0;
64 
65  private:
66  DISALLOW_COPY_AND_ASSIGN(MediaParser);
67 };
68 
69 } // namespace media
70 } // namespace shaka
71 
72 #endif // PACKAGER_MEDIA_BASE_MEDIA_PARSER_H_
-
virtual bool Parse(const uint8_t *buf, int size) WARN_UNUSED_RESULT=0
-
All the methods that are virtual are virtual for mocking.
-
base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
Definition: media_parser.h:34
-
base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
Definition: media_parser.h:43
-
virtual void Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source)=0
-
virtual bool Flush() WARN_UNUSED_RESULT=0
-
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:48
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_MEDIA_PARSER_H_
+
8 #define PACKAGER_MEDIA_BASE_MEDIA_PARSER_H_
+
9 
+
10 #include <memory>
+
11 #include <string>
+
12 #include <vector>
+
13 #include "packager/base/callback.h"
+
14 #include "packager/base/compiler_specific.h"
+
15 #include "packager/media/base/container_names.h"
+
16 
+
17 namespace shaka {
+
18 namespace media {
+
19 
+
20 class KeySource;
+
21 class MediaSample;
+
22 class StreamInfo;
+
23 class TextSample;
+
24 
+
25 class MediaParser {
+
26  public:
+
27  MediaParser() {}
+
28  virtual ~MediaParser() {}
+
29 
+
33  typedef base::Callback<void(
+
34  const std::vector<std::shared_ptr<StreamInfo> >& stream_info)>
+ +
36 
+
42  typedef base::Callback<bool(uint32_t track_id,
+
43  std::shared_ptr<MediaSample> media_sample)>
+ +
45 
+
51  typedef base::Callback<bool(uint32_t track_id,
+
52  std::shared_ptr<TextSample> text_sample)>
+ +
54 
+
65  virtual void Init(const InitCB& init_cb,
+
66  const NewMediaSampleCB& new_media_sample_cb,
+
67  const NewTextSampleCB& new_text_sample_cb,
+
68  KeySource* decryption_key_source) = 0;
+
69 
+
73  virtual bool Flush() WARN_UNUSED_RESULT = 0;
+
74 
+
77  virtual bool Parse(const uint8_t* buf, int size) WARN_UNUSED_RESULT = 0;
+
78 
+
79  private:
+
80  DISALLOW_COPY_AND_ASSIGN(MediaParser);
+
81 };
+
82 
+
83 } // namespace media
+
84 } // namespace shaka
+
85 
+
86 #endif // PACKAGER_MEDIA_BASE_MEDIA_PARSER_H_
+
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:51
+ +
virtual bool Parse(const uint8_t *buf, int size) WARN_UNUSED_RESULT=0
+
base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
Definition: media_parser.h:53
+
virtual bool Flush() WARN_UNUSED_RESULT=0
+
virtual void Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source)=0
+
base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
Definition: media_parser.h:44
+
base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
Definition: media_parser.h:35
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/d15/mpd__notifier_8h_source.html b/docs/d7/d15/mpd__notifier_8h_source.html index 0ec3837d17..22fe0a4bcf 100644 --- a/docs/d7/d15/mpd__notifier_8h_source.html +++ b/docs/d7/d15/mpd__notifier_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mpd_notifier.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mpd_notifier.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // MpdNotifier is responsible for notifying the MpdBuilder class to generate an
8 // MPD file.
9 
10 #ifndef MPD_BASE_MPD_NOTIFIER_H_
11 #define MPD_BASE_MPD_NOTIFIER_H_
12 
13 #include <stdint.h>
14 #include <string>
15 #include <vector>
16 
17 #include "packager/base/macros.h"
18 #include "packager/mpd/base/mpd_options.h"
19 
20 namespace shaka {
21 
22 class MediaInfo;
23 struct ContentProtectionElement;
24 
27 class MpdNotifier {
28  public:
29  explicit MpdNotifier(const MpdOptions& mpd_options)
30  : mpd_options_(mpd_options) {}
31  virtual ~MpdNotifier() {}
32 
36  virtual bool Init() = 0;
37 
46  virtual bool NotifyNewContainer(const MediaInfo& media_info,
47  uint32_t* container_id) = 0;
48 
56  virtual bool NotifySampleDuration(uint32_t container_id,
57  uint32_t sample_duration) = 0;
58 
69  virtual bool NotifyNewSegment(uint32_t container_id,
70  uint64_t start_time,
71  uint64_t duration,
72  uint64_t size) = 0;
73 
79  virtual bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) = 0;
80 
90  virtual bool NotifyEncryptionUpdate(uint32_t container_id,
91  const std::string& drm_uuid,
92  const std::vector<uint8_t>& new_key_id,
93  const std::vector<uint8_t>& new_pssh) = 0;
94 
99  virtual bool NotifyMediaInfoUpdate(uint32_t container_id,
100  const MediaInfo& media_info) = 0;
101 
105  virtual bool Flush() = 0;
106 
108  DashProfile dash_profile() const { return mpd_options_.dash_profile; }
109 
111  MpdType mpd_type() const { return mpd_options_.mpd_type; }
112 
113  private:
114  const MpdOptions mpd_options_;
115 
116  DISALLOW_COPY_AND_ASSIGN(MpdNotifier);
117 };
118 
119 } // namespace shaka
120 
121 #endif // MPD_BASE_MPD_NOTIFIER_H_
virtual bool Flush()=0
-
MpdType mpd_type() const
Definition: mpd_notifier.h:111
-
virtual bool Init()=0
-
virtual bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0
-
DashProfile dash_profile() const
Definition: mpd_notifier.h:108
-
virtual bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0
-
All the methods that are virtual are virtual for mocking.
-
virtual bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0
-
virtual bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0
-
virtual bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0
- -
virtual bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0
-
Defines Mpd Options.
Definition: mpd_options.h:25
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // MpdNotifier is responsible for notifying the MpdBuilder class to generate an
+
8 // MPD file.
+
9 
+
10 #ifndef MPD_BASE_MPD_NOTIFIER_H_
+
11 #define MPD_BASE_MPD_NOTIFIER_H_
+
12 
+
13 #include <stdint.h>
+
14 #include <string>
+
15 #include <vector>
+
16 
+
17 #include "packager/base/macros.h"
+
18 #include "packager/mpd/base/mpd_options.h"
+
19 
+
20 namespace shaka {
+
21 
+
22 class MediaInfo;
+
23 struct ContentProtectionElement;
+
24 
+
27 class MpdNotifier {
+
28  public:
+
29  explicit MpdNotifier(const MpdOptions& mpd_options)
+
30  : mpd_options_(mpd_options) {}
+
31  virtual ~MpdNotifier() {}
+
32 
+
36  virtual bool Init() = 0;
+
37 
+
46  virtual bool NotifyNewContainer(const MediaInfo& media_info,
+
47  uint32_t* container_id) = 0;
+
48 
+
56  virtual bool NotifySampleDuration(uint32_t container_id,
+
57  uint32_t sample_duration) = 0;
+
58 
+
69  virtual bool NotifyNewSegment(uint32_t container_id,
+
70  uint64_t start_time,
+
71  uint64_t duration,
+
72  uint64_t size) = 0;
+
73 
+
79  virtual bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) = 0;
+
80 
+
90  virtual bool NotifyEncryptionUpdate(uint32_t container_id,
+
91  const std::string& drm_uuid,
+
92  const std::vector<uint8_t>& new_key_id,
+
93  const std::vector<uint8_t>& new_pssh) = 0;
+
94 
+
99  virtual bool NotifyMediaInfoUpdate(uint32_t container_id,
+
100  const MediaInfo& media_info) = 0;
+
101 
+
105  virtual bool Flush() = 0;
+
106 
+
108  bool include_mspr_pro() const { return mpd_options_.mpd_params.include_mspr_pro; }
+
109 
+
111  DashProfile dash_profile() const { return mpd_options_.dash_profile; }
+
112 
+
114  MpdType mpd_type() const { return mpd_options_.mpd_type; }
+
115 
+
116  private:
+
117  const MpdOptions mpd_options_;
+
118 
+
119  DISALLOW_COPY_AND_ASSIGN(MpdNotifier);
+
120 };
+
121 
+
122 } // namespace shaka
+
123 
+
124 #endif // MPD_BASE_MPD_NOTIFIER_H_
+ +
MpdType mpd_type() const
Definition: mpd_notifier.h:114
+
virtual bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0
+
DashProfile dash_profile() const
Definition: mpd_notifier.h:111
+
virtual bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0
+
virtual bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0
+
virtual bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0
+
virtual bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0
+
virtual bool Init()=0
+
virtual bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0
+
bool include_mspr_pro() const
Definition: mpd_notifier.h:108
+
virtual bool Flush()=0
+
All the methods that are virtual are virtual for mocking.
+
Defines Mpd Options.
Definition: mpd_options.h:25
+
bool include_mspr_pro
Definition: mpd_params.h:89
diff --git a/docs/d7/d16/structshaka_1_1media_1_1mp4_1_1VideoSampleEntry-members.html b/docs/d7/d16/structshaka_1_1media_1_1mp4_1_1VideoSampleEntry-members.html index 50f329065f..92f31e205d 100644 --- a/docs/d7/d16/structshaka_1_1media_1_1mp4_1_1VideoSampleEntry-members.html +++ b/docs/d7/d16/structshaka_1_1media_1_1mp4_1_1VideoSampleEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d7/d1d/text__chunker_8h_source.html b/docs/d7/d1d/text__chunker_8h_source.html index 65c444ee96..3a39a7a724 100644 --- a/docs/d7/d1d/text__chunker_8h_source.html +++ b/docs/d7/d1d/text__chunker_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking/text_chunker.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
text_chunker.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CHUNKING_TEXT_CHUNKER_H_
8 #define PACKAGER_MEDIA_CHUNKING_TEXT_CHUNKER_H_
9 
10 #include <list>
11 
12 #include "packager/media/base/media_handler.h"
13 
14 namespace shaka {
15 namespace media {
16 
17 // Media handler for taking a single stream of text samples and inserting
18 // segment info based on a fixed segment duration and on cue events. The
19 // only time a segment's duration will not match the fixed segment duration
20 // is when a cue event is seen.
21 class TextChunker : public MediaHandler {
22  public:
23  explicit TextChunker(double segment_duration_in_seconds);
24 
25  private:
26  TextChunker(const TextChunker&) = delete;
27  TextChunker& operator=(const TextChunker&) = delete;
28 
29  Status InitializeInternal() override { return Status::OK; }
30 
31  Status Process(std::unique_ptr<StreamData> stream_data) override;
32  Status OnFlushRequest(size_t input_stream_index) override;
33 
34  Status OnStreamInfo(std::shared_ptr<const StreamInfo> info);
35  Status OnCueEvent(std::shared_ptr<const CueEvent> cue);
36  Status OnTextSample(std::shared_ptr<const TextSample> sample);
37 
38  // This does two things that should always happen together:
39  // 1. Dispatch all the samples and a segment info for the time range
40  // segment_start_ to segment_start_ + duration
41  // 2. Set the next segment to start at segment_start_ + duration and
42  // remove all samples that don't last into that segment.
43  Status DispatchSegment(int64_t duration);
44 
45  int64_t ScaleTime(double seconds) const;
46 
47  double segment_duration_in_seconds_;
48 
49  int64_t time_scale_ = -1; // Set in OnStreamInfo
50 
51  // Time values are in scaled units.
52  int64_t segment_start_ = -1; // Set when the first sample comes in.
53  int64_t segment_duration_ = -1; // Set in OnStreamInfo.
54 
55  // All samples that make up the current segment. We must store the samples
56  // until the segment ends because a cue event may end the segment sooner
57  // than we expected.
58  std::list<std::shared_ptr<const TextSample>> samples_in_current_segment_;
59 };
60 
61 } // namespace media
62 } // namespace shaka
63 
64 #endif // PACKAGER_MEDIA_CHUNKING_TEXT_CHUNKER_H_
-
All the methods that are virtual are virtual for mocking.
- - +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CHUNKING_TEXT_CHUNKER_H_
+
8 #define PACKAGER_MEDIA_CHUNKING_TEXT_CHUNKER_H_
+
9 
+
10 #include <list>
+
11 
+
12 #include "packager/media/base/media_handler.h"
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 
+
17 // Media handler for taking a single stream of text samples and inserting
+
18 // segment info based on a fixed segment duration and on cue events. The
+
19 // only time a segment's duration will not match the fixed segment duration
+
20 // is when a cue event is seen.
+
21 class TextChunker : public MediaHandler {
+
22  public:
+
23  explicit TextChunker(double segment_duration_in_seconds);
+
24 
+
25  private:
+
26  TextChunker(const TextChunker&) = delete;
+
27  TextChunker& operator=(const TextChunker&) = delete;
+
28 
+
29  Status InitializeInternal() override { return Status::OK; }
+
30 
+
31  Status Process(std::unique_ptr<StreamData> stream_data) override;
+
32  Status OnFlushRequest(size_t input_stream_index) override;
+
33 
+
34  Status OnStreamInfo(std::shared_ptr<const StreamInfo> info);
+
35  Status OnCueEvent(std::shared_ptr<const CueEvent> cue);
+
36  Status OnTextSample(std::shared_ptr<const TextSample> sample);
+
37 
+
38  // This does two things that should always happen together:
+
39  // 1. Dispatch all the samples and a segment info for the time range
+
40  // segment_start_ to segment_start_ + duration
+
41  // 2. Set the next segment to start at segment_start_ + duration and
+
42  // remove all samples that don't last into that segment.
+
43  Status DispatchSegment(int64_t duration);
+
44 
+
45  int64_t ScaleTime(double seconds) const;
+
46 
+
47  double segment_duration_in_seconds_;
+
48 
+
49  int64_t time_scale_ = -1; // Set in OnStreamInfo
+
50 
+
51  // Time values are in scaled units.
+
52  int64_t segment_start_ = -1; // Set when the first sample comes in.
+
53  int64_t segment_duration_ = -1; // Set in OnStreamInfo.
+
54 
+
55  // All samples that make up the current segment. We must store the samples
+
56  // until the segment ends because a cue event may end the segment sooner
+
57  // than we expected.
+
58  std::list<std::shared_ptr<const TextSample>> samples_in_current_segment_;
+
59 };
+
60 
+
61 } // namespace media
+
62 } // namespace shaka
+
63 
+
64 #endif // PACKAGER_MEDIA_CHUNKING_TEXT_CHUNKER_H_
+ + + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/d1e/subsample__generator_8cc_source.html b/docs/d7/d1e/subsample__generator_8cc_source.html index 40979ea0cc..cd992c1183 100644 --- a/docs/d7/d1e/subsample__generator_8cc_source.html +++ b/docs/d7/d1e/subsample__generator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto/subsample_generator.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
subsample_generator.cc
-
1 // Copyright 2018 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/crypto/subsample_generator.h"
8 
9 #include <algorithm>
10 #include <limits>
11 
12 #include "packager/media/base/decrypt_config.h"
13 #include "packager/media/base/video_stream_info.h"
14 #include "packager/media/codecs/av1_parser.h"
15 #include "packager/media/codecs/video_slice_header_parser.h"
16 #include "packager/media/codecs/vp8_parser.h"
17 #include "packager/media/codecs/vp9_parser.h"
18 
19 namespace shaka {
20 namespace media {
21 namespace {
22 
23 const size_t kAesBlockSize = 16u;
24 
25 uint8_t GetNaluLengthSize(const StreamInfo& stream_info) {
26  if (stream_info.stream_type() != kStreamVideo)
27  return 0;
28 
29  const VideoStreamInfo& video_stream_info =
30  static_cast<const VideoStreamInfo&>(stream_info);
31  return video_stream_info.nalu_length_size();
32 }
33 
34 bool ShouldAlignProtectedData(Codec codec,
35  FourCC protection_scheme,
36  bool vp9_subsample_encryption) {
37  switch (codec) {
38  case kCodecAV1:
39  // Per AV1 in ISO-BMFF spec [1], BytesOfProtectedData SHALL be a multiple
40  // of 16 bytes.
41  // [1] https://aomediacodec.github.io/av1-isobmff/#subsample-encryption
42  return true;
43  case kCodecVP9:
44  // "VP Codec ISO Media File Format Binding" document requires that the
45  // encrypted bytes of each frame within the superframe must be block
46  // aligned so that the counter state can be computed for each frame
47  // within the superframe.
48  // ISO/IEC 23001-7:2016 10.2 'cbc1' 10.3 'cens'
49  // The BytesOfProtectedData size SHALL be a multiple of 16 bytes to
50  // avoid partial blocks in Subsamples.
51  // For consistency, apply block alignment to all frames when VP9 subsample
52  // encryption is enabled.
53  return vp9_subsample_encryption;
54  default:
55  // ISO/IEC 23001-7:2016 10.2 'cbc1' 10.3 'cens'
56  // The BytesOfProtectedData size SHALL be a multiple of 16 bytes to avoid
57  // partial blocks in Subsamples.
58  // CMAF requires 'cenc' scheme BytesOfProtectedData SHALL be a multiple of
59  // 16 bytes; while 'cbcs' scheme BytesOfProtectedData SHALL start on the
60  // first byte of video data following the slice header.
61  return protection_scheme == FOURCC_cbc1 ||
62  protection_scheme == FOURCC_cens ||
63  protection_scheme == FOURCC_cenc;
64  }
65 }
66 
67 // A convenient util class to organize subsamples, e.g. combine consecutive
68 // subsamples with only clear bytes, split subsamples if the clear bytes exceeds
69 // 2^16 etc.
70 class SubsampleOrganizer {
71  public:
72  SubsampleOrganizer(bool align_protected_data,
73  std::vector<SubsampleEntry>* subsamples)
74  : align_protected_data_(align_protected_data), subsamples_(subsamples) {}
75 
76  ~SubsampleOrganizer() {
77  if (accumulated_clear_bytes_ > 0) {
78  PushSubsample(accumulated_clear_bytes_, 0);
79  accumulated_clear_bytes_ = 0;
80  }
81  }
82 
83  void AddSubsample(size_t clear_bytes, size_t cipher_bytes) {
84  DCHECK_LT(clear_bytes, std::numeric_limits<uint32_t>::max());
85  DCHECK_LT(cipher_bytes, std::numeric_limits<uint32_t>::max());
86 
87  if (align_protected_data_ && cipher_bytes != 0) {
88  const size_t misalign_bytes = cipher_bytes % kAesBlockSize;
89  clear_bytes += misalign_bytes;
90  cipher_bytes -= misalign_bytes;
91  }
92 
93  accumulated_clear_bytes_ += clear_bytes;
94  // Accumulated clear bytes are handled later.
95  if (cipher_bytes == 0)
96  return;
97 
98  PushSubsample(accumulated_clear_bytes_, cipher_bytes);
99  accumulated_clear_bytes_ = 0;
100  }
101 
102  private:
103  SubsampleOrganizer(const SubsampleOrganizer&) = delete;
104  SubsampleOrganizer& operator=(const SubsampleOrganizer&) = delete;
105 
106  void PushSubsample(size_t clear_bytes, size_t cipher_bytes) {
107  const uint16_t kUInt16Max = std::numeric_limits<uint16_t>::max();
108  while (clear_bytes > kUInt16Max) {
109  subsamples_->emplace_back(kUInt16Max, 0);
110  clear_bytes -= kUInt16Max;
111  }
112  subsamples_->emplace_back(static_cast<uint16_t>(clear_bytes),
113  static_cast<uint32_t>(cipher_bytes));
114  }
115 
116  const bool align_protected_data_ = false;
117  std::vector<SubsampleEntry>* const subsamples_ = nullptr;
118  size_t accumulated_clear_bytes_ = 0;
119 };
120 
121 } // namespace
122 
123 SubsampleGenerator::SubsampleGenerator(bool vp9_subsample_encryption)
124  : vp9_subsample_encryption_(vp9_subsample_encryption) {}
125 
126 SubsampleGenerator::~SubsampleGenerator() {}
127 
128 Status SubsampleGenerator::Initialize(FourCC protection_scheme,
129  const StreamInfo& stream_info) {
130  codec_ = stream_info.codec();
131  nalu_length_size_ = GetNaluLengthSize(stream_info);
132 
133  switch (codec_) {
134  case kCodecAV1:
135  av1_parser_.reset(new AV1Parser);
136  break;
137  case kCodecVP9:
138  if (vp9_subsample_encryption_)
139  vpx_parser_.reset(new VP9Parser);
140  break;
141  case kCodecH264:
142  header_parser_.reset(new H264VideoSliceHeaderParser);
143  break;
144  case kCodecH265:
145  case kCodecH265DolbyVision:
146  header_parser_.reset(new H265VideoSliceHeaderParser);
147  break;
148  default:
149  // Other codecs should have nalu length size == 0.
150  if (nalu_length_size_ > 0) {
151  LOG(WARNING) << "Unknown video codec '" << codec_ << "'";
152  return Status(error::ENCRYPTION_FAILURE, "Unknown video codec.");
153  }
154  }
155  if (av1_parser_) {
156  // Parse configOBUs in AV1CodecConfigurationRecord if exists.
157  // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-syntax.
158  const size_t kConfigOBUsOffset = 4;
159  const bool has_config_obus =
160  stream_info.codec_config().size() > kConfigOBUsOffset;
161  std::vector<AV1Parser::Tile> tiles;
162  if (has_config_obus &&
163  !av1_parser_->Parse(
164  &stream_info.codec_config()[kConfigOBUsOffset],
165  stream_info.codec_config().size() - kConfigOBUsOffset, &tiles)) {
166  return Status(
167  error::ENCRYPTION_FAILURE,
168  "Failed to parse configOBUs in AV1CodecConfigurationRecord.");
169  }
170  DCHECK(tiles.empty());
171  }
172  if (header_parser_) {
173  CHECK_NE(nalu_length_size_, 0u) << "AnnexB stream is not supported yet";
174  if (!header_parser_->Initialize(stream_info.codec_config())) {
175  return Status(error::ENCRYPTION_FAILURE,
176  "Failed to read SPS and PPS data.");
177  }
178  }
179 
180  align_protected_data_ = ShouldAlignProtectedData(codec_, protection_scheme,
181  vp9_subsample_encryption_);
182 
183  if (protection_scheme == kAppleSampleAesProtectionScheme) {
184  const size_t kH264LeadingClearBytesSize = 32u;
185  const size_t kAudioLeadingClearBytesSize = 16u;
186  switch (codec_) {
187  case kCodecH264:
188  leading_clear_bytes_size_ = kH264LeadingClearBytesSize;
189  min_protected_data_size_ =
190  leading_clear_bytes_size_ + kAesBlockSize + 1u;
191  break;
192  case kCodecAAC:
193  FALLTHROUGH_INTENDED;
194  case kCodecAC3:
195  leading_clear_bytes_size_ = kAudioLeadingClearBytesSize;
196  min_protected_data_size_ = leading_clear_bytes_size_ + kAesBlockSize;
197  break;
198  case kCodecEAC3:
199  // E-AC3 encryption is handled by SampleAesEc3Cryptor, which also
200  // manages leading clear bytes.
201  leading_clear_bytes_size_ = 0;
202  min_protected_data_size_ = leading_clear_bytes_size_ + kAesBlockSize;
203  break;
204  default:
205  LOG(ERROR) << "Unexpected codec for SAMPLE-AES " << codec_;
206  return Status(error::ENCRYPTION_FAILURE,
207  "Unexpected codec for SAMPLE-AES.");
208  }
209  }
210  return Status::OK;
211 }
212 
214  const uint8_t* frame,
215  size_t frame_size,
216  std::vector<SubsampleEntry>* subsamples) {
217  subsamples->clear();
218  switch (codec_) {
219  case kCodecAV1:
220  return GenerateSubsamplesFromAV1Frame(frame, frame_size, subsamples);
221  case kCodecH264:
222  FALLTHROUGH_INTENDED;
223  case kCodecH265:
224  case kCodecH265DolbyVision:
225  return GenerateSubsamplesFromH26xFrame(frame, frame_size, subsamples);
226  case kCodecVP9:
227  if (vp9_subsample_encryption_)
228  return GenerateSubsamplesFromVPxFrame(frame, frame_size, subsamples);
229  // Full sample encrypted so no subsamples.
230  break;
231  default:
232  // Other codecs are full sample encrypted unless there are clear leading
233  // bytes.
234  if (leading_clear_bytes_size_ > 0) {
235  SubsampleOrganizer subsample_organizer(align_protected_data_,
236  subsamples);
237  const size_t clear_bytes =
238  std::min(frame_size, leading_clear_bytes_size_);
239  const size_t cipher_bytes = frame_size - clear_bytes;
240  subsample_organizer.AddSubsample(clear_bytes, cipher_bytes);
241  } else {
242  // Full sample encrypted so no subsamples.
243  }
244  break;
245  }
246  return Status::OK;
247 }
248 
249 void SubsampleGenerator::InjectVpxParserForTesting(
250  std::unique_ptr<VPxParser> vpx_parser) {
251  vpx_parser_ = std::move(vpx_parser);
252 }
253 
254 void SubsampleGenerator::InjectVideoSliceHeaderParserForTesting(
255  std::unique_ptr<VideoSliceHeaderParser> header_parser) {
256  header_parser_ = std::move(header_parser);
257 }
258 
259 void SubsampleGenerator::InjectAV1ParserForTesting(
260  std::unique_ptr<AV1Parser> av1_parser) {
261  av1_parser_ = std::move(av1_parser);
262 }
263 
264 Status SubsampleGenerator::GenerateSubsamplesFromVPxFrame(
265  const uint8_t* frame,
266  size_t frame_size,
267  std::vector<SubsampleEntry>* subsamples) {
268  DCHECK(vpx_parser_);
269  std::vector<VPxFrameInfo> vpx_frames;
270  if (!vpx_parser_->Parse(frame, frame_size, &vpx_frames))
271  return Status(error::ENCRYPTION_FAILURE, "Failed to parse vpx frame.");
272 
273  SubsampleOrganizer subsample_organizer(align_protected_data_, subsamples);
274 
275  size_t total_size = 0;
276  for (const VPxFrameInfo& frame : vpx_frames) {
277  subsample_organizer.AddSubsample(
278  frame.uncompressed_header_size,
279  frame.frame_size - frame.uncompressed_header_size);
280  total_size += frame.frame_size;
281  }
282  // Add subsample for the superframe index if exists.
283  const bool is_superframe = vpx_frames.size() > 1;
284  if (is_superframe) {
285  const size_t index_size = frame_size - total_size;
286  DCHECK_LE(index_size, 2 + vpx_frames.size() * 4);
287  DCHECK_GE(index_size, 2 + vpx_frames.size() * 1);
288  subsample_organizer.AddSubsample(index_size, 0);
289  } else {
290  DCHECK_EQ(total_size, frame_size);
291  }
292  return Status::OK;
293 }
294 
295 Status SubsampleGenerator::GenerateSubsamplesFromH26xFrame(
296  const uint8_t* frame,
297  size_t frame_size,
298  std::vector<SubsampleEntry>* subsamples) {
299  DCHECK_NE(nalu_length_size_, 0u);
300  DCHECK(header_parser_);
301 
302  SubsampleOrganizer subsample_organizer(align_protected_data_, subsamples);
303 
304  const Nalu::CodecType nalu_type =
305  (codec_ == kCodecH265 || codec_ == kCodecH265DolbyVision) ? Nalu::kH265
306  : Nalu::kH264;
307  NaluReader reader(nalu_type, nalu_length_size_, frame, frame_size);
308 
309  Nalu nalu;
310  NaluReader::Result result;
311  while ((result = reader.Advance(&nalu)) == NaluReader::kOk) {
312  // |header_parser_| is only used if |leading_clear_bytes_size_| is not
313  // availble. See lines below.
314  if (leading_clear_bytes_size_ == 0 && !header_parser_->ProcessNalu(nalu)) {
315  LOG(ERROR) << "Failed to process NAL unit: NAL type = " << nalu.type();
316  return Status(error::ENCRYPTION_FAILURE, "Failed to process NAL unit.");
317  }
318 
319  const size_t nalu_total_size = nalu.header_size() + nalu.payload_size();
320  size_t clear_bytes = 0;
321  if (nalu.is_video_slice() && nalu_total_size >= min_protected_data_size_) {
322  clear_bytes = leading_clear_bytes_size_;
323  if (clear_bytes == 0) {
324  // For video-slice NAL units, encrypt the video slice. This skips
325  // the frame header.
326  const int64_t video_slice_header_size =
327  header_parser_->GetHeaderSize(nalu);
328  if (video_slice_header_size < 0) {
329  LOG(ERROR) << "Failed to read slice header.";
330  return Status(error::ENCRYPTION_FAILURE,
331  "Failed to read slice header.");
332  }
333  clear_bytes = nalu.header_size() + video_slice_header_size;
334  }
335  } else {
336  // For non-video-slice or small NAL units, don't encrypt.
337  clear_bytes = nalu_total_size;
338  }
339  const size_t cipher_bytes = nalu_total_size - clear_bytes;
340  subsample_organizer.AddSubsample(nalu_length_size_ + clear_bytes,
341  cipher_bytes);
342  }
343  if (result != NaluReader::kEOStream) {
344  LOG(ERROR) << "Failed to parse NAL units.";
345  return Status(error::ENCRYPTION_FAILURE, "Failed to parse NAL units.");
346  }
347  return Status::OK;
348 }
349 
350 Status SubsampleGenerator::GenerateSubsamplesFromAV1Frame(
351  const uint8_t* frame,
352  size_t frame_size,
353  std::vector<SubsampleEntry>* subsamples) {
354  DCHECK(av1_parser_);
355  std::vector<AV1Parser::Tile> av1_tiles;
356  if (!av1_parser_->Parse(frame, frame_size, &av1_tiles))
357  return Status(error::ENCRYPTION_FAILURE, "Failed to parse AV1 frame.");
358 
359  SubsampleOrganizer subsample_organizer(align_protected_data_, subsamples);
360 
361  size_t last_tile_end_offset = 0;
362  for (const AV1Parser::Tile& tile : av1_tiles) {
363  DCHECK_LE(last_tile_end_offset, tile.start_offset_in_bytes);
364  // Per AV1 in ISO-BMFF spec [1], only decode_tile is encrypted.
365  // [1] https://aomediacodec.github.io/av1-isobmff/#subsample-encryption
366  subsample_organizer.AddSubsample(
367  tile.start_offset_in_bytes - last_tile_end_offset, tile.size_in_bytes);
368  last_tile_end_offset = tile.start_offset_in_bytes + tile.size_in_bytes;
369  }
370  DCHECK_LE(last_tile_end_offset, frame_size);
371  if (last_tile_end_offset < frame_size)
372  subsample_organizer.AddSubsample(frame_size - last_tile_end_offset, 0);
373  return Status::OK;
374 }
375 
376 } // namespace media
377 } // namespace shaka
-
Abstract class holds stream information.
Definition: stream_info.h:62
-
bool is_video_slice() const
Slice data partition NALs are not considered as slice NALs.
Definition: nalu_reader.h:117
- - -
All the methods that are virtual are virtual for mocking.
-
uint64_t header_size() const
The size of the header, e.g. 1 for H.264.
Definition: nalu_reader.h:100
- - -
virtual Status GenerateSubsamples(const uint8_t *frame, size_t frame_size, std::vector< SubsampleEntry > *subsamples)
- -
Result Advance(Nalu *nalu)
Definition: nalu_reader.cc:241
-
Class to parse a vp9 bit stream.
Definition: vp9_parser.h:20
- -
SubsampleGenerator(bool vp9_subsample_encryption)
-
int type() const
Definition: nalu_reader.h:113
-
virtual Status Initialize(FourCC protection_scheme, const StreamInfo &stream_info)
- -
uint64_t payload_size() const
Size of this Nalu minus header_size().
Definition: nalu_reader.h:102
+
1 // Copyright 2018 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/crypto/subsample_generator.h"
+
8 
+
9 #include <algorithm>
+
10 #include <limits>
+
11 
+
12 #include "packager/media/base/decrypt_config.h"
+
13 #include "packager/media/base/video_stream_info.h"
+
14 #include "packager/media/codecs/av1_parser.h"
+
15 #include "packager/media/codecs/video_slice_header_parser.h"
+
16 #include "packager/media/codecs/vp8_parser.h"
+
17 #include "packager/media/codecs/vp9_parser.h"
+
18 
+
19 namespace shaka {
+
20 namespace media {
+
21 namespace {
+
22 
+
23 const size_t kAesBlockSize = 16u;
+
24 
+
25 uint8_t GetNaluLengthSize(const StreamInfo& stream_info) {
+
26  if (stream_info.stream_type() != kStreamVideo)
+
27  return 0;
+
28 
+
29  const VideoStreamInfo& video_stream_info =
+
30  static_cast<const VideoStreamInfo&>(stream_info);
+
31  return video_stream_info.nalu_length_size();
+
32 }
+
33 
+
34 bool ShouldAlignProtectedData(Codec codec,
+
35  FourCC protection_scheme,
+
36  bool vp9_subsample_encryption) {
+
37  switch (codec) {
+
38  case kCodecVP9:
+
39  // "VP Codec ISO Media File Format Binding" document requires that the
+
40  // encrypted bytes of each frame within the superframe must be block
+
41  // aligned so that the counter state can be computed for each frame
+
42  // within the superframe.
+
43  // ISO/IEC 23001-7:2016 10.2 'cbc1' 10.3 'cens'
+
44  // The BytesOfProtectedData size SHALL be a multiple of 16 bytes to
+
45  // avoid partial blocks in Subsamples.
+
46  // For consistency, apply block alignment to all frames when VP9 subsample
+
47  // encryption is enabled.
+
48  return vp9_subsample_encryption;
+
49  default:
+
50  // ISO/IEC 23001-7:2016 10.2 'cbc1' 10.3 'cens'
+
51  // The BytesOfProtectedData size SHALL be a multiple of 16 bytes to avoid
+
52  // partial blocks in Subsamples.
+
53  // CMAF requires 'cenc' scheme BytesOfProtectedData SHALL be a multiple of
+
54  // 16 bytes; while 'cbcs' scheme BytesOfProtectedData SHALL start on the
+
55  // first byte of video data following the slice header.
+
56  // https://aomediacodec.github.io/av1-isobmff/#subsample-encryption AV1
+
57  // has a similar clause.
+
58  return protection_scheme == FOURCC_cbc1 ||
+
59  protection_scheme == FOURCC_cens ||
+
60  protection_scheme == FOURCC_cenc;
+
61  }
+
62 }
+
63 
+
64 // A convenient util class to organize subsamples, e.g. combine consecutive
+
65 // subsamples with only clear bytes, split subsamples if the clear bytes exceeds
+
66 // 2^16 etc.
+
67 class SubsampleOrganizer {
+
68  public:
+
69  SubsampleOrganizer(bool align_protected_data,
+
70  std::vector<SubsampleEntry>* subsamples)
+
71  : align_protected_data_(align_protected_data), subsamples_(subsamples) {}
+
72 
+
73  ~SubsampleOrganizer() {
+
74  if (accumulated_clear_bytes_ > 0) {
+
75  PushSubsample(accumulated_clear_bytes_, 0);
+
76  accumulated_clear_bytes_ = 0;
+
77  }
+
78  }
+
79 
+
80  void AddSubsample(size_t clear_bytes, size_t cipher_bytes) {
+
81  DCHECK_LT(clear_bytes, std::numeric_limits<uint32_t>::max());
+
82  DCHECK_LT(cipher_bytes, std::numeric_limits<uint32_t>::max());
+
83 
+
84  if (align_protected_data_ && cipher_bytes != 0) {
+
85  const size_t misalign_bytes = cipher_bytes % kAesBlockSize;
+
86  clear_bytes += misalign_bytes;
+
87  cipher_bytes -= misalign_bytes;
+
88  }
+
89 
+
90  accumulated_clear_bytes_ += clear_bytes;
+
91  // Accumulated clear bytes are handled later.
+
92  if (cipher_bytes == 0)
+
93  return;
+
94 
+
95  PushSubsample(accumulated_clear_bytes_, cipher_bytes);
+
96  accumulated_clear_bytes_ = 0;
+
97  }
+
98 
+
99  private:
+
100  SubsampleOrganizer(const SubsampleOrganizer&) = delete;
+
101  SubsampleOrganizer& operator=(const SubsampleOrganizer&) = delete;
+
102 
+
103  void PushSubsample(size_t clear_bytes, size_t cipher_bytes) {
+
104  const uint16_t kUInt16Max = std::numeric_limits<uint16_t>::max();
+
105  while (clear_bytes > kUInt16Max) {
+
106  subsamples_->emplace_back(kUInt16Max, 0);
+
107  clear_bytes -= kUInt16Max;
+
108  }
+
109  subsamples_->emplace_back(static_cast<uint16_t>(clear_bytes),
+
110  static_cast<uint32_t>(cipher_bytes));
+
111  }
+
112 
+
113  const bool align_protected_data_ = false;
+
114  std::vector<SubsampleEntry>* const subsamples_ = nullptr;
+
115  size_t accumulated_clear_bytes_ = 0;
+
116 };
+
117 
+
118 } // namespace
+
119 
+
120 SubsampleGenerator::SubsampleGenerator(bool vp9_subsample_encryption)
+
121  : vp9_subsample_encryption_(vp9_subsample_encryption) {}
+
122 
+
123 SubsampleGenerator::~SubsampleGenerator() {}
+
124 
+
125 Status SubsampleGenerator::Initialize(FourCC protection_scheme,
+
126  const StreamInfo& stream_info) {
+
127  codec_ = stream_info.codec();
+
128  nalu_length_size_ = GetNaluLengthSize(stream_info);
+
129 
+
130  switch (codec_) {
+
131  case kCodecAV1:
+
132  av1_parser_.reset(new AV1Parser);
+
133  break;
+
134  case kCodecVP9:
+
135  if (vp9_subsample_encryption_)
+
136  vpx_parser_.reset(new VP9Parser);
+
137  break;
+
138  case kCodecH264:
+
139  header_parser_.reset(new H264VideoSliceHeaderParser);
+
140  break;
+
141  case kCodecH265:
+
142  case kCodecH265DolbyVision:
+
143  header_parser_.reset(new H265VideoSliceHeaderParser);
+
144  break;
+
145  default:
+
146  // Other codecs should have nalu length size == 0.
+
147  if (nalu_length_size_ > 0) {
+
148  LOG(WARNING) << "Unknown video codec '" << codec_ << "'";
+
149  return Status(error::ENCRYPTION_FAILURE, "Unknown video codec.");
+
150  }
+
151  }
+
152  if (av1_parser_) {
+
153  // Parse configOBUs in AV1CodecConfigurationRecord if exists.
+
154  // https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-syntax.
+
155  const size_t kConfigOBUsOffset = 4;
+
156  const bool has_config_obus =
+
157  stream_info.codec_config().size() > kConfigOBUsOffset;
+
158  std::vector<AV1Parser::Tile> tiles;
+
159  if (has_config_obus &&
+
160  !av1_parser_->Parse(
+
161  &stream_info.codec_config()[kConfigOBUsOffset],
+
162  stream_info.codec_config().size() - kConfigOBUsOffset, &tiles)) {
+
163  return Status(
+
164  error::ENCRYPTION_FAILURE,
+
165  "Failed to parse configOBUs in AV1CodecConfigurationRecord.");
+
166  }
+
167  DCHECK(tiles.empty());
+
168  }
+
169  if (header_parser_) {
+
170  CHECK_NE(nalu_length_size_, 0u) << "AnnexB stream is not supported yet";
+
171  if (!header_parser_->Initialize(stream_info.codec_config())) {
+
172  return Status(error::ENCRYPTION_FAILURE,
+
173  "Failed to read SPS and PPS data.");
+
174  }
+
175  }
+
176 
+
177  align_protected_data_ = ShouldAlignProtectedData(codec_, protection_scheme,
+
178  vp9_subsample_encryption_);
+
179 
+
180  if (protection_scheme == kAppleSampleAesProtectionScheme) {
+
181  const size_t kH264LeadingClearBytesSize = 32u;
+
182  const size_t kAudioLeadingClearBytesSize = 16u;
+
183  switch (codec_) {
+
184  case kCodecH264:
+
185  leading_clear_bytes_size_ = kH264LeadingClearBytesSize;
+
186  min_protected_data_size_ =
+
187  leading_clear_bytes_size_ + kAesBlockSize + 1u;
+
188  break;
+
189  case kCodecAAC:
+
190  FALLTHROUGH_INTENDED;
+
191  case kCodecAC3:
+
192  leading_clear_bytes_size_ = kAudioLeadingClearBytesSize;
+
193  min_protected_data_size_ = leading_clear_bytes_size_ + kAesBlockSize;
+
194  break;
+
195  case kCodecEAC3:
+
196  // E-AC3 encryption is handled by SampleAesEc3Cryptor, which also
+
197  // manages leading clear bytes.
+
198  leading_clear_bytes_size_ = 0;
+
199  min_protected_data_size_ = leading_clear_bytes_size_ + kAesBlockSize;
+
200  break;
+
201  default:
+
202  LOG(ERROR) << "Unexpected codec for SAMPLE-AES " << codec_;
+
203  return Status(error::ENCRYPTION_FAILURE,
+
204  "Unexpected codec for SAMPLE-AES.");
+
205  }
+
206  }
+
207  return Status::OK;
+
208 }
+
209 
+ +
211  const uint8_t* frame,
+
212  size_t frame_size,
+
213  std::vector<SubsampleEntry>* subsamples) {
+
214  subsamples->clear();
+
215  switch (codec_) {
+
216  case kCodecAV1:
+
217  return GenerateSubsamplesFromAV1Frame(frame, frame_size, subsamples);
+
218  case kCodecH264:
+
219  FALLTHROUGH_INTENDED;
+
220  case kCodecH265:
+
221  case kCodecH265DolbyVision:
+
222  return GenerateSubsamplesFromH26xFrame(frame, frame_size, subsamples);
+
223  case kCodecVP9:
+
224  if (vp9_subsample_encryption_)
+
225  return GenerateSubsamplesFromVPxFrame(frame, frame_size, subsamples);
+
226  // Full sample encrypted so no subsamples.
+
227  break;
+
228  default:
+
229  // Other codecs are full sample encrypted unless there are clear leading
+
230  // bytes.
+
231  if (leading_clear_bytes_size_ > 0) {
+
232  SubsampleOrganizer subsample_organizer(align_protected_data_,
+
233  subsamples);
+
234  const size_t clear_bytes =
+
235  std::min(frame_size, leading_clear_bytes_size_);
+
236  const size_t cipher_bytes = frame_size - clear_bytes;
+
237  subsample_organizer.AddSubsample(clear_bytes, cipher_bytes);
+
238  } else {
+
239  // Full sample encrypted so no subsamples.
+
240  }
+
241  break;
+
242  }
+
243  return Status::OK;
+
244 }
+
245 
+
246 void SubsampleGenerator::InjectVpxParserForTesting(
+
247  std::unique_ptr<VPxParser> vpx_parser) {
+
248  vpx_parser_ = std::move(vpx_parser);
+
249 }
+
250 
+
251 void SubsampleGenerator::InjectVideoSliceHeaderParserForTesting(
+
252  std::unique_ptr<VideoSliceHeaderParser> header_parser) {
+
253  header_parser_ = std::move(header_parser);
+
254 }
+
255 
+
256 void SubsampleGenerator::InjectAV1ParserForTesting(
+
257  std::unique_ptr<AV1Parser> av1_parser) {
+
258  av1_parser_ = std::move(av1_parser);
+
259 }
+
260 
+
261 Status SubsampleGenerator::GenerateSubsamplesFromVPxFrame(
+
262  const uint8_t* frame,
+
263  size_t frame_size,
+
264  std::vector<SubsampleEntry>* subsamples) {
+
265  DCHECK(vpx_parser_);
+
266  std::vector<VPxFrameInfo> vpx_frames;
+
267  if (!vpx_parser_->Parse(frame, frame_size, &vpx_frames))
+
268  return Status(error::ENCRYPTION_FAILURE, "Failed to parse vpx frame.");
+
269 
+
270  SubsampleOrganizer subsample_organizer(align_protected_data_, subsamples);
+
271 
+
272  size_t total_size = 0;
+
273  for (const VPxFrameInfo& frame : vpx_frames) {
+
274  subsample_organizer.AddSubsample(
+
275  frame.uncompressed_header_size,
+
276  frame.frame_size - frame.uncompressed_header_size);
+
277  total_size += frame.frame_size;
+
278  }
+
279  // Add subsample for the superframe index if exists.
+
280  const bool is_superframe = vpx_frames.size() > 1;
+
281  if (is_superframe) {
+
282  const size_t index_size = frame_size - total_size;
+
283  DCHECK_LE(index_size, 2 + vpx_frames.size() * 4);
+
284  DCHECK_GE(index_size, 2 + vpx_frames.size() * 1);
+
285  subsample_organizer.AddSubsample(index_size, 0);
+
286  } else {
+
287  DCHECK_EQ(total_size, frame_size);
+
288  }
+
289  return Status::OK;
+
290 }
+
291 
+
292 Status SubsampleGenerator::GenerateSubsamplesFromH26xFrame(
+
293  const uint8_t* frame,
+
294  size_t frame_size,
+
295  std::vector<SubsampleEntry>* subsamples) {
+
296  DCHECK_NE(nalu_length_size_, 0u);
+
297  DCHECK(header_parser_);
+
298 
+
299  SubsampleOrganizer subsample_organizer(align_protected_data_, subsamples);
+
300 
+
301  const Nalu::CodecType nalu_type =
+
302  (codec_ == kCodecH265 || codec_ == kCodecH265DolbyVision) ? Nalu::kH265
+
303  : Nalu::kH264;
+
304  NaluReader reader(nalu_type, nalu_length_size_, frame, frame_size);
+
305 
+
306  Nalu nalu;
+
307  NaluReader::Result result;
+
308  while ((result = reader.Advance(&nalu)) == NaluReader::kOk) {
+
309  // |header_parser_| is only used if |leading_clear_bytes_size_| is not
+
310  // availble. See lines below.
+
311  if (leading_clear_bytes_size_ == 0 && !header_parser_->ProcessNalu(nalu)) {
+
312  LOG(ERROR) << "Failed to process NAL unit: NAL type = " << nalu.type();
+
313  return Status(error::ENCRYPTION_FAILURE, "Failed to process NAL unit.");
+
314  }
+
315 
+
316  const size_t nalu_total_size = nalu.header_size() + nalu.payload_size();
+
317  size_t clear_bytes = 0;
+
318  if (nalu.is_video_slice() && nalu_total_size >= min_protected_data_size_) {
+
319  clear_bytes = leading_clear_bytes_size_;
+
320  if (clear_bytes == 0) {
+
321  // For video-slice NAL units, encrypt the video slice. This skips
+
322  // the frame header.
+
323  const int64_t video_slice_header_size =
+
324  header_parser_->GetHeaderSize(nalu);
+
325  if (video_slice_header_size < 0) {
+
326  LOG(ERROR) << "Failed to read slice header.";
+
327  return Status(error::ENCRYPTION_FAILURE,
+
328  "Failed to read slice header.");
+
329  }
+
330  clear_bytes = nalu.header_size() + video_slice_header_size;
+
331  }
+
332  } else {
+
333  // For non-video-slice or small NAL units, don't encrypt.
+
334  clear_bytes = nalu_total_size;
+
335  }
+
336  const size_t cipher_bytes = nalu_total_size - clear_bytes;
+
337  subsample_organizer.AddSubsample(nalu_length_size_ + clear_bytes,
+
338  cipher_bytes);
+
339  }
+
340  if (result != NaluReader::kEOStream) {
+
341  LOG(ERROR) << "Failed to parse NAL units.";
+
342  return Status(error::ENCRYPTION_FAILURE, "Failed to parse NAL units.");
+
343  }
+
344  return Status::OK;
+
345 }
+
346 
+
347 Status SubsampleGenerator::GenerateSubsamplesFromAV1Frame(
+
348  const uint8_t* frame,
+
349  size_t frame_size,
+
350  std::vector<SubsampleEntry>* subsamples) {
+
351  DCHECK(av1_parser_);
+
352  std::vector<AV1Parser::Tile> av1_tiles;
+
353  if (!av1_parser_->Parse(frame, frame_size, &av1_tiles))
+
354  return Status(error::ENCRYPTION_FAILURE, "Failed to parse AV1 frame.");
+
355 
+
356  SubsampleOrganizer subsample_organizer(align_protected_data_, subsamples);
+
357 
+
358  size_t last_tile_end_offset = 0;
+
359  for (const AV1Parser::Tile& tile : av1_tiles) {
+
360  DCHECK_LE(last_tile_end_offset, tile.start_offset_in_bytes);
+
361  // Per AV1 in ISO-BMFF spec [1], only decode_tile is encrypted.
+
362  // [1] https://aomediacodec.github.io/av1-isobmff/#subsample-encryption
+
363  subsample_organizer.AddSubsample(
+
364  tile.start_offset_in_bytes - last_tile_end_offset, tile.size_in_bytes);
+
365  last_tile_end_offset = tile.start_offset_in_bytes + tile.size_in_bytes;
+
366  }
+
367  DCHECK_LE(last_tile_end_offset, frame_size);
+
368  if (last_tile_end_offset < frame_size)
+
369  subsample_organizer.AddSubsample(frame_size - last_tile_end_offset, 0);
+
370  return Status::OK;
+
371 }
+
372 
+
373 } // namespace media
+
374 } // namespace shaka
+ + + + +
Abstract class holds stream information.
Definition: stream_info.h:65
+
SubsampleGenerator(bool vp9_subsample_encryption)
+
virtual Status GenerateSubsamples(const uint8_t *frame, size_t frame_size, std::vector< SubsampleEntry > *subsamples)
+
virtual Status Initialize(FourCC protection_scheme, const StreamInfo &stream_info)
+
Class to parse a vp9 bit stream.
Definition: vp9_parser.h:20
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/d20/period_8h_source.html b/docs/d7/d20/period_8h_source.html index 6b63eb02a0..eef2896aea 100644 --- a/docs/d7/d20/period_8h_source.html +++ b/docs/d7/d20/period_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/period.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
period.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
8 
9 #ifndef PACKAGER_MPD_BASE_PERIOD_H_
10 #define PACKAGER_MPD_BASE_PERIOD_H_
11 
12 #include <list>
13 #include <map>
14 
15 #include "packager/base/optional.h"
16 #include "packager/mpd/base/adaptation_set.h"
17 #include "packager/mpd/base/media_info.pb.h"
18 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
19 
20 namespace shaka {
21 
22 struct MpdOptions;
23 
24 namespace xml {
25 class XmlNode;
26 } // namespace xml
27 
30 class Period {
31  public:
32  virtual ~Period() = default;
33 
44  // TODO(kqyang): Move |content_protection_in_adaptation_set| to Period
45  // constructor.
46  virtual AdaptationSet* GetOrCreateAdaptationSet(
47  const MediaInfo& media_info,
48  bool content_protection_in_adaptation_set);
49 
53  xml::scoped_xml_ptr<xmlNode> GetXml(bool output_period_duration);
54 
56  const std::list<AdaptationSet*> GetAdaptationSets() const;
57 
59  double start_time_in_seconds() const { return start_time_in_seconds_; }
60 
62  double duration_seconds() const { return duration_seconds_; }
63 
65  void set_duration_seconds(double duration_seconds) {
66  duration_seconds_ = duration_seconds;
67  }
68 
69  protected:
75  Period(uint32_t period_id,
76  double start_time_in_seconds,
77  const MpdOptions& mpd_options,
78  uint32_t* representation_counter);
79 
80  private:
81  Period(const Period&) = delete;
82  Period& operator=(const Period&) = delete;
83 
84  friend class MpdBuilder;
85  friend class PeriodTest;
86 
87  // Calls AdaptationSet constructor. For mock injection.
88  virtual std::unique_ptr<AdaptationSet> NewAdaptationSet(
89  const std::string& lang,
90  const MpdOptions& options,
91  uint32_t* representation_counter);
92 
93  // Helper function to set new AdaptationSet attributes.
94  bool SetNewAdaptationSetAttributes(
95  const std::string& language,
96  const MediaInfo& media_info,
97  const std::list<AdaptationSet*>& adaptation_sets,
98  AdaptationSet* new_adaptation_set);
99 
100  // Gets the original AdaptationSet which the trick play video belongs to.
101  // It is assumed that the corresponding AdaptationSet has been created before
102  // the trick play AdaptationSet.
103  // Returns the original AdaptationSet if found, otherwise returns nullptr;
104  const AdaptationSet* FindOriginalAdaptationSetForTrickPlay(
105  const MediaInfo& media_info);
106 
107  const uint32_t id_;
108  const double start_time_in_seconds_;
109  double duration_seconds_ = 0;
110  const MpdOptions& mpd_options_;
111  uint32_t* const representation_counter_;
112  std::list<std::unique_ptr<AdaptationSet>> adaptation_sets_;
113  // AdaptationSets grouped by a specific adaptation set grouping key.
114  // AdaptationSets with the same key contain identical parameters except
115  // ContentProtection parameters. A single AdaptationSet would be created
116  // if they contain identical ContentProtection elements. This map is only
117  // useful when ContentProtection element is placed in AdaptationSet.
118  std::map<std::string, std::list<AdaptationSet*>> adaptation_set_list_map_;
119 
120  // Tracks ProtectedContent in AdaptationSet.
121  class ProtectedAdaptationSetMap {
122  public:
123  ProtectedAdaptationSetMap() = default;
124  // Register the |adaptation_set| with associated |media_info| in the map.
125  void Register(const AdaptationSet& adaptation_set,
126  const MediaInfo& media_info);
127  // Check if the protected content associated with |adaptation_set| matches
128  // with the one in |media_info|.
129  bool Match(const AdaptationSet& adaptation_set,
130  const MediaInfo& media_info);
131  // Check if the two adaptation sets are switchable.
132  bool Switchable(const AdaptationSet& adaptation_set_a,
133  const AdaptationSet& adaptation_set_b);
134 
135  private:
136  ProtectedAdaptationSetMap(const ProtectedAdaptationSetMap&) = delete;
137  ProtectedAdaptationSetMap& operator=(const ProtectedAdaptationSetMap&) =
138  delete;
139 
140  // AdaptationSet => ProtectedContent map.
141  std::map<const AdaptationSet*, MediaInfo::ProtectedContent>
142  protected_content_map_;
143  };
144  ProtectedAdaptationSetMap protected_adaptation_set_map_;
145 };
146 
147 } // namespace shaka
148 
149 #endif // PACKAGER_MPD_BASE_PERIOD_H_
-
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:37
-
All the methods that are virtual are virtual for mocking.
-
double duration_seconds() const
Definition: period.h:62
-
void set_duration_seconds(double duration_seconds)
Set period duration.
Definition: period.h:65
-
double start_time_in_seconds() const
Definition: period.h:59
-
Defines Mpd Options.
Definition: mpd_options.h:25
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
8 
+
9 #ifndef PACKAGER_MPD_BASE_PERIOD_H_
+
10 #define PACKAGER_MPD_BASE_PERIOD_H_
+
11 
+
12 #include <list>
+
13 #include <map>
+
14 
+
15 #include "packager/base/optional.h"
+
16 #include "packager/mpd/base/adaptation_set.h"
+
17 #include "packager/mpd/base/media_info.pb.h"
+
18 #include "packager/mpd/base/xml/xml_node.h"
+
19 
+
20 namespace shaka {
+
21 
+
22 struct MpdOptions;
+
23 
+
26 class Period {
+
27  public:
+
28  virtual ~Period();
+
29 
+
40  // TODO(kqyang): Move |content_protection_in_adaptation_set| to Period
+
41  // constructor.
+ +
43  const MediaInfo& media_info,
+
44  bool content_protection_in_adaptation_set);
+
45 
+
49  base::Optional<xml::XmlNode> GetXml(bool output_period_duration);
+
50 
+
52  const std::list<AdaptationSet*> GetAdaptationSets() const;
+
53 
+
55  double start_time_in_seconds() const { return start_time_in_seconds_; }
+
56 
+
58  double duration_seconds() const { return duration_seconds_; }
+
59 
+ +
62  duration_seconds_ = duration_seconds;
+
63  }
+
64 
+
66  const std::map<std::string, std::list<AdaptationSet*>>& trickplay_cache()
+
67  const {
+
68  return trickplay_cache_;
+
69  }
+
70 
+
71  protected:
+
77  Period(uint32_t period_id,
+
78  double start_time_in_seconds,
+
79  const MpdOptions& mpd_options,
+
80  uint32_t* representation_counter);
+
81 
+
82  private:
+
83  Period(const Period&) = delete;
+
84  Period& operator=(const Period&) = delete;
+
85 
+
86  friend class MpdBuilder;
+
87  friend class PeriodTest;
+
88 
+
89  // Calls AdaptationSet constructor. For mock injection.
+
90  virtual std::unique_ptr<AdaptationSet> NewAdaptationSet(
+
91  const std::string& lang,
+
92  const MpdOptions& options,
+
93  uint32_t* representation_counter);
+
94 
+
95  // Helper function to set new AdaptationSet attributes.
+
96  bool SetNewAdaptationSetAttributes(
+
97  const std::string& language,
+
98  const MediaInfo& media_info,
+
99  const std::list<AdaptationSet*>& adaptation_sets,
+
100  bool content_protection_in_adaptation_set,
+
101  AdaptationSet* new_adaptation_set);
+
102 
+
103  // If processing a trick play AdaptationSet, gets the original AdaptationSet
+
104  // which the trick play video belongs to.It is assumed that the corresponding
+
105  // AdaptationSet has been created before the trick play AdaptationSet.
+
106  // Returns the matching AdaptationSet if found, otherwise returns nullptr;
+
107  // If processing non-trick play AdaptationSet, gets the trick play
+
108  // AdaptationSet that belongs to current AdaptationSet from trick play cache.
+
109  // Returns nullptr if matching trick play AdaptationSet is not found.
+
110  AdaptationSet* FindMatchingAdaptationSetForTrickPlay(
+
111  const MediaInfo& media_info,
+
112  bool content_protection_in_adaptation_set,
+
113  std::string* adaptation_set_key);
+
114 
+
115  // Returns AdaptationSet key without ':trickplay' in it for trickplay
+
116  // AdaptationSet.
+
117  std::string GetAdaptationSetKeyForTrickPlay(const MediaInfo& media_info);
+
118 
+
119  // FindMatchingAdaptationSetForTrickPlay
+
120  const uint32_t id_;
+
121  const double start_time_in_seconds_;
+
122  double duration_seconds_ = 0;
+
123  const MpdOptions& mpd_options_;
+
124  uint32_t* const representation_counter_;
+
125  std::list<std::unique_ptr<AdaptationSet>> adaptation_sets_;
+
126  // AdaptationSets grouped by a specific adaptation set grouping key.
+
127  // AdaptationSets with the same key contain identical parameters except
+
128  // ContentProtection parameters. A single AdaptationSet would be created
+
129  // if they contain identical ContentProtection elements. This map is only
+
130  // useful when ContentProtection element is placed in AdaptationSet.
+
131  std::map<std::string, std::list<AdaptationSet*>> adaptation_set_list_map_;
+
132  // Contains Trickplay AdaptationSets grouped by specific adaptation set
+
133  // grouping key. These AdaptationSets still have not found reference
+
134  // AdaptationSet.
+
135  std::map<std::string, std::list<AdaptationSet*>> trickplay_cache_;
+
136 
+
137  // Tracks ProtectedContent in AdaptationSet.
+
138  class ProtectedAdaptationSetMap {
+
139  public:
+
140  ProtectedAdaptationSetMap() = default;
+
141  // Register the |adaptation_set| with associated |media_info| in the map.
+
142  void Register(const AdaptationSet& adaptation_set,
+
143  const MediaInfo& media_info);
+
144  // Check if the protected content associated with |adaptation_set| matches
+
145  // with the one in |media_info|.
+
146  bool Match(const AdaptationSet& adaptation_set,
+
147  const MediaInfo& media_info,
+
148  bool content_protection_in_adaptation_set);
+
149  // Check if the two adaptation sets are switchable.
+
150  bool Switchable(const AdaptationSet& adaptation_set_a,
+
151  const AdaptationSet& adaptation_set_b);
+
152 
+
153  private:
+
154  ProtectedAdaptationSetMap(const ProtectedAdaptationSetMap&) = delete;
+
155  ProtectedAdaptationSetMap& operator=(const ProtectedAdaptationSetMap&) =
+
156  delete;
+
157 
+
158  // AdaptationSet => ProtectedContent map.
+
159  std::map<const AdaptationSet*, MediaInfo::ProtectedContent>
+
160  protected_content_map_;
+
161  };
+
162  ProtectedAdaptationSetMap protected_adaptation_set_map_;
+
163 };
+
164 
+
165 } // namespace shaka
+
166 
+
167 #endif // PACKAGER_MPD_BASE_PERIOD_H_
+ +
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:36
+ +
double duration_seconds() const
Definition: period.h:58
+
void set_duration_seconds(double duration_seconds)
Set period duration.
Definition: period.h:61
+
virtual AdaptationSet * GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)
Definition: period.cc:74
+
Period(uint32_t period_id, double start_time_in_seconds, const MpdOptions &mpd_options, uint32_t *representation_counter)
Definition: period.cc:65
+
double start_time_in_seconds() const
Definition: period.h:55
+
const std::map< std::string, std::list< AdaptationSet * > > & trickplay_cache() const
Definition: period.h:66
+
base::Optional< xml::XmlNode > GetXml(bool output_period_duration)
Definition: period.cc:123
+
const std::list< AdaptationSet * > GetAdaptationSets() const
Definition: period.cc:160
+
All the methods that are virtual are virtual for mocking.
+
Defines Mpd Options.
Definition: mpd_options.h:25
diff --git a/docs/d7/d21/classshaka_1_1MockPeriod-members.html b/docs/d7/d21/classshaka_1_1MockPeriod-members.html index 1c2bd327b2..2189cd912f 100644 --- a/docs/d7/d21/classshaka_1_1MockPeriod-members.html +++ b/docs/d7/d21/classshaka_1_1MockPeriod-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
duration_seconds() constshaka::Periodinline GetAdaptationSets() constshaka::Period GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)shaka::Periodvirtual - GetXml(bool output_period_duration)shaka::Period + GetXml(bool output_period_duration)shaka::Period MOCK_METHOD2(GetOrCreateAdaptationSet, AdaptationSet *(const MediaInfo &media_info, bool content_protection_in_adaptation_set)) (defined in shaka::MockPeriod)shaka::MockPeriod MockPeriod(uint32_t period_id, double start_time_in_seconds) (defined in shaka::MockPeriod)shaka::MockPeriod Period(uint32_t period_id, double start_time_in_seconds, const MpdOptions &mpd_options, uint32_t *representation_counter)shaka::Periodprotected set_duration_seconds(double duration_seconds)shaka::Periodinline start_time_in_seconds() constshaka::Periodinline - ~Period()=default (defined in shaka::Period)shaka::Periodvirtual + trickplay_cache() constshaka::Periodinline + ~Period() (defined in shaka::Period)shaka::Periodvirtual
diff --git a/docs/d7/d22/libcrypto__threading_8h_source.html b/docs/d7/d22/libcrypto__threading_8h_source.html index 015189af31..c2c253ec43 100644 --- a/docs/d7/d22/libcrypto__threading_8h_source.html +++ b/docs/d7/d22/libcrypto__threading_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/libcrypto_threading.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
libcrypto_threading.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef APP_LIBCRYPTO_THREADING_H_
8 #define APP_LIBCRYPTO_THREADING_H_
9 
10 #include "packager/base/macros.h"
11 
12 namespace shaka {
13 namespace media {
14 
17  public:
20 
21  private:
22  DISALLOW_COPY_AND_ASSIGN(LibcryptoThreading);
23 };
24 
25 } // namespace media
26 } // namespace shaka
27 
28 #endif // APP_LIBCRYPTO_THREADING_H_
Convenience class which initializes and terminates libcrypto threading.
-
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef APP_LIBCRYPTO_THREADING_H_
+
8 #define APP_LIBCRYPTO_THREADING_H_
+
9 
+
10 #include "packager/base/macros.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+ +
17  public:
+ + +
20 
+
21  private:
+
22  DISALLOW_COPY_AND_ASSIGN(LibcryptoThreading);
+
23 };
+
24 
+
25 } // namespace media
+
26 } // namespace shaka
+
27 
+
28 #endif // APP_LIBCRYPTO_THREADING_H_
+
Convenience class which initializes and terminates libcrypto threading.
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/d26/classshaka_1_1media_1_1mp4_1_1SyncSampleIterator.html b/docs/d7/d26/classshaka_1_1media_1_1mp4_1_1SyncSampleIterator.html index b5b556a481..1f7a5da1ec 100644 --- a/docs/d7/d26/classshaka_1_1media_1_1mp4_1_1SyncSampleIterator.html +++ b/docs/d7/d26/classshaka_1_1media_1_1mp4_1_1SyncSampleIterator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SyncSampleIterator Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d7/d29/structshaka_1_1media_1_1H265Sps-members.html b/docs/d7/d29/structshaka_1_1media_1_1H265Sps-members.html index 149b8cb867..c111442db9 100644 --- a/docs/d7/d29/structshaka_1_1media_1_1H265Sps-members.html +++ b/docs/d7/d29/structshaka_1_1media_1_1H265Sps-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d7/d29/structshaka_1_1media_1_1mp4_1_1CompositionTimeToSample-members.html b/docs/d7/d29/structshaka_1_1media_1_1mp4_1_1CompositionTimeToSample-members.html index bcbd5c11df..66a0aa0abf 100644 --- a/docs/d7/d29/structshaka_1_1media_1_1mp4_1_1CompositionTimeToSample-members.html +++ b/docs/d7/d29/structshaka_1_1media_1_1mp4_1_1CompositionTimeToSample-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d7/d2a/manifest__flags_8h_source.html b/docs/d7/d2a/manifest__flags_8h_source.html index 949ed15369..2d96b31f2d 100644 --- a/docs/d7/d2a/manifest__flags_8h_source.html +++ b/docs/d7/d2a/manifest__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/manifest_flags.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
manifest_flags.h
-
1 // Copyright 2018 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Common flags applicable to both DASH and HLS.
8 
9 #ifndef PACKAGER_APP_MANIFEST_FLAGS_H_
10 #define PACKAGER_APP_MANIFEST_FLAGS_H_
11 
12 #include <gflags/gflags.h>
13 
14 DECLARE_double(time_shift_buffer_depth);
15 DECLARE_uint64(preserved_segments_outside_live_window);
16 DECLARE_string(default_language);
17 DECLARE_string(default_text_language);
18 
19 #endif // PACKAGER_APP_MANIFEST_FLAGS_H_
+
1 // Copyright 2018 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Common flags applicable to both DASH and HLS.
+
8 
+
9 #ifndef PACKAGER_APP_MANIFEST_FLAGS_H_
+
10 #define PACKAGER_APP_MANIFEST_FLAGS_H_
+
11 
+
12 #include <gflags/gflags.h>
+
13 
+
14 DECLARE_double(time_shift_buffer_depth);
+
15 DECLARE_uint64(preserved_segments_outside_live_window);
+
16 DECLARE_string(default_language);
+
17 DECLARE_string(default_text_language);
+
18 
+
19 #endif // PACKAGER_APP_MANIFEST_FLAGS_H_
+
diff --git a/docs/d7/d30/classshaka_1_1media_1_1SubtitleComposer.html b/docs/d7/d30/classshaka_1_1media_1_1SubtitleComposer.html new file mode 100644 index 0000000000..b8d3a47007 --- /dev/null +++ b/docs/d7/d30/classshaka_1_1media_1_1SubtitleComposer.html @@ -0,0 +1,126 @@ + + + + + + + +Shaka Packager SDK: shaka::media::SubtitleComposer Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::SubtitleComposer Class Reference
+
+
+ +

#include <subtitle_composer.h>

+ + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

DISALLOW_COPY_AND_ASSIGN (SubtitleComposer)
 
+void SetDisplaySize (uint16_t width, uint16_t height)
 
+bool SetRegionPosition (uint8_t region_id, uint16_t x, uint16_t y)
 
+bool SetRegionInfo (uint8_t region_id, uint8_t color_space_id, uint16_t width, uint16_t height)
 
+bool SetObjectInfo (uint16_t object_id, uint8_t region_id, uint16_t x, uint16_t y, int default_color_code)
 
+DvbImageColorSpaceGetColorSpace (uint8_t color_space_id)
 
+DvbImageColorSpaceGetColorSpaceForObject (uint16_t object_id)
 
+DvbImageBuilderGetObjectImage (uint16_t object_id)
 
+bool GetSamples (int64_t start, int64_t end, std::vector< std::shared_ptr< TextSample >> *samples) const
 
+void ClearObjects ()
 
+

Detailed Description

+

Holds pixel/caption data for a single DVB-sub page. This composes multiple objects and creates TextSample objects from it.

+ +

Definition at line 23 of file subtitle_composer.h.

+

The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/d7/d34/structshaka_1_1media_1_1EncryptionConfig.html b/docs/d7/d34/structshaka_1_1media_1_1EncryptionConfig.html index 5743e90607..91a67c314e 100644 --- a/docs/d7/d34/structshaka_1_1media_1_1EncryptionConfig.html +++ b/docs/d7/d34/structshaka_1_1media_1_1EncryptionConfig.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::EncryptionConfig Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d7/d36/classshaka_1_1media_1_1ContentEncoding-members.html b/docs/d7/d36/classshaka_1_1media_1_1ContentEncoding-members.html index 2a249ac814..e4f9621ddd 100644 --- a/docs/d7/d36/classshaka_1_1media_1_1ContentEncoding-members.html +++ b/docs/d7/d36/classshaka_1_1media_1_1ContentEncoding-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
set_scope(Scope scope) (defined in shaka::media::ContentEncoding)shaka::media::ContentEncodinginline set_type(Type type) (defined in shaka::media::ContentEncoding)shaka::media::ContentEncodinginline SetEncryptionKeyId(const uint8_t *encryption_key_id, int size) (defined in shaka::media::ContentEncoding)shaka::media::ContentEncoding - Type enum name (defined in shaka::media::ContentEncoding)shaka::media::ContentEncoding - type() const (defined in shaka::media::ContentEncoding)shaka::media::ContentEncodinginline + type() const (defined in shaka::media::ContentEncoding)shaka::media::ContentEncodinginline + Type enum name (defined in shaka::media::ContentEncoding)shaka::media::ContentEncoding ~ContentEncoding() (defined in shaka::media::ContentEncoding)shaka::media::ContentEncoding
diff --git a/docs/d7/d36/structshaka_1_1media_1_1AV1Parser_1_1Tile.html b/docs/d7/d36/structshaka_1_1media_1_1AV1Parser_1_1Tile.html index e41b7bb370..f70f772091 100644 --- a/docs/d7/d36/structshaka_1_1media_1_1AV1Parser_1_1Tile.html +++ b/docs/d7/d36/structshaka_1_1media_1_1AV1Parser_1_1Tile.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AV1Parser::Tile Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
size_in_bytes diff --git a/docs/d7/d42/protection__system__specific__info_8cc_source.html b/docs/d7/d42/protection__system__specific__info_8cc_source.html index b56ed804c6..cd5f2efb9a 100644 --- a/docs/d7/d42/protection__system__specific__info_8cc_source.html +++ b/docs/d7/d42/protection__system__specific__info_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/protection_system_specific_info.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
protection_system_specific_info.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/protection_system_specific_info.h"
8 
9 #include <map>
10 
11 #include "packager/media/base/buffer_reader.h"
12 #include "packager/media/base/buffer_writer.h"
13 #include "packager/media/base/fourccs.h"
14 #include "packager/media/base/rcheck.h"
15 
16 #define RETURN_NULL_IF_FALSE(x) \
17  do { \
18  if (!(x)) { \
19  LOG(ERROR) << "Failure while processing: " << #x; \
20  return nullptr; \
21  } \
22  } while (0)
23 
24 namespace shaka {
25 namespace media {
26 
27 namespace {
28 const size_t kSystemIdSize = 16u;
29 // 4-byte size, 4-byte fourcc, 4-byte version_and_flags.
30 const size_t kPsshBoxHeaderSize = 12u;
31 const size_t kKeyIdSize = 16u;
32 } // namespace
33 
35  const uint8_t* data,
36  size_t data_size,
37  std::vector<ProtectionSystemSpecificInfo>* pssh_infos) {
38  std::map<std::vector<uint8_t>, size_t> info_map;
39  pssh_infos->clear();
40 
41  BufferReader reader(data, data_size);
42  while (reader.HasBytes(1)) {
43  uint32_t size;
44  RCHECK(reader.Read4(&size));
45  RCHECK(reader.SkipBytes(size - 4));
46  RCHECK(size > kPsshBoxHeaderSize + kSystemIdSize);
47 
48  const std::vector<uint8_t> system_id(
49  data + kPsshBoxHeaderSize, data + kPsshBoxHeaderSize + kSystemIdSize);
50  auto iter = info_map.find(system_id);
51  if (iter != info_map.end()) {
52  ProtectionSystemSpecificInfo& info = (*pssh_infos)[iter->second];
53  info.psshs.insert(info.psshs.end(), data, data + size);
54  } else {
55  pssh_infos->push_back(
56  {system_id, std::vector<uint8_t>(data, data + size)});
57  info_map[system_id] = pssh_infos->size() - 1;
58  }
59 
60  data += size;
61  }
62 
63  return true;
64 }
65 
66 std::unique_ptr<PsshBoxBuilder> PsshBoxBuilder::ParseFromBox(
67  const uint8_t* data,
68  size_t data_size) {
69  std::unique_ptr<PsshBoxBuilder> pssh_builder(new PsshBoxBuilder);
70  BufferReader reader(data, data_size);
71 
72  uint32_t size;
73  uint32_t box_type;
74  uint32_t version_and_flags;
75  RETURN_NULL_IF_FALSE(reader.Read4(&size));
76  RETURN_NULL_IF_FALSE(reader.Read4(&box_type));
77  RETURN_NULL_IF_FALSE(box_type == FOURCC_pssh);
78  RETURN_NULL_IF_FALSE(reader.Read4(&version_and_flags));
79 
80  pssh_builder->version_ = (version_and_flags >> 24);
81  RETURN_NULL_IF_FALSE(pssh_builder->version_ < 2);
82 
83  RETURN_NULL_IF_FALSE(
84  reader.ReadToVector(&pssh_builder->system_id_, kSystemIdSize));
85 
86  if (pssh_builder->version_ == 1) {
87  uint32_t key_id_count;
88  RETURN_NULL_IF_FALSE(reader.Read4(&key_id_count));
89 
90  pssh_builder->key_ids_.resize(key_id_count);
91  for (uint32_t i = 0; i < key_id_count; i++) {
92  RETURN_NULL_IF_FALSE(
93  reader.ReadToVector(&pssh_builder->key_ids_[i], kKeyIdSize));
94  }
95  }
96 
97  // TODO: Consider parsing key IDs from Widevine PSSH data.
98  uint32_t pssh_data_size;
99  RETURN_NULL_IF_FALSE(reader.Read4(&pssh_data_size));
100  RETURN_NULL_IF_FALSE(
101  reader.ReadToVector(&pssh_builder->pssh_data_, pssh_data_size));
102 
103  // Ignore extra data if there is any.
104  return pssh_builder;
105 }
106 
107 std::vector<uint8_t> PsshBoxBuilder::CreateBox() const {
108  DCHECK_EQ(kSystemIdSize, system_id_.size());
109 
110  const uint32_t box_type = FOURCC_pssh;
111  const uint32_t version_and_flags = (static_cast<uint32_t>(version_) << 24);
112  const uint32_t pssh_data_size = pssh_data_.size();
113 
114  const uint32_t key_id_count = key_ids_.size();
115  const uint32_t key_ids_size =
116  sizeof(key_id_count) + kKeyIdSize * key_id_count;
117  const uint32_t extra_size = version_ == 1 ? key_ids_size : 0;
118 
119  const uint32_t total_size =
120  sizeof(total_size) + sizeof(box_type) + sizeof(version_and_flags) +
121  kSystemIdSize + extra_size + sizeof(pssh_data_size) + pssh_data_size;
122 
123  BufferWriter writer;
124  writer.AppendInt(total_size);
125  writer.AppendInt(box_type);
126  writer.AppendInt(version_and_flags);
127  writer.AppendVector(system_id_);
128  if (version_ == 1) {
129  writer.AppendInt(key_id_count);
130  for (size_t i = 0; i < key_id_count; i++) {
131  DCHECK_EQ(kKeyIdSize, key_ids_[i].size());
132  writer.AppendVector(key_ids_[i]);
133  }
134  }
135  writer.AppendInt(pssh_data_size);
136  writer.AppendVector(pssh_data_);
137 
138  DCHECK_EQ(total_size, writer.Size());
139  return std::vector<uint8_t>(writer.Buffer(), writer.Buffer() + writer.Size());
140 }
141 
142 } // namespace media
143 } // namespace shaka
const uint8_t * Buffer() const
Definition: buffer_writer.h:61
-
std::vector< uint8_t > CreateBox() const
Creates a PSSH box for the current data.
-
All the methods that are virtual are virtual for mocking.
- - -
bool HasBytes(size_t count)
Definition: buffer_reader.h:32
-
bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
-
static std::unique_ptr< PsshBoxBuilder > ParseFromBox(const uint8_t *data, size_t data_size)
- - - -
static bool ParseBoxes(const uint8_t *data, size_t data_size, std::vector< ProtectionSystemSpecificInfo > *pssh_boxes)
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/protection_system_specific_info.h"
+
8 
+
9 #include <map>
+
10 
+
11 #include "packager/media/base/buffer_reader.h"
+
12 #include "packager/media/base/buffer_writer.h"
+
13 #include "packager/media/base/fourccs.h"
+
14 #include "packager/media/base/rcheck.h"
+
15 
+
16 #define RETURN_NULL_IF_FALSE(x) \
+
17  do { \
+
18  if (!(x)) { \
+
19  LOG(ERROR) << "Failure while processing: " << #x; \
+
20  return nullptr; \
+
21  } \
+
22  } while (0)
+
23 
+
24 namespace shaka {
+
25 namespace media {
+
26 
+
27 namespace {
+
28 const size_t kSystemIdSize = 16u;
+
29 // 4-byte size, 4-byte fourcc, 4-byte version_and_flags.
+
30 const size_t kPsshBoxHeaderSize = 12u;
+
31 const size_t kKeyIdSize = 16u;
+
32 } // namespace
+
33 
+ +
35  const uint8_t* data,
+
36  size_t data_size,
+
37  std::vector<ProtectionSystemSpecificInfo>* pssh_infos) {
+
38  std::map<std::vector<uint8_t>, size_t> info_map;
+
39  pssh_infos->clear();
+
40 
+
41  BufferReader reader(data, data_size);
+
42  while (reader.HasBytes(1)) {
+
43  uint32_t size;
+
44  RCHECK(reader.Read4(&size));
+
45  RCHECK(reader.SkipBytes(size - 4));
+
46  RCHECK(size > kPsshBoxHeaderSize + kSystemIdSize);
+
47 
+
48  const std::vector<uint8_t> system_id(
+
49  data + kPsshBoxHeaderSize, data + kPsshBoxHeaderSize + kSystemIdSize);
+
50  auto iter = info_map.find(system_id);
+
51  if (iter != info_map.end()) {
+
52  ProtectionSystemSpecificInfo& info = (*pssh_infos)[iter->second];
+
53  info.psshs.insert(info.psshs.end(), data, data + size);
+
54  } else {
+
55  pssh_infos->push_back(
+
56  {system_id, std::vector<uint8_t>(data, data + size)});
+
57  info_map[system_id] = pssh_infos->size() - 1;
+
58  }
+
59 
+
60  data += size;
+
61  }
+
62 
+
63  return true;
+
64 }
+
65 
+
66 std::unique_ptr<PsshBoxBuilder> PsshBoxBuilder::ParseFromBox(
+
67  const uint8_t* data,
+
68  size_t data_size) {
+
69  std::unique_ptr<PsshBoxBuilder> pssh_builder(new PsshBoxBuilder);
+
70  BufferReader reader(data, data_size);
+
71 
+
72  uint32_t size;
+
73  uint32_t box_type;
+
74  uint32_t version_and_flags;
+
75  RETURN_NULL_IF_FALSE(reader.Read4(&size));
+
76  RETURN_NULL_IF_FALSE(reader.Read4(&box_type));
+
77  RETURN_NULL_IF_FALSE(box_type == FOURCC_pssh);
+
78  RETURN_NULL_IF_FALSE(reader.Read4(&version_and_flags));
+
79 
+
80  pssh_builder->version_ = (version_and_flags >> 24);
+
81  RETURN_NULL_IF_FALSE(pssh_builder->version_ < 2);
+
82 
+
83  RETURN_NULL_IF_FALSE(
+
84  reader.ReadToVector(&pssh_builder->system_id_, kSystemIdSize));
+
85 
+
86  if (pssh_builder->version_ == 1) {
+
87  uint32_t key_id_count;
+
88  RETURN_NULL_IF_FALSE(reader.Read4(&key_id_count));
+
89 
+
90  pssh_builder->key_ids_.resize(key_id_count);
+
91  for (uint32_t i = 0; i < key_id_count; i++) {
+
92  RETURN_NULL_IF_FALSE(
+
93  reader.ReadToVector(&pssh_builder->key_ids_[i], kKeyIdSize));
+
94  }
+
95  }
+
96 
+
97  // TODO: Consider parsing key IDs from Widevine PSSH data.
+
98  uint32_t pssh_data_size;
+
99  RETURN_NULL_IF_FALSE(reader.Read4(&pssh_data_size));
+
100  RETURN_NULL_IF_FALSE(
+
101  reader.ReadToVector(&pssh_builder->pssh_data_, pssh_data_size));
+
102 
+
103  // Ignore extra data if there is any.
+
104  return pssh_builder;
+
105 }
+
106 
+
107 std::vector<uint8_t> PsshBoxBuilder::CreateBox() const {
+
108  DCHECK_EQ(kSystemIdSize, system_id_.size());
+
109 
+
110  const uint32_t box_type = FOURCC_pssh;
+
111  const uint32_t version_and_flags = (static_cast<uint32_t>(version_) << 24);
+
112  const uint32_t pssh_data_size = pssh_data_.size();
+
113 
+
114  const uint32_t key_id_count = key_ids_.size();
+
115  const uint32_t key_ids_size =
+
116  sizeof(key_id_count) + kKeyIdSize * key_id_count;
+
117  const uint32_t extra_size = version_ == 1 ? key_ids_size : 0;
+
118 
+
119  const uint32_t total_size =
+
120  sizeof(total_size) + sizeof(box_type) + sizeof(version_and_flags) +
+
121  kSystemIdSize + extra_size + sizeof(pssh_data_size) + pssh_data_size;
+
122 
+
123  BufferWriter writer;
+
124  writer.AppendInt(total_size);
+
125  writer.AppendInt(box_type);
+
126  writer.AppendInt(version_and_flags);
+
127  writer.AppendVector(system_id_);
+
128  if (version_ == 1) {
+
129  writer.AppendInt(key_id_count);
+
130  for (size_t i = 0; i < key_id_count; i++) {
+
131  DCHECK_EQ(kKeyIdSize, key_ids_[i].size());
+
132  writer.AppendVector(key_ids_[i]);
+
133  }
+
134  }
+
135  writer.AppendInt(pssh_data_size);
+
136  writer.AppendVector(pssh_data_);
+
137 
+
138  DCHECK_EQ(total_size, writer.Size());
+
139  return std::vector<uint8_t>(writer.Buffer(), writer.Buffer() + writer.Size());
+
140 }
+
141 
+
142 } // namespace media
+
143 } // namespace shaka
+ +
bool HasBytes(size_t count)
Definition: buffer_reader.h:32
+
bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
+ + +
const uint8_t * Buffer() const
Definition: buffer_writer.h:61
+ +
std::vector< uint8_t > CreateBox() const
Creates a PSSH box for the current data.
+
static std::unique_ptr< PsshBoxBuilder > ParseFromBox(const uint8_t *data, size_t data_size)
+
All the methods that are virtual are virtual for mocking.
+ +
static bool ParseBoxes(const uint8_t *data, size_t data_size, std::vector< ProtectionSystemSpecificInfo > *pssh_boxes)
diff --git a/docs/d7/d42/structshaka_1_1media_1_1mp4_1_1SampleSize.html b/docs/d7/d42/structshaka_1_1media_1_1mp4_1_1SampleSize.html index 815e1abb61..8e32263187 100644 --- a/docs/d7/d42/structshaka_1_1media_1_1mp4_1_1SampleSize.html +++ b/docs/d7/d42/structshaka_1_1media_1_1mp4_1_1SampleSize.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleSize Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::mp4::FullBox shaka::media::mp4::Box - -
+ + @@ -127,7 +130,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 461 of file box_definitions.h.

+

Definition at line 474 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -155,7 +158,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 791 of file box_definitions.cc.

+

Definition at line 804 of file box_definitions.cc.

@@ -166,9 +169,7 @@ Additional Inherited Members diff --git a/docs/d7/d44/structshaka_1_1media_1_1mp4_1_1SampleEncryption-members.html b/docs/d7/d44/structshaka_1_1media_1_1mp4_1_1SampleEncryption-members.html index d04c07a537..dc621f6d81 100644 --- a/docs/d7/d44/structshaka_1_1media_1_1mp4_1_1SampleEncryption-members.html +++ b/docs/d7/d44/structshaka_1_1media_1_1mp4_1_1SampleEncryption-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d7/d46/classshaka_1_1media_1_1WebMListParser-members.html b/docs/d7/d46/classshaka_1_1media_1_1WebMListParser-members.html index 87a708bad7..9d18f8ef5f 100644 --- a/docs/d7/d46/classshaka_1_1media_1_1WebMListParser-members.html +++ b/docs/d7/d46/classshaka_1_1media_1_1WebMListParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d7/d4f/classshaka_1_1media_1_1CommonPsshGenerator-members.html b/docs/d7/d4f/classshaka_1_1media_1_1CommonPsshGenerator-members.html index 24de0e330d..54bcdf106e 100644 --- a/docs/d7/d4f/classshaka_1_1media_1_1CommonPsshGenerator-members.html +++ b/docs/d7/d4f/classshaka_1_1media_1_1CommonPsshGenerator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d7/d53/classshaka_1_1media_1_1WebVttToMp4Handler.html b/docs/d7/d53/classshaka_1_1media_1_1WebVttToMp4Handler.html index 30d9f79d7d..aeb78f2644 100644 --- a/docs/d7/d53/classshaka_1_1media_1_1WebVttToMp4Handler.html +++ b/docs/d7/d53/classshaka_1_1media_1_1WebVttToMp4Handler.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebVttToMp4Handler Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::MediaHandler - -
+ + @@ -96,9 +99,9 @@ bool  - - + + @@ -165,9 +168,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/d7/d54/classshaka_1_1media_1_1H26xByteToUnitStreamConverter-members.html b/docs/d7/d54/classshaka_1_1media_1_1H26xByteToUnitStreamConverter-members.html index e581671485..347e18a8c8 100644 --- a/docs/d7/d54/classshaka_1_1media_1_1H26xByteToUnitStreamConverter-members.html +++ b/docs/d7/d54/classshaka_1_1media_1_1H26xByteToUnitStreamConverter-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

Additional Inherited Members

 Validate if the handler is connected to its upstream handler.
 
- Static Public Member Functions inherited from shaka::media::MediaHandler
-static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
 
+static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
 
- Protected Member Functions inherited from shaka::media::MediaHandler
virtual Status OnFlushRequest (size_t input_stream_index)
- + +/* @license-end */
diff --git a/docs/d7/d59/classshaka_1_1media_1_1DecryptorSource.html b/docs/d7/d59/classshaka_1_1media_1_1DecryptorSource.html index c4fb31ef86..95745355ce 100644 --- a/docs/d7/d59/classshaka_1_1media_1_1DecryptorSource.html +++ b/docs/d7/d59/classshaka_1_1media_1_1DecryptorSource.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::DecryptorSource Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-

DecryptorSource wraps KeySource and is responsible for decryptor management. +

DecryptorSource wraps KeySource and is responsible for decryptor management. More...

#include <decryptor_source.h>

@@ -83,7 +86,7 @@ Public Member Functions  

Detailed Description

-

DecryptorSource wraps KeySource and is responsible for decryptor management.

+

DecryptorSource wraps KeySource and is responsible for decryptor management.

Definition at line 22 of file decryptor_source.h.

Constructor & Destructor Documentation

@@ -110,7 +113,7 @@ Public Member Functions
-

Constructs a DecryptorSource object.

Parameters
+

Constructs a DecryptorSource object.

Parameters
key_sourcepoints to the key source that contains the keys.
@@ -181,9 +184,7 @@ Public Member Functions
diff --git a/docs/d7/d5a/classshaka_1_1media_1_1SyncPointQueue-members.html b/docs/d7/d5a/classshaka_1_1media_1_1SyncPointQueue-members.html index 29de226f74..95890e4f3b 100644 --- a/docs/d7/d5a/classshaka_1_1media_1_1SyncPointQueue-members.html +++ b/docs/d7/d5a/classshaka_1_1media_1_1SyncPointQueue-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d7/d5c/classshaka_1_1hls_1_1SimpleHlsNotifier.html b/docs/d7/d5c/classshaka_1_1hls_1_1SimpleHlsNotifier.html index 78231b5d1c..da342487b1 100644 --- a/docs/d7/d5c/classshaka_1_1hls_1_1SimpleHlsNotifier.html +++ b/docs/d7/d5c/classshaka_1_1hls_1_1SimpleHlsNotifier.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::hls::SimpleHlsNotifier Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::hls::HlsNotifier - -
+ + @@ -96,8 +99,7 @@ Public Member Functions

Public Member Functions

const HlsParamshls_params () const
 
- + @@ -185,7 +187,7 @@ class 

-HlsNotifier implemetation overrides.

HlsNotifier implemetation overrides.

class SimpleHlsNotifierTest
 }@
shaka::hls::HlsNotifier.

-

Definition at line 499 of file simple_hls_notifier.cc.

+

Definition at line 500 of file simple_hls_notifier.cc.

@@ -215,7 +217,7 @@ class 
shaka::hls::HlsNotifier.

-

Definition at line 298 of file simple_hls_notifier.cc.

+

Definition at line 299 of file simple_hls_notifier.cc.

@@ -263,7 +265,7 @@ class 
shaka::hls::HlsNotifier.

-

Definition at line 425 of file simple_hls_notifier.cc.

+

Definition at line 426 of file simple_hls_notifier.cc.

@@ -331,7 +333,7 @@ class 
shaka::hls::HlsNotifier.

-

Definition at line 437 of file simple_hls_notifier.cc.

+

Definition at line 438 of file simple_hls_notifier.cc.

@@ -392,7 +394,7 @@ class 
shaka::hls::HlsNotifier.

-

Definition at line 410 of file simple_hls_notifier.cc.

+

Definition at line 411 of file simple_hls_notifier.cc.

@@ -467,7 +469,7 @@ class 
shaka::hls::HlsNotifier.

-

Definition at line 359 of file simple_hls_notifier.cc.

+

Definition at line 360 of file simple_hls_notifier.cc.

@@ -536,7 +538,7 @@ class 
shaka::hls::HlsNotifier.

-

Definition at line 302 of file simple_hls_notifier.cc.

+

Definition at line 303 of file simple_hls_notifier.cc.

@@ -584,7 +586,7 @@ class 
shaka::hls::HlsNotifier.

-

Definition at line 346 of file simple_hls_notifier.cc.

+

Definition at line 347 of file simple_hls_notifier.cc.

@@ -595,9 +597,7 @@ class 
diff --git a/docs/d7/d6c/structshaka_1_1HlsParams-members.html b/docs/d7/d6c/structshaka_1_1HlsParams-members.html index b1ee73217f..2f0ff4395f 100644 --- a/docs/d7/d6c/structshaka_1_1HlsParams-members.html +++ b/docs/d7/d6c/structshaka_1_1HlsParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */ diff --git a/docs/d7/d6d/classshaka_1_1media_1_1MediaSample.html b/docs/d7/d6d/classshaka_1_1media_1_1MediaSample.html index 610a4355d8..f09ef6512d 100644 --- a/docs/d7/d6d/classshaka_1_1media_1_1MediaSample.html +++ b/docs/d7/d6d/classshaka_1_1media_1_1MediaSample.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MediaSample Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
std::shared_ptr< MediaSampleClone () const - Clone the object and return a new MediaSample.
+ Clone the object and return a new MediaSample.
  void TransferData (std::shared_ptr< uint8_t > data, size_t data_size)   @@ -157,7 +160,7 @@ Static Public Member Functions   static std::shared_ptr< MediaSampleCreateEmptyMediaSample () - Create a MediaSample object with default members.
+ Create a MediaSample object with default members.
  static std::shared_ptr< MediaSampleCreateEOSBuffer ()   @@ -212,7 +215,7 @@ Protected Member Functions
-

Create a MediaSample object from input.

Parameters
+

Create a MediaSample object from input.

Parameters
@@ -276,7 +279,7 @@ Protected Member Functions
datapoints to the buffer containing the sample data. Must not be NULL.
sizeindicates sample size in bytes. Must not be negative.
-

Create a MediaSample object from input.

Parameters
+

Create a MediaSample object from input.

Parameters
@@ -313,7 +316,7 @@ Protected Member Functions
datapoints to the buffer containing the sample data. Must not be NULL.
side_datapoints to the buffer containing the additional data. Some containers allow additional data to be specified. Must not be NULL.
-

Create a MediaSample indicating we've reached end of stream. Calling any method other than end_of_stream() on the resulting buffer is disallowed.

+

Create a MediaSample indicating we've reached end of stream. Calling any method other than end_of_stream() on the resulting buffer is disallowed.

Definition at line 76 of file media_sample.cc.

@@ -352,7 +355,7 @@ Protected Member Functions
-

Create a MediaSample object from metadata. Unlike other factory methods, this cannot be a key frame. It must be only for metadata.

Parameters
+

Create a MediaSample object from metadata. Unlike other factory methods, this cannot be a key frame. It must be only for metadata.

Parameters
@@ -465,9 +468,7 @@ Protected Member Functions diff --git a/docs/d7/d6d/structshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes.html b/docs/d7/d6d/structshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes.html index 6a338ec744..0db94f7690 100644 --- a/docs/d7/d6d/structshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes.html +++ b/docs/d7/d6d/structshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::EncryptionParams::EncryptedStreamAttributes Struct Reference @@ -29,18 +29,21 @@
metadatapoints to the buffer containing metadata. Must not be NULL.
metadata_sizeis the size of metadata in bytes.
- + +/* @license-end */
-

Public Types

enum  StreamType { kUnknown, -kVideo, -kAudio +
enum  StreamType { kUnknown +, kVideo +, kAudio }
 
@@ -95,23 +98,21 @@ Public Attributes - - +
StreamType stream_type = kUnknown
 
+
union shaka::EncryptionParams::EncryptedStreamAttributes::OneOf oneof
 
 

Detailed Description

Encrypted stream information that is used to determine stream label.

-

Definition at line 145 of file crypto_params.h.

+

Definition at line 187 of file crypto_params.h.


The documentation for this struct was generated from the following file:
diff --git a/docs/d7/d72/classshaka_1_1media_1_1MockAesCryptor-members.html b/docs/d7/d72/classshaka_1_1media_1_1MockAesCryptor-members.html index 9d1b94e19e..bcde595e87 100644 --- a/docs/d7/d72/classshaka_1_1media_1_1MockAesCryptor-members.html +++ b/docs/d7/d72/classshaka_1_1media_1_1MockAesCryptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d7/d75/callback__file_8h_source.html b/docs/d7/d75/callback__file_8h_source.html index 2de3ddc540..3872ded63a 100644 --- a/docs/d7/d75/callback__file_8h_source.html +++ b/docs/d7/d75/callback__file_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/callback_file.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
callback_file.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/file/file.h"
8 
9 namespace shaka {
10 
13 class CallbackFile : public File {
14  public:
20  CallbackFile(const char* file_name, const char* mode);
21 
24  bool Close() override;
25  int64_t Read(void* buffer, uint64_t length) override;
26  int64_t Write(const void* buffer, uint64_t length) override;
27  int64_t Size() override;
28  bool Flush() override;
29  bool Seek(uint64_t position) override;
30  bool Tell(uint64_t* position) override;
32 
33  protected:
34  ~CallbackFile() override;
35 
36  bool Open() override;
37 
38  private:
39  CallbackFile(const CallbackFile&) = delete;
40  CallbackFile& operator=(const CallbackFile&) = delete;
41 
42  const BufferCallbackParams* callback_params_ = nullptr;
43  std::string name_;
44  std::string file_mode_;
45 };
46 
47 } // namespace shaka
bool Close() override
-
Define an abstract file interface.
Definition: file.h:26
-
const std::string & file_name() const
Definition: file.h:94
-
int64_t Write(const void *buffer, uint64_t length) override
-
All the methods that are virtual are virtual for mocking.
-
bool Tell(uint64_t *position) override
-
bool Flush() override
-
bool Seek(uint64_t position) override
-
bool Open() override
Internal open. Should not be used directly.
- -
int64_t Read(void *buffer, uint64_t length) override
-
CallbackFile(const char *file_name, const char *mode)
-
Buffer callback params.
-
int64_t Size() override
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/file/file.h"
+
8 
+
9 namespace shaka {
+
10 
+
13 class CallbackFile : public File {
+
14  public:
+
20  CallbackFile(const char* file_name, const char* mode);
+
21 
+
24  bool Close() override;
+
25  int64_t Read(void* buffer, uint64_t length) override;
+
26  int64_t Write(const void* buffer, uint64_t length) override;
+
27  int64_t Size() override;
+
28  bool Flush() override;
+
29  bool Seek(uint64_t position) override;
+
30  bool Tell(uint64_t* position) override;
+
32 
+
33  protected:
+
34  ~CallbackFile() override;
+
35 
+
36  bool Open() override;
+
37 
+
38  private:
+
39  CallbackFile(const CallbackFile&) = delete;
+
40  CallbackFile& operator=(const CallbackFile&) = delete;
+
41 
+
42  const BufferCallbackParams* callback_params_ = nullptr;
+
43  std::string name_;
+
44  std::string file_mode_;
+
45 };
+
46 
+
47 } // namespace shaka
+ +
CallbackFile(const char *file_name, const char *mode)
+
bool Seek(uint64_t position) override
+
int64_t Read(void *buffer, uint64_t length) override
+
int64_t Write(const void *buffer, uint64_t length) override
+
bool Close() override
+
int64_t Size() override
+
bool Open() override
Internal open. Should not be used directly.
+
bool Tell(uint64_t *position) override
+
bool Flush() override
+
Define an abstract file interface.
Definition: file.h:27
+
const std::string & file_name() const
Definition: file.h:95
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d7/d75/structshaka_1_1media_1_1mp4_1_1MediaHeader-members.html b/docs/d7/d75/structshaka_1_1media_1_1mp4_1_1MediaHeader-members.html index 831dfb44b8..e7f1320a6d 100644 --- a/docs/d7/d75/structshaka_1_1media_1_1mp4_1_1MediaHeader-members.html +++ b/docs/d7/d75/structshaka_1_1media_1_1mp4_1_1MediaHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d7/d78/structshaka_1_1media_1_1H264SEIMessage-members.html b/docs/d7/d78/structshaka_1_1media_1_1H264SEIMessage-members.html index ac98bdefab..637b3f7fed 100644 --- a/docs/d7/d78/structshaka_1_1media_1_1H264SEIMessage-members.html +++ b/docs/d7/d78/structshaka_1_1media_1_1H264SEIMessage-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */ diff --git a/docs/d7/d79/chunking__handler_8h_source.html b/docs/d7/d79/chunking__handler_8h_source.html index 675100ac6a..d41ea395b3 100644 --- a/docs/d7/d79/chunking__handler_8h_source.html +++ b/docs/d7/d79/chunking__handler_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking/chunking_handler.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
chunking_handler.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CHUNKING_CHUNKING_HANDLER_
8 #define PACKAGER_MEDIA_CHUNKING_CHUNKING_HANDLER_
9 
10 #include <atomic>
11 #include <queue>
12 
13 #include "packager/base/logging.h"
14 #include "packager/base/optional.h"
15 #include "packager/media/base/media_handler.h"
16 #include "packager/media/public/chunking_params.h"
17 
18 namespace shaka {
19 namespace media {
20 
39 class ChunkingHandler : public MediaHandler {
40  public:
41  explicit ChunkingHandler(const ChunkingParams& chunking_params);
42  ~ChunkingHandler() override = default;
43 
44  protected:
47  Status InitializeInternal() override;
48  Status Process(std::unique_ptr<StreamData> stream_data) override;
49  Status OnFlushRequest(size_t input_stream_index) override;
51 
52  private:
53  friend class ChunkingHandlerTest;
54 
55  ChunkingHandler(const ChunkingHandler&) = delete;
56  ChunkingHandler& operator=(const ChunkingHandler&) = delete;
57 
58  Status OnStreamInfo(std::shared_ptr<const StreamInfo> info);
59  Status OnCueEvent(std::shared_ptr<const CueEvent> event);
60  Status OnMediaSample(std::shared_ptr<const MediaSample> sample);
61 
62  Status EndSegmentIfStarted() const;
63  Status EndSubsegmentIfStarted() const;
64 
65  bool IsSubsegmentEnabled() {
66  return subsegment_duration_ > 0 &&
67  subsegment_duration_ != segment_duration_;
68  }
69 
70  const ChunkingParams chunking_params_;
71 
72  // Segment and subsegment duration in stream's time scale.
73  int64_t segment_duration_ = 0;
74  int64_t subsegment_duration_ = 0;
75 
76  // Current segment index, useful to determine where to do chunking.
77  int64_t current_segment_index_ = -1;
78  // Current subsegment index, useful to determine where to do chunking.
79  int64_t current_subsegment_index_ = -1;
80 
81  base::Optional<int64_t> segment_start_time_;
82  base::Optional<int64_t> subsegment_start_time_;
83  int64_t max_segment_time_ = 0;
84  uint32_t time_scale_ = 0;
85 
86  // The offset is applied to sample timestamps so a full segment is generated
87  // after cue points.
88  int64_t cue_offset_ = 0;
89 };
90 
91 } // namespace media
92 } // namespace shaka
93 
94 #endif // PACKAGER_MEDIA_CHUNKING_CHUNKING_HANDLER_
Status Process(std::unique_ptr< StreamData > stream_data) override
-
Status InitializeInternal() override
- -
All the methods that are virtual are virtual for mocking.
- -
Status OnFlushRequest(size_t input_stream_index) override
Event handler for flush request at the specific input stream index.
-
Chunking (segmentation) related parameters.
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CHUNKING_CHUNKING_HANDLER_
+
8 #define PACKAGER_MEDIA_CHUNKING_CHUNKING_HANDLER_
+
9 
+
10 #include <atomic>
+
11 #include <queue>
+
12 
+
13 #include "packager/base/logging.h"
+
14 #include "packager/base/optional.h"
+
15 #include "packager/media/base/media_handler.h"
+
16 #include "packager/media/public/chunking_params.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 
+
39 class ChunkingHandler : public MediaHandler {
+
40  public:
+
41  explicit ChunkingHandler(const ChunkingParams& chunking_params);
+
42  ~ChunkingHandler() override = default;
+
43 
+
44  protected:
+
47  Status InitializeInternal() override;
+
48  Status Process(std::unique_ptr<StreamData> stream_data) override;
+
49  Status OnFlushRequest(size_t input_stream_index) override;
+
51 
+
52  private:
+
53  friend class ChunkingHandlerTest;
+
54 
+
55  ChunkingHandler(const ChunkingHandler&) = delete;
+
56  ChunkingHandler& operator=(const ChunkingHandler&) = delete;
+
57 
+
58  Status OnStreamInfo(std::shared_ptr<const StreamInfo> info);
+
59  Status OnCueEvent(std::shared_ptr<const CueEvent> event);
+
60  Status OnMediaSample(std::shared_ptr<const MediaSample> sample);
+
61 
+
62  Status EndSegmentIfStarted() const;
+
63  Status EndSubsegmentIfStarted() const;
+
64 
+
65  bool IsSubsegmentEnabled() {
+
66  return subsegment_duration_ > 0 &&
+
67  subsegment_duration_ != segment_duration_;
+
68  }
+
69 
+
70  const ChunkingParams chunking_params_;
+
71 
+
72  // Segment and subsegment duration in stream's time scale.
+
73  int64_t segment_duration_ = 0;
+
74  int64_t subsegment_duration_ = 0;
+
75 
+
76  // Current segment index, useful to determine where to do chunking.
+
77  int64_t current_segment_index_ = -1;
+
78  // Current subsegment index, useful to determine where to do chunking.
+
79  int64_t current_subsegment_index_ = -1;
+
80 
+
81  base::Optional<int64_t> segment_start_time_;
+
82  base::Optional<int64_t> subsegment_start_time_;
+
83  int64_t max_segment_time_ = 0;
+
84  uint32_t time_scale_ = 0;
+
85 
+
86  // The offset is applied to sample timestamps so a full segment is generated
+
87  // after cue points.
+
88  int64_t cue_offset_ = 0;
+
89 };
+
90 
+
91 } // namespace media
+
92 } // namespace shaka
+
93 
+
94 #endif // PACKAGER_MEDIA_CHUNKING_CHUNKING_HANDLER_
+ + +
Status Process(std::unique_ptr< StreamData > stream_data) override
+
Status InitializeInternal() override
+
Status OnFlushRequest(size_t input_stream_index) override
Event handler for flush request at the specific input stream index.
+ +
All the methods that are virtual are virtual for mocking.
+
Chunking (segmentation) related parameters.
diff --git a/docs/d7/d7c/vlog__flags_8h_source.html b/docs/d7/d7c/vlog__flags_8h_source.html index b0482859dc..79bcdabfa2 100644 --- a/docs/d7/d7c/vlog__flags_8h_source.html +++ b/docs/d7/d7c/vlog__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/vlog_flags.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
vlog_flags.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef APP_VLOG_FLAGS_H_
8 #define APP_VLOG_FLAGS_H_
9 
10 #include <gflags/gflags.h>
11 
12 DECLARE_int32(v);
13 DECLARE_string(vmodule);
14 
15 #endif // APP_VLOG_FLAGS_H_
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef APP_VLOG_FLAGS_H_
+
8 #define APP_VLOG_FLAGS_H_
+
9 
+
10 #include <gflags/gflags.h>
+
11 
+
12 DECLARE_int32(v);
+
13 DECLARE_string(vmodule);
+
14 
+
15 #endif // APP_VLOG_FLAGS_H_
+
diff --git a/docs/d7/d87/video__stream__info_8h_source.html b/docs/d7/d87/video__stream__info_8h_source.html index b42c1b20ac..8aa760aa81 100644 --- a/docs/d7/d87/video__stream__info_8h_source.html +++ b/docs/d7/d87/video__stream__info_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/video_stream_info.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
video_stream_info.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_VIDEO_STREAM_INFO_H_
8 #define PACKAGER_MEDIA_BASE_VIDEO_STREAM_INFO_H_
9 
10 #include "packager/media/base/stream_info.h"
11 
12 namespace shaka {
13 namespace media {
14 
15 enum class H26xStreamFormat {
16  kUnSpecified,
17  kAnnexbByteStream,
18  kNalUnitStreamWithParameterSetNalus,
19  kNalUnitStreamWithoutParameterSetNalus,
20 };
21 
23 class VideoStreamInfo : public StreamInfo {
24  public:
25  VideoStreamInfo() = default;
26 
30  VideoStreamInfo(int track_id,
31  uint32_t time_scale,
32  uint64_t duration,
33  Codec codec,
34  H26xStreamFormat h26x_stream_format,
35  const std::string& codec_string,
36  const uint8_t* codec_config,
37  size_t codec_config_size,
38  uint16_t width,
39  uint16_t height,
40  uint32_t pixel_width,
41  uint32_t pixel_height,
42  uint8_t transfer_characteristics,
43  uint32_t trick_play_factor,
44  uint8_t nalu_length_size,
45  const std::string& language,
46  bool is_encrypted);
47 
48  ~VideoStreamInfo() override;
49 
52  bool IsValidConfig() const override;
53  std::string ToString() const override;
54  std::unique_ptr<StreamInfo> Clone() const override;
56 
57  const std::vector<uint8_t>& extra_config() const { return extra_config_; }
58  H26xStreamFormat h26x_stream_format() const { return h26x_stream_format_; }
59  uint16_t width() const { return width_; }
60  uint16_t height() const { return height_; }
63  uint32_t pixel_width() const { return pixel_width_; }
66  uint32_t pixel_height() const { return pixel_height_; }
67  uint8_t transfer_characteristics() const { return transfer_characteristics_; }
68  uint8_t nalu_length_size() const { return nalu_length_size_; }
69  uint32_t trick_play_factor() const { return trick_play_factor_; }
70  uint32_t playback_rate() const { return playback_rate_; }
71  const std::vector<uint8_t>& eme_init_data() const { return eme_init_data_; }
72 
73  void set_extra_config(const std::vector<uint8_t>& extra_config) {
74  extra_config_ = extra_config;
75  }
76  void set_width(uint32_t width) { width_ = width; }
77  void set_height(uint32_t height) { height_ = height; }
78  void set_pixel_width(uint32_t pixel_width) { pixel_width_ = pixel_width; }
79  void set_pixel_height(uint32_t pixel_height) { pixel_height_ = pixel_height; }
80  void set_transfer_characteristics(uint8_t transfer_characteristics) {
81  transfer_characteristics_ = transfer_characteristics;
82  }
83  void set_trick_play_factor(uint32_t trick_play_factor) {
84  trick_play_factor_ = trick_play_factor;
85  }
86  void set_playback_rate(uint32_t playback_rate) {
87  playback_rate_ = playback_rate;
88  }
89  void set_eme_init_data(const uint8_t* eme_init_data,
90  size_t eme_init_data_size) {
91  eme_init_data_.assign(eme_init_data, eme_init_data + eme_init_data_size);
92  }
93 
94  private:
95  // Extra codec configuration in a stream of mp4 boxes. It is only applicable
96  // to mp4 container only. It is needed by some codecs, e.g. Dolby Vision.
97  std::vector<uint8_t> extra_config_;
98  H26xStreamFormat h26x_stream_format_;
99  uint16_t width_;
100  uint16_t height_;
101 
102  // pixel_width_:pixel_height_ is the sample aspect ratio.
103  // 0 means unknown.
104  uint32_t pixel_width_;
105  uint32_t pixel_height_;
106  uint8_t transfer_characteristics_ = 0;
107  uint32_t trick_play_factor_ = 0; // Non-zero for trick-play streams.
108 
109  // Playback rate is the attribute for trick play stream, which signals the
110  // playout capabilities
111  // (http://dashif.org/wp-content/uploads/2016/12/DASH-IF-IOP-v4.0-clean.pdf,
112  // page 18, line 1). It is the ratio of main frame rate to the trick play
113  // frame rate. If the time scale and frame duration are not modified after
114  // trick play handler processing, the playback_rate equals to the number of
115  // frames between consecutive key frames selected for trick play stream. For
116  // example, if the video stream has GOP size of 10 and the trick play factor
117  // is 3, the key frames are in this trick play stream are [frame_0, frame_30,
118  // frame_60, ...]. Then the playback_rate is 30.
119  // Non-zero for trick-play streams.
120  uint32_t playback_rate_ = 0;
121 
122  // Specifies the size of the NAL unit length field. Can be 1, 2 or 4 bytes, or
123  // 0 if the stream is not a NAL structured video stream or if it is an AnnexB
124  // byte stream.
125  uint8_t nalu_length_size_;
126 
127  // Container-specific data used by CDM to generate a license request:
128  // https://w3c.github.io/encrypted-media/#initialization-data.
129  std::vector<uint8_t> eme_init_data_;
130 
131  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
132  // generated copy constructor and assignment operator. Since the extra data is
133  // typically small, the performance impact is minimal.
134 };
135 
136 } // namespace media
137 } // namespace shaka
138 
139 #endif // PACKAGER_MEDIA_BASE_VIDEO_STREAM_INFO_H_
Abstract class holds stream information.
Definition: stream_info.h:62
-
All the methods that are virtual are virtual for mocking.
- - -
Holds video stream information.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_VIDEO_STREAM_INFO_H_
+
8 #define PACKAGER_MEDIA_BASE_VIDEO_STREAM_INFO_H_
+
9 
+
10 #include "packager/media/base/stream_info.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+
15 enum class H26xStreamFormat {
+
16  kUnSpecified,
+
17  kAnnexbByteStream,
+
18  kNalUnitStreamWithParameterSetNalus,
+
19  kNalUnitStreamWithoutParameterSetNalus,
+
20 };
+
21 
+
23 class VideoStreamInfo : public StreamInfo {
+
24  public:
+
25  VideoStreamInfo() = default;
+
26 
+
30  VideoStreamInfo(int track_id,
+
31  uint32_t time_scale,
+
32  uint64_t duration,
+
33  Codec codec,
+
34  H26xStreamFormat h26x_stream_format,
+
35  const std::string& codec_string,
+
36  const uint8_t* codec_config,
+
37  size_t codec_config_size,
+
38  uint16_t width,
+
39  uint16_t height,
+
40  uint32_t pixel_width,
+
41  uint32_t pixel_height,
+
42  uint8_t transfer_characteristics,
+
43  uint32_t trick_play_factor,
+
44  uint8_t nalu_length_size,
+
45  const std::string& language,
+
46  bool is_encrypted);
+
47 
+
48  ~VideoStreamInfo() override;
+
49 
+
52  bool IsValidConfig() const override;
+
53  std::string ToString() const override;
+
54  std::unique_ptr<StreamInfo> Clone() const override;
+
56 
+
57  const std::vector<uint8_t>& extra_config() const { return extra_config_; }
+
58  H26xStreamFormat h26x_stream_format() const { return h26x_stream_format_; }
+
59  uint16_t width() const { return width_; }
+
60  uint16_t height() const { return height_; }
+
63  uint32_t pixel_width() const { return pixel_width_; }
+
66  uint32_t pixel_height() const { return pixel_height_; }
+
67  uint8_t transfer_characteristics() const { return transfer_characteristics_; }
+
68  uint8_t nalu_length_size() const { return nalu_length_size_; }
+
69  uint32_t trick_play_factor() const { return trick_play_factor_; }
+
70  uint32_t playback_rate() const { return playback_rate_; }
+
71  const std::vector<uint8_t>& eme_init_data() const { return eme_init_data_; }
+
72 
+
73  void set_extra_config(const std::vector<uint8_t>& extra_config) {
+
74  extra_config_ = extra_config;
+
75  }
+
76  void set_width(uint32_t width) { width_ = width; }
+
77  void set_height(uint32_t height) { height_ = height; }
+
78  void set_pixel_width(uint32_t pixel_width) { pixel_width_ = pixel_width; }
+
79  void set_pixel_height(uint32_t pixel_height) { pixel_height_ = pixel_height; }
+
80  void set_transfer_characteristics(uint8_t transfer_characteristics) {
+
81  transfer_characteristics_ = transfer_characteristics;
+
82  }
+
83  void set_trick_play_factor(uint32_t trick_play_factor) {
+
84  trick_play_factor_ = trick_play_factor;
+
85  }
+
86  void set_playback_rate(uint32_t playback_rate) {
+
87  playback_rate_ = playback_rate;
+
88  }
+
89  void set_eme_init_data(const uint8_t* eme_init_data,
+
90  size_t eme_init_data_size) {
+
91  eme_init_data_.assign(eme_init_data, eme_init_data + eme_init_data_size);
+
92  }
+
93 
+
94  private:
+
95  // Extra codec configuration in a stream of mp4 boxes. It is only applicable
+
96  // to mp4 container only. It is needed by some codecs, e.g. Dolby Vision.
+
97  std::vector<uint8_t> extra_config_;
+
98  H26xStreamFormat h26x_stream_format_;
+
99  uint16_t width_;
+
100  uint16_t height_;
+
101 
+
102  // pixel_width_:pixel_height_ is the sample aspect ratio.
+
103  // 0 means unknown.
+
104  uint32_t pixel_width_;
+
105  uint32_t pixel_height_;
+
106  uint8_t transfer_characteristics_ = 0;
+
107  uint32_t trick_play_factor_ = 0; // Non-zero for trick-play streams.
+
108 
+
109  // Playback rate is the attribute for trick play stream, which signals the
+
110  // playout capabilities
+
111  // (http://dashif.org/wp-content/uploads/2016/12/DASH-IF-IOP-v4.0-clean.pdf,
+
112  // page 18, line 1). It is the ratio of main frame rate to the trick play
+
113  // frame rate. If the time scale and frame duration are not modified after
+
114  // trick play handler processing, the playback_rate equals to the number of
+
115  // frames between consecutive key frames selected for trick play stream. For
+
116  // example, if the video stream has GOP size of 10 and the trick play factor
+
117  // is 3, the key frames are in this trick play stream are [frame_0, frame_30,
+
118  // frame_60, ...]. Then the playback_rate is 30.
+
119  // Non-zero for trick-play streams.
+
120  uint32_t playback_rate_ = 0;
+
121 
+
122  // Specifies the size of the NAL unit length field. Can be 1, 2 or 4 bytes, or
+
123  // 0 if the stream is not a NAL structured video stream or if it is an AnnexB
+
124  // byte stream.
+
125  uint8_t nalu_length_size_;
+
126 
+
127  // Container-specific data used by CDM to generate a license request:
+
128  // https://w3c.github.io/encrypted-media/#initialization-data.
+
129  std::vector<uint8_t> eme_init_data_;
+
130 
+
131  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
+
132  // generated copy constructor and assignment operator. Since the extra data is
+
133  // typically small, the performance impact is minimal.
+
134 };
+
135 
+
136 } // namespace media
+
137 } // namespace shaka
+
138 
+
139 #endif // PACKAGER_MEDIA_BASE_VIDEO_STREAM_INFO_H_
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
Holds video stream information.
+
std::unique_ptr< StreamInfo > Clone() const override
+ +
bool IsValidConfig() const override
+
std::string ToString() const override
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/d91/text__padder_8h_source.html b/docs/d7/d91/text__padder_8h_source.html index 6c9dba5a35..c42de866d5 100644 --- a/docs/d7/d91/text__padder_8h_source.html +++ b/docs/d7/d91/text__padder_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/text_padder.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
text_padder.h
-
1 // Copyright 2018 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_TEXT_PADDER_H_
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_TEXT_PADDER_H_
9 
10 #include "packager/media/base/media_handler.h"
11 
12 namespace shaka {
13 namespace media {
14 
17 class TextPadder : public MediaHandler {
18  public:
27  explicit TextPadder(int64_t zero_start_bias_ms);
28  ~TextPadder() override = default;
29 
30  private:
31  TextPadder(const TextPadder&) = delete;
32  TextPadder& operator=(const TextPadder&) = delete;
33 
34  Status InitializeInternal() override;
35 
36  Status Process(std::unique_ptr<StreamData> data) override;
37  Status OnTextSample(std::unique_ptr<StreamData> data);
38 
39  const int64_t zero_start_bias_ms_;
40  // Will be set once we see our first sample. Using -1 to signal that we have
41  // not seen the first sample yet.
42  int64_t max_end_time_ms_ = -1;
43 };
44 
45 } // namespace media
46 } // namespace shaka
47 
48 #endif // MEDIA_FORMATS_WEBVTT_TEXT_PADDER_H_
-
All the methods that are virtual are virtual for mocking.
- -
TextPadder(int64_t zero_start_bias_ms)
Definition: text_padder.cc:19
- +
1 // Copyright 2018 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_TEXT_PADDER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_TEXT_PADDER_H_
+
9 
+
10 #include "packager/media/base/media_handler.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+
17 class TextPadder : public MediaHandler {
+
18  public:
+
27  explicit TextPadder(int64_t zero_start_bias_ms);
+
28  ~TextPadder() override = default;
+
29 
+
30  private:
+
31  TextPadder(const TextPadder&) = delete;
+
32  TextPadder& operator=(const TextPadder&) = delete;
+
33 
+
34  Status InitializeInternal() override;
+
35 
+
36  Status Process(std::unique_ptr<StreamData> data) override;
+
37  Status OnTextSample(std::unique_ptr<StreamData> data);
+
38 
+
39  const int64_t zero_start_bias_ms_;
+
40  // Will be set once we see our first sample. Using -1 to signal that we have
+
41  // not seen the first sample yet.
+
42  int64_t max_end_time_ms_ = -1;
+
43 };
+
44 
+
45 } // namespace media
+
46 } // namespace shaka
+
47 
+
48 #endif // MEDIA_FORMATS_WEBVTT_TEXT_PADDER_H_
+ + + +
TextPadder(int64_t zero_start_bias_ms)
Definition: text_padder.cc:19
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/d94/classshaka_1_1media_1_1CachingMediaHandler.html b/docs/d7/d94/classshaka_1_1media_1_1CachingMediaHandler.html index 24bc765a93..ec5f7a139d 100644 --- a/docs/d7/d94/classshaka_1_1media_1_1CachingMediaHandler.html +++ b/docs/d7/d94/classshaka_1_1media_1_1CachingMediaHandler.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::CachingMediaHandler Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::MediaHandler - -
+ + @@ -106,9 +109,9 @@ bool  - - + + @@ -159,7 +162,7 @@ const std::map< size_t, std::pair< std::shared_ptr<

Detailed Description

-

Definition at line 273 of file media_handler_test_base.h.

+

Definition at line 269 of file media_handler_test_base.h.


The documentation for this class was generated from the following files:
  • packager/media/base/media_handler_test_base.h
  • packager/media/base/media_handler_test_base.cc
  • @@ -167,9 +170,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/d7/d94/representation_8cc_source.html b/docs/d7/d94/representation_8cc_source.html index f03d2538a8..9def55cd63 100644 --- a/docs/d7/d94/representation_8cc_source.html +++ b/docs/d7/d94/representation_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/representation.cc Source File @@ -29,18 +29,21 @@

Public Member Functions

Additional Inherited Members

- Static Public Member Functions inherited from shaka::media::MediaHandler
-static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
 
+static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
 
- Protected Member Functions inherited from shaka::media::MediaHandler
Status Dispatch (std::unique_ptr< StreamData > stream_data) const
 
- + +/* @license-end */
representation.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/mpd/base/representation.h"
8 
9 #include <gflags/gflags.h>
10 
11 #include <algorithm>
12 
13 #include "packager/base/logging.h"
14 #include "packager/base/strings/stringprintf.h"
15 #include "packager/file/file.h"
16 #include "packager/media/base/muxer_util.h"
17 #include "packager/mpd/base/mpd_options.h"
18 #include "packager/mpd/base/mpd_utils.h"
19 #include "packager/mpd/base/xml/xml_node.h"
20 
21 namespace shaka {
22 namespace {
23 
24 std::string GetMimeType(const std::string& prefix,
25  MediaInfo::ContainerType container_type) {
26  switch (container_type) {
27  case MediaInfo::CONTAINER_MP4:
28  return prefix + "/mp4";
29  case MediaInfo::CONTAINER_MPEG2_TS:
30  // NOTE: DASH MPD spec uses lowercase but RFC3555 says uppercase.
31  return prefix + "/MP2T";
32  case MediaInfo::CONTAINER_WEBM:
33  return prefix + "/webm";
34  default:
35  break;
36  }
37 
38  // Unsupported container types should be rejected/handled by the caller.
39  LOG(ERROR) << "Unrecognized container type: " << container_type;
40  return std::string();
41 }
42 
43 // Check whether the video info has width and height.
44 // DASH IOP also requires several other fields for video representations, namely
45 // width, height, framerate, and sar.
46 bool HasRequiredVideoFields(const MediaInfo_VideoInfo& video_info) {
47  if (!video_info.has_height() || !video_info.has_width()) {
48  LOG(ERROR)
49  << "Width and height are required fields for generating a valid MPD.";
50  return false;
51  }
52  // These fields are not required for a valid MPD, but required for DASH IOP
53  // compliant MPD. MpdBuilder can keep generating MPDs without these fields.
54  LOG_IF(WARNING, !video_info.has_time_scale())
55  << "Video info does not contain timescale required for "
56  "calculating framerate. @frameRate is required for DASH IOP.";
57  LOG_IF(WARNING, !video_info.has_pixel_width())
58  << "Video info does not contain pixel_width to calculate the sample "
59  "aspect ratio required for DASH IOP.";
60  LOG_IF(WARNING, !video_info.has_pixel_height())
61  << "Video info does not contain pixel_height to calculate the sample "
62  "aspect ratio required for DASH IOP.";
63  return true;
64 }
65 
66 uint32_t GetTimeScale(const MediaInfo& media_info) {
67  if (media_info.has_reference_time_scale()) {
68  return media_info.reference_time_scale();
69  }
70 
71  if (media_info.has_video_info()) {
72  return media_info.video_info().time_scale();
73  }
74 
75  if (media_info.has_audio_info()) {
76  return media_info.audio_info().time_scale();
77  }
78 
79  LOG(WARNING) << "No timescale specified, using 1 as timescale.";
80  return 1;
81 }
82 
83 } // namespace
84 
86  const MediaInfo& media_info,
87  const MpdOptions& mpd_options,
88  uint32_t id,
89  std::unique_ptr<RepresentationStateChangeListener> state_change_listener)
90  : media_info_(media_info),
91  id_(id),
92  mpd_options_(mpd_options),
93  state_change_listener_(std::move(state_change_listener)),
94  allow_approximate_segment_timeline_(
95  // TODO(kqyang): Need a better check. $Time is legitimate but not a
96  // template.
97  media_info.segment_template().find("$Time") == std::string::npos &&
98  mpd_options_.mpd_params.allow_approximate_segment_timeline) {}
99 
101  const Representation& representation,
102  std::unique_ptr<RepresentationStateChangeListener> state_change_listener)
103  : Representation(representation.media_info_,
104  representation.mpd_options_,
105  representation.id_,
106  std::move(state_change_listener)) {
107  mime_type_ = representation.mime_type_;
108  codecs_ = representation.codecs_;
109 
110  start_number_ = representation.start_number_;
111  for (const SegmentInfo& segment_info : representation.segment_infos_)
112  start_number_ += segment_info.repeat + 1;
113 }
114 
115 Representation::~Representation() {}
116 
118  if (!AtLeastOneTrue(media_info_.has_video_info(),
119  media_info_.has_audio_info(),
120  media_info_.has_text_info())) {
121  // This is an error. Segment information can be in AdaptationSet, Period, or
122  // MPD but the interface does not provide a way to set them.
123  // See 5.3.9.1 ISO 23009-1:2012 for segment info.
124  LOG(ERROR) << "Representation needs one of video, audio, or text.";
125  return false;
126  }
127 
128  if (MoreThanOneTrue(media_info_.has_video_info(),
129  media_info_.has_audio_info(),
130  media_info_.has_text_info())) {
131  LOG(ERROR) << "Only one of VideoInfo, AudioInfo, or TextInfo can be set.";
132  return false;
133  }
134 
135  if (media_info_.container_type() == MediaInfo::CONTAINER_UNKNOWN) {
136  LOG(ERROR) << "'container_type' in MediaInfo cannot be CONTAINER_UNKNOWN.";
137  return false;
138  }
139 
140  if (media_info_.has_video_info()) {
141  mime_type_ = GetVideoMimeType();
142  if (!HasRequiredVideoFields(media_info_.video_info())) {
143  LOG(ERROR) << "Missing required fields to create a video Representation.";
144  return false;
145  }
146  } else if (media_info_.has_audio_info()) {
147  mime_type_ = GetAudioMimeType();
148  } else if (media_info_.has_text_info()) {
149  mime_type_ = GetTextMimeType();
150  }
151 
152  if (mime_type_.empty())
153  return false;
154 
155  codecs_ = GetCodecs(media_info_);
156  return true;
157 }
158 
160  const ContentProtectionElement& content_protection_element) {
161  content_protection_elements_.push_back(content_protection_element);
162  RemoveDuplicateAttributes(&content_protection_elements_.back());
163 }
164 
165 void Representation::UpdateContentProtectionPssh(const std::string& drm_uuid,
166  const std::string& pssh) {
167  UpdateContentProtectionPsshHelper(drm_uuid, pssh,
168  &content_protection_elements_);
169 }
170 
171 void Representation::AddNewSegment(int64_t start_time,
172  int64_t duration,
173  uint64_t size) {
174  if (start_time == 0 && duration == 0) {
175  LOG(WARNING) << "Got segment with start_time and duration == 0. Ignoring.";
176  return;
177  }
178 
179  // In order for the oldest segment to be accessible for at least
180  // |time_shift_buffer_depth| seconds, the latest segment should not be in the
181  // sliding window since the player could be playing any part of the latest
182  // segment. So the current segment duration is added to the sum of segment
183  // durations (in the manifest/playlist) after sliding the window.
184  SlideWindow();
185 
186  if (state_change_listener_)
187  state_change_listener_->OnNewSegmentForRepresentation(start_time, duration);
188 
189  AddSegmentInfo(start_time, duration);
190  current_buffer_depth_ += segment_infos_.back().duration;
191 
192  bandwidth_estimator_.AddBlock(
193  size, static_cast<double>(duration) / media_info_.reference_time_scale());
194 }
195 
196 void Representation::SetSampleDuration(uint32_t frame_duration) {
197  // Sample duration is used to generate approximate SegmentTimeline.
198  // Text is required to have exactly the same segment duration.
199  if (media_info_.has_audio_info() || media_info_.has_video_info())
200  frame_duration_ = frame_duration;
201 
202  if (media_info_.has_video_info()) {
203  media_info_.mutable_video_info()->set_frame_duration(frame_duration);
204  if (state_change_listener_) {
205  state_change_listener_->OnSetFrameRateForRepresentation(
206  frame_duration, media_info_.video_info().time_scale());
207  }
208  }
209 }
210 
211 const MediaInfo& Representation::GetMediaInfo() const {
212  return media_info_;
213 }
214 
215 // Uses info in |media_info_| and |content_protection_elements_| to create a
216 // "Representation" node.
217 // MPD schema has strict ordering. The following must be done in order.
218 // AddVideoInfo() (possibly adds FramePacking elements), AddAudioInfo() (Adds
219 // AudioChannelConfig elements), AddContentProtectionElements*(), and
220 // AddVODOnlyInfo() (Adds segment info).
221 xml::scoped_xml_ptr<xmlNode> Representation::GetXml() {
222  if (!HasRequiredMediaInfoFields()) {
223  LOG(ERROR) << "MediaInfo missing required fields.";
224  return xml::scoped_xml_ptr<xmlNode>();
225  }
226 
227  const uint64_t bandwidth = media_info_.has_bandwidth()
228  ? media_info_.bandwidth()
229  : bandwidth_estimator_.Max();
230 
231  DCHECK(!(HasVODOnlyFields(media_info_) && HasLiveOnlyFields(media_info_)));
232 
233  xml::RepresentationXmlNode representation;
234  // Mandatory fields for Representation.
235  representation.SetId(id_);
236  representation.SetIntegerAttribute("bandwidth", bandwidth);
237  if (!codecs_.empty())
238  representation.SetStringAttribute("codecs", codecs_);
239  representation.SetStringAttribute("mimeType", mime_type_);
240 
241  const bool has_video_info = media_info_.has_video_info();
242  const bool has_audio_info = media_info_.has_audio_info();
243 
244  if (has_video_info &&
245  !representation.AddVideoInfo(
246  media_info_.video_info(),
247  !(output_suppression_flags_ & kSuppressWidth),
248  !(output_suppression_flags_ & kSuppressHeight),
249  !(output_suppression_flags_ & kSuppressFrameRate))) {
250  LOG(ERROR) << "Failed to add video info to Representation XML.";
251  return xml::scoped_xml_ptr<xmlNode>();
252  }
253 
254  if (has_audio_info &&
255  !representation.AddAudioInfo(media_info_.audio_info())) {
256  LOG(ERROR) << "Failed to add audio info to Representation XML.";
257  return xml::scoped_xml_ptr<xmlNode>();
258  }
259 
260  if (!representation.AddContentProtectionElements(
261  content_protection_elements_)) {
262  return xml::scoped_xml_ptr<xmlNode>();
263  }
264 
265  if (HasVODOnlyFields(media_info_) &&
266  !representation.AddVODOnlyInfo(media_info_)) {
267  LOG(ERROR) << "Failed to add VOD info.";
268  return xml::scoped_xml_ptr<xmlNode>();
269  }
270 
271  if (HasLiveOnlyFields(media_info_) &&
272  !representation.AddLiveOnlyInfo(media_info_, segment_infos_,
273  start_number_)) {
274  LOG(ERROR) << "Failed to add Live info.";
275  return xml::scoped_xml_ptr<xmlNode>();
276  }
277  // TODO(rkuroiwa): It is likely that all representations have the exact same
278  // SegmentTemplate. Optimize and propagate the tag up to AdaptationSet level.
279 
280  output_suppression_flags_ = 0;
281  return representation.PassScopedPtr();
282 }
283 
284 void Representation::SuppressOnce(SuppressFlag flag) {
285  output_suppression_flags_ |= flag;
286 }
287 
289  double presentation_time_offset) {
290  int64_t pto = presentation_time_offset * media_info_.reference_time_scale();
291  if (pto <= 0)
292  return;
293  media_info_.set_presentation_time_offset(pto);
294 }
295 
297  double* start_timestamp_seconds,
298  double* end_timestamp_seconds) const {
299  if (segment_infos_.empty())
300  return false;
301 
302  if (start_timestamp_seconds) {
303  *start_timestamp_seconds =
304  static_cast<double>(segment_infos_.begin()->start_time) /
305  GetTimeScale(media_info_);
306  }
307  if (end_timestamp_seconds) {
308  *end_timestamp_seconds =
309  static_cast<double>(segment_infos_.rbegin()->start_time +
310  segment_infos_.rbegin()->duration *
311  (segment_infos_.rbegin()->repeat + 1)) /
312  GetTimeScale(media_info_);
313  }
314  return true;
315 }
316 
317 bool Representation::HasRequiredMediaInfoFields() const {
318  if (HasVODOnlyFields(media_info_) && HasLiveOnlyFields(media_info_)) {
319  LOG(ERROR) << "MediaInfo cannot have both VOD and Live fields.";
320  return false;
321  }
322 
323  if (!media_info_.has_container_type()) {
324  LOG(ERROR) << "MediaInfo missing required field: container_type.";
325  return false;
326  }
327 
328  return true;
329 }
330 
331 void Representation::AddSegmentInfo(int64_t start_time, int64_t duration) {
332  const uint64_t kNoRepeat = 0;
333  const int64_t adjusted_duration = AdjustDuration(duration);
334 
335  if (!segment_infos_.empty()) {
336  // Contiguous segment.
337  const SegmentInfo& previous = segment_infos_.back();
338  const int64_t previous_segment_end_time =
339  previous.start_time + previous.duration * (previous.repeat + 1);
340  // Make it continuous if the segment start time is close to previous segment
341  // end time.
342  if (ApproximiatelyEqual(previous_segment_end_time, start_time)) {
343  const int64_t segment_end_time_for_same_duration =
344  previous_segment_end_time + previous.duration;
345  const int64_t actual_segment_end_time = start_time + duration;
346  // Consider the segments having identical duration if the segment end time
347  // is close to calculated segment end time by assuming identical duration.
348  if (ApproximiatelyEqual(segment_end_time_for_same_duration,
349  actual_segment_end_time)) {
350  ++segment_infos_.back().repeat;
351  } else {
352  segment_infos_.push_back(
353  {previous_segment_end_time,
354  actual_segment_end_time - previous_segment_end_time, kNoRepeat});
355  }
356  return;
357  }
358 
359  // A gap since previous.
360  const int64_t kRoundingErrorGrace = 5;
361  if (previous_segment_end_time + kRoundingErrorGrace < start_time) {
362  LOG(WARNING) << RepresentationAsString() << " Found a gap of size "
363  << (start_time - previous_segment_end_time)
364  << " > kRoundingErrorGrace (" << kRoundingErrorGrace
365  << "). The new segment starts at " << start_time
366  << " but the previous segment ends at "
367  << previous_segment_end_time << ".";
368  }
369 
370  // No overlapping segments.
371  if (start_time < previous_segment_end_time - kRoundingErrorGrace) {
372  LOG(WARNING)
373  << RepresentationAsString()
374  << " Segments should not be overlapping. The new segment starts at "
375  << start_time << " but the previous segment ends at "
376  << previous_segment_end_time << ".";
377  }
378  }
379 
380  segment_infos_.push_back({start_time, adjusted_duration, kNoRepeat});
381 }
382 
383 bool Representation::ApproximiatelyEqual(int64_t time1, int64_t time2) const {
384  if (!allow_approximate_segment_timeline_)
385  return time1 == time2;
386 
387  // It is not always possible to align segment duration to target duration
388  // exactly. For example, for AAC with sampling rate of 44100, there are always
389  // 1024 audio samples per frame, so the frame duration is 1024/44100. For a
390  // target duration of 2 seconds, the closest segment duration would be 1.984
391  // or 2.00533.
392 
393  // An arbitrary error threshold cap. This makes sure that the error is not too
394  // large for large samples.
395  const double kErrorThresholdSeconds = 0.05;
396 
397  // So we consider two times equal if they differ by less than one sample.
398  const uint32_t error_threshold =
399  std::min(frame_duration_,
400  static_cast<uint32_t>(kErrorThresholdSeconds *
401  media_info_.reference_time_scale()));
402  return std::abs(time1 - time2) <= error_threshold;
403 }
404 
405 int64_t Representation::AdjustDuration(int64_t duration) const {
406  if (!allow_approximate_segment_timeline_)
407  return duration;
408  const int64_t scaled_target_duration =
409  mpd_options_.mpd_params.target_segment_duration *
410  media_info_.reference_time_scale();
411  return ApproximiatelyEqual(scaled_target_duration, duration)
412  ? scaled_target_duration
413  : duration;
414 }
415 
416 void Representation::SlideWindow() {
417  if (mpd_options_.mpd_params.time_shift_buffer_depth <= 0.0 ||
418  mpd_options_.mpd_type == MpdType::kStatic)
419  return;
420 
421  const uint32_t time_scale = GetTimeScale(media_info_);
422  DCHECK_GT(time_scale, 0u);
423 
424  const int64_t time_shift_buffer_depth = static_cast<int64_t>(
425  mpd_options_.mpd_params.time_shift_buffer_depth * time_scale);
426 
427  if (current_buffer_depth_ <= time_shift_buffer_depth)
428  return;
429 
430  std::list<SegmentInfo>::iterator first = segment_infos_.begin();
431  std::list<SegmentInfo>::iterator last = first;
432  for (; last != segment_infos_.end(); ++last) {
433  // Remove the current segment only if it falls completely out of time shift
434  // buffer range.
435  while (last->repeat >= 0 &&
436  current_buffer_depth_ - last->duration >= time_shift_buffer_depth) {
437  current_buffer_depth_ -= last->duration;
438  RemoveOldSegment(&*last);
439  start_number_++;
440  }
441  if (last->repeat >= 0)
442  break;
443  }
444  segment_infos_.erase(first, last);
445 }
446 
447 void Representation::RemoveOldSegment(SegmentInfo* segment_info) {
448  int64_t segment_start_time = segment_info->start_time;
449  segment_info->start_time += segment_info->duration;
450  segment_info->repeat--;
451 
452  if (mpd_options_.mpd_params.preserved_segments_outside_live_window == 0)
453  return;
454 
455  segments_to_be_removed_.push_back(
456  media::GetSegmentName(media_info_.segment_template(), segment_start_time,
457  start_number_ - 1, media_info_.bandwidth()));
458  while (segments_to_be_removed_.size() >
459  mpd_options_.mpd_params.preserved_segments_outside_live_window) {
460  VLOG(2) << "Deleting " << segments_to_be_removed_.front();
461  if (!File::Delete(segments_to_be_removed_.front().c_str())) {
462  LOG(WARNING) << "Failed to delete " << segments_to_be_removed_.front()
463  << "; Will retry later.";
464  break;
465  }
466  segments_to_be_removed_.pop_front();
467  }
468 }
469 
470 std::string Representation::GetVideoMimeType() const {
471  return GetMimeType("video", media_info_.container_type());
472 }
473 
474 std::string Representation::GetAudioMimeType() const {
475  return GetMimeType("audio", media_info_.container_type());
476 }
477 
478 std::string Representation::GetTextMimeType() const {
479  CHECK(media_info_.has_text_info());
480  if (media_info_.text_info().codec() == "ttml") {
481  switch (media_info_.container_type()) {
482  case MediaInfo::CONTAINER_TEXT:
483  return "application/ttml+xml";
484  case MediaInfo::CONTAINER_MP4:
485  return "application/mp4";
486  default:
487  LOG(ERROR) << "Failed to determine MIME type for TTML container: "
488  << media_info_.container_type();
489  return "";
490  }
491  }
492  if (media_info_.text_info().codec() == "wvtt") {
493  if (media_info_.container_type() == MediaInfo::CONTAINER_TEXT) {
494  return "text/vtt";
495  } else if (media_info_.container_type() == MediaInfo::CONTAINER_MP4) {
496  return "application/mp4";
497  }
498  LOG(ERROR) << "Failed to determine MIME type for VTT container: "
499  << media_info_.container_type();
500  return "";
501  }
502 
503  LOG(ERROR) << "Cannot determine MIME type for format: "
504  << media_info_.text_info().codec()
505  << " container: " << media_info_.container_type();
506  return "";
507 }
508 
509 std::string Representation::RepresentationAsString() const {
510  std::string s = base::StringPrintf("Representation (id=%d,", id_);
511  if (media_info_.has_video_info()) {
512  const MediaInfo_VideoInfo& video_info = media_info_.video_info();
513  base::StringAppendF(&s, "codec='%s',width=%d,height=%d",
514  video_info.codec().c_str(), video_info.width(),
515  video_info.height());
516  } else if (media_info_.has_audio_info()) {
517  const MediaInfo_AudioInfo& audio_info = media_info_.audio_info();
518  base::StringAppendF(
519  &s, "codec='%s',frequency=%d,language='%s'", audio_info.codec().c_str(),
520  audio_info.sampling_frequency(), audio_info.language().c_str());
521  } else if (media_info_.has_text_info()) {
522  const MediaInfo_TextInfo& text_info = media_info_.text_info();
523  base::StringAppendF(&s, "codec='%s',language='%s'",
524  text_info.codec().c_str(),
525  text_info.language().c_str());
526  }
527  base::StringAppendF(&s, ")");
528  return s;
529 }
530 
531 } // namespace shaka
bool AddVideoInfo(const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate)
Definition: xml_node.cc:309
-
virtual const MediaInfo & GetMediaInfo() const
-
RepresentationType in MPD.
Definition: xml_node.h:156
-
static bool Delete(const char *file_name)
Definition: file.cc:198
- -
size_t preserved_segments_outside_live_window
Definition: mpd_params.h:46
-
Representation(const MediaInfo &media_info, const MpdOptions &mpd_options, uint32_t representation_id, std::unique_ptr< RepresentationStateChangeListener > state_change_listener)
-
virtual void AddNewSegment(int64_t start_time, int64_t duration, uint64_t size)
-
virtual void SetSampleDuration(uint32_t sample_duration)
-
STL namespace.
-
scoped_xml_ptr< xmlNode > PassScopedPtr()
Definition: xml_node.cc:204
-
All the methods that are virtual are virtual for mocking.
-
bool AddVODOnlyInfo(const MediaInfo &media_info)
Definition: xml_node.cc:354
-
void SetStringAttribute(const char *attribute_name, const std::string &attribute)
Definition: xml_node.cc:166
-
void AddBlock(uint64_t size_in_bytes, double duration)
- -
bool AddLiveOnlyInfo(const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number)
Definition: xml_node.cc:400
-
void SetId(uint32_t id)
Definition: xml_node.cc:189
-
xml::scoped_xml_ptr< xmlNode > GetXml()
-
void SetPresentationTimeOffset(double presentation_time_offset)
Set in SegmentBase / SegmentTemplate.
-
double target_segment_duration
Definition: mpd_params.h:82
- -
virtual void AddContentProtectionElement(const ContentProtectionElement &element)
- -
void SetIntegerAttribute(const char *attribute_name, uint64_t number)
Definition: xml_node.cc:173
-
Defines Mpd Options.
Definition: mpd_options.h:25
-
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
- -
double time_shift_buffer_depth
Definition: mpd_params.h:39
-
void SuppressOnce(SuppressFlag flag)
-
bool AddAudioInfo(const MediaInfo::AudioInfo &audio_info)
Definition: xml_node.cc:346
-
bool GetStartAndEndTimestamps(double *start_timestamp_seconds, double *end_timestamp_seconds) const
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/mpd/base/representation.h"
+
8 
+
9 #include <gflags/gflags.h>
+
10 
+
11 #include <algorithm>
+
12 
+
13 #include "packager/base/logging.h"
+
14 #include "packager/base/strings/stringprintf.h"
+
15 #include "packager/file/file.h"
+
16 #include "packager/media/base/muxer_util.h"
+
17 #include "packager/mpd/base/mpd_options.h"
+
18 #include "packager/mpd/base/mpd_utils.h"
+
19 #include "packager/mpd/base/xml/xml_node.h"
+
20 
+
21 namespace shaka {
+
22 namespace {
+
23 
+
24 std::string GetMimeType(const std::string& prefix,
+
25  MediaInfo::ContainerType container_type) {
+
26  switch (container_type) {
+
27  case MediaInfo::CONTAINER_MP4:
+
28  return prefix + "/mp4";
+
29  case MediaInfo::CONTAINER_MPEG2_TS:
+
30  // NOTE: DASH MPD spec uses lowercase but RFC3555 says uppercase.
+
31  return prefix + "/MP2T";
+
32  case MediaInfo::CONTAINER_WEBM:
+
33  return prefix + "/webm";
+
34  default:
+
35  break;
+
36  }
+
37 
+
38  // Unsupported container types should be rejected/handled by the caller.
+
39  LOG(ERROR) << "Unrecognized container type: " << container_type;
+
40  return std::string();
+
41 }
+
42 
+
43 // Check whether the video info has width and height.
+
44 // DASH IOP also requires several other fields for video representations, namely
+
45 // width, height, framerate, and sar.
+
46 bool HasRequiredVideoFields(const MediaInfo_VideoInfo& video_info) {
+
47  if (!video_info.has_height() || !video_info.has_width()) {
+
48  LOG(ERROR)
+
49  << "Width and height are required fields for generating a valid MPD.";
+
50  return false;
+
51  }
+
52  // These fields are not required for a valid MPD, but required for DASH IOP
+
53  // compliant MPD. MpdBuilder can keep generating MPDs without these fields.
+
54  LOG_IF(WARNING, !video_info.has_time_scale())
+
55  << "Video info does not contain timescale required for "
+
56  "calculating framerate. @frameRate is required for DASH IOP.";
+
57  LOG_IF(WARNING, !video_info.has_pixel_width())
+
58  << "Video info does not contain pixel_width to calculate the sample "
+
59  "aspect ratio required for DASH IOP.";
+
60  LOG_IF(WARNING, !video_info.has_pixel_height())
+
61  << "Video info does not contain pixel_height to calculate the sample "
+
62  "aspect ratio required for DASH IOP.";
+
63  return true;
+
64 }
+
65 
+
66 uint32_t GetTimeScale(const MediaInfo& media_info) {
+
67  if (media_info.has_reference_time_scale()) {
+
68  return media_info.reference_time_scale();
+
69  }
+
70 
+
71  if (media_info.has_video_info()) {
+
72  return media_info.video_info().time_scale();
+
73  }
+
74 
+
75  if (media_info.has_audio_info()) {
+
76  return media_info.audio_info().time_scale();
+
77  }
+
78 
+
79  LOG(WARNING) << "No timescale specified, using 1 as timescale.";
+
80  return 1;
+
81 }
+
82 
+
83 } // namespace
+
84 
+ +
86  const MediaInfo& media_info,
+
87  const MpdOptions& mpd_options,
+
88  uint32_t id,
+
89  std::unique_ptr<RepresentationStateChangeListener> state_change_listener)
+
90  : media_info_(media_info),
+
91  id_(id),
+
92  mpd_options_(mpd_options),
+
93  state_change_listener_(std::move(state_change_listener)),
+
94  allow_approximate_segment_timeline_(
+
95  // TODO(kqyang): Need a better check. $Time is legitimate but not a
+
96  // template.
+
97  media_info.segment_template().find("$Time") == std::string::npos &&
+
98  mpd_options_.mpd_params.allow_approximate_segment_timeline) {}
+
99 
+ +
101  const Representation& representation,
+
102  std::unique_ptr<RepresentationStateChangeListener> state_change_listener)
+
103  : Representation(representation.media_info_,
+
104  representation.mpd_options_,
+
105  representation.id_,
+
106  std::move(state_change_listener)) {
+
107  mime_type_ = representation.mime_type_;
+
108  codecs_ = representation.codecs_;
+
109 
+
110  start_number_ = representation.start_number_;
+
111  for (const SegmentInfo& segment_info : representation.segment_infos_)
+
112  start_number_ += segment_info.repeat + 1;
+
113 }
+
114 
+
115 Representation::~Representation() {}
+
116 
+ +
118  if (!AtLeastOneTrue(media_info_.has_video_info(),
+
119  media_info_.has_audio_info(),
+
120  media_info_.has_text_info())) {
+
121  // This is an error. Segment information can be in AdaptationSet, Period, or
+
122  // MPD but the interface does not provide a way to set them.
+
123  // See 5.3.9.1 ISO 23009-1:2012 for segment info.
+
124  LOG(ERROR) << "Representation needs one of video, audio, or text.";
+
125  return false;
+
126  }
+
127 
+
128  if (MoreThanOneTrue(media_info_.has_video_info(),
+
129  media_info_.has_audio_info(),
+
130  media_info_.has_text_info())) {
+
131  LOG(ERROR) << "Only one of VideoInfo, AudioInfo, or TextInfo can be set.";
+
132  return false;
+
133  }
+
134 
+
135  if (media_info_.container_type() == MediaInfo::CONTAINER_UNKNOWN) {
+
136  LOG(ERROR) << "'container_type' in MediaInfo cannot be CONTAINER_UNKNOWN.";
+
137  return false;
+
138  }
+
139 
+
140  if (media_info_.has_video_info()) {
+
141  mime_type_ = GetVideoMimeType();
+
142  if (!HasRequiredVideoFields(media_info_.video_info())) {
+
143  LOG(ERROR) << "Missing required fields to create a video Representation.";
+
144  return false;
+
145  }
+
146  } else if (media_info_.has_audio_info()) {
+
147  mime_type_ = GetAudioMimeType();
+
148  } else if (media_info_.has_text_info()) {
+
149  mime_type_ = GetTextMimeType();
+
150  }
+
151 
+
152  if (mime_type_.empty())
+
153  return false;
+
154 
+
155  codecs_ = GetCodecs(media_info_);
+
156  return true;
+
157 }
+
158 
+ +
160  const ContentProtectionElement& content_protection_element) {
+
161  content_protection_elements_.push_back(content_protection_element);
+
162  RemoveDuplicateAttributes(&content_protection_elements_.back());
+
163 }
+
164 
+
165 void Representation::UpdateContentProtectionPssh(const std::string& drm_uuid,
+
166  const std::string& pssh) {
+
167  UpdateContentProtectionPsshHelper(drm_uuid, pssh,
+
168  &content_protection_elements_);
+
169 }
+
170 
+
171 void Representation::AddNewSegment(int64_t start_time,
+
172  int64_t duration,
+
173  uint64_t size) {
+
174  if (start_time == 0 && duration == 0) {
+
175  LOG(WARNING) << "Got segment with start_time and duration == 0. Ignoring.";
+
176  return;
+
177  }
+
178 
+
179  // In order for the oldest segment to be accessible for at least
+
180  // |time_shift_buffer_depth| seconds, the latest segment should not be in the
+
181  // sliding window since the player could be playing any part of the latest
+
182  // segment. So the current segment duration is added to the sum of segment
+
183  // durations (in the manifest/playlist) after sliding the window.
+
184  SlideWindow();
+
185 
+
186  if (state_change_listener_)
+
187  state_change_listener_->OnNewSegmentForRepresentation(start_time, duration);
+
188 
+
189  AddSegmentInfo(start_time, duration);
+
190  current_buffer_depth_ += segment_infos_.back().duration;
+
191 
+
192  bandwidth_estimator_.AddBlock(
+
193  size, static_cast<double>(duration) / media_info_.reference_time_scale());
+
194 }
+
195 
+
196 void Representation::SetSampleDuration(uint32_t frame_duration) {
+
197  // Sample duration is used to generate approximate SegmentTimeline.
+
198  // Text is required to have exactly the same segment duration.
+
199  if (media_info_.has_audio_info() || media_info_.has_video_info())
+
200  frame_duration_ = frame_duration;
+
201 
+
202  if (media_info_.has_video_info()) {
+
203  media_info_.mutable_video_info()->set_frame_duration(frame_duration);
+
204  if (state_change_listener_) {
+
205  state_change_listener_->OnSetFrameRateForRepresentation(
+
206  frame_duration, media_info_.video_info().time_scale());
+
207  }
+
208  }
+
209 }
+
210 
+
211 const MediaInfo& Representation::GetMediaInfo() const {
+
212  return media_info_;
+
213 }
+
214 
+
215 // Uses info in |media_info_| and |content_protection_elements_| to create a
+
216 // "Representation" node.
+
217 // MPD schema has strict ordering. The following must be done in order.
+
218 // AddVideoInfo() (possibly adds FramePacking elements), AddAudioInfo() (Adds
+
219 // AudioChannelConfig elements), AddContentProtectionElements*(), and
+
220 // AddVODOnlyInfo() (Adds segment info).
+
221 base::Optional<xml::XmlNode> Representation::GetXml() {
+
222  if (!HasRequiredMediaInfoFields()) {
+
223  LOG(ERROR) << "MediaInfo missing required fields.";
+
224  return base::nullopt;
+
225  }
+
226 
+
227  const uint64_t bandwidth = media_info_.has_bandwidth()
+
228  ? media_info_.bandwidth()
+
229  : bandwidth_estimator_.Max();
+
230 
+
231  DCHECK(!(HasVODOnlyFields(media_info_) && HasLiveOnlyFields(media_info_)));
+
232 
+
233  xml::RepresentationXmlNode representation;
+
234  // Mandatory fields for Representation.
+
235  if (!representation.SetId(id_) ||
+
236  !representation.SetIntegerAttribute("bandwidth", bandwidth) ||
+
237  !(codecs_.empty() ||
+
238  representation.SetStringAttribute("codecs", codecs_)) ||
+
239  !representation.SetStringAttribute("mimeType", mime_type_)) {
+
240  return base::nullopt;
+
241  }
+
242 
+
243  const bool has_video_info = media_info_.has_video_info();
+
244  const bool has_audio_info = media_info_.has_audio_info();
+
245 
+
246  if (has_video_info &&
+
247  !representation.AddVideoInfo(
+
248  media_info_.video_info(),
+
249  !(output_suppression_flags_ & kSuppressWidth),
+
250  !(output_suppression_flags_ & kSuppressHeight),
+
251  !(output_suppression_flags_ & kSuppressFrameRate))) {
+
252  LOG(ERROR) << "Failed to add video info to Representation XML.";
+
253  return base::nullopt;
+
254  }
+
255 
+
256  if (has_audio_info &&
+
257  !representation.AddAudioInfo(media_info_.audio_info())) {
+
258  LOG(ERROR) << "Failed to add audio info to Representation XML.";
+
259  return base::nullopt;
+
260  }
+
261 
+
262  if (!representation.AddContentProtectionElements(
+
263  content_protection_elements_)) {
+
264  return base::nullopt;
+
265  }
+
266 
+
267  if (HasVODOnlyFields(media_info_) &&
+
268  !representation.AddVODOnlyInfo(media_info_)) {
+
269  LOG(ERROR) << "Failed to add VOD info.";
+
270  return base::nullopt;
+
271  }
+
272 
+
273  if (HasLiveOnlyFields(media_info_) &&
+
274  !representation.AddLiveOnlyInfo(media_info_, segment_infos_,
+
275  start_number_)) {
+
276  LOG(ERROR) << "Failed to add Live info.";
+
277  return base::nullopt;
+
278  }
+
279  // TODO(rkuroiwa): It is likely that all representations have the exact same
+
280  // SegmentTemplate. Optimize and propagate the tag up to AdaptationSet level.
+
281 
+
282  output_suppression_flags_ = 0;
+
283  return std::move(representation);
+
284 }
+
285 
+
286 void Representation::SuppressOnce(SuppressFlag flag) {
+
287  output_suppression_flags_ |= flag;
+
288 }
+
289 
+ +
291  double presentation_time_offset) {
+
292  int64_t pto = presentation_time_offset * media_info_.reference_time_scale();
+
293  if (pto <= 0)
+
294  return;
+
295  media_info_.set_presentation_time_offset(pto);
+
296 }
+
297 
+ +
299  double* start_timestamp_seconds,
+
300  double* end_timestamp_seconds) const {
+
301  if (segment_infos_.empty())
+
302  return false;
+
303 
+
304  if (start_timestamp_seconds) {
+
305  *start_timestamp_seconds =
+
306  static_cast<double>(segment_infos_.begin()->start_time) /
+
307  GetTimeScale(media_info_);
+
308  }
+
309  if (end_timestamp_seconds) {
+
310  *end_timestamp_seconds =
+
311  static_cast<double>(segment_infos_.rbegin()->start_time +
+
312  segment_infos_.rbegin()->duration *
+
313  (segment_infos_.rbegin()->repeat + 1)) /
+
314  GetTimeScale(media_info_);
+
315  }
+
316  return true;
+
317 }
+
318 
+
319 bool Representation::HasRequiredMediaInfoFields() const {
+
320  if (HasVODOnlyFields(media_info_) && HasLiveOnlyFields(media_info_)) {
+
321  LOG(ERROR) << "MediaInfo cannot have both VOD and Live fields.";
+
322  return false;
+
323  }
+
324 
+
325  if (!media_info_.has_container_type()) {
+
326  LOG(ERROR) << "MediaInfo missing required field: container_type.";
+
327  return false;
+
328  }
+
329 
+
330  return true;
+
331 }
+
332 
+
333 void Representation::AddSegmentInfo(int64_t start_time, int64_t duration) {
+
334  const uint64_t kNoRepeat = 0;
+
335  const int64_t adjusted_duration = AdjustDuration(duration);
+
336 
+
337  if (!segment_infos_.empty()) {
+
338  // Contiguous segment.
+
339  const SegmentInfo& previous = segment_infos_.back();
+
340  const int64_t previous_segment_end_time =
+
341  previous.start_time + previous.duration * (previous.repeat + 1);
+
342  // Make it continuous if the segment start time is close to previous segment
+
343  // end time.
+
344  if (ApproximiatelyEqual(previous_segment_end_time, start_time)) {
+
345  const int64_t segment_end_time_for_same_duration =
+
346  previous_segment_end_time + previous.duration;
+
347  const int64_t actual_segment_end_time = start_time + duration;
+
348  // Consider the segments having identical duration if the segment end time
+
349  // is close to calculated segment end time by assuming identical duration.
+
350  if (ApproximiatelyEqual(segment_end_time_for_same_duration,
+
351  actual_segment_end_time)) {
+
352  ++segment_infos_.back().repeat;
+
353  } else {
+
354  segment_infos_.push_back(
+
355  {previous_segment_end_time,
+
356  actual_segment_end_time - previous_segment_end_time, kNoRepeat});
+
357  }
+
358  return;
+
359  }
+
360 
+
361  // A gap since previous.
+
362  const int64_t kRoundingErrorGrace = 5;
+
363  if (previous_segment_end_time + kRoundingErrorGrace < start_time) {
+
364  LOG(WARNING) << RepresentationAsString() << " Found a gap of size "
+
365  << (start_time - previous_segment_end_time)
+
366  << " > kRoundingErrorGrace (" << kRoundingErrorGrace
+
367  << "). The new segment starts at " << start_time
+
368  << " but the previous segment ends at "
+
369  << previous_segment_end_time << ".";
+
370  }
+
371 
+
372  // No overlapping segments.
+
373  if (start_time < previous_segment_end_time - kRoundingErrorGrace) {
+
374  LOG(WARNING)
+
375  << RepresentationAsString()
+
376  << " Segments should not be overlapping. The new segment starts at "
+
377  << start_time << " but the previous segment ends at "
+
378  << previous_segment_end_time << ".";
+
379  }
+
380  }
+
381 
+
382  segment_infos_.push_back({start_time, adjusted_duration, kNoRepeat});
+
383 }
+
384 
+
385 bool Representation::ApproximiatelyEqual(int64_t time1, int64_t time2) const {
+
386  if (!allow_approximate_segment_timeline_)
+
387  return time1 == time2;
+
388 
+
389  // It is not always possible to align segment duration to target duration
+
390  // exactly. For example, for AAC with sampling rate of 44100, there are always
+
391  // 1024 audio samples per frame, so the frame duration is 1024/44100. For a
+
392  // target duration of 2 seconds, the closest segment duration would be 1.984
+
393  // or 2.00533.
+
394 
+
395  // An arbitrary error threshold cap. This makes sure that the error is not too
+
396  // large for large samples.
+
397  const double kErrorThresholdSeconds = 0.05;
+
398 
+
399  // So we consider two times equal if they differ by less than one sample.
+
400  const uint32_t error_threshold =
+
401  std::min(frame_duration_,
+
402  static_cast<uint32_t>(kErrorThresholdSeconds *
+
403  media_info_.reference_time_scale()));
+
404  return std::abs(time1 - time2) <= error_threshold;
+
405 }
+
406 
+
407 int64_t Representation::AdjustDuration(int64_t duration) const {
+
408  if (!allow_approximate_segment_timeline_)
+
409  return duration;
+
410  const int64_t scaled_target_duration =
+
411  mpd_options_.mpd_params.target_segment_duration *
+
412  media_info_.reference_time_scale();
+
413  return ApproximiatelyEqual(scaled_target_duration, duration)
+
414  ? scaled_target_duration
+
415  : duration;
+
416 }
+
417 
+
418 void Representation::SlideWindow() {
+
419  if (mpd_options_.mpd_params.time_shift_buffer_depth <= 0.0 ||
+
420  mpd_options_.mpd_type == MpdType::kStatic)
+
421  return;
+
422 
+
423  const uint32_t time_scale = GetTimeScale(media_info_);
+
424  DCHECK_GT(time_scale, 0u);
+
425 
+
426  const int64_t time_shift_buffer_depth = static_cast<int64_t>(
+
427  mpd_options_.mpd_params.time_shift_buffer_depth * time_scale);
+
428 
+
429  if (current_buffer_depth_ <= time_shift_buffer_depth)
+
430  return;
+
431 
+
432  std::list<SegmentInfo>::iterator first = segment_infos_.begin();
+
433  std::list<SegmentInfo>::iterator last = first;
+
434  for (; last != segment_infos_.end(); ++last) {
+
435  // Remove the current segment only if it falls completely out of time shift
+
436  // buffer range.
+
437  while (last->repeat >= 0 &&
+
438  current_buffer_depth_ - last->duration >= time_shift_buffer_depth) {
+
439  current_buffer_depth_ -= last->duration;
+
440  RemoveOldSegment(&*last);
+
441  start_number_++;
+
442  }
+
443  if (last->repeat >= 0)
+
444  break;
+
445  }
+
446  segment_infos_.erase(first, last);
+
447 }
+
448 
+
449 void Representation::RemoveOldSegment(SegmentInfo* segment_info) {
+
450  int64_t segment_start_time = segment_info->start_time;
+
451  segment_info->start_time += segment_info->duration;
+
452  segment_info->repeat--;
+
453 
+
454  if (mpd_options_.mpd_params.preserved_segments_outside_live_window == 0)
+
455  return;
+
456 
+
457  segments_to_be_removed_.push_back(
+
458  media::GetSegmentName(media_info_.segment_template(), segment_start_time,
+
459  start_number_ - 1, media_info_.bandwidth()));
+
460  while (segments_to_be_removed_.size() >
+
461  mpd_options_.mpd_params.preserved_segments_outside_live_window) {
+
462  VLOG(2) << "Deleting " << segments_to_be_removed_.front();
+
463  if (!File::Delete(segments_to_be_removed_.front().c_str())) {
+
464  LOG(WARNING) << "Failed to delete " << segments_to_be_removed_.front()
+
465  << "; Will retry later.";
+
466  break;
+
467  }
+
468  segments_to_be_removed_.pop_front();
+
469  }
+
470 }
+
471 
+
472 std::string Representation::GetVideoMimeType() const {
+
473  return GetMimeType("video", media_info_.container_type());
+
474 }
+
475 
+
476 std::string Representation::GetAudioMimeType() const {
+
477  return GetMimeType("audio", media_info_.container_type());
+
478 }
+
479 
+
480 std::string Representation::GetTextMimeType() const {
+
481  CHECK(media_info_.has_text_info());
+
482  if (media_info_.text_info().codec() == "ttml") {
+
483  switch (media_info_.container_type()) {
+
484  case MediaInfo::CONTAINER_TEXT:
+
485  return "application/ttml+xml";
+
486  case MediaInfo::CONTAINER_MP4:
+
487  return "application/mp4";
+
488  default:
+
489  LOG(ERROR) << "Failed to determine MIME type for TTML container: "
+
490  << media_info_.container_type();
+
491  return "";
+
492  }
+
493  }
+
494  if (media_info_.text_info().codec() == "wvtt") {
+
495  if (media_info_.container_type() == MediaInfo::CONTAINER_TEXT) {
+
496  return "text/vtt";
+
497  } else if (media_info_.container_type() == MediaInfo::CONTAINER_MP4) {
+
498  return "application/mp4";
+
499  }
+
500  LOG(ERROR) << "Failed to determine MIME type for VTT container: "
+
501  << media_info_.container_type();
+
502  return "";
+
503  }
+
504 
+
505  LOG(ERROR) << "Cannot determine MIME type for format: "
+
506  << media_info_.text_info().codec()
+
507  << " container: " << media_info_.container_type();
+
508  return "";
+
509 }
+
510 
+
511 std::string Representation::RepresentationAsString() const {
+
512  std::string s = base::StringPrintf("Representation (id=%d,", id_);
+
513  if (media_info_.has_video_info()) {
+
514  const MediaInfo_VideoInfo& video_info = media_info_.video_info();
+
515  base::StringAppendF(&s, "codec='%s',width=%d,height=%d",
+
516  video_info.codec().c_str(), video_info.width(),
+
517  video_info.height());
+
518  } else if (media_info_.has_audio_info()) {
+
519  const MediaInfo_AudioInfo& audio_info = media_info_.audio_info();
+
520  base::StringAppendF(
+
521  &s, "codec='%s',frequency=%d,language='%s'", audio_info.codec().c_str(),
+
522  audio_info.sampling_frequency(), audio_info.language().c_str());
+
523  } else if (media_info_.has_text_info()) {
+
524  const MediaInfo_TextInfo& text_info = media_info_.text_info();
+
525  base::StringAppendF(&s, "codec='%s',language='%s'",
+
526  text_info.codec().c_str(),
+
527  text_info.language().c_str());
+
528  }
+
529  base::StringAppendF(&s, ")");
+
530  return s;
+
531 }
+
532 
+
533 } // namespace shaka
+ +
void AddBlock(uint64_t size_in_bytes, double duration)
+
static bool Delete(const char *file_name)
Definition: file.cc:212
+ +
virtual void SetSampleDuration(uint32_t sample_duration)
+
virtual void AddContentProtectionElement(const ContentProtectionElement &element)
+
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
+
void SuppressOnce(SuppressFlag flag)
+
virtual const MediaInfo & GetMediaInfo() const
+
bool GetStartAndEndTimestamps(double *start_timestamp_seconds, double *end_timestamp_seconds) const
+
Representation(const MediaInfo &media_info, const MpdOptions &mpd_options, uint32_t representation_id, std::unique_ptr< RepresentationStateChangeListener > state_change_listener)
+
void SetPresentationTimeOffset(double presentation_time_offset)
Set @presentationTimeOffset in SegmentBase / SegmentTemplate.
+
base::Optional< xml::XmlNode > GetXml()
+ +
virtual void AddNewSegment(int64_t start_time, int64_t duration, uint64_t size)
+
RepresentationType in MPD.
Definition: xml_node.h:182
+
bool AddVideoInfo(const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate) WARN_UNUSED_RESULT
Definition: xml_node.cc:337
+
bool AddVODOnlyInfo(const MediaInfo &media_info) WARN_UNUSED_RESULT
Definition: xml_node.cc:379
+
bool AddLiveOnlyInfo(const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number) WARN_UNUSED_RESULT
Definition: xml_node.cc:433
+
bool AddAudioInfo(const MediaInfo::AudioInfo &audio_info) WARN_UNUSED_RESULT
Definition: xml_node.cc:374
+
bool SetIntegerAttribute(const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULT
Definition: xml_node.cc:190
+
bool SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
Definition: xml_node.cc:183
+
bool SetId(uint32_t id) WARN_UNUSED_RESULT
Definition: xml_node.cc:204
+
All the methods that are virtual are virtual for mocking.
+ +
Defines Mpd Options.
Definition: mpd_options.h:25
+
size_t preserved_segments_outside_live_window
Definition: mpd_params.h:46
+
double target_segment_duration
Definition: mpd_params.h:82
+
double time_shift_buffer_depth
Definition: mpd_params.h:39
+
diff --git a/docs/d7/d9c/structshaka_1_1media_1_1H265SliceHeader_1_1LongTermPicsInfo.html b/docs/d7/d9c/structshaka_1_1media_1_1H265SliceHeader_1_1LongTermPicsInfo.html index e7442e82d6..47be1ad8d0 100644 --- a/docs/d7/d9c/structshaka_1_1media_1_1H265SliceHeader_1_1LongTermPicsInfo.html +++ b/docs/d7/d9c/structshaka_1_1media_1_1H265SliceHeader_1_1LongTermPicsInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265SliceHeader::LongTermPicsInfo Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
delta_poc_msb_cycle_lt
diff --git a/docs/d7/d9d/progress__listener_8h_source.html b/docs/d7/d9d/progress__listener_8h_source.html index be62249568..2502be1898 100644 --- a/docs/d7/d9d/progress__listener_8h_source.html +++ b/docs/d7/d9d/progress__listener_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/progress_listener.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
progress_listener.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Event handler for progress updates.
8 
9 #ifndef PACKAGER_MEDIA_EVENT_PROGRESS_LISTENER_H_
10 #define PACKAGER_MEDIA_EVENT_PROGRESS_LISTENER_H_
11 
12 #include <stdint.h>
13 
14 #include "packager/base/macros.h"
15 
16 namespace shaka {
17 namespace media {
18 
21  public:
22  virtual ~ProgressListener() {}
23 
26  virtual void OnProgress(double progress) = 0;
27 
28  protected:
29  ProgressListener() {}
30 
31  private:
32  DISALLOW_COPY_AND_ASSIGN(ProgressListener);
33 };
34 
35 } // namespace media
36 } // namespace shaka
37 
38 #endif // PACKAGER_MEDIA_EVENT_PROGRESS_LISTENER_H_
All the methods that are virtual are virtual for mocking.
-
This class listens to progress updates events.
-
virtual void OnProgress(double progress)=0
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Event handler for progress updates.
+
8 
+
9 #ifndef PACKAGER_MEDIA_EVENT_PROGRESS_LISTENER_H_
+
10 #define PACKAGER_MEDIA_EVENT_PROGRESS_LISTENER_H_
+
11 
+
12 #include <stdint.h>
+
13 
+
14 #include "packager/base/macros.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+ +
21  public:
+
22  virtual ~ProgressListener() {}
+
23 
+
26  virtual void OnProgress(double progress) = 0;
+
27 
+
28  protected:
+
29  ProgressListener() {}
+
30 
+
31  private:
+
32  DISALLOW_COPY_AND_ASSIGN(ProgressListener);
+
33 };
+
34 
+
35 } // namespace media
+
36 } // namespace shaka
+
37 
+
38 #endif // PACKAGER_MEDIA_EVENT_PROGRESS_LISTENER_H_
+
This class listens to progress updates events.
+
virtual void OnProgress(double progress)=0
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d3/de7/classshaka_1_1media_1_1PeekingReader-members.html b/docs/d7/d9e/structshaka_1_1media_1_1JobManager_1_1JobEntry-members.html similarity index 58% rename from docs/d3/de7/classshaka_1_1media_1_1PeekingReader-members.html rename to docs/d7/d9e/structshaka_1_1media_1_1JobManager_1_1JobEntry-members.html index 624913186b..a83dd23a9a 100644 --- a/docs/d3/de7/classshaka_1_1media_1_1PeekingReader-members.html +++ b/docs/d7/d9e/structshaka_1_1media_1_1JobManager_1_1JobEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
-
shaka::media::PeekingReader Member List
+
shaka::media::JobManager::JobEntry Member List
-

This is the complete list of members for shaka::media::PeekingReader, including all inherited members.

+

This is the complete list of members for shaka::media::JobManager::JobEntry, including all inherited members.

- - - + +
Next(char *out) (defined in shaka::media::PeekingReader)shaka::media::PeekingReader
Peek(char *out) (defined in shaka::media::PeekingReader)shaka::media::PeekingReader
PeekingReader(std::unique_ptr< FileReader > source) (defined in shaka::media::PeekingReader)shaka::media::PeekingReaderexplicit
name (defined in shaka::media::JobManager::JobEntry)shaka::media::JobManager::JobEntry
worker (defined in shaka::media::JobManager::JobEntry)shaka::media::JobManager::JobEntry
diff --git a/docs/d7/da4/track__run__iterator_8h_source.html b/docs/d7/da4/track__run__iterator_8h_source.html index 5648338f97..54c53cc5fb 100644 --- a/docs/d7/da4/track__run__iterator_8h_source.html +++ b/docs/d7/da4/track__run__iterator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/track_run_iterator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
track_run_iterator.h
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_MP4_TRACK_RUN_ITERATOR_H_
6 #define PACKAGER_MEDIA_FORMATS_MP4_TRACK_RUN_ITERATOR_H_
7 
8 #include <map>
9 #include <memory>
10 #include <vector>
11 
12 #include "packager/media/formats/mp4/box_definitions.h"
13 
14 namespace shaka {
15 namespace media {
16 
17 class DecryptConfig;
18 
19 namespace mp4 {
20 
21 struct SampleInfo;
22 struct TrackRunInfo;
23 
25  public:
28  explicit TrackRunIterator(const Movie* moov);
30 
37  bool Init();
38 
41  bool Init(const MovieFragment& moof);
42 
45  bool IsRunValid() const;
48  bool IsSampleValid() const;
49 
52  void AdvanceRun();
55  void AdvanceSample();
56 
60 
65  bool CacheAuxInfo(const uint8_t* buf, int size);
66 
73  int64_t GetMaxClearOffset();
74 
77  uint32_t track_id() const;
78  int64_t aux_info_offset() const;
79  int aux_info_size() const;
80  bool is_encrypted() const;
81  bool is_audio() const;
82  bool is_video() const;
84 
86  const AudioSampleEntry& audio_description() const;
88  const VideoSampleEntry& video_description() const;
89 
92  int64_t sample_offset() const;
93  int sample_size() const;
94  int64_t dts() const;
95  int64_t cts() const;
96  int64_t duration() const;
97  bool is_keyframe() const;
99 
102  std::unique_ptr<DecryptConfig> GetDecryptConfig();
103 
104  private:
105  void ResetRun();
106  const TrackEncryption& track_encryption() const;
107  int64_t GetTimestampAdjustment(const Movie& movie,
108  const Track& track,
109  const TrackFragment* traf);
110 
111  const Movie* moov_;
112 
113  std::vector<TrackRunInfo> runs_;
114  std::vector<TrackRunInfo>::const_iterator run_itr_;
115  std::vector<SampleInfo>::const_iterator sample_itr_;
116 
117  // Track the start dts of the next segment, only useful if decode_time box is
118  // absent.
119  std::vector<int64_t> next_fragment_start_dts_;
120 
121  int64_t sample_dts_;
122  int64_t sample_offset_;
123 
124  // TrackId => adjustment map.
125  std::map<uint32_t, int64_t> timestamp_adjustment_map_;
126 
127  DISALLOW_COPY_AND_ASSIGN(TrackRunIterator);
128 };
129 
130 } // namespace mp4
131 } // namespace media
132 } // namespace shaka
133 
134 #endif // PACKAGER_MEDIA_FORMATS_MP4_TRACK_RUN_ITERATOR_H_
- - - - - -
All the methods that are virtual are virtual for mocking.
-
const VideoSampleEntry & video_description() const
Only valid if is_video() is true.
- - - - - - -
std::unique_ptr< DecryptConfig > GetDecryptConfig()
- - - - -
bool CacheAuxInfo(const uint8_t *buf, int size)
-
const AudioSampleEntry & audio_description() const
Only valid if is_audio() is true.
+
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_MP4_TRACK_RUN_ITERATOR_H_
+
6 #define PACKAGER_MEDIA_FORMATS_MP4_TRACK_RUN_ITERATOR_H_
+
7 
+
8 #include <map>
+
9 #include <memory>
+
10 #include <vector>
+
11 
+
12 #include "packager/media/formats/mp4/box_definitions.h"
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 
+
17 class DecryptConfig;
+
18 
+
19 namespace mp4 {
+
20 
+
21 struct SampleInfo;
+
22 struct TrackRunInfo;
+
23 
+ +
25  public:
+
28  explicit TrackRunIterator(const Movie* moov);
+ +
30 
+
37  bool Init();
+
38 
+
41  bool Init(const MovieFragment& moof);
+
42 
+
45  bool IsRunValid() const;
+
48  bool IsSampleValid() const;
+
49 
+
52  void AdvanceRun();
+
55  void AdvanceSample();
+
56 
+ +
60 
+
65  bool CacheAuxInfo(const uint8_t* buf, int size);
+
66 
+
73  int64_t GetMaxClearOffset();
+
74 
+
77  uint32_t track_id() const;
+
78  int64_t aux_info_offset() const;
+
79  int aux_info_size() const;
+
80  bool is_encrypted() const;
+
81  bool is_audio() const;
+
82  bool is_video() const;
+
84 
+
86  const AudioSampleEntry& audio_description() const;
+
88  const VideoSampleEntry& video_description() const;
+
89 
+
92  int64_t sample_offset() const;
+
93  int sample_size() const;
+
94  int64_t dts() const;
+
95  int64_t cts() const;
+
96  int64_t duration() const;
+
97  bool is_keyframe() const;
+
99 
+
102  std::unique_ptr<DecryptConfig> GetDecryptConfig();
+
103 
+
104  private:
+
105  void ResetRun();
+
106  const TrackEncryption& track_encryption() const;
+
107  int64_t GetTimestampAdjustment(const Movie& movie,
+
108  const Track& track,
+
109  const TrackFragment* traf);
+
110 
+
111  const Movie* moov_;
+
112 
+
113  std::vector<TrackRunInfo> runs_;
+
114  std::vector<TrackRunInfo>::const_iterator run_itr_;
+
115  std::vector<SampleInfo>::const_iterator sample_itr_;
+
116 
+
117  // Track the start dts of the next segment, only useful if decode_time box is
+
118  // absent.
+
119  std::vector<int64_t> next_fragment_start_dts_;
+
120 
+
121  int64_t sample_dts_;
+
122  int64_t sample_offset_;
+
123 
+
124  // TrackId => adjustment map.
+
125  std::map<uint32_t, int64_t> timestamp_adjustment_map_;
+
126 
+
127  DISALLOW_COPY_AND_ASSIGN(TrackRunIterator);
+
128 };
+
129 
+
130 } // namespace mp4
+
131 } // namespace media
+
132 } // namespace shaka
+
133 
+
134 #endif // PACKAGER_MEDIA_FORMATS_MP4_TRACK_RUN_ITERATOR_H_
+ + +
const VideoSampleEntry & video_description() const
Only valid if is_video() is true.
+ + + + +
const AudioSampleEntry & audio_description() const
Only valid if is_audio() is true.
+
bool CacheAuxInfo(const uint8_t *buf, int size)
+ + + +
std::unique_ptr< DecryptConfig > GetDecryptConfig()
+
All the methods that are virtual are virtual for mocking.
+ + + + + + +
diff --git a/docs/d7/dad/simple__hls__notifier_8cc_source.html b/docs/d7/dad/simple__hls__notifier_8cc_source.html index e4179bc979..57f655ce23 100644 --- a/docs/d7/dad/simple__hls__notifier_8cc_source.html +++ b/docs/d7/dad/simple__hls__notifier_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/simple_hls_notifier.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
simple_hls_notifier.cc
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/hls/base/simple_hls_notifier.h"
8 
9 #include <gflags/gflags.h>
10 #include <cmath>
11 
12 #include "packager/base/base64.h"
13 #include "packager/base/files/file_path.h"
14 #include "packager/base/logging.h"
15 #include "packager/base/optional.h"
16 #include "packager/base/strings/string_number_conversions.h"
17 #include "packager/base/strings/stringprintf.h"
18 #include "packager/hls/base/media_playlist.h"
19 #include "packager/media/base/protection_system_ids.h"
20 #include "packager/media/base/protection_system_specific_info.h"
21 #include "packager/media/base/proto_json_util.h"
22 #include "packager/media/base/widevine_pssh_data.pb.h"
23 
24 DEFINE_bool(enable_legacy_widevine_hls_signaling,
25  false,
26  "Specifies whether Legacy Widevine HLS, i.e. v1 is signalled in "
27  "the media playlist. Applies to Widevine protection system in HLS "
28  "with SAMPLE-AES only.");
29 
30 namespace shaka {
31 
32 using base::FilePath;
33 
34 namespace hls {
35 
36 namespace {
37 
38 const char kUriBase64Prefix[] = "data:text/plain;base64,";
39 const char kUriFairPlayPrefix[] = "skd://";
40 const char kWidevineDashIfIopUUID[] =
41  "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed";
42 
43 bool IsWidevineSystemId(const std::vector<uint8_t>& system_id) {
44  return system_id.size() == arraysize(media::kWidevineSystemId) &&
45  std::equal(system_id.begin(), system_id.end(),
46  media::kWidevineSystemId);
47 }
48 
49 bool IsCommonSystemId(const std::vector<uint8_t>& system_id) {
50  return system_id.size() == arraysize(media::kCommonSystemId) &&
51  std::equal(system_id.begin(), system_id.end(), media::kCommonSystemId);
52 }
53 
54 bool IsFairPlaySystemId(const std::vector<uint8_t>& system_id) {
55  return system_id.size() == arraysize(media::kFairPlaySystemId) &&
56  std::equal(system_id.begin(), system_id.end(),
57  media::kFairPlaySystemId);
58 }
59 
60 std::string Base64EncodeData(const std::string& prefix,
61  const std::string& data) {
62  std::string data_base64;
63  base::Base64Encode(data, &data_base64);
64  return prefix + data_base64;
65 }
66 
67 std::string VectorToString(const std::vector<uint8_t>& v) {
68  return std::string(v.begin(), v.end());
69 }
70 
71 // TODO(rkuroiwa): Dedup these with the functions in MpdBuilder.
72 // If |media_path| is contained in |parent_path|, then
73 // Strips the common path and keep only the relative part of |media_path|.
74 // e.g. if |parent_path| is /some/parent/ and
75 // |media_path| is /some/parent/abc/child/item.ext,
76 // abc/child/item.ext is returned.
77 // else
78 // Returns |media_path|.
79 // The path separator of the output is also changed to "/" if it is not.
80 std::string MakePathRelative(const std::string& media_path,
81  const FilePath& parent_path) {
82  FilePath relative_path;
83  const FilePath child_path = FilePath::FromUTF8Unsafe(media_path);
84  const bool is_child =
85  parent_path.AppendRelativePath(child_path, &relative_path);
86  if (!is_child)
87  relative_path = child_path;
88  return relative_path.NormalizePathSeparatorsTo('/').AsUTF8Unsafe();
89 }
90 
91 // Segment URL is relative to either output directory or the directory
92 // containing the media playlist depends on whether base_url is set.
93 std::string GenerateSegmentUrl(const std::string& segment_name,
94  const std::string& base_url,
95  const std::string& output_dir,
96  const std::string& playlist_file_name) {
97  FilePath output_path = FilePath::FromUTF8Unsafe(output_dir);
98  if (!base_url.empty()) {
99  // Media segment URL is base_url + segment path relative to output
100  // directory.
101  return base_url + MakePathRelative(segment_name, output_path);
102  }
103  // Media segment URL is segment path relative to the directory containing the
104  // playlist.
105  const FilePath playlist_dir =
106  output_path.Append(FilePath::FromUTF8Unsafe(playlist_file_name))
107  .DirName()
108  .AsEndingWithSeparator();
109  return MakePathRelative(segment_name, playlist_dir);
110 }
111 
112 MediaInfo MakeMediaInfoPathsRelativeToPlaylist(
113  const MediaInfo& media_info,
114  const std::string& base_url,
115  const std::string& output_dir,
116  const std::string& playlist_name) {
117  MediaInfo media_info_copy = media_info;
118  if (media_info_copy.has_init_segment_name()) {
119  media_info_copy.set_init_segment_url(
120  GenerateSegmentUrl(media_info_copy.init_segment_name(), base_url,
121  output_dir, playlist_name));
122  }
123  if (media_info_copy.has_media_file_name()) {
124  media_info_copy.set_media_file_url(
125  GenerateSegmentUrl(media_info_copy.media_file_name(), base_url,
126  output_dir, playlist_name));
127  }
128  if (media_info_copy.has_segment_template()) {
129  media_info_copy.set_segment_template_url(
130  GenerateSegmentUrl(media_info_copy.segment_template(), base_url,
131  output_dir, playlist_name));
132  }
133  return media_info_copy;
134 }
135 
136 bool WidevinePsshToJson(const std::vector<uint8_t>& pssh_box,
137  const std::vector<uint8_t>& key_id,
138  std::string* pssh_json) {
139  std::unique_ptr<media::PsshBoxBuilder> pssh_builder =
140  media::PsshBoxBuilder::ParseFromBox(pssh_box.data(), pssh_box.size());
141  if (!pssh_builder) {
142  LOG(ERROR) << "Failed to parse PSSH box.";
143  return false;
144  }
145 
146  media::WidevinePsshData pssh_proto;
147  if (!pssh_proto.ParseFromArray(pssh_builder->pssh_data().data(),
148  pssh_builder->pssh_data().size())) {
149  LOG(ERROR) << "Failed to parse protection_system_specific_data.";
150  return false;
151  }
152 
153  media::WidevineHeader widevine_header;
154 
155  if (pssh_proto.has_provider()) {
156  widevine_header.set_provider(pssh_proto.provider());
157  } else {
158  LOG(WARNING) << "Missing provider in Widevine PSSH. The content may not "
159  "play in some devices.";
160  }
161 
162  if (pssh_proto.has_content_id()) {
163  widevine_header.set_content_id(pssh_proto.content_id());
164  } else {
165  LOG(WARNING) << "Missing content_id in Widevine PSSH. The content may not "
166  "play in some devices.";
167  }
168 
169  // Place the current |key_id| to the front and converts all key_id to hex
170  // format.
171  widevine_header.add_key_ids(base::HexEncode(key_id.data(), key_id.size()));
172  for (const std::string& key_id_in_pssh : pssh_proto.key_id()) {
173  const std::string key_id_hex =
174  base::HexEncode(key_id_in_pssh.data(), key_id_in_pssh.size());
175  if (widevine_header.key_ids(0) != key_id_hex)
176  widevine_header.add_key_ids(key_id_hex);
177  }
178 
179  *pssh_json = media::MessageToJsonString(widevine_header);
180  return true;
181 }
182 
183 base::Optional<MediaPlaylist::EncryptionMethod> StringToEncryptionMethod(
184  const std::string& method) {
185  if (method == "cenc") {
186  return MediaPlaylist::EncryptionMethod::kSampleAesCenc;
187  }
188  if (method == "cbcs") {
189  return MediaPlaylist::EncryptionMethod::kSampleAes;
190  }
191  if (method == "cbca") {
192  // cbca is a place holder for sample aes.
193  return MediaPlaylist::EncryptionMethod::kSampleAes;
194  }
195  return base::nullopt;
196 }
197 
198 void NotifyEncryptionToMediaPlaylist(
199  MediaPlaylist::EncryptionMethod encryption_method,
200  const std::string& uri,
201  const std::vector<uint8_t>& key_id,
202  const std::vector<uint8_t>& iv,
203  const std::string& key_format,
204  const std::string& key_format_version,
205  MediaPlaylist* media_playlist) {
206  std::string iv_string;
207  if (!iv.empty()) {
208  iv_string = "0x" + base::HexEncode(iv.data(), iv.size());
209  }
210  std::string key_id_string;
211  if (!key_id.empty()) {
212  key_id_string = "0x" + base::HexEncode(key_id.data(), key_id.size());
213  }
214 
215  media_playlist->AddEncryptionInfo(
216  encryption_method,
217  uri, key_id_string, iv_string,
218  key_format, key_format_version);
219 }
220 
221 // Creates JSON format and the format similar to MPD.
222 bool HandleWidevineKeyFormats(
223  MediaPlaylist::EncryptionMethod encryption_method,
224  const std::vector<uint8_t>& key_id,
225  const std::vector<uint8_t>& iv,
226  const std::vector<uint8_t>& protection_system_specific_data,
227  MediaPlaylist* media_playlist) {
228  if (FLAGS_enable_legacy_widevine_hls_signaling &&
229  encryption_method == MediaPlaylist::EncryptionMethod::kSampleAes) {
230  // This format allows SAMPLE-AES only.
231  std::string key_uri_data;
232  if (!WidevinePsshToJson(protection_system_specific_data, key_id,
233  &key_uri_data)) {
234  return false;
235  }
236  std::string key_uri_data_base64 =
237  Base64EncodeData(kUriBase64Prefix, key_uri_data);
238  NotifyEncryptionToMediaPlaylist(encryption_method, key_uri_data_base64,
239  std::vector<uint8_t>(), iv, "com.widevine",
240  "1", media_playlist);
241  }
242 
243  std::string pssh_as_string(
244  reinterpret_cast<const char*>(protection_system_specific_data.data()),
245  protection_system_specific_data.size());
246  std::string key_uri_data_base64 =
247  Base64EncodeData(kUriBase64Prefix, pssh_as_string);
248  NotifyEncryptionToMediaPlaylist(encryption_method, key_uri_data_base64,
249  key_id, iv, kWidevineDashIfIopUUID, "1",
250  media_playlist);
251  return true;
252 }
253 
254 bool WriteMediaPlaylist(const std::string& output_dir,
255  MediaPlaylist* playlist) {
256  std::string file_path =
257  FilePath::FromUTF8Unsafe(output_dir)
258  .Append(FilePath::FromUTF8Unsafe(playlist->file_name()))
259  .AsUTF8Unsafe();
260  if (!playlist->WriteToFile(file_path)) {
261  LOG(ERROR) << "Failed to write playlist " << file_path;
262  return false;
263  }
264  return true;
265 }
266 
267 } // namespace
268 
269 MediaPlaylistFactory::~MediaPlaylistFactory() {}
270 
271 std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create(
272  const HlsParams& hls_params,
273  const std::string& file_name,
274  const std::string& name,
275  const std::string& group_id) {
276  return std::unique_ptr<MediaPlaylist>(
277  new MediaPlaylist(hls_params, file_name, name, group_id));
278 }
279 
281  : HlsNotifier(hls_params),
282  media_playlist_factory_(new MediaPlaylistFactory()) {
283  const base::FilePath master_playlist_path(
284  base::FilePath::FromUTF8Unsafe(hls_params.master_playlist_output));
285  master_playlist_dir_ = master_playlist_path.DirName().AsUTF8Unsafe();
286  const std::string& default_audio_langauge = hls_params.default_language;
287  const std::string& default_text_language =
288  hls_params.default_text_language.empty()
289  ? hls_params.default_language
290  : hls_params.default_text_language;
291  master_playlist_.reset(
292  new MasterPlaylist(master_playlist_path.BaseName().AsUTF8Unsafe(),
293  default_audio_langauge, default_text_language));
294 }
295 
296 SimpleHlsNotifier::~SimpleHlsNotifier() {}
297 
299  return true;
300 }
301 
302 bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
303  const std::string& playlist_name,
304  const std::string& name,
305  const std::string& group_id,
306  uint32_t* stream_id) {
307  DCHECK(stream_id);
308 
309  const std::string relative_playlist_path = MakePathRelative(
310  playlist_name, FilePath::FromUTF8Unsafe(master_playlist_dir_));
311 
312  std::unique_ptr<MediaPlaylist> media_playlist =
313  media_playlist_factory_->Create(hls_params(), relative_playlist_path,
314  name, group_id);
315  MediaInfo adjusted_media_info = MakeMediaInfoPathsRelativeToPlaylist(
316  media_info, hls_params().base_url, master_playlist_dir_,
317  media_playlist->file_name());
318  if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
319  LOG(ERROR) << "Failed to set media info for playlist " << playlist_name;
320  return false;
321  }
322 
323  MediaPlaylist::EncryptionMethod encryption_method =
324  MediaPlaylist::EncryptionMethod::kNone;
325  if (media_info.protected_content().has_protection_scheme()) {
326  const std::string& protection_scheme =
327  media_info.protected_content().protection_scheme();
328  base::Optional<MediaPlaylist::EncryptionMethod> enc_method =
329  StringToEncryptionMethod(protection_scheme);
330  if (!enc_method) {
331  LOG(ERROR) << "Failed to recognize protection scheme "
332  << protection_scheme;
333  return false;
334  }
335  encryption_method = enc_method.value();
336  }
337 
338  base::AutoLock auto_lock(lock_);
339  *stream_id = sequence_number_++;
340  media_playlists_.push_back(media_playlist.get());
341  stream_map_[*stream_id].reset(
342  new StreamEntry{std::move(media_playlist), encryption_method});
343  return true;
344 }
345 
347  uint32_t sample_duration) {
348  base::AutoLock auto_lock(lock_);
349  auto stream_iterator = stream_map_.find(stream_id);
350  if (stream_iterator == stream_map_.end()) {
351  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
352  return false;
353  }
354  auto& media_playlist = stream_iterator->second->media_playlist;
355  media_playlist->SetSampleDuration(sample_duration);
356  return true;
357 }
358 
359 bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
360  const std::string& segment_name,
361  uint64_t start_time,
362  uint64_t duration,
363  uint64_t start_byte_offset,
364  uint64_t size) {
365  base::AutoLock auto_lock(lock_);
366  auto stream_iterator = stream_map_.find(stream_id);
367  if (stream_iterator == stream_map_.end()) {
368  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
369  return false;
370  }
371  auto& media_playlist = stream_iterator->second->media_playlist;
372  const std::string& segment_url =
373  GenerateSegmentUrl(segment_name, hls_params().base_url,
374  master_playlist_dir_, media_playlist->file_name());
375  media_playlist->AddSegment(segment_url, start_time, duration,
376  start_byte_offset, size);
377 
378  // Update target duration.
379  uint32_t longest_segment_duration =
380  static_cast<uint32_t>(ceil(media_playlist->GetLongestSegmentDuration()));
381  bool target_duration_updated = false;
382  if (longest_segment_duration > target_duration_) {
383  target_duration_ = longest_segment_duration;
384  target_duration_updated = true;
385  }
386 
387  // Update the playlists when there is new segments in live mode.
388  if (hls_params().playlist_type == HlsPlaylistType::kLive ||
389  hls_params().playlist_type == HlsPlaylistType::kEvent) {
390  // Update all playlists if target duration is updated.
391  if (target_duration_updated) {
392  for (MediaPlaylist* playlist : media_playlists_) {
393  playlist->SetTargetDuration(target_duration_);
394  if (!WriteMediaPlaylist(master_playlist_dir_, playlist))
395  return false;
396  }
397  } else {
398  if (!WriteMediaPlaylist(master_playlist_dir_, media_playlist.get()))
399  return false;
400  }
401  if (!master_playlist_->WriteMasterPlaylist(
402  hls_params().base_url, master_playlist_dir_, media_playlists_)) {
403  LOG(ERROR) << "Failed to write master playlist.";
404  return false;
405  }
406  }
407  return true;
408 }
409 
410 bool SimpleHlsNotifier::NotifyKeyFrame(uint32_t stream_id,
411  uint64_t timestamp,
412  uint64_t start_byte_offset,
413  uint64_t size) {
414  base::AutoLock auto_lock(lock_);
415  auto stream_iterator = stream_map_.find(stream_id);
416  if (stream_iterator == stream_map_.end()) {
417  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
418  return false;
419  }
420  auto& media_playlist = stream_iterator->second->media_playlist;
421  media_playlist->AddKeyFrame(timestamp, start_byte_offset, size);
422  return true;
423 }
424 
425 bool SimpleHlsNotifier::NotifyCueEvent(uint32_t stream_id, uint64_t timestamp) {
426  base::AutoLock auto_lock(lock_);
427  auto stream_iterator = stream_map_.find(stream_id);
428  if (stream_iterator == stream_map_.end()) {
429  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
430  return false;
431  }
432  auto& media_playlist = stream_iterator->second->media_playlist;
433  media_playlist->AddPlacementOpportunity();
434  return true;
435 }
436 
438  uint32_t stream_id,
439  const std::vector<uint8_t>& key_id,
440  const std::vector<uint8_t>& system_id,
441  const std::vector<uint8_t>& iv,
442  const std::vector<uint8_t>& protection_system_specific_data) {
443  base::AutoLock auto_lock(lock_);
444  auto stream_iterator = stream_map_.find(stream_id);
445  if (stream_iterator == stream_map_.end()) {
446  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
447  return false;
448  }
449 
450  std::unique_ptr<MediaPlaylist>& media_playlist =
451  stream_iterator->second->media_playlist;
452  const MediaPlaylist::EncryptionMethod encryption_method =
453  stream_iterator->second->encryption_method;
454  LOG_IF(WARNING, encryption_method == MediaPlaylist::EncryptionMethod::kNone)
455  << "Got encryption notification but the encryption method is NONE";
456  if (IsWidevineSystemId(system_id)) {
457  return HandleWidevineKeyFormats(encryption_method,
458  key_id, iv, protection_system_specific_data,
459  media_playlist.get());
460  }
461 
462  // Key Id does not need to be specified with "identity" and "sdk".
463  const std::vector<uint8_t> empty_key_id;
464 
465  if (IsCommonSystemId(system_id)) {
466  std::string key_uri = hls_params().key_uri;
467  if (key_uri.empty()) {
468  // Use key_id as the key_uri. The player needs to have custom logic to
469  // convert it to the actual key uri.
470  std::string key_uri_data = VectorToString(key_id);
471  key_uri = Base64EncodeData(kUriBase64Prefix, key_uri_data);
472  }
473  NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id,
474  iv, "identity", "", media_playlist.get());
475  return true;
476  }
477  if (IsFairPlaySystemId(system_id)) {
478  std::string key_uri = hls_params().key_uri;
479  if (key_uri.empty()) {
480  // Use key_id as the key_uri. The player needs to have custom logic to
481  // convert it to the actual key uri.
482  std::string key_uri_data = VectorToString(key_id);
483  key_uri = Base64EncodeData(kUriFairPlayPrefix, key_uri_data);
484  }
485 
486  // FairPlay defines IV to be carried with the key, not the playlist.
487  const std::vector<uint8_t> empty_iv;
488  NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id,
489  empty_iv, "com.apple.streamingkeydelivery",
490  "1", media_playlist.get());
491  return true;
492  }
493 
494  LOG(WARNING) << "HLS: Ignore unknown or unsupported system ID: "
495  << base::HexEncode(system_id.data(), system_id.size());
496  return true;
497 }
498 
500  base::AutoLock auto_lock(lock_);
501  for (MediaPlaylist* playlist : media_playlists_) {
502  playlist->SetTargetDuration(target_duration_);
503  if (!WriteMediaPlaylist(master_playlist_dir_, playlist))
504  return false;
505  }
506  if (!master_playlist_->WriteMasterPlaylist(
507  hls_params().base_url, master_playlist_dir_, media_playlists_)) {
508  LOG(ERROR) << "Failed to write master playlist.";
509  return false;
510  }
511  return true;
512 }
513 
514 } // namespace hls
515 } // namespace shaka
std::string master_playlist_output
HLS master playlist output path.
Definition: hls_params.h:27
- -
bool NotifyNewSegment(uint32_t stream_id, const std::string &segment_name, uint64_t start_time, uint64_t duration, uint64_t start_byte_offset, uint64_t size) override
-
std::string default_text_language
Definition: hls_params.h:53
- -
HLS related parameters.
Definition: hls_params.h:23
-
SimpleHlsNotifier(const HlsParams &hls_params)
-
All the methods that are virtual are virtual for mocking.
- - -
bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override
-
const HlsParams & hls_params() const
Definition: hls_notifier.h:104
-
Methods are virtual for mocking.
-
static std::unique_ptr< PsshBoxBuilder > ParseFromBox(const uint8_t *data, size_t data_size)
-
bool NotifyNewStream(const MediaInfo &media_info, const std::string &playlist_name, const std::string &stream_name, const std::string &group_id, uint32_t *stream_id) override
-
std::string default_language
Definition: hls_params.h:50
-
bool NotifyKeyFrame(uint32_t stream_id, uint64_t timestamp, uint64_t start_byte_offset, uint64_t size) override
- -
bool NotifySampleDuration(uint32_t stream_id, uint32_t sample_duration) override
-
bool NotifyEncryptionUpdate(uint32_t stream_id, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &system_id, const std::vector< uint8_t > &iv, const std::vector< uint8_t > &protection_system_specific_data) override
-
HlsPlaylistType playlist_type
HLS playlist type. See HLS specification for details.
Definition: hls_params.h:25
-
std::string key_uri
Definition: hls_params.h:44
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/hls/base/simple_hls_notifier.h"
+
8 
+
9 #include <gflags/gflags.h>
+
10 #include <cmath>
+
11 
+
12 #include "packager/base/base64.h"
+
13 #include "packager/base/files/file_path.h"
+
14 #include "packager/base/logging.h"
+
15 #include "packager/base/optional.h"
+
16 #include "packager/base/strings/string_number_conversions.h"
+
17 #include "packager/base/strings/stringprintf.h"
+
18 #include "packager/hls/base/media_playlist.h"
+
19 #include "packager/media/base/protection_system_ids.h"
+
20 #include "packager/media/base/protection_system_specific_info.h"
+
21 #include "packager/media/base/proto_json_util.h"
+
22 #include "packager/media/base/widevine_pssh_data.pb.h"
+
23 
+
24 DEFINE_bool(enable_legacy_widevine_hls_signaling,
+
25  false,
+
26  "Specifies whether Legacy Widevine HLS, i.e. v1 is signalled in "
+
27  "the media playlist. Applies to Widevine protection system in HLS "
+
28  "with SAMPLE-AES only.");
+
29 
+
30 namespace shaka {
+
31 
+
32 using base::FilePath;
+
33 
+
34 namespace hls {
+
35 
+
36 namespace {
+
37 
+
38 const char kUriBase64Prefix[] = "data:text/plain;base64,";
+
39 const char kUriFairPlayPrefix[] = "skd://";
+
40 const char kWidevineDashIfIopUUID[] =
+
41  "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed";
+
42 
+
43 bool IsWidevineSystemId(const std::vector<uint8_t>& system_id) {
+
44  return system_id.size() == arraysize(media::kWidevineSystemId) &&
+
45  std::equal(system_id.begin(), system_id.end(),
+
46  media::kWidevineSystemId);
+
47 }
+
48 
+
49 bool IsCommonSystemId(const std::vector<uint8_t>& system_id) {
+
50  return system_id.size() == arraysize(media::kCommonSystemId) &&
+
51  std::equal(system_id.begin(), system_id.end(), media::kCommonSystemId);
+
52 }
+
53 
+
54 bool IsFairPlaySystemId(const std::vector<uint8_t>& system_id) {
+
55  return system_id.size() == arraysize(media::kFairPlaySystemId) &&
+
56  std::equal(system_id.begin(), system_id.end(),
+
57  media::kFairPlaySystemId);
+
58 }
+
59 
+
60 std::string Base64EncodeData(const std::string& prefix,
+
61  const std::string& data) {
+
62  std::string data_base64;
+
63  base::Base64Encode(data, &data_base64);
+
64  return prefix + data_base64;
+
65 }
+
66 
+
67 std::string VectorToString(const std::vector<uint8_t>& v) {
+
68  return std::string(v.begin(), v.end());
+
69 }
+
70 
+
71 // TODO(rkuroiwa): Dedup these with the functions in MpdBuilder.
+
72 // If |media_path| is contained in |parent_path|, then
+
73 // Strips the common path and keep only the relative part of |media_path|.
+
74 // e.g. if |parent_path| is /some/parent/ and
+
75 // |media_path| is /some/parent/abc/child/item.ext,
+
76 // abc/child/item.ext is returned.
+
77 // else
+
78 // Returns |media_path|.
+
79 // The path separator of the output is also changed to "/" if it is not.
+
80 std::string MakePathRelative(const std::string& media_path,
+
81  const FilePath& parent_path) {
+
82  FilePath relative_path;
+
83  const FilePath child_path = FilePath::FromUTF8Unsafe(media_path);
+
84  const bool is_child =
+
85  parent_path.AppendRelativePath(child_path, &relative_path);
+
86  if (!is_child)
+
87  relative_path = child_path;
+
88  return relative_path.NormalizePathSeparatorsTo('/').AsUTF8Unsafe();
+
89 }
+
90 
+
91 // Segment URL is relative to either output directory or the directory
+
92 // containing the media playlist depends on whether base_url is set.
+
93 std::string GenerateSegmentUrl(const std::string& segment_name,
+
94  const std::string& base_url,
+
95  const std::string& output_dir,
+
96  const std::string& playlist_file_name) {
+
97  FilePath output_path = FilePath::FromUTF8Unsafe(output_dir);
+
98  if (!base_url.empty()) {
+
99  // Media segment URL is base_url + segment path relative to output
+
100  // directory.
+
101  return base_url + MakePathRelative(segment_name, output_path);
+
102  }
+
103  // Media segment URL is segment path relative to the directory containing the
+
104  // playlist.
+
105  const FilePath playlist_dir =
+
106  output_path.Append(FilePath::FromUTF8Unsafe(playlist_file_name))
+
107  .DirName()
+
108  .AsEndingWithSeparator();
+
109  return MakePathRelative(segment_name, playlist_dir);
+
110 }
+
111 
+
112 MediaInfo MakeMediaInfoPathsRelativeToPlaylist(
+
113  const MediaInfo& media_info,
+
114  const std::string& base_url,
+
115  const std::string& output_dir,
+
116  const std::string& playlist_name) {
+
117  MediaInfo media_info_copy = media_info;
+
118  if (media_info_copy.has_init_segment_name()) {
+
119  media_info_copy.set_init_segment_url(
+
120  GenerateSegmentUrl(media_info_copy.init_segment_name(), base_url,
+
121  output_dir, playlist_name));
+
122  }
+
123  if (media_info_copy.has_media_file_name()) {
+
124  media_info_copy.set_media_file_url(
+
125  GenerateSegmentUrl(media_info_copy.media_file_name(), base_url,
+
126  output_dir, playlist_name));
+
127  }
+
128  if (media_info_copy.has_segment_template()) {
+
129  media_info_copy.set_segment_template_url(
+
130  GenerateSegmentUrl(media_info_copy.segment_template(), base_url,
+
131  output_dir, playlist_name));
+
132  }
+
133  return media_info_copy;
+
134 }
+
135 
+
136 bool WidevinePsshToJson(const std::vector<uint8_t>& pssh_box,
+
137  const std::vector<uint8_t>& key_id,
+
138  std::string* pssh_json) {
+
139  std::unique_ptr<media::PsshBoxBuilder> pssh_builder =
+
140  media::PsshBoxBuilder::ParseFromBox(pssh_box.data(), pssh_box.size());
+
141  if (!pssh_builder) {
+
142  LOG(ERROR) << "Failed to parse PSSH box.";
+
143  return false;
+
144  }
+
145 
+
146  media::WidevinePsshData pssh_proto;
+
147  if (!pssh_proto.ParseFromArray(pssh_builder->pssh_data().data(),
+
148  pssh_builder->pssh_data().size())) {
+
149  LOG(ERROR) << "Failed to parse protection_system_specific_data.";
+
150  return false;
+
151  }
+
152 
+
153  media::WidevineHeader widevine_header;
+
154 
+
155  if (pssh_proto.has_provider()) {
+
156  widevine_header.set_provider(pssh_proto.provider());
+
157  } else {
+
158  LOG(WARNING) << "Missing provider in Widevine PSSH. The content may not "
+
159  "play in some devices.";
+
160  }
+
161 
+
162  if (pssh_proto.has_content_id()) {
+
163  widevine_header.set_content_id(pssh_proto.content_id());
+
164  } else {
+
165  LOG(WARNING) << "Missing content_id in Widevine PSSH. The content may not "
+
166  "play in some devices.";
+
167  }
+
168 
+
169  // Place the current |key_id| to the front and converts all key_id to hex
+
170  // format.
+
171  widevine_header.add_key_ids(base::HexEncode(key_id.data(), key_id.size()));
+
172  for (const std::string& key_id_in_pssh : pssh_proto.key_id()) {
+
173  const std::string key_id_hex =
+
174  base::HexEncode(key_id_in_pssh.data(), key_id_in_pssh.size());
+
175  if (widevine_header.key_ids(0) != key_id_hex)
+
176  widevine_header.add_key_ids(key_id_hex);
+
177  }
+
178 
+
179  *pssh_json = media::MessageToJsonString(widevine_header);
+
180  return true;
+
181 }
+
182 
+
183 base::Optional<MediaPlaylist::EncryptionMethod> StringToEncryptionMethod(
+
184  const std::string& method) {
+
185  if (method == "cenc") {
+
186  return MediaPlaylist::EncryptionMethod::kSampleAesCenc;
+
187  }
+
188  if (method == "cbcs") {
+
189  return MediaPlaylist::EncryptionMethod::kSampleAes;
+
190  }
+
191  if (method == "cbca") {
+
192  // cbca is a place holder for sample aes.
+
193  return MediaPlaylist::EncryptionMethod::kSampleAes;
+
194  }
+
195  return base::nullopt;
+
196 }
+
197 
+
198 void NotifyEncryptionToMediaPlaylist(
+
199  MediaPlaylist::EncryptionMethod encryption_method,
+
200  const std::string& uri,
+
201  const std::vector<uint8_t>& key_id,
+
202  const std::vector<uint8_t>& iv,
+
203  const std::string& key_format,
+
204  const std::string& key_format_version,
+
205  MediaPlaylist* media_playlist) {
+
206  std::string iv_string;
+
207  if (!iv.empty()) {
+
208  iv_string = "0x" + base::HexEncode(iv.data(), iv.size());
+
209  }
+
210  std::string key_id_string;
+
211  if (!key_id.empty()) {
+
212  key_id_string = "0x" + base::HexEncode(key_id.data(), key_id.size());
+
213  }
+
214 
+
215  media_playlist->AddEncryptionInfo(
+
216  encryption_method,
+
217  uri, key_id_string, iv_string,
+
218  key_format, key_format_version);
+
219 }
+
220 
+
221 // Creates JSON format and the format similar to MPD.
+
222 bool HandleWidevineKeyFormats(
+
223  MediaPlaylist::EncryptionMethod encryption_method,
+
224  const std::vector<uint8_t>& key_id,
+
225  const std::vector<uint8_t>& iv,
+
226  const std::vector<uint8_t>& protection_system_specific_data,
+
227  MediaPlaylist* media_playlist) {
+
228  if (FLAGS_enable_legacy_widevine_hls_signaling &&
+
229  encryption_method == MediaPlaylist::EncryptionMethod::kSampleAes) {
+
230  // This format allows SAMPLE-AES only.
+
231  std::string key_uri_data;
+
232  if (!WidevinePsshToJson(protection_system_specific_data, key_id,
+
233  &key_uri_data)) {
+
234  return false;
+
235  }
+
236  std::string key_uri_data_base64 =
+
237  Base64EncodeData(kUriBase64Prefix, key_uri_data);
+
238  NotifyEncryptionToMediaPlaylist(encryption_method, key_uri_data_base64,
+
239  std::vector<uint8_t>(), iv, "com.widevine",
+
240  "1", media_playlist);
+
241  }
+
242 
+
243  std::string pssh_as_string(
+
244  reinterpret_cast<const char*>(protection_system_specific_data.data()),
+
245  protection_system_specific_data.size());
+
246  std::string key_uri_data_base64 =
+
247  Base64EncodeData(kUriBase64Prefix, pssh_as_string);
+
248  NotifyEncryptionToMediaPlaylist(encryption_method, key_uri_data_base64,
+
249  key_id, iv, kWidevineDashIfIopUUID, "1",
+
250  media_playlist);
+
251  return true;
+
252 }
+
253 
+
254 bool WriteMediaPlaylist(const std::string& output_dir,
+
255  MediaPlaylist* playlist) {
+
256  std::string file_path =
+
257  FilePath::FromUTF8Unsafe(output_dir)
+
258  .Append(FilePath::FromUTF8Unsafe(playlist->file_name()))
+
259  .AsUTF8Unsafe();
+
260  if (!playlist->WriteToFile(file_path)) {
+
261  LOG(ERROR) << "Failed to write playlist " << file_path;
+
262  return false;
+
263  }
+
264  return true;
+
265 }
+
266 
+
267 } // namespace
+
268 
+
269 MediaPlaylistFactory::~MediaPlaylistFactory() {}
+
270 
+
271 std::unique_ptr<MediaPlaylist> MediaPlaylistFactory::Create(
+
272  const HlsParams& hls_params,
+
273  const std::string& file_name,
+
274  const std::string& name,
+
275  const std::string& group_id) {
+
276  return std::unique_ptr<MediaPlaylist>(
+
277  new MediaPlaylist(hls_params, file_name, name, group_id));
+
278 }
+
279 
+ +
281  : HlsNotifier(hls_params),
+
282  media_playlist_factory_(new MediaPlaylistFactory()) {
+
283  const base::FilePath master_playlist_path(
+
284  base::FilePath::FromUTF8Unsafe(hls_params.master_playlist_output));
+
285  master_playlist_dir_ = master_playlist_path.DirName().AsUTF8Unsafe();
+
286  const std::string& default_audio_langauge = hls_params.default_language;
+
287  const std::string& default_text_language =
+ + + +
291  master_playlist_.reset(
+
292  new MasterPlaylist(master_playlist_path.BaseName().AsUTF8Unsafe(),
+
293  default_audio_langauge, default_text_language,
+
294  hls_params.is_independent_segments));
+
295 }
+
296 
+
297 SimpleHlsNotifier::~SimpleHlsNotifier() {}
+
298 
+ +
300  return true;
+
301 }
+
302 
+
303 bool SimpleHlsNotifier::NotifyNewStream(const MediaInfo& media_info,
+
304  const std::string& playlist_name,
+
305  const std::string& name,
+
306  const std::string& group_id,
+
307  uint32_t* stream_id) {
+
308  DCHECK(stream_id);
+
309 
+
310  const std::string relative_playlist_path = MakePathRelative(
+
311  playlist_name, FilePath::FromUTF8Unsafe(master_playlist_dir_));
+
312 
+
313  std::unique_ptr<MediaPlaylist> media_playlist =
+
314  media_playlist_factory_->Create(hls_params(), relative_playlist_path,
+
315  name, group_id);
+
316  MediaInfo adjusted_media_info = MakeMediaInfoPathsRelativeToPlaylist(
+
317  media_info, hls_params().base_url, master_playlist_dir_,
+
318  media_playlist->file_name());
+
319  if (!media_playlist->SetMediaInfo(adjusted_media_info)) {
+
320  LOG(ERROR) << "Failed to set media info for playlist " << playlist_name;
+
321  return false;
+
322  }
+
323 
+
324  MediaPlaylist::EncryptionMethod encryption_method =
+
325  MediaPlaylist::EncryptionMethod::kNone;
+
326  if (media_info.protected_content().has_protection_scheme()) {
+
327  const std::string& protection_scheme =
+
328  media_info.protected_content().protection_scheme();
+
329  base::Optional<MediaPlaylist::EncryptionMethod> enc_method =
+
330  StringToEncryptionMethod(protection_scheme);
+
331  if (!enc_method) {
+
332  LOG(ERROR) << "Failed to recognize protection scheme "
+
333  << protection_scheme;
+
334  return false;
+
335  }
+
336  encryption_method = enc_method.value();
+
337  }
+
338 
+
339  base::AutoLock auto_lock(lock_);
+
340  *stream_id = sequence_number_++;
+
341  media_playlists_.push_back(media_playlist.get());
+
342  stream_map_[*stream_id].reset(
+
343  new StreamEntry{std::move(media_playlist), encryption_method});
+
344  return true;
+
345 }
+
346 
+ +
348  uint32_t sample_duration) {
+
349  base::AutoLock auto_lock(lock_);
+
350  auto stream_iterator = stream_map_.find(stream_id);
+
351  if (stream_iterator == stream_map_.end()) {
+
352  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
+
353  return false;
+
354  }
+
355  auto& media_playlist = stream_iterator->second->media_playlist;
+
356  media_playlist->SetSampleDuration(sample_duration);
+
357  return true;
+
358 }
+
359 
+
360 bool SimpleHlsNotifier::NotifyNewSegment(uint32_t stream_id,
+
361  const std::string& segment_name,
+
362  uint64_t start_time,
+
363  uint64_t duration,
+
364  uint64_t start_byte_offset,
+
365  uint64_t size) {
+
366  base::AutoLock auto_lock(lock_);
+
367  auto stream_iterator = stream_map_.find(stream_id);
+
368  if (stream_iterator == stream_map_.end()) {
+
369  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
+
370  return false;
+
371  }
+
372  auto& media_playlist = stream_iterator->second->media_playlist;
+
373  const std::string& segment_url =
+
374  GenerateSegmentUrl(segment_name, hls_params().base_url,
+
375  master_playlist_dir_, media_playlist->file_name());
+
376  media_playlist->AddSegment(segment_url, start_time, duration,
+
377  start_byte_offset, size);
+
378 
+
379  // Update target duration.
+
380  uint32_t longest_segment_duration =
+
381  static_cast<uint32_t>(ceil(media_playlist->GetLongestSegmentDuration()));
+
382  bool target_duration_updated = false;
+
383  if (longest_segment_duration > target_duration_) {
+
384  target_duration_ = longest_segment_duration;
+
385  target_duration_updated = true;
+
386  }
+
387 
+
388  // Update the playlists when there is new segments in live mode.
+
389  if (hls_params().playlist_type == HlsPlaylistType::kLive ||
+
390  hls_params().playlist_type == HlsPlaylistType::kEvent) {
+
391  // Update all playlists if target duration is updated.
+
392  if (target_duration_updated) {
+
393  for (MediaPlaylist* playlist : media_playlists_) {
+
394  playlist->SetTargetDuration(target_duration_);
+
395  if (!WriteMediaPlaylist(master_playlist_dir_, playlist))
+
396  return false;
+
397  }
+
398  } else {
+
399  if (!WriteMediaPlaylist(master_playlist_dir_, media_playlist.get()))
+
400  return false;
+
401  }
+
402  if (!master_playlist_->WriteMasterPlaylist(
+
403  hls_params().base_url, master_playlist_dir_, media_playlists_)) {
+
404  LOG(ERROR) << "Failed to write master playlist.";
+
405  return false;
+
406  }
+
407  }
+
408  return true;
+
409 }
+
410 
+
411 bool SimpleHlsNotifier::NotifyKeyFrame(uint32_t stream_id,
+
412  uint64_t timestamp,
+
413  uint64_t start_byte_offset,
+
414  uint64_t size) {
+
415  base::AutoLock auto_lock(lock_);
+
416  auto stream_iterator = stream_map_.find(stream_id);
+
417  if (stream_iterator == stream_map_.end()) {
+
418  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
+
419  return false;
+
420  }
+
421  auto& media_playlist = stream_iterator->second->media_playlist;
+
422  media_playlist->AddKeyFrame(timestamp, start_byte_offset, size);
+
423  return true;
+
424 }
+
425 
+
426 bool SimpleHlsNotifier::NotifyCueEvent(uint32_t stream_id, uint64_t timestamp) {
+
427  base::AutoLock auto_lock(lock_);
+
428  auto stream_iterator = stream_map_.find(stream_id);
+
429  if (stream_iterator == stream_map_.end()) {
+
430  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
+
431  return false;
+
432  }
+
433  auto& media_playlist = stream_iterator->second->media_playlist;
+
434  media_playlist->AddPlacementOpportunity();
+
435  return true;
+
436 }
+
437 
+ +
439  uint32_t stream_id,
+
440  const std::vector<uint8_t>& key_id,
+
441  const std::vector<uint8_t>& system_id,
+
442  const std::vector<uint8_t>& iv,
+
443  const std::vector<uint8_t>& protection_system_specific_data) {
+
444  base::AutoLock auto_lock(lock_);
+
445  auto stream_iterator = stream_map_.find(stream_id);
+
446  if (stream_iterator == stream_map_.end()) {
+
447  LOG(ERROR) << "Cannot find stream with ID: " << stream_id;
+
448  return false;
+
449  }
+
450 
+
451  std::unique_ptr<MediaPlaylist>& media_playlist =
+
452  stream_iterator->second->media_playlist;
+
453  const MediaPlaylist::EncryptionMethod encryption_method =
+
454  stream_iterator->second->encryption_method;
+
455  LOG_IF(WARNING, encryption_method == MediaPlaylist::EncryptionMethod::kNone)
+
456  << "Got encryption notification but the encryption method is NONE";
+
457  if (IsWidevineSystemId(system_id)) {
+
458  return HandleWidevineKeyFormats(encryption_method,
+
459  key_id, iv, protection_system_specific_data,
+
460  media_playlist.get());
+
461  }
+
462 
+
463  // Key Id does not need to be specified with "identity" and "sdk".
+
464  const std::vector<uint8_t> empty_key_id;
+
465 
+
466  if (IsCommonSystemId(system_id)) {
+
467  std::string key_uri = hls_params().key_uri;
+
468  if (key_uri.empty()) {
+
469  // Use key_id as the key_uri. The player needs to have custom logic to
+
470  // convert it to the actual key uri.
+
471  std::string key_uri_data = VectorToString(key_id);
+
472  key_uri = Base64EncodeData(kUriBase64Prefix, key_uri_data);
+
473  }
+
474  NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id,
+
475  iv, "identity", "", media_playlist.get());
+
476  return true;
+
477  }
+
478  if (IsFairPlaySystemId(system_id)) {
+
479  std::string key_uri = hls_params().key_uri;
+
480  if (key_uri.empty()) {
+
481  // Use key_id as the key_uri. The player needs to have custom logic to
+
482  // convert it to the actual key uri.
+
483  std::string key_uri_data = VectorToString(key_id);
+
484  key_uri = Base64EncodeData(kUriFairPlayPrefix, key_uri_data);
+
485  }
+
486 
+
487  // FairPlay defines IV to be carried with the key, not the playlist.
+
488  const std::vector<uint8_t> empty_iv;
+
489  NotifyEncryptionToMediaPlaylist(encryption_method, key_uri, empty_key_id,
+
490  empty_iv, "com.apple.streamingkeydelivery",
+
491  "1", media_playlist.get());
+
492  return true;
+
493  }
+
494 
+
495  LOG(WARNING) << "HLS: Ignore unknown or unsupported system ID: "
+
496  << base::HexEncode(system_id.data(), system_id.size());
+
497  return true;
+
498 }
+
499 
+ +
501  base::AutoLock auto_lock(lock_);
+
502  for (MediaPlaylist* playlist : media_playlists_) {
+
503  playlist->SetTargetDuration(target_duration_);
+
504  if (!WriteMediaPlaylist(master_playlist_dir_, playlist))
+
505  return false;
+
506  }
+
507  if (!master_playlist_->WriteMasterPlaylist(
+
508  hls_params().base_url, master_playlist_dir_, media_playlists_)) {
+
509  LOG(ERROR) << "Failed to write master playlist.";
+
510  return false;
+
511  }
+
512  return true;
+
513 }
+
514 
+
515 } // namespace hls
+
516 } // namespace shaka
+ +
const HlsParams & hls_params() const
Definition: hls_notifier.h:104
+ + +
Methods are virtual for mocking.
+ +
bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override
+
SimpleHlsNotifier(const HlsParams &hls_params)
+
bool NotifyKeyFrame(uint32_t stream_id, uint64_t timestamp, uint64_t start_byte_offset, uint64_t size) override
+ +
bool NotifyNewStream(const MediaInfo &media_info, const std::string &playlist_name, const std::string &stream_name, const std::string &group_id, uint32_t *stream_id) override
+
bool NotifySampleDuration(uint32_t stream_id, uint32_t sample_duration) override
+
bool NotifyEncryptionUpdate(uint32_t stream_id, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &system_id, const std::vector< uint8_t > &iv, const std::vector< uint8_t > &protection_system_specific_data) override
+
bool NotifyNewSegment(uint32_t stream_id, const std::string &segment_name, uint64_t start_time, uint64_t duration, uint64_t start_byte_offset, uint64_t size) override
+
static std::unique_ptr< PsshBoxBuilder > ParseFromBox(const uint8_t *data, size_t data_size)
+
All the methods that are virtual are virtual for mocking.
+
HLS related parameters.
Definition: hls_params.h:23
+
std::string key_uri
Definition: hls_params.h:44
+
std::string default_text_language
Definition: hls_params.h:53
+
HlsPlaylistType playlist_type
HLS playlist type. See HLS specification for details.
Definition: hls_params.h:25
+
std::string default_language
Definition: hls_params.h:50
+
std::string master_playlist_output
HLS master playlist output path.
Definition: hls_params.h:27
diff --git a/docs/d7/dae/structshaka_1_1media_1_1mp4_1_1MediaData.html b/docs/d7/dae/structshaka_1_1media_1_1mp4_1_1MediaData.html index e836847fc9..1919499d4b 100644 --- a/docs/d7/dae/structshaka_1_1media_1_1mp4_1_1MediaData.html +++ b/docs/d7/dae/structshaka_1_1media_1_1mp4_1_1MediaData.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MediaData Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 794 of file box_definitions.h.

+

Definition at line 812 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2703 of file box_definitions.cc.

+

Definition at line 2807 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d7/db0/mpd__writer_8h_source.html b/docs/d7/db0/mpd__writer_8h_source.html index 0fa330e257..deaa84c3ba 100644 --- a/docs/d7/db0/mpd__writer_8h_source.html +++ b/docs/d7/db0/mpd__writer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/util/mpd_writer.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
mpd_writer.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Class for reading in MediaInfo from files and writing out an MPD.
8 
9 #ifndef MPD_UTIL_MPD_WRITER_H_
10 #define MPD_UTIL_MPD_WRITER_H_
11 
12 #include <list>
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 #include "packager/base/macros.h"
18 #include "packager/mpd/base/mpd_notifier.h"
19 #include "packager/mpd/base/mpd_options.h"
20 
21 namespace shaka {
22 
23 namespace media {
24 class File;
25 } // namespace media
26 
27 class MediaInfo;
28 
33  public:
35  virtual ~MpdNotifierFactory() {}
36 
37  virtual std::unique_ptr<MpdNotifier> Create(
38  const MpdOptions& mpd_options) = 0;
39 };
40 
41 // An instance of this class takes a set of MediaInfo files and generates an
42 // MPD when one of WriteMpd* methods are called. This generates an MPD with one
43 // <Period> element and at most three <AdaptationSet> elements, each for video,
44 // audio, and text. Information in MediaInfo will be put into one of the
45 // AdaptationSets by checking the video_info, audio_info, and text_info fields.
46 // Therefore, this cannot handle an instance of MediaInfo with video, audio, and
47 // text combination.
48 class MpdWriter {
49  public:
50  MpdWriter();
51  ~MpdWriter();
52 
53  // Add |media_info_path| for MPD generation.
54  // The content of |media_info_path| should be a string representation of
55  // MediaInfo, i.e. the content should be a result of using
56  // google::protobuf::TestFormat::Print*() methods.
57  // If necessary, this method can be called after WriteMpd*() methods.
58  bool AddFile(const std::string& media_info_path);
59 
60  // |base_url| will be used for <BaseURL> element for the MPD. The BaseURL
61  // element will be a direct child element of the <MPD> element.
62  void AddBaseUrl(const std::string& base_url);
63 
64  // Write the MPD to |file_name|. |file_name| should not be NULL.
65  // This opens the file in write mode, IOW if the
66  // file exists this will over write whatever is in the file.
67  // AddFile() should be called before calling this function to generate an MPD.
68  // On success, the MPD gets written to |file| and returns true, otherwise
69  // returns false.
70  // This method can be called multiple times, if necessary.
71  bool WriteMpdToFile(const char* file_name);
72 
73  private:
74  friend class MpdWriterTest;
75 
76  void SetMpdNotifierFactoryForTest(
77  std::unique_ptr<MpdNotifierFactory> factory);
78 
79  std::list<MediaInfo> media_infos_;
80  std::vector<std::string> base_urls_;
81 
82  std::unique_ptr<MpdNotifierFactory> notifier_factory_;
83 
84  DISALLOW_COPY_AND_ASSIGN(MpdWriter);
85 };
86 
87 } // namespace shaka
88 
89 #endif // MPD_UTIL_MPD_WRITER_H_
-
All the methods that are virtual are virtual for mocking.
- -
Defines Mpd Options.
Definition: mpd_options.h:25
-
bool WriteMpdToFile(const std::string &output_path, MpdBuilder *mpd_builder)
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Class for reading in MediaInfo from files and writing out an MPD.
+
8 
+
9 #ifndef MPD_UTIL_MPD_WRITER_H_
+
10 #define MPD_UTIL_MPD_WRITER_H_
+
11 
+
12 #include <list>
+
13 #include <memory>
+
14 #include <string>
+
15 #include <vector>
+
16 
+
17 #include "packager/base/macros.h"
+
18 #include "packager/mpd/base/mpd_notifier.h"
+
19 #include "packager/mpd/base/mpd_options.h"
+
20 
+
21 namespace shaka {
+
22 
+
23 namespace media {
+
24 class File;
+
25 } // namespace media
+
26 
+
27 class MediaInfo;
+
28 
+ +
33  public:
+ +
35  virtual ~MpdNotifierFactory() {}
+
36 
+
37  virtual std::unique_ptr<MpdNotifier> Create(
+
38  const MpdOptions& mpd_options) = 0;
+
39 };
+
40 
+
41 // An instance of this class takes a set of MediaInfo files and generates an
+
42 // MPD when one of WriteMpd* methods are called. This generates an MPD with one
+
43 // <Period> element and at most three <AdaptationSet> elements, each for video,
+
44 // audio, and text. Information in MediaInfo will be put into one of the
+
45 // AdaptationSets by checking the video_info, audio_info, and text_info fields.
+
46 // Therefore, this cannot handle an instance of MediaInfo with video, audio, and
+
47 // text combination.
+
48 class MpdWriter {
+
49  public:
+
50  MpdWriter();
+
51  ~MpdWriter();
+
52 
+
53  // Add |media_info_path| for MPD generation.
+
54  // The content of |media_info_path| should be a string representation of
+
55  // MediaInfo, i.e. the content should be a result of using
+
56  // google::protobuf::TestFormat::Print*() methods.
+
57  // If necessary, this method can be called after WriteMpd*() methods.
+
58  bool AddFile(const std::string& media_info_path);
+
59 
+
60  // |base_url| will be used for <BaseURL> element for the MPD. The BaseURL
+
61  // element will be a direct child element of the <MPD> element.
+
62  void AddBaseUrl(const std::string& base_url);
+
63 
+
64  // Write the MPD to |file_name|. |file_name| should not be NULL.
+
65  // This opens the file in write mode, IOW if the
+
66  // file exists this will over write whatever is in the file.
+
67  // AddFile() should be called before calling this function to generate an MPD.
+
68  // On success, the MPD gets written to |file| and returns true, otherwise
+
69  // returns false.
+
70  // This method can be called multiple times, if necessary.
+
71  bool WriteMpdToFile(const char* file_name);
+
72 
+
73  private:
+
74  friend class MpdWriterTest;
+
75 
+
76  void SetMpdNotifierFactoryForTest(
+
77  std::unique_ptr<MpdNotifierFactory> factory);
+
78 
+
79  std::list<MediaInfo> media_infos_;
+
80  std::vector<std::string> base_urls_;
+
81 
+
82  std::unique_ptr<MpdNotifierFactory> notifier_factory_;
+
83 
+
84  DISALLOW_COPY_AND_ASSIGN(MpdWriter);
+
85 };
+
86 
+
87 } // namespace shaka
+
88 
+
89 #endif // MPD_UTIL_MPD_WRITER_H_
+ + +
All the methods that are virtual are virtual for mocking.
+
Defines Mpd Options.
Definition: mpd_options.h:25
diff --git a/docs/d7/db7/structshaka_1_1media_1_1mp4_1_1SampleToChunk-members.html b/docs/d7/db7/structshaka_1_1media_1_1mp4_1_1SampleToChunk-members.html index a9bd42dca9..60cba5726b 100644 --- a/docs/d7/db7/structshaka_1_1media_1_1mp4_1_1SampleToChunk-members.html +++ b/docs/d7/db7/structshaka_1_1media_1_1mp4_1_1SampleToChunk-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d7/dbd/classshaka_1_1LocalFile.html b/docs/d7/dbd/classshaka_1_1LocalFile.html index fd94c6bfd4..5431772381 100644 --- a/docs/d7/dbd/classshaka_1_1LocalFile.html +++ b/docs/d7/dbd/classshaka_1_1LocalFile.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::LocalFile Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-

Implement LocalFile which deals with local storage. +

Implement LocalFile which deals with local storage. More...

#include <local_file.h>

@@ -82,9 +85,9 @@ Inheritance diagram for shaka::LocalFile:
-shaka::File - -
+shaka::File + + @@ -155,7 +158,7 @@ bool 

Public Member Functions

 

Detailed Description

-

Implement LocalFile which deals with local storage.

+

Implement LocalFile which deals with local storage.

Definition at line 20 of file local_file.h.

Constructor & Destructor Documentation

@@ -219,7 +222,7 @@ bool  -

Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

Returns
true on success. For writable files, returning false MAY INDICATE DATA LOSS.
+

Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

Returns
true on success. For writable files, returning false MAY INDICATE DATA LOSS.

Implements shaka::File.

@@ -284,7 +287,7 @@ bool  -

Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

Returns
true on success, false otherwise.
+

Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

Returns
true on success, false otherwise.

Implements shaka::File.

@@ -499,9 +502,7 @@ bool  diff --git a/docs/d7/dc3/structshaka_1_1media_1_1mp4_1_1TextSampleEntry.html b/docs/d7/dc3/structshaka_1_1media_1_1mp4_1_1TextSampleEntry.html index 93dbb84290..23233a02c3 100644 --- a/docs/d7/dc3/structshaka_1_1media_1_1mp4_1_1TextSampleEntry.html +++ b/docs/d7/dc3/structshaka_1_1media_1_1mp4_1_1TextSampleEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TextSampleEntry Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -106,6 +109,12 @@ FourCC  + + + + @@ -121,7 +130,7 @@ Additional Inherited Members

Public Member Functions

format = FOURCC
uint16_t data_reference_index = 1u
 
+std::string namespace_
 
+std::string schema_location
 
WebVTTConfigurationBox config
 

Detailed Description

-

Definition at line 391 of file box_definitions.h.

+

Definition at line 399 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -149,7 +158,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 1947 of file box_definitions.cc.

+

Definition at line 1996 of file box_definitions.cc.

@@ -160,9 +169,7 @@ Additional Inherited Members diff --git a/docs/d7/dc6/byte__queue_8h_source.html b/docs/d7/dc6/byte__queue_8h_source.html index d7a92bf554..e0d19c8b42 100644 --- a/docs/d7/dc6/byte__queue_8h_source.html +++ b/docs/d7/dc6/byte__queue_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/byte_queue.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
byte_queue.h
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_BASE_BYTE_QUEUE_H_
6 #define PACKAGER_MEDIA_BASE_BYTE_QUEUE_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 
12 #include "packager/base/macros.h"
13 
14 namespace shaka {
15 namespace media {
16 
22 class ByteQueue {
23  public:
24  ByteQueue();
25  ~ByteQueue();
26 
28  void Reset();
29 
31  void Push(const uint8_t* data, int size);
32 
35  void Peek(const uint8_t** data, int* size) const;
36 
39  void Pop(int count);
40 
41  private:
42  // Returns a pointer to the front of the queue.
43  uint8_t* front() const;
44 
45  std::unique_ptr<uint8_t[]> buffer_;
46 
47  // Size of |buffer_|.
48  size_t size_;
49 
50  // Offset from the start of |buffer_| that marks the front of the queue.
51  size_t offset_;
52 
53  // Number of bytes stored in the queue.
54  int used_;
55 
56  DISALLOW_COPY_AND_ASSIGN(ByteQueue);
57 };
58 
59 } // namespace media
60 } // namespace shaka
61 
62 #endif // PACKAGER_MEDIA_BASE_BYTE_QUEUE_H_
All the methods that are virtual are virtual for mocking.
-
void Push(const uint8_t *data, int size)
Append new bytes to the end of the queue.
Definition: byte_queue.cc:29
-
void Pop(int count)
Definition: byte_queue.cc:70
-
void Reset()
Reset the queue to the empty state.
Definition: byte_queue.cc:24
-
void Peek(const uint8_t **data, int *size) const
Definition: byte_queue.cc:63
- +
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_BASE_BYTE_QUEUE_H_
+
6 #define PACKAGER_MEDIA_BASE_BYTE_QUEUE_H_
+
7 
+
8 #include <stdint.h>
+
9 
+
10 #include <memory>
+
11 
+
12 #include "packager/base/macros.h"
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 
+
22 class ByteQueue {
+
23  public:
+
24  ByteQueue();
+
25  ~ByteQueue();
+
26 
+
28  void Reset();
+
29 
+
31  void Push(const uint8_t* data, int size);
+
32 
+
35  void Peek(const uint8_t** data, int* size) const;
+
36 
+
39  void Pop(int count);
+
40 
+
41  private:
+
42  // Returns a pointer to the front of the queue.
+
43  uint8_t* front() const;
+
44 
+
45  std::unique_ptr<uint8_t[]> buffer_;
+
46 
+
47  // Size of |buffer_|.
+
48  size_t size_;
+
49 
+
50  // Offset from the start of |buffer_| that marks the front of the queue.
+
51  size_t offset_;
+
52 
+
53  // Number of bytes stored in the queue.
+
54  int used_;
+
55 
+
56  DISALLOW_COPY_AND_ASSIGN(ByteQueue);
+
57 };
+
58 
+
59 } // namespace media
+
60 } // namespace shaka
+
61 
+
62 #endif // PACKAGER_MEDIA_BASE_BYTE_QUEUE_H_
+ +
void Pop(int count)
Definition: byte_queue.cc:69
+
void Peek(const uint8_t **data, int *size) const
Definition: byte_queue.cc:62
+
void Reset()
Reset the queue to the empty state.
Definition: byte_queue.cc:24
+
void Push(const uint8_t *data, int size)
Append new bytes to the end of the queue.
Definition: byte_queue.cc:29
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/dcf/classshaka_1_1media_1_1CcStreamFilter-members.html b/docs/d7/dcf/classshaka_1_1media_1_1CcStreamFilter-members.html new file mode 100644 index 0000000000..a7f6007300 --- /dev/null +++ b/docs/d7/dcf/classshaka_1_1media_1_1CcStreamFilter-members.html @@ -0,0 +1,107 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::CcStreamFilter Member List
+
+
+ +

This is the complete list of members for shaka::media::CcStreamFilter, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
CcStreamFilter(const std::string &language, uint16_t cc_index) (defined in shaka::media::CcStreamFilter)shaka::media::CcStreamFilter
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) constshaka::media::MediaHandlerinlineprotected
DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) constshaka::media::MediaHandlerinlineprotected
DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) constshaka::media::MediaHandlerinlineprotected
DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) constshaka::media::MediaHandlerinlineprotected
FlushAllDownstreams()shaka::media::MediaHandlerprotected
FlushDownstream(size_t output_stream_index)shaka::media::MediaHandlerprotected
Initialize()shaka::media::MediaHandler
initialized() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
InitializeInternal() overrideshaka::media::CcStreamFilterprotectedvirtual
IsConnected()shaka::media::MediaHandlerinline
MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandler
next_output_stream_index() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
num_input_streams() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
OnFlushRequest(size_t input_stream_index)shaka::media::MediaHandlerprotectedvirtual
output_handlers() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
Process(std::unique_ptr< StreamData > stream_data) overrideshaka::media::CcStreamFilterprotectedvirtual
SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandler
ValidateOutputStreamIndex(size_t stream_index) constshaka::media::MediaHandlerprotectedvirtual
~CcStreamFilter() override=default (defined in shaka::media::CcStreamFilter)shaka::media::CcStreamFilter
~MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandlervirtual
+ + + + diff --git a/docs/d7/dd0/mpd__notifier__util_8h_source.html b/docs/d7/dd0/mpd__notifier__util_8h_source.html index a75e23b8bb..2555886356 100644 --- a/docs/d7/dd0/mpd__notifier__util_8h_source.html +++ b/docs/d7/dd0/mpd__notifier__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mpd_notifier_util.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mpd_notifier_util.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
9 
10 #ifndef MPD_BASE_MPD_NOTIFIER_UTIL_H_
11 #define MPD_BASE_MPD_NOTIFIER_UTIL_H_
12 
13 #include <string>
14 #include <vector>
15 
16 #include "packager/base/base64.h"
17 #include "packager/mpd/base/media_info.pb.h"
18 #include "packager/mpd/base/mpd_builder.h"
19 
20 namespace shaka{
21 
22 enum ContentType {
23  kContentTypeUnknown,
24  kContentTypeVideo,
25  kContentTypeAudio,
26  kContentTypeText
27 };
28 
32 bool WriteMpdToFile(const std::string& output_path, MpdBuilder* mpd_builder);
33 
37 ContentType GetContentType(const MediaInfo& media_info);
38 
40 std::string Uint8VectorToBase64(const std::vector<uint8_t>& input);
41 
42 } // namespace shaka
43 
44 #endif // MPD_BASE_MPD_NOTIFIER_UTIL_H_
All the methods that are virtual are virtual for mocking.
-
std::string Uint8VectorToBase64(const std::vector< uint8_t > &input)
Converts uint8 vector into base64 encoded string.
-
ContentType GetContentType(const MediaInfo &media_info)
-
bool WriteMpdToFile(const std::string &output_path, MpdBuilder *mpd_builder)
+
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
9 
+
10 #ifndef MPD_BASE_MPD_NOTIFIER_UTIL_H_
+
11 #define MPD_BASE_MPD_NOTIFIER_UTIL_H_
+
12 
+
13 #include <string>
+
14 #include <vector>
+
15 
+
16 #include "packager/base/base64.h"
+
17 #include "packager/mpd/base/media_info.pb.h"
+
18 #include "packager/mpd/base/mpd_builder.h"
+
19 
+
20 namespace shaka{
+
21 
+
22 enum ContentType {
+
23  kContentTypeUnknown,
+
24  kContentTypeVideo,
+
25  kContentTypeAudio,
+
26  kContentTypeText
+
27 };
+
28 
+
32 bool WriteMpdToFile(const std::string& output_path, MpdBuilder* mpd_builder);
+
33 
+
37 ContentType GetContentType(const MediaInfo& media_info);
+
38 
+
40 std::string Uint8VectorToBase64(const std::vector<uint8_t>& input);
+
41 
+
42 } // namespace shaka
+
43 
+
44 #endif // MPD_BASE_MPD_NOTIFIER_UTIL_H_
+
All the methods that are virtual are virtual for mocking.
+
std::string Uint8VectorToBase64(const std::vector< uint8_t > &input)
Converts uint8 vector into base64 encoded string.
+
ContentType GetContentType(const MediaInfo &media_info)
+
bool WriteMpdToFile(const std::string &output_path, MpdBuilder *mpd_builder)
diff --git a/docs/d7/dd4/request__signer_8h_source.html b/docs/d7/dd4/request__signer_8h_source.html index 0fdb9bd193..9acfc30eed 100644 --- a/docs/d7/dd4/request__signer_8h_source.html +++ b/docs/d7/dd4/request__signer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/request_signer.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
request_signer.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_REQUEST_SIGNER_H_
8 #define PACKAGER_MEDIA_BASE_REQUEST_SIGNER_H_
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "packager/base/macros.h"
15 
16 namespace shaka {
17 namespace media {
18 
19 class AesCbcEncryptor;
20 class RsaPrivateKey;
21 
24  public:
25  virtual ~RequestSigner();
26 
30  virtual bool GenerateSignature(const std::string& message,
31  std::string* signature) = 0;
32 
33  const std::string& signer_name() const { return signer_name_; }
34 
35  protected:
36  explicit RequestSigner(const std::string& signer_name);
37 
38  private:
39  std::string signer_name_;
40 
41  DISALLOW_COPY_AND_ASSIGN(RequestSigner);
42 };
43 
46  public:
47  ~AesRequestSigner() override;
48 
51  static AesRequestSigner* CreateSigner(const std::string& signer_name,
52  const std::vector<uint8_t>& aes_key,
53  const std::vector<uint8_t>& iv);
54 
56  bool GenerateSignature(const std::string& message,
57  std::string* signature) override;
58 
59  private:
60  AesRequestSigner(const std::string& signer_name,
61  std::unique_ptr<AesCbcEncryptor> encryptor);
62 
63  std::unique_ptr<AesCbcEncryptor> aes_cbc_encryptor_;
64 
65  DISALLOW_COPY_AND_ASSIGN(AesRequestSigner);
66 };
67 
70  public:
71  ~RsaRequestSigner() override;
72 
75  static RsaRequestSigner* CreateSigner(const std::string& signer_name,
76  const std::string& pkcs1_rsa_key);
77 
79  bool GenerateSignature(const std::string& message,
80  std::string* signature) override;
81 
82  private:
83  RsaRequestSigner(const std::string& signer_name,
84  std::unique_ptr<RsaPrivateKey> rsa_private_key);
85 
86  std::unique_ptr<RsaPrivateKey> rsa_private_key_;
87 
88  DISALLOW_COPY_AND_ASSIGN(RsaRequestSigner);
89 };
90 
91 } // namespace media
92 } // namespace shaka
93 
94 #endif // PACKAGER_MEDIA_BASE_REQUEST_SIGNER_H_
Abstract class used for signature generation.
-
All the methods that are virtual are virtual for mocking.
-
RsaRequestSigner uses RSA-PSS signing.
-
AesRequestSigner uses AES-CBC signing.
-
virtual bool GenerateSignature(const std::string &message, std::string *signature)=0
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_REQUEST_SIGNER_H_
+
8 #define PACKAGER_MEDIA_BASE_REQUEST_SIGNER_H_
+
9 
+
10 #include <memory>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/base/macros.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+
19 class AesCbcEncryptor;
+
20 class RsaPrivateKey;
+
21 
+ +
24  public:
+
25  virtual ~RequestSigner();
+
26 
+
30  virtual bool GenerateSignature(const std::string& message,
+
31  std::string* signature) = 0;
+
32 
+
33  const std::string& signer_name() const { return signer_name_; }
+
34 
+
35  protected:
+
36  explicit RequestSigner(const std::string& signer_name);
+
37 
+
38  private:
+
39  std::string signer_name_;
+
40 
+
41  DISALLOW_COPY_AND_ASSIGN(RequestSigner);
+
42 };
+
43 
+ +
46  public:
+
47  ~AesRequestSigner() override;
+
48 
+
51  static AesRequestSigner* CreateSigner(const std::string& signer_name,
+
52  const std::vector<uint8_t>& aes_key,
+
53  const std::vector<uint8_t>& iv);
+
54 
+
56  bool GenerateSignature(const std::string& message,
+
57  std::string* signature) override;
+
58 
+
59  private:
+
60  AesRequestSigner(const std::string& signer_name,
+
61  std::unique_ptr<AesCbcEncryptor> encryptor);
+
62 
+
63  std::unique_ptr<AesCbcEncryptor> aes_cbc_encryptor_;
+
64 
+
65  DISALLOW_COPY_AND_ASSIGN(AesRequestSigner);
+
66 };
+
67 
+ +
70  public:
+
71  ~RsaRequestSigner() override;
+
72 
+
75  static RsaRequestSigner* CreateSigner(const std::string& signer_name,
+
76  const std::string& pkcs1_rsa_key);
+
77 
+
79  bool GenerateSignature(const std::string& message,
+
80  std::string* signature) override;
+
81 
+
82  private:
+
83  RsaRequestSigner(const std::string& signer_name,
+
84  std::unique_ptr<RsaPrivateKey> rsa_private_key);
+
85 
+
86  std::unique_ptr<RsaPrivateKey> rsa_private_key_;
+
87 
+
88  DISALLOW_COPY_AND_ASSIGN(RsaRequestSigner);
+
89 };
+
90 
+
91 } // namespace media
+
92 } // namespace shaka
+
93 
+
94 #endif // PACKAGER_MEDIA_BASE_REQUEST_SIGNER_H_
+
AesRequestSigner uses AES-CBC signing.
+
bool GenerateSignature(const std::string &message, std::string *signature) override
RequestSigner implementation override.
+
static AesRequestSigner * CreateSigner(const std::string &signer_name, const std::vector< uint8_t > &aes_key, const std::vector< uint8_t > &iv)
+
Abstract class used for signature generation.
+
virtual bool GenerateSignature(const std::string &message, std::string *signature)=0
+
RsaRequestSigner uses RSA-PSS signing.
+
bool GenerateSignature(const std::string &message, std::string *signature) override
RequestSigner implementation override.
+
static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/dd5/ac4__audio__util_8h_source.html b/docs/d7/dd5/ac4__audio__util_8h_source.html new file mode 100644 index 0000000000..5774f4462b --- /dev/null +++ b/docs/d7/dd5/ac4__audio__util_8h_source.html @@ -0,0 +1,114 @@ + + + + + + + +Shaka Packager SDK: packager/media/codecs/ac4_audio_util.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ac4_audio_util.h
+
+
+
1 // Copyright 2020 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // AC4 audio utility functions.
+
8 
+
9 #ifndef PACKAGER_MEDIA_CODECS_AC4_AUDIO_UTIL_H_
+
10 #define PACKAGER_MEDIA_CODECS_AC4_AUDIO_UTIL_H_
+
11 
+
12 #include <stddef.h>
+
13 #include <stdint.h>
+
14 #include <vector>
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+
23 bool CalculateAC4ChannelMask(const std::vector<uint8_t>& ac4_data,
+
24  uint32_t* ac4_channel_mask);
+
25 
+
31 bool CalculateAC4ChannelMPEGValue(const std::vector<uint8_t>& ac4_data,
+
32  uint32_t* ac4_channel_mpeg_value);
+
33 
+
39 bool GetAc4CodecInfo(const std::vector<uint8_t>& ac4_data,
+
40  uint8_t* ac4_codec_info);
+
41 
+
45 bool GetAc4ImmersiveInfo(const std::vector<uint8_t>& ac4_data,
+
46  bool* ac4_ims_flag,
+
47  bool* ac4_cbi_flag);
+
48 
+
49 } // namespace media
+
50 } // namespace shaka
+
51 
+
52 #endif // PACKAGER_MEDIA_CODECS_AC4_AUDIO_UTIL_H_
+
All the methods that are virtual are virtual for mocking.
+
+ + + + diff --git a/docs/d7/dd5/classshaka_1_1media_1_1mp4_1_1MP4MediaParser.html b/docs/d7/dd5/classshaka_1_1media_1_1mp4_1_1MP4MediaParser.html index 7be0bb4965..5ab9cb322a 100644 --- a/docs/d7/dd5/classshaka_1_1media_1_1mp4_1_1MP4MediaParser.html +++ b/docs/d7/dd5/classshaka_1_1media_1_1mp4_1_1MP4MediaParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MP4MediaParser Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::MediaParser - -
+ + - - + + @@ -96,8 +99,10 @@ Additional Inherited Members - - + + + +

Public Member Functions

bool LoadMoov (const std::string &file_path)
 
MediaParser implementation overrides.
void Init (const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
 
void Init (const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
 
bool Flush () override WARN_UNUSED_RESULT
 
bool Parse (const uint8_t *buf, int size) override WARN_UNUSED_RESULT
- Public Types inherited from shaka::media::MediaParser
typedef base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
 
typedef base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
 
typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
 
typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
 

Detailed Description

@@ -129,12 +134,12 @@ Additional Inherited Members

Implements shaka::media::MediaParser.

-

Definition at line 187 of file mp4_media_parser.cc.

+

Definition at line 205 of file mp4_media_parser.cc.

- -

◆ Init()

+ +

◆ Init()

@@ -151,8 +156,14 @@ Additional Inherited Members - const NewSampleCB &  - new_sample_cb, + const NewMediaSampleCB &  + new_media_sample_cb, + + + + + const NewTextSampleCB &  + new_text_sample_cb, @@ -175,14 +186,16 @@ Additional Inherited Members

Initialize the parser with necessary callbacks. Must be called before any data is passed to Parse().

Parameters
- + + +
init_cbwill be called once enough data has been parsed to determine the initial stream configurations.
new_sample_cbwill be called each time a new media sample is available from the parser. May be NULL, and caller retains ownership.
new_media_sample_cbwill be called each time a new media sample is available from the parser.
new_text_sample_cbwill be called each time a new text sample is available from the parser.
decryption_key_sourcethe key source to decrypt the frames. May be NULL, and caller retains ownership.
-

Implements shaka::media::MediaParser.

+

Implements shaka::media::MediaParser.

-

Definition at line 164 of file mp4_media_parser.cc.

+

Definition at line 181 of file mp4_media_parser.cc.

@@ -209,7 +222,7 @@ Additional Inherited Members
Returns
true if successful, false otherwise.
-

Definition at line 228 of file mp4_media_parser.cc.

+

Definition at line 246 of file mp4_media_parser.cc.

@@ -250,7 +263,7 @@ Additional Inherited Members

Implements shaka::media::MediaParser.

-

Definition at line 194 of file mp4_media_parser.cc.

+

Definition at line 212 of file mp4_media_parser.cc.

@@ -261,9 +274,7 @@ Additional Inherited Members diff --git a/docs/d7/dd6/key__source_8cc_source.html b/docs/d7/dd6/key__source_8cc_source.html index 2bea927ddd..992c830fa9 100644 --- a/docs/d7/dd6/key__source_8cc_source.html +++ b/docs/d7/dd6/key__source_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/key_source.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
key_source.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/key_source.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/media/base/common_pssh_generator.h"
11 #include "packager/media/base/playready_pssh_generator.h"
12 #include "packager/media/base/protection_system_ids.h"
13 #include "packager/media/base/widevine_pssh_generator.h"
14 #include "packager/status_macros.h"
15 
16 namespace shaka {
17 namespace media {
18 
19 KeySource::KeySource(int protection_systems_flags, FourCC protection_scheme) {
20  if (protection_systems_flags & COMMON_PROTECTION_SYSTEM_FLAG) {
21  pssh_generators_.emplace_back(new CommonPsshGenerator());
22  }
23 
24  if (protection_systems_flags & PLAYREADY_PROTECTION_SYSTEM_FLAG) {
25  pssh_generators_.emplace_back(
26  new PlayReadyPsshGenerator(protection_scheme));
27  }
28 
29  if (protection_systems_flags & WIDEVINE_PROTECTION_SYSTEM_FLAG) {
30  pssh_generators_.emplace_back(new WidevinePsshGenerator(protection_scheme));
31  }
32 
33  if (protection_systems_flags & FAIRPLAY_PROTECTION_SYSTEM_FLAG) {
34  no_pssh_systems_.emplace_back(std::begin(kFairPlaySystemId),
35  std::end(kFairPlaySystemId));
36  }
37  // We only support Marlin Adaptive Streaming Specification – Simple Profile
38  // with Implicit Content ID Mapping, which does not need a PSSH. Marlin
39  // specific PSSH with Explicit Content ID Mapping is not generated.
40  if (protection_systems_flags & MARLIN_PROTECTION_SYSTEM_FLAG) {
41  no_pssh_systems_.emplace_back(std::begin(kMarlinSystemId),
42  std::end(kMarlinSystemId));
43  }
44 }
45 
46 KeySource::~KeySource() = default;
47 
49  EncryptionKeyMap* encryption_key_map) {
50  for (const auto& pssh_generator : pssh_generators_) {
51  const bool support_multiple_keys = pssh_generator->SupportMultipleKeys();
52  if (support_multiple_keys) {
54  std::vector<std::vector<uint8_t>> key_ids;
55  for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
56  key_ids.push_back(pair.second->key_id);
57  }
58  RETURN_IF_ERROR(pssh_generator->GeneratePsshFromKeyIds(key_ids, &info));
59  for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
60  pair.second->key_system_info.push_back(info);
61  }
62  } else {
63  for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
65  RETURN_IF_ERROR(pssh_generator->GeneratePsshFromKeyIdAndKey(
66  pair.second->key_id, pair.second->key, &info));
67  pair.second->key_system_info.push_back(info);
68  }
69  }
70  }
71 
72  for (const auto& no_pssh_system : no_pssh_systems_) {
74  info.system_id = no_pssh_system;
75  for (const EncryptionKeyMap::value_type& pair : *encryption_key_map) {
76  pair.second->key_system_info.push_back(info);
77  }
78  }
79 
80  return Status::OK;
81 }
82 
83 } // namespace media
84 } // namespace shaka
All the methods that are virtual are virtual for mocking.
- -
Status UpdateProtectionSystemInfo(EncryptionKeyMap *encryption_key_map)
Definition: key_source.cc:48
- +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/key_source.h"
+
8 
+
9 namespace shaka {
+
10 namespace media {
+
11 
+
12 KeySource::KeySource() = default;
+
13 
+
14 KeySource::~KeySource() = default;
+
15 
+
16 } // namespace media
+
17 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/dda/classshaka_1_1media_1_1ByteQueue.html b/docs/d7/dda/classshaka_1_1media_1_1ByteQueue.html index b3c5e3739d..76be6e3128 100644 --- a/docs/d7/dda/classshaka_1_1media_1_1ByteQueue.html +++ b/docs/d7/dda/classshaka_1_1media_1_1ByteQueue.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ByteQueue Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
 

Detailed Description

-

Represents a queue of bytes. Data is added to the end of the queue via an Push() and removed via Pop(). The contents of the queue can be observed via the Peek() method. This class manages the underlying storage of the queue and tries to minimize the number of buffer copies when data is appended and removed.

+

Represents a queue of bytes. Data is added to the end of the queue via an Push() and removed via Pop(). The contents of the queue can be observed via the Peek() method. This class manages the underlying storage of the queue and tries to minimize the number of buffer copies when data is appended and removed.

Definition at line 22 of file byte_queue.h.

Member Function Documentation

@@ -117,9 +120,9 @@ void  -

Get a pointer to the front of the queue and the queue size. These values are only valid until the next Push() or Pop() call.

+

Get a pointer to the front of the queue and the queue size. These values are only valid until the next Push() or Pop() call.

-

Definition at line 63 of file byte_queue.cc.

+

Definition at line 62 of file byte_queue.cc.

@@ -145,7 +148,7 @@ void Definition at line 70 of file byte_queue.cc.

+

Definition at line 69 of file byte_queue.cc.

@@ -156,9 +159,7 @@ void  diff --git a/docs/d7/ddd/classshaka_1_1media_1_1RsaRequestSigner.html b/docs/d7/ddd/classshaka_1_1media_1_1RsaRequestSigner.html index c2aef273bb..1145c2294b 100644 --- a/docs/d7/ddd/classshaka_1_1media_1_1RsaRequestSigner.html +++ b/docs/d7/ddd/classshaka_1_1media_1_1RsaRequestSigner.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::RsaRequestSigner Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-

RsaRequestSigner uses RSA-PSS signing. +

RsaRequestSigner uses RSA-PSS signing. More...

#include <request_signer.h>

@@ -81,15 +84,15 @@ Inheritance diagram for shaka::media::RsaRequestSigner:
-shaka::media::RequestSigner - -
+shaka::media::RequestSigner + + - +

Public Member Functions

bool GenerateSignature (const std::string &message, std::string *signature) override
 RequestSigner implementation override.
 RequestSigner implementation override.
 
- Public Member Functions inherited from shaka::media::RequestSigner
@@ -109,7 +112,7 @@ Additional Inherited Members
 

Detailed Description

-

RsaRequestSigner uses RSA-PSS signing.

+

RsaRequestSigner uses RSA-PSS signing.

Definition at line 69 of file request_signer.h.

Member Function Documentation

@@ -146,7 +149,7 @@ Additional Inherited Members
-

Create an RsaSigner object using a DER encoded PKCS#1 RSAPrivateKey.

Returns
The created RsaRequestSigner object on success, NULL otherwise.
+

Create an RsaSigner object using a DER encoded PKCS#1 RSAPrivateKey.

Returns
The created RsaRequestSigner object on success, NULL otherwise.

Definition at line 53 of file request_signer.cc.

@@ -159,9 +162,7 @@ Additional Inherited Members
diff --git a/docs/d7/dde/cc__stream__filter_8cc_source.html b/docs/d7/dde/cc__stream__filter_8cc_source.html new file mode 100644 index 0000000000..3dc4a1dbc9 --- /dev/null +++ b/docs/d7/dde/cc__stream__filter_8cc_source.html @@ -0,0 +1,135 @@ + + + + + + + +Shaka Packager SDK: packager/media/base/cc_stream_filter.cc Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
cc_stream_filter.cc
+
+
+
1 // Copyright 2020 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/cc_stream_filter.h"
+
8 
+
9 #include "packager/media/base/stream_info.h"
+
10 #include "packager/media/base/text_stream_info.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+
15 CcStreamFilter::CcStreamFilter(const std::string& language, uint16_t cc_index)
+
16  : language_(language), cc_index_(cc_index) {}
+
17 
+
18 Status CcStreamFilter::InitializeInternal() {
+
19  return Status::OK;
+
20 }
+
21 
+
22 Status CcStreamFilter::Process(std::unique_ptr<StreamData> stream_data) {
+
23  if (stream_data->stream_data_type == StreamDataType::kTextSample) {
+
24  if (stream_data->text_sample->sub_stream_index() != -1 &&
+
25  stream_data->text_sample->sub_stream_index() != cc_index_) {
+
26  return Status::OK;
+
27  }
+
28  } else if (stream_data->stream_data_type == StreamDataType::kStreamInfo) {
+
29  if (stream_data->stream_info->stream_type() == kStreamText) {
+
30  // Overwrite the per-input-stream language with our per-output-stream
+
31  // language; this requires cloning the stream info as it is used by other
+
32  // output streams.
+
33  auto clone = stream_data->stream_info->Clone();
+
34  if (!language_.empty()) {
+
35  clone->set_language(language_);
+
36  } else {
+
37  // Try to find the language in the sub-stream info.
+
38  auto* text_info = static_cast<TextStreamInfo*>(clone.get());
+
39  auto it = text_info->sub_streams().find(cc_index_);
+
40  if (it != text_info->sub_streams().end()) {
+
41  clone->set_language(it->second.language);
+
42  }
+
43  }
+
44 
+
45  stream_data = StreamData::FromStreamInfo(stream_data->stream_index,
+
46  std::move(clone));
+
47  }
+
48  }
+
49 
+
50  return Dispatch(std::move(stream_data));
+
51 }
+
52 
+
53 } // namespace media
+
54 } // namespace shaka
+ + +
All the methods that are virtual are virtual for mocking.
+
+ + + + diff --git a/docs/d7/ddf/structshaka_1_1media_1_1ProtectionSystemSpecificInfo-members.html b/docs/d7/ddf/structshaka_1_1media_1_1ProtectionSystemSpecificInfo-members.html index 40f142aceb..9dd019213c 100644 --- a/docs/d7/ddf/structshaka_1_1media_1_1ProtectionSystemSpecificInfo-members.html +++ b/docs/d7/ddf/structshaka_1_1media_1_1ProtectionSystemSpecificInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d7/de0/classshaka_1_1media_1_1HttpKeyFetcher.html b/docs/d7/de0/classshaka_1_1media_1_1HttpKeyFetcher.html index 7fbb994c55..30a91003b2 100644 --- a/docs/d7/de0/classshaka_1_1media_1_1HttpKeyFetcher.html +++ b/docs/d7/de0/classshaka_1_1media_1_1HttpKeyFetcher.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::HttpKeyFetcher Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-shaka::media::KeyFetcher - -
+shaka::media::KeyFetcher + + @@ -90,23 +93,18 @@ Public Member Functions

Public Member Functions

 HttpKeyFetcher (uint32_t timeout_in_seconds)
 
- + - - - -

-KeyFetcher implementation overrides.

KeyFetcher implementation overrides.

Status FetchKeys (const std::string &url, const std::string &request, std::string *response) override
 
virtual Status Get (const std::string &url, std::string *response)
 
virtual Status Post (const std::string &url, const std::string &data, std::string *response)
 
void SetClientCertInfo (const std::string &cert_file, const std::string &private_key_file, const std::string &private_key_password)
 
void SetCaFile (const std::string &ca_file)
 

Detailed Description

-

A KeyFetcher implementation that retrieves keys over HTTP(s). This class is not fully thread safe. It can be used in multi-thread environment once constructed, but it may not be safe to create a HttpKeyFetcher object when any other thread is running due to use of curl_global_init.

+

A KeyFetcher implementation that retrieves keys over HTTP(s). This class is not fully thread safe. It can be used in multi-thread environment once constructed, but it may not be safe to create a HttpKeyFetcher object when any other thread is running due to use of curl_global_init.

-

Definition at line 26 of file http_key_fetcher.h.

+

Definition at line 25 of file http_key_fetcher.h.

Constructor & Destructor Documentation

◆ HttpKeyFetcher()

@@ -130,7 +128,7 @@ KeyFetcher implementation overrides. -

Definition at line 139 of file http_key_fetcher.cc.

+

Definition at line 27 of file http_key_fetcher.cc.

@@ -186,7 +184,7 @@ KeyFetcher implementation overrides.

Implements shaka::media::KeyFetcher.

-

Definition at line 144 of file http_key_fetcher.cc.

+

Definition at line 32 of file http_key_fetcher.cc.

@@ -232,7 +230,7 @@ KeyFetcher implementation overrides.
Returns
OK on success.
-

Definition at line 150 of file http_key_fetcher.cc.

+

Definition at line 38 of file http_key_fetcher.cc.

@@ -284,93 +282,7 @@ KeyFetcher implementation overrides.
Returns
OK on success.
-

Definition at line 154 of file http_key_fetcher.cc.

- - - - -

◆ SetCaFile()

- -
-
- - - - - -
- - - - - - - - -
void shaka::media::HttpKeyFetcher::SetCaFile (const std::string & ca_file)
-
-inline
-
-

Sets the Certifiate Authority file information for http requests.

Parameters
- - -
ca_fileabsolute path to the client certificate
-
-
- -

Definition at line 70 of file http_key_fetcher.h.

- -
-
- -

◆ SetClientCertInfo()

- -
-
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
void shaka::media::HttpKeyFetcher::SetClientCertInfo (const std::string & cert_file,
const std::string & private_key_file,
const std::string & private_key_password 
)
-
-inline
-
-

Sets client certificate information for http requests.

Parameters
- - - - -
cert_fileabsolute path to the client certificate.
private_key_fileabsolute path to the client certificate private key file.
private_key_passwordprivate key password.
-
-
- -

Definition at line 61 of file http_key_fetcher.h.

+

Definition at line 42 of file http_key_fetcher.cc.

@@ -381,9 +293,7 @@ KeyFetcher implementation overrides. diff --git a/docs/d7/de0/structshaka_1_1media_1_1mp4_1_1SampleToGroupEntry.html b/docs/d7/de0/structshaka_1_1media_1_1mp4_1_1SampleToGroupEntry.html index 75d910048e..85b328130d 100644 --- a/docs/d7/de0/structshaka_1_1media_1_1mp4_1_1SampleToGroupEntry.html +++ b/docs/d7/de0/structshaka_1_1media_1_1mp4_1_1SampleToGroupEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleToGroupEntry Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Public Types

-enum  GroupDescriptionIndexBase { kTrackGroupDescriptionIndexBase = 0, -kTrackFragmentGroupDescriptionIndexBase = 0x10000 +enum  GroupDescriptionIndexBase { kTrackGroupDescriptionIndexBase = 0 +, kTrackFragmentGroupDescriptionIndexBase = 0x10000 }   @@ -89,16 +92,14 @@ uint32_t 
group_description

Detailed Description

-

Definition at line 533 of file box_definitions.h.

+

Definition at line 546 of file box_definitions.h.


The documentation for this struct was generated from the following file:
diff --git a/docs/d7/dec/h264__byte__to__unit__stream__converter_8h_source.html b/docs/d7/dec/h264__byte__to__unit__stream__converter_8h_source.html index 015fffe350..f760b0934d 100644 --- a/docs/d7/dec/h264__byte__to__unit__stream__converter_8h_source.html +++ b/docs/d7/dec/h264__byte__to__unit__stream__converter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h264_byte_to_unit_stream_converter.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
h264_byte_to_unit_stream_converter.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CODECS_H264_BYTE_TO_UNIT_STREAM_CONVERTER_H_
8 #define PACKAGER_MEDIA_CODECS_H264_BYTE_TO_UNIT_STREAM_CONVERTER_H_
9 
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <vector>
14 
15 #include "packager/media/codecs/h26x_byte_to_unit_stream_converter.h"
16 
17 namespace shaka {
18 namespace media {
19 
23  public:
27 
30  explicit H264ByteToUnitStreamConverter(H26xStreamFormat stream_format);
31 
33 
37  std::vector<uint8_t>* decoder_config) const override;
39 
40  private:
41  bool ProcessNalu(const Nalu& nalu) override;
42 
43  std::vector<uint8_t> last_sps_;
44  std::vector<uint8_t> last_pps_;
45 
46  DISALLOW_COPY_AND_ASSIGN(H264ByteToUnitStreamConverter);
47 };
48 
49 } // namespace media
50 } // namespace shaka
51 
52 #endif // PACKAGER_MEDIA_CODECS_H264_BYTE_TO_UNIT_STREAM_CONVERTER_H_
- -
All the methods that are virtual are virtual for mocking.
-
bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const override
-
A base class that is used to convert H.26x byte streams to NAL unit streams.
- +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_H264_BYTE_TO_UNIT_STREAM_CONVERTER_H_
+
8 #define PACKAGER_MEDIA_CODECS_H264_BYTE_TO_UNIT_STREAM_CONVERTER_H_
+
9 
+
10 #include <stddef.h>
+
11 #include <stdint.h>
+
12 
+
13 #include <vector>
+
14 
+
15 #include "packager/media/codecs/h26x_byte_to_unit_stream_converter.h"
+
16 
+
17 namespace shaka {
+
18 namespace media {
+
19 
+ +
23  public:
+ +
27 
+
30  explicit H264ByteToUnitStreamConverter(H26xStreamFormat stream_format);
+
31 
+ +
33 
+ +
37  std::vector<uint8_t>* decoder_config) const override;
+
39 
+
40  private:
+
41  bool ProcessNalu(const Nalu& nalu) override;
+
42 
+
43  std::vector<uint8_t> last_sps_;
+
44  std::vector<uint8_t> last_pps_;
+
45  std::vector<uint8_t> last_sps_ext_;
+
46 
+
47  DISALLOW_COPY_AND_ASSIGN(H264ByteToUnitStreamConverter);
+
48 };
+
49 
+
50 } // namespace media
+
51 } // namespace shaka
+
52 
+
53 #endif // PACKAGER_MEDIA_CODECS_H264_BYTE_TO_UNIT_STREAM_CONVERTER_H_
+ + +
bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const override
+
A base class that is used to convert H.26x byte streams to NAL unit streams.
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/dee/mpd__generator_8cc_source.html b/docs/d7/dee/mpd__generator_8cc_source.html index 6f77d55452..c3fdc07ad9 100644 --- a/docs/d7/dee/mpd__generator_8cc_source.html +++ b/docs/d7/dee/mpd__generator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/mpd_generator.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mpd_generator.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include <iostream>
8 
9 #include "packager/app/mpd_generator_flags.h"
10 #include "packager/app/vlog_flags.h"
11 #include "packager/base/at_exit.h"
12 #include "packager/base/command_line.h"
13 #include "packager/base/logging.h"
14 #include "packager/base/strings/string_split.h"
15 #include "packager/base/strings/stringprintf.h"
16 #include "packager/mpd/util/mpd_writer.h"
17 #include "packager/tools/license_notice.h"
18 #include "packager/version/version.h"
19 
20 #if defined(OS_WIN)
21 #include <codecvt>
22 #include <functional>
23 #include <locale>
24 #endif // defined(OS_WIN)
25 
26 DEFINE_bool(licenses, false, "Dump licenses.");
27 DEFINE_string(test_packager_version,
28  "",
29  "Packager version for testing. Should be used for testing only.");
30 
31 namespace shaka {
32 namespace {
33 const char kUsage[] =
34  "MPD generation driver program.\n"
35  "This program accepts MediaInfo files in human readable text "
36  "format and outputs an MPD.\n"
37  "The main use case for this is to output MPD for VOD.\n"
38  "Limitations:\n"
39  " Each MediaInfo can only have one of VideoInfo, AudioInfo, or TextInfo.\n"
40  " There will be at most 3 AdaptationSets in the MPD, i.e. 1 video, 1 "
41  "audio, and 1 text.\n"
42  "Sample Usage:\n"
43  "%s --input=\"video1.media_info,video2.media_info,audio1.media_info\" "
44  "--output=\"video_audio.mpd\"";
45 
46 enum ExitStatus {
47  kSuccess = 0,
48  kEmptyInputError,
49  kEmptyOutputError,
50  kFailedToWriteMpdToFileError
51 };
52 
53 ExitStatus CheckRequiredFlags() {
54  if (FLAGS_input.empty()) {
55  LOG(ERROR) << "--input is required.";
56  return kEmptyInputError;
57  }
58 
59  if (FLAGS_output.empty()) {
60  LOG(ERROR) << "--output is required.";
61  return kEmptyOutputError;
62  }
63 
64  return kSuccess;
65 }
66 
67 ExitStatus RunMpdGenerator() {
68  DCHECK_EQ(CheckRequiredFlags(), kSuccess);
69  std::vector<std::string> base_urls;
70  typedef std::vector<std::string>::const_iterator Iterator;
71 
72  std::vector<std::string> input_files = base::SplitString(
73  FLAGS_input, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
74 
75  if (!FLAGS_base_urls.empty()) {
76  base_urls = base::SplitString(FLAGS_base_urls, ",", base::KEEP_WHITESPACE,
77  base::SPLIT_WANT_ALL);
78  }
79 
80  MpdWriter mpd_writer;
81  for (Iterator it = base_urls.begin(); it != base_urls.end(); ++it)
82  mpd_writer.AddBaseUrl(*it);
83 
84  for (const std::string& file : input_files) {
85  if (!mpd_writer.AddFile(file)) {
86  LOG(WARNING) << "MpdWriter failed to read " << file << ", skipping.";
87  }
88  }
89 
90  if (!mpd_writer.WriteMpdToFile(FLAGS_output.c_str())) {
91  LOG(ERROR) << "Failed to write MPD to " << FLAGS_output;
92  return kFailedToWriteMpdToFileError;
93  }
94 
95  return kSuccess;
96 }
97 
98 int MpdMain(int argc, char** argv) {
99  base::AtExitManager exit;
100  // Needed to enable VLOG/DVLOG through --vmodule or --v.
101  base::CommandLine::Init(argc, argv);
102 
103  // Set up logging.
104  logging::LoggingSettings log_settings;
105  log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
106  CHECK(logging::InitLogging(log_settings));
107 
108  google::SetVersionString(GetPackagerVersion());
109  google::SetUsageMessage(base::StringPrintf(kUsage, argv[0]));
110  google::ParseCommandLineFlags(&argc, &argv, true);
111  if (FLAGS_licenses) {
112  for (const char* line : kLicenseNotice)
113  std::cout << line << std::endl;
114  return kSuccess;
115  }
116 
117  ExitStatus status = CheckRequiredFlags();
118  if (status != kSuccess) {
119  google::ShowUsageWithFlags("Usage");
120  return status;
121  }
122 
123  if (!FLAGS_test_packager_version.empty())
124  SetPackagerVersionForTesting(FLAGS_test_packager_version);
125 
126  return RunMpdGenerator();
127 }
128 
129 } // namespace
130 } // namespace shaka
131 
132 #if defined(OS_WIN)
133 // Windows wmain, which converts wide character arguments to UTF-8.
134 int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) {
135  std::unique_ptr<char* [], std::function<void(char**)>> utf8_argv(
136  new char*[argc], [argc](char** utf8_args) {
137  // TODO(tinskip): This leaks, but if this code is enabled, it crashes.
138  // Figure out why. I suspect gflags does something funny with the
139  // argument array.
140  // for (int idx = 0; idx < argc; ++idx)
141  // delete[] utf8_args[idx];
142  delete[] utf8_args;
143  });
144  std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
145  for (int idx = 0; idx < argc; ++idx) {
146  std::string utf8_arg(converter.to_bytes(argv[idx]));
147  utf8_arg += '\0';
148  utf8_argv[idx] = new char[utf8_arg.size()];
149  memcpy(utf8_argv[idx], &utf8_arg[0], utf8_arg.size());
150  }
151  return shaka::MpdMain(argc, utf8_argv.get());
152 }
153 #else
154 int main(int argc, char** argv) {
155  return shaka::MpdMain(argc, argv);
156 }
157 #endif // !defined(OS_WIN)
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include <iostream>
+
8 
+
9 #include "packager/app/mpd_generator_flags.h"
+
10 #include "packager/app/vlog_flags.h"
+
11 #include "packager/base/at_exit.h"
+
12 #include "packager/base/command_line.h"
+
13 #include "packager/base/logging.h"
+
14 #include "packager/base/strings/string_split.h"
+
15 #include "packager/base/strings/stringprintf.h"
+
16 #include "packager/mpd/util/mpd_writer.h"
+
17 #include "packager/tools/license_notice.h"
+
18 #include "packager/version/version.h"
+
19 
+
20 #if defined(OS_WIN)
+
21 #include <codecvt>
+
22 #include <functional>
+
23 #include <locale>
+
24 #endif // defined(OS_WIN)
+
25 
+
26 DEFINE_bool(licenses, false, "Dump licenses.");
+
27 DEFINE_string(test_packager_version,
+
28  "",
+
29  "Packager version for testing. Should be used for testing only.");
+
30 
+
31 namespace shaka {
+
32 namespace {
+
33 const char kUsage[] =
+
34  "MPD generation driver program.\n"
+
35  "This program accepts MediaInfo files in human readable text "
+
36  "format and outputs an MPD.\n"
+
37  "The main use case for this is to output MPD for VOD.\n"
+
38  "Limitations:\n"
+
39  " Each MediaInfo can only have one of VideoInfo, AudioInfo, or TextInfo.\n"
+
40  " There will be at most 3 AdaptationSets in the MPD, i.e. 1 video, 1 "
+
41  "audio, and 1 text.\n"
+
42  "Sample Usage:\n"
+
43  "%s --input=\"video1.media_info,video2.media_info,audio1.media_info\" "
+
44  "--output=\"video_audio.mpd\"";
+
45 
+
46 enum ExitStatus {
+
47  kSuccess = 0,
+
48  kEmptyInputError,
+
49  kEmptyOutputError,
+
50  kFailedToWriteMpdToFileError
+
51 };
+
52 
+
53 ExitStatus CheckRequiredFlags() {
+
54  if (FLAGS_input.empty()) {
+
55  LOG(ERROR) << "--input is required.";
+
56  return kEmptyInputError;
+
57  }
+
58 
+
59  if (FLAGS_output.empty()) {
+
60  LOG(ERROR) << "--output is required.";
+
61  return kEmptyOutputError;
+
62  }
+
63 
+
64  return kSuccess;
+
65 }
+
66 
+
67 ExitStatus RunMpdGenerator() {
+
68  DCHECK_EQ(CheckRequiredFlags(), kSuccess);
+
69  std::vector<std::string> base_urls;
+
70  typedef std::vector<std::string>::const_iterator Iterator;
+
71 
+
72  std::vector<std::string> input_files = base::SplitString(
+
73  FLAGS_input, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+
74 
+
75  if (!FLAGS_base_urls.empty()) {
+
76  base_urls = base::SplitString(FLAGS_base_urls, ",", base::KEEP_WHITESPACE,
+
77  base::SPLIT_WANT_ALL);
+
78  }
+
79 
+
80  MpdWriter mpd_writer;
+
81  for (Iterator it = base_urls.begin(); it != base_urls.end(); ++it)
+
82  mpd_writer.AddBaseUrl(*it);
+
83 
+
84  for (const std::string& file : input_files) {
+
85  if (!mpd_writer.AddFile(file)) {
+
86  LOG(WARNING) << "MpdWriter failed to read " << file << ", skipping.";
+
87  }
+
88  }
+
89 
+
90  if (!mpd_writer.WriteMpdToFile(FLAGS_output.c_str())) {
+
91  LOG(ERROR) << "Failed to write MPD to " << FLAGS_output;
+
92  return kFailedToWriteMpdToFileError;
+
93  }
+
94 
+
95  return kSuccess;
+
96 }
+
97 
+
98 int MpdMain(int argc, char** argv) {
+
99  base::AtExitManager exit;
+
100  // Needed to enable VLOG/DVLOG through --vmodule or --v.
+
101  base::CommandLine::Init(argc, argv);
+
102 
+
103  // Set up logging.
+
104  logging::LoggingSettings log_settings;
+
105  log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+
106  CHECK(logging::InitLogging(log_settings));
+
107 
+
108  google::SetVersionString(GetPackagerVersion());
+
109  google::SetUsageMessage(base::StringPrintf(kUsage, argv[0]));
+
110  google::ParseCommandLineFlags(&argc, &argv, true);
+
111  if (FLAGS_licenses) {
+
112  for (const char* line : kLicenseNotice)
+
113  std::cout << line << std::endl;
+
114  return kSuccess;
+
115  }
+
116 
+
117  ExitStatus status = CheckRequiredFlags();
+
118  if (status != kSuccess) {
+
119  google::ShowUsageWithFlags("Usage");
+
120  return status;
+
121  }
+
122 
+
123  if (!FLAGS_test_packager_version.empty())
+
124  SetPackagerVersionForTesting(FLAGS_test_packager_version);
+
125 
+
126  return RunMpdGenerator();
+
127 }
+
128 
+
129 } // namespace
+
130 } // namespace shaka
+
131 
+
132 #if defined(OS_WIN)
+
133 // Windows wmain, which converts wide character arguments to UTF-8.
+
134 int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) {
+
135  std::unique_ptr<char* [], std::function<void(char**)>> utf8_argv(
+
136  new char*[argc], [argc](char** utf8_args) {
+
137  // TODO(tinskip): This leaks, but if this code is enabled, it crashes.
+
138  // Figure out why. I suspect gflags does something funny with the
+
139  // argument array.
+
140  // for (int idx = 0; idx < argc; ++idx)
+
141  // delete[] utf8_args[idx];
+
142  delete[] utf8_args;
+
143  });
+
144  std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
+
145  for (int idx = 0; idx < argc; ++idx) {
+
146  std::string utf8_arg(converter.to_bytes(argv[idx]));
+
147  utf8_arg += '\0';
+
148  utf8_argv[idx] = new char[utf8_arg.size()];
+
149  memcpy(utf8_argv[idx], &utf8_arg[0], utf8_arg.size());
+
150  }
+
151  return shaka::MpdMain(argc, utf8_argv.get());
+
152 }
+
153 #else
+
154 int main(int argc, char** argv) {
+
155  return shaka::MpdMain(argc, argv);
+
156 }
+
157 #endif // !defined(OS_WIN)
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/def/mp4__media__parser_8cc_source.html b/docs/d7/def/mp4__media__parser_8cc_source.html index e288e42710..6b2103487f 100644 --- a/docs/d7/def/mp4__media__parser_8cc_source.html +++ b/docs/d7/def/mp4__media__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/mp4_media_parser.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mp4_media_parser.cc
-
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/mp4/mp4_media_parser.h"
6 
7 #include <algorithm>
8 
9 #include "packager/base/callback.h"
10 #include "packager/base/callback_helpers.h"
11 #include "packager/base/logging.h"
12 #include "packager/base/strings/string_number_conversions.h"
13 #include "packager/file/file.h"
14 #include "packager/file/file_closer.h"
15 #include "packager/media/base/audio_stream_info.h"
16 #include "packager/media/base/buffer_reader.h"
17 #include "packager/media/base/decrypt_config.h"
18 #include "packager/media/base/key_source.h"
19 #include "packager/media/base/macros.h"
20 #include "packager/media/base/media_sample.h"
21 #include "packager/media/base/rcheck.h"
22 #include "packager/media/base/video_stream_info.h"
23 #include "packager/media/base/video_util.h"
24 #include "packager/media/codecs/ac3_audio_util.h"
25 #include "packager/media/codecs/av1_codec_configuration_record.h"
26 #include "packager/media/codecs/avc_decoder_configuration_record.h"
27 #include "packager/media/codecs/dovi_decoder_configuration_record.h"
28 #include "packager/media/codecs/ec3_audio_util.h"
29 #include "packager/media/codecs/es_descriptor.h"
30 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
31 #include "packager/media/codecs/vp_codec_configuration_record.h"
32 #include "packager/media/formats/mp4/box_definitions.h"
33 #include "packager/media/formats/mp4/box_reader.h"
34 #include "packager/media/formats/mp4/track_run_iterator.h"
35 
36 namespace shaka {
37 namespace media {
38 namespace mp4 {
39 namespace {
40 
41 uint64_t Rescale(uint64_t time_in_old_scale,
42  uint32_t old_scale,
43  uint32_t new_scale) {
44  return (static_cast<double>(time_in_old_scale) / old_scale) * new_scale;
45 }
46 
47 H26xStreamFormat GetH26xStreamFormat(FourCC fourcc) {
48  switch (fourcc) {
49  case FOURCC_avc1:
50  case FOURCC_dvh1:
51  case FOURCC_hvc1:
52  return H26xStreamFormat::kNalUnitStreamWithoutParameterSetNalus;
53  case FOURCC_avc3:
54  case FOURCC_dvhe:
55  case FOURCC_hev1:
56  return H26xStreamFormat::kNalUnitStreamWithParameterSetNalus;
57  default:
58  return H26xStreamFormat::kUnSpecified;
59  }
60 }
61 
62 Codec FourCCToCodec(FourCC fourcc) {
63  switch (fourcc) {
64  case FOURCC_av01:
65  return kCodecAV1;
66  case FOURCC_avc1:
67  case FOURCC_avc3:
68  return kCodecH264;
69  case FOURCC_dvh1:
70  case FOURCC_dvhe:
71  return kCodecH265DolbyVision;
72  case FOURCC_hev1:
73  case FOURCC_hvc1:
74  return kCodecH265;
75  case FOURCC_vp08:
76  return kCodecVP8;
77  case FOURCC_vp09:
78  return kCodecVP9;
79  case FOURCC_Opus:
80  return kCodecOpus;
81  case FOURCC_dtsc:
82  return kCodecDTSC;
83  case FOURCC_dtsh:
84  return kCodecDTSH;
85  case FOURCC_dtsl:
86  return kCodecDTSL;
87  case FOURCC_dtse:
88  return kCodecDTSE;
89  case FOURCC_dtsp:
90  return kCodecDTSP;
91  case FOURCC_dtsm:
92  return kCodecDTSM;
93  case FOURCC_ac_3:
94  return kCodecAC3;
95  case FOURCC_ec_3:
96  return kCodecEAC3;
97  case FOURCC_fLaC:
98  return kCodecFlac;
99  default:
100  return kUnknownCodec;
101  }
102 }
103 
104 Codec ObjectTypeToCodec(ObjectType object_type) {
105  switch (object_type) {
106  case ObjectType::kISO_14496_3:
107  case ObjectType::kISO_13818_7_AAC_LC:
108  return kCodecAAC;
109  case ObjectType::kDTSC:
110  return kCodecDTSC;
111  case ObjectType::kDTSE:
112  return kCodecDTSE;
113  case ObjectType::kDTSH:
114  return kCodecDTSH;
115  case ObjectType::kDTSL:
116  return kCodecDTSL;
117  default:
118  return kUnknownCodec;
119  }
120 }
121 
122 std::vector<uint8_t> GetDOVIDecoderConfig(
123  const std::vector<CodecConfiguration>& configs) {
124  for (const CodecConfiguration& config : configs) {
125  if (config.box_type == FOURCC_dvcC || config.box_type == FOURCC_dvvC) {
126  return config.data;
127  }
128  }
129  return std::vector<uint8_t>();
130 }
131 
132 bool UpdateCodecStringForDolbyVision(
133  FourCC actual_format,
134  const std::vector<CodecConfiguration>& configs,
135  std::string* codec_string) {
136  DOVIDecoderConfigurationRecord dovi_config;
137  if (!dovi_config.Parse(GetDOVIDecoderConfig(configs))) {
138  LOG(ERROR) << "Failed to parse Dolby Vision decoder "
139  "configuration record.";
140  return false;
141  }
142  if (actual_format == FOURCC_dvh1 || actual_format == FOURCC_dvhe) {
143  // Non-Backward compatibility mode. Replace the code string with
144  // Dolby Vision only.
145  *codec_string = dovi_config.GetCodecString(actual_format);
146  } else {
147  // TODO(kqyang): Support backward compatible signaling.
148  }
149  return true;
150 }
151 
152 const uint64_t kNanosecondsPerSecond = 1000000000ull;
153 
154 } // namespace
155 
156 MP4MediaParser::MP4MediaParser()
157  : state_(kWaitingForInit),
158  decryption_key_source_(NULL),
159  moof_head_(0),
160  mdat_tail_(0) {}
161 
162 MP4MediaParser::~MP4MediaParser() {}
163 
164 void MP4MediaParser::Init(const InitCB& init_cb,
165  const NewSampleCB& new_sample_cb,
166  KeySource* decryption_key_source) {
167  DCHECK_EQ(state_, kWaitingForInit);
168  DCHECK(init_cb_.is_null());
169  DCHECK(!init_cb.is_null());
170  DCHECK(!new_sample_cb.is_null());
171 
172  ChangeState(kParsingBoxes);
173  init_cb_ = init_cb;
174  new_sample_cb_ = new_sample_cb;
175  decryption_key_source_ = decryption_key_source;
176  if (decryption_key_source)
177  decryptor_source_.reset(new DecryptorSource(decryption_key_source));
178 }
179 
180 void MP4MediaParser::Reset() {
181  queue_.Reset();
182  runs_.reset();
183  moof_head_ = 0;
184  mdat_tail_ = 0;
185 }
186 
188  DCHECK_NE(state_, kWaitingForInit);
189  Reset();
190  ChangeState(kParsingBoxes);
191  return true;
192 }
193 
194 bool MP4MediaParser::Parse(const uint8_t* buf, int size) {
195  DCHECK_NE(state_, kWaitingForInit);
196 
197  if (state_ == kError)
198  return false;
199 
200  queue_.Push(buf, size);
201 
202  bool result, err = false;
203 
204  do {
205  if (state_ == kParsingBoxes) {
206  result = ParseBox(&err);
207  } else {
208  DCHECK_EQ(kEmittingSamples, state_);
209  result = EnqueueSample(&err);
210  if (result) {
211  int64_t max_clear = runs_->GetMaxClearOffset() + moof_head_;
212  err = !ReadAndDiscardMDATsUntil(max_clear);
213  }
214  }
215  } while (result && !err);
216 
217  if (err) {
218  DLOG(ERROR) << "Error while parsing MP4";
219  moov_.reset();
220  Reset();
221  ChangeState(kError);
222  return false;
223  }
224 
225  return true;
226 }
227 
228 bool MP4MediaParser::LoadMoov(const std::string& file_path) {
229  std::unique_ptr<File, FileCloser> file(
230  File::OpenWithNoBuffering(file_path.c_str(), "r"));
231  if (!file) {
232  LOG(ERROR) << "Unable to open media file '" << file_path << "'";
233  return false;
234  }
235  if (!file->Seek(0)) {
236  LOG(WARNING) << "Filesystem does not support seeking on file '" << file_path
237  << "'";
238  return false;
239  }
240 
241  uint64_t file_position(0);
242  bool mdat_seen(false);
243  while (true) {
244  const uint32_t kBoxHeaderReadSize(16);
245  std::vector<uint8_t> buffer(kBoxHeaderReadSize);
246  int64_t bytes_read = file->Read(&buffer[0], kBoxHeaderReadSize);
247  if (bytes_read == 0) {
248  LOG(ERROR) << "Could not find 'moov' box in file '" << file_path << "'";
249  return false;
250  }
251  if (bytes_read < kBoxHeaderReadSize) {
252  LOG(ERROR) << "Error reading media file '" << file_path << "'";
253  return false;
254  }
255  uint64_t box_size;
256  FourCC box_type;
257  bool err;
258  if (!BoxReader::StartBox(&buffer[0], kBoxHeaderReadSize, &box_type,
259  &box_size, &err)) {
260  LOG(ERROR) << "Could not start box from file '" << file_path << "'";
261  return false;
262  }
263  if (box_type == FOURCC_mdat) {
264  mdat_seen = true;
265  } else if (box_type == FOURCC_moov) {
266  if (!mdat_seen) {
267  // 'moov' is before 'mdat'. Nothing to do.
268  break;
269  }
270  // 'mdat' before 'moov'. Read and parse 'moov'.
271  if (!Parse(&buffer[0], bytes_read)) {
272  LOG(ERROR) << "Error parsing mp4 file '" << file_path << "'";
273  return false;
274  }
275  uint64_t bytes_to_read = box_size - bytes_read;
276  buffer.resize(bytes_to_read);
277  while (bytes_to_read > 0) {
278  bytes_read = file->Read(&buffer[0], bytes_to_read);
279  if (bytes_read <= 0) {
280  LOG(ERROR) << "Error reading 'moov' contents from file '" << file_path
281  << "'";
282  return false;
283  }
284  if (!Parse(&buffer[0], bytes_read)) {
285  LOG(ERROR) << "Error parsing mp4 file '" << file_path << "'";
286  return false;
287  }
288  bytes_to_read -= bytes_read;
289  }
290  queue_.Reset(); // So that we don't need to adjust data offsets.
291  mdat_tail_ = 0; // So it will skip boxes until mdat.
292  break; // Done.
293  }
294  file_position += box_size;
295  if (!file->Seek(file_position)) {
296  LOG(ERROR) << "Error skipping box in mp4 file '" << file_path << "'";
297  return false;
298  }
299  }
300  return true;
301 }
302 
303 bool MP4MediaParser::ParseBox(bool* err) {
304  const uint8_t* buf;
305  int size;
306  queue_.Peek(&buf, &size);
307  if (!size)
308  return false;
309 
310  std::unique_ptr<BoxReader> reader(BoxReader::ReadBox(buf, size, err));
311  if (reader.get() == NULL)
312  return false;
313 
314  if (reader->type() == FOURCC_mdat) {
315  if (!moov_) {
316  // For seekable files, we seek to the 'moov' and load the 'moov' first
317  // then seek back (see LoadMoov function for details); we do not support
318  // having 'mdat' before 'moov' for non-seekable files. The code ends up
319  // here only if it is a non-seekable file.
320  NOTIMPLEMENTED() << " Non-seekable Files with 'mdat' box before 'moov' "
321  "box is not supported.";
322  *err = true;
323  return false;
324  } else {
325  // This can happen if there are unused 'mdat' boxes, which is unusual
326  // but allowed by the spec. Ignore the 'mdat' and proceed.
327  LOG(INFO)
328  << "Ignore unused 'mdat' box - this could be as a result of extra "
329  "not usable 'mdat' or 'mdat' associated with unrecognized track.";
330  }
331  }
332 
333  // Set up mdat offset for ReadMDATsUntil().
334  mdat_tail_ = queue_.head() + reader->size();
335 
336  if (reader->type() == FOURCC_moov) {
337  *err = !ParseMoov(reader.get());
338  } else if (reader->type() == FOURCC_moof) {
339  moof_head_ = queue_.head();
340  *err = !ParseMoof(reader.get());
341 
342  // Return early to avoid evicting 'moof' data from queue. Auxiliary info may
343  // be located anywhere in the file, including inside the 'moof' itself.
344  // (Since 'default-base-is-moof' is mandated, no data references can come
345  // before the head of the 'moof', so keeping this box around is sufficient.)
346  return !(*err);
347  } else {
348  VLOG(2) << "Skipping top-level box: " << FourCCToString(reader->type());
349  }
350 
351  queue_.Pop(static_cast<int>(reader->size()));
352  return !(*err);
353 }
354 
355 bool MP4MediaParser::ParseMoov(BoxReader* reader) {
356  if (moov_)
357  return true; // Already parsed the 'moov' box.
358 
359  moov_.reset(new Movie);
360  RCHECK(moov_->Parse(reader));
361  runs_.reset();
362 
363  std::vector<std::shared_ptr<StreamInfo>> streams;
364 
365  for (std::vector<Track>::const_iterator track = moov_->tracks.begin();
366  track != moov_->tracks.end(); ++track) {
367  const uint32_t timescale = track->media.header.timescale;
368 
369  // Calculate duration (based on timescale).
370  uint64_t duration = 0;
371  if (track->media.header.duration > 0) {
372  duration = track->media.header.duration;
373  } else if (moov_->extends.header.fragment_duration > 0) {
374  DCHECK(moov_->header.timescale != 0);
375  duration = Rescale(moov_->extends.header.fragment_duration,
376  moov_->header.timescale,
377  timescale);
378  } else if (moov_->header.duration > 0 &&
379  moov_->header.duration != std::numeric_limits<uint64_t>::max()) {
380  DCHECK(moov_->header.timescale != 0);
381  duration =
382  Rescale(moov_->header.duration, moov_->header.timescale, timescale);
383  }
384 
385  const SampleDescription& samp_descr =
386  track->media.information.sample_table.description;
387 
388  size_t desc_idx = 0;
389 
390  // Read sample description index from mvex if it exists otherwise read
391  // from the first entry in Sample To Chunk box.
392  if (moov_->extends.tracks.size() > 0) {
393  for (size_t t = 0; t < moov_->extends.tracks.size(); t++) {
394  const TrackExtends& trex = moov_->extends.tracks[t];
395  if (trex.track_id == track->header.track_id) {
396  desc_idx = trex.default_sample_description_index;
397  break;
398  }
399  }
400  } else {
401  const std::vector<ChunkInfo>& chunk_info =
402  track->media.information.sample_table.sample_to_chunk.chunk_info;
403  RCHECK(chunk_info.size() > 0);
404  desc_idx = chunk_info[0].sample_description_index;
405  }
406  RCHECK(desc_idx > 0);
407  desc_idx -= 1; // BMFF descriptor index is one-based
408 
409  if (samp_descr.type == kAudio) {
410  RCHECK(!samp_descr.audio_entries.empty());
411 
412  // It is not uncommon to find otherwise-valid files with incorrect sample
413  // description indices, so we fail gracefully in that case.
414  if (desc_idx >= samp_descr.audio_entries.size())
415  desc_idx = 0;
416 
417  const AudioSampleEntry& entry = samp_descr.audio_entries[desc_idx];
418  const FourCC actual_format = entry.GetActualFormat();
419  Codec codec = FourCCToCodec(actual_format);
420  uint8_t num_channels = entry.channelcount;
421  uint32_t sampling_frequency = entry.samplerate;
422  uint64_t codec_delay_ns = 0;
423  uint8_t audio_object_type = 0;
424  uint32_t max_bitrate = 0;
425  uint32_t avg_bitrate = 0;
426  std::vector<uint8_t> codec_config;
427 
428  switch (actual_format) {
429  case FOURCC_mp4a: {
430  const DecoderConfigDescriptor& decoder_config =
431  entry.esds.es_descriptor.decoder_config_descriptor();
432  max_bitrate = decoder_config.max_bitrate();
433  avg_bitrate = decoder_config.avg_bitrate();
434 
435  codec = ObjectTypeToCodec(decoder_config.object_type());
436  if (codec == kCodecAAC) {
437  const AACAudioSpecificConfig& aac_audio_specific_config =
438  entry.esds.aac_audio_specific_config;
439  num_channels = aac_audio_specific_config.GetNumChannels();
440  sampling_frequency =
441  aac_audio_specific_config.GetSamplesPerSecond();
442  audio_object_type = aac_audio_specific_config.GetAudioObjectType();
443  codec_config =
444  decoder_config.decoder_specific_info_descriptor().data();
445  } else if (codec == kUnknownCodec) {
446  // Intentionally not to fail in the parser as there may be multiple
447  // streams in the source content, which allows the supported stream
448  // to be packaged. An error will be returned if the unsupported
449  // stream is passed to the muxer.
450  LOG(WARNING) << "Unsupported audio object type "
451  << static_cast<int>(decoder_config.object_type())
452  << " in stsd.es_desriptor.";
453  }
454  break;
455  }
456  case FOURCC_dtsc:
457  FALLTHROUGH_INTENDED;
458  case FOURCC_dtse:
459  FALLTHROUGH_INTENDED;
460  case FOURCC_dtsh:
461  FALLTHROUGH_INTENDED;
462  case FOURCC_dtsl:
463  FALLTHROUGH_INTENDED;
464  case FOURCC_dtsm:
465  codec_config = entry.ddts.extra_data;
466  max_bitrate = entry.ddts.max_bitrate;
467  avg_bitrate = entry.ddts.avg_bitrate;
468  break;
469  case FOURCC_ac_3:
470  codec_config = entry.dac3.data;
471  num_channels = static_cast<uint8_t>(GetAc3NumChannels(codec_config));
472  break;
473  case FOURCC_ec_3:
474  codec_config = entry.dec3.data;
475  num_channels = static_cast<uint8_t>(GetEc3NumChannels(codec_config));
476  break;
477  case FOURCC_fLaC:
478  codec_config = entry.dfla.data;
479  break;
480  case FOURCC_Opus:
481  codec_config = entry.dops.opus_identification_header;
482  codec_delay_ns =
483  entry.dops.preskip * kNanosecondsPerSecond / sampling_frequency;
484  break;
485  default:
486  // Intentionally not to fail in the parser as there may be multiple
487  // streams in the source content, which allows the supported stream to
488  // be packaged.
489  // An error will be returned if the unsupported stream is passed to
490  // the muxer.
491  LOG(WARNING) << "Unsupported audio format '"
492  << FourCCToString(actual_format) << "' in stsd box.";
493  break;
494  }
495 
496  // Extract possible seek preroll.
497  uint64_t seek_preroll_ns = 0;
498  for (const auto& sample_group_description :
499  track->media.information.sample_table.sample_group_descriptions) {
500  if (sample_group_description.grouping_type != FOURCC_roll)
501  continue;
502  const auto& audio_roll_recovery_entries =
503  sample_group_description.audio_roll_recovery_entries;
504  if (audio_roll_recovery_entries.size() != 1) {
505  LOG(WARNING) << "Unexpected number of entries in "
506  "SampleGroupDescription table with grouping type "
507  "'roll'.";
508  break;
509  }
510  const int16_t roll_distance_in_samples =
511  audio_roll_recovery_entries[0].roll_distance;
512  if (roll_distance_in_samples < 0) {
513  RCHECK(sampling_frequency != 0);
514  seek_preroll_ns = kNanosecondsPerSecond *
515  (-roll_distance_in_samples) / sampling_frequency;
516  } else {
517  LOG(WARNING)
518  << "Roll distance is supposed to be negative, but seeing "
519  << roll_distance_in_samples;
520  }
521  break;
522  }
523 
524  // The stream will be decrypted if a |decryptor_source_| is available.
525  const bool is_encrypted =
526  decryptor_source_
527  ? false
528  : entry.sinf.info.track_encryption.default_is_protected == 1;
529  DVLOG(1) << "is_audio_track_encrypted_: " << is_encrypted;
530  streams.emplace_back(new AudioStreamInfo(
531  track->header.track_id, timescale, duration, codec,
532  AudioStreamInfo::GetCodecString(codec, audio_object_type),
533  codec_config.data(), codec_config.size(), entry.samplesize,
534  num_channels, sampling_frequency, seek_preroll_ns, codec_delay_ns,
535  max_bitrate, avg_bitrate, track->media.header.language.code,
536  is_encrypted));
537  }
538 
539  if (samp_descr.type == kVideo) {
540  RCHECK(!samp_descr.video_entries.empty());
541  if (desc_idx >= samp_descr.video_entries.size())
542  desc_idx = 0;
543  const VideoSampleEntry& entry = samp_descr.video_entries[desc_idx];
544  std::vector<uint8_t> codec_configuration_data =
545  entry.codec_configuration.data;
546 
547  uint32_t coded_width = entry.width;
548  uint32_t coded_height = entry.height;
549  uint32_t pixel_width = entry.pixel_aspect.h_spacing;
550  uint32_t pixel_height = entry.pixel_aspect.v_spacing;
551  if (pixel_width == 0 && pixel_height == 0) {
552  DerivePixelWidthHeight(coded_width, coded_height, track->header.width,
553  track->header.height, &pixel_width,
554  &pixel_height);
555  }
556  std::string codec_string;
557  uint8_t nalu_length_size = 0;
558  uint8_t transfer_characteristics = 0;
559 
560  const FourCC actual_format = entry.GetActualFormat();
561  const Codec video_codec = FourCCToCodec(actual_format);
562  switch (actual_format) {
563  case FOURCC_av01: {
564  AV1CodecConfigurationRecord av1_config;
565  if (!av1_config.Parse(codec_configuration_data)) {
566  LOG(ERROR) << "Failed to parse av1c.";
567  return false;
568  }
569  codec_string = av1_config.GetCodecString();
570  break;
571  }
572  case FOURCC_avc1:
573  case FOURCC_avc3: {
575  if (!avc_config.Parse(codec_configuration_data)) {
576  LOG(ERROR) << "Failed to parse avcc.";
577  return false;
578  }
579  codec_string = avc_config.GetCodecString(actual_format);
580  nalu_length_size = avc_config.nalu_length_size();
581  transfer_characteristics = avc_config.transfer_characteristics();
582 
583  // Use configurations from |avc_config| if it is valid.
584  if (avc_config.coded_width() != 0) {
585  DCHECK_NE(avc_config.coded_height(), 0u);
586  if (coded_width != avc_config.coded_width() ||
587  coded_height != avc_config.coded_height()) {
588  LOG(WARNING) << "Resolution in VisualSampleEntry (" << coded_width
589  << "," << coded_height
590  << ") does not match with resolution in "
591  "AVCDecoderConfigurationRecord ("
592  << avc_config.coded_width() << ","
593  << avc_config.coded_height()
594  << "). Use AVCDecoderConfigurationRecord.";
595  coded_width = avc_config.coded_width();
596  coded_height = avc_config.coded_height();
597  }
598 
599  DCHECK_NE(avc_config.pixel_width(), 0u);
600  DCHECK_NE(avc_config.pixel_height(), 0u);
601  if (pixel_width != avc_config.pixel_width() ||
602  pixel_height != avc_config.pixel_height()) {
603  LOG_IF(WARNING, pixel_width != 1 || pixel_height != 1)
604  << "Pixel aspect ratio in PASP box (" << pixel_width << ","
605  << pixel_height
606  << ") does not match with SAR in "
607  "AVCDecoderConfigurationRecord "
608  "("
609  << avc_config.pixel_width() << ","
610  << avc_config.pixel_height()
611  << "). Use AVCDecoderConfigurationRecord.";
612  pixel_width = avc_config.pixel_width();
613  pixel_height = avc_config.pixel_height();
614  }
615  }
616  break;
617  }
618  case FOURCC_dvh1:
619  case FOURCC_dvhe:
620  case FOURCC_hev1:
621  case FOURCC_hvc1: {
622  HEVCDecoderConfigurationRecord hevc_config;
623  if (!hevc_config.Parse(codec_configuration_data)) {
624  LOG(ERROR) << "Failed to parse hevc.";
625  return false;
626  }
627  codec_string = hevc_config.GetCodecString(actual_format);
628  nalu_length_size = hevc_config.nalu_length_size();
629  transfer_characteristics = hevc_config.transfer_characteristics();
630 
631  if (!entry.extra_codec_configs.empty()) {
632  if (!UpdateCodecStringForDolbyVision(
633  actual_format, entry.extra_codec_configs, &codec_string)) {
634  return false;
635  }
636  }
637  break;
638  }
639  case FOURCC_vp08:
640  case FOURCC_vp09: {
641  VPCodecConfigurationRecord vp_config;
642  if (!vp_config.ParseMP4(codec_configuration_data)) {
643  LOG(ERROR) << "Failed to parse vpcc.";
644  return false;
645  }
646  if (actual_format == FOURCC_vp09 &&
647  (!vp_config.is_level_set() || vp_config.level() == 0)) {
648  const double kUnknownSampleDuration = 0.0;
649  vp_config.SetVP9Level(coded_width, coded_height,
650  kUnknownSampleDuration);
651  vp_config.WriteMP4(&codec_configuration_data);
652  }
653  codec_string = vp_config.GetCodecString(video_codec);
654  break;
655  }
656  default:
657  // Intentionally not to fail in the parser as there may be multiple
658  // streams in the source content, which allows the supported stream to
659  // be packaged.
660  // An error will be returned if the unsupported stream is passed to
661  // the muxer.
662  LOG(WARNING) << "Unsupported video format '"
663  << FourCCToString(actual_format) << "' in stsd box.";
664  break;
665  }
666 
667  // The stream will be decrypted if a |decryptor_source_| is available.
668  const bool is_encrypted =
669  decryptor_source_
670  ? false
671  : entry.sinf.info.track_encryption.default_is_protected == 1;
672  DVLOG(1) << "is_video_track_encrypted_: " << is_encrypted;
673  std::shared_ptr<VideoStreamInfo> video_stream_info(new VideoStreamInfo(
674  track->header.track_id, timescale, duration, video_codec,
675  GetH26xStreamFormat(actual_format), codec_string,
676  codec_configuration_data.data(), codec_configuration_data.size(),
677  coded_width, coded_height, pixel_width, pixel_height,
678  transfer_characteristics,
679  0, // trick_play_factor
680  nalu_length_size, track->media.header.language.code, is_encrypted));
681  video_stream_info->set_extra_config(entry.ExtraCodecConfigsAsVector());
682 
683  // Set pssh raw data if it has.
684  if (moov_->pssh.size() > 0) {
685  std::vector<uint8_t> pssh_raw_data;
686  for (const auto& pssh : moov_->pssh) {
687  pssh_raw_data.insert(pssh_raw_data.end(), pssh.raw_box.begin(),
688  pssh.raw_box.end());
689  }
690  video_stream_info->set_eme_init_data(pssh_raw_data.data(),
691  pssh_raw_data.size());
692  }
693 
694  streams.push_back(video_stream_info);
695  }
696  }
697 
698  init_cb_.Run(streams);
699  if (!FetchKeysIfNecessary(moov_->pssh))
700  return false;
701  runs_.reset(new TrackRunIterator(moov_.get()));
702  RCHECK(runs_->Init());
703  ChangeState(kEmittingSamples);
704  return true;
705 }
706 
707 bool MP4MediaParser::ParseMoof(BoxReader* reader) {
708  // Must already have initialization segment.
709  RCHECK(moov_.get());
710  MovieFragment moof;
711  RCHECK(moof.Parse(reader));
712  if (!runs_)
713  runs_.reset(new TrackRunIterator(moov_.get()));
714  RCHECK(runs_->Init(moof));
715  if (!FetchKeysIfNecessary(moof.pssh))
716  return false;
717  ChangeState(kEmittingSamples);
718  return true;
719 }
720 
721 bool MP4MediaParser::FetchKeysIfNecessary(
722  const std::vector<ProtectionSystemSpecificHeader>& headers) {
723  if (headers.empty())
724  return true;
725 
726  // An error will be returned later if the samples need to be decrypted.
727  if (!decryption_key_source_)
728  return true;
729 
730  std::vector<uint8_t> pssh_raw_data;
731  for (const auto& header : headers) {
732  pssh_raw_data.insert(pssh_raw_data.end(), header.raw_box.begin(),
733  header.raw_box.end());
734  }
735  Status status =
736  decryption_key_source_->FetchKeys(EmeInitDataType::CENC, pssh_raw_data);
737  if (!status.ok()) {
738  LOG(ERROR) << "Error fetching decryption keys: " << status;
739  return false;
740  }
741  return true;
742 }
743 
744 bool MP4MediaParser::EnqueueSample(bool* err) {
745  if (!runs_->IsRunValid()) {
746  // Remain in kEnqueueingSamples state, discarding data, until the end of
747  // the current 'mdat' box has been appended to the queue.
748  if (!queue_.Trim(mdat_tail_))
749  return false;
750 
751  ChangeState(kParsingBoxes);
752  return true;
753  }
754 
755  if (!runs_->IsSampleValid()) {
756  runs_->AdvanceRun();
757  return true;
758  }
759 
760  DCHECK(!(*err));
761 
762  const uint8_t* buf;
763  int buf_size;
764  queue_.Peek(&buf, &buf_size);
765  if (!buf_size)
766  return false;
767 
768  // Skip this entire track if it is not audio nor video.
769  if (!runs_->is_audio() && !runs_->is_video())
770  runs_->AdvanceRun();
771 
772  // Attempt to cache the auxiliary information first. Aux info is usually
773  // placed in a contiguous block before the sample data, rather than being
774  // interleaved. If we didn't cache it, this would require that we retain the
775  // start of the segment buffer while reading samples. Aux info is typically
776  // quite small compared to sample data, so this pattern is useful on
777  // memory-constrained devices where the source buffer consumes a substantial
778  // portion of the total system memory.
779  if (runs_->AuxInfoNeedsToBeCached()) {
780  queue_.PeekAt(runs_->aux_info_offset() + moof_head_, &buf, &buf_size);
781  if (buf_size < runs_->aux_info_size())
782  return false;
783  *err = !runs_->CacheAuxInfo(buf, buf_size);
784  return !*err;
785  }
786 
787  int64_t sample_offset = runs_->sample_offset() + moof_head_;
788  queue_.PeekAt(sample_offset, &buf, &buf_size);
789  if (buf_size < runs_->sample_size()) {
790  if (sample_offset < queue_.head()) {
791  LOG(ERROR) << "Incorrect sample offset " << sample_offset
792  << " < " << queue_.head();
793  *err = true;
794  }
795  return false;
796  }
797 
798  const uint8_t* media_data = buf;
799  const size_t media_data_size = runs_->sample_size();
800  // Use a dummy data size of 0 to avoid copying overhead.
801  // Actual media data is set later.
802  const size_t kDummyDataSize = 0;
803  std::shared_ptr<MediaSample> stream_sample(
804  MediaSample::CopyFrom(media_data, kDummyDataSize, runs_->is_keyframe()));
805 
806  if (runs_->is_encrypted()) {
807  std::shared_ptr<uint8_t> decrypted_media_data(
808  new uint8_t[media_data_size], std::default_delete<uint8_t[]>());
809  std::unique_ptr<DecryptConfig> decrypt_config = runs_->GetDecryptConfig();
810  if (!decrypt_config) {
811  *err = true;
812  LOG(ERROR) << "Missing decrypt config.";
813  return false;
814  }
815 
816  if (!decryptor_source_) {
817  stream_sample->SetData(media_data, media_data_size);
818  // If the demuxer does not have the decryptor_source_, store
819  // decrypt_config so that the demuxed sample can be decrypted later.
820  stream_sample->set_decrypt_config(std::move(decrypt_config));
821  stream_sample->set_is_encrypted(true);
822  } else {
823  if (!decryptor_source_->DecryptSampleBuffer(decrypt_config.get(),
824  media_data, media_data_size,
825  decrypted_media_data.get())) {
826  *err = true;
827  LOG(ERROR) << "Cannot decrypt samples.";
828  return false;
829  }
830  stream_sample->TransferData(std::move(decrypted_media_data),
831  media_data_size);
832  }
833  } else {
834  stream_sample->SetData(media_data, media_data_size);
835  }
836 
837  stream_sample->set_dts(runs_->dts());
838  stream_sample->set_pts(runs_->cts());
839  stream_sample->set_duration(runs_->duration());
840 
841  DVLOG(3) << "Pushing frame: "
842  << ", key=" << runs_->is_keyframe()
843  << ", dur=" << runs_->duration()
844  << ", dts=" << runs_->dts()
845  << ", cts=" << runs_->cts()
846  << ", size=" << runs_->sample_size();
847 
848  if (!new_sample_cb_.Run(runs_->track_id(), stream_sample)) {
849  *err = true;
850  LOG(ERROR) << "Failed to process the sample.";
851  return false;
852  }
853 
854  runs_->AdvanceSample();
855  return true;
856 }
857 
858 bool MP4MediaParser::ReadAndDiscardMDATsUntil(const int64_t offset) {
859  bool err = false;
860  while (mdat_tail_ < offset) {
861  const uint8_t* buf;
862  int size;
863  queue_.PeekAt(mdat_tail_, &buf, &size);
864 
865  FourCC type;
866  uint64_t box_sz;
867  if (!BoxReader::StartBox(buf, size, &type, &box_sz, &err))
868  break;
869 
870  mdat_tail_ += box_sz;
871  }
872  queue_.Trim(std::min(mdat_tail_, offset));
873  return !err;
874 }
875 
876 void MP4MediaParser::ChangeState(State new_state) {
877  DVLOG(2) << "Changing state: " << new_state;
878  state_ = new_state;
879 }
880 
881 } // namespace mp4
882 } // namespace media
883 } // namespace shaka
- -
Class for parsing or writing VP codec configuration record.
- - - -
bool Flush() override WARN_UNUSED_RESULT
- -
All the methods that are virtual are virtual for mocking.
- - - -
void SetVP9Level(uint16_t width, uint16_t height, double sample_duration_seconds)
Compute and set VP9 Level based on the input attributes.
-
bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
- - -
bool Parse(const std::vector< uint8_t > &data)
-
std::string GetCodecString(FourCC codec_fourcc) const
-
Class for reading MP4 boxes.
Definition: box_reader.h:25
-
bool Parse(const std::vector< uint8_t > &data)
-
void WriteMP4(std::vector< uint8_t > *data) const
- - - -
bool ParseMP4(const std::vector< uint8_t > &data)
-
Class for parsing AV1 codec configuration record.
-
Class for parsing HEVC decoder configuration record.
-
static File * OpenWithNoBuffering(const char *file_name, const char *mode)
Definition: file.cc:187
- -
static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
-
bool LoadMoov(const std::string &file_path)
-
Class for parsing AVC decoder configuration record.
-
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
Definition: media_sample.cc:42
-
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:48
- -
void Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
-
Holds video stream information.
-
Holds audio stream information.
-
DecryptorSource wraps KeySource and is responsible for decryptor management.
-
static bool StartBox(const uint8_t *buf, const size_t buf_size, FourCC *type, uint64_t *box_size, bool *err) WARN_UNUSED_RESULT
Definition: box_reader.cc:54
- - -
static BoxReader * ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)
Definition: box_reader.cc:36
+
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/mp4/mp4_media_parser.h"
+
6 
+
7 #include <algorithm>
+
8 
+
9 #include "packager/base/callback.h"
+
10 #include "packager/base/callback_helpers.h"
+
11 #include "packager/base/logging.h"
+
12 #include "packager/base/strings/string_number_conversions.h"
+
13 #include "packager/file/file.h"
+
14 #include "packager/file/file_closer.h"
+
15 #include "packager/media/base/audio_stream_info.h"
+
16 #include "packager/media/base/buffer_reader.h"
+
17 #include "packager/media/base/decrypt_config.h"
+
18 #include "packager/media/base/key_source.h"
+
19 #include "packager/media/base/macros.h"
+
20 #include "packager/media/base/media_sample.h"
+
21 #include "packager/media/base/rcheck.h"
+
22 #include "packager/media/base/video_stream_info.h"
+
23 #include "packager/media/base/video_util.h"
+
24 #include "packager/media/codecs/ac3_audio_util.h"
+
25 #include "packager/media/codecs/av1_codec_configuration_record.h"
+
26 #include "packager/media/codecs/avc_decoder_configuration_record.h"
+
27 #include "packager/media/codecs/dovi_decoder_configuration_record.h"
+
28 #include "packager/media/codecs/ec3_audio_util.h"
+
29 #include "packager/media/codecs/ac4_audio_util.h"
+
30 #include "packager/media/codecs/es_descriptor.h"
+
31 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
+
32 #include "packager/media/codecs/vp_codec_configuration_record.h"
+
33 #include "packager/media/formats/mp4/box_definitions.h"
+
34 #include "packager/media/formats/mp4/box_reader.h"
+
35 #include "packager/media/formats/mp4/track_run_iterator.h"
+
36 
+
37 namespace shaka {
+
38 namespace media {
+
39 namespace mp4 {
+
40 namespace {
+
41 
+
42 uint64_t Rescale(uint64_t time_in_old_scale,
+
43  uint32_t old_scale,
+
44  uint32_t new_scale) {
+
45  return (static_cast<double>(time_in_old_scale) / old_scale) * new_scale;
+
46 }
+
47 
+
48 H26xStreamFormat GetH26xStreamFormat(FourCC fourcc) {
+
49  switch (fourcc) {
+
50  case FOURCC_avc1:
+
51  case FOURCC_dvh1:
+
52  case FOURCC_hvc1:
+
53  return H26xStreamFormat::kNalUnitStreamWithoutParameterSetNalus;
+
54  case FOURCC_avc3:
+
55  case FOURCC_dvhe:
+
56  case FOURCC_hev1:
+
57  return H26xStreamFormat::kNalUnitStreamWithParameterSetNalus;
+
58  default:
+
59  return H26xStreamFormat::kUnSpecified;
+
60  }
+
61 }
+
62 
+
63 Codec FourCCToCodec(FourCC fourcc) {
+
64  switch (fourcc) {
+
65  case FOURCC_av01:
+
66  return kCodecAV1;
+
67  case FOURCC_avc1:
+
68  case FOURCC_avc3:
+
69  return kCodecH264;
+
70  case FOURCC_dvh1:
+
71  case FOURCC_dvhe:
+
72  return kCodecH265DolbyVision;
+
73  case FOURCC_hev1:
+
74  case FOURCC_hvc1:
+
75  return kCodecH265;
+
76  case FOURCC_vp08:
+
77  return kCodecVP8;
+
78  case FOURCC_vp09:
+
79  return kCodecVP9;
+
80  case FOURCC_Opus:
+
81  return kCodecOpus;
+
82  case FOURCC_dtsc:
+
83  return kCodecDTSC;
+
84  case FOURCC_dtsh:
+
85  return kCodecDTSH;
+
86  case FOURCC_dtsl:
+
87  return kCodecDTSL;
+
88  case FOURCC_dtse:
+
89  return kCodecDTSE;
+
90  case FOURCC_dtsp:
+
91  return kCodecDTSP;
+
92  case FOURCC_dtsm:
+
93  return kCodecDTSM;
+
94  case FOURCC_ac_3:
+
95  return kCodecAC3;
+
96  case FOURCC_ec_3:
+
97  return kCodecEAC3;
+
98  case FOURCC_ac_4:
+
99  return kCodecAC4;
+
100  case FOURCC_fLaC:
+
101  return kCodecFlac;
+
102  default:
+
103  return kUnknownCodec;
+
104  }
+
105 }
+
106 
+
107 Codec ObjectTypeToCodec(ObjectType object_type) {
+
108  switch (object_type) {
+
109  case ObjectType::kISO_14496_3:
+
110  case ObjectType::kISO_13818_7_AAC_LC:
+
111  return kCodecAAC;
+
112  case ObjectType::kDTSC:
+
113  return kCodecDTSC;
+
114  case ObjectType::kDTSE:
+
115  return kCodecDTSE;
+
116  case ObjectType::kDTSH:
+
117  return kCodecDTSH;
+
118  case ObjectType::kDTSL:
+
119  return kCodecDTSL;
+
120  default:
+
121  return kUnknownCodec;
+
122  }
+
123 }
+
124 
+
125 std::vector<uint8_t> GetDOVIDecoderConfig(
+
126  const std::vector<CodecConfiguration>& configs) {
+
127  for (const CodecConfiguration& config : configs) {
+
128  if (config.box_type == FOURCC_dvcC || config.box_type == FOURCC_dvvC) {
+
129  return config.data;
+
130  }
+
131  }
+
132  return std::vector<uint8_t>();
+
133 }
+
134 
+
135 bool UpdateCodecStringForDolbyVision(
+
136  FourCC actual_format,
+
137  const std::vector<CodecConfiguration>& configs,
+
138  std::string* codec_string) {
+
139  DOVIDecoderConfigurationRecord dovi_config;
+
140  if (!dovi_config.Parse(GetDOVIDecoderConfig(configs))) {
+
141  LOG(ERROR) << "Failed to parse Dolby Vision decoder "
+
142  "configuration record.";
+
143  return false;
+
144  }
+
145  switch (actual_format) {
+
146  case FOURCC_dvh1:
+
147  case FOURCC_dvhe:
+
148  // Non-Backward compatibility mode. Replace the code string with
+
149  // Dolby Vision only.
+
150  *codec_string = dovi_config.GetCodecString(actual_format);
+
151  break;
+
152  case FOURCC_hev1:
+
153  // Backward compatibility mode. Two codecs are signalled: base codec
+
154  // without Dolby Vision and HDR with Dolby Vision.
+
155  *codec_string += ";" + dovi_config.GetCodecString(FOURCC_dvhe);
+
156  break;
+
157  case FOURCC_hvc1:
+
158  // See above.
+
159  *codec_string += ";" + dovi_config.GetCodecString(FOURCC_dvh1);
+
160  break;
+
161  default:
+
162  LOG(ERROR) << "Unsupported format with extra codec "
+
163  << FourCCToString(actual_format);
+
164  return false;
+
165  }
+
166  return true;
+
167 }
+
168 
+
169 const uint64_t kNanosecondsPerSecond = 1000000000ull;
+
170 
+
171 } // namespace
+
172 
+
173 MP4MediaParser::MP4MediaParser()
+
174  : state_(kWaitingForInit),
+
175  decryption_key_source_(NULL),
+
176  moof_head_(0),
+
177  mdat_tail_(0) {}
+
178 
+
179 MP4MediaParser::~MP4MediaParser() {}
+
180 
+
181 void MP4MediaParser::Init(const InitCB& init_cb,
+
182  const NewMediaSampleCB& new_media_sample_cb,
+
183  const NewTextSampleCB& new_text_sample_cb,
+
184  KeySource* decryption_key_source) {
+
185  DCHECK_EQ(state_, kWaitingForInit);
+
186  DCHECK(init_cb_.is_null());
+
187  DCHECK(!init_cb.is_null());
+
188  DCHECK(!new_media_sample_cb.is_null());
+
189 
+
190  ChangeState(kParsingBoxes);
+
191  init_cb_ = init_cb;
+
192  new_sample_cb_ = new_media_sample_cb;
+
193  decryption_key_source_ = decryption_key_source;
+
194  if (decryption_key_source)
+
195  decryptor_source_.reset(new DecryptorSource(decryption_key_source));
+
196 }
+
197 
+
198 void MP4MediaParser::Reset() {
+
199  queue_.Reset();
+
200  runs_.reset();
+
201  moof_head_ = 0;
+
202  mdat_tail_ = 0;
+
203 }
+
204 
+
205 bool MP4MediaParser::Flush() {
+
206  DCHECK_NE(state_, kWaitingForInit);
+
207  Reset();
+
208  ChangeState(kParsingBoxes);
+
209  return true;
+
210 }
+
211 
+
212 bool MP4MediaParser::Parse(const uint8_t* buf, int size) {
+
213  DCHECK_NE(state_, kWaitingForInit);
+
214 
+
215  if (state_ == kError)
+
216  return false;
+
217 
+
218  queue_.Push(buf, size);
+
219 
+
220  bool result, err = false;
+
221 
+
222  do {
+
223  if (state_ == kParsingBoxes) {
+
224  result = ParseBox(&err);
+
225  } else {
+
226  DCHECK_EQ(kEmittingSamples, state_);
+
227  result = EnqueueSample(&err);
+
228  if (result) {
+
229  int64_t max_clear = runs_->GetMaxClearOffset() + moof_head_;
+
230  err = !ReadAndDiscardMDATsUntil(max_clear);
+
231  }
+
232  }
+
233  } while (result && !err);
+
234 
+
235  if (err) {
+
236  DLOG(ERROR) << "Error while parsing MP4";
+
237  moov_.reset();
+
238  Reset();
+
239  ChangeState(kError);
+
240  return false;
+
241  }
+
242 
+
243  return true;
+
244 }
+
245 
+
246 bool MP4MediaParser::LoadMoov(const std::string& file_path) {
+
247  std::unique_ptr<File, FileCloser> file(
+
248  File::OpenWithNoBuffering(file_path.c_str(), "r"));
+
249  if (!file) {
+
250  LOG(ERROR) << "Unable to open media file '" << file_path << "'";
+
251  return false;
+
252  }
+
253  if (!file->Seek(0)) {
+
254  LOG(WARNING) << "Filesystem does not support seeking on file '" << file_path
+
255  << "'";
+
256  return false;
+
257  }
+
258 
+
259  uint64_t file_position(0);
+
260  bool mdat_seen(false);
+
261  while (true) {
+
262  const uint32_t kBoxHeaderReadSize(16);
+
263  std::vector<uint8_t> buffer(kBoxHeaderReadSize);
+
264  int64_t bytes_read = file->Read(&buffer[0], kBoxHeaderReadSize);
+
265  if (bytes_read == 0) {
+
266  LOG(ERROR) << "Could not find 'moov' box in file '" << file_path << "'";
+
267  return false;
+
268  }
+
269  if (bytes_read < kBoxHeaderReadSize) {
+
270  LOG(ERROR) << "Error reading media file '" << file_path << "'";
+
271  return false;
+
272  }
+
273  uint64_t box_size;
+
274  FourCC box_type;
+
275  bool err;
+
276  if (!BoxReader::StartBox(&buffer[0], kBoxHeaderReadSize, &box_type,
+
277  &box_size, &err)) {
+
278  LOG(ERROR) << "Could not start box from file '" << file_path << "'";
+
279  return false;
+
280  }
+
281  if (box_type == FOURCC_mdat) {
+
282  mdat_seen = true;
+
283  } else if (box_type == FOURCC_moov) {
+
284  if (!mdat_seen) {
+
285  // 'moov' is before 'mdat'. Nothing to do.
+
286  break;
+
287  }
+
288  // 'mdat' before 'moov'. Read and parse 'moov'.
+
289  if (!Parse(&buffer[0], bytes_read)) {
+
290  LOG(ERROR) << "Error parsing mp4 file '" << file_path << "'";
+
291  return false;
+
292  }
+
293  uint64_t bytes_to_read = box_size - bytes_read;
+
294  buffer.resize(bytes_to_read);
+
295  while (bytes_to_read > 0) {
+
296  bytes_read = file->Read(&buffer[0], bytes_to_read);
+
297  if (bytes_read <= 0) {
+
298  LOG(ERROR) << "Error reading 'moov' contents from file '" << file_path
+
299  << "'";
+
300  return false;
+
301  }
+
302  if (!Parse(&buffer[0], bytes_read)) {
+
303  LOG(ERROR) << "Error parsing mp4 file '" << file_path << "'";
+
304  return false;
+
305  }
+
306  bytes_to_read -= bytes_read;
+
307  }
+
308  queue_.Reset(); // So that we don't need to adjust data offsets.
+
309  mdat_tail_ = 0; // So it will skip boxes until mdat.
+
310  break; // Done.
+
311  }
+
312  file_position += box_size;
+
313  if (!file->Seek(file_position)) {
+
314  LOG(ERROR) << "Error skipping box in mp4 file '" << file_path << "'";
+
315  return false;
+
316  }
+
317  }
+
318  return true;
+
319 }
+
320 
+
321 bool MP4MediaParser::ParseBox(bool* err) {
+
322  const uint8_t* buf;
+
323  int size;
+
324  queue_.Peek(&buf, &size);
+
325  if (!size)
+
326  return false;
+
327 
+
328  std::unique_ptr<BoxReader> reader(BoxReader::ReadBox(buf, size, err));
+
329  if (reader.get() == NULL)
+
330  return false;
+
331 
+
332  if (reader->type() == FOURCC_mdat) {
+
333  if (!moov_) {
+
334  // For seekable files, we seek to the 'moov' and load the 'moov' first
+
335  // then seek back (see LoadMoov function for details); we do not support
+
336  // having 'mdat' before 'moov' for non-seekable files. The code ends up
+
337  // here only if it is a non-seekable file.
+
338  NOTIMPLEMENTED() << " Non-seekable Files with 'mdat' box before 'moov' "
+
339  "box is not supported.";
+
340  *err = true;
+
341  return false;
+
342  } else {
+
343  // This can happen if there are unused 'mdat' boxes, which is unusual
+
344  // but allowed by the spec. Ignore the 'mdat' and proceed.
+
345  LOG(INFO)
+
346  << "Ignore unused 'mdat' box - this could be as a result of extra "
+
347  "not usable 'mdat' or 'mdat' associated with unrecognized track.";
+
348  }
+
349  }
+
350 
+
351  // Set up mdat offset for ReadMDATsUntil().
+
352  mdat_tail_ = queue_.head() + reader->size();
+
353 
+
354  if (reader->type() == FOURCC_moov) {
+
355  *err = !ParseMoov(reader.get());
+
356  } else if (reader->type() == FOURCC_moof) {
+
357  moof_head_ = queue_.head();
+
358  *err = !ParseMoof(reader.get());
+
359 
+
360  // Return early to avoid evicting 'moof' data from queue. Auxiliary info may
+
361  // be located anywhere in the file, including inside the 'moof' itself.
+
362  // (Since 'default-base-is-moof' is mandated, no data references can come
+
363  // before the head of the 'moof', so keeping this box around is sufficient.)
+
364  return !(*err);
+
365  } else {
+
366  VLOG(2) << "Skipping top-level box: " << FourCCToString(reader->type());
+
367  }
+
368 
+
369  queue_.Pop(static_cast<int>(reader->size()));
+
370  return !(*err);
+
371 }
+
372 
+
373 bool MP4MediaParser::ParseMoov(BoxReader* reader) {
+
374  if (moov_)
+
375  return true; // Already parsed the 'moov' box.
+
376 
+
377  moov_.reset(new Movie);
+
378  RCHECK(moov_->Parse(reader));
+
379  runs_.reset();
+
380 
+
381  std::vector<std::shared_ptr<StreamInfo>> streams;
+
382 
+
383  for (std::vector<Track>::const_iterator track = moov_->tracks.begin();
+
384  track != moov_->tracks.end(); ++track) {
+
385  const uint32_t timescale = track->media.header.timescale;
+
386 
+
387  // Calculate duration (based on timescale).
+
388  uint64_t duration = 0;
+
389  if (track->media.header.duration > 0) {
+
390  duration = track->media.header.duration;
+
391  } else if (moov_->extends.header.fragment_duration > 0) {
+
392  DCHECK(moov_->header.timescale != 0);
+
393  duration = Rescale(moov_->extends.header.fragment_duration,
+
394  moov_->header.timescale,
+
395  timescale);
+
396  } else if (moov_->header.duration > 0 &&
+
397  moov_->header.duration != std::numeric_limits<uint64_t>::max()) {
+
398  DCHECK(moov_->header.timescale != 0);
+
399  duration =
+
400  Rescale(moov_->header.duration, moov_->header.timescale, timescale);
+
401  }
+
402 
+
403  const SampleDescription& samp_descr =
+
404  track->media.information.sample_table.description;
+
405 
+
406  size_t desc_idx = 0;
+
407 
+
408  // Read sample description index from mvex if it exists otherwise read
+
409  // from the first entry in Sample To Chunk box.
+
410  if (moov_->extends.tracks.size() > 0) {
+
411  for (size_t t = 0; t < moov_->extends.tracks.size(); t++) {
+
412  const TrackExtends& trex = moov_->extends.tracks[t];
+
413  if (trex.track_id == track->header.track_id) {
+
414  desc_idx = trex.default_sample_description_index;
+
415  break;
+
416  }
+
417  }
+
418  } else {
+
419  const std::vector<ChunkInfo>& chunk_info =
+
420  track->media.information.sample_table.sample_to_chunk.chunk_info;
+
421  RCHECK(chunk_info.size() > 0);
+
422  desc_idx = chunk_info[0].sample_description_index;
+
423  }
+
424  RCHECK(desc_idx > 0);
+
425  desc_idx -= 1; // BMFF descriptor index is one-based
+
426 
+
427  if (samp_descr.type == kAudio) {
+
428  RCHECK(!samp_descr.audio_entries.empty());
+
429 
+
430  // It is not uncommon to find otherwise-valid files with incorrect sample
+
431  // description indices, so we fail gracefully in that case.
+
432  if (desc_idx >= samp_descr.audio_entries.size())
+
433  desc_idx = 0;
+
434 
+
435  const AudioSampleEntry& entry = samp_descr.audio_entries[desc_idx];
+
436  const FourCC actual_format = entry.GetActualFormat();
+
437  Codec codec = FourCCToCodec(actual_format);
+
438  uint8_t num_channels = entry.channelcount;
+
439  uint32_t sampling_frequency = entry.samplerate;
+
440  uint64_t codec_delay_ns = 0;
+
441  uint8_t audio_object_type = 0;
+
442  uint32_t max_bitrate = 0;
+
443  uint32_t avg_bitrate = 0;
+
444  std::vector<uint8_t> codec_config;
+
445 
+
446  switch (actual_format) {
+
447  case FOURCC_mp4a: {
+
448  const DecoderConfigDescriptor& decoder_config =
+
449  entry.esds.es_descriptor.decoder_config_descriptor();
+
450  max_bitrate = decoder_config.max_bitrate();
+
451  avg_bitrate = decoder_config.avg_bitrate();
+
452 
+
453  codec = ObjectTypeToCodec(decoder_config.object_type());
+
454  if (codec == kCodecAAC) {
+
455  const AACAudioSpecificConfig& aac_audio_specific_config =
+
456  entry.esds.aac_audio_specific_config;
+
457  num_channels = aac_audio_specific_config.GetNumChannels();
+
458  sampling_frequency =
+
459  aac_audio_specific_config.GetSamplesPerSecond();
+
460  audio_object_type = aac_audio_specific_config.GetAudioObjectType();
+
461  codec_config =
+
462  decoder_config.decoder_specific_info_descriptor().data();
+
463  } else if (codec == kUnknownCodec) {
+
464  // Intentionally not to fail in the parser as there may be multiple
+
465  // streams in the source content, which allows the supported stream
+
466  // to be packaged. An error will be returned if the unsupported
+
467  // stream is passed to the muxer.
+
468  LOG(WARNING) << "Unsupported audio object type "
+
469  << static_cast<int>(decoder_config.object_type())
+
470  << " in stsd.es_desriptor.";
+
471  }
+
472  break;
+
473  }
+
474  case FOURCC_dtsc:
+
475  FALLTHROUGH_INTENDED;
+
476  case FOURCC_dtse:
+
477  FALLTHROUGH_INTENDED;
+
478  case FOURCC_dtsh:
+
479  FALLTHROUGH_INTENDED;
+
480  case FOURCC_dtsl:
+
481  FALLTHROUGH_INTENDED;
+
482  case FOURCC_dtsm:
+
483  codec_config = entry.ddts.extra_data;
+
484  max_bitrate = entry.ddts.max_bitrate;
+
485  avg_bitrate = entry.ddts.avg_bitrate;
+
486  break;
+
487  case FOURCC_ac_3:
+
488  codec_config = entry.dac3.data;
+
489  num_channels = static_cast<uint8_t>(GetAc3NumChannels(codec_config));
+
490  break;
+
491  case FOURCC_ec_3:
+
492  codec_config = entry.dec3.data;
+
493  num_channels = static_cast<uint8_t>(GetEc3NumChannels(codec_config));
+
494  break;
+
495  case FOURCC_ac_4:
+
496  codec_config = entry.dac4.data;
+
497  // Stop the process if have errors when parsing AC-4 dac4 box,
+
498  // bitstream version 0 (has beed deprecated) and contains multiple
+
499  // presentations in single AC-4 stream (only used for broadcast).
+
500  if (!GetAc4CodecInfo(codec_config, &audio_object_type)) {
+
501  LOG(ERROR) << "Failed to parse dac4.";
+
502  return false;
+
503  }
+
504  break;
+
505  case FOURCC_fLaC:
+
506  codec_config = entry.dfla.data;
+
507  break;
+
508  case FOURCC_Opus:
+
509  codec_config = entry.dops.opus_identification_header;
+
510  codec_delay_ns =
+
511  entry.dops.preskip * kNanosecondsPerSecond / sampling_frequency;
+
512  break;
+
513  default:
+
514  // Intentionally not to fail in the parser as there may be multiple
+
515  // streams in the source content, which allows the supported stream to
+
516  // be packaged.
+
517  // An error will be returned if the unsupported stream is passed to
+
518  // the muxer.
+
519  LOG(WARNING) << "Unsupported audio format '"
+
520  << FourCCToString(actual_format) << "' in stsd box.";
+
521  break;
+
522  }
+
523 
+
524  // Extract possible seek preroll.
+
525  uint64_t seek_preroll_ns = 0;
+
526  for (const auto& sample_group_description :
+
527  track->media.information.sample_table.sample_group_descriptions) {
+
528  if (sample_group_description.grouping_type != FOURCC_roll)
+
529  continue;
+
530  const auto& audio_roll_recovery_entries =
+
531  sample_group_description.audio_roll_recovery_entries;
+
532  if (audio_roll_recovery_entries.size() != 1) {
+
533  LOG(WARNING) << "Unexpected number of entries in "
+
534  "SampleGroupDescription table with grouping type "
+
535  "'roll'.";
+
536  break;
+
537  }
+
538  const int16_t roll_distance_in_samples =
+
539  audio_roll_recovery_entries[0].roll_distance;
+
540  if (roll_distance_in_samples < 0) {
+
541  RCHECK(sampling_frequency != 0);
+
542  seek_preroll_ns = kNanosecondsPerSecond *
+
543  (-roll_distance_in_samples) / sampling_frequency;
+
544  } else {
+
545  LOG(WARNING)
+
546  << "Roll distance is supposed to be negative, but seeing "
+
547  << roll_distance_in_samples;
+
548  }
+
549  break;
+
550  }
+
551 
+
552  // The stream will be decrypted if a |decryptor_source_| is available.
+
553  const bool is_encrypted =
+
554  decryptor_source_
+
555  ? false
+
556  : entry.sinf.info.track_encryption.default_is_protected == 1;
+
557  DVLOG(1) << "is_audio_track_encrypted_: " << is_encrypted;
+
558  streams.emplace_back(new AudioStreamInfo(
+
559  track->header.track_id, timescale, duration, codec,
+
560  AudioStreamInfo::GetCodecString(codec, audio_object_type),
+
561  codec_config.data(), codec_config.size(), entry.samplesize,
+
562  num_channels, sampling_frequency, seek_preroll_ns, codec_delay_ns,
+
563  max_bitrate, avg_bitrate, track->media.header.language.code,
+
564  is_encrypted));
+
565  }
+
566 
+
567  if (samp_descr.type == kVideo) {
+
568  RCHECK(!samp_descr.video_entries.empty());
+
569  if (desc_idx >= samp_descr.video_entries.size())
+
570  desc_idx = 0;
+
571  const VideoSampleEntry& entry = samp_descr.video_entries[desc_idx];
+
572  std::vector<uint8_t> codec_configuration_data =
+
573  entry.codec_configuration.data;
+
574 
+
575  uint32_t coded_width = entry.width;
+
576  uint32_t coded_height = entry.height;
+
577  uint32_t pixel_width = entry.pixel_aspect.h_spacing;
+
578  uint32_t pixel_height = entry.pixel_aspect.v_spacing;
+
579  if (pixel_width == 0 && pixel_height == 0) {
+
580  DerivePixelWidthHeight(coded_width, coded_height, track->header.width,
+
581  track->header.height, &pixel_width,
+
582  &pixel_height);
+
583  }
+
584  std::string codec_string;
+
585  uint8_t nalu_length_size = 0;
+
586  uint8_t transfer_characteristics = 0;
+
587 
+
588  const FourCC actual_format = entry.GetActualFormat();
+
589  const Codec video_codec = FourCCToCodec(actual_format);
+
590  switch (actual_format) {
+
591  case FOURCC_av01: {
+
592  AV1CodecConfigurationRecord av1_config;
+
593  if (!av1_config.Parse(codec_configuration_data)) {
+
594  LOG(ERROR) << "Failed to parse av1c.";
+
595  return false;
+
596  }
+
597  codec_string = av1_config.GetCodecString();
+
598  break;
+
599  }
+
600  case FOURCC_avc1:
+
601  case FOURCC_avc3: {
+
602  AVCDecoderConfigurationRecord avc_config;
+
603  if (!avc_config.Parse(codec_configuration_data)) {
+
604  LOG(ERROR) << "Failed to parse avcc.";
+
605  return false;
+
606  }
+
607  codec_string = avc_config.GetCodecString(actual_format);
+
608  nalu_length_size = avc_config.nalu_length_size();
+
609  transfer_characteristics = avc_config.transfer_characteristics();
+
610 
+
611  // Use configurations from |avc_config| if it is valid.
+
612  if (avc_config.coded_width() != 0) {
+
613  DCHECK_NE(avc_config.coded_height(), 0u);
+
614  if (coded_width != avc_config.coded_width() ||
+
615  coded_height != avc_config.coded_height()) {
+
616  LOG(WARNING) << "Resolution in VisualSampleEntry (" << coded_width
+
617  << "," << coded_height
+
618  << ") does not match with resolution in "
+
619  "AVCDecoderConfigurationRecord ("
+
620  << avc_config.coded_width() << ","
+
621  << avc_config.coded_height()
+
622  << "). Use AVCDecoderConfigurationRecord.";
+
623  coded_width = avc_config.coded_width();
+
624  coded_height = avc_config.coded_height();
+
625  }
+
626 
+
627  DCHECK_NE(avc_config.pixel_width(), 0u);
+
628  DCHECK_NE(avc_config.pixel_height(), 0u);
+
629  if (pixel_width != avc_config.pixel_width() ||
+
630  pixel_height != avc_config.pixel_height()) {
+
631  LOG_IF(WARNING, pixel_width != 1 || pixel_height != 1)
+
632  << "Pixel aspect ratio in PASP box (" << pixel_width << ","
+
633  << pixel_height
+
634  << ") does not match with SAR in "
+
635  "AVCDecoderConfigurationRecord "
+
636  "("
+
637  << avc_config.pixel_width() << ","
+
638  << avc_config.pixel_height()
+
639  << "). Use AVCDecoderConfigurationRecord.";
+
640  pixel_width = avc_config.pixel_width();
+
641  pixel_height = avc_config.pixel_height();
+
642  }
+
643  }
+
644  break;
+
645  }
+
646  case FOURCC_dvh1:
+
647  case FOURCC_dvhe:
+
648  case FOURCC_hev1:
+
649  case FOURCC_hvc1: {
+
650  HEVCDecoderConfigurationRecord hevc_config;
+
651  if (!hevc_config.Parse(codec_configuration_data)) {
+
652  LOG(ERROR) << "Failed to parse hevc.";
+
653  return false;
+
654  }
+
655  codec_string = hevc_config.GetCodecString(actual_format);
+
656  nalu_length_size = hevc_config.nalu_length_size();
+
657  transfer_characteristics = hevc_config.transfer_characteristics();
+
658 
+
659  if (!entry.extra_codec_configs.empty()) {
+
660  // |extra_codec_configs| is present only for Dolby Vision.
+
661  if (!UpdateCodecStringForDolbyVision(
+
662  actual_format, entry.extra_codec_configs, &codec_string)) {
+
663  return false;
+
664  }
+
665  }
+
666  break;
+
667  }
+
668  case FOURCC_vp08:
+
669  case FOURCC_vp09: {
+
670  VPCodecConfigurationRecord vp_config;
+
671  if (!vp_config.ParseMP4(codec_configuration_data)) {
+
672  LOG(ERROR) << "Failed to parse vpcc.";
+
673  return false;
+
674  }
+
675  if (actual_format == FOURCC_vp09 &&
+
676  (!vp_config.is_level_set() || vp_config.level() == 0)) {
+
677  const double kUnknownSampleDuration = 0.0;
+
678  vp_config.SetVP9Level(coded_width, coded_height,
+
679  kUnknownSampleDuration);
+
680  vp_config.WriteMP4(&codec_configuration_data);
+
681  }
+
682  codec_string = vp_config.GetCodecString(video_codec);
+
683  break;
+
684  }
+
685  default:
+
686  // Intentionally not to fail in the parser as there may be multiple
+
687  // streams in the source content, which allows the supported stream to
+
688  // be packaged.
+
689  // An error will be returned if the unsupported stream is passed to
+
690  // the muxer.
+
691  LOG(WARNING) << "Unsupported video format '"
+
692  << FourCCToString(actual_format) << "' in stsd box.";
+
693  break;
+
694  }
+
695 
+
696  // The stream will be decrypted if a |decryptor_source_| is available.
+
697  const bool is_encrypted =
+
698  decryptor_source_
+
699  ? false
+
700  : entry.sinf.info.track_encryption.default_is_protected == 1;
+
701  DVLOG(1) << "is_video_track_encrypted_: " << is_encrypted;
+
702  std::shared_ptr<VideoStreamInfo> video_stream_info(new VideoStreamInfo(
+
703  track->header.track_id, timescale, duration, video_codec,
+
704  GetH26xStreamFormat(actual_format), codec_string,
+
705  codec_configuration_data.data(), codec_configuration_data.size(),
+
706  coded_width, coded_height, pixel_width, pixel_height,
+
707  transfer_characteristics,
+
708  0, // trick_play_factor
+
709  nalu_length_size, track->media.header.language.code, is_encrypted));
+
710  video_stream_info->set_extra_config(entry.ExtraCodecConfigsAsVector());
+
711 
+
712  // Set pssh raw data if it has.
+
713  if (moov_->pssh.size() > 0) {
+
714  std::vector<uint8_t> pssh_raw_data;
+
715  for (const auto& pssh : moov_->pssh) {
+
716  pssh_raw_data.insert(pssh_raw_data.end(), pssh.raw_box.begin(),
+
717  pssh.raw_box.end());
+
718  }
+
719  video_stream_info->set_eme_init_data(pssh_raw_data.data(),
+
720  pssh_raw_data.size());
+
721  }
+
722 
+
723  streams.push_back(video_stream_info);
+
724  }
+
725  }
+
726 
+
727  init_cb_.Run(streams);
+
728  if (!FetchKeysIfNecessary(moov_->pssh))
+
729  return false;
+
730  runs_.reset(new TrackRunIterator(moov_.get()));
+
731  RCHECK(runs_->Init());
+
732  ChangeState(kEmittingSamples);
+
733  return true;
+
734 }
+
735 
+
736 bool MP4MediaParser::ParseMoof(BoxReader* reader) {
+
737  // Must already have initialization segment.
+
738  RCHECK(moov_.get());
+
739  MovieFragment moof;
+
740  RCHECK(moof.Parse(reader));
+
741  if (!runs_)
+
742  runs_.reset(new TrackRunIterator(moov_.get()));
+
743  RCHECK(runs_->Init(moof));
+
744  if (!FetchKeysIfNecessary(moof.pssh))
+
745  return false;
+
746  ChangeState(kEmittingSamples);
+
747  return true;
+
748 }
+
749 
+
750 bool MP4MediaParser::FetchKeysIfNecessary(
+
751  const std::vector<ProtectionSystemSpecificHeader>& headers) {
+
752  if (headers.empty())
+
753  return true;
+
754 
+
755  // An error will be returned later if the samples need to be decrypted.
+
756  if (!decryption_key_source_)
+
757  return true;
+
758 
+
759  std::vector<uint8_t> pssh_raw_data;
+
760  for (const auto& header : headers) {
+
761  pssh_raw_data.insert(pssh_raw_data.end(), header.raw_box.begin(),
+
762  header.raw_box.end());
+
763  }
+
764  Status status =
+
765  decryption_key_source_->FetchKeys(EmeInitDataType::CENC, pssh_raw_data);
+
766  if (!status.ok()) {
+
767  LOG(ERROR) << "Error fetching decryption keys: " << status;
+
768  return false;
+
769  }
+
770  return true;
+
771 }
+
772 
+
773 bool MP4MediaParser::EnqueueSample(bool* err) {
+
774  if (!runs_->IsRunValid()) {
+
775  // Remain in kEnqueueingSamples state, discarding data, until the end of
+
776  // the current 'mdat' box has been appended to the queue.
+
777  if (!queue_.Trim(mdat_tail_))
+
778  return false;
+
779 
+
780  ChangeState(kParsingBoxes);
+
781  return true;
+
782  }
+
783 
+
784  if (!runs_->IsSampleValid()) {
+
785  runs_->AdvanceRun();
+
786  return true;
+
787  }
+
788 
+
789  DCHECK(!(*err));
+
790 
+
791  const uint8_t* buf;
+
792  int buf_size;
+
793  queue_.Peek(&buf, &buf_size);
+
794  if (!buf_size)
+
795  return false;
+
796 
+
797  // Skip this entire track if it is not audio nor video.
+
798  if (!runs_->is_audio() && !runs_->is_video())
+
799  runs_->AdvanceRun();
+
800 
+
801  // Attempt to cache the auxiliary information first. Aux info is usually
+
802  // placed in a contiguous block before the sample data, rather than being
+
803  // interleaved. If we didn't cache it, this would require that we retain the
+
804  // start of the segment buffer while reading samples. Aux info is typically
+
805  // quite small compared to sample data, so this pattern is useful on
+
806  // memory-constrained devices where the source buffer consumes a substantial
+
807  // portion of the total system memory.
+
808  if (runs_->AuxInfoNeedsToBeCached()) {
+
809  queue_.PeekAt(runs_->aux_info_offset() + moof_head_, &buf, &buf_size);
+
810  if (buf_size < runs_->aux_info_size())
+
811  return false;
+
812  *err = !runs_->CacheAuxInfo(buf, buf_size);
+
813  return !*err;
+
814  }
+
815 
+
816  int64_t sample_offset = runs_->sample_offset() + moof_head_;
+
817  queue_.PeekAt(sample_offset, &buf, &buf_size);
+
818  if (buf_size < runs_->sample_size()) {
+
819  if (sample_offset < queue_.head()) {
+
820  LOG(ERROR) << "Incorrect sample offset " << sample_offset
+
821  << " < " << queue_.head();
+
822  *err = true;
+
823  }
+
824  return false;
+
825  }
+
826 
+
827  const uint8_t* media_data = buf;
+
828  const size_t media_data_size = runs_->sample_size();
+
829  // Use a dummy data size of 0 to avoid copying overhead.
+
830  // Actual media data is set later.
+
831  const size_t kDummyDataSize = 0;
+
832  std::shared_ptr<MediaSample> stream_sample(
+
833  MediaSample::CopyFrom(media_data, kDummyDataSize, runs_->is_keyframe()));
+
834 
+
835  if (runs_->is_encrypted()) {
+
836  std::shared_ptr<uint8_t> decrypted_media_data(
+
837  new uint8_t[media_data_size], std::default_delete<uint8_t[]>());
+
838  std::unique_ptr<DecryptConfig> decrypt_config = runs_->GetDecryptConfig();
+
839  if (!decrypt_config) {
+
840  *err = true;
+
841  LOG(ERROR) << "Missing decrypt config.";
+
842  return false;
+
843  }
+
844 
+
845  if (!decryptor_source_) {
+
846  stream_sample->SetData(media_data, media_data_size);
+
847  // If the demuxer does not have the decryptor_source_, store
+
848  // decrypt_config so that the demuxed sample can be decrypted later.
+
849  stream_sample->set_decrypt_config(std::move(decrypt_config));
+
850  stream_sample->set_is_encrypted(true);
+
851  } else {
+
852  if (!decryptor_source_->DecryptSampleBuffer(decrypt_config.get(),
+
853  media_data, media_data_size,
+
854  decrypted_media_data.get())) {
+
855  *err = true;
+
856  LOG(ERROR) << "Cannot decrypt samples.";
+
857  return false;
+
858  }
+
859  stream_sample->TransferData(std::move(decrypted_media_data),
+
860  media_data_size);
+
861  }
+
862  } else {
+
863  stream_sample->SetData(media_data, media_data_size);
+
864  }
+
865 
+
866  stream_sample->set_dts(runs_->dts());
+
867  stream_sample->set_pts(runs_->cts());
+
868  stream_sample->set_duration(runs_->duration());
+
869 
+
870  DVLOG(3) << "Pushing frame: "
+
871  << ", key=" << runs_->is_keyframe()
+
872  << ", dur=" << runs_->duration()
+
873  << ", dts=" << runs_->dts()
+
874  << ", cts=" << runs_->cts()
+
875  << ", size=" << runs_->sample_size();
+
876 
+
877  if (!new_sample_cb_.Run(runs_->track_id(), stream_sample)) {
+
878  *err = true;
+
879  LOG(ERROR) << "Failed to process the sample.";
+
880  return false;
+
881  }
+
882 
+
883  runs_->AdvanceSample();
+
884  return true;
+
885 }
+
886 
+
887 bool MP4MediaParser::ReadAndDiscardMDATsUntil(const int64_t offset) {
+
888  bool err = false;
+
889  while (mdat_tail_ < offset) {
+
890  const uint8_t* buf;
+
891  int size;
+
892  queue_.PeekAt(mdat_tail_, &buf, &size);
+
893 
+
894  FourCC type;
+
895  uint64_t box_sz;
+
896  if (!BoxReader::StartBox(buf, size, &type, &box_sz, &err))
+
897  break;
+
898 
+
899  mdat_tail_ += box_sz;
+
900  }
+
901  queue_.Trim(std::min(mdat_tail_, offset));
+
902  return !err;
+
903 }
+
904 
+
905 void MP4MediaParser::ChangeState(State new_state) {
+
906  DVLOG(2) << "Changing state: " << new_state;
+
907  state_ = new_state;
+
908 }
+
909 
+
910 } // namespace mp4
+
911 } // namespace media
+
912 } // namespace shaka
+
DecryptorSource wraps KeySource and is responsible for decryptor management.
+
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:51
+
base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
Definition: media_parser.h:53
+
base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
Definition: media_parser.h:44
+
base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
Definition: media_parser.h:35
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d7/df9/byte__queue_8cc_source.html b/docs/d7/df9/byte__queue_8cc_source.html index 97334ab780..5f3df94fc3 100644 --- a/docs/d7/df9/byte__queue_8cc_source.html +++ b/docs/d7/df9/byte__queue_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/byte_queue.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
byte_queue.cc
-
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/base/byte_queue.h"
6 
7 #include "packager/base/logging.h"
8 
9 namespace shaka {
10 namespace media {
11 
12 // Default starting size for the queue.
13 enum { kDefaultQueueSize = 1024 };
14 
15 ByteQueue::ByteQueue()
16  : buffer_(new uint8_t[kDefaultQueueSize]),
17  size_(kDefaultQueueSize),
18  offset_(0),
19  used_(0) {
20 }
21 
22 ByteQueue::~ByteQueue() {}
23 
25  offset_ = 0;
26  used_ = 0;
27 }
28 
29 void ByteQueue::Push(const uint8_t* data, int size) {
30  DCHECK(data);
31  DCHECK_GT(size, 0);
32 
33  size_t size_needed = used_ + size;
34 
35  // Check to see if we need a bigger buffer.
36  if (size_needed > size_) {
37  size_t new_size = 2 * size_;
38  while (size_needed > new_size && new_size > size_)
39  new_size *= 2;
40 
41  // Sanity check to make sure we didn't overflow.
42  CHECK_GT(new_size, size_);
43 
44  std::unique_ptr<uint8_t[]> new_buffer(new uint8_t[new_size]);
45 
46  // Copy the data from the old buffer to the start of the new one.
47  if (used_ > 0)
48  memcpy(new_buffer.get(), front(), used_);
49 
50  buffer_.reset(new_buffer.release());
51  size_ = new_size;
52  offset_ = 0;
53  } else if ((offset_ + used_ + size) > size_) {
54  // The buffer is big enough, but we need to move the data in the queue.
55  memmove(buffer_.get(), front(), used_);
56  offset_ = 0;
57  }
58 
59  memcpy(front() + used_, data, size);
60  used_ += size;
61 }
62 
63 void ByteQueue::Peek(const uint8_t** data, int* size) const {
64  DCHECK(data);
65  DCHECK(size);
66  *data = front();
67  *size = used_;
68 }
69 
70 void ByteQueue::Pop(int count) {
71  DCHECK_LE(count, used_);
72 
73  offset_ += count;
74  used_ -= count;
75 
76  // Move the offset back to 0 if we have reached the end of the buffer.
77  if (offset_ == size_) {
78  DCHECK_EQ(used_, 0);
79  offset_ = 0;
80  }
81 }
82 
83 uint8_t* ByteQueue::front() const {
84  return buffer_.get() + offset_;
85 }
86 
87 } // namespace media
88 } // namespace shaka
All the methods that are virtual are virtual for mocking.
-
void Push(const uint8_t *data, int size)
Append new bytes to the end of the queue.
Definition: byte_queue.cc:29
-
void Pop(int count)
Definition: byte_queue.cc:70
-
void Reset()
Reset the queue to the empty state.
Definition: byte_queue.cc:24
-
void Peek(const uint8_t **data, int *size) const
Definition: byte_queue.cc:63
+
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/base/byte_queue.h"
+
6 
+
7 #include "packager/base/logging.h"
+
8 
+
9 namespace shaka {
+
10 namespace media {
+
11 
+
12 // Default starting size for the queue.
+
13 enum { kDefaultQueueSize = 1024 };
+
14 
+
15 ByteQueue::ByteQueue()
+
16  : buffer_(new uint8_t[kDefaultQueueSize]),
+
17  size_(kDefaultQueueSize),
+
18  offset_(0),
+
19  used_(0) {
+
20 }
+
21 
+
22 ByteQueue::~ByteQueue() {}
+
23 
+
24 void ByteQueue::Reset() {
+
25  offset_ = 0;
+
26  used_ = 0;
+
27 }
+
28 
+
29 void ByteQueue::Push(const uint8_t* data, int size) {
+
30  DCHECK(data);
+
31 
+
32  size_t size_needed = used_ + size;
+
33 
+
34  // Check to see if we need a bigger buffer.
+
35  if (size_needed > size_) {
+
36  size_t new_size = 2 * size_;
+
37  while (size_needed > new_size && new_size > size_)
+
38  new_size *= 2;
+
39 
+
40  // Sanity check to make sure we didn't overflow.
+
41  CHECK_GT(new_size, size_);
+
42 
+
43  std::unique_ptr<uint8_t[]> new_buffer(new uint8_t[new_size]);
+
44 
+
45  // Copy the data from the old buffer to the start of the new one.
+
46  if (used_ > 0)
+
47  memcpy(new_buffer.get(), front(), used_);
+
48 
+
49  buffer_.reset(new_buffer.release());
+
50  size_ = new_size;
+
51  offset_ = 0;
+
52  } else if ((offset_ + used_ + size) > size_) {
+
53  // The buffer is big enough, but we need to move the data in the queue.
+
54  memmove(buffer_.get(), front(), used_);
+
55  offset_ = 0;
+
56  }
+
57 
+
58  memcpy(front() + used_, data, size);
+
59  used_ += size;
+
60 }
+
61 
+
62 void ByteQueue::Peek(const uint8_t** data, int* size) const {
+
63  DCHECK(data);
+
64  DCHECK(size);
+
65  *data = front();
+
66  *size = used_;
+
67 }
+
68 
+
69 void ByteQueue::Pop(int count) {
+
70  DCHECK_LE(count, used_);
+
71 
+
72  offset_ += count;
+
73  used_ -= count;
+
74 
+
75  // Move the offset back to 0 if we have reached the end of the buffer.
+
76  if (offset_ == size_) {
+
77  DCHECK_EQ(used_, 0);
+
78  offset_ = 0;
+
79  }
+
80 }
+
81 
+
82 uint8_t* ByteQueue::front() const {
+
83  return buffer_.get() + offset_;
+
84 }
+
85 
+
86 } // namespace media
+
87 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d00/structshaka_1_1media_1_1TextFragmentStyle-members.html b/docs/d8/d00/structshaka_1_1media_1_1TextFragmentStyle-members.html new file mode 100644 index 0000000000..67a6c62fcf --- /dev/null +++ b/docs/d8/d00/structshaka_1_1media_1_1TextFragmentStyle-members.html @@ -0,0 +1,84 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::TextFragmentStyle Member List
+
+
+ +

This is the complete list of members for shaka::media::TextFragmentStyle, including all inherited members.

+ + + + +
bold (defined in shaka::media::TextFragmentStyle)shaka::media::TextFragmentStyle
italic (defined in shaka::media::TextFragmentStyle)shaka::media::TextFragmentStyle
underline (defined in shaka::media::TextFragmentStyle)shaka::media::TextFragmentStyle
+ + + + diff --git a/docs/d8/d02/classshaka_1_1MockPeriod.html b/docs/d8/d02/classshaka_1_1MockPeriod.html index 3ab62c5268..6287ec6532 100644 --- a/docs/d8/d02/classshaka_1_1MockPeriod.html +++ b/docs/d8/d02/classshaka_1_1MockPeriod.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MockPeriod Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::Period - -
+ + @@ -90,8 +93,8 @@ Public Member Functions - - + + @@ -102,6 +105,8 @@ Public Member Functions void  + +

Public Member Functions

- Public Member Functions inherited from shaka::Period
virtual AdaptationSetGetOrCreateAdaptationSet (const MediaInfo &media_info, bool content_protection_in_adaptation_set)
 
xml::scoped_xml_ptr< xmlNode > GetXml (bool output_period_duration)
 
base::Optional< xml::XmlNodeGetXml (bool output_period_duration)
 
const std::list< AdaptationSet * > GetAdaptationSets () const
 
double start_time_in_seconds () const
set_duration_seconds (double duration_seconds)
 Set period duration.
 
const std::map< std::string, std::list< AdaptationSet * > > & trickplay_cache () const
 
@@ -119,9 +124,7 @@ Additional Inherited Members diff --git a/docs/d8/d04/classshaka_1_1media_1_1ttml_1_1TtmlGenerator-members.html b/docs/d8/d04/classshaka_1_1media_1_1ttml_1_1TtmlGenerator-members.html new file mode 100644 index 0000000000..3737053674 --- /dev/null +++ b/docs/d8/d04/classshaka_1_1media_1_1ttml_1_1TtmlGenerator-members.html @@ -0,0 +1,88 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+

Additional Inherited Members

+ + + + + +
+
Shaka Packager SDK +
+
+ + + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
shaka::media::ttml::TtmlGenerator Member List
+
+
+ +

This is the complete list of members for shaka::media::ttml::TtmlGenerator, including all inherited members.

+ + + + + + + + +
AddSample(const TextSample &sample) (defined in shaka::media::ttml::TtmlGenerator)shaka::media::ttml::TtmlGenerator
Dump(std::string *result) const (defined in shaka::media::ttml::TtmlGenerator)shaka::media::ttml::TtmlGenerator
Initialize(const std::map< std::string, TextRegion > &regions, const std::string &language, uint32_t time_scale) (defined in shaka::media::ttml::TtmlGenerator)shaka::media::ttml::TtmlGenerator
kTtNamespace (defined in shaka::media::ttml::TtmlGenerator)shaka::media::ttml::TtmlGeneratorstatic
Reset() (defined in shaka::media::ttml::TtmlGenerator)shaka::media::ttml::TtmlGenerator
TtmlGenerator() (defined in shaka::media::ttml::TtmlGenerator)shaka::media::ttml::TtmlGeneratorexplicit
~TtmlGenerator() (defined in shaka::media::ttml::TtmlGenerator)shaka::media::ttml::TtmlGenerator
+ + + + diff --git a/docs/d8/d08/classshaka_1_1media_1_1H264ByteToUnitStreamConverter.html b/docs/d8/d08/classshaka_1_1media_1_1H264ByteToUnitStreamConverter.html index f8d5601c04..d0bc4e9a73 100644 --- a/docs/d8/d08/classshaka_1_1media_1_1H264ByteToUnitStreamConverter.html +++ b/docs/d8/d08/classshaka_1_1media_1_1H264ByteToUnitStreamConverter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264ByteToUnitStreamConverter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-shaka::media::H26xByteToUnitStreamConverter - -
+shaka::media::H26xByteToUnitStreamConverter + + @@ -136,7 +139,7 @@ void 

Public Member Functions

WarnIfNotMatch (i

Create a H264 byte to unit stream converter. The setting of KeepParameterSetNalus is defined by a gflag.

-

Definition at line 18 of file h264_byte_to_unit_stream_converter.cc.

+

Definition at line 33 of file h264_byte_to_unit_stream_converter.cc.

@@ -165,7 +168,7 @@ void 
WarnIfNotMatch (i

Create a H264 byte to unit stream converter with desired output stream format (whether to include parameter set nal units).

-

Definition at line 21 of file h264_byte_to_unit_stream_converter.cc.

+

Definition at line 36 of file h264_byte_to_unit_stream_converter.cc.

@@ -193,7 +196,7 @@ void 
WarnIfNotMatch (i
-

Creates either an AVCDecoderConfigurationRecord or a HEVCDecoderConfigurationRecord from the units extracted from the byte stream.

Parameters
+

Creates either an AVCDecoderConfigurationRecord or a HEVCDecoderConfigurationRecord from the units extracted from the byte stream.

Parameters
decoder_configis a pointer to a vector, which on successful return will contain the computed record.
@@ -203,7 +206,7 @@ void WarnIfNotMatch (i

Implements shaka::media::H26xByteToUnitStreamConverter.

-

Definition at line 27 of file h264_byte_to_unit_stream_converter.cc.

+

Definition at line 42 of file h264_byte_to_unit_stream_converter.cc.

@@ -214,9 +217,7 @@ void WarnIfNotMatch (i diff --git a/docs/d8/d08/classshaka_1_1media_1_1WebMClusterParser-members.html b/docs/d8/d08/classshaka_1_1media_1_1WebMClusterParser-members.html index 9a7f29a773..dd914948ce 100644 --- a/docs/d8/d08/classshaka_1_1media_1_1WebMClusterParser-members.html +++ b/docs/d8/d08/classshaka_1_1media_1_1WebMClusterParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
OnString(int id, const std::string &str) (defined in shaka::media::WebMParserClient)shaka::media::WebMParserClientvirtual Parse(const uint8_t *buf, int size)shaka::media::WebMClusterParser Reset()shaka::media::WebMClusterParser - WebMClusterParser(int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)shaka::media::WebMClusterParser + WebMClusterParser(int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewMediaSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)shaka::media::WebMClusterParser WebMParserClient() (defined in shaka::media::WebMParserClient)shaka::media::WebMParserClientprotected ~WebMClusterParser() override (defined in shaka::media::WebMClusterParser)shaka::media::WebMClusterParser ~WebMParserClient() (defined in shaka::media::WebMParserClient)shaka::media::WebMParserClientvirtual
diff --git a/docs/d8/d08/classshaka_1_1media_1_1mp2t_1_1TsWriter-members.html b/docs/d8/d08/classshaka_1_1media_1_1mp2t_1_1TsWriter-members.html index 6bdcb288ed..971acc66c4 100644 --- a/docs/d8/d08/classshaka_1_1media_1_1mp2t_1_1TsWriter-members.html +++ b/docs/d8/d08/classshaka_1_1media_1_1mp2t_1_1TsWriter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
This is the complete list of members for shaka::media::mp2t::TsWriter, including all inherited members.

- - - - + +
AddPesPacket(std::unique_ptr< PesPacket > pes_packet)shaka::media::mp2t::TsWritervirtual
FinalizeSegment()shaka::media::mp2t::TsWritervirtual
GetFilePosition()shaka::media::mp2t::TsWriter
NewSegment(const std::string &file_name)shaka::media::mp2t::TsWritervirtual
AddPesPacket(std::unique_ptr< PesPacket > pes_packet, BufferWriter *buffer)shaka::media::mp2t::TsWritervirtual
NewSegment(BufferWriter *buffer)shaka::media::mp2t::TsWritervirtual
SignalEncrypted()shaka::media::mp2t::TsWritervirtual
TsWriter(std::unique_ptr< ProgramMapTableWriter > pmt_writer) (defined in shaka::media::mp2t::TsWriter)shaka::media::mp2t::TsWriterexplicit
~TsWriter() (defined in shaka::media::mp2t::TsWriter)shaka::media::mp2t::TsWritervirtual
diff --git a/docs/d8/d08/structshaka_1_1media_1_1mp4_1_1MovieHeader-members.html b/docs/d8/d08/structshaka_1_1media_1_1mp4_1_1MovieHeader-members.html index 2b61c8adad..5eb0ced795 100644 --- a/docs/d8/d08/structshaka_1_1media_1_1mp4_1_1MovieHeader-members.html +++ b/docs/d8/d08/structshaka_1_1media_1_1mp4_1_1MovieHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d0c/classshaka_1_1media_1_1MultiCodecMuxerListener-members.html b/docs/d8/d0c/classshaka_1_1media_1_1MultiCodecMuxerListener-members.html new file mode 100644 index 0000000000..366c4a8c3a --- /dev/null +++ b/docs/d8/d0c/classshaka_1_1media_1_1MultiCodecMuxerListener-members.html @@ -0,0 +1,103 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::MultiCodecMuxerListener Member List
+
+
+ +

This is the complete list of members for shaka::media::MultiCodecMuxerListener, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + +
AddListener(std::unique_ptr< MuxerListener > listener) (defined in shaka::media::CombinedMuxerListener)shaka::media::CombinedMuxerListener
CombinedMuxerListener()=default (defined in shaka::media::CombinedMuxerListener)shaka::media::CombinedMuxerListener
ContainerType enum name (defined in shaka::media::MuxerListener)shaka::media::MuxerListener
kContainerMp4 enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener
kContainerMpeg2ts enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener
kContainerPackedAudio enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener
kContainerText enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener
kContainerUnknown enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener
kContainerWebM enum value (defined in shaka::media::MuxerListener)shaka::media::MuxerListener
LimitNumOfMuxerListners(size_t num)shaka::media::CombinedMuxerListenerinlineprotected
MultiCodecMuxerListener()=default (defined in shaka::media::MultiCodecMuxerListener)shaka::media::MultiCodecMuxerListener
MuxerListener()=default (defined in shaka::media::MuxerListener)shaka::media::MuxerListenerprotected
MuxerListenerAt(size_t index)shaka::media::CombinedMuxerListenerinlineprotected
OnCueEvent(int64_t timestamp, const std::string &cue_data) overrideshaka::media::CombinedMuxerListenervirtual
OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) overrideshaka::media::CombinedMuxerListenervirtual
OnEncryptionStart() overrideshaka::media::CombinedMuxerListenervirtual
OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)shaka::media::CombinedMuxerListenervirtual
OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) overrideshaka::media::CombinedMuxerListenervirtual
OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) overrideshaka::media::MultiCodecMuxerListenervirtual
OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) overrideshaka::media::CombinedMuxerListenervirtual
OnSampleDurationReady(uint32_t sample_duration) overrideshaka::media::CombinedMuxerListenervirtual
~MuxerListener()=default (defined in shaka::media::MuxerListener)shaka::media::MuxerListenervirtual
+ + + + diff --git a/docs/d8/d0c/webvtt__text__output__handler_8h_source.html b/docs/d8/d0c/webvtt__text__output__handler_8h_source.html deleted file mode 100644 index c12576acac..0000000000 --- a/docs/d8/d0c/webvtt__text__output__handler_8h_source.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - -Shaka Packager SDK: packager/media/formats/webvtt/webvtt_text_output_handler.h Source File - - - - - - - - - -
-
- - - - - - -
-
Shaka Packager SDK -
-
-
- - - - - - - - -
-
- - -
- -
- - -
-
-
-
webvtt_text_output_handler.h
-
-
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_TEXT_HANDLER_H_
8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_TEXT_HANDLER_H_
9 
10 #include <stdint.h>
11 
12 #include <vector>
13 
14 #include "packager/media/base/media_handler.h"
15 #include "packager/media/base/muxer_options.h"
16 #include "packager/media/event/muxer_listener.h"
17 #include "packager/media/formats/webvtt/webvtt_file_buffer.h"
18 
19 namespace shaka {
20 namespace media {
21 
23  public:
24  WebVttTextOutputHandler(const MuxerOptions& muxer_options,
25  std::unique_ptr<MuxerListener> muxer_listener);
26  virtual ~WebVttTextOutputHandler() = default;
27 
28  private:
30  WebVttTextOutputHandler& operator=(const WebVttTextOutputHandler&) = delete;
31 
32  Status InitializeInternal() override;
33  Status Process(std::unique_ptr<StreamData> stream_data) override;
34  Status OnFlushRequest(size_t input_stream_index) override;
35 
36  Status OnStreamInfo(const StreamInfo& info);
37  Status OnSegmentInfo(const SegmentInfo& info);
38  Status OnCueEvent(const CueEvent& event);
39  void OnTextSample(const TextSample& sample);
40 
41  Status OnSegmentEnded();
42 
43  void GoToNextSegment(uint64_t start_time_ms);
44 
45  const MuxerOptions muxer_options_;
46  std::unique_ptr<MuxerListener> muxer_listener_;
47 
48  // Sum together all segment durations so we know how long the stream is.
49  uint64_t total_duration_ms_ = 0;
50  uint32_t segment_index_ = 0;
51 
52  std::unique_ptr<WebVttFileBuffer> buffer_;
53 };
54 
55 } // namespace media
56 } // namespace shaka
57 
58 #endif // PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_TEXT_HANDLER_H_
-
Abstract class holds stream information.
Definition: stream_info.h:62
- - -
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
- - - -
- - - - diff --git a/docs/d8/d0d/media__sample_8cc_source.html b/docs/d8/d0d/media__sample_8cc_source.html index 1769f4ac08..607ed50b5c 100644 --- a/docs/d8/d0d/media__sample_8cc_source.html +++ b/docs/d8/d0d/media__sample_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/media_sample.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
media_sample.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/base/media_sample.h"
8 
9 #include <inttypes.h>
10 
11 #include "packager/base/logging.h"
12 #include "packager/base/strings/stringprintf.h"
13 
14 namespace shaka {
15 namespace media {
16 
17 MediaSample::MediaSample(const uint8_t* data,
18  size_t data_size,
19  const uint8_t* side_data,
20  size_t side_data_size,
21  bool is_key_frame)
22  : is_key_frame_(is_key_frame) {
23  if (!data) {
24  CHECK_EQ(data_size, 0u);
25  }
26 
27  SetData(data, data_size);
28  if (side_data) {
29  std::shared_ptr<uint8_t> shared_side_data(new uint8_t[side_data_size],
30  std::default_delete<uint8_t[]>());
31  memcpy(shared_side_data.get(), side_data, side_data_size);
32  side_data_ = std::move(shared_side_data);
33  side_data_size_ = side_data_size;
34  }
35 }
36 
37 MediaSample::MediaSample() {}
38 
39 MediaSample::~MediaSample() {}
40 
41 // static
42 std::shared_ptr<MediaSample> MediaSample::CopyFrom(const uint8_t* data,
43  size_t data_size,
44  bool is_key_frame) {
45  // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
46  CHECK(data);
47  return std::shared_ptr<MediaSample>(
48  new MediaSample(data, data_size, nullptr, 0u, is_key_frame));
49 }
50 
51 // static
52 std::shared_ptr<MediaSample> MediaSample::CopyFrom(const uint8_t* data,
53  size_t data_size,
54  const uint8_t* side_data,
55  size_t side_data_size,
56  bool is_key_frame) {
57  // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
58  CHECK(data);
59  return std::shared_ptr<MediaSample>(new MediaSample(
60  data, data_size, side_data, side_data_size, is_key_frame));
61 }
62 
63 // static
64 std::shared_ptr<MediaSample> MediaSample::FromMetadata(const uint8_t* metadata,
65  size_t metadata_size) {
66  return std::shared_ptr<MediaSample>(
67  new MediaSample(nullptr, 0, metadata, metadata_size, false));
68 }
69 
70 // static
71 std::shared_ptr<MediaSample> MediaSample::CreateEmptyMediaSample() {
72  return std::shared_ptr<MediaSample>(new MediaSample);
73 }
74 
75 // static
76 std::shared_ptr<MediaSample> MediaSample::CreateEOSBuffer() {
77  return std::shared_ptr<MediaSample>(
78  new MediaSample(nullptr, 0, nullptr, 0, false));
79 }
80 
81 std::shared_ptr<MediaSample> MediaSample::Clone() const {
82  std::shared_ptr<MediaSample> new_media_sample(new MediaSample);
83  new_media_sample->dts_ = dts_;
84  new_media_sample->pts_ = pts_;
85  new_media_sample->duration_ = duration_;
86  new_media_sample->is_key_frame_ = is_key_frame_;
87  new_media_sample->is_encrypted_ = is_encrypted_;
88  new_media_sample->data_ = data_;
89  new_media_sample->data_size_ = data_size_;
90  new_media_sample->side_data_ = side_data_;
91  new_media_sample->side_data_size_ = side_data_size_;
92  new_media_sample->config_id_ = config_id_;
93  if (decrypt_config_) {
94  new_media_sample->decrypt_config_.reset(new DecryptConfig(
95  decrypt_config_->key_id(), decrypt_config_->iv(),
96  decrypt_config_->subsamples(), decrypt_config_->protection_scheme(),
97  decrypt_config_->crypt_byte_block(),
98  decrypt_config_->skip_byte_block()));
99  }
100  return new_media_sample;
101 }
102 
103 void MediaSample::TransferData(std::shared_ptr<uint8_t> data,
104  size_t data_size) {
105  data_ = std::move(data);
106  data_size_ = data_size;
107 }
108 
109 void MediaSample::SetData(const uint8_t* data, size_t data_size) {
110  std::shared_ptr<uint8_t> shared_data(new uint8_t[data_size],
111  std::default_delete<uint8_t[]>());
112  memcpy(shared_data.get(), data, data_size);
113  TransferData(std::move(shared_data), data_size);
114 }
115 
116 std::string MediaSample::ToString() const {
117  if (end_of_stream())
118  return "End of stream sample\n";
119  return base::StringPrintf(
120  "dts: %" PRId64 "\n pts: %" PRId64 "\n duration: %" PRId64
121  "\n "
122  "is_key_frame: %s\n size: %zu\n side_data_size: %zu\n",
123  dts_, pts_, duration_, is_key_frame_ ? "true" : "false", data_size_,
124  side_data_size_);
125 }
126 
127 } // namespace media
128 } // namespace shaka
std::shared_ptr< MediaSample > Clone() const
Clone the object and return a new MediaSample.
Definition: media_sample.cc:81
- -
static std::shared_ptr< MediaSample > CreateEOSBuffer()
Definition: media_sample.cc:76
-
std::string ToString() const
-
static std::shared_ptr< MediaSample > CreateEmptyMediaSample()
Create a MediaSample object with default members.
Definition: media_sample.cc:71
-
All the methods that are virtual are virtual for mocking.
-
void SetData(const uint8_t *data, size_t data_size)
-
static std::shared_ptr< MediaSample > FromMetadata(const uint8_t *metadata, size_t metadata_size)
Definition: media_sample.cc:64
-
void TransferData(std::shared_ptr< uint8_t > data, size_t data_size)
-
Class to hold a media sample.
Definition: media_sample.h:22
-
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
Definition: media_sample.cc:42
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/base/media_sample.h"
+
8 
+
9 #include <inttypes.h>
+
10 
+
11 #include "packager/base/logging.h"
+
12 #include "packager/base/strings/stringprintf.h"
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 
+
17 MediaSample::MediaSample(const uint8_t* data,
+
18  size_t data_size,
+
19  const uint8_t* side_data,
+
20  size_t side_data_size,
+
21  bool is_key_frame)
+
22  : is_key_frame_(is_key_frame) {
+
23  if (!data) {
+
24  CHECK_EQ(data_size, 0u);
+
25  }
+
26 
+
27  SetData(data, data_size);
+
28  if (side_data) {
+
29  std::shared_ptr<uint8_t> shared_side_data(new uint8_t[side_data_size],
+
30  std::default_delete<uint8_t[]>());
+
31  memcpy(shared_side_data.get(), side_data, side_data_size);
+
32  side_data_ = std::move(shared_side_data);
+
33  side_data_size_ = side_data_size;
+
34  }
+
35 }
+
36 
+
37 MediaSample::MediaSample() {}
+
38 
+
39 MediaSample::~MediaSample() {}
+
40 
+
41 // static
+
42 std::shared_ptr<MediaSample> MediaSample::CopyFrom(const uint8_t* data,
+
43  size_t data_size,
+
44  bool is_key_frame) {
+
45  // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
+
46  CHECK(data);
+
47  return std::shared_ptr<MediaSample>(
+
48  new MediaSample(data, data_size, nullptr, 0u, is_key_frame));
+
49 }
+
50 
+
51 // static
+
52 std::shared_ptr<MediaSample> MediaSample::CopyFrom(const uint8_t* data,
+
53  size_t data_size,
+
54  const uint8_t* side_data,
+
55  size_t side_data_size,
+
56  bool is_key_frame) {
+
57  // If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
+
58  CHECK(data);
+
59  return std::shared_ptr<MediaSample>(new MediaSample(
+
60  data, data_size, side_data, side_data_size, is_key_frame));
+
61 }
+
62 
+
63 // static
+
64 std::shared_ptr<MediaSample> MediaSample::FromMetadata(const uint8_t* metadata,
+
65  size_t metadata_size) {
+
66  return std::shared_ptr<MediaSample>(
+
67  new MediaSample(nullptr, 0, metadata, metadata_size, false));
+
68 }
+
69 
+
70 // static
+
71 std::shared_ptr<MediaSample> MediaSample::CreateEmptyMediaSample() {
+
72  return std::shared_ptr<MediaSample>(new MediaSample);
+
73 }
+
74 
+
75 // static
+
76 std::shared_ptr<MediaSample> MediaSample::CreateEOSBuffer() {
+
77  return std::shared_ptr<MediaSample>(
+
78  new MediaSample(nullptr, 0, nullptr, 0, false));
+
79 }
+
80 
+
81 std::shared_ptr<MediaSample> MediaSample::Clone() const {
+
82  std::shared_ptr<MediaSample> new_media_sample(new MediaSample);
+
83  new_media_sample->dts_ = dts_;
+
84  new_media_sample->pts_ = pts_;
+
85  new_media_sample->duration_ = duration_;
+
86  new_media_sample->is_key_frame_ = is_key_frame_;
+
87  new_media_sample->is_encrypted_ = is_encrypted_;
+
88  new_media_sample->data_ = data_;
+
89  new_media_sample->data_size_ = data_size_;
+
90  new_media_sample->side_data_ = side_data_;
+
91  new_media_sample->side_data_size_ = side_data_size_;
+
92  new_media_sample->config_id_ = config_id_;
+
93  if (decrypt_config_) {
+
94  new_media_sample->decrypt_config_.reset(new DecryptConfig(
+
95  decrypt_config_->key_id(), decrypt_config_->iv(),
+
96  decrypt_config_->subsamples(), decrypt_config_->protection_scheme(),
+
97  decrypt_config_->crypt_byte_block(),
+
98  decrypt_config_->skip_byte_block()));
+
99  }
+
100  return new_media_sample;
+
101 }
+
102 
+
103 void MediaSample::TransferData(std::shared_ptr<uint8_t> data,
+
104  size_t data_size) {
+
105  data_ = std::move(data);
+
106  data_size_ = data_size;
+
107 }
+
108 
+
109 void MediaSample::SetData(const uint8_t* data, size_t data_size) {
+
110  std::shared_ptr<uint8_t> shared_data(new uint8_t[data_size],
+
111  std::default_delete<uint8_t[]>());
+
112  memcpy(shared_data.get(), data, data_size);
+
113  TransferData(std::move(shared_data), data_size);
+
114 }
+
115 
+
116 std::string MediaSample::ToString() const {
+
117  if (end_of_stream())
+
118  return "End of stream sample\n";
+
119  return base::StringPrintf(
+
120  "dts: %" PRId64 "\n pts: %" PRId64 "\n duration: %" PRId64
+
121  "\n "
+
122  "is_key_frame: %s\n size: %zu\n side_data_size: %zu\n",
+
123  dts_, pts_, duration_, is_key_frame_ ? "true" : "false", data_size_,
+
124  side_data_size_);
+
125 }
+
126 
+
127 } // namespace media
+
128 } // namespace shaka
+ +
Class to hold a media sample.
Definition: media_sample.h:22
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d0f/protection__system__flags_8h_source.html b/docs/d8/d0f/protection__system__flags_8h_source.html index f8790b9986..c614eebe0d 100644 --- a/docs/d8/d0f/protection__system__flags_8h_source.html +++ b/docs/d8/d0f/protection__system__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/protection_system_flags.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
protection_system_flags.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines command line flags for protection systems.
8 
9 #ifndef PACKAGER_APP_PROTECTION_SYSTEM_FLAGS_H_
10 #define PACKAGER_APP_PROTECTION_SYSTEM_FLAGS_H_
11 
12 #include <gflags/gflags.h>
13 
14 DECLARE_string(protection_systems);
15 
16 #endif // PACKAGER_APP_PROTECTION_SYSTEM_FLAGS_H_
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines command line flags for protection systems.
+
8 
+
9 #ifndef PACKAGER_APP_PROTECTION_SYSTEM_FLAGS_H_
+
10 #define PACKAGER_APP_PROTECTION_SYSTEM_FLAGS_H_
+
11 
+
12 #include <gflags/gflags.h>
+
13 
+
14 DECLARE_string(protection_systems);
+
15 
+
16 #endif // PACKAGER_APP_PROTECTION_SYSTEM_FLAGS_H_
+
diff --git a/docs/d8/d12/structshaka_1_1media_1_1mp4_1_1DecodingTime.html b/docs/d8/d12/structshaka_1_1media_1_1mp4_1_1DecodingTime.html index d656233b86..8626a2d71c 100644 --- a/docs/d8/d12/structshaka_1_1media_1_1mp4_1_1DecodingTime.html +++ b/docs/d8/d12/structshaka_1_1media_1_1mp4_1_1DecodingTime.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::DecodingTime Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
sample_delta<

Detailed Description

-

Definition at line 420 of file box_definitions.h.

+

Definition at line 433 of file box_definitions.h.


The documentation for this struct was generated from the following file:
diff --git a/docs/d8/d13/classshaka_1_1media_1_1BitReader-members.html b/docs/d8/d13/classshaka_1_1media_1_1BitReader-members.html index d255086cdb..afe684b8c6 100644 --- a/docs/d8/d13/classshaka_1_1media_1_1BitReader-members.html +++ b/docs/d8/d13/classshaka_1_1media_1_1BitReader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
bit_position() constshaka::media::BitReaderinline BitReader(const uint8_t *data, size_t size)shaka::media::BitReader bits_available() constshaka::media::BitReaderinline - ReadBits(size_t num_bits, T *out)shaka::media::BitReaderinline - ReadBits(size_t num_bits, bool *out) (defined in shaka::media::BitReader)shaka::media::BitReaderinline - SkipBits(size_t num_bits)shaka::media::BitReader - SkipBitsConditional(bool condition, size_t num_bits)shaka::media::BitReaderinline - SkipBytes(size_t num_bytes)shaka::media::BitReader - SkipToNextByte()shaka::media::BitReader - ~BitReader() (defined in shaka::media::BitReader)shaka::media::BitReader + current_byte_ptr() constshaka::media::BitReaderinline + ReadBits(size_t num_bits, T *out)shaka::media::BitReaderinline + ReadBits(size_t num_bits, bool *out) (defined in shaka::media::BitReader)shaka::media::BitReaderinline + SkipBits(size_t num_bits)shaka::media::BitReader + SkipBitsConditional(bool condition, size_t num_bits)shaka::media::BitReaderinline + SkipBytes(size_t num_bytes)shaka::media::BitReader + SkipToNextByte()shaka::media::BitReader + ~BitReader() (defined in shaka::media::BitReader)shaka::media::BitReader
diff --git a/docs/d8/d14/classshaka_1_1media_1_1VP8Parser.html b/docs/d8/d14/classshaka_1_1media_1_1VP8Parser.html index 415092666a..21aa999b25 100644 --- a/docs/d8/d14/classshaka_1_1media_1_1VP8Parser.html +++ b/docs/d8/d14/classshaka_1_1media_1_1VP8Parser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::VP8Parser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::VPxParser - -
+ + @@ -213,9 +216,7 @@ Additional Inherited Members diff --git a/docs/d8/d16/http__file_8cc_source.html b/docs/d8/d16/http__file_8cc_source.html new file mode 100644 index 0000000000..989f3b435a --- /dev/null +++ b/docs/d8/d16/http__file_8cc_source.html @@ -0,0 +1,424 @@ + + + + + + + +Shaka Packager SDK: packager/file/http_file.cc Source File + + + + + + + + + +
+
+

Public Member Functions

+ + + + + +
+
Shaka Packager SDK +
+
+ + + + + + + + + +
+
+ + +
+ +
+ + + +
+
+
http_file.cc
+
+
+
1 // Copyright 2020 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/file/http_file.h"
+
8 
+
9 #include <curl/curl.h>
+
10 #include <gflags/gflags.h>
+
11 
+
12 #include "packager/base/bind.h"
+
13 #include "packager/base/files/file_util.h"
+
14 #include "packager/base/logging.h"
+
15 #include "packager/base/strings/string_number_conversions.h"
+
16 #include "packager/base/strings/stringprintf.h"
+
17 #include "packager/base/threading/worker_pool.h"
+
18 
+
19 DEFINE_string(ca_file,
+
20  "",
+
21  "Absolute path to the Certificate Authority file for the "
+
22  "server cert. PEM format");
+
23 DEFINE_string(client_cert_file,
+
24  "",
+
25  "Absolute path to client certificate file.");
+
26 DEFINE_string(client_cert_private_key_file,
+
27  "",
+
28  "Absolute path to the Private Key file.");
+
29 DEFINE_string(client_cert_private_key_password,
+
30  "",
+
31  "Password to the private key file.");
+
32 DEFINE_bool(disable_peer_verification,
+
33  false,
+
34  "Disable peer verification. This is needed to talk to servers "
+
35  "without valid certificates.");
+
36 DECLARE_uint64(io_cache_size);
+
37 
+
38 namespace shaka {
+
39 
+
40 namespace {
+
41 
+
42 constexpr const char* kBinaryContentType = "application/octet-stream";
+
43 constexpr const char* kUserAgent = "shaka-packager-http-fetch/1.0";
+
44 constexpr const int kMinLogLevelForCurlDebugFunction = 2;
+
45 
+
46 size_t CurlWriteCallback(char* buffer, size_t size, size_t nmemb, void* user) {
+
47  IoCache* cache = reinterpret_cast<IoCache*>(user);
+
48  size_t length = cache->Write(buffer, size * nmemb);
+
49  VLOG(3) << "CurlWriteCallback length=" << length;
+
50  return length;
+
51 }
+
52 
+
53 size_t CurlReadCallback(char* buffer, size_t size, size_t nitems, void* user) {
+
54  IoCache* cache = reinterpret_cast<IoCache*>(user);
+
55  size_t length = cache->Read(buffer, size * nitems);
+
56  VLOG(3) << "CurlRead length=" << length;
+
57  return length;
+
58 }
+
59 
+
60 int CurlDebugCallback(CURL* /* handle */,
+
61  curl_infotype type,
+
62  const char* data,
+
63  size_t size,
+
64  void* /* userptr */) {
+
65  const char* type_text;
+
66  int log_level;
+
67  bool in_hex;
+
68  switch (type) {
+
69  case CURLINFO_TEXT:
+
70  type_text = "== Info";
+
71  log_level = kMinLogLevelForCurlDebugFunction + 1;
+
72  in_hex = false;
+
73  break;
+
74  case CURLINFO_HEADER_IN:
+
75  type_text = "<= Recv header";
+
76  log_level = kMinLogLevelForCurlDebugFunction;
+
77  in_hex = false;
+
78  break;
+
79  case CURLINFO_HEADER_OUT:
+
80  type_text = "=> Send header";
+
81  log_level = kMinLogLevelForCurlDebugFunction;
+
82  in_hex = false;
+
83  break;
+
84  case CURLINFO_DATA_IN:
+
85  type_text = "<= Recv data";
+
86  log_level = kMinLogLevelForCurlDebugFunction + 1;
+
87  in_hex = true;
+
88  break;
+
89  case CURLINFO_DATA_OUT:
+
90  type_text = "=> Send data";
+
91  log_level = kMinLogLevelForCurlDebugFunction + 1;
+
92  in_hex = true;
+
93  break;
+
94  case CURLINFO_SSL_DATA_IN:
+
95  type_text = "<= Recv SSL data";
+
96  log_level = kMinLogLevelForCurlDebugFunction + 2;
+
97  in_hex = true;
+
98  break;
+
99  case CURLINFO_SSL_DATA_OUT:
+
100  type_text = "=> Send SSL data";
+
101  log_level = kMinLogLevelForCurlDebugFunction + 2;
+
102  in_hex = true;
+
103  break;
+
104  default:
+
105  // Ignore other debug data.
+
106  return 0;
+
107  }
+
108 
+
109  VLOG(log_level) << "\n\n"
+
110  << type_text << " (0x" << std::hex << size << std::dec
+
111  << " bytes)\n"
+
112  << (in_hex ? base::HexEncode(data, size)
+
113  : std::string(data, size));
+
114  return 0;
+
115 }
+
116 
+
117 class LibCurlInitializer {
+
118  public:
+
119  LibCurlInitializer() {
+
120  curl_global_init(CURL_GLOBAL_DEFAULT);
+
121  }
+
122 
+
123  ~LibCurlInitializer() {
+
124  curl_global_cleanup();
+
125  }
+
126 
+
127  LibCurlInitializer(const LibCurlInitializer&) = delete;
+
128  LibCurlInitializer& operator=(const LibCurlInitializer&) = delete;
+
129 };
+
130 
+
131 template <typename List>
+
132 bool AppendHeader(const std::string& header, List* list) {
+
133  auto* temp = curl_slist_append(list->get(), header.c_str());
+
134  if (temp) {
+
135  list->release(); // Don't free old list since it's part of the new one.
+
136  list->reset(temp);
+
137  return true;
+
138  } else {
+
139  return false;
+
140  }
+
141 }
+
142 
+
143 } // namespace
+
144 
+
145 HttpFile::HttpFile(HttpMethod method, const std::string& url)
+
146  : HttpFile(method, url, kBinaryContentType, {}, 0) {}
+
147 
+
148 HttpFile::HttpFile(HttpMethod method,
+
149  const std::string& url,
+
150  const std::string& upload_content_type,
+
151  const std::vector<std::string>& headers,
+
152  uint32_t timeout_in_seconds)
+
153  : File(url.c_str()),
+
154  url_(url),
+
155  upload_content_type_(upload_content_type),
+
156  timeout_in_seconds_(timeout_in_seconds),
+
157  method_(method),
+
158  download_cache_(FLAGS_io_cache_size),
+
159  upload_cache_(FLAGS_io_cache_size),
+
160  curl_(curl_easy_init()),
+
161  status_(Status::OK),
+
162  task_exit_event_(base::WaitableEvent::ResetPolicy::MANUAL,
+
163  base::WaitableEvent::InitialState::NOT_SIGNALED) {
+
164  static LibCurlInitializer lib_curl_initializer;
+
165 
+
166  // We will have at least one header, so use a null header to signal error
+
167  // to Open.
+
168 
+
169  // Don't wait for 100-Continue.
+
170  std::unique_ptr<curl_slist, CurlDelete> temp_headers;
+
171  if (!AppendHeader("Expect:", &temp_headers))
+
172  return;
+
173  if (!upload_content_type.empty() &&
+
174  !AppendHeader("Content-Type: " + upload_content_type_, &temp_headers)) {
+
175  return;
+
176  }
+
177  if (method != HttpMethod::kGet &&
+
178  !AppendHeader("Transfer-Encoding: chunked", &temp_headers)) {
+
179  return;
+
180  }
+
181  for (const auto& item : headers) {
+
182  if (!AppendHeader(item, &temp_headers)) {
+
183  return;
+
184  }
+
185  }
+
186  request_headers_ = std::move(temp_headers);
+
187 }
+
188 
+
189 HttpFile::~HttpFile() {}
+
190 
+
191 bool HttpFile::Open() {
+
192  VLOG(2) << "Opening " << url_;
+
193 
+
194  if (!curl_ || !request_headers_) {
+
195  LOG(ERROR) << "curl_easy_init() failed.";
+
196  return false;
+
197  }
+
198  // TODO: Try to connect initially so we can return connection error here.
+
199 
+
200  // TODO: Implement retrying with exponential backoff, see
+
201  // "widevine_key_source.cc"
+
202 
+
203  base::WorkerPool::PostTask(
+
204  FROM_HERE, base::Bind(&HttpFile::ThreadMain, base::Unretained(this)),
+
205  /* task_is_slow= */ true);
+
206 
+
207  return true;
+
208 }
+
209 
+
210 Status HttpFile::CloseWithStatus() {
+
211  VLOG(2) << "Closing " << url_;
+
212  // Close the cache first so the thread will finish uploading. Otherwise it
+
213  // will wait for more data forever.
+
214  download_cache_.Close();
+
215  upload_cache_.Close();
+
216  task_exit_event_.Wait();
+
217 
+
218  const Status result = status_;
+
219  LOG_IF(ERROR, !result.ok()) << "HttpFile request failed: " << result;
+
220  delete this;
+
221  return result;
+
222 }
+
223 
+
224 bool HttpFile::Close() {
+
225  return CloseWithStatus().ok();
+
226 }
+
227 
+
228 int64_t HttpFile::Read(void* buffer, uint64_t length) {
+
229  VLOG(2) << "Reading from " << url_ << ", length=" << length;
+
230  return download_cache_.Read(buffer, length);
+
231 }
+
232 
+
233 int64_t HttpFile::Write(const void* buffer, uint64_t length) {
+
234  VLOG(2) << "Writing to " << url_ << ", length=" << length;
+
235  return upload_cache_.Write(buffer, length);
+
236 }
+
237 
+
238 int64_t HttpFile::Size() {
+
239  LOG(ERROR) << "HttpFile does not support Size().";
+
240  return -1;
+
241 }
+
242 
+
243 bool HttpFile::Flush() {
+
244  upload_cache_.Close();
+
245  return true;
+
246 }
+
247 
+
248 bool HttpFile::Seek(uint64_t position) {
+
249  LOG(ERROR) << "HttpFile does not support Seek().";
+
250  return false;
+
251 }
+
252 
+
253 bool HttpFile::Tell(uint64_t* position) {
+
254  LOG(ERROR) << "HttpFile does not support Tell().";
+
255  return false;
+
256 }
+
257 
+
258 void HttpFile::CurlDelete::operator()(CURL* curl) {
+
259  curl_easy_cleanup(curl);
+
260 }
+
261 
+
262 void HttpFile::CurlDelete::operator()(curl_slist* headers) {
+
263  curl_slist_free_all(headers);
+
264 }
+
265 
+
266 void HttpFile::SetupRequest() {
+
267  auto* curl = curl_.get();
+
268 
+
269  switch (method_) {
+
270  case HttpMethod::kGet:
+
271  curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
+
272  break;
+
273  case HttpMethod::kPost:
+
274  curl_easy_setopt(curl, CURLOPT_POST, 1L);
+
275  break;
+
276  case HttpMethod::kPut:
+
277  curl_easy_setopt(curl, CURLOPT_PUT, 1L);
+
278  break;
+
279  }
+
280 
+
281  curl_easy_setopt(curl, CURLOPT_URL, url_.c_str());
+
282  curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgent);
+
283  curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout_in_seconds_);
+
284  curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
+
285  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
+
286  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlWriteCallback);
+
287  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &download_cache_);
+
288  if (method_ != HttpMethod::kGet) {
+
289  curl_easy_setopt(curl, CURLOPT_READFUNCTION, &CurlReadCallback);
+
290  curl_easy_setopt(curl, CURLOPT_READDATA, &upload_cache_);
+
291  }
+
292 
+
293  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, request_headers_.get());
+
294 
+
295  if (FLAGS_disable_peer_verification)
+
296  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+
297 
+
298  // Client authentication
+
299  if (!FLAGS_client_cert_private_key_file.empty() &&
+
300  !FLAGS_client_cert_file.empty()) {
+
301  curl_easy_setopt(curl, CURLOPT_SSLKEY,
+
302  FLAGS_client_cert_private_key_file.data());
+
303  curl_easy_setopt(curl, CURLOPT_SSLCERT, FLAGS_client_cert_file.data());
+
304  curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
+
305  curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
+
306 
+
307  if (!FLAGS_client_cert_private_key_password.empty()) {
+
308  curl_easy_setopt(curl, CURLOPT_KEYPASSWD,
+
309  FLAGS_client_cert_private_key_password.data());
+
310  }
+
311  }
+
312  if (!FLAGS_ca_file.empty()) {
+
313  curl_easy_setopt(curl, CURLOPT_CAINFO, FLAGS_ca_file.data());
+
314  }
+
315 
+
316  if (VLOG_IS_ON(kMinLogLevelForCurlDebugFunction)) {
+
317  curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, CurlDebugCallback);
+
318  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
+
319  }
+
320 }
+
321 
+
322 void HttpFile::ThreadMain() {
+
323  SetupRequest();
+
324 
+
325  CURLcode res = curl_easy_perform(curl_.get());
+
326  if (res != CURLE_OK) {
+
327  std::string error_message = curl_easy_strerror(res);
+
328  if (res == CURLE_HTTP_RETURNED_ERROR) {
+
329  long response_code = 0;
+
330  curl_easy_getinfo(curl_.get(), CURLINFO_RESPONSE_CODE, &response_code);
+
331  error_message +=
+
332  base::StringPrintf(", response code: %ld.", response_code);
+
333  }
+
334 
+
335  status_ = Status(
+
336  res == CURLE_OPERATION_TIMEDOUT ? error::TIME_OUT : error::HTTP_FAILURE,
+
337  error_message);
+
338  }
+
339 
+
340  download_cache_.Close();
+
341  task_exit_event_.Signal();
+
342 }
+
343 
+
344 } // namespace shaka
+ +
All the methods that are virtual are virtual for mocking.
+
+ + + + diff --git a/docs/d8/d16/structshaka_1_1media_1_1MuxerOptions-members.html b/docs/d8/d16/structshaka_1_1media_1_1MuxerOptions-members.html index f6202e2e7a..8db47af6cc 100644 --- a/docs/d8/d16/structshaka_1_1media_1_1MuxerOptions-members.html +++ b/docs/d8/d16/structshaka_1_1media_1_1MuxerOptions-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d19/bandwidth__estimator_8h_source.html b/docs/d8/d19/bandwidth__estimator_8h_source.html index b7d42948fb..126ec5ea44 100644 --- a/docs/d8/d19/bandwidth__estimator_8h_source.html +++ b/docs/d8/d19/bandwidth__estimator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/bandwidth_estimator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
bandwidth_estimator.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef MPD_BASE_BANDWIDTH_ESTIMATOR_H_
8 #define MPD_BASE_BANDWIDTH_ESTIMATOR_H_
9 
10 #include <stdint.h>
11 
12 #include <vector>
13 
14 namespace shaka {
15 
17  public:
20 
23  void AddBlock(uint64_t size_in_bytes, double duration);
24 
29  uint64_t Estimate() const;
30 
35  uint64_t Max() const;
36 
37  private:
38  BandwidthEstimator(const BandwidthEstimator&) = delete;
39  BandwidthEstimator& operator=(const BandwidthEstimator&) = delete;
40 
41  struct Block {
42  uint64_t size_in_bits;
43  double duration;
44  };
45  // Return the average block duration of the blocks in |initial_blocks_|.
46  double GetAverageBlockDuration() const;
47  // Return the bitrate of the block. Note that a bitrate of 0 is returned if
48  // the block duration is less than 50% of target block duration.
49  uint64_t GetBitrate(const Block& block, double target_block_duration) const;
50 
51  std::vector<Block> initial_blocks_;
52  // Target block duration will be estimated from the average duration of the
53  // initial blocks.
54  double target_block_duration_ = 0;
55 
56  uint64_t total_size_in_bits_ = 0;
57  double total_duration_ = 0;
58  uint64_t max_bitrate_ = 0;
59 };
60 
61 } // namespace shaka
62 
63 #endif // MPD_BASE_BANDWIDTH_ESTIMATOR_H_
All the methods that are virtual are virtual for mocking.
-
void AddBlock(uint64_t size_in_bytes, double duration)
- - - +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef MPD_BASE_BANDWIDTH_ESTIMATOR_H_
+
8 #define MPD_BASE_BANDWIDTH_ESTIMATOR_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <vector>
+
13 
+
14 namespace shaka {
+
15 
+ +
17  public:
+ + +
20 
+
23  void AddBlock(uint64_t size_in_bytes, double duration);
+
24 
+
29  uint64_t Estimate() const;
+
30 
+
35  uint64_t Max() const;
+
36 
+
37  private:
+
38  BandwidthEstimator(const BandwidthEstimator&) = delete;
+
39  BandwidthEstimator& operator=(const BandwidthEstimator&) = delete;
+
40 
+
41  struct Block {
+
42  uint64_t size_in_bits;
+
43  double duration;
+
44  };
+
45  // Return the average block duration of the blocks in |initial_blocks_|.
+
46  double GetAverageBlockDuration() const;
+
47  // Return the bitrate of the block. Note that a bitrate of 0 is returned if
+
48  // the block duration is less than 50% of target block duration.
+
49  uint64_t GetBitrate(const Block& block, double target_block_duration) const;
+
50 
+
51  std::vector<Block> initial_blocks_;
+
52  // Target block duration will be estimated from the average duration of the
+
53  // initial blocks.
+
54  double target_block_duration_ = 0;
+
55 
+
56  uint64_t total_size_in_bits_ = 0;
+
57  double total_duration_ = 0;
+
58  uint64_t max_bitrate_ = 0;
+
59 };
+
60 
+
61 } // namespace shaka
+
62 
+
63 #endif // MPD_BASE_BANDWIDTH_ESTIMATOR_H_
+ + +
void AddBlock(uint64_t size_in_bytes, double duration)
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d1c/crypto__flags_8cc_source.html b/docs/d8/d1c/crypto__flags_8cc_source.html index 0b27f5d8f9..75eb4207ae 100644 --- a/docs/d8/d1c/crypto__flags_8cc_source.html +++ b/docs/d8/d1c/crypto__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/crypto_flags.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
crypto_flags.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/crypto_flags.h"
8 
9 #include <stdio.h>
10 
11 DEFINE_string(protection_scheme,
12  "cenc",
13  "Specify a protection scheme, 'cenc' or 'cbc1' or pattern-based "
14  "protection schemes 'cens' or 'cbcs'.");
15 DEFINE_bool(vp9_subsample_encryption, true, "Enable VP9 subsample encryption.");
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/app/crypto_flags.h"
+
8 
+
9 #include <stdio.h>
+
10 
+
11 DEFINE_string(protection_scheme,
+
12  "cenc",
+
13  "Specify a protection scheme, 'cenc' or 'cbc1' or pattern-based "
+
14  "protection schemes 'cens' or 'cbcs'.");
+
15 DEFINE_int32(
+
16  crypt_byte_block,
+
17  1,
+
18  "Specify the count of the encrypted blocks in the protection pattern, "
+
19  "where block is of size 16-bytes. There are three common "
+
20  "patterns (crypt_byte_block:skip_byte_block): 1:9 (default), 5:5, 10:0. "
+
21  "Apply to video streams with 'cbcs' and 'cens' protection schemes only; "
+
22  "ignored otherwise.");
+
23 DEFINE_int32(
+
24  skip_byte_block,
+
25  9,
+
26  "Specify the count of the unencrypted blocks in the protection pattern. "
+
27  "Apply to video streams with 'cbcs' and 'cens' protection schemes only; "
+
28  "ignored otherwise.");
+
29 DEFINE_bool(vp9_subsample_encryption, true, "Enable VP9 subsample encryption.");
+
30 DEFINE_string(playready_extra_header_data,
+
31  "",
+
32  "Extra XML data to add to PlayReady headers.");
+
33 
+
34 bool ValueNotGreaterThanTen(const char* flagname, int32_t value) {
+
35  if (value > 10) {
+
36  fprintf(stderr, "ERROR: %s must not be greater than 10.\n", flagname);
+
37  return false;
+
38  }
+
39  if (value < 0) {
+
40  fprintf(stderr, "ERROR: %s must be non-negative.\n", flagname);
+
41  return false;
+
42  }
+
43  return true;
+
44 }
+
45 
+
46 bool ValueIsXml(const char* flagname, const std::string& value) {
+
47  if (value.empty())
+
48  return true;
+
49 
+
50  if (value[0] != '<' || value[value.size() - 1] != '>') {
+
51  fprintf(stderr, "ERROR: %s must be valid XML.\n", flagname);
+
52  return false;
+
53  }
+
54  return true;
+
55 }
+
56 
+
57 DEFINE_validator(crypt_byte_block, &ValueNotGreaterThanTen);
+
58 DEFINE_validator(skip_byte_block, &ValueNotGreaterThanTen);
+
59 DEFINE_validator(playready_extra_header_data, &ValueIsXml);
+
diff --git a/docs/d8/d20/structshaka_1_1media_1_1mp4_1_1WebVTTConfigurationBox.html b/docs/d8/d20/structshaka_1_1media_1_1mp4_1_1WebVTTConfigurationBox.html index 3aaa552c40..7220e61edc 100644 --- a/docs/d8/d20/structshaka_1_1media_1_1mp4_1_1WebVTTConfigurationBox.html +++ b/docs/d8/d20/structshaka_1_1media_1_1mp4_1_1WebVTTConfigurationBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::WebVTTConfigurationBox Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 379 of file box_definitions.h.

+

Definition at line 387 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 1910 of file box_definitions.cc.

+

Definition at line 1959 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d8/d23/structshaka_1_1media_1_1SubsampleEntry-members.html b/docs/d8/d23/structshaka_1_1media_1_1SubsampleEntry-members.html index 86c97466f2..afdc1fda1f 100644 --- a/docs/d8/d23/structshaka_1_1media_1_1SubsampleEntry-members.html +++ b/docs/d8/d23/structshaka_1_1media_1_1SubsampleEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d28/es__parser__h265_8h_source.html b/docs/d8/d28/es__parser__h265_8h_source.html index 65adfa7419..c6e374c880 100644 --- a/docs/d8/d28/es__parser__h265_8h_source.html +++ b/docs/d8/d28/es__parser__h265_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser_h265.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
es_parser_h265.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H265_H_
8 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H265_H_
9 
10 #include <stdint.h>
11 
12 #include <list>
13 #include <memory>
14 #include <utility>
15 
16 #include "packager/base/callback.h"
17 #include "packager/base/compiler_specific.h"
18 #include "packager/media/formats/mp2t/es_parser_h26x.h"
19 
20 namespace shaka {
21 namespace media {
22 
23 class H265Parser;
24 
25 namespace mp2t {
26 
27 class EsParserH265 : public EsParserH26x {
28  public:
29  EsParserH265(uint32_t pid,
30  const NewStreamInfoCB& new_stream_info_cb,
31  const EmitSampleCB& emit_sample_cb);
32  ~EsParserH265() override;
33 
34  // EsParserH26x implementation override.
35  void Reset() override;
36 
37  private:
38  // Processes a NAL unit found in ParseInternal.
39  bool ProcessNalu(const Nalu& nalu, VideoSliceInfo* video_slice_info) override;
40 
41  // Update the video decoder config based on an H264 SPS.
42  // Return true if successful.
43  bool UpdateVideoDecoderConfig(int sps_id) override;
44 
45  // Callback to pass the stream configuration.
46  NewStreamInfoCB new_stream_info_cb_;
47 
48  // Last video decoder config.
49  std::shared_ptr<StreamInfo> last_video_decoder_config_;
50  bool decoder_config_check_pending_;
51 
52  std::unique_ptr<H265Parser> h265_parser_;
53 };
54 
55 } // namespace mp2t
56 } // namespace media
57 } // namespace shaka
58 
59 #endif // PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H265_H_
- -
All the methods that are virtual are virtual for mocking.
- - +
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H265_H_
+
8 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H265_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <list>
+
13 #include <memory>
+
14 #include <utility>
+
15 
+
16 #include "packager/base/callback.h"
+
17 #include "packager/base/compiler_specific.h"
+
18 #include "packager/media/formats/mp2t/es_parser_h26x.h"
+
19 
+
20 namespace shaka {
+
21 namespace media {
+
22 
+
23 class H265Parser;
+
24 
+
25 namespace mp2t {
+
26 
+
27 class EsParserH265 : public EsParserH26x {
+
28  public:
+
29  EsParserH265(uint32_t pid,
+
30  const NewStreamInfoCB& new_stream_info_cb,
+
31  const EmitSampleCB& emit_sample_cb);
+
32  ~EsParserH265() override;
+
33 
+
34  // EsParserH26x implementation override.
+
35  void Reset() override;
+
36 
+
37  private:
+
38  // Processes a NAL unit found in ParseInternal.
+
39  bool ProcessNalu(const Nalu& nalu, VideoSliceInfo* video_slice_info) override;
+
40 
+
41  // Update the video decoder config based on an H264 SPS.
+
42  // Return true if successful.
+
43  bool UpdateVideoDecoderConfig(int sps_id) override;
+
44 
+
45  // Callback to pass the stream configuration.
+
46  NewStreamInfoCB new_stream_info_cb_;
+
47 
+
48  // Last video decoder config.
+
49  std::shared_ptr<StreamInfo> last_video_decoder_config_;
+
50  bool decoder_config_check_pending_;
+
51 
+
52  std::unique_ptr<H265Parser> h265_parser_;
+
53 };
+
54 
+
55 } // namespace mp2t
+
56 } // namespace media
+
57 } // namespace shaka
+
58 
+
59 #endif // PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H265_H_
+ + + +
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d8/d33/webm__content__encodings__client_8h_source.html b/docs/d8/d33/webm__content__encodings__client_8h_source.html index b237b90277..950e8f35bf 100644 --- a/docs/d8/d33/webm__content__encodings__client_8h_source.html +++ b/docs/d8/d33/webm__content__encodings__client_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_content_encodings_client.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
webm_content_encodings_client.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "packager/base/callback.h"
12 #include "packager/media/formats/webm/webm_content_encodings.h"
13 #include "packager/media/formats/webm/webm_parser.h"
14 
15 namespace shaka {
16 namespace media {
17 
18 typedef std::vector<std::unique_ptr<ContentEncoding>> ContentEncodings;
19 
22  public:
24  ~WebMContentEncodingsClient() override;
25 
26  const ContentEncodings& content_encodings() const;
27 
29  WebMParserClient* OnListStart(int id) override;
30  bool OnListEnd(int id) override;
31  bool OnUInt(int id, int64_t val) override;
32  bool OnBinary(int id, const uint8_t* data, int size) override;
33 
34  private:
35  std::unique_ptr<ContentEncoding> cur_content_encoding_;
36  bool content_encryption_encountered_;
37  ContentEncodings content_encodings_;
38 
39  // |content_encodings_| is ready. For debugging purpose.
40  bool content_encodings_ready_;
41 
42  DISALLOW_COPY_AND_ASSIGN(WebMContentEncodingsClient);
43 };
44 
45 } // namespace media
46 } // namespace shaka
47 
48 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_
Parser for WebM ContentEncodings element.
-
All the methods that are virtual are virtual for mocking.
-
WebMParserClient * OnListStart(int id) override
WebMParserClient methods.
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_
+
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_
+
7 
+
8 #include <memory>
+
9 #include <vector>
+
10 
+
11 #include "packager/base/callback.h"
+
12 #include "packager/media/formats/webm/webm_content_encodings.h"
+
13 #include "packager/media/formats/webm/webm_parser.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 
+
18 typedef std::vector<std::unique_ptr<ContentEncoding>> ContentEncodings;
+
19 
+ +
22  public:
+ +
24  ~WebMContentEncodingsClient() override;
+
25 
+
26  const ContentEncodings& content_encodings() const;
+
27 
+
29  WebMParserClient* OnListStart(int id) override;
+
30  bool OnListEnd(int id) override;
+
31  bool OnUInt(int id, int64_t val) override;
+
32  bool OnBinary(int id, const uint8_t* data, int size) override;
+
33 
+
34  private:
+
35  std::unique_ptr<ContentEncoding> cur_content_encoding_;
+
36  bool content_encryption_encountered_;
+
37  ContentEncodings content_encodings_;
+
38 
+
39  // |content_encodings_| is ready. For debugging purpose.
+
40  bool content_encodings_ready_;
+
41 
+
42  DISALLOW_COPY_AND_ASSIGN(WebMContentEncodingsClient);
+
43 };
+
44 
+
45 } // namespace media
+
46 } // namespace shaka
+
47 
+
48 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_CLIENT_H_
+
Parser for WebM ContentEncodings element.
+
WebMParserClient * OnListStart(int id) override
WebMParserClient methods.
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d48/structshaka_1_1WidevineDecryptionParams.html b/docs/d8/d48/structshaka_1_1WidevineDecryptionParams.html index ed7b00dd67..1f6481c579 100644 --- a/docs/d8/d48/structshaka_1_1WidevineDecryptionParams.html +++ b/docs/d8/d48/structshaka_1_1WidevineDecryptionParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::WidevineDecryptionParams Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */

Detailed Description

Widevine decryption parameters.

-

Definition at line 178 of file crypto_params.h.

+

Definition at line 220 of file crypto_params.h.


The documentation for this struct was generated from the following file:
diff --git a/docs/d8/d4a/mpeg1__header_8h_source.html b/docs/d8/d4a/mpeg1__header_8h_source.html new file mode 100644 index 0000000000..4a933e38c7 --- /dev/null +++ b/docs/d8/d4a/mpeg1__header_8h_source.html @@ -0,0 +1,141 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/mp2t/mpeg1_header.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
mpeg1_header.h
+
+
+
1 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_MPEG1_HEADER_H_
+
2 #define PACKAGER_MEDIA_FORMATS_MP2T_MPEG1_HEADER_H_
+
3 
+
4 #include <stdint.h>
+
5 
+
6 #include <vector>
+
7 
+
8 #include "packager/media/formats/mp2t/audio_header.h"
+
9 
+
10 namespace shaka {
+
11 namespace media {
+
12 namespace mp2t {
+
17 class Mpeg1Header : public AudioHeader {
+
18  public:
+
19  Mpeg1Header() = default;
+
20  ~Mpeg1Header() override = default;
+
21 
+
24  bool IsSyncWord(const uint8_t* buf) const override;
+
25  size_t GetMinFrameSize() const override;
+
26  size_t GetSamplesPerFrame() const override;
+
27  bool Parse(const uint8_t* mpeg1_frame, size_t mpeg1_frame_size) override;
+
28  size_t GetHeaderSize() const override;
+
29  size_t GetFrameSize() const override;
+
30  size_t GetFrameSizeWithoutParsing(const uint8_t* data,
+
31  size_t num_bytes) const override;
+
32  void GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const override;
+
33  uint8_t GetObjectType() const override;
+
34  uint32_t GetSamplingFrequency() const override;
+
35  uint8_t GetNumChannels() const override;
+
37 
+
38  private:
+
39  Mpeg1Header(const Mpeg1Header&) = delete;
+
40  Mpeg1Header& operator=(const Mpeg1Header&) = delete;
+
41 
+
42  uint8_t version_ = 0;
+
43  uint8_t layer_ = 0;
+
44  uint8_t protection_absent_ = 0;
+
45 
+
46  uint32_t bitrate_ = 0;
+
47  uint32_t sample_rate_ = 0; /* in hz */
+
48  uint8_t padded_ = 0;
+
49  uint8_t channel_mode_ = 0;
+
50 };
+
51 
+
52 } // namespace mp2t
+
53 } // namespace media
+
54 } // namespace shaka
+
55 
+
56 #endif // PACKAGER_MEDIA_FORMATS_MP2T_MPEG1_HEADER_H_
+ + +
size_t GetMinFrameSize() const override
+
size_t GetFrameSize() const override
+
void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
+
size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
+
bool IsSyncWord(const uint8_t *buf) const override
Definition: mpeg1_header.cc:94
+
uint8_t GetObjectType() const override
+
uint8_t GetNumChannels() const override
+
size_t GetSamplesPerFrame() const override
+
uint32_t GetSamplingFrequency() const override
+
bool Parse(const uint8_t *mpeg1_frame, size_t mpeg1_frame_size) override
+
size_t GetHeaderSize() const override
+
All the methods that are virtual are virtual for mocking.
+
+ + + + diff --git a/docs/d8/d4d/aes__decryptor_8h_source.html b/docs/d8/d4d/aes__decryptor_8h_source.html index a34f2e5f8f..6a9ac7f362 100644 --- a/docs/d8/d4d/aes__decryptor_8h_source.html +++ b/docs/d8/d4d/aes__decryptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/aes_decryptor.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
aes_decryptor.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // AES Decryptor implementation using openssl.
8 
9 #ifndef PACKAGER_MEDIA_BASE_AES_DECRYPTOR_H_
10 #define PACKAGER_MEDIA_BASE_AES_DECRYPTOR_H_
11 
12 #include <vector>
13 
14 #include "packager/base/macros.h"
15 #include "packager/media/base/aes_cryptor.h"
16 #include "packager/media/base/aes_encryptor.h"
17 
18 namespace shaka {
19 namespace media {
20 
22 using AesCtrDecryptor = AesCtrEncryptor;
23 
25 class AesCbcDecryptor : public AesCryptor {
26  public:
31  explicit AesCbcDecryptor(CbcPaddingScheme padding_scheme);
32 
40  AesCbcDecryptor(CbcPaddingScheme padding_scheme,
41  ConstantIvFlag constant_iv_flag);
42 
43  ~AesCbcDecryptor() override;
44 
47  bool InitializeWithIv(const std::vector<uint8_t>& key,
48  const std::vector<uint8_t>& iv) override;
50 
51  private:
52  bool CryptInternal(const uint8_t* ciphertext,
53  size_t ciphertext_size,
54  uint8_t* plaintext,
55  size_t* plaintext_size) override;
56  void SetIvInternal() override;
57 
58  const CbcPaddingScheme padding_scheme_;
59  // 16-byte internal iv for crypto operations.
60  std::vector<uint8_t> internal_iv_;
61 
62  DISALLOW_COPY_AND_ASSIGN(AesCbcDecryptor);
63 };
64 
65 } // namespace media
66 } // namespace shaka
67 
68 #endif // PACKAGER_MEDIA_BASE_AES_DECRYPTOR_H_
-
Class which implements AES-CBC (Cipher block chaining) decryption.
Definition: aes_decryptor.h:25
-
All the methods that are virtual are virtual for mocking.
-
AesCbcDecryptor(CbcPaddingScheme padding_scheme)
-
bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
-
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // AES Decryptor implementation using openssl.
+
8 
+
9 #ifndef PACKAGER_MEDIA_BASE_AES_DECRYPTOR_H_
+
10 #define PACKAGER_MEDIA_BASE_AES_DECRYPTOR_H_
+
11 
+
12 #include <vector>
+
13 
+
14 #include "packager/base/macros.h"
+
15 #include "packager/media/base/aes_cryptor.h"
+
16 #include "packager/media/base/aes_encryptor.h"
+
17 
+
18 namespace shaka {
+
19 namespace media {
+
20 
+
22 using AesCtrDecryptor = AesCtrEncryptor;
+
23 
+
25 class AesCbcDecryptor : public AesCryptor {
+
26  public:
+
31  explicit AesCbcDecryptor(CbcPaddingScheme padding_scheme);
+
32 
+
40  AesCbcDecryptor(CbcPaddingScheme padding_scheme,
+
41  ConstantIvFlag constant_iv_flag);
+
42 
+
43  ~AesCbcDecryptor() override;
+
44 
+
47  bool InitializeWithIv(const std::vector<uint8_t>& key,
+
48  const std::vector<uint8_t>& iv) override;
+
50 
+
51  private:
+
52  bool CryptInternal(const uint8_t* ciphertext,
+
53  size_t ciphertext_size,
+
54  uint8_t* plaintext,
+
55  size_t* plaintext_size) override;
+
56  void SetIvInternal() override;
+
57 
+
58  const CbcPaddingScheme padding_scheme_;
+
59  // 16-byte internal iv for crypto operations.
+
60  std::vector<uint8_t> internal_iv_;
+
61 
+
62  DISALLOW_COPY_AND_ASSIGN(AesCbcDecryptor);
+
63 };
+
64 
+
65 } // namespace media
+
66 } // namespace shaka
+
67 
+
68 #endif // PACKAGER_MEDIA_BASE_AES_DECRYPTOR_H_
+
Class which implements AES-CBC (Cipher block chaining) decryption.
Definition: aes_decryptor.h:25
+
bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
+
AesCbcDecryptor(CbcPaddingScheme padding_scheme)
+ +
const std::vector< uint8_t > & iv() const
Definition: aes_cryptor.h:82
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d4f/classshaka_1_1media_1_1TextSample-members.html b/docs/d8/d4f/classshaka_1_1media_1_1TextSample-members.html index 07ad9b5a2f..c84ba360b8 100644 --- a/docs/d8/d4f/classshaka_1_1media_1_1TextSample-members.html +++ b/docs/d8/d4f/classshaka_1_1media_1_1TextSample-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::media::TextSample, including all inherited members.

- - - - - - - - - - - + + + + + + + + +
AppendPayload(const std::string &payload) (defined in shaka::media::TextSample)shaka::media::TextSample
AppendStyle(const std::string &style) (defined in shaka::media::TextSample)shaka::media::TextSample
duration() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
EndTime() const (defined in shaka::media::TextSample)shaka::media::TextSample
id() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
payload() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
set_id(const std::string &id) (defined in shaka::media::TextSample)shaka::media::TextSampleinline
SetTime(int64_t start_time, int64_t end_time) (defined in shaka::media::TextSample)shaka::media::TextSample
settings() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
start_time() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
TextSample()=default (defined in shaka::media::TextSample)shaka::media::TextSample
body() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
duration() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
EndTime() const (defined in shaka::media::TextSample)shaka::media::TextSample
id() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
set_sub_stream_index(int32_t idx) (defined in shaka::media::TextSample)shaka::media::TextSampleinline
settings() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
start_time() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
sub_stream_index() const (defined in shaka::media::TextSample)shaka::media::TextSampleinline
TextSample(const std::string &id, int64_t start_time, int64_t end_time, const TextSettings &settings, const TextFragment &body) (defined in shaka::media::TextSample)shaka::media::TextSample
diff --git a/docs/d8/d51/text__readers_8cc_source.html b/docs/d8/d51/text__readers_8cc_source.html index 106f95dbf7..5ef656ab1d 100644 --- a/docs/d8/d51/text__readers_8cc_source.html +++ b/docs/d8/d51/text__readers_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/text_readers.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
text_readers.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webvtt/text_readers.h"
8 
9 #include "packager/base/logging.h"
10 #include "packager/file/file.h"
11 
12 namespace shaka {
13 namespace media {
14 
15 Status FileReader::Open(const std::string& filename,
16  std::unique_ptr<FileReader>* out) {
17  const char* kReadOnly = "r";
18 
19  std::unique_ptr<File, FileCloser> file(
20  File::Open(filename.c_str(), kReadOnly));
21 
22  if (!file) {
23  return Status(error::INVALID_ARGUMENT,
24  "Could not open input file " + filename);
25  }
26 
27  *out = std::unique_ptr<FileReader>(new FileReader(std::move(file)));
28 
29  return Status::OK;
30 }
31 
32 bool FileReader::Next(char* out) {
33  // TODO(vaage): If file reading performance is poor, change this to buffer
34  // data and read from the buffer.
35  return file_->Read(out, 1) == 1;
36 }
37 
38 FileReader::FileReader(std::unique_ptr<File, FileCloser> file)
39  : file_(std::move(file)) {
40  DCHECK(file_);
41 }
42 
43 PeekingReader::PeekingReader(std::unique_ptr<FileReader> source)
44  : source_(std::move(source)) {}
45 
46 bool PeekingReader::Next(char* out) {
47  DCHECK(out);
48  if (Peek(out)) {
49  has_cached_next_ = false;
50  return true;
51  }
52  return false;
53 }
54 
55 bool PeekingReader::Peek(char* out) {
56  DCHECK(out);
57  if (!has_cached_next_ && source_->Next(&cached_next_)) {
58  has_cached_next_ = true;
59  }
60  if (has_cached_next_) {
61  *out = cached_next_;
62  return true;
63  }
64  return false;
65 }
66 
67 LineReader::LineReader(std::unique_ptr<FileReader> source)
68  : source_(std::move(source)) {}
69 
70 // Split lines based on https://w3c.github.io/webvtt/#webvtt-line-terminator
71 bool LineReader::Next(std::string* out) {
72  DCHECK(out);
73  out->clear();
74  bool read_something = false;
75  char now;
76  while (source_.Next(&now)) {
77  read_something = true;
78  // handle \n
79  if (now == '\n') {
80  break;
81  }
82  // handle \r and \r\n
83  if (now == '\r') {
84  char next;
85  if (source_.Peek(&next) && next == '\n') {
86  source_.Next(&next); // Read in the '\n' that was just seen via |Peek|
87  }
88  break;
89  }
90  out->push_back(now);
91  }
92  return read_something;
93 }
94 
95 BlockReader::BlockReader(std::unique_ptr<FileReader> source)
96  : source_(std::move(source)) {}
97 
98 bool BlockReader::Next(std::vector<std::string>* out) {
99  DCHECK(out);
100 
101  out->clear();
102 
103  bool in_block = false;
104 
105  // Read through lines until a non-empty line is found. With a non-empty
106  // line is found, start adding the lines to the output and once an empty
107  // line if found again, stop adding lines and exit.
108  std::string line;
109  while (source_.Next(&line)) {
110  if (in_block && line.empty()) {
111  break;
112  }
113  if (in_block || !line.empty()) {
114  out->push_back(line);
115  in_block = true;
116  }
117  }
118 
119  return in_block;
120 }
121 } // namespace media
122 } // namespace shaka
All the methods that are virtual are virtual for mocking.
- -
bool Next(char *out)
Definition: text_readers.cc:32
-
Class to read character-by-character from a file.
Definition: text_readers.h:23
-
virtual bool Open()=0
Internal open. Should not be used directly.
-
static Status Open(const std::string &filename, std::unique_ptr< FileReader > *out)
Definition: text_readers.cc:15
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/webvtt/text_readers.h"
+
8 
+
9 #include <cstring>
+
10 
+
11 #include "packager/base/logging.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
16 LineReader::LineReader() : should_flush_(false) {}
+
17 
+
18 void LineReader::PushData(const uint8_t* data, size_t data_size) {
+
19  buffer_.Push(data, static_cast<int>(data_size));
+
20  should_flush_ = false;
+
21 }
+
22 
+
23 // Split lines based on https://w3c.github.io/webvtt/#webvtt-line-terminator
+
24 bool LineReader::Next(std::string* out) {
+
25  DCHECK(out);
+
26 
+
27  int i;
+
28  int skip = 0;
+
29  const uint8_t* data;
+
30  int data_size;
+
31  buffer_.Peek(&data, &data_size);
+
32  for (i = 0; i < data_size; i++) {
+
33  // Handle \n
+
34  if (data[i] == '\n') {
+
35  skip = 1;
+
36  break;
+
37  }
+
38 
+
39  // Handle \r and \r\n
+
40  if (data[i] == '\r') {
+
41  // Only read if we can see the next character; this ensures we don't get
+
42  // the '\n' in the next PushData.
+
43  if (i + 1 == data_size) {
+
44  if (!should_flush_)
+
45  return false;
+
46  skip = 1;
+
47  } else {
+
48  if (data[i + 1] == '\n')
+
49  skip = 2;
+
50  else
+
51  skip = 1;
+
52  }
+
53  break;
+
54  }
+
55  }
+
56 
+
57  if (i == data_size && (!should_flush_ || i == 0)) {
+
58  return false;
+
59  }
+
60 
+
61  // TODO(modmaker): Handle character encodings?
+
62  out->assign(data, data + i);
+
63  buffer_.Pop(i + skip);
+
64  return true;
+
65 }
+
66 
+
67 void LineReader::Flush() {
+
68  should_flush_ = true;
+
69 }
+
70 
+
71 BlockReader::BlockReader() : should_flush_(false) {}
+
72 
+
73 void BlockReader::PushData(const uint8_t* data, size_t data_size) {
+
74  source_.PushData(data, data_size);
+
75  should_flush_ = false;
+
76 }
+
77 
+
78 bool BlockReader::Next(std::vector<std::string>* out) {
+
79  DCHECK(out);
+
80 
+
81  bool end_block = false;
+
82  // Read through lines until a non-empty line is found. With a non-empty
+
83  // line is found, start adding the lines to the output and once an empty
+
84  // line if found again, stop adding lines and exit.
+
85  std::string line;
+
86  while (source_.Next(&line)) {
+
87  if (!temp_.empty() && line.empty()) {
+
88  end_block = true;
+
89  break;
+
90  }
+
91  if (!line.empty()) {
+
92  temp_.emplace_back(std::move(line));
+
93  }
+
94  }
+
95 
+
96  if (!end_block && (!should_flush_ || temp_.empty()))
+
97  return false;
+
98 
+
99  *out = std::move(temp_);
+
100  return true;
+
101 }
+
102 
+ +
104  source_.Flush();
+
105  should_flush_ = true;
+
106 }
+
107 
+
108 } // namespace media
+
109 } // namespace shaka
+
void PushData(const uint8_t *data, size_t data_size)
Pushes data onto the end of the buffer.
Definition: text_readers.cc:73
+ +
bool Next(std::vector< std::string > *out)
Definition: text_readers.cc:78
+ +
bool Next(std::string *out)
Definition: text_readers.cc:24
+
void PushData(const uint8_t *data, size_t data_size)
Pushes data onto the end of the buffer.
Definition: text_readers.cc:18
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d53/crypto__flags_8h_source.html b/docs/d8/d53/crypto__flags_8h_source.html index eac57c5cb7..ddc0ac96d6 100644 --- a/docs/d8/d53/crypto__flags_8h_source.html +++ b/docs/d8/d53/crypto__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/crypto_flags.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
crypto_flags.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines common command line flags for encryption and decryption, which
8 // applies to all key sources, i.e. raw key, Widevine and PlayReady.
9 
10 #ifndef PACKAGER_APP_CRYPTO_FLAGS_H_
11 #define PACKAGER_APP_CRYPTO_FLAGS_H_
12 
13 #include <gflags/gflags.h>
14 
15 DECLARE_string(protection_scheme);
16 DECLARE_bool(vp9_subsample_encryption);
17 
18 #endif // PACKAGER_APP_CRYPTO_FLAGS_H_
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines common command line flags for encryption and decryption, which
+
8 // applies to all key sources, i.e. raw key, Widevine and PlayReady.
+
9 
+
10 #ifndef PACKAGER_APP_CRYPTO_FLAGS_H_
+
11 #define PACKAGER_APP_CRYPTO_FLAGS_H_
+
12 
+
13 #include <gflags/gflags.h>
+
14 
+
15 DECLARE_string(protection_scheme);
+
16 DECLARE_int32(crypt_byte_block);
+
17 DECLARE_int32(skip_byte_block);
+
18 DECLARE_bool(vp9_subsample_encryption);
+
19 DECLARE_string(playready_extra_header_data);
+
20 
+
21 #endif // PACKAGER_APP_CRYPTO_FLAGS_H_
+
diff --git a/docs/d8/d54/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer-members.html b/docs/d8/d54/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer-members.html new file mode 100644 index 0000000000..c52da1eaeb --- /dev/null +++ b/docs/d8/d54/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer-members.html @@ -0,0 +1,120 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::webvtt::WebVttMuxer Member List
+
+
+ +

This is the complete list of members for shaka::media::webvtt::WebVttMuxer, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
Cancel()shaka::media::Muxer
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
clock() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) constshaka::media::MediaHandlerinlineprotected
DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) constshaka::media::MediaHandlerinlineprotected
DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) constshaka::media::MediaHandlerinlineprotected
DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) constshaka::media::MediaHandlerinlineprotected
FlushAllDownstreams()shaka::media::MediaHandlerprotected
FlushDownstream(size_t output_stream_index)shaka::media::MediaHandlerprotected
Initialize()shaka::media::MediaHandler
initialized() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
InitializeInternal() overrideshaka::media::Muxerinlineprotectedvirtual
IsConnected()shaka::media::MediaHandlerinline
MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandler
Muxer(const MuxerOptions &options) (defined in shaka::media::Muxer)shaka::media::Muxerexplicit
muxer_listener() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
next_output_stream_index() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
num_input_streams() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
OnFlushRequest(size_t input_stream_index) overrideshaka::media::Muxerprotectedvirtual
options() const (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
output_handlers() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
Process(std::unique_ptr< StreamData > stream_data) overrideshaka::media::Muxerprotectedvirtual
progress_listener() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
set_clock(base::Clock *clock)shaka::media::Muxerinline
SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandler
SetMuxerListener(std::unique_ptr< MuxerListener > muxer_listener)shaka::media::Muxer
SetProgressListener(std::unique_ptr< ProgressListener > progress_listener)shaka::media::Muxer
streams() const (defined in shaka::media::Muxer)shaka::media::Muxerinline
TextMuxer(const MuxerOptions &options) (defined in shaka::media::TextMuxer)shaka::media::TextMuxerexplicit
ValidateOutputStreamIndex(size_t stream_index) constshaka::media::MediaHandlerprotectedvirtual
WebVttMuxer(const MuxerOptions &options)shaka::media::webvtt::WebVttMuxerexplicit
~MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandlervirtual
~Muxer() (defined in shaka::media::Muxer)shaka::media::Muxervirtual
~TextMuxer() override (defined in shaka::media::TextMuxer)shaka::media::TextMuxer
~WebVttMuxer() override (defined in shaka::media::webvtt::WebVttMuxer)shaka::media::webvtt::WebVttMuxer
+ + + + diff --git a/docs/d8/d5b/structshaka_1_1media_1_1mp4_1_1AudioSampleEntry.html b/docs/d8/d5b/structshaka_1_1media_1_1mp4_1_1AudioSampleEntry.html index 0aab85971a..c62f77afeb 100644 --- a/docs/d8/d5b/structshaka_1_1media_1_1mp4_1_1AudioSampleEntry.html +++ b/docs/d8/d5b/structshaka_1_1media_1_1mp4_1_1AudioSampleEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::AudioSampleEntry Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -133,6 +136,9 @@ uint32_t  + + @@ -148,7 +154,7 @@ Additional Inherited Members

Public Member Functions

samplerate =
EC3Specific dec3
 
+AC4Specific dac4
 
OpusSpecific dops
 

Detailed Description

-

Definition at line 353 of file box_definitions.h.

+

Definition at line 360 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -176,7 +182,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 1841 of file box_definitions.cc.

+

Definition at line 1888 of file box_definitions.cc.

@@ -187,9 +193,7 @@ Additional Inherited Members diff --git a/docs/d8/d61/ac3__audio__util_8cc_source.html b/docs/d8/d61/ac3__audio__util_8cc_source.html index 98c2de0522..9581c135c4 100644 --- a/docs/d8/d61/ac3__audio__util_8cc_source.html +++ b/docs/d8/d61/ac3__audio__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/ac3_audio_util.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
ac3_audio_util.cc
-
1 // Copyright 2018 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/codecs/ac3_audio_util.h"
8 
9 #include "packager/base/strings/string_number_conversions.h"
10 #include "packager/media/base/bit_reader.h"
11 #include "packager/media/base/rcheck.h"
12 
13 namespace shaka {
14 namespace media {
15 
16 namespace {
17 
18 // ASTC Standard A/52:2012 Table 5.8 Audio Coding Mode.
19 const uint8_t kAc3NumChannelsTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
20 
21 bool ExtractAc3Data(const std::vector<uint8_t>& ac3_data,
22  uint8_t* audio_coding_mode,
23  bool* lfe_channel_on) {
24  BitReader bit_reader(ac3_data.data(), ac3_data.size());
25 
26  // fscod: 2 bits
27  // bsid: 5 bits
28  // bsmod: 3 bits
29  // acmod: 3 bits
30  // lfeon: 1 bit
31  // bit_rate_code: 5 bits
32  RCHECK(bit_reader.SkipBits(10));
33  RCHECK(bit_reader.ReadBits(3, audio_coding_mode));
34  RCHECK(bit_reader.ReadBits(1, lfe_channel_on));
35  return true;
36 }
37 
38 } // namespace
39 
40 size_t GetAc3NumChannels(const std::vector<uint8_t>& ac3_data) {
41  uint8_t audio_coding_mode;
42  bool lfe_channel_on;
43  if (!ExtractAc3Data(ac3_data, &audio_coding_mode, &lfe_channel_on)) {
44  LOG(WARNING) << "Seeing invalid AC3 data: "
45  << base::HexEncode(ac3_data.data(), ac3_data.size());
46  return 0;
47  }
48  return kAc3NumChannelsTable[audio_coding_mode] + (lfe_channel_on ? 1 : 0);
49 }
50 
51 } // namespace media
52 } // namespace shaka
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2018 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/codecs/ac3_audio_util.h"
+
8 
+
9 #include "packager/base/strings/string_number_conversions.h"
+
10 #include "packager/media/base/bit_reader.h"
+
11 #include "packager/media/base/rcheck.h"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 
+
16 namespace {
+
17 
+
18 // ASTC Standard A/52:2012 Table 5.8 Audio Coding Mode.
+
19 const uint8_t kAc3NumChannelsTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
+
20 
+
21 bool ExtractAc3Data(const std::vector<uint8_t>& ac3_data,
+
22  uint8_t* audio_coding_mode,
+
23  bool* lfe_channel_on) {
+
24  BitReader bit_reader(ac3_data.data(), ac3_data.size());
+
25 
+
26  // fscod: 2 bits
+
27  // bsid: 5 bits
+
28  // bsmod: 3 bits
+
29  // acmod: 3 bits
+
30  // lfeon: 1 bit
+
31  // bit_rate_code: 5 bits
+
32  RCHECK(bit_reader.SkipBits(10));
+
33  RCHECK(bit_reader.ReadBits(3, audio_coding_mode));
+
34  RCHECK(bit_reader.ReadBits(1, lfe_channel_on));
+
35  return true;
+
36 }
+
37 
+
38 } // namespace
+
39 
+
40 size_t GetAc3NumChannels(const std::vector<uint8_t>& ac3_data) {
+
41  uint8_t audio_coding_mode;
+
42  bool lfe_channel_on;
+
43  if (!ExtractAc3Data(ac3_data, &audio_coding_mode, &lfe_channel_on)) {
+
44  LOG(WARNING) << "Seeing invalid AC3 data: "
+
45  << base::HexEncode(ac3_data.data(), ac3_data.size());
+
46  return 0;
+
47  }
+
48  return kAc3NumChannelsTable[audio_coding_mode] + (lfe_channel_on ? 1 : 0);
+
49 }
+
50 
+
51 } // namespace media
+
52 } // namespace shaka
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d66/classshaka_1_1UdpFile-members.html b/docs/d8/d66/classshaka_1_1UdpFile-members.html index e5842321eb..ea100338c6 100644 --- a/docs/d8/d66/classshaka_1_1UdpFile-members.html +++ b/docs/d8/d66/classshaka_1_1UdpFile-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d8/d6a/classshaka_1_1media_1_1ClusterBuilder-members.html b/docs/d8/d6a/classshaka_1_1media_1_1ClusterBuilder-members.html index c020f8380a..3276cf0075 100644 --- a/docs/d8/d6a/classshaka_1_1media_1_1ClusterBuilder-members.html +++ b/docs/d8/d6a/classshaka_1_1media_1_1ClusterBuilder-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d6d/structshaka_1_1media_1_1mp4_1_1DataInformation.html b/docs/d8/d6d/structshaka_1_1media_1_1mp4_1_1DataInformation.html index 4b9fd4fbcc..2e1fc5a907 100644 --- a/docs/d8/d6d/structshaka_1_1media_1_1mp4_1_1DataInformation.html +++ b/docs/d8/d6d/structshaka_1_1media_1_1mp4_1_1DataInformation.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::DataInformation Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 610 of file box_definitions.h.

+

Definition at line 627 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2115 of file box_definitions.cc.

+

Definition at line 2190 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d8/d6f/origin__handler_8h_source.html b/docs/d8/d6f/origin__handler_8h_source.html index 0b82a60581..b9f2a84a0f 100644 --- a/docs/d8/d6f/origin__handler_8h_source.html +++ b/docs/d8/d6f/origin__handler_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/origin/origin_handler.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
origin_handler.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_ORIGIN_ORIGIN_HANDLER_H_
8 #define PACKAGER_MEDIA_ORIGIN_ORIGIN_HANDLER_H_
9 
10 #include "packager/media/base/media_handler.h"
11 
12 namespace shaka {
13 namespace media {
14 
15 // Origin handlers are handlers that sit at the head of a pipeline (chain of
16 // handlers). They are expect to take input from an alternative source (like
17 // a file or network connection).
18 class OriginHandler : public MediaHandler {
19  public:
20  OriginHandler() = default;
21 
22  // Process all data and send messages down stream. This is the main
23  // method of the handler. Since origin handlers do not take input via
24  // |Process|, run will take input from an alternative source. This call
25  // is expect to be blocking. To exit a call to |Run|, |Cancel| should
26  // be used.
27  virtual Status Run() = 0;
28 
29  // Non-blocking call to the handler, requesting that it exit the
30  // current call to |Run|. The handler should stop processing data
31  // as soon is convenient.
32  virtual void Cancel() = 0;
33 
34  private:
35  OriginHandler(const OriginHandler&) = delete;
36  OriginHandler& operator=(const OriginHandler&) = delete;
37 
38  Status Process(std::unique_ptr<StreamData> stream_data) override;
39 };
40 
41 } // namespace media
42 } // namespace shaka
43 
44 #endif // PACKAGER_MEDIA_ORIGIN_ORIGIN_HANDLER_H_
- -
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_ORIGIN_ORIGIN_HANDLER_H_
+
8 #define PACKAGER_MEDIA_ORIGIN_ORIGIN_HANDLER_H_
+
9 
+
10 #include "packager/media/base/media_handler.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+
15 // Origin handlers are handlers that sit at the head of a pipeline (chain of
+
16 // handlers). They are expect to take input from an alternative source (like
+
17 // a file or network connection).
+
18 class OriginHandler : public MediaHandler {
+
19  public:
+
20  OriginHandler() = default;
+
21 
+
22  // Process all data and send messages down stream. This is the main
+
23  // method of the handler. Since origin handlers do not take input via
+
24  // |Process|, run will take input from an alternative source. This call
+
25  // is expect to be blocking. To exit a call to |Run|, |Cancel| should
+
26  // be used.
+
27  virtual Status Run() = 0;
+
28 
+
29  // Non-blocking call to the handler, requesting that it exit the
+
30  // current call to |Run|. The handler should stop processing data
+
31  // as soon is convenient.
+
32  virtual void Cancel() = 0;
+
33 
+
34  private:
+
35  OriginHandler(const OriginHandler&) = delete;
+
36  OriginHandler& operator=(const OriginHandler&) = delete;
+
37 
+
38  Status Process(std::unique_ptr<StreamData> stream_data) override;
+
39 };
+
40 
+
41 } // namespace media
+
42 } // namespace shaka
+
43 
+
44 #endif // PACKAGER_MEDIA_ORIGIN_ORIGIN_HANDLER_H_
+ + + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d70/structshaka_1_1media_1_1mp4_1_1Metadata-members.html b/docs/d8/d70/structshaka_1_1media_1_1mp4_1_1Metadata-members.html index 86cebe4db6..3bce1ab906 100644 --- a/docs/d8/d70/structshaka_1_1media_1_1mp4_1_1Metadata-members.html +++ b/docs/d8/d70/structshaka_1_1media_1_1mp4_1_1Metadata-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d8/d72/adaptation__set_8h_source.html b/docs/d8/d72/adaptation__set_8h_source.html index 98f3917c4d..a1b2656352 100644 --- a/docs/d8/d72/adaptation__set_8h_source.html +++ b/docs/d8/d72/adaptation__set_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/adaptation_set.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
adaptation_set.h
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
8 
9 #ifndef PACKAGER_MPD_BASE_ADAPTATION_SET_H_
10 #define PACKAGER_MPD_BASE_ADAPTATION_SET_H_
11 
12 #include <stdint.h>
13 
14 #include <list>
15 #include <map>
16 #include <memory>
17 #include <set>
18 #include <vector>
19 
20 #include "packager/base/optional.h"
21 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
22 
23 namespace shaka {
24 
25 class MediaInfo;
26 class Representation;
27 
28 struct ContentProtectionElement;
29 struct MpdOptions;
30 
31 namespace xml {
32 class XmlNode;
33 } // namespace xml
34 
38  public:
39  // The role for this AdaptationSet. These values are used to add a Role
40  // element to the AdaptationSet with schemeIdUri=urn:mpeg:dash:role:2011.
41  // See ISO/IEC 23009-1:2012 section 5.8.5.5.
42  enum Role {
43  kRoleUnknown,
44  kRoleCaption,
45  kRoleSubtitle,
46  kRoleMain,
47  kRoleAlternate,
48  kRoleSupplementary,
49  kRoleCommentary,
50  kRoleDub
51  };
52 
53  virtual ~AdaptationSet();
54 
61  virtual Representation* AddRepresentation(const MediaInfo& media_info);
62 
69  virtual Representation* CopyRepresentation(
70  const Representation& representation);
71 
81  virtual void AddContentProtectionElement(
82  const ContentProtectionElement& element);
83 
95  virtual void UpdateContentProtectionPssh(const std::string& drm_uuid,
96  const std::string& pssh);
97 
102  virtual void AddAccessibility(const std::string& scheme,
103  const std::string& value);
104 
109  virtual void AddRole(Role role);
110 
115  xml::scoped_xml_ptr<xmlNode> GetXml();
116 
122  virtual void ForceSetSegmentAlignment(bool segment_alignment);
123 
126  virtual void AddAdaptationSetSwitching(const AdaptationSet* adaptation_set);
127 
129  bool has_id() const { return static_cast<bool>(id_); }
130 
131  // Must be unique in the Period.
132  uint32_t id() const { return id_.value(); }
133 
136  void set_id(uint32_t id) { id_ = id; }
137 
149  void OnNewSegmentForRepresentation(uint32_t representation_id,
150  uint64_t start_time,
151  uint64_t duration);
152 
165  void OnSetFrameRateForRepresentation(uint32_t representation_id,
166  uint32_t frame_duration,
167  uint32_t timescale);
168 
171  virtual void AddTrickPlayReference(const AdaptationSet* adaptation_set);
172 
173  // Return the list of Representations in this AdaptationSet.
174  const std::list<Representation*> GetRepresentations() const;
175 
177  bool IsVideo() const;
178 
179  protected:
186  AdaptationSet(const std::string& language,
187  const MpdOptions& mpd_options,
188  uint32_t* representation_counter);
189 
190  private:
191  AdaptationSet(const AdaptationSet&) = delete;
192  AdaptationSet& operator=(const AdaptationSet&) = delete;
193 
194  friend class Period;
195  friend class AdaptationSetTest;
196 
197  // kSegmentAlignmentUnknown means that it is uncertain if the
198  // (sub)segments are aligned or not.
199  // kSegmentAlignmentTrue means that it is certain that the all the (current)
200  // segments added to the adaptation set are aligned.
201  // kSegmentAlignmentFalse means that it is it is certain that some segments
202  // are not aligned. This is useful to disable the computation for
203  // segment alignment, once it is certain that some segments are not aligned.
204  enum SegmentAligmentStatus {
205  kSegmentAlignmentUnknown,
206  kSegmentAlignmentTrue,
207  kSegmentAlignmentFalse
208  };
209 
210  // This maps Representations (IDs) to a list of start times of the segments.
211  // e.g.
212  // If Representation 1 has start time 0, 100, 200 and Representation 2 has
213  // start times 0, 200, 400, then the map contains:
214  // 1 -> [0, 100, 200]
215  // 2 -> [0, 200, 400]
216  typedef std::map<uint32_t, std::list<uint64_t>> RepresentationTimeline;
217 
218  // Update AdaptationSet attributes for new MediaInfo.
219  void UpdateFromMediaInfo(const MediaInfo& media_info);
220 
229  void CheckDynamicSegmentAlignment(uint32_t representation_id,
230  uint64_t start_time,
231  uint64_t duration);
232 
233  // Checks representation_segment_start_times_ and sets segments_aligned_.
234  // Use this for static MPD, do not use for dynamic MPD.
235  void CheckStaticSegmentAlignment();
236 
237  // Records the framerate of a Representation.
238  void RecordFrameRate(uint32_t frame_duration, uint32_t timescale);
239 
240  std::list<ContentProtectionElement> content_protection_elements_;
241  // representation_id => Representation map. It also keeps the representations_
242  // sorted by default.
243  std::map<uint32_t, std::unique_ptr<Representation>> representation_map_;
244 
245  uint32_t* const representation_counter_;
246 
247  base::Optional<uint32_t> id_;
248  const std::string language_;
249  const MpdOptions& mpd_options_;
250 
251  // An array of adaptation sets this adaptation set can switch to.
252  std::vector<const AdaptationSet*> switchable_adaptation_sets_;
253 
254  // Video widths and heights of Representations. Note that this is a set; if
255  // there is only 1 resolution, then @width & @height should be set, otherwise
256  // @maxWidth & @maxHeight should be set for DASH IOP.
257  std::set<uint32_t> video_widths_;
258  std::set<uint32_t> video_heights_;
259 
260  // Video representations' frame rates.
261  // The frame rate notation for MPD is <integer>/<integer> (where the
262  // denominator is optional). This means the frame rate could be non-whole
263  // rational value, therefore the key is of type double.
264  // Value is <integer>/<integer> in string form.
265  // So, key == CalculatedValue(value)
266  std::map<double, std::string> video_frame_rates_;
267 
268  // contentType attribute of AdaptationSet.
269  // Determined by examining the MediaInfo passed to AddRepresentation().
270  std::string content_type_;
271 
272  // This does not have to be a set, it could be a list or vector because all we
273  // really care is whether there is more than one entry.
274  // Contains one entry if all the Representations have the same picture aspect
275  // ratio (@par attribute for AdaptationSet).
276  // There will be more than one entry if there are multiple picture aspect
277  // ratios.
278  // The @par attribute should only be set if there is exactly one entry
279  // in this set.
280  std::set<std::string> picture_aspect_ratio_;
281 
282  // accessibilities of this AdaptationSet.
283  struct Accessibility {
284  std::string scheme;
285  std::string value;
286  };
287  std::vector<Accessibility> accessibilities_;
288 
289  // The roles of this AdaptationSet.
290  std::set<Role> roles_;
291 
292  // True iff all the segments are aligned.
293  SegmentAligmentStatus segments_aligned_;
294  bool force_set_segment_alignment_;
295 
296  // Keeps track of segment start times of Representations.
297  // For static MPD, this will not be cleared, all the segment start times are
298  // stored in this. This should not out-of-memory for a reasonable length
299  // video and reasonable subsegment length.
300  // For dynamic MPD, the entries are deleted (see
301  // CheckDynamicSegmentAlignment() implementation comment) because storing the
302  // entire timeline is not reasonable and may cause an out-of-memory problem.
303  RepresentationTimeline representation_segment_start_times_;
304 
305  // Record the original AdaptationSets the trick play stream belongs to. There
306  // can be more than one reference AdaptationSets as multiple streams e.g. SD
307  // and HD videos in different AdaptationSets can share the same trick play
308  // stream.
309  std::vector<const AdaptationSet*> trick_play_references_;
310 };
311 
312 } // namespace shaka
313 
314 #endif // PACKAGER_MPD_BASE_ADAPTATION_SET_H_
- -
All the methods that are virtual are virtual for mocking.
- - -
Defines Mpd Options.
Definition: mpd_options.h:25
-
void set_id(uint32_t id)
- +
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
8 
+
9 #ifndef PACKAGER_MPD_BASE_ADAPTATION_SET_H_
+
10 #define PACKAGER_MPD_BASE_ADAPTATION_SET_H_
+
11 
+
12 #include <stdint.h>
+
13 
+
14 #include <list>
+
15 #include <map>
+
16 #include <memory>
+
17 #include <set>
+
18 #include <vector>
+
19 
+
20 #include "packager/base/optional.h"
+
21 #include "packager/mpd/base/xml/xml_node.h"
+
22 
+
23 namespace shaka {
+
24 
+
25 class MediaInfo;
+
26 class Representation;
+
27 
+
28 struct ContentProtectionElement;
+
29 struct MpdOptions;
+
30 
+ +
34  public:
+
35  // The role for this AdaptationSet. These values are used to add a Role
+
36  // element to the AdaptationSet with schemeIdUri=urn:mpeg:dash:role:2011.
+
37  // See ISO/IEC 23009-1:2012 section 5.8.5.5.
+
38  enum Role {
+
39  kRoleUnknown,
+
40  kRoleCaption,
+
41  kRoleSubtitle,
+
42  kRoleMain,
+
43  kRoleAlternate,
+
44  kRoleSupplementary,
+
45  kRoleCommentary,
+
46  kRoleDub
+
47  };
+
48 
+
49  virtual ~AdaptationSet();
+
50 
+
57  virtual Representation* AddRepresentation(const MediaInfo& media_info);
+
58 
+ +
66  const Representation& representation);
+
67 
+
77  virtual void AddContentProtectionElement(
+
78  const ContentProtectionElement& element);
+
79 
+
91  virtual void UpdateContentProtectionPssh(const std::string& drm_uuid,
+
92  const std::string& pssh);
+
93 
+
98  virtual void AddAccessibility(const std::string& scheme,
+
99  const std::string& value);
+
100 
+
105  virtual void AddRole(Role role);
+
106 
+
111  base::Optional<xml::XmlNode> GetXml();
+
112 
+
118  virtual void ForceSetSegmentAlignment(bool segment_alignment);
+
119 
+
122  virtual void AddAdaptationSetSwitching(const AdaptationSet* adaptation_set);
+
123 
+
125  bool has_id() const { return static_cast<bool>(id_); }
+
126 
+
127  // Must be unique in the Period.
+
128  uint32_t id() const { return id_.value(); }
+
129 
+
132  void set_id(uint32_t id) { id_ = id; }
+
133 
+
145  void OnNewSegmentForRepresentation(uint32_t representation_id,
+
146  uint64_t start_time,
+
147  uint64_t duration);
+
148 
+
161  void OnSetFrameRateForRepresentation(uint32_t representation_id,
+
162  uint32_t frame_duration,
+
163  uint32_t timescale);
+
164 
+
167  virtual void AddTrickPlayReference(const AdaptationSet* adaptation_set);
+
168 
+
169  // Return the list of Representations in this AdaptationSet.
+
170  const std::list<Representation*> GetRepresentations() const;
+
171 
+
173  bool IsVideo() const;
+
174 
+
176  const std::string& codec() const { return codec_; }
+
177 
+
180  void set_codec(const std::string& codec) { codec_ = codec; };
+
181 
+
182  protected:
+
189  AdaptationSet(const std::string& language,
+
190  const MpdOptions& mpd_options,
+
191  uint32_t* representation_counter);
+
192 
+
193  private:
+
194  AdaptationSet(const AdaptationSet&) = delete;
+
195  AdaptationSet& operator=(const AdaptationSet&) = delete;
+
196 
+
197  friend class Period;
+
198  friend class AdaptationSetTest;
+
199 
+
200  // kSegmentAlignmentUnknown means that it is uncertain if the
+
201  // (sub)segments are aligned or not.
+
202  // kSegmentAlignmentTrue means that it is certain that the all the (current)
+
203  // segments added to the adaptation set are aligned.
+
204  // kSegmentAlignmentFalse means that it is it is certain that some segments
+
205  // are not aligned. This is useful to disable the computation for
+
206  // segment alignment, once it is certain that some segments are not aligned.
+
207  enum SegmentAligmentStatus {
+
208  kSegmentAlignmentUnknown,
+
209  kSegmentAlignmentTrue,
+
210  kSegmentAlignmentFalse
+
211  };
+
212 
+
213  // This maps Representations (IDs) to a list of start times of the segments.
+
214  // e.g.
+
215  // If Representation 1 has start time 0, 100, 200 and Representation 2 has
+
216  // start times 0, 200, 400, then the map contains:
+
217  // 1 -> [0, 100, 200]
+
218  // 2 -> [0, 200, 400]
+
219  typedef std::map<uint32_t, std::list<uint64_t>> RepresentationTimeline;
+
220 
+
221  // Update AdaptationSet attributes for new MediaInfo.
+
222  void UpdateFromMediaInfo(const MediaInfo& media_info);
+
223 
+
232  void CheckDynamicSegmentAlignment(uint32_t representation_id,
+
233  uint64_t start_time,
+
234  uint64_t duration);
+
235 
+
236  // Checks representation_segment_start_times_ and sets segments_aligned_.
+
237  // Use this for static MPD, do not use for dynamic MPD.
+
238  void CheckStaticSegmentAlignment();
+
239 
+
240  // Records the framerate of a Representation.
+
241  void RecordFrameRate(uint32_t frame_duration, uint32_t timescale);
+
242 
+
243  std::list<ContentProtectionElement> content_protection_elements_;
+
244  // representation_id => Representation map. It also keeps the representations_
+
245  // sorted by default.
+
246  std::map<uint32_t, std::unique_ptr<Representation>> representation_map_;
+
247 
+
248  uint32_t* const representation_counter_;
+
249 
+
250  base::Optional<uint32_t> id_;
+
251  const std::string language_;
+
252  const MpdOptions& mpd_options_;
+
253 
+
254  // An array of adaptation sets this adaptation set can switch to.
+
255  std::vector<const AdaptationSet*> switchable_adaptation_sets_;
+
256 
+
257  // Video widths and heights of Representations. Note that this is a set; if
+
258  // there is only 1 resolution, then @width & @height should be set, otherwise
+
259  // @maxWidth & @maxHeight should be set for DASH IOP.
+
260  std::set<uint32_t> video_widths_;
+
261  std::set<uint32_t> video_heights_;
+
262 
+
263  // Video representations' frame rates.
+
264  // The frame rate notation for MPD is <integer>/<integer> (where the
+
265  // denominator is optional). This means the frame rate could be non-whole
+
266  // rational value, therefore the key is of type double.
+
267  // Value is <integer>/<integer> in string form.
+
268  // So, key == CalculatedValue(value)
+
269  std::map<double, std::string> video_frame_rates_;
+
270 
+
271  // contentType attribute of AdaptationSet.
+
272  // Determined by examining the MediaInfo passed to AddRepresentation().
+
273  std::string content_type_;
+
274 
+
275  // Codec of AdaptationSet.
+
276  std::string codec_;
+
277 
+
278  // This does not have to be a set, it could be a list or vector because all we
+
279  // really care is whether there is more than one entry.
+
280  // Contains one entry if all the Representations have the same picture aspect
+
281  // ratio (@par attribute for AdaptationSet).
+
282  // There will be more than one entry if there are multiple picture aspect
+
283  // ratios.
+
284  // The @par attribute should only be set if there is exactly one entry
+
285  // in this set.
+
286  std::set<std::string> picture_aspect_ratio_;
+
287 
+
288  // accessibilities of this AdaptationSet.
+
289  struct Accessibility {
+
290  std::string scheme;
+
291  std::string value;
+
292  };
+
293  std::vector<Accessibility> accessibilities_;
+
294 
+
295  // The roles of this AdaptationSet.
+
296  std::set<Role> roles_;
+
297 
+
298  // True iff all the segments are aligned.
+
299  SegmentAligmentStatus segments_aligned_;
+
300  bool force_set_segment_alignment_;
+
301 
+
302  // Keeps track of segment start times of Representations.
+
303  // For static MPD, this will not be cleared, all the segment start times are
+
304  // stored in this. This should not out-of-memory for a reasonable length
+
305  // video and reasonable subsegment length.
+
306  // For dynamic MPD, the entries are deleted (see
+
307  // CheckDynamicSegmentAlignment() implementation comment) because storing the
+
308  // entire timeline is not reasonable and may cause an out-of-memory problem.
+
309  RepresentationTimeline representation_segment_start_times_;
+
310 
+
311  // Record the original AdaptationSets the trick play stream belongs to. There
+
312  // can be more than one reference AdaptationSets as multiple streams e.g. SD
+
313  // and HD videos in different AdaptationSets can share the same trick play
+
314  // stream.
+
315  std::vector<const AdaptationSet*> trick_play_references_;
+
316 };
+
317 
+
318 } // namespace shaka
+
319 
+
320 #endif // PACKAGER_MPD_BASE_ADAPTATION_SET_H_
+ +
virtual Representation * AddRepresentation(const MediaInfo &media_info)
+
virtual void AddAccessibility(const std::string &scheme, const std::string &value)
+
base::Optional< xml::XmlNode > GetXml()
+
virtual void AddContentProtectionElement(const ContentProtectionElement &element)
+
void OnSetFrameRateForRepresentation(uint32_t representation_id, uint32_t frame_duration, uint32_t timescale)
+
virtual void ForceSetSegmentAlignment(bool segment_alignment)
+
const std::string & codec() const
+
virtual Representation * CopyRepresentation(const Representation &representation)
+ +
virtual void AddTrickPlayReference(const AdaptationSet *adaptation_set)
+
virtual void AddAdaptationSetSwitching(const AdaptationSet *adaptation_set)
+
AdaptationSet(const std::string &language, const MpdOptions &mpd_options, uint32_t *representation_counter)
+ +
void set_codec(const std::string &codec)
+
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
+
virtual void AddRole(Role role)
+
void set_id(uint32_t id)
+
void OnNewSegmentForRepresentation(uint32_t representation_id, uint64_t start_time, uint64_t duration)
+ + +
All the methods that are virtual are virtual for mocking.
+ +
Defines Mpd Options.
Definition: mpd_options.h:25
diff --git a/docs/d8/d74/classshaka_1_1media_1_1TracksBuilder.html b/docs/d8/d74/classshaka_1_1media_1_1TracksBuilder.html index fc3e27e423..7ca8c03b87 100644 --- a/docs/d8/d74/classshaka_1_1media_1_1TracksBuilder.html +++ b/docs/d8/d74/classshaka_1_1media_1_1TracksBuilder.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::TracksBuilder Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d8/d81/classshaka_1_1LocalFile-members.html b/docs/d8/d81/classshaka_1_1LocalFile-members.html index d87265cea1..020dd7d012 100644 --- a/docs/d8/d81/classshaka_1_1LocalFile-members.html +++ b/docs/d8/d81/classshaka_1_1LocalFile-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d86/classshaka_1_1media_1_1WebMTracksParser.html b/docs/d8/d86/classshaka_1_1media_1_1WebMTracksParser.html index 1453848d66..e651934fa5 100644 --- a/docs/d8/d86/classshaka_1_1media_1_1WebMTracksParser.html +++ b/docs/d8/d86/classshaka_1_1media_1_1WebMTracksParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMTracksParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::WebMParserClient - -
+ + @@ -206,9 +209,7 @@ The number of bytes parsed on success. diff --git a/docs/d8/d88/structshaka_1_1media_1_1mp4_1_1MovieExtends-members.html b/docs/d8/d88/structshaka_1_1media_1_1mp4_1_1MovieExtends-members.html index d83021720a..52e493e518 100644 --- a/docs/d8/d88/structshaka_1_1media_1_1mp4_1_1MovieExtends-members.html +++ b/docs/d8/d88/structshaka_1_1media_1_1mp4_1_1MovieExtends-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

Public Types

- + +/* @license-end */
diff --git a/docs/d8/d8e/classshaka_1_1AdaptationSet.html b/docs/d8/d8e/classshaka_1_1AdaptationSet.html index 19e4be76c3..ce153117f5 100644 --- a/docs/d8/d8e/classshaka_1_1AdaptationSet.html +++ b/docs/d8/d8e/classshaka_1_1AdaptationSet.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::AdaptationSet Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::MockAdaptationSet - -
+ + @@ -115,8 +118,8 @@ Public Member Functions - - + + @@ -139,6 +142,10 @@ const std::list< + + + +

Public Types

enum  Role {
-  kRoleUnknown, -kRoleCaption, -kRoleSubtitle, -kRoleMain, -
-  kRoleAlternate, -kRoleSupplementary, -kRoleCommentary, -kRoleDub +  kRoleUnknown +, kRoleCaption +, kRoleSubtitle +, kRoleMain +,
+  kRoleAlternate +, kRoleSupplementary +, kRoleCommentary +, kRoleDub
}
 
 
virtual void AddRole (Role role)
 
xml::scoped_xml_ptr< xmlNode > GetXml ()
 
base::Optional< xml::XmlNodeGetXml ()
 
virtual void ForceSetSegmentAlignment (bool segment_alignment)
 
virtual void AddAdaptationSetSwitching (const AdaptationSet *adaptation_set)
 
bool IsVideo () const
 
const std::string & codec () const
 
void set_codec (const std::string &codec)
 
@@ -157,7 +164,7 @@ class 

Protected Member Functions

AdaptationSetTest

Detailed Description

AdaptationSet class provides methods to add Representations and <ContentProtection> elements to the AdaptationSet element.

-

Definition at line 37 of file adaptation_set.h.

+

Definition at line 33 of file adaptation_set.h.

Constructor & Destructor Documentation

◆ AdaptationSet()

@@ -288,7 +295,7 @@ class 
AdaptationSetTest -

Definition at line 353 of file adaptation_set.cc.

+

Definition at line 382 of file adaptation_set.cc.

@@ -425,7 +432,35 @@ class 
AdaptationSetTest -

Definition at line 381 of file adaptation_set.cc.

+

Definition at line 410 of file adaptation_set.cc.

+ + + + +

◆ codec()

+ +
+
+ + + + + +
+ + + + + + + +
const std::string& shaka::AdaptationSet::codec () const
+
+inline
+
+
Returns
codec.
+ +

Definition at line 176 of file adaptation_set.h.

@@ -494,18 +529,18 @@ class 
AdaptationSetTest -

Definition at line 347 of file adaptation_set.cc.

+

Definition at line 376 of file adaptation_set.cc.

- -

◆ GetXml()

+ +

◆ GetXml()

- + @@ -542,7 +577,7 @@ class 
xml::scoped_xml_ptr< xmlNode > shaka::AdaptationSet::GetXml base::Optional< xml::XmlNode > shaka::AdaptationSet::GetXml ( ) AdaptationSetTest
Returns
true if id is set, false otherwise.
-

Definition at line 129 of file adaptation_set.h.

+

Definition at line 125 of file adaptation_set.h.

@@ -562,7 +597,7 @@ class 
AdaptationSetTest
Returns
true if it is a video AdaptationSet.
-

Definition at line 393 of file adaptation_set.cc.

+

Definition at line 422 of file adaptation_set.cc.

@@ -606,7 +641,7 @@ class 
AdaptationSetTest -

Definition at line 364 of file adaptation_set.cc.

+

Definition at line 393 of file adaptation_set.cc.

@@ -643,13 +678,47 @@ class 
AdaptationSetTest

Notifies the AdaptationSet instance that the sample duration for the Representation was set. The frame duration for a video Representation might not be specified when a Representation is created (by calling AddRepresentation()). This should be used to notify this instance that the frame rate for a Represenatation has been set. This method is called automatically when Represenatation::SetSampleDuration() is called if the Represenatation instance was created using AddRepresentation().

Parameters
- +
representation_idis the id of the Representation. is the duration of a frame in the Representation.
representation_idis the id of the Representation. @frame_duration is the duration of a frame in the Representation.
timescaleis the timescale of the Representation.
-

Definition at line 375 of file adaptation_set.cc.

+

Definition at line 404 of file adaptation_set.cc.

+ +
+ + +

◆ set_codec()

+ +
+
+ + + + + +
+ + + + + + + + +
void shaka::AdaptationSet::set_codec (const std::string & codec)
+
+inline
+
+

Set AdaptationSet@codec.

Parameters
+ + +
codecis the new codec to be set.
+
+
+ +

Definition at line 180 of file adaptation_set.h.

@@ -676,14 +745,14 @@ class 
AdaptationSetTest
-

Set AdaptationSet.

Parameters
+

Set AdaptationSet@id.

Parameters
idis the new ID to be set.
-

Definition at line 136 of file adaptation_set.h.

+

Definition at line 132 of file adaptation_set.h.

@@ -740,9 +809,7 @@ class 
AdaptationSetTest diff --git a/docs/d8/d91/classshaka_1_1media_1_1AesCtrEncryptor-members.html b/docs/d8/d91/classshaka_1_1media_1_1AesCtrEncryptor-members.html index dca71096fe..e1d896cc90 100644 --- a/docs/d8/d91/classshaka_1_1media_1_1AesCtrEncryptor-members.html +++ b/docs/d8/d91/classshaka_1_1media_1_1AesCtrEncryptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d8/d92/classshaka_1_1media_1_1AesRequestSigner-members.html b/docs/d8/d92/classshaka_1_1media_1_1AesRequestSigner-members.html index 5f0fedc064..985f28a229 100644 --- a/docs/d8/d92/classshaka_1_1media_1_1AesRequestSigner-members.html +++ b/docs/d8/d92/classshaka_1_1media_1_1AesRequestSigner-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d92/structshaka_1_1media_1_1H264DecRefPicMarking-members.html b/docs/d8/d92/structshaka_1_1media_1_1H264DecRefPicMarking-members.html index 95b7f1918b..d56c46c1e3 100644 --- a/docs/d8/d92/structshaka_1_1media_1_1H264DecRefPicMarking-members.html +++ b/docs/d8/d92/structshaka_1_1media_1_1H264DecRefPicMarking-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d93/structshaka_1_1media_1_1mp4_1_1SubtitleMediaHeader-members.html b/docs/d8/d93/structshaka_1_1media_1_1mp4_1_1SubtitleMediaHeader-members.html index ee41da09ef..ca112a3de5 100644 --- a/docs/d8/d93/structshaka_1_1media_1_1mp4_1_1SubtitleMediaHeader-members.html +++ b/docs/d8/d93/structshaka_1_1media_1_1mp4_1_1SubtitleMediaHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d94/pes__packet_8h_source.html b/docs/d8/d94/pes__packet_8h_source.html index 632f99d557..74061177d0 100644 --- a/docs/d8/d94/pes__packet_8h_source.html +++ b/docs/d8/d94/pes__packet_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/pes_packet.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
pes_packet.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_H_
8 #define PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_H_
9 
10 #include <stdint.h>
11 #include <vector>
12 
13 #include "packager/base/macros.h"
14 
15 namespace shaka {
16 namespace media {
17 namespace mp2t {
18 
20 class PesPacket {
21  public:
22  PesPacket();
23  ~PesPacket();
24 
26  uint8_t stream_id() const { return stream_id_; }
28  void set_stream_id(uint8_t stream_id) { stream_id_ = stream_id; }
29 
31  bool has_dts() const { return dts_ >= 0; }
33  bool has_pts() const { return pts_ >= 0; }
34 
36  int64_t dts() const { return dts_; }
38  void set_dts(int64_t dts) {
39  dts_ = dts;
40  }
41 
43  int64_t pts() const { return pts_; }
45  void set_pts(int64_t pts) {
46  pts_ = pts;
47  }
48 
50  bool is_key_frame() const { return is_key_frame_; }
52  void set_is_key_frame(bool is_key_frame) { is_key_frame_ = is_key_frame; }
53 
54  const std::vector<uint8_t>& data() const { return data_; }
56  std::vector<uint8_t>* mutable_data() { return &data_; }
57 
58  private:
59  uint8_t stream_id_ = 0;
60 
61  // These values mean "not set" when the value is less than 0.
62  int64_t dts_ = -1;
63  int64_t pts_ = -1;
64  bool is_key_frame_ = false;
65 
66  std::vector<uint8_t> data_;
67 
68  DISALLOW_COPY_AND_ASSIGN(PesPacket);
69 };
70 
71 } // namespace mp2t
72 } // namespace media
73 } // namespace shaka
74 
75 #endif // PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_H_
- -
void set_stream_id(uint8_t stream_id)
Definition: pes_packet.h:28
-
All the methods that are virtual are virtual for mocking.
- -
void set_pts(int64_t pts)
Definition: pes_packet.h:45
- -
void set_dts(int64_t dts)
Definition: pes_packet.h:38
-
Class that carries PES packet information.
Definition: pes_packet.h:20
-
uint8_t stream_id() const
Definition: pes_packet.h:26
- -
void set_is_key_frame(bool is_key_frame)
Definition: pes_packet.h:52
-
std::vector< uint8_t > * mutable_data()
Definition: pes_packet.h:56
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_H_
+
8 #define PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <vector>
+
12 
+
13 #include "packager/base/macros.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 namespace mp2t {
+
18 
+
20 class PesPacket {
+
21  public:
+
22  PesPacket();
+
23  ~PesPacket();
+
24 
+
26  uint8_t stream_id() const { return stream_id_; }
+
28  void set_stream_id(uint8_t stream_id) { stream_id_ = stream_id; }
+
29 
+
31  bool has_dts() const { return dts_ >= 0; }
+
33  bool has_pts() const { return pts_ >= 0; }
+
34 
+
36  int64_t dts() const { return dts_; }
+
38  void set_dts(int64_t dts) {
+
39  dts_ = dts;
+
40  }
+
41 
+
43  int64_t pts() const { return pts_; }
+
45  void set_pts(int64_t pts) {
+
46  pts_ = pts;
+
47  }
+
48 
+
50  bool is_key_frame() const { return is_key_frame_; }
+
52  void set_is_key_frame(bool is_key_frame) { is_key_frame_ = is_key_frame; }
+
53 
+
54  const std::vector<uint8_t>& data() const { return data_; }
+
56  std::vector<uint8_t>* mutable_data() { return &data_; }
+
57 
+
58  private:
+
59  uint8_t stream_id_ = 0;
+
60 
+
61  // These values mean "not set" when the value is less than 0.
+
62  int64_t dts_ = -1;
+
63  int64_t pts_ = -1;
+
64  bool is_key_frame_ = false;
+
65 
+
66  std::vector<uint8_t> data_;
+
67 
+
68  DISALLOW_COPY_AND_ASSIGN(PesPacket);
+
69 };
+
70 
+
71 } // namespace mp2t
+
72 } // namespace media
+
73 } // namespace shaka
+
74 
+
75 #endif // PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_H_
+
Class that carries PES packet information.
Definition: pes_packet.h:20
+ +
void set_pts(int64_t pts)
Definition: pes_packet.h:45
+ +
uint8_t stream_id() const
Definition: pes_packet.h:26
+
void set_is_key_frame(bool is_key_frame)
Definition: pes_packet.h:52
+
std::vector< uint8_t > * mutable_data()
Definition: pes_packet.h:56
+
void set_dts(int64_t dts)
Definition: pes_packet.h:38
+ + +
void set_stream_id(uint8_t stream_id)
Definition: pes_packet.h:28
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/dc6/classshaka_1_1media_1_1PeekingReader.html b/docs/d8/d99/structshaka_1_1media_1_1TextNumber.html similarity index 54% rename from docs/d8/dc6/classshaka_1_1media_1_1PeekingReader.html rename to docs/d8/d99/structshaka_1_1media_1_1TextNumber.html index c997758fd8..90e2a8466a 100644 --- a/docs/d8/dc6/classshaka_1_1media_1_1PeekingReader.html +++ b/docs/d8/d99/structshaka_1_1media_1_1TextNumber.html @@ -1,11 +1,11 @@ - + - + -Shaka Packager SDK: shaka::media::PeekingReader Class Reference +Shaka Packager SDK: shaka::media::TextNumber Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
-
shaka::media::PeekingReader Class Reference
+
shaka::media::TextNumber Struct Reference
- - - - - - + + +

Public Member Functions

PeekingReader (std::unique_ptr< FileReader > source)
 
-bool Peek (char *out)
 
-bool Next (char *out)
 
TextNumber (float value, TextUnitType type)
 
+ + + + +

+Public Attributes

+float value
 
+TextUnitType type
 

Detailed Description

-

Definition at line 46 of file text_readers.h.

-

The documentation for this class was generated from the following files:

The documentation for this struct was generated from the following file: diff --git a/docs/d8/d99/structshaka_1_1media_1_1mp4_1_1VTTAdditionalTextBox-members.html b/docs/d8/d99/structshaka_1_1media_1_1mp4_1_1VTTAdditionalTextBox-members.html index 1fc2dd4ea1..e5ace83a74 100644 --- a/docs/d8/d99/structshaka_1_1media_1_1mp4_1_1VTTAdditionalTextBox-members.html +++ b/docs/d8/d99/structshaka_1_1media_1_1mp4_1_1VTTAdditionalTextBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/d9a/fragmenter_8cc_source.html b/docs/d8/d9a/fragmenter_8cc_source.html index 84161cce4a..e836b11936 100644 --- a/docs/d8/d9a/fragmenter_8cc_source.html +++ b/docs/d8/d9a/fragmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/fragmenter.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
fragmenter.cc
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/mp4/fragmenter.h"
8 
9 #include <algorithm>
10 #include <limits>
11 
12 #include "packager/media/base/audio_stream_info.h"
13 #include "packager/media/base/buffer_writer.h"
14 #include "packager/media/base/media_sample.h"
15 #include "packager/media/formats/mp4/box_definitions.h"
16 #include "packager/media/formats/mp4/key_frame_info.h"
17 #include "packager/status_macros.h"
18 
19 namespace shaka {
20 namespace media {
21 namespace mp4 {
22 
23 namespace {
24 const int64_t kInvalidTime = std::numeric_limits<int64_t>::max();
25 
26 int64_t GetSeekPreroll(const StreamInfo& stream_info) {
27  if (stream_info.stream_type() != kStreamAudio)
28  return 0;
29  const AudioStreamInfo& audio_stream_info =
30  static_cast<const AudioStreamInfo&>(stream_info);
31  return audio_stream_info.seek_preroll_ns();
32 }
33 
34 void NewSampleEncryptionEntry(const DecryptConfig& decrypt_config,
35  bool use_constant_iv,
36  TrackFragment* traf) {
37  SampleEncryption& sample_encryption = traf->sample_encryption;
38  SampleEncryptionEntry sample_encryption_entry;
39  if (!use_constant_iv)
40  sample_encryption_entry.initialization_vector = decrypt_config.iv();
41  sample_encryption_entry.subsamples = decrypt_config.subsamples();
42  sample_encryption.sample_encryption_entries.push_back(
43  sample_encryption_entry);
44  traf->auxiliary_size.sample_info_sizes.push_back(
45  sample_encryption_entry.ComputeSize());
46 }
47 
48 } // namespace
49 
50 Fragmenter::Fragmenter(std::shared_ptr<const StreamInfo> stream_info,
51  TrackFragment* traf,
52  int64_t edit_list_offset)
53  : stream_info_(std::move(stream_info)),
54  traf_(traf),
55  edit_list_offset_(edit_list_offset),
56  seek_preroll_(GetSeekPreroll(*stream_info_)),
57  earliest_presentation_time_(kInvalidTime),
58  first_sap_time_(kInvalidTime) {
59  DCHECK(stream_info_);
60  DCHECK(traf);
61 }
62 
63 Fragmenter::~Fragmenter() {}
64 
66  const int64_t pts = sample.pts();
67  const int64_t dts = sample.dts();
68  const int64_t duration = sample.duration();
69  if (duration == 0)
70  LOG(WARNING) << "Unexpected sample with zero duration @ dts " << dts;
71 
72  if (!fragment_initialized_)
73  RETURN_IF_ERROR(InitializeFragment(dts));
74 
75  if (sample.side_data_size() > 0)
76  LOG(WARNING) << "MP4 samples do not support side data. Side data ignored.";
77 
78  // Fill in sample parameters. It will be optimized later.
79  traf_->runs[0].sample_sizes.push_back(
80  static_cast<uint32_t>(sample.data_size()));
81  traf_->runs[0].sample_durations.push_back(duration);
82  traf_->runs[0].sample_flags.push_back(
83  sample.is_key_frame() ? 0 : TrackFragmentHeader::kNonKeySampleMask);
84 
85  if (sample.decrypt_config()) {
86  NewSampleEncryptionEntry(
87  *sample.decrypt_config(),
88  !stream_info_->encryption_config().constant_iv.empty(), traf_);
89  }
90 
91  if (stream_info_->stream_type() == StreamType::kStreamVideo &&
92  sample.is_key_frame()) {
93  key_frame_infos_.push_back(
94  {static_cast<uint64_t>(pts), data_->Size(), sample.data_size()});
95  }
96 
97  data_->AppendArray(sample.data(), sample.data_size());
98 
99  traf_->runs[0].sample_composition_time_offsets.push_back(pts - dts);
100  if (pts != dts)
101  traf_->runs[0].flags |= TrackFragmentRun::kSampleCompTimeOffsetsPresentMask;
102 
103  // Exclude the part of sample with negative pts out of duration calculation as
104  // they are not presented.
105  if (pts < 0) {
106  const int64_t end_pts = pts + duration;
107  if (end_pts > 0) {
108  // Include effective presentation duration.
109  fragment_duration_ += end_pts;
110 
111  earliest_presentation_time_ = 0;
112  if (sample.is_key_frame())
113  first_sap_time_ = 0;
114  }
115  } else {
116  fragment_duration_ += duration;
117 
118  if (earliest_presentation_time_ > pts)
119  earliest_presentation_time_ = pts;
120 
121  if (sample.is_key_frame()) {
122  if (first_sap_time_ == kInvalidTime)
123  first_sap_time_ = pts;
124  }
125  }
126  return Status::OK;
127 }
128 
129 Status Fragmenter::InitializeFragment(int64_t first_sample_dts) {
130  fragment_initialized_ = true;
131  fragment_finalized_ = false;
132 
133  // |first_sample_dts| is adjusted by the edit list offset. The offset should
134  // be un-applied in |decode_time|, so when applying the Edit List, the result
135  // dts is |first_sample_dts|.
136  const int64_t dts_before_edit = first_sample_dts + edit_list_offset_;
137  traf_->decode_time.decode_time = dts_before_edit;
138 
139  traf_->runs.clear();
140  traf_->runs.resize(1);
141  traf_->runs[0].flags = TrackFragmentRun::kDataOffsetPresentMask;
142  traf_->auxiliary_size.sample_info_sizes.clear();
143  traf_->auxiliary_offset.offsets.clear();
144  traf_->sample_encryption.sample_encryption_entries.clear();
145  traf_->sample_group_descriptions.clear();
146  traf_->sample_to_groups.clear();
147  traf_->header.sample_description_index = 1; // 1-based.
148  traf_->header.flags = TrackFragmentHeader::kDefaultBaseIsMoofMask |
149  TrackFragmentHeader::kSampleDescriptionIndexPresentMask;
150 
151  fragment_duration_ = 0;
152  earliest_presentation_time_ = kInvalidTime;
153  first_sap_time_ = kInvalidTime;
154  data_.reset(new BufferWriter());
155  key_frame_infos_.clear();
156  return Status::OK;
157 }
158 
160  if (stream_info_->is_encrypted()) {
161  Status status = FinalizeFragmentForEncryption();
162  if (!status.ok())
163  return status;
164  }
165 
166  // Optimize trun box.
167  traf_->runs[0].sample_count =
168  static_cast<uint32_t>(traf_->runs[0].sample_sizes.size());
169  if (OptimizeSampleEntries(&traf_->runs[0].sample_durations,
170  &traf_->header.default_sample_duration)) {
171  traf_->header.flags |=
172  TrackFragmentHeader::kDefaultSampleDurationPresentMask;
173  } else {
174  traf_->runs[0].flags |= TrackFragmentRun::kSampleDurationPresentMask;
175  }
176  if (OptimizeSampleEntries(&traf_->runs[0].sample_sizes,
177  &traf_->header.default_sample_size)) {
178  traf_->header.flags |= TrackFragmentHeader::kDefaultSampleSizePresentMask;
179  } else {
180  traf_->runs[0].flags |= TrackFragmentRun::kSampleSizePresentMask;
181  }
182  if (OptimizeSampleEntries(&traf_->runs[0].sample_flags,
183  &traf_->header.default_sample_flags)) {
184  traf_->header.flags |= TrackFragmentHeader::kDefaultSampleFlagsPresentMask;
185  } else {
186  traf_->runs[0].flags |= TrackFragmentRun::kSampleFlagsPresentMask;
187  }
188 
189  // Add SampleToGroup boxes. A SampleToGroup box with grouping type of 'roll'
190  // needs to be added if there is seek preroll, referencing sample group
191  // description in track level; Also need to add SampleToGroup boxes
192  // correponding to every SampleGroupDescription boxes, referencing sample
193  // group description in fragment level.
194  DCHECK_EQ(traf_->sample_to_groups.size(), 0u);
195  if (seek_preroll_ > 0) {
196  traf_->sample_to_groups.resize(traf_->sample_to_groups.size() + 1);
197  SampleToGroup& sample_to_group = traf_->sample_to_groups.back();
198  sample_to_group.grouping_type = FOURCC_roll;
199 
200  sample_to_group.entries.resize(1);
201  SampleToGroupEntry& sample_to_group_entry = sample_to_group.entries.back();
202  sample_to_group_entry.sample_count = traf_->runs[0].sample_count;
203  sample_to_group_entry.group_description_index =
204  SampleToGroupEntry::kTrackGroupDescriptionIndexBase + 1;
205  }
206  for (const auto& sample_group_description :
207  traf_->sample_group_descriptions) {
208  traf_->sample_to_groups.resize(traf_->sample_to_groups.size() + 1);
209  SampleToGroup& sample_to_group = traf_->sample_to_groups.back();
210  sample_to_group.grouping_type = sample_group_description.grouping_type;
211 
212  sample_to_group.entries.resize(1);
213  SampleToGroupEntry& sample_to_group_entry = sample_to_group.entries.back();
214  sample_to_group_entry.sample_count = traf_->runs[0].sample_count;
215  sample_to_group_entry.group_description_index =
216  SampleToGroupEntry::kTrackFragmentGroupDescriptionIndexBase + 1;
217  }
218 
219  fragment_finalized_ = true;
220  fragment_initialized_ = false;
221  return Status::OK;
222 }
223 
225  // NOTE: Daisy chain is not supported currently.
226  reference->reference_type = false;
227  reference->subsegment_duration = fragment_duration_;
228  reference->starts_with_sap = StartsWithSAP();
229  if (kInvalidTime == first_sap_time_) {
230  reference->sap_type = SegmentReference::TypeUnknown;
231  reference->sap_delta_time = 0;
232  } else {
233  reference->sap_type = SegmentReference::Type1;
234  reference->sap_delta_time = first_sap_time_ - earliest_presentation_time_;
235  }
236  reference->earliest_presentation_time = earliest_presentation_time_;
237 }
238 
239 Status Fragmenter::FinalizeFragmentForEncryption() {
240  SampleEncryption& sample_encryption = traf_->sample_encryption;
241  if (sample_encryption.sample_encryption_entries.empty()) {
242  // This fragment is not encrypted.
243  // There are two sample description entries, an encrypted entry and a clear
244  // entry, are generated. The 1-based clear entry index is always 2.
245  const uint32_t kClearSampleDescriptionIndex = 2;
246  traf_->header.sample_description_index = kClearSampleDescriptionIndex;
247  return Status::OK;
248  }
249  if (sample_encryption.sample_encryption_entries.size() !=
250  traf_->runs[0].sample_sizes.size()) {
251  LOG(ERROR) << "Partially encrypted segment is not supported";
252  return Status(error::MUXER_FAILURE,
253  "Partially encrypted segment is not supported.");
254  }
255 
256  const SampleEncryptionEntry& sample_encryption_entry =
257  sample_encryption.sample_encryption_entries.front();
258  const bool use_subsample_encryption =
259  !sample_encryption_entry.subsamples.empty();
260  if (use_subsample_encryption)
261  traf_->sample_encryption.flags |= SampleEncryption::kUseSubsampleEncryption;
262  traf_->sample_encryption.iv_size = static_cast<uint8_t>(
263  sample_encryption_entry.initialization_vector.size());
264 
265  // The offset will be adjusted in Segmenter after knowing moof size.
266  traf_->auxiliary_offset.offsets.push_back(0);
267 
268  // Optimize saiz box.
269  SampleAuxiliaryInformationSize& saiz = traf_->auxiliary_size;
270  saiz.sample_count = static_cast<uint32_t>(saiz.sample_info_sizes.size());
271  DCHECK_EQ(saiz.sample_info_sizes.size(),
272  traf_->sample_encryption.sample_encryption_entries.size());
273  if (!OptimizeSampleEntries(&saiz.sample_info_sizes,
274  &saiz.default_sample_info_size)) {
275  saiz.default_sample_info_size = 0;
276  }
277 
278  // It should only happen with full sample encryption + constant iv, i.e.
279  // 'cbcs' applying to audio.
280  if (saiz.default_sample_info_size == 0 && saiz.sample_info_sizes.empty()) {
281  DCHECK(!use_subsample_encryption);
282  // ISO/IEC 23001-7:2016(E) The sample auxiliary information would then be
283  // empty and should be omitted. Clear saiz and saio boxes so they are not
284  // written.
285  saiz.sample_count = 0;
286  traf_->auxiliary_offset.offsets.clear();
287  }
288  return Status::OK;
289 }
290 
291 bool Fragmenter::StartsWithSAP() const {
292  DCHECK(!traf_->runs.empty());
293  uint32_t start_sample_flag;
294  if (traf_->runs[0].flags & TrackFragmentRun::kSampleFlagsPresentMask) {
295  DCHECK(!traf_->runs[0].sample_flags.empty());
296  start_sample_flag = traf_->runs[0].sample_flags[0];
297  } else {
298  DCHECK(traf_->header.flags &
299  TrackFragmentHeader::kDefaultSampleFlagsPresentMask);
300  start_sample_flag = traf_->header.default_sample_flags;
301  }
302  return (start_sample_flag & TrackFragmentHeader::kNonKeySampleMask) == 0;
303 }
304 
305 } // namespace mp4
306 } // namespace media
307 } // namespace shaka
- - -
STL namespace.
-
All the methods that are virtual are virtual for mocking.
-
Status InitializeFragment(int64_t first_sample_dts)
Definition: fragmenter.cc:129
- -
void GenerateSegmentReference(SegmentReference *reference) const
Fill reference with current fragment information.
Definition: fragmenter.cc:224
- -
Status AddSample(const MediaSample &sample)
Definition: fragmenter.cc:65
- -
Fragmenter(std::shared_ptr< const StreamInfo > info, TrackFragment *traf, int64_t edit_list_offset)
Definition: fragmenter.cc:50
-
Class to hold a media sample.
Definition: media_sample.h:22
- - - -
Status FinalizeFragment()
Finalize and optimize the fragment.
Definition: fragmenter.cc:159
-
bool OptimizeSampleEntries(std::vector< T > *entries, T *default_value)
Definition: fragmenter.h:105
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/mp4/fragmenter.h"
+
8 
+
9 #include <algorithm>
+
10 #include <limits>
+
11 
+
12 #include "packager/media/base/audio_stream_info.h"
+
13 #include "packager/media/base/buffer_writer.h"
+
14 #include "packager/media/base/media_sample.h"
+
15 #include "packager/media/formats/mp4/box_definitions.h"
+
16 #include "packager/media/formats/mp4/key_frame_info.h"
+
17 #include "packager/status_macros.h"
+
18 
+
19 namespace shaka {
+
20 namespace media {
+
21 namespace mp4 {
+
22 
+
23 namespace {
+
24 const int64_t kInvalidTime = std::numeric_limits<int64_t>::max();
+
25 
+
26 int64_t GetSeekPreroll(const StreamInfo& stream_info) {
+
27  if (stream_info.stream_type() != kStreamAudio)
+
28  return 0;
+
29  const AudioStreamInfo& audio_stream_info =
+
30  static_cast<const AudioStreamInfo&>(stream_info);
+
31  return audio_stream_info.seek_preroll_ns();
+
32 }
+
33 
+
34 void NewSampleEncryptionEntry(const DecryptConfig& decrypt_config,
+
35  bool use_constant_iv,
+
36  TrackFragment* traf) {
+
37  SampleEncryption& sample_encryption = traf->sample_encryption;
+
38  SampleEncryptionEntry sample_encryption_entry;
+
39  if (!use_constant_iv)
+
40  sample_encryption_entry.initialization_vector = decrypt_config.iv();
+
41  sample_encryption_entry.subsamples = decrypt_config.subsamples();
+
42  sample_encryption.sample_encryption_entries.push_back(
+
43  sample_encryption_entry);
+
44  traf->auxiliary_size.sample_info_sizes.push_back(
+
45  sample_encryption_entry.ComputeSize());
+
46 }
+
47 
+
48 } // namespace
+
49 
+
50 Fragmenter::Fragmenter(std::shared_ptr<const StreamInfo> stream_info,
+
51  TrackFragment* traf,
+
52  int64_t edit_list_offset)
+
53  : stream_info_(std::move(stream_info)),
+
54  traf_(traf),
+
55  edit_list_offset_(edit_list_offset),
+
56  seek_preroll_(GetSeekPreroll(*stream_info_)),
+
57  earliest_presentation_time_(kInvalidTime),
+
58  first_sap_time_(kInvalidTime) {
+
59  DCHECK(stream_info_);
+
60  DCHECK(traf);
+
61 }
+
62 
+
63 Fragmenter::~Fragmenter() {}
+
64 
+ +
66  const int64_t pts = sample.pts();
+
67  const int64_t dts = sample.dts();
+
68  const int64_t duration = sample.duration();
+
69  if (duration == 0)
+
70  LOG(WARNING) << "Unexpected sample with zero duration @ dts " << dts;
+
71 
+
72  if (!fragment_initialized_)
+
73  RETURN_IF_ERROR(InitializeFragment(dts));
+
74 
+
75  if (sample.side_data_size() > 0)
+
76  LOG(WARNING) << "MP4 samples do not support side data. Side data ignored.";
+
77 
+
78  // Fill in sample parameters. It will be optimized later.
+
79  traf_->runs[0].sample_sizes.push_back(
+
80  static_cast<uint32_t>(sample.data_size()));
+
81  traf_->runs[0].sample_durations.push_back(duration);
+
82  traf_->runs[0].sample_flags.push_back(
+
83  sample.is_key_frame() ? 0 : TrackFragmentHeader::kNonKeySampleMask);
+
84 
+
85  if (sample.decrypt_config()) {
+
86  NewSampleEncryptionEntry(
+
87  *sample.decrypt_config(),
+
88  !stream_info_->encryption_config().constant_iv.empty(), traf_);
+
89  }
+
90 
+
91  if (stream_info_->stream_type() == StreamType::kStreamVideo &&
+
92  sample.is_key_frame()) {
+
93  key_frame_infos_.push_back(
+
94  {static_cast<uint64_t>(pts), data_->Size(), sample.data_size()});
+
95  }
+
96 
+
97  data_->AppendArray(sample.data(), sample.data_size());
+
98 
+
99  traf_->runs[0].sample_composition_time_offsets.push_back(pts - dts);
+
100  if (pts != dts)
+
101  traf_->runs[0].flags |= TrackFragmentRun::kSampleCompTimeOffsetsPresentMask;
+
102 
+
103  // Exclude the part of sample with negative pts out of duration calculation as
+
104  // they are not presented.
+
105  if (pts < 0) {
+
106  const int64_t end_pts = pts + duration;
+
107  if (end_pts > 0) {
+
108  // Include effective presentation duration.
+
109  fragment_duration_ += end_pts;
+
110 
+
111  earliest_presentation_time_ = 0;
+
112  if (sample.is_key_frame())
+
113  first_sap_time_ = 0;
+
114  }
+
115  } else {
+
116  fragment_duration_ += duration;
+
117 
+
118  if (earliest_presentation_time_ > pts)
+
119  earliest_presentation_time_ = pts;
+
120 
+
121  if (sample.is_key_frame()) {
+
122  if (first_sap_time_ == kInvalidTime)
+
123  first_sap_time_ = pts;
+
124  }
+
125  }
+
126  return Status::OK;
+
127 }
+
128 
+
129 Status Fragmenter::InitializeFragment(int64_t first_sample_dts) {
+
130  fragment_initialized_ = true;
+
131  fragment_finalized_ = false;
+
132 
+
133  // |first_sample_dts| is adjusted by the edit list offset. The offset should
+
134  // be un-applied in |decode_time|, so when applying the Edit List, the result
+
135  // dts is |first_sample_dts|.
+
136  const int64_t dts_before_edit = first_sample_dts + edit_list_offset_;
+
137  traf_->decode_time.decode_time = dts_before_edit;
+
138 
+
139  traf_->runs.clear();
+
140  traf_->runs.resize(1);
+
141  traf_->runs[0].flags = TrackFragmentRun::kDataOffsetPresentMask;
+
142  traf_->auxiliary_size.sample_info_sizes.clear();
+
143  traf_->auxiliary_offset.offsets.clear();
+
144  traf_->sample_encryption.sample_encryption_entries.clear();
+
145  traf_->sample_group_descriptions.clear();
+
146  traf_->sample_to_groups.clear();
+
147  traf_->header.sample_description_index = 1; // 1-based.
+
148  traf_->header.flags = TrackFragmentHeader::kDefaultBaseIsMoofMask |
+
149  TrackFragmentHeader::kSampleDescriptionIndexPresentMask;
+
150 
+
151  fragment_duration_ = 0;
+
152  earliest_presentation_time_ = kInvalidTime;
+
153  first_sap_time_ = kInvalidTime;
+
154  data_.reset(new BufferWriter());
+
155  key_frame_infos_.clear();
+
156  return Status::OK;
+
157 }
+
158 
+ +
160  if (!fragment_initialized_)
+
161  return Status::OK;
+
162 
+
163  if (stream_info_->is_encrypted()) {
+
164  Status status = FinalizeFragmentForEncryption();
+
165  if (!status.ok())
+
166  return status;
+
167  }
+
168 
+
169  // Optimize trun box.
+
170  traf_->runs[0].sample_count =
+
171  static_cast<uint32_t>(traf_->runs[0].sample_sizes.size());
+
172  if (OptimizeSampleEntries(&traf_->runs[0].sample_durations,
+
173  &traf_->header.default_sample_duration)) {
+
174  traf_->header.flags |=
+
175  TrackFragmentHeader::kDefaultSampleDurationPresentMask;
+
176  } else {
+
177  traf_->runs[0].flags |= TrackFragmentRun::kSampleDurationPresentMask;
+
178  }
+
179  if (OptimizeSampleEntries(&traf_->runs[0].sample_sizes,
+
180  &traf_->header.default_sample_size)) {
+
181  traf_->header.flags |= TrackFragmentHeader::kDefaultSampleSizePresentMask;
+
182  } else {
+
183  traf_->runs[0].flags |= TrackFragmentRun::kSampleSizePresentMask;
+
184  }
+
185  if (OptimizeSampleEntries(&traf_->runs[0].sample_flags,
+
186  &traf_->header.default_sample_flags)) {
+
187  traf_->header.flags |= TrackFragmentHeader::kDefaultSampleFlagsPresentMask;
+
188  } else {
+
189  traf_->runs[0].flags |= TrackFragmentRun::kSampleFlagsPresentMask;
+
190  }
+
191 
+
192  // Add SampleToGroup boxes. A SampleToGroup box with grouping type of 'roll'
+
193  // needs to be added if there is seek preroll, referencing sample group
+
194  // description in track level; Also need to add SampleToGroup boxes
+
195  // correponding to every SampleGroupDescription boxes, referencing sample
+
196  // group description in fragment level.
+
197  DCHECK_EQ(traf_->sample_to_groups.size(), 0u);
+
198  if (seek_preroll_ > 0) {
+
199  traf_->sample_to_groups.resize(traf_->sample_to_groups.size() + 1);
+
200  SampleToGroup& sample_to_group = traf_->sample_to_groups.back();
+
201  sample_to_group.grouping_type = FOURCC_roll;
+
202 
+
203  sample_to_group.entries.resize(1);
+
204  SampleToGroupEntry& sample_to_group_entry = sample_to_group.entries.back();
+
205  sample_to_group_entry.sample_count = traf_->runs[0].sample_count;
+
206  sample_to_group_entry.group_description_index =
+
207  SampleToGroupEntry::kTrackGroupDescriptionIndexBase + 1;
+
208  }
+
209  for (const auto& sample_group_description :
+
210  traf_->sample_group_descriptions) {
+
211  traf_->sample_to_groups.resize(traf_->sample_to_groups.size() + 1);
+
212  SampleToGroup& sample_to_group = traf_->sample_to_groups.back();
+
213  sample_to_group.grouping_type = sample_group_description.grouping_type;
+
214 
+
215  sample_to_group.entries.resize(1);
+
216  SampleToGroupEntry& sample_to_group_entry = sample_to_group.entries.back();
+
217  sample_to_group_entry.sample_count = traf_->runs[0].sample_count;
+
218  sample_to_group_entry.group_description_index =
+
219  SampleToGroupEntry::kTrackFragmentGroupDescriptionIndexBase + 1;
+
220  }
+
221 
+
222  fragment_finalized_ = true;
+
223  fragment_initialized_ = false;
+
224  return Status::OK;
+
225 }
+
226 
+ +
228  // NOTE: Daisy chain is not supported currently.
+
229  reference->reference_type = false;
+
230  reference->subsegment_duration = fragment_duration_;
+
231  reference->starts_with_sap = StartsWithSAP();
+
232  if (kInvalidTime == first_sap_time_) {
+
233  reference->sap_type = SegmentReference::TypeUnknown;
+
234  reference->sap_delta_time = 0;
+
235  } else {
+
236  reference->sap_type = SegmentReference::Type1;
+
237  reference->sap_delta_time = first_sap_time_ - earliest_presentation_time_;
+
238  }
+
239  reference->earliest_presentation_time = earliest_presentation_time_;
+
240 }
+
241 
+
242 Status Fragmenter::FinalizeFragmentForEncryption() {
+
243  SampleEncryption& sample_encryption = traf_->sample_encryption;
+
244  if (sample_encryption.sample_encryption_entries.empty()) {
+
245  // This fragment is not encrypted.
+
246  // There are two sample description entries, an encrypted entry and a clear
+
247  // entry, are generated. The 1-based clear entry index is always 2.
+
248  const uint32_t kClearSampleDescriptionIndex = 2;
+
249  traf_->header.sample_description_index = kClearSampleDescriptionIndex;
+
250  return Status::OK;
+
251  }
+
252  if (sample_encryption.sample_encryption_entries.size() !=
+
253  traf_->runs[0].sample_sizes.size()) {
+
254  LOG(ERROR) << "Partially encrypted segment is not supported";
+
255  return Status(error::MUXER_FAILURE,
+
256  "Partially encrypted segment is not supported.");
+
257  }
+
258 
+
259  const SampleEncryptionEntry& sample_encryption_entry =
+
260  sample_encryption.sample_encryption_entries.front();
+
261  const bool use_subsample_encryption =
+
262  !sample_encryption_entry.subsamples.empty();
+
263  if (use_subsample_encryption)
+
264  traf_->sample_encryption.flags |= SampleEncryption::kUseSubsampleEncryption;
+
265  traf_->sample_encryption.iv_size = static_cast<uint8_t>(
+
266  sample_encryption_entry.initialization_vector.size());
+
267 
+
268  // The offset will be adjusted in Segmenter after knowing moof size.
+
269  traf_->auxiliary_offset.offsets.push_back(0);
+
270 
+
271  // Optimize saiz box.
+
272  SampleAuxiliaryInformationSize& saiz = traf_->auxiliary_size;
+
273  saiz.sample_count = static_cast<uint32_t>(saiz.sample_info_sizes.size());
+
274  DCHECK_EQ(saiz.sample_info_sizes.size(),
+
275  traf_->sample_encryption.sample_encryption_entries.size());
+
276  if (!OptimizeSampleEntries(&saiz.sample_info_sizes,
+
277  &saiz.default_sample_info_size)) {
+
278  saiz.default_sample_info_size = 0;
+
279  }
+
280 
+
281  // It should only happen with full sample encryption + constant iv, i.e.
+
282  // 'cbcs' applying to audio.
+
283  if (saiz.default_sample_info_size == 0 && saiz.sample_info_sizes.empty()) {
+
284  DCHECK(!use_subsample_encryption);
+
285  // ISO/IEC 23001-7:2016(E) The sample auxiliary information would then be
+
286  // empty and should be omitted. Clear saiz and saio boxes so they are not
+
287  // written.
+
288  saiz.sample_count = 0;
+
289  traf_->auxiliary_offset.offsets.clear();
+
290  }
+
291  return Status::OK;
+
292 }
+
293 
+
294 bool Fragmenter::StartsWithSAP() const {
+
295  DCHECK(!traf_->runs.empty());
+
296  uint32_t start_sample_flag;
+
297  if (traf_->runs[0].flags & TrackFragmentRun::kSampleFlagsPresentMask) {
+
298  DCHECK(!traf_->runs[0].sample_flags.empty());
+
299  start_sample_flag = traf_->runs[0].sample_flags[0];
+
300  } else {
+
301  DCHECK(traf_->header.flags &
+
302  TrackFragmentHeader::kDefaultSampleFlagsPresentMask);
+
303  start_sample_flag = traf_->header.default_sample_flags;
+
304  }
+
305  return (start_sample_flag & TrackFragmentHeader::kNonKeySampleMask) == 0;
+
306 }
+
307 
+
308 } // namespace mp4
+
309 } // namespace media
+
310 } // namespace shaka
+ + +
Class to hold a media sample.
Definition: media_sample.h:22
+
bool OptimizeSampleEntries(std::vector< T > *entries, T *default_value)
Definition: fragmenter.h:105
+
Status AddSample(const MediaSample &sample)
Definition: fragmenter.cc:65
+
Status InitializeFragment(int64_t first_sample_dts)
Definition: fragmenter.cc:129
+
void GenerateSegmentReference(SegmentReference *reference) const
Fill reference with current fragment information.
Definition: fragmenter.cc:227
+
Status FinalizeFragment()
Finalize and optimize the fragment.
Definition: fragmenter.cc:159
+
Fragmenter(std::shared_ptr< const StreamInfo > info, TrackFragment *traf, int64_t edit_list_offset)
Definition: fragmenter.cc:50
+
All the methods that are virtual are virtual for mocking.
+ + + + +
diff --git a/docs/d8/d9c/webm__tracks__parser_8cc_source.html b/docs/d8/d9c/webm__tracks__parser_8cc_source.html index 78df5731fa..b55c015399 100644 --- a/docs/d8/d9c/webm__tracks__parser_8cc_source.html +++ b/docs/d8/d9c/webm__tracks__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_tracks_parser.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
webm_tracks_parser.cc
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "packager/media/formats/webm/webm_tracks_parser.h"
6 
7 #include "packager/base/logging.h"
8 #include "packager/base/strings/string_number_conversions.h"
9 #include "packager/base/strings/string_util.h"
10 #include "packager/media/base/timestamp.h"
11 #include "packager/media/formats/webm/webm_constants.h"
12 #include "packager/media/formats/webm/webm_content_encodings.h"
13 
14 namespace shaka {
15 namespace media {
16 
17 static TextKind CodecIdToTextKind(const std::string& codec_id) {
18  if (codec_id == kWebMCodecSubtitles)
19  return kTextSubtitles;
20 
21  if (codec_id == kWebMCodecCaptions)
22  return kTextCaptions;
23 
24  if (codec_id == kWebMCodecDescriptions)
25  return kTextDescriptions;
26 
27  if (codec_id == kWebMCodecMetadata)
28  return kTextMetadata;
29 
30  return kTextNone;
31 }
32 
33 static int64_t PrecisionCappedDefaultDuration(
34  const double timecode_scale_in_us,
35  const int64_t duration_in_ns) {
36  if (duration_in_ns <= 0)
37  return kNoTimestamp;
38 
39  int64_t mult = duration_in_ns / 1000;
40  mult /= timecode_scale_in_us;
41  if (mult == 0)
42  return kNoTimestamp;
43 
44  mult = static_cast<double>(mult) * timecode_scale_in_us;
45  return mult;
46 }
47 
48 WebMTracksParser::WebMTracksParser(bool ignore_text_tracks)
49  : track_type_(-1),
50  track_num_(-1),
51  seek_preroll_(-1),
52  codec_delay_(-1),
53  default_duration_(-1),
54  audio_track_num_(-1),
55  audio_default_duration_(-1),
56  video_track_num_(-1),
57  video_default_duration_(-1),
58  ignore_text_tracks_(ignore_text_tracks),
59  audio_client_(),
60  video_client_() {
61 }
62 
63 WebMTracksParser::~WebMTracksParser() {}
64 
65 int WebMTracksParser::Parse(const uint8_t* buf, int size) {
66  track_type_ =-1;
67  track_num_ = -1;
68  default_duration_ = -1;
69  track_name_.clear();
70  track_language_.clear();
71  audio_track_num_ = -1;
72  audio_default_duration_ = -1;
73  audio_stream_info_ = nullptr;
74  video_track_num_ = -1;
75  video_default_duration_ = -1;
76  video_stream_info_ = nullptr;
77  text_tracks_.clear();
78  ignored_tracks_.clear();
79 
80  WebMListParser parser(kWebMIdTracks, this);
81  int result = parser.Parse(buf, size);
82 
83  if (result <= 0)
84  return result;
85 
86  // For now we do all or nothing parsing.
87  return parser.IsParsingComplete() ? result : 0;
88 }
89 
91  const double timecode_scale_in_us) const {
92  return PrecisionCappedDefaultDuration(timecode_scale_in_us,
93  audio_default_duration_);
94 }
95 
96 int64_t WebMTracksParser::GetVideoDefaultDuration(
97  const double timecode_scale_in_us) const {
98  return PrecisionCappedDefaultDuration(timecode_scale_in_us,
99  video_default_duration_);
100 }
101 
102 WebMParserClient* WebMTracksParser::OnListStart(int id) {
103  if (id == kWebMIdContentEncodings) {
104  DCHECK(!track_content_encodings_client_.get());
105  track_content_encodings_client_.reset(new WebMContentEncodingsClient());
106  return track_content_encodings_client_->OnListStart(id);
107  }
108 
109  if (id == kWebMIdTrackEntry) {
110  track_type_ = -1;
111  track_num_ = -1;
112  default_duration_ = -1;
113  track_name_.clear();
114  track_language_.clear();
115  codec_id_ = "";
116  codec_private_.clear();
117  audio_client_.Reset();
118  video_client_.Reset();
119  return this;
120  }
121 
122  if (id == kWebMIdAudio)
123  return &audio_client_;
124 
125  if (id == kWebMIdVideo)
126  return &video_client_;
127 
128  return this;
129 }
130 
131 bool WebMTracksParser::OnListEnd(int id) {
132  if (id == kWebMIdContentEncodings) {
133  DCHECK(track_content_encodings_client_.get());
134  return track_content_encodings_client_->OnListEnd(id);
135  }
136 
137  if (id == kWebMIdTrackEntry) {
138  if (track_type_ == -1 || track_num_ == -1) {
139  LOG(ERROR) << "Missing TrackEntry data for "
140  << " TrackType " << track_type_ << " TrackNum " << track_num_;
141  return false;
142  }
143 
144  if (track_type_ != kWebMTrackTypeAudio &&
145  track_type_ != kWebMTrackTypeVideo &&
146  track_type_ != kWebMTrackTypeSubtitlesOrCaptions &&
147  track_type_ != kWebMTrackTypeDescriptionsOrMetadata) {
148  LOG(ERROR) << "Unexpected TrackType " << track_type_;
149  return false;
150  }
151 
152  TextKind text_track_kind = kTextNone;
153  if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions) {
154  text_track_kind = CodecIdToTextKind(codec_id_);
155  if (text_track_kind == kTextNone) {
156  LOG(ERROR) << "Missing TrackEntry CodecID"
157  << " TrackNum " << track_num_;
158  return false;
159  }
160 
161  if (text_track_kind != kTextSubtitles &&
162  text_track_kind != kTextCaptions) {
163  LOG(ERROR) << "Wrong TrackEntry CodecID"
164  << " TrackNum " << track_num_;
165  return false;
166  }
167  } else if (track_type_ == kWebMTrackTypeDescriptionsOrMetadata) {
168  text_track_kind = CodecIdToTextKind(codec_id_);
169  if (text_track_kind == kTextNone) {
170  LOG(ERROR) << "Missing TrackEntry CodecID"
171  << " TrackNum " << track_num_;
172  return false;
173  }
174 
175  if (text_track_kind != kTextDescriptions &&
176  text_track_kind != kTextMetadata) {
177  LOG(ERROR) << "Wrong TrackEntry CodecID"
178  << " TrackNum " << track_num_;
179  return false;
180  }
181  }
182 
183  std::string encryption_key_id;
184  if (track_content_encodings_client_) {
185  DCHECK(!track_content_encodings_client_->content_encodings().empty());
186  // If we have multiple ContentEncoding in one track. Always choose the
187  // key id in the first ContentEncoding as the key id of the track.
188  encryption_key_id = track_content_encodings_client_->
189  content_encodings()[0]->encryption_key_id();
190  }
191 
192  if (track_type_ == kWebMTrackTypeAudio) {
193  if (audio_track_num_ == -1) {
194  audio_track_num_ = track_num_;
195  audio_encryption_key_id_ = encryption_key_id;
196 
197  if (default_duration_ == 0) {
198  LOG(ERROR) << "Illegal 0ns audio TrackEntry "
199  "DefaultDuration";
200  return false;
201  }
202  audio_default_duration_ = default_duration_;
203 
204  DCHECK(!audio_stream_info_);
205  audio_stream_info_ = audio_client_.GetAudioStreamInfo(
206  audio_track_num_, codec_id_, codec_private_, seek_preroll_,
207  codec_delay_, track_language_, !audio_encryption_key_id_.empty());
208  if (!audio_stream_info_)
209  return false;
210  } else {
211  DLOG(INFO) << "Ignoring audio track " << track_num_;
212  ignored_tracks_.insert(track_num_);
213  }
214  } else if (track_type_ == kWebMTrackTypeVideo) {
215  if (video_track_num_ == -1) {
216  video_track_num_ = track_num_;
217  video_encryption_key_id_ = encryption_key_id;
218 
219  if (default_duration_ == 0) {
220  LOG(ERROR) << "Illegal 0ns video TrackEntry "
221  "DefaultDuration";
222  return false;
223  }
224  video_default_duration_ = default_duration_;
225 
226  DCHECK(!video_stream_info_);
227  video_stream_info_ = video_client_.GetVideoStreamInfo(
228  video_track_num_, codec_id_, codec_private_,
229  !video_encryption_key_id_.empty());
230  if (!video_stream_info_)
231  return false;
232 
233  if (codec_id_ == "V_VP8" || codec_id_ == "V_VP9") {
234  vp_config_ = video_client_.GetVpCodecConfig(codec_private_);
235  const double kNanosecondsPerSecond = 1000000000.0;
236  if (codec_id_ == "V_VP9" &&
237  (!vp_config_.is_level_set() || vp_config_.level() == 0)) {
238  vp_config_.SetVP9Level(
239  video_stream_info_->width(), video_stream_info_->height(),
240  video_default_duration_ / kNanosecondsPerSecond);
241  }
242  }
243 
244  } else {
245  DLOG(INFO) << "Ignoring video track " << track_num_;
246  ignored_tracks_.insert(track_num_);
247  }
248  } else if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions ||
249  track_type_ == kWebMTrackTypeDescriptionsOrMetadata) {
250  if (ignore_text_tracks_) {
251  DLOG(INFO) << "Ignoring text track " << track_num_;
252  ignored_tracks_.insert(track_num_);
253  } else {
254  std::string track_num = base::Int64ToString(track_num_);
255  text_tracks_[track_num_] = TextTrackConfig(
256  text_track_kind, track_name_, track_language_, track_num);
257  }
258  } else {
259  LOG(ERROR) << "Unexpected TrackType " << track_type_;
260  return false;
261  }
262 
263  track_type_ = -1;
264  track_num_ = -1;
265  default_duration_ = -1;
266  track_name_.clear();
267  track_language_.clear();
268  codec_id_ = "";
269  codec_private_.clear();
270  track_content_encodings_client_.reset();
271 
272  audio_client_.Reset();
273  video_client_.Reset();
274  return true;
275  }
276 
277  return true;
278 }
279 
280 bool WebMTracksParser::OnUInt(int id, int64_t val) {
281  int64_t* dst = NULL;
282 
283  switch (id) {
284  case kWebMIdTrackNumber:
285  dst = &track_num_;
286  break;
287  case kWebMIdTrackType:
288  dst = &track_type_;
289  break;
290  case kWebMIdSeekPreRoll:
291  dst = &seek_preroll_;
292  break;
293  case kWebMIdCodecDelay:
294  dst = &codec_delay_;
295  break;
296  case kWebMIdDefaultDuration:
297  dst = &default_duration_;
298  break;
299  default:
300  return true;
301  }
302 
303  if (*dst != -1) {
304  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified";
305  return false;
306  }
307 
308  *dst = val;
309  return true;
310 }
311 
312 bool WebMTracksParser::OnFloat(int id, double val) {
313  return true;
314 }
315 
316 bool WebMTracksParser::OnBinary(int id, const uint8_t* data, int size) {
317  if (id == kWebMIdCodecPrivate) {
318  if (!codec_private_.empty()) {
319  LOG(ERROR) << "Multiple CodecPrivate fields in a track.";
320  return false;
321  }
322  codec_private_.assign(data, data + size);
323  return true;
324  }
325  return true;
326 }
327 
328 bool WebMTracksParser::OnString(int id, const std::string& str) {
329  if (id == kWebMIdCodecID) {
330  if (!codec_id_.empty()) {
331  LOG(ERROR) << "Multiple CodecID fields in a track";
332  return false;
333  }
334 
335  codec_id_ = str;
336  return true;
337  }
338 
339  if (id == kWebMIdName) {
340  track_name_ = str;
341  return true;
342  }
343 
344  if (id == kWebMIdLanguage) {
345  track_language_ = str;
346  return true;
347  }
348 
349  return true;
350 }
351 
352 } // namespace media
353 } // namespace shaka
Parser for WebM ContentEncodings element.
- -
All the methods that are virtual are virtual for mocking.
- -
int Parse(const uint8_t *buf, int size)
Definition: webm_parser.cc:738
-
int64_t GetAudioDefaultDuration(const double timecode_scale_in_us) const
-
int Parse(const uint8_t *buf, int size)
- - +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #include "packager/media/formats/webm/webm_tracks_parser.h"
+
6 
+
7 #include "packager/base/logging.h"
+
8 #include "packager/base/strings/string_number_conversions.h"
+
9 #include "packager/base/strings/string_util.h"
+
10 #include "packager/media/base/timestamp.h"
+
11 #include "packager/media/formats/webm/webm_constants.h"
+
12 #include "packager/media/formats/webm/webm_content_encodings.h"
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 
+
17 static TextKind CodecIdToTextKind(const std::string& codec_id) {
+
18  if (codec_id == kWebMCodecSubtitles)
+
19  return kTextSubtitles;
+
20 
+
21  if (codec_id == kWebMCodecCaptions)
+
22  return kTextCaptions;
+
23 
+
24  if (codec_id == kWebMCodecDescriptions)
+
25  return kTextDescriptions;
+
26 
+
27  if (codec_id == kWebMCodecMetadata)
+
28  return kTextMetadata;
+
29 
+
30  return kTextNone;
+
31 }
+
32 
+
33 static int64_t PrecisionCappedDefaultDuration(
+
34  const double timecode_scale_in_us,
+
35  const int64_t duration_in_ns) {
+
36  if (duration_in_ns <= 0)
+
37  return kNoTimestamp;
+
38 
+
39  int64_t mult = duration_in_ns / 1000;
+
40  mult /= timecode_scale_in_us;
+
41  if (mult == 0)
+
42  return kNoTimestamp;
+
43 
+
44  mult = static_cast<double>(mult) * timecode_scale_in_us;
+
45  return mult;
+
46 }
+
47 
+
48 WebMTracksParser::WebMTracksParser(bool ignore_text_tracks)
+
49  : track_type_(-1),
+
50  track_num_(-1),
+
51  seek_preroll_(-1),
+
52  codec_delay_(-1),
+
53  default_duration_(-1),
+
54  audio_track_num_(-1),
+
55  audio_default_duration_(-1),
+
56  video_track_num_(-1),
+
57  video_default_duration_(-1),
+
58  ignore_text_tracks_(ignore_text_tracks),
+
59  audio_client_(),
+
60  video_client_() {
+
61 }
+
62 
+
63 WebMTracksParser::~WebMTracksParser() {}
+
64 
+
65 int WebMTracksParser::Parse(const uint8_t* buf, int size) {
+
66  track_type_ =-1;
+
67  track_num_ = -1;
+
68  default_duration_ = -1;
+
69  track_name_.clear();
+
70  track_language_.clear();
+
71  audio_track_num_ = -1;
+
72  audio_default_duration_ = -1;
+
73  audio_stream_info_ = nullptr;
+
74  video_track_num_ = -1;
+
75  video_default_duration_ = -1;
+
76  video_stream_info_ = nullptr;
+
77  text_tracks_.clear();
+
78  ignored_tracks_.clear();
+
79 
+
80  WebMListParser parser(kWebMIdTracks, this);
+
81  int result = parser.Parse(buf, size);
+
82 
+
83  if (result <= 0)
+
84  return result;
+
85 
+
86  // For now we do all or nothing parsing.
+
87  return parser.IsParsingComplete() ? result : 0;
+
88 }
+
89 
+
90 int64_t WebMTracksParser::GetAudioDefaultDuration(
+
91  const double timecode_scale_in_us) const {
+
92  return PrecisionCappedDefaultDuration(timecode_scale_in_us,
+
93  audio_default_duration_);
+
94 }
+
95 
+
96 int64_t WebMTracksParser::GetVideoDefaultDuration(
+
97  const double timecode_scale_in_us) const {
+
98  return PrecisionCappedDefaultDuration(timecode_scale_in_us,
+
99  video_default_duration_);
+
100 }
+
101 
+
102 WebMParserClient* WebMTracksParser::OnListStart(int id) {
+
103  if (id == kWebMIdContentEncodings) {
+
104  DCHECK(!track_content_encodings_client_.get());
+
105  track_content_encodings_client_.reset(new WebMContentEncodingsClient());
+
106  return track_content_encodings_client_->OnListStart(id);
+
107  }
+
108 
+
109  if (id == kWebMIdTrackEntry) {
+
110  track_type_ = -1;
+
111  track_num_ = -1;
+
112  default_duration_ = -1;
+
113  track_name_.clear();
+
114  track_language_.clear();
+
115  codec_id_ = "";
+
116  codec_private_.clear();
+
117  audio_client_.Reset();
+
118  video_client_.Reset();
+
119  return this;
+
120  }
+
121 
+
122  if (id == kWebMIdAudio)
+
123  return &audio_client_;
+
124 
+
125  if (id == kWebMIdVideo)
+
126  return &video_client_;
+
127 
+
128  return this;
+
129 }
+
130 
+
131 bool WebMTracksParser::OnListEnd(int id) {
+
132  if (id == kWebMIdContentEncodings) {
+
133  DCHECK(track_content_encodings_client_.get());
+
134  return track_content_encodings_client_->OnListEnd(id);
+
135  }
+
136 
+
137  if (id == kWebMIdTrackEntry) {
+
138  if (track_type_ == -1 || track_num_ == -1) {
+
139  LOG(ERROR) << "Missing TrackEntry data for "
+
140  << " TrackType " << track_type_ << " TrackNum " << track_num_;
+
141  return false;
+
142  }
+
143 
+
144  if (track_type_ != kWebMTrackTypeAudio &&
+
145  track_type_ != kWebMTrackTypeVideo &&
+
146  track_type_ != kWebMTrackTypeSubtitlesOrCaptions &&
+
147  track_type_ != kWebMTrackTypeDescriptionsOrMetadata) {
+
148  LOG(ERROR) << "Unexpected TrackType " << track_type_;
+
149  return false;
+
150  }
+
151 
+
152  TextKind text_track_kind = kTextNone;
+
153  if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions) {
+
154  text_track_kind = CodecIdToTextKind(codec_id_);
+
155  if (text_track_kind == kTextNone) {
+
156  LOG(ERROR) << "Missing TrackEntry CodecID"
+
157  << " TrackNum " << track_num_;
+
158  return false;
+
159  }
+
160 
+
161  if (text_track_kind != kTextSubtitles &&
+
162  text_track_kind != kTextCaptions) {
+
163  LOG(ERROR) << "Wrong TrackEntry CodecID"
+
164  << " TrackNum " << track_num_;
+
165  return false;
+
166  }
+
167  } else if (track_type_ == kWebMTrackTypeDescriptionsOrMetadata) {
+
168  text_track_kind = CodecIdToTextKind(codec_id_);
+
169  if (text_track_kind == kTextNone) {
+
170  LOG(ERROR) << "Missing TrackEntry CodecID"
+
171  << " TrackNum " << track_num_;
+
172  return false;
+
173  }
+
174 
+
175  if (text_track_kind != kTextDescriptions &&
+
176  text_track_kind != kTextMetadata) {
+
177  LOG(ERROR) << "Wrong TrackEntry CodecID"
+
178  << " TrackNum " << track_num_;
+
179  return false;
+
180  }
+
181  }
+
182 
+
183  std::string encryption_key_id;
+
184  if (track_content_encodings_client_) {
+
185  DCHECK(!track_content_encodings_client_->content_encodings().empty());
+
186  // If we have multiple ContentEncoding in one track. Always choose the
+
187  // key id in the first ContentEncoding as the key id of the track.
+
188  encryption_key_id = track_content_encodings_client_->
+
189  content_encodings()[0]->encryption_key_id();
+
190  }
+
191 
+
192  if (track_type_ == kWebMTrackTypeAudio) {
+
193  if (audio_track_num_ == -1) {
+
194  audio_track_num_ = track_num_;
+
195  audio_encryption_key_id_ = encryption_key_id;
+
196 
+
197  if (default_duration_ == 0) {
+
198  LOG(ERROR) << "Illegal 0ns audio TrackEntry "
+
199  "DefaultDuration";
+
200  return false;
+
201  }
+
202  audio_default_duration_ = default_duration_;
+
203 
+
204  DCHECK(!audio_stream_info_);
+
205  audio_stream_info_ = audio_client_.GetAudioStreamInfo(
+
206  audio_track_num_, codec_id_, codec_private_, seek_preroll_,
+
207  codec_delay_, track_language_, !audio_encryption_key_id_.empty());
+
208  if (!audio_stream_info_)
+
209  return false;
+
210  } else {
+
211  DLOG(INFO) << "Ignoring audio track " << track_num_;
+
212  ignored_tracks_.insert(track_num_);
+
213  }
+
214  } else if (track_type_ == kWebMTrackTypeVideo) {
+
215  if (video_track_num_ == -1) {
+
216  video_track_num_ = track_num_;
+
217  video_encryption_key_id_ = encryption_key_id;
+
218 
+
219  if (default_duration_ == 0) {
+
220  LOG(ERROR) << "Illegal 0ns video TrackEntry "
+
221  "DefaultDuration";
+
222  return false;
+
223  }
+
224  video_default_duration_ = default_duration_;
+
225 
+
226  DCHECK(!video_stream_info_);
+
227  video_stream_info_ = video_client_.GetVideoStreamInfo(
+
228  video_track_num_, codec_id_, codec_private_,
+
229  !video_encryption_key_id_.empty());
+
230  if (!video_stream_info_)
+
231  return false;
+
232 
+
233  if (codec_id_ == "V_VP8" || codec_id_ == "V_VP9") {
+
234  vp_config_ = video_client_.GetVpCodecConfig(codec_private_);
+
235  const double kNanosecondsPerSecond = 1000000000.0;
+
236  if (codec_id_ == "V_VP9" &&
+
237  (!vp_config_.is_level_set() || vp_config_.level() == 0)) {
+
238  vp_config_.SetVP9Level(
+
239  video_stream_info_->width(), video_stream_info_->height(),
+
240  video_default_duration_ / kNanosecondsPerSecond);
+
241  }
+
242  }
+
243 
+
244  } else {
+
245  DLOG(INFO) << "Ignoring video track " << track_num_;
+
246  ignored_tracks_.insert(track_num_);
+
247  }
+
248  } else if (track_type_ == kWebMTrackTypeSubtitlesOrCaptions ||
+
249  track_type_ == kWebMTrackTypeDescriptionsOrMetadata) {
+
250  if (ignore_text_tracks_) {
+
251  DLOG(INFO) << "Ignoring text track " << track_num_;
+
252  ignored_tracks_.insert(track_num_);
+
253  } else {
+
254  std::string track_num = base::Int64ToString(track_num_);
+
255  text_tracks_[track_num_] = TextTrackConfig(
+
256  text_track_kind, track_name_, track_language_, track_num);
+
257  }
+
258  } else {
+
259  LOG(ERROR) << "Unexpected TrackType " << track_type_;
+
260  return false;
+
261  }
+
262 
+
263  track_type_ = -1;
+
264  track_num_ = -1;
+
265  default_duration_ = -1;
+
266  track_name_.clear();
+
267  track_language_.clear();
+
268  codec_id_ = "";
+
269  codec_private_.clear();
+
270  track_content_encodings_client_.reset();
+
271 
+
272  audio_client_.Reset();
+
273  video_client_.Reset();
+
274  return true;
+
275  }
+
276 
+
277  return true;
+
278 }
+
279 
+
280 bool WebMTracksParser::OnUInt(int id, int64_t val) {
+
281  int64_t* dst = NULL;
+
282 
+
283  switch (id) {
+
284  case kWebMIdTrackNumber:
+
285  dst = &track_num_;
+
286  break;
+
287  case kWebMIdTrackType:
+
288  dst = &track_type_;
+
289  break;
+
290  case kWebMIdSeekPreRoll:
+
291  dst = &seek_preroll_;
+
292  break;
+
293  case kWebMIdCodecDelay:
+
294  dst = &codec_delay_;
+
295  break;
+
296  case kWebMIdDefaultDuration:
+
297  dst = &default_duration_;
+
298  break;
+
299  default:
+
300  return true;
+
301  }
+
302 
+
303  if (*dst != -1) {
+
304  LOG(ERROR) << "Multiple values for id " << std::hex << id << " specified";
+
305  return false;
+
306  }
+
307 
+
308  *dst = val;
+
309  return true;
+
310 }
+
311 
+
312 bool WebMTracksParser::OnFloat(int id, double val) {
+
313  return true;
+
314 }
+
315 
+
316 bool WebMTracksParser::OnBinary(int id, const uint8_t* data, int size) {
+
317  if (id == kWebMIdCodecPrivate) {
+
318  if (!codec_private_.empty()) {
+
319  LOG(ERROR) << "Multiple CodecPrivate fields in a track.";
+
320  return false;
+
321  }
+
322  codec_private_.assign(data, data + size);
+
323  return true;
+
324  }
+
325  return true;
+
326 }
+
327 
+
328 bool WebMTracksParser::OnString(int id, const std::string& str) {
+
329  if (id == kWebMIdCodecID) {
+
330  if (!codec_id_.empty()) {
+
331  LOG(ERROR) << "Multiple CodecID fields in a track";
+
332  return false;
+
333  }
+
334 
+
335  codec_id_ = str;
+
336  return true;
+
337  }
+
338 
+
339  if (id == kWebMIdName) {
+
340  track_name_ = str;
+
341  return true;
+
342  }
+
343 
+
344  if (id == kWebMIdLanguage) {
+
345  track_language_ = str;
+
346  return true;
+
347  }
+
348 
+
349  return true;
+
350 }
+
351 
+
352 } // namespace media
+
353 } // namespace shaka
+ +
int Parse(const uint8_t *buf, int size)
Definition: webm_parser.cc:738
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/d9f/udp__file_8h_source.html b/docs/d8/d9f/udp__file_8h_source.html index 7ad0de1924..4173be2e62 100644 --- a/docs/d8/d9f/udp__file_8h_source.html +++ b/docs/d8/d9f/udp__file_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/udp_file.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
udp_file.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef MEDIA_FILE_UDP_FILE_H_
8 #define MEDIA_FILE_UDP_FILE_H_
9 
10 #include <stdint.h>
11 
12 #include <string>
13 
14 #include "packager/base/compiler_specific.h"
15 #include "packager/file/file.h"
16 
17 #if defined(OS_WIN)
18 #include <winsock2.h>
19 #else
20 typedef int SOCKET;
21 #endif // defined(OS_WIN)
22 
23 namespace shaka {
24 
26 class UdpFile : public File {
27  public:
30  explicit UdpFile(const char* address_and_port);
31 
34  bool Close() override;
35  int64_t Read(void* buffer, uint64_t length) override;
36  int64_t Write(const void* buffer, uint64_t length) override;
37  int64_t Size() override;
38  bool Flush() override;
39  bool Seek(uint64_t position) override;
40  bool Tell(uint64_t* position) override;
42 
43  protected:
44  ~UdpFile() override;
45 
46  bool Open() override;
47 
48  private:
49  SOCKET socket_;
50 #if defined(OS_WIN)
51  // For Winsock in Windows.
52  bool wsa_started_ = false;
53 #endif // defined(OS_WIN)
54 
55  DISALLOW_COPY_AND_ASSIGN(UdpFile);
56 };
57 
58 } // namespace shaka
59 
60 #endif // MEDIA_FILE_UDP_FILE_H_
int64_t Read(void *buffer, uint64_t length) override
Definition: udp_file.cc:76
-
bool Tell(uint64_t *position) override
Definition: udp_file.cc:115
-
bool Seek(uint64_t position) override
Definition: udp_file.cc:110
-
UdpFile(const char *address_and_port)
Definition: udp_file.cc:58
-
Define an abstract file interface.
Definition: file.h:26
-
int64_t Write(const void *buffer, uint64_t length) override
Definition: udp_file.cc:93
-
All the methods that are virtual are virtual for mocking.
-
Implements UdpFile, which receives UDP unicast and multicast streams.
Definition: udp_file.h:26
-
bool Close() override
Definition: udp_file.cc:63
-
bool Open() override
Internal open. Should not be used directly.
Definition: udp_file.cc:143
-
int64_t Size() override
Definition: udp_file.cc:98
-
bool Flush() override
Definition: udp_file.cc:105
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef MEDIA_FILE_UDP_FILE_H_
+
8 #define MEDIA_FILE_UDP_FILE_H_
+
9 
+
10 #include <stdint.h>
+
11 
+
12 #include <string>
+
13 
+
14 #include "packager/base/compiler_specific.h"
+
15 #include "packager/file/file.h"
+
16 
+
17 #if defined(OS_WIN)
+
18 #include <winsock2.h>
+
19 #else
+
20 typedef int SOCKET;
+
21 #endif // defined(OS_WIN)
+
22 
+
23 namespace shaka {
+
24 
+
26 class UdpFile : public File {
+
27  public:
+
30  explicit UdpFile(const char* address_and_port);
+
31 
+
34  bool Close() override;
+
35  int64_t Read(void* buffer, uint64_t length) override;
+
36  int64_t Write(const void* buffer, uint64_t length) override;
+
37  int64_t Size() override;
+
38  bool Flush() override;
+
39  bool Seek(uint64_t position) override;
+
40  bool Tell(uint64_t* position) override;
+
42 
+
43  protected:
+
44  ~UdpFile() override;
+
45 
+
46  bool Open() override;
+
47 
+
48  private:
+
49  SOCKET socket_;
+
50 #if defined(OS_WIN)
+
51  // For Winsock in Windows.
+
52  bool wsa_started_ = false;
+
53 #endif // defined(OS_WIN)
+
54 
+
55  DISALLOW_COPY_AND_ASSIGN(UdpFile);
+
56 };
+
57 
+
58 } // namespace shaka
+
59 
+
60 #endif // MEDIA_FILE_UDP_FILE_H_
+
Define an abstract file interface.
Definition: file.h:27
+
Implements UdpFile, which receives UDP unicast and multicast streams.
Definition: udp_file.h:26
+
int64_t Size() override
Definition: udp_file.cc:98
+
bool Seek(uint64_t position) override
Definition: udp_file.cc:110
+
int64_t Write(const void *buffer, uint64_t length) override
Definition: udp_file.cc:93
+
bool Tell(uint64_t *position) override
Definition: udp_file.cc:115
+
bool Flush() override
Definition: udp_file.cc:105
+
bool Close() override
Definition: udp_file.cc:63
+
int64_t Read(void *buffer, uint64_t length) override
Definition: udp_file.cc:76
+
bool Open() override
Internal open. Should not be used directly.
Definition: udp_file.cc:143
+
UdpFile(const char *address_and_port)
Definition: udp_file.cc:58
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/da3/classshaka_1_1media_1_1DecryptorSource-members.html b/docs/d8/da3/classshaka_1_1media_1_1DecryptorSource-members.html index 32fbed23d4..fd6852bb5b 100644 --- a/docs/d8/da3/classshaka_1_1media_1_1DecryptorSource-members.html +++ b/docs/d8/da3/classshaka_1_1media_1_1DecryptorSource-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d8/da5/structshaka_1_1media_1_1mp4_1_1SampleSize-members.html b/docs/d8/da5/structshaka_1_1media_1_1mp4_1_1SampleSize-members.html index 3a57922638..79e74f62f0 100644 --- a/docs/d8/da5/structshaka_1_1media_1_1mp4_1_1SampleSize-members.html +++ b/docs/d8/da5/structshaka_1_1media_1_1mp4_1_1SampleSize-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/da6/classshaka_1_1media_1_1NaluReader-members.html b/docs/d8/da6/classshaka_1_1media_1_1NaluReader-members.html index ed4e6ba33f..bac7b105f7 100644 --- a/docs/d8/da6/classshaka_1_1media_1_1NaluReader-members.html +++ b/docs/d8/da6/classshaka_1_1media_1_1NaluReader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/da9/classshaka_1_1media_1_1DvbSubParser.html b/docs/d8/da9/classshaka_1_1media_1_1DvbSubParser.html new file mode 100644 index 0000000000..80f3eddb13 --- /dev/null +++ b/docs/d8/da9/classshaka_1_1media_1_1DvbSubParser.html @@ -0,0 +1,111 @@ + + + + + + + +Shaka Packager SDK: shaka::media::DvbSubParser Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::DvbSubParser Class Reference
+
+
+ + + + + + + + + + +

+Public Member Functions

DvbSubParser (const DvbSubParser &)=delete
 
+DvbSubParseroperator= (const DvbSubParser &)=delete
 
+bool Parse (DvbSubSegmentType segment_type, int64_t pts, const uint8_t *payload, size_t size, std::vector< std::shared_ptr< TextSample >> *samples)
 
+bool Flush (std::vector< std::shared_ptr< TextSample >> *samples)
 
+ + + +

+Friends

+class DvbSubParserTest
 
+

Detailed Description

+
+

Definition at line 33 of file dvb_sub_parser.h.

+

The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/d8/daa/stream__info_8h_source.html b/docs/d8/daa/stream__info_8h_source.html index 02bc3484f3..225582764e 100644 --- a/docs/d8/daa/stream__info_8h_source.html +++ b/docs/d8/daa/stream__info_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/stream_info.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
stream_info.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_BASE_STREAM_INFO_H_
8 #define PACKAGER_MEDIA_BASE_STREAM_INFO_H_
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "packager/media/base/encryption_config.h"
15 
16 namespace shaka {
17 namespace media {
18 
19 enum StreamType {
20  kStreamUnknown = 0,
21  kStreamAudio,
22  kStreamVideo,
23  kStreamText,
24 };
25 
26 std::string StreamTypeToString(StreamType type);
27 
28 enum Codec {
29  kUnknownCodec = 0,
30 
31  kCodecVideo = 100,
32  kCodecAV1 = kCodecVideo,
33  kCodecH264,
34  kCodecH265,
35  kCodecH265DolbyVision,
36  kCodecVP8,
37  kCodecVP9,
38  kCodecVideoMaxPlusOne,
39 
40  kCodecAudio = 200,
41  kCodecAAC = kCodecAudio,
42  kCodecAC3,
43  // TODO(kqyang): Use kCodecDTS and a kDtsStreamFormat for the various DTS
44  // streams.
45  kCodecDTSC,
46  kCodecDTSE,
47  kCodecDTSH,
48  kCodecDTSL,
49  kCodecDTSM,
50  kCodecDTSP,
51  kCodecEAC3,
52  kCodecFlac,
53  kCodecOpus,
54  kCodecVorbis,
55  kCodecAudioMaxPlusOne,
56 
57  kCodecText = 300,
58  kCodecWebVtt = kCodecText,
59 };
60 
62 class StreamInfo {
63  public:
64  StreamInfo() = default;
65 
66  StreamInfo(StreamType stream_type,
67  int track_id,
68  uint32_t time_scale,
69  uint64_t duration,
70  Codec codec,
71  const std::string& codec_string,
72  const uint8_t* codec_config,
73  size_t codec_config_size,
74  const std::string& language,
75  bool is_encrypted);
76 
77  virtual ~StreamInfo();
78 
81  virtual bool IsValidConfig() const = 0;
82 
84  virtual std::string ToString() const;
85 
89  virtual std::unique_ptr<StreamInfo> Clone() const = 0;
90 
91  StreamType stream_type() const { return stream_type_; }
92  uint32_t track_id() const { return track_id_; }
93  uint32_t time_scale() const { return time_scale_; }
94  uint64_t duration() const { return duration_; }
95  Codec codec() const { return codec_; }
96  const std::string& codec_string() const { return codec_string_; }
97  const std::vector<uint8_t>& codec_config() const { return codec_config_; }
98  const std::string& language() const { return language_; }
99  bool is_encrypted() const { return is_encrypted_; }
100  bool has_clear_lead() const { return has_clear_lead_; }
101  const EncryptionConfig& encryption_config() const {
102  return encryption_config_;
103  }
104 
105  void set_duration(uint64_t duration) { duration_ = duration; }
106  void set_codec(Codec codec) { codec_ = codec; }
107  void set_codec_config(const std::vector<uint8_t>& data) {
108  codec_config_ = data;
109  }
110  void set_codec_string(const std::string& codec_string) {
111  codec_string_ = codec_string;
112  }
113  void set_language(const std::string& language) { language_ = language; }
114  void set_is_encrypted(bool is_encrypted) { is_encrypted_ = is_encrypted; }
115  void set_has_clear_lead(bool has_clear_lead) {
116  has_clear_lead_ = has_clear_lead;
117  }
118  void set_encryption_config(const EncryptionConfig& encryption_config) {
119  encryption_config_ = encryption_config;
120  }
121 
122  private:
123  // Whether the stream is Audio or Video.
124  StreamType stream_type_;
125  uint32_t track_id_;
126  // The actual time is calculated as time / time_scale_ in seconds.
127  uint32_t time_scale_;
128  // Duration base on time_scale.
129  uint64_t duration_;
130  Codec codec_;
131  std::string codec_string_;
132  std::string language_;
133  // Whether the stream is potentially encrypted.
134  // Note that in a potentially encrypted stream, individual buffers
135  // can be encrypted or not encrypted.
136  bool is_encrypted_;
137  // Whether the stream has clear lead.
138  bool has_clear_lead_ = false;
139  EncryptionConfig encryption_config_;
140  // Optional byte data required for some audio/video decoders such as Vorbis
141  // codebooks.
142  std::vector<uint8_t> codec_config_;
143 
144  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
145  // generated copy constructor and assignment operator. Since the extra data is
146  // typically small, the performance impact is minimal.
147 };
148 
149 } // namespace media
150 } // namespace shaka
151 
152 #endif // PACKAGER_MEDIA_BASE_STREAM_INFO_H_
Abstract class holds stream information.
Definition: stream_info.h:62
-
virtual std::unique_ptr< StreamInfo > Clone() const =0
-
virtual bool IsValidConfig() const =0
-
virtual std::string ToString() const
Definition: stream_info.cc:58
-
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_BASE_STREAM_INFO_H_
+
8 #define PACKAGER_MEDIA_BASE_STREAM_INFO_H_
+
9 
+
10 #include <memory>
+
11 #include <string>
+
12 #include <vector>
+
13 
+
14 #include "packager/media/base/encryption_config.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+
19 enum StreamType {
+
20  kStreamUnknown = 0,
+
21  kStreamAudio,
+
22  kStreamVideo,
+
23  kStreamText,
+
24 };
+
25 
+
26 std::string StreamTypeToString(StreamType type);
+
27 
+
28 enum Codec {
+
29  kUnknownCodec = 0,
+
30 
+
31  kCodecVideo = 100,
+
32  kCodecAV1 = kCodecVideo,
+
33  kCodecH264,
+
34  kCodecH265,
+
35  kCodecH265DolbyVision,
+
36  kCodecVP8,
+
37  kCodecVP9,
+
38  kCodecVideoMaxPlusOne,
+
39 
+
40  kCodecAudio = 200,
+
41  kCodecAAC = kCodecAudio,
+
42  kCodecAC3,
+
43  kCodecAC4,
+
44  // TODO(kqyang): Use kCodecDTS and a kDtsStreamFormat for the various DTS
+
45  // streams.
+
46  kCodecDTSC,
+
47  kCodecDTSE,
+
48  kCodecDTSH,
+
49  kCodecDTSL,
+
50  kCodecDTSM,
+
51  kCodecDTSP,
+
52  kCodecEAC3,
+
53  kCodecFlac,
+
54  kCodecOpus,
+
55  kCodecVorbis,
+
56  kCodecMP3,
+
57  kCodecAudioMaxPlusOne,
+
58 
+
59  kCodecText = 300,
+
60  kCodecWebVtt = kCodecText,
+
61  kCodecTtml,
+
62 };
+
63 
+
65 class StreamInfo {
+
66  public:
+
67  StreamInfo() = default;
+
68 
+
69  StreamInfo(StreamType stream_type,
+
70  int track_id,
+
71  uint32_t time_scale,
+
72  uint64_t duration,
+
73  Codec codec,
+
74  const std::string& codec_string,
+
75  const uint8_t* codec_config,
+
76  size_t codec_config_size,
+
77  const std::string& language,
+
78  bool is_encrypted);
+
79 
+
80  virtual ~StreamInfo();
+
81 
+
84  virtual bool IsValidConfig() const = 0;
+
85 
+
87  virtual std::string ToString() const;
+
88 
+
92  virtual std::unique_ptr<StreamInfo> Clone() const = 0;
+
93 
+
94  StreamType stream_type() const { return stream_type_; }
+
95  uint32_t track_id() const { return track_id_; }
+
96  uint32_t time_scale() const { return time_scale_; }
+
97  uint64_t duration() const { return duration_; }
+
98  Codec codec() const { return codec_; }
+
99  const std::string& codec_string() const { return codec_string_; }
+
100  const std::vector<uint8_t>& codec_config() const { return codec_config_; }
+
101  const std::string& language() const { return language_; }
+
102  bool is_encrypted() const { return is_encrypted_; }
+
103  bool has_clear_lead() const { return has_clear_lead_; }
+
104  const EncryptionConfig& encryption_config() const {
+
105  return encryption_config_;
+
106  }
+
107 
+
108  void set_duration(uint64_t duration) { duration_ = duration; }
+
109  void set_codec(Codec codec) { codec_ = codec; }
+
110  void set_codec_config(const std::vector<uint8_t>& data) {
+
111  codec_config_ = data;
+
112  }
+
113  void set_codec_string(const std::string& codec_string) {
+
114  codec_string_ = codec_string;
+
115  }
+
116  void set_language(const std::string& language) { language_ = language; }
+
117  void set_is_encrypted(bool is_encrypted) { is_encrypted_ = is_encrypted; }
+
118  void set_has_clear_lead(bool has_clear_lead) {
+
119  has_clear_lead_ = has_clear_lead;
+
120  }
+
121  void set_encryption_config(const EncryptionConfig& encryption_config) {
+
122  encryption_config_ = encryption_config;
+
123  }
+
124 
+
125  private:
+
126  // Whether the stream is Audio or Video.
+
127  StreamType stream_type_;
+
128  uint32_t track_id_;
+
129  // The actual time is calculated as time / time_scale_ in seconds.
+
130  uint32_t time_scale_;
+
131  // Duration base on time_scale.
+
132  uint64_t duration_;
+
133  Codec codec_;
+
134  std::string codec_string_;
+
135  std::string language_;
+
136  // Whether the stream is potentially encrypted.
+
137  // Note that in a potentially encrypted stream, individual buffers
+
138  // can be encrypted or not encrypted.
+
139  bool is_encrypted_;
+
140  // Whether the stream has clear lead.
+
141  bool has_clear_lead_ = false;
+
142  EncryptionConfig encryption_config_;
+
143  // Optional byte data required for some audio/video decoders such as Vorbis
+
144  // codebooks.
+
145  std::vector<uint8_t> codec_config_;
+
146 
+
147  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
+
148  // generated copy constructor and assignment operator. Since the extra data is
+
149  // typically small, the performance impact is minimal.
+
150 };
+
151 
+
152 } // namespace media
+
153 } // namespace shaka
+
154 
+
155 #endif // PACKAGER_MEDIA_BASE_STREAM_INFO_H_
+
Abstract class holds stream information.
Definition: stream_info.h:65
+
virtual bool IsValidConfig() const =0
+
virtual std::string ToString() const
Definition: stream_info.cc:59
+
virtual std::unique_ptr< StreamInfo > Clone() const =0
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/daf/namespaceshaka.html b/docs/d8/daf/namespaceshaka.html index ab7f2ba679..3b6efa04e0 100644 --- a/docs/d8/daf/namespaceshaka.html +++ b/docs/d8/daf/namespaceshaka.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka Namespace Reference @@ -29,18 +29,21 @@
- + +/* @license-end */

All the methods that are virtual are virtual for mocking. -More...

+More...

- - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + - + + - + + - + + - + + - - + - - + + - + + - + + - - - - - - - - - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - - + + + - - + + - - + + - - + - - - - - - - - +

Classes

class  AdaptationSet
 
struct  AdCueGeneratorParams
 Cuepoint generator related parameters. More...
 
class  BandwidthEstimator
 
struct  BufferCallbackParams
 Buffer callback params. More...
 
class  CallbackFile
 
struct  ChunkingParams
 Chunking (segmentation) related parameters. More...
 
struct  ContentProtectionElement
 
struct  Cuepoint
 
struct  DecryptionParams
 Decryption parameters. More...
 
struct  Element
 
struct  EncryptionParams
 Encryption parameters. More...
 
class  File
 Define an abstract file interface. More...
 
struct  FileCloser
 
struct  HlsParams
 HLS related parameters. More...
class  HttpFile
 
class  IoCache
 Declaration of class which implements a thread-safe circular buffer. More...
 
class  LocalFile
 Implement LocalFile which deals with local storage. More...
 Implement LocalFile which deals with local storage. More...
 
class  MemoryFile
 
class  MockAdaptationSet
struct  BufferCallbackParams
 Buffer callback params. More...
 
class  MockMpdBuilder
class  ThreadedIoFile
 Declaration of class which implements a thread-safe circular buffer. More...
 
class  MockMpdNotifier
class  UdpFile
 Implements UdpFile, which receives UDP unicast and multicast streams. More...
 
class  MockPeriod
class  UdpOptions
 Options parsed from UDP url string of the form: udp://ip:port[?options]. More...
 
class  MockRepresentation
struct  HlsParams
 HLS related parameters. More...
 
struct  Mp4OutputParams
 MP4 (ISO-BMFF) output related parameters. More...
struct  Cuepoint
 
class  MpdBuilder
 This class generates DASH MPDs (Media Presentation Descriptions). More...
struct  AdCueGeneratorParams
 Cuepoint generator related parameters. More...
 
class  MpdNotifier
struct  ChunkingParams
 Chunking (segmentation) related parameters. More...
 
class  MpdNotifierFactory
struct  WidevineSigner
 Signer credential for Widevine license server. More...
 
struct  MpdOptions
 Defines Mpd Options. More...
 
struct  MpdParams
 DASH MPD related parameters. More...
 
class  MpdWriter
 
class  Packager
 
struct  PackagingParams
 Packaging parameters. More...
 
class  Period
struct  WidevineEncryptionParams
 Widevine encryption parameters. More...
 
struct  PlayReadyEncryptionParams
 
struct  RawKeyParams
 Raw key encryption/decryption parameters, i.e. with key parameters provided. More...
 
class  Representation
struct  EncryptionParams
 Encryption parameters. More...
 
struct  WidevineDecryptionParams
 Widevine decryption parameters. More...
 
struct  DecryptionParams
 Decryption parameters. More...
 
struct  Mp4OutputParams
 MP4 (ISO-BMFF) output related parameters. More...
 
class  AdaptationSet
 
class  BandwidthEstimator
 
struct  Element
 
struct  ContentProtectionElement
 
class  MockMpdBuilder
 
class  MockPeriod
 
class  MockAdaptationSet
 
class  MockRepresentation
 
class  MockMpdNotifier
 
class  MpdBuilder
 This class generates DASH MPDs (Media Presentation Descriptions). More...
 
class  MpdNotifier
 
struct  MpdOptions
 Defines Mpd Options. More...
 
class  Period
 
class  RepresentationStateChangeListener
 
class  Representation
 
struct  SegmentInfo
 
class  SimpleMpdNotifier
 
class  Status
struct  MpdParams
 DASH MPD related parameters. More...
 
struct  StreamDescriptor
 Defines a single input/output stream. More...
class  MpdNotifierFactory
 
class  MpdWriter
 
struct  TestParams
 Parameters used for testing. More...
 
class  ThreadedIoFile
 Declaration of class which implements a thread-safe circular buffer. More...
struct  PackagingParams
 Packaging parameters. More...
 
class  UdpFile
 Implements UdpFile, which receives UDP unicast and multicast streams. More...
struct  StreamDescriptor
 Defines a single input/output stream. More...
 
class  UdpOptions
 Options parsed from UDP url string of the form: udp://ip:port[?options]. More...
class  Packager
 
struct  WidevineDecryptionParams
 Widevine decryption parameters. More...
 
struct  WidevineEncryptionParams
 Widevine encryption parameters. More...
 
struct  WidevineSigner
 Signer credential for Widevine license server. More...
class  Status
 

@@ -203,31 +208,46 @@ typedef MediaInfo::VideoInfo 

- + + - - + - + + - -

Enumerations

enum  HlsPlaylistType { kVod, -kEvent, -kLive +
enum class  HttpMethod { kGet +, kPost +, kPut + }
 
enum class  HlsPlaylistType { kVod +, kEvent +, kLive }
 
enum  KeyProvider { kNone = 0, -kWidevine = 1, -kPlayReady = 2, -kRawKey = 3 - }
 Encryption / decryption key providers.
enum class  KeyProvider { kNone +, kRawKey +, kWidevine +, kPlayReady + }
 
enum  ContentType { kContentTypeUnknown, -kContentTypeVideo, -kContentTypeAudio, -kContentTypeText +
enum class  ProtectionSystem : uint16_t {
+  kNone = 0 +, kCommon = (1 << 0) +, kWidevine = (1 << 1) +, kPlayReady = (1 << 2) +,
+  kFairPlay = (1 << 3) +, kMarlin = (1 << 4) +
+ }
 
enum  ContentType { kContentTypeUnknown +, kContentTypeVideo +, kContentTypeAudio +, kContentTypeText }
 
enum  DashProfile { kUnknown, -kOnDemand, -kLive +
enum class  DashProfile { kUnknown +, kOnDemand +, kLive }
 
enum  MpdType { kStatic, -kDynamic +
enum class  MpdType { kStatic +, kDynamic }
 
@@ -257,6 +277,24 @@ bool  + + + + + + + + + + + + @@ -283,9 +321,9 @@ std::string  - - + + @@ -310,6 +348,9 @@ void  + + @@ -328,6 +369,12 @@ const char *  + + + + @@ -340,10 +387,12 @@ const char  + +
ValidateHexString
 
std::string LanguageToISO_639_2 (const std::string &language)
 
+ProtectionSystem operator| (ProtectionSystem a, ProtectionSystem b)
 
+ProtectionSystemoperator|= (ProtectionSystem &a, ProtectionSystem b)
 
+ProtectionSystem operator& (ProtectionSystem a, ProtectionSystem b)
 
+ProtectionSystemoperator&= (ProtectionSystem &a, ProtectionSystem b)
 
+ProtectionSystem operator~ (ProtectionSystem a)
 
+bool has_flag (ProtectionSystem value, ProtectionSystem flag)
 
bool WriteMpdToFile (const std::string &output_path, MpdBuilder *mpd_builder)
 
ContentType GetContentType (const MediaInfo &media_info)
GetCodecs
std::string GetBaseCodec (const MediaInfo &media_info)
 
-std::string GetAdaptationSetKey (const MediaInfo &media_info)
 
+std::string GetAdaptationSetKey (const MediaInfo &media_info, bool ignore_codec)
 
std::string SecondsToXmlDuration (double seconds)
 
UpdateContentProtecti
 
void AddContentProtectionElements (const MediaInfo &media_info, AdaptationSet *parent)
 
+bool XmlEqual (const std::string &xml1, const xml::XmlNode &xml2)
 
std::ostream & operator<< (std::ostream &os, const Status &x)
 
kMemoryFilePr
const char * kUdpFilePrefix = "udp://"
 
+const char * kHttpFilePrefix = "http://"
 
+const char * kHttpsFilePrefix = "https://"
 
const int64_t kWholeFile = -1
 
kEncryptedMp4Sc
const char kPsshElementName [] = "cenc:pssh"
 
+const char kMsproElementName [] = "mspr:pro"
 

Detailed Description

All the methods that are virtual are virtual for mocking.

-

NOTE: Inclusion of this module will cause curl_global_init and curl_global_cleanup to be called at static initialization / deinitialization time.

All the methods that are virtual are virtual for mocking. NOTE: Inclusion of this module will cause xmlInitParser and xmlCleanupParser to be called at static initialization / deinitialization time.

This file contains helper functions and enums for MpdNotifier implementations.

Enumeration Type Documentation

@@ -372,46 +421,63 @@ const char kPsshElementNam
-

Function Documentation

- -

◆ AddContentProtectionElements() [1/2]

+ +

◆ KeyProvider

+ + + + + +
- - - - - - - - - - - - - - - +
void shaka::AddContentProtectionElements (const MediaInfo & media_info,
Representationparent 
)enum shaka::KeyProvider
+
+strong
-

Adds <ContentProtection> elements specified by media_info to adaptation_set. Note that this will add the elements as direct chlidren of AdaptationSet.

Parameters
- - - -
media_infomay or may not have protected_content field.
adaptation_setis the parent element that owns the ContentProtection elements.
-
-
+

Encryption key providers. These provide keys to decrypt the content if the source content is encrypted, or used to encrypt the content.

-

Definition at line 436 of file mpd_utils.cc.

+

Definition at line 21 of file crypto_params.h.

+ +

◆ ProtectionSystem

+ +
+
+ + + + + +
+ + + + +
enum shaka::ProtectionSystem : uint16_t
+
+strong
+
+

Protection systems that handle decryption during playback. This affects the protection info that is stored in the content. Multiple protection systems can be combined using OR.

+ + +
Enumerator
kCommon 

The common key system from EME: https://goo.gl/s8RIhr.

+
+ +

Definition at line 31 of file crypto_params.h.

+ +
+
+

Function Documentation

-

◆ AddContentProtectionElements() [2/2]

+

◆ AddContentProtectionElements() [1/2]

@@ -443,7 +509,44 @@ const char kPsshElementNam -

Definition at line 441 of file mpd_utils.cc.

+

Definition at line 478 of file mpd_utils.cc.

+ +
+
+ +

◆ AddContentProtectionElements() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + +
void shaka::AddContentProtectionElements (const MediaInfo & media_info,
Representationparent 
)
+
+

Adds <ContentProtection> elements specified by media_info to adaptation_set. Note that this will add the elements as direct chlidren of AdaptationSet.

Parameters
+ + + +
media_infomay or may not have protected_content field.
adaptation_setis the parent element that owns the ContentProtection elements.
+
+
+ +

Definition at line 473 of file mpd_utils.cc.

@@ -507,7 +610,7 @@ const char kPsshElementNam -

Definition at line 228 of file mpd_utils.cc.

+

Definition at line 232 of file mpd_utils.cc.

@@ -577,7 +680,7 @@ const char kPsshElementNam
Returns
true if successful, false otherwise. May print error messages.
-

Definition at line 92 of file stream_descriptor.cc.

+

Definition at line 98 of file stream_descriptor.cc.

@@ -747,7 +850,7 @@ template<class FlagType >

Validate PlayReady encryption flags.

Returns
true on success, false otherwise.
-

Definition at line 34 of file playready_key_encryption_flags.cc.

+

Definition at line 25 of file playready_key_encryption_flags.cc.

@@ -831,9 +934,7 @@ template<class FlagType > diff --git a/docs/d8/db4/classshaka_1_1media_1_1DvbImageColorSpace.html b/docs/d8/db4/classshaka_1_1media_1_1DvbImageColorSpace.html new file mode 100644 index 0000000000..c171679f03 --- /dev/null +++ b/docs/d8/db4/classshaka_1_1media_1_1DvbImageColorSpace.html @@ -0,0 +1,120 @@ + + + + + + + +Shaka Packager SDK: shaka::media::DvbImageColorSpace Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::DvbImageColorSpace Class Reference
+
+
+ +

#include <dvb_image.h>

+ + + + + + + + + + + + + + + + + + + +

+Public Member Functions

DvbImageColorSpace (const DvbImageColorSpace &)=delete
 
+DvbImageColorSpaceoperator= (const DvbImageColorSpace &)=delete
 
+RgbaColor GetColor (BitDepth bit_depth, uint8_t entry_id) const
 
+void SetColor (BitDepth bit_depth, uint8_t entry_id, RgbaColor color)
 
+void Set2To4BitDepthMap (const uint8_t *map)
 Must pass a 4-element array; elements are copied over.
 
+void Set2To8BitDepthMap (const uint8_t *map)
 Must pass a 4-element array; elements are copied over.
 
+void Set4To8BitDepthMap (const uint8_t *map)
 Must pass a 16-element array; elements are copied over.
 
+

Detailed Description

+

Defines a color-space for DVB-sub images. This maps to a single CLUT in the spec. This holds a map of the byte codes to the respective RGB colors. This also handles getting the default colors when none are provided and converting between bit-depths if applicable.

+

When handling bit-depths, this will attempt to use the bit-depth provided before converting upward then downward. Each color is only set for that specific bit-depth; meaning different bit-depths can have different colors mapped to the same byte-code.

+ +

Definition at line 47 of file dvb_image.h.

+

The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/d8/db7/classshaka_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html b/docs/d8/db7/classshaka_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html index 32e0549e84..df12d4ec88 100644 --- a/docs/d8/db7/classshaka_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html +++ b/docs/d8/db7/classshaka_1_1media_1_1mp4_1_1MultiSegmentSegmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MultiSegmentSegmenter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Segmenter - -
+ + @@ -119,7 +122,7 @@ Additional Inherited Members - + @@ -247,9 +250,7 @@ void 

Public Member Functions

- Protected Member Functions inherited from shaka::media::mp4::Segmenter
void UpdateProgress (uint64_t progress)
 Update segmentation progress using ProgressListener.
 Update segmentation progress using ProgressListener.
 
void SetComplete ()
set_progress_target diff --git a/docs/d8/db9/classshaka_1_1media_1_1WebMContentEncodingsClient-members.html b/docs/d8/db9/classshaka_1_1media_1_1WebMContentEncodingsClient-members.html index dea9c99f18..e300e271bc 100644 --- a/docs/d8/db9/classshaka_1_1media_1_1WebMContentEncodingsClient-members.html +++ b/docs/d8/db9/classshaka_1_1media_1_1WebMContentEncodingsClient-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d8/dbf/classshaka_1_1media_1_1PsshGenerator.html b/docs/d8/dbf/classshaka_1_1media_1_1PsshGenerator.html index 25c1f542d0..46d05c725c 100644 --- a/docs/d8/dbf/classshaka_1_1media_1_1PsshGenerator.html +++ b/docs/d8/dbf/classshaka_1_1media_1_1PsshGenerator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::PsshGenerator Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::CommonPsshGenerator shaka::media::PlayReadyPsshGenerator shaka::media::WidevinePsshGenerator - -
+ + @@ -239,7 +242,7 @@ Public Member Functions @@ -250,9 +253,7 @@ Public Member Functions diff --git a/docs/d8/dc2/classshaka_1_1media_1_1Replicator-members.html b/docs/d8/dc2/classshaka_1_1media_1_1Replicator-members.html index e678d7af01..b2e0a1be2d 100644 --- a/docs/d8/dc2/classshaka_1_1media_1_1Replicator-members.html +++ b/docs/d8/dc2/classshaka_1_1media_1_1Replicator-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

Public Member Functions

- + +/* @license-end */
This is the complete list of members for shaka::media::Replicator, including all inherited members.

- + @@ -92,9 +95,7 @@ $(function() {
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
diff --git a/docs/d8/dc2/structshaka_1_1media_1_1mp2t_1_1EsParserH26x_1_1VideoSliceInfo.html b/docs/d8/dc2/structshaka_1_1media_1_1mp2t_1_1EsParserH26x_1_1VideoSliceInfo.html index 762ee0d7f2..abd535ea73 100644 --- a/docs/d8/dc2/structshaka_1_1media_1_1mp2t_1_1EsParserH26x_1_1VideoSliceInfo.html +++ b/docs/d8/dc2/structshaka_1_1media_1_1mp2t_1_1EsParserH26x_1_1VideoSliceInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::EsParserH26x::VideoSliceInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
frame_num = 0
diff --git a/docs/d8/dc3/structshaka_1_1media_1_1mp4_1_1CueTimeBox.html b/docs/d8/dc3/structshaka_1_1media_1_1mp4_1_1CueTimeBox.html index e2ccf25d99..30a80e00f2 100644 --- a/docs/d8/dc3/structshaka_1_1media_1_1mp4_1_1CueTimeBox.html +++ b/docs/d8/dc3/structshaka_1_1media_1_1mp4_1_1CueTimeBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CueTimeBox Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 810 of file box_definitions.h.

+

Definition at line 828 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2737 of file box_definitions.cc.

+

Definition at line 2841 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d8/dca/ts__writer_8h_source.html b/docs/d8/dca/ts__writer_8h_source.html index 21c6594bef..1db700d4b1 100644 --- a/docs/d8/dca/ts__writer_8h_source.html +++ b/docs/d8/dca/ts__writer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_writer.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
ts_writer.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_H_
8 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_H_
9 
10 #include <list>
11 #include <map>
12 #include <memory>
13 #include <vector>
14 
15 #include "packager/base/optional.h"
16 #include "packager/file/file.h"
17 #include "packager/file/file_closer.h"
18 #include "packager/media/formats/mp2t/continuity_counter.h"
19 
20 namespace shaka {
21 namespace media {
22 namespace mp2t {
23 
24 class PesPacket;
25 class ProgramMapTableWriter;
26 
29 class TsWriter {
30  public:
31  explicit TsWriter(std::unique_ptr<ProgramMapTableWriter> pmt_writer);
32  virtual ~TsWriter();
33 
38  virtual bool NewSegment(const std::string& file_name);
39 
41  virtual void SignalEncrypted();
42 
46  virtual bool FinalizeSegment();
47 
52  virtual bool AddPesPacket(std::unique_ptr<PesPacket> pes_packet);
53 
55  base::Optional<uint64_t> GetFilePosition();
56 
57  private:
58  TsWriter(const TsWriter&) = delete;
59  TsWriter& operator=(const TsWriter&) = delete;
60 
61  // True if further segments generated by this instance should be encrypted.
62  bool encrypted_ = false;
63 
64  ContinuityCounter pat_continuity_counter_;
65  ContinuityCounter elementary_stream_continuity_counter_;
66 
67  std::unique_ptr<ProgramMapTableWriter> pmt_writer_;
68 
69  std::unique_ptr<File, FileCloser> current_file_;
70 };
71 
72 } // namespace mp2t
73 } // namespace media
74 } // namespace shaka
75 
76 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_H_
virtual bool NewSegment(const std::string &file_name)
Definition: ts_writer.cc:166
-
base::Optional< uint64_t > GetFilePosition()
Definition: ts_writer.cc:217
-
All the methods that are virtual are virtual for mocking.
-
virtual bool AddPesPacket(std::unique_ptr< PesPacket > pes_packet)
Definition: ts_writer.cc:205
- - -
virtual bool FinalizeSegment()
Definition: ts_writer.cc:201
-
virtual void SignalEncrypted()
Signals the writer that the rest of the segments are encrypted.
Definition: ts_writer.cc:197
+
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_H_
+
9 
+
10 #include <list>
+
11 #include <map>
+
12 #include <memory>
+
13 #include <vector>
+
14 
+
15 #include "packager/base/optional.h"
+
16 #include "packager/file/file.h"
+
17 #include "packager/file/file_closer.h"
+
18 #include "packager/media/formats/mp2t/continuity_counter.h"
+
19 #include "packager/media/base/buffer_writer.h"
+
20 
+
21 namespace shaka {
+
22 namespace media {
+
23 namespace mp2t {
+
24 
+
25 class PesPacket;
+
26 class ProgramMapTableWriter;
+
27 
+
30 class TsWriter {
+
31  public:
+
32  explicit TsWriter(std::unique_ptr<ProgramMapTableWriter> pmt_writer);
+
33  virtual ~TsWriter();
+
34 
+
38  virtual bool NewSegment(BufferWriter* buffer);
+
39 
+
41  virtual void SignalEncrypted();
+
42 
+
48  virtual bool AddPesPacket(std::unique_ptr<PesPacket> pes_packet, BufferWriter* buffer);
+
49 
+
50  private:
+
51  TsWriter(const TsWriter&) = delete;
+
52  TsWriter& operator=(const TsWriter&) = delete;
+
53 
+
54  // True if further segments generated by this instance should be encrypted.
+
55  bool encrypted_ = false;
+
56 
+
57  ContinuityCounter pat_continuity_counter_;
+
58  ContinuityCounter elementary_stream_continuity_counter_;
+
59 
+
60  std::unique_ptr<ProgramMapTableWriter> pmt_writer_;
+
61 };
+
62 
+
63 } // namespace mp2t
+
64 } // namespace media
+
65 } // namespace shaka
+
66 
+
67 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_H_
+ + + +
virtual bool NewSegment(BufferWriter *buffer)
Definition: ts_writer.cc:168
+
virtual bool AddPesPacket(std::unique_ptr< PesPacket > pes_packet, BufferWriter *buffer)
Definition: ts_writer.cc:189
+
virtual void SignalEncrypted()
Signals the writer that the rest of the segments are encrypted.
Definition: ts_writer.cc:185
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/dcb/dvb__image_8cc_source.html b/docs/d8/dcb/dvb__image_8cc_source.html new file mode 100644 index 0000000000..ed4e6cee57 --- /dev/null +++ b/docs/d8/dcb/dvb__image_8cc_source.html @@ -0,0 +1,354 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/dvb/dvb_image.cc Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
dvb_image.cc
+
+
+
1 // Copyright 2020 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/dvb/dvb_image.h"
+
8 
+
9 #include <algorithm>
+
10 #include <cstring>
+
11 #include <tuple>
+
12 
+
13 #include "packager/base/logging.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 
+
18 namespace {
+
19 
+
20 // See ETSI EN 300 743 Section 9.1.
+
21 constexpr const uint8_t k4To2ReductionMap[] = {
+
22  0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+
23  0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3,
+
24 };
+
25 
+
26 // The only time when A==0 is when it is transparent. This means we can use
+
27 // other values internally for special values.
+
28 constexpr const RgbaColor kNoColor{145, 92, 47, 0};
+
29 
+
30 // DVB uses transparency, but libpng uses alpha, so we need to reverse the T
+
31 // value so we can pass the value to libpng.
+
32 #define COLOR(r, g, b, t) \
+
33  RgbaColor { \
+
34  static_cast<uint8_t>(255 * (r) / 100), \
+
35  static_cast<uint8_t>(255 * (g) / 100), \
+
36  static_cast<uint8_t>(255 * (b) / 100), \
+
37  static_cast<uint8_t>(255 * (100 - t) / 100) \
+
38  }
+
39 // Default color maps see ETSI EN 300 743 Section 10.
+
40 constexpr const RgbaColor k2BitDefaultColors[] = {
+
41  COLOR(0, 0, 0, 100), // 0 = 0b00
+
42  COLOR(100, 100, 100, 0), // 1 = 0b01
+
43  COLOR(0, 0, 0, 0), // 2 = 0b10
+
44  COLOR(50, 50, 50, 0), // 3 = 0b11
+
45 };
+
46 // Default color maps see ETSI EN 300 743 Section 10.
+
47 constexpr const RgbaColor k4BitDefaultColors[] = {
+
48  COLOR(0, 0, 0, 100), // 0 = 0b0000
+
49  COLOR(100, 0, 0, 0), // 1 = 0b0001
+
50  COLOR(0, 100, 0, 0), // 2 = 0b0010
+
51  COLOR(100, 100, 0, 0), // 3 = 0b0011
+
52  COLOR(0, 0, 100, 0), // 4 = 0b0100
+
53  COLOR(100, 0, 100, 0), // 5 = 0b0101
+
54  COLOR(0, 100, 100, 0), // 6 = 0b0110
+
55  COLOR(100, 100, 100, 0), // 7 = 0b0111
+
56 
+
57  COLOR(0, 0, 0, 0), // 8 = 0b1000
+
58  COLOR(50, 0, 0, 0), // 9 = 0b1001
+
59  COLOR(0, 50, 0, 0), // 10 = 0b1010
+
60  COLOR(50, 50, 0, 0), // 11 = 0b1011
+
61  COLOR(0, 0, 50, 0), // 12 = 0b1100
+
62  COLOR(50, 0, 50, 0), // 13 = 0b1101
+
63  COLOR(0, 50, 50, 0), // 14 = 0b1110
+
64  COLOR(50, 50, 50, 0), // 15 = 0b1111
+
65 };
+
66 
+
67 #define GET_BIT(n) ((entry_id >> (8 - (n))) & 0x1)
+
68 // Default color maps see ETSI EN 300 743 Section 10.
+
69 RgbaColor Get8BitDefaultColor(uint8_t entry_id) {
+
70  uint8_t r, g, b, t;
+
71  if (entry_id == 0) {
+
72  return COLOR(0, 0, 0, 100);
+
73  } else if ((entry_id & 0xf8) == 0) {
+
74  r = 100 * GET_BIT(8);
+
75  g = 100 * GET_BIT(7);
+
76  b = 100 * GET_BIT(6);
+
77  t = 75;
+
78  } else if (!GET_BIT(1)) {
+
79  r = (33 * GET_BIT(8)) + (67 * GET_BIT(4));
+
80  g = (33 * GET_BIT(7)) + (67 * GET_BIT(3));
+
81  b = (33 * GET_BIT(6)) + (67 * GET_BIT(2));
+
82  t = GET_BIT(5) ? 50 : 0;
+
83  } else {
+
84  r = (17 * GET_BIT(8)) + (33 * GET_BIT(4)) + (GET_BIT(5) ? 0 : 50);
+
85  g = (17 * GET_BIT(7)) + (33 * GET_BIT(3)) + (GET_BIT(5) ? 0 : 50);
+
86  b = (17 * GET_BIT(6)) + (33 * GET_BIT(2)) + (GET_BIT(5) ? 0 : 50);
+
87  t = 0;
+
88  }
+
89  return COLOR(r, g, b, t);
+
90 }
+
91 #undef GET_BIT
+
92 #undef COLOR
+
93 
+
94 } // namespace
+
95 
+
96 DvbImageColorSpace::DvbImageColorSpace() {
+
97  for (auto& item : color_map_2_)
+
98  item = kNoColor;
+
99  for (auto& item : color_map_4_)
+
100  item = kNoColor;
+
101  for (auto& item : color_map_8_)
+
102  item = kNoColor;
+
103 }
+
104 
+
105 DvbImageColorSpace::~DvbImageColorSpace() {}
+
106 
+
107 RgbaColor DvbImageColorSpace::GetColor(BitDepth bit_depth,
+
108  uint8_t entry_id) const {
+
109  auto color = GetColorRaw(bit_depth, entry_id);
+
110  if (color != kNoColor)
+
111  return color;
+
112 
+
113  // If we don't have the exact bit-depth, try mapping to another bit-depth.
+
114  // See ETSI EN 300 743 Section 9.
+
115  RgbaColor default_color, alt1, alt2;
+
116  switch (bit_depth) {
+
117  case BitDepth::k2Bit:
+
118  DCHECK_LT(entry_id, 4u);
+
119  alt1 = GetColorRaw(BitDepth::k4Bit, bit_depth_2_to_4_[entry_id]);
+
120  alt2 = GetColorRaw(BitDepth::k8Bit, bit_depth_2_to_8_[entry_id]);
+
121  default_color = k2BitDefaultColors[entry_id];
+
122  break;
+
123  case BitDepth::k4Bit:
+
124  DCHECK_LT(entry_id, 16u);
+
125  alt1 = GetColorRaw(BitDepth::k8Bit, bit_depth_4_to_8_[entry_id]);
+
126  alt2 = GetColorRaw(BitDepth::k2Bit, k4To2ReductionMap[entry_id]);
+
127  default_color = k4BitDefaultColors[entry_id];
+
128  break;
+
129  case BitDepth::k8Bit:
+
130  // 8-to-4-bit reduction is just take the low bits.
+
131  alt1 = GetColorRaw(BitDepth::k4Bit, entry_id & 0xf);
+
132  alt2 = GetColorRaw(BitDepth::k2Bit, k4To2ReductionMap[entry_id & 0xf]);
+
133  default_color = Get8BitDefaultColor(entry_id);
+
134  break;
+
135  default:
+
136  // Windows can't detect that all enums are handled and doesn't like
+
137  // NOTREACHED.
+
138  return kNoColor;
+
139  }
+
140 
+
141  if (alt1 != kNoColor)
+
142  return alt1;
+
143  if (alt2 != kNoColor)
+
144  return alt2;
+
145  return default_color;
+
146 }
+
147 
+
148 void DvbImageColorSpace::SetColor(BitDepth bit_depth,
+
149  uint8_t entry_id,
+
150  RgbaColor color) {
+
151  DCHECK(color != kNoColor);
+
152  switch (bit_depth) {
+
153  case BitDepth::k2Bit:
+
154  DCHECK_LT(entry_id, 4u);
+
155  color_map_2_[entry_id] = color;
+
156  break;
+
157  case BitDepth::k4Bit:
+
158  DCHECK_LT(entry_id, 16u);
+
159  color_map_4_[entry_id] = color;
+
160  break;
+
161  case BitDepth::k8Bit:
+
162  color_map_8_[entry_id] = color;
+
163  break;
+
164  }
+
165 }
+
166 
+
167 void DvbImageColorSpace::Set2To4BitDepthMap(const uint8_t* map) {
+
168  memcpy(bit_depth_2_to_4_, map, sizeof(bit_depth_2_to_4_));
+
169 }
+
170 
+
171 void DvbImageColorSpace::Set2To8BitDepthMap(const uint8_t* map) {
+
172  memcpy(bit_depth_2_to_8_, map, sizeof(bit_depth_2_to_8_));
+
173 }
+
174 
+
175 void DvbImageColorSpace::Set4To8BitDepthMap(const uint8_t* map) {
+
176  memcpy(bit_depth_4_to_8_, map, sizeof(bit_depth_4_to_8_));
+
177 }
+
178 
+
179 RgbaColor DvbImageColorSpace::GetColorRaw(BitDepth bit_depth,
+
180  uint8_t entry_id) const {
+
181  switch (bit_depth) {
+
182  case BitDepth::k2Bit:
+
183  return color_map_2_[entry_id];
+
184  case BitDepth::k4Bit:
+
185  return color_map_4_[entry_id];
+
186  case BitDepth::k8Bit:
+
187  return color_map_8_[entry_id];
+
188  }
+
189  // Not reached, but Windows doesn't like NOTREACHED.
+
190  return kNoColor;
+
191 }
+
192 
+
193 DvbImageBuilder::DvbImageBuilder(const DvbImageColorSpace* color_space,
+
194  const RgbaColor& default_color,
+
195  uint16_t max_width,
+
196  uint16_t max_height)
+
197  : pixels_(new RgbaColor[max_width * max_height]),
+
198  color_space_(color_space),
+
199  top_pos_{0, 0},
+
200  bottom_pos_{0, 1}, // Skip top row for bottom row.
+
201  max_width_(max_width),
+
202  max_height_(max_height),
+
203  width_(0) {
+
204  for (size_t i = 0; i < static_cast<size_t>(max_width) * max_height; i++)
+
205  pixels_[i] = default_color;
+
206 }
+
207 
+
208 DvbImageBuilder::~DvbImageBuilder() {}
+
209 
+
210 bool DvbImageBuilder::AddPixel(BitDepth bit_depth,
+
211  uint8_t byte_code,
+
212  bool is_top_rows) {
+
213  auto& pos = is_top_rows ? top_pos_ : bottom_pos_;
+
214  if (pos.x >= max_width_ || pos.y >= max_height_) {
+
215  LOG(ERROR) << "DVB-sub image cannot fit in region/window";
+
216  return false;
+
217  }
+
218 
+
219  pixels_[pos.y * max_width_ + pos.x++] =
+
220  color_space_->GetColor(bit_depth, byte_code);
+
221  if (pos.x > width_)
+
222  width_ = pos.x;
+
223  return true;
+
224 }
+
225 
+
226 void DvbImageBuilder::NewRow(bool is_top_rows) {
+
227  auto& pos = is_top_rows ? top_pos_ : bottom_pos_;
+
228  pos.x = 0;
+
229  pos.y += 2; // Skip other row.
+
230 }
+
231 
+ +
233  for (size_t line = 0; line < max_height_ - 1u; line += 2) {
+
234  std::memcpy(&pixels_[(line + 1) * max_width_], &pixels_[line * max_width_],
+
235  max_width_ * sizeof(RgbaColor));
+
236  }
+
237  bottom_pos_ = top_pos_;
+
238  if (max_height_ % 2 == 0)
+
239  bottom_pos_.y++;
+
240  else
+
241  bottom_pos_.y--; // Odd-height images don't end in odd-row, so move back.
+
242 }
+
243 
+ +
245  uint16_t* width,
+
246  uint16_t* height) const {
+
247  size_t max_y, min_y;
+
248  std::tie(min_y, max_y) = std::minmax(top_pos_.y, bottom_pos_.y);
+
249  if (max_y == 1 || max_y != min_y + 1) {
+
250  // 1. We should have at least one row.
+
251  // 2. Both top-rows and bottom-rows should have the same number of rows.
+
252  LOG(ERROR) << "Incomplete DVB-sub image";
+
253  return false;
+
254  }
+
255 
+
256  *width = width_;
+
257  // We skipped the other row in NewRow, so rollback.
+
258  *height = static_cast<uint16_t>(max_y - 1);
+
259  *pixels = pixels_.get();
+
260  if (*height > max_height_) {
+
261  LOG(ERROR) << "DVB-sub image cannot fit in region/window";
+
262  return false;
+
263  }
+
264 
+
265  return true;
+
266 }
+
267 
+
268 } // namespace media
+
269 } // namespace shaka
+
bool GetPixels(const RgbaColor **pixels, uint16_t *width, uint16_t *height) const
Definition: dvb_image.cc:244
+
void MirrorToBottomRows()
Copies the top-rows to the bottom rows.
Definition: dvb_image.cc:232
+
void Set4To8BitDepthMap(const uint8_t *map)
Must pass a 16-element array; elements are copied over.
Definition: dvb_image.cc:175
+
void Set2To8BitDepthMap(const uint8_t *map)
Must pass a 4-element array; elements are copied over.
Definition: dvb_image.cc:171
+
void Set2To4BitDepthMap(const uint8_t *map)
Must pass a 4-element array; elements are copied over.
Definition: dvb_image.cc:167
+
All the methods that are virtual are virtual for mocking.
+ +
+ + + + diff --git a/docs/d8/dcd/structshaka_1_1media_1_1mp4_1_1DecodingTime-members.html b/docs/d8/dcd/structshaka_1_1media_1_1mp4_1_1DecodingTime-members.html index c71de39047..6b893dc3d1 100644 --- a/docs/d8/dcd/structshaka_1_1media_1_1mp4_1_1DecodingTime-members.html +++ b/docs/d8/dcd/structshaka_1_1media_1_1mp4_1_1DecodingTime-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d8/dcd/structshaka_1_1media_1_1mp4_1_1TrackExtends-members.html b/docs/d8/dcd/structshaka_1_1media_1_1mp4_1_1TrackExtends-members.html index 359975175f..fbea2804ed 100644 --- a/docs/d8/dcd/structshaka_1_1media_1_1mp4_1_1TrackExtends-members.html +++ b/docs/d8/dcd/structshaka_1_1media_1_1mp4_1_1TrackExtends-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/dd2/classshaka_1_1media_1_1WebVttFileBuffer-members.html b/docs/d8/dd2/classshaka_1_1media_1_1WebVttFileBuffer-members.html index 2952a5f08c..44f61687ae 100644 --- a/docs/d8/dd2/classshaka_1_1media_1_1WebVttFileBuffer-members.html +++ b/docs/d8/dd2/classshaka_1_1media_1_1WebVttFileBuffer-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
Reset() (defined in shaka::media::WebVttFileBuffer)shaka::media::WebVttFileBuffer sample_count() const (defined in shaka::media::WebVttFileBuffer)shaka::media::WebVttFileBufferinline WebVttFileBuffer(uint32_t transport_stream_timestamp_offset_ms, const std::string &style_region_config) (defined in shaka::media::WebVttFileBuffer)shaka::media::WebVttFileBuffer - WriteTo(File *file) (defined in shaka::media::WebVttFileBuffer)shaka::media::WebVttFileBuffer + WriteTo(File *file, uint64_t *size) (defined in shaka::media::WebVttFileBuffer)shaka::media::WebVttFileBuffer ~WebVttFileBuffer()=default (defined in shaka::media::WebVttFileBuffer)shaka::media::WebVttFileBuffervirtual
diff --git a/docs/d8/dd3/classshaka_1_1media_1_1TextMuxer-members.html b/docs/d8/dd3/classshaka_1_1media_1_1TextMuxer-members.html new file mode 100644 index 0000000000..3c4570bd3e --- /dev/null +++ b/docs/d8/dd3/classshaka_1_1media_1_1TextMuxer-members.html @@ -0,0 +1,118 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
shaka::media::TextMuxer Member List
+
+
+ +

This is the complete list of members for shaka::media::TextMuxer, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
Cancel()shaka::media::Muxer
Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
clock() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) constshaka::media::MediaHandlerinlineprotected
DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) constshaka::media::MediaHandlerinlineprotected
DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) constshaka::media::MediaHandlerinlineprotected
DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) constshaka::media::MediaHandlerinlineprotected
FlushAllDownstreams()shaka::media::MediaHandlerprotected
FlushDownstream(size_t output_stream_index)shaka::media::MediaHandlerprotected
Initialize()shaka::media::MediaHandler
initialized() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
InitializeInternal() overrideshaka::media::Muxerinlineprotectedvirtual
IsConnected()shaka::media::MediaHandlerinline
MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandler
Muxer(const MuxerOptions &options) (defined in shaka::media::Muxer)shaka::media::Muxerexplicit
muxer_listener() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
next_output_stream_index() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
num_input_streams() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
OnFlushRequest(size_t input_stream_index) overrideshaka::media::Muxerprotectedvirtual
options() const (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
output_handlers() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
Process(std::unique_ptr< StreamData > stream_data) overrideshaka::media::Muxerprotectedvirtual
progress_listener() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected
set_clock(base::Clock *clock)shaka::media::Muxerinline
SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandler
SetMuxerListener(std::unique_ptr< MuxerListener > muxer_listener)shaka::media::Muxer
SetProgressListener(std::unique_ptr< ProgressListener > progress_listener)shaka::media::Muxer
streams() const (defined in shaka::media::Muxer)shaka::media::Muxerinline
TextMuxer(const MuxerOptions &options) (defined in shaka::media::TextMuxer)shaka::media::TextMuxerexplicit
ValidateOutputStreamIndex(size_t stream_index) constshaka::media::MediaHandlerprotectedvirtual
~MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandlervirtual
~Muxer() (defined in shaka::media::Muxer)shaka::media::Muxervirtual
~TextMuxer() override (defined in shaka::media::TextMuxer)shaka::media::TextMuxer
+ + + + diff --git a/docs/d8/dd6/classshaka_1_1media_1_1mp2t_1_1ContinuityCounter.html b/docs/d8/dd6/classshaka_1_1media_1_1mp2t_1_1ContinuityCounter.html index eb94f60fa1..dff5e02372 100644 --- a/docs/d8/dd6/classshaka_1_1media_1_1mp2t_1_1ContinuityCounter.html +++ b/docs/d8/dd6/classshaka_1_1media_1_1mp2t_1_1ContinuityCounter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::ContinuityCounter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/dd6/structshaka_1_1media_1_1mp4_1_1CencSampleEncryptionInfoEntry.html b/docs/d8/dd6/structshaka_1_1media_1_1mp4_1_1CencSampleEncryptionInfoEntry.html index 555f91495e..d49224cfa8 100644 --- a/docs/d8/dd6/structshaka_1_1media_1_1mp4_1_1CencSampleEncryptionInfoEntry.html +++ b/docs/d8/dd6/structshaka_1_1media_1_1mp4_1_1CencSampleEncryptionInfoEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CencSampleEncryptionInfoEntry Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

Detailed Description

-

Definition at line 496 of file box_definitions.h.

+

Definition at line 509 of file box_definitions.h.


The documentation for this struct was generated from the following files:
diff --git a/docs/d8/de1/classshaka_1_1Period.html b/docs/d8/de1/classshaka_1_1Period.html index eb6d1a0e6a..ec0e3ee19f 100644 --- a/docs/d8/de1/classshaka_1_1Period.html +++ b/docs/d8/de1/classshaka_1_1Period.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::Period Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::MockPeriod - -
+ + - - + + @@ -100,6 +103,8 @@ Public Member Functions void  + +

Public Member Functions

virtual AdaptationSetGetOrCreateAdaptationSet (const MediaInfo &media_info, bool content_protection_in_adaptation_set)
 
xml::scoped_xml_ptr< xmlNode > GetXml (bool output_period_duration)
 
base::Optional< xml::XmlNodeGetXml (bool output_period_duration)
 
const std::list< AdaptationSet * > GetAdaptationSets () const
 
double start_time_in_seconds () const
set_duration_seconds (double duration_seconds)
 Set period duration.
 
const std::map< std::string, std::list< AdaptationSet * > > & trickplay_cache () const
 
@@ -118,7 +123,7 @@ class <

Detailed Description

Period class maps to <Period> element and provides methods to add AdaptationSets.

-

Definition at line 30 of file period.h.

+

Definition at line 26 of file period.h.

Constructor & Destructor Documentation

◆ Period()

@@ -204,7 +209,7 @@ class <
Returns
period duration in seconds.
-

Definition at line 62 of file period.h.

+

Definition at line 58 of file period.h.

@@ -224,7 +229,7 @@ class <
Returns
The list of AdaptationSets in this Period.
-

Definition at line 159 of file period.cc.

+

Definition at line 160 of file period.cc.

@@ -274,14 +279,14 @@ class < - -

◆ GetXml()

+ +

◆ GetXml()

Protected Member Functions

PeriodTest PeriodTest PeriodTest PeriodTest
- + @@ -291,7 +296,7 @@ class <

Generates <Period> xml element with its child AdaptationSet elements.

Returns
On success returns a non-NULL scoped_xml_ptr. Otherwise returns a NULL scoped_xml_ptr.
-

Definition at line 127 of file period.cc.

+

Definition at line 123 of file period.cc.

@@ -319,7 +324,35 @@ class <
Returns
The start time of this Period.
-

Definition at line 59 of file period.h.

+

Definition at line 55 of file period.h.

+ +
+ + +

◆ trickplay_cache()

+ +
+
+
xml::scoped_xml_ptr< xmlNode > shaka::Period::GetXml base::Optional< xml::XmlNode > shaka::Period::GetXml ( bool  output_period_duration)PeriodTest PeriodTest
+ + + + +
+ + + + + + + +
const std::map<std::string, std::list<AdaptationSet*> >& shaka::Period::trickplay_cache () const
+
+inline
+
+
Returns
trickplay_cache.
+ +

Definition at line 66 of file period.h.

@@ -330,9 +363,7 @@ class PeriodTest< diff --git a/docs/d8/de1/classshaka_1_1SimpleMpdNotifier.html b/docs/d8/de1/classshaka_1_1SimpleMpdNotifier.html index 8c6c482f82..cbc99960c7 100644 --- a/docs/d8/de1/classshaka_1_1SimpleMpdNotifier.html +++ b/docs/d8/de1/classshaka_1_1SimpleMpdNotifier.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::SimpleMpdNotifier Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::MpdNotifier - -
+ + @@ -110,6 +113,8 @@ Public Member Functions + + @@ -219,7 +224,7 @@ class 

Public Member Functions

 MpdNotifier (const MpdOptions &mpd_options)
 
bool include_mspr_pro () const
 
DashProfile dash_profile () const
 
MpdType mpd_type () const
SimpleMpdNotifierTes
-

Notifies MpdBuilder that there is a new CueEvent.

Parameters
+

Notifies MpdBuilder that there is a new CueEvent.

Parameters
@@ -279,7 +284,7 @@ class 
container_idContainer ID obtained from calling NotifyNewContainer().
timestampis the timestamp of the CueEvent.
SimpleMpdNotifierTes
-

Notifiers MpdBuilder that there is a new PSSH for the container. This may be called whenever the key has to change, e.g. key rotation.

Parameters
+

Notifiers MpdBuilder that there is a new PSSH for the container. This may be called whenever the key has to change, e.g. key rotation.

Parameters
@@ -376,9 +381,9 @@ class 
container_idContainer ID obtained from calling NotifyNewContainer().
drm_uuidis the UUID of the DRM for encryption.
SimpleMpdNotifierTes
-

Notifies the MpdBuilder that there is a new container along with media_info. Live may have multiple files (segments) but those should be notified via NotifyNewSegment().

Parameters
+

Notifies the MpdBuilder that there is a new container along with media_info. Live may have multiple files (segments) but those should be notified via NotifyNewSegment().

Parameters
- +
media_infois the MediaInfo that will be passed to MpdBuilder.
media_infois the MediaInfo that will be passed to MpdBuilder.
[out]container_idis the numeric ID of the container, possibly for NotifyNewSegment() and AddContentProtectionElement(). Only populated on success.
@@ -436,7 +441,7 @@ class SimpleMpdNotifierTes
-

Notifies MpdBuilder that there is a new segment ready. For live, this is usually a new segment, for VOD this is usually a subsegment.

Parameters
+

Notifies MpdBuilder that there is a new segment ready. For live, this is usually a new segment, for VOD this is usually a subsegment.

Parameters
@@ -508,9 +513,7 @@ class 
container_idContainer ID obtained from calling NotifyNewContainer().
start_timeis the start time of the new segment, in units of the stream's time scale.
SimpleMpdNotifierTes diff --git a/docs/d8/de6/webm__crypto__helpers_8h_source.html b/docs/d8/de6/webm__crypto__helpers_8h_source.html index d436adb1d7..1e09bbe2d3 100644 --- a/docs/d8/de6/webm__crypto__helpers_8h_source.html +++ b/docs/d8/de6/webm__crypto__helpers_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_crypto_helpers.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
webm_crypto_helpers.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CRYPTO_HELPERS_H_
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CRYPTO_HELPERS_H_
7 
8 #include <stdint.h>
9 #include <memory>
10 #include "packager/media/base/decrypt_config.h"
11 
12 namespace shaka {
13 namespace media {
14 
23 bool WebMCreateDecryptConfig(const uint8_t* data,
24  int data_size,
25  const uint8_t* key_id,
26  size_t key_id_size,
27  std::unique_ptr<DecryptConfig>* decrypt_config,
28  int* data_offset);
29 
30 } // namespace media
31 } // namespace shaka
32 
33 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CRYPT_HELPERS_H_
All the methods that are virtual are virtual for mocking.
+
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CRYPTO_HELPERS_H_
+
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CRYPTO_HELPERS_H_
+
7 
+
8 #include <stdint.h>
+
9 #include <memory>
+
10 #include "packager/media/base/decrypt_config.h"
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+
23 bool WebMCreateDecryptConfig(const uint8_t* data,
+
24  int data_size,
+
25  const uint8_t* key_id,
+
26  size_t key_id_size,
+
27  std::unique_ptr<DecryptConfig>* decrypt_config,
+
28  int* data_offset);
+
29 
+
30 } // namespace media
+
31 } // namespace shaka
+
32 
+
33 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CRYPT_HELPERS_H_
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d8/deb/classshaka_1_1media_1_1mp2t_1_1EsParser-members.html b/docs/d8/deb/classshaka_1_1media_1_1mp2t_1_1EsParser-members.html index 0f8459d78f..91765e1f9d 100644 --- a/docs/d8/deb/classshaka_1_1media_1_1mp2t_1_1EsParser-members.html +++ b/docs/d8/deb/classshaka_1_1media_1_1mp2t_1_1EsParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
This is the complete list of members for shaka::media::mp2t::EsParser, including all inherited members.

- - - - - - - + + + + + + + +
EmitSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
Flush()=0 (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserpure virtual
NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts)=0 (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserpure virtual
pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
Reset()=0 (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserpure virtual
~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
EmitTextSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
Flush()=0 (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserpure virtual
NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts)=0 (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserpure virtual
pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
Reset()=0 (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserpure virtual
~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
diff --git a/docs/d8/deb/retired__flags_8cc_source.html b/docs/d8/deb/retired__flags_8cc_source.html index 6ee3cfc3d9..9e3c491076 100644 --- a/docs/d8/deb/retired__flags_8cc_source.html +++ b/docs/d8/deb/retired__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/retired_flags.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
retired_flags.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines retired / deprecated flags. These flags will be removed in later
8 // versions.
9 
10 #include "packager/app/retired_flags.h"
11 
12 #include <stdio.h>
13 
14 DEFINE_string(profile, "", "This flag is deprecated. Do not use.");
15 DEFINE_bool(single_segment, true, "This flag is deprecated. Do not use.");
16 DEFINE_bool(webm_subsample_encryption,
17  true,
18  "This flag is deprecated. Use vp9_subsample_encryption instead.");
19 DEFINE_double(availability_time_offset,
20  0,
21  "This flag is deprecated. Use suggested_presentation_delay "
22  "instead which can achieve similar effect.");
23 DEFINE_string(playready_key_id,
24  "",
25  "This flag is deprecated. Use --enable_raw_key_encryption with "
26  "--generate_playready_pssh to generate PlayReady PSSH.");
27 DEFINE_string(playready_key,
28  "",
29  "This flag is deprecated. Use --enable_raw_key_encryption with "
30  "--generate_playready_pssh to generate PlayReady PSSH.");
31 DEFINE_bool(mp4_use_decoding_timestamp_in_timeline,
32  false,
33  "This flag is deprecated. Do not use.");
34 DEFINE_int32(
35  num_subsegments_per_sidx,
36  0,
37  "This flag is deprecated. Use --generate_sidx_in_media_segments instead.");
38 DEFINE_bool(generate_widevine_pssh,
39  false,
40  "This flag is deprecated. Use --protection_systems instead.");
41 DEFINE_bool(generate_playready_pssh,
42  false,
43  "This flag is deprecated. Use --protection_systems instead.");
44 DEFINE_bool(generate_common_pssh,
45  false,
46  "This flag is deprecated. Use --protection_systems instead.");
47 DEFINE_bool(generate_static_mpd,
48  false,
49  "This flag is deprecated. Use --generate_static_live_mpd instead.");
50 
51 // The current gflags library does not provide a way to check whether a flag is
52 // set in command line. If a flag has a different value to its default value,
53 // the flag must have been set. It is possible that the flag is set to the same
54 // value as its default value though.
55 bool InformRetiredStringFlag(const char* flagname, const std::string& value) {
56  if (!value.empty())
57  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
58  return true;
59 }
60 
61 bool InformRetiredDefaultTrueFlag(const char* flagname, bool value) {
62  if (!value)
63  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
64  return true;
65 }
66 
67 bool InformRetiredDefaultFalseFlag(const char* flagname, bool value) {
68  if (value)
69  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
70  return true;
71 }
72 
73 bool InformRetiredDefaultDoubleFlag(const char* flagname, double value) {
74  if (value != 0)
75  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
76  return true;
77 }
78 
79 bool InformRetiredDefaultInt32Flag(const char* flagname, int32_t value) {
80  if (value != 0)
81  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
82  return true;
83 }
84 
85 bool InformRetiredPsshGenerationFlag(const char* flagname, bool value) {
86  if (value) {
87  fprintf(stderr,
88  "WARNING: %s is deprecated and ignored. Please switch to "
89  "--protection_systems.\n",
90  flagname);
91  }
92  return true;
93 }
94 
95 bool InformRetiredGenerateStaticMpdFlag(const char* flagname, bool value) {
96  if (value) {
97  fprintf(stderr,
98  "WARNING: %s is deprecated and ignored. Please switch to "
99  "--generate_static_live_mpd.\n",
100  flagname);
101  }
102  return true;
103 }
104 
105 DEFINE_validator(profile, &InformRetiredStringFlag);
106 DEFINE_validator(single_segment, &InformRetiredDefaultTrueFlag);
107 DEFINE_validator(webm_subsample_encryption, &InformRetiredDefaultTrueFlag);
108 DEFINE_validator(availability_time_offset, &InformRetiredDefaultDoubleFlag);
109 DEFINE_validator(playready_key_id, &InformRetiredStringFlag);
110 DEFINE_validator(playready_key, &InformRetiredStringFlag);
111 DEFINE_validator(mp4_use_decoding_timestamp_in_timeline,
112  &InformRetiredDefaultFalseFlag);
113 DEFINE_validator(num_subsegments_per_sidx, &InformRetiredDefaultInt32Flag);
114 DEFINE_validator(generate_widevine_pssh, &InformRetiredPsshGenerationFlag);
115 DEFINE_validator(generate_playready_pssh, &InformRetiredPsshGenerationFlag);
116 DEFINE_validator(generate_common_pssh, &InformRetiredPsshGenerationFlag);
117 DEFINE_validator(generate_static_mpd, &InformRetiredGenerateStaticMpdFlag);
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines retired / deprecated flags. These flags will be removed in later
+
8 // versions.
+
9 
+
10 #include "packager/app/retired_flags.h"
+
11 
+
12 #include <stdio.h>
+
13 
+
14 DEFINE_string(profile, "", "This flag is deprecated. Do not use.");
+
15 DEFINE_bool(single_segment, true, "This flag is deprecated. Do not use.");
+
16 DEFINE_bool(webm_subsample_encryption,
+
17  true,
+
18  "This flag is deprecated. Use vp9_subsample_encryption instead.");
+
19 DEFINE_double(availability_time_offset,
+
20  0,
+
21  "This flag is deprecated. Use suggested_presentation_delay "
+
22  "instead which can achieve similar effect.");
+
23 DEFINE_string(playready_key_id,
+
24  "",
+
25  "This flag is deprecated. Use --enable_raw_key_encryption with "
+
26  "--generate_playready_pssh to generate PlayReady PSSH.");
+
27 DEFINE_string(playready_key,
+
28  "",
+
29  "This flag is deprecated. Use --enable_raw_key_encryption with "
+
30  "--generate_playready_pssh to generate PlayReady PSSH.");
+
31 DEFINE_bool(mp4_use_decoding_timestamp_in_timeline,
+
32  false,
+
33  "This flag is deprecated. Do not use.");
+
34 DEFINE_int32(
+
35  num_subsegments_per_sidx,
+
36  0,
+
37  "This flag is deprecated. Use --generate_sidx_in_media_segments instead.");
+
38 DEFINE_bool(generate_widevine_pssh,
+
39  false,
+
40  "This flag is deprecated. Use --protection_systems instead.");
+
41 DEFINE_bool(generate_playready_pssh,
+
42  false,
+
43  "This flag is deprecated. Use --protection_systems instead.");
+
44 DEFINE_bool(generate_common_pssh,
+
45  false,
+
46  "This flag is deprecated. Use --protection_systems instead.");
+
47 DEFINE_bool(generate_static_mpd,
+
48  false,
+
49  "This flag is deprecated. Use --generate_static_live_mpd instead.");
+
50 
+
51 // The current gflags library does not provide a way to check whether a flag is
+
52 // set in command line. If a flag has a different value to its default value,
+
53 // the flag must have been set. It is possible that the flag is set to the same
+
54 // value as its default value though.
+
55 bool InformRetiredStringFlag(const char* flagname, const std::string& value) {
+
56  if (!value.empty())
+
57  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
+
58  return true;
+
59 }
+
60 
+
61 bool InformRetiredDefaultTrueFlag(const char* flagname, bool value) {
+
62  if (!value)
+
63  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
+
64  return true;
+
65 }
+
66 
+
67 bool InformRetiredDefaultFalseFlag(const char* flagname, bool value) {
+
68  if (value)
+
69  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
+
70  return true;
+
71 }
+
72 
+
73 bool InformRetiredDefaultDoubleFlag(const char* flagname, double value) {
+
74  if (value != 0)
+
75  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
+
76  return true;
+
77 }
+
78 
+
79 bool InformRetiredDefaultInt32Flag(const char* flagname, int32_t value) {
+
80  if (value != 0)
+
81  fprintf(stderr, "WARNING: %s is deprecated and ignored.\n", flagname);
+
82  return true;
+
83 }
+
84 
+
85 bool InformRetiredPsshGenerationFlag(const char* flagname, bool value) {
+
86  if (value) {
+
87  fprintf(stderr,
+
88  "WARNING: %s is deprecated and ignored. Please switch to "
+
89  "--protection_systems.\n",
+
90  flagname);
+
91  }
+
92  return true;
+
93 }
+
94 
+
95 bool InformRetiredGenerateStaticMpdFlag(const char* flagname, bool value) {
+
96  if (value) {
+
97  fprintf(stderr,
+
98  "WARNING: %s is deprecated and ignored. Please switch to "
+
99  "--generate_static_live_mpd.\n",
+
100  flagname);
+
101  }
+
102  return true;
+
103 }
+
104 
+
105 DEFINE_validator(profile, &InformRetiredStringFlag);
+
106 DEFINE_validator(single_segment, &InformRetiredDefaultTrueFlag);
+
107 DEFINE_validator(webm_subsample_encryption, &InformRetiredDefaultTrueFlag);
+
108 DEFINE_validator(availability_time_offset, &InformRetiredDefaultDoubleFlag);
+
109 DEFINE_validator(playready_key_id, &InformRetiredStringFlag);
+
110 DEFINE_validator(playready_key, &InformRetiredStringFlag);
+
111 DEFINE_validator(mp4_use_decoding_timestamp_in_timeline,
+
112  &InformRetiredDefaultFalseFlag);
+
113 DEFINE_validator(num_subsegments_per_sidx, &InformRetiredDefaultInt32Flag);
+
114 DEFINE_validator(generate_widevine_pssh, &InformRetiredPsshGenerationFlag);
+
115 DEFINE_validator(generate_playready_pssh, &InformRetiredPsshGenerationFlag);
+
116 DEFINE_validator(generate_common_pssh, &InformRetiredPsshGenerationFlag);
+
117 DEFINE_validator(generate_static_mpd, &InformRetiredGenerateStaticMpdFlag);
+
diff --git a/docs/d8/dec/ttml__to__mp4__handler_8cc_source.html b/docs/d8/dec/ttml__to__mp4__handler_8cc_source.html new file mode 100644 index 0000000000..62f6d68866 --- /dev/null +++ b/docs/d8/dec/ttml__to__mp4__handler_8cc_source.html @@ -0,0 +1,205 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/ttml/ttml_to_mp4_handler.cc Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ttml_to_mp4_handler.cc
+
+
+
1 // Copyright 2020 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/ttml/ttml_to_mp4_handler.h"
+
8 
+
9 #include "packager/status_macros.h"
+
10 
+
11 namespace shaka {
+
12 namespace media {
+
13 namespace ttml {
+
14 
+
15 namespace {
+
16 
+
17 size_t kTrackId = 0;
+
18 
+
19 std::shared_ptr<MediaSample> CreateMediaSample(const std::string& data,
+
20  int64_t start_time,
+
21  int64_t duration) {
+
22  DCHECK_GE(start_time, 0);
+
23  DCHECK_GT(duration, 0);
+
24 
+
25  const bool kIsKeyFrame = true;
+
26 
+
27  std::shared_ptr<MediaSample> sample = MediaSample::CopyFrom(
+
28  reinterpret_cast<const uint8_t*>(data.data()), data.size(), kIsKeyFrame);
+
29  sample->set_pts(start_time);
+
30  sample->set_dts(start_time);
+
31  sample->set_duration(duration);
+
32 
+
33  return sample;
+
34 }
+
35 
+
36 } // namespace
+
37 
+
38 Status TtmlToMp4Handler::InitializeInternal() {
+
39  return Status::OK;
+
40 }
+
41 
+
42 Status TtmlToMp4Handler::Process(std::unique_ptr<StreamData> stream_data) {
+
43  switch (stream_data->stream_data_type) {
+
44  case StreamDataType::kStreamInfo:
+
45  return OnStreamInfo(std::move(stream_data));
+
46  case StreamDataType::kCueEvent:
+
47  return OnCueEvent(std::move(stream_data));
+
48  case StreamDataType::kSegmentInfo:
+
49  return OnSegmentInfo(std::move(stream_data));
+
50  case StreamDataType::kTextSample:
+
51  return OnTextSample(std::move(stream_data));
+
52  default:
+
53  return Status(error::INTERNAL_ERROR,
+
54  "Invalid stream data type (" +
+
55  StreamDataTypeToString(stream_data->stream_data_type) +
+
56  ") for this TtmlToMp4 handler");
+
57  }
+
58 }
+
59 
+
60 Status TtmlToMp4Handler::OnStreamInfo(std::unique_ptr<StreamData> stream_data) {
+
61  DCHECK(stream_data);
+
62  DCHECK(stream_data->stream_info);
+
63 
+
64  auto clone = stream_data->stream_info->Clone();
+
65  clone->set_codec(kCodecTtml);
+
66  clone->set_codec_string("ttml");
+
67 
+
68  if (clone->stream_type() != kStreamText)
+
69  return Status(error::MUXER_FAILURE, "Incorrect stream type");
+
70  auto* text_stream = static_cast<const TextStreamInfo*>(clone.get());
+
71  generator_.Initialize(text_stream->regions(), text_stream->language(),
+
72  text_stream->time_scale());
+
73 
+
74  return Dispatch(
+
75  StreamData::FromStreamInfo(stream_data->stream_index, std::move(clone)));
+
76 }
+
77 
+
78 Status TtmlToMp4Handler::OnCueEvent(std::unique_ptr<StreamData> stream_data) {
+
79  DCHECK(stream_data);
+
80  DCHECK(stream_data->cue_event);
+
81  return Dispatch(std::move(stream_data));
+
82 }
+
83 
+
84 Status TtmlToMp4Handler::OnSegmentInfo(
+
85  std::unique_ptr<StreamData> stream_data) {
+
86  DCHECK(stream_data);
+
87  DCHECK(stream_data->segment_info);
+
88 
+
89  const auto& segment = stream_data->segment_info;
+
90 
+
91  std::string data;
+
92  if (!generator_.Dump(&data))
+
93  return Status(error::INTERNAL_ERROR, "Error generating XML");
+
94  generator_.Reset();
+
95 
+
96  RETURN_IF_ERROR(DispatchMediaSample(
+
97  kTrackId,
+
98  CreateMediaSample(data, segment->start_timestamp, segment->duration)));
+
99 
+
100  return Dispatch(std::move(stream_data));
+
101 }
+
102 
+
103 Status TtmlToMp4Handler::OnTextSample(std::unique_ptr<StreamData> stream_data) {
+
104  DCHECK(stream_data);
+
105  DCHECK(stream_data->text_sample);
+
106 
+
107  auto& sample = stream_data->text_sample;
+
108 
+
109  // Ignore empty samples. This will create gaps, but we will handle that
+
110  // later.
+
111  if (sample->body().is_empty()) {
+
112  return Status::OK;
+
113  }
+
114 
+
115  // Add the new text sample to the cache of samples that belong in the
+
116  // current segment.
+
117  generator_.AddSample(*sample);
+
118  return Status::OK;
+
119 }
+
120 
+
121 } // namespace ttml
+
122 } // namespace media
+
123 } // namespace shaka
+
Status DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
Dispatch the media sample to downstream handlers.
+
Status Dispatch(std::unique_ptr< StreamData > stream_data) const
+
static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
Definition: media_sample.cc:42
+
All the methods that are virtual are virtual for mocking.
+
+ + + + diff --git a/docs/d8/dee/classshaka_1_1media_1_1AudioTimestampHelper-members.html b/docs/d8/dee/classshaka_1_1media_1_1AudioTimestampHelper-members.html index 9aef46d09f..eefd28c405 100644 --- a/docs/d8/dee/classshaka_1_1media_1_1AudioTimestampHelper-members.html +++ b/docs/d8/dee/classshaka_1_1media_1_1AudioTimestampHelper-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/dee/classshaka_1_1media_1_1VPxParser-members.html b/docs/d8/dee/classshaka_1_1media_1_1VPxParser-members.html index 53b4376eb7..e8c1c4e013 100644 --- a/docs/d8/dee/classshaka_1_1media_1_1VPxParser-members.html +++ b/docs/d8/dee/classshaka_1_1media_1_1VPxParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d8/df0/webm_2single__segment__segmenter_8cc_source.html b/docs/d8/df0/webm_2single__segment__segmenter_8cc_source.html index 56e21720b6..ad4efb6139 100644 --- a/docs/d8/df0/webm_2single__segment__segmenter_8cc_source.html +++ b/docs/d8/df0/webm_2single__segment__segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/single_segment_segmenter.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
single_segment_segmenter.cc
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/formats/webm/single_segment_segmenter.h"
8 
9 #include "packager/media/base/muxer_options.h"
10 #include "packager/media/event/muxer_listener.h"
11 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
12 
13 namespace shaka {
14 namespace media {
15 namespace webm {
16 
17 SingleSegmentSegmenter::SingleSegmentSegmenter(const MuxerOptions& options)
18  : Segmenter(options), init_end_(0), index_start_(0) {}
19 
20 SingleSegmentSegmenter::~SingleSegmentSegmenter() {}
21 
23  uint64_t duration_timestamp,
24  bool is_subsegment) {
25  Status status = Segmenter::FinalizeSegment(start_timestamp,
26  duration_timestamp, is_subsegment);
27  if (!status.ok())
28  return status;
29  // No-op for subsegment in single segment mode.
30  if (is_subsegment)
31  return Status::OK;
32  CHECK(cluster());
33  if (!cluster()->Finalize())
34  return Status(error::FILE_FAILURE, "Error finalizing cluster.");
35  if (muxer_listener()) {
36  const uint64_t size = cluster()->Size();
37  muxer_listener()->OnNewSegment(options().output_file_name, start_timestamp,
38  duration_timestamp, size);
39  }
40  return Status::OK;
41 }
42 
43 bool SingleSegmentSegmenter::GetInitRangeStartAndEnd(uint64_t* start,
44  uint64_t* end) {
45  *start = 0;
46  *end = init_end_;
47  return true;
48 }
49 
50 bool SingleSegmentSegmenter::GetIndexRangeStartAndEnd(uint64_t* start,
51  uint64_t* end) {
52  *start = index_start_;
53  *end = index_end_;
54  return true;
55 }
56 
57 std::vector<Range> SingleSegmentSegmenter::GetSegmentRanges() {
58  std::vector<Range> ranges;
59  if (cues()->cue_entries_size() == 0) {
60  return ranges;
61  }
62  for (int32_t i = 0; i < cues()->cue_entries_size() - 1; ++i) {
63  const mkvmuxer::CuePoint* cue_point = cues()->GetCueByIndex(i);
64  Range r;
65  // Cue point cluster position is relative to segment payload pos.
66  r.start = segment_payload_pos() + cue_point->cluster_pos();
67  r.end =
68  segment_payload_pos() + cues()->GetCueByIndex(i + 1)->cluster_pos() - 1;
69  ranges.push_back(r);
70  }
71 
72  Range last_range;
73  const mkvmuxer::CuePoint* last_cue_point =
74  cues()->GetCueByIndex(cues()->cue_entries_size() - 1);
75  last_range.start = segment_payload_pos() + last_cue_point->cluster_pos();
76  last_range.end = last_range.start + cluster()->Size() - 1;
77  ranges.push_back(last_range);
78  return ranges;
79 }
80 
81 Status SingleSegmentSegmenter::DoInitialize() {
82  if (!writer_) {
83  std::unique_ptr<MkvWriter> writer(new MkvWriter);
84  Status status = writer->Open(options().output_file_name);
85  if (!status.ok())
86  return status;
87  writer_ = std::move(writer);
88  }
89 
90  Status ret = WriteSegmentHeader(0, writer_.get());
91  init_end_ = writer_->Position() - 1;
92  seek_head()->set_cluster_pos(init_end_ + 1 - segment_payload_pos());
93  return ret;
94 }
95 
96 Status SingleSegmentSegmenter::DoFinalize() {
97  // Write the Cues to the end of the file.
98  index_start_ = writer_->Position();
99  seek_head()->set_cues_pos(index_start_ - segment_payload_pos());
100  if (!cues()->Write(writer_.get()))
101  return Status(error::FILE_FAILURE, "Error writing Cues data.");
102 
103  // The WebM index is at the end of the file.
104  index_end_ = writer_->Position() - 1;
105  writer_->Position(0);
106 
107  Status status = WriteSegmentHeader(index_end_ + 1, writer_.get());
108  status.Update(writer_->Close());
109  return status;
110 }
111 
112 Status SingleSegmentSegmenter::NewSegment(uint64_t start_timestamp,
113  bool is_subsegment) {
114  // No-op for subsegment in single segment mode.
115  if (is_subsegment)
116  return Status::OK;
117  // Create a new Cue point.
118  uint64_t position = writer_->Position();
119  uint64_t start_timecode = FromBmffTimestamp(start_timestamp);
120 
121  mkvmuxer::CuePoint* cue_point = new mkvmuxer::CuePoint;
122  cue_point->set_time(start_timecode);
123  cue_point->set_track(track_id());
124  cue_point->set_cluster_pos(position - segment_payload_pos());
125  if (!cues()->AddCue(cue_point))
126  return Status(error::INTERNAL_ERROR, "Error adding CuePoint.");
127 
128  return SetCluster(start_timecode, position, writer_.get());
129 }
130 
131 } // namespace webm
132 } // namespace media
133 } // namespace shaka
All the methods that are virtual are virtual for mocking.
- -
An implementation of IMkvWriter using our File type.
Definition: mkv_writer.h:21
-
virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
-
void Update(Status new_status)
Definition: status.cc:78
- -
Status FinalizeSegment(size_t stream_id, const SegmentInfo &segment_info)
Definition: segmenter.cc:147
- +
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/formats/webm/single_segment_segmenter.h"
+
8 
+
9 #include "packager/media/base/muxer_options.h"
+
10 #include "packager/media/event/muxer_listener.h"
+
11 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
+
12 
+
13 namespace shaka {
+
14 namespace media {
+
15 namespace webm {
+
16 
+
17 SingleSegmentSegmenter::SingleSegmentSegmenter(const MuxerOptions& options)
+
18  : Segmenter(options), init_end_(0), index_start_(0) {}
+
19 
+
20 SingleSegmentSegmenter::~SingleSegmentSegmenter() {}
+
21 
+
22 Status SingleSegmentSegmenter::FinalizeSegment(uint64_t start_timestamp,
+
23  uint64_t duration_timestamp,
+
24  bool is_subsegment) {
+
25  Status status = Segmenter::FinalizeSegment(start_timestamp,
+
26  duration_timestamp, is_subsegment);
+
27  if (!status.ok())
+
28  return status;
+
29  // No-op for subsegment in single segment mode.
+
30  if (is_subsegment)
+
31  return Status::OK;
+
32  CHECK(cluster());
+
33  if (!cluster()->Finalize())
+
34  return Status(error::FILE_FAILURE, "Error finalizing cluster.");
+
35  if (muxer_listener()) {
+
36  const uint64_t size = cluster()->Size();
+
37  muxer_listener()->OnNewSegment(options().output_file_name, start_timestamp,
+
38  duration_timestamp, size);
+
39  }
+
40  return Status::OK;
+
41 }
+
42 
+
43 bool SingleSegmentSegmenter::GetInitRangeStartAndEnd(uint64_t* start,
+
44  uint64_t* end) {
+
45  *start = 0;
+
46  *end = init_end_;
+
47  return true;
+
48 }
+
49 
+
50 bool SingleSegmentSegmenter::GetIndexRangeStartAndEnd(uint64_t* start,
+
51  uint64_t* end) {
+
52  *start = index_start_;
+
53  *end = index_end_;
+
54  return true;
+
55 }
+
56 
+
57 std::vector<Range> SingleSegmentSegmenter::GetSegmentRanges() {
+
58  std::vector<Range> ranges;
+
59  if (cues()->cue_entries_size() == 0) {
+
60  return ranges;
+
61  }
+
62  for (int32_t i = 0; i < cues()->cue_entries_size() - 1; ++i) {
+
63  const mkvmuxer::CuePoint* cue_point = cues()->GetCueByIndex(i);
+
64  Range r;
+
65  // Cue point cluster position is relative to segment payload pos.
+
66  r.start = segment_payload_pos() + cue_point->cluster_pos();
+
67  r.end =
+
68  segment_payload_pos() + cues()->GetCueByIndex(i + 1)->cluster_pos() - 1;
+
69  ranges.push_back(r);
+
70  }
+
71 
+
72  Range last_range;
+
73  const mkvmuxer::CuePoint* last_cue_point =
+
74  cues()->GetCueByIndex(cues()->cue_entries_size() - 1);
+
75  last_range.start = segment_payload_pos() + last_cue_point->cluster_pos();
+
76  last_range.end = last_range.start + cluster()->Size() - 1;
+
77  ranges.push_back(last_range);
+
78  return ranges;
+
79 }
+
80 
+
81 Status SingleSegmentSegmenter::DoInitialize() {
+
82  if (!writer_) {
+
83  std::unique_ptr<MkvWriter> writer(new MkvWriter);
+
84  Status status = writer->Open(options().output_file_name);
+
85  if (!status.ok())
+
86  return status;
+
87  writer_ = std::move(writer);
+
88  }
+
89 
+
90  Status ret = WriteSegmentHeader(0, writer_.get());
+
91  init_end_ = writer_->Position() - 1;
+
92  seek_head()->set_cluster_pos(init_end_ + 1 - segment_payload_pos());
+
93  return ret;
+
94 }
+
95 
+
96 Status SingleSegmentSegmenter::DoFinalize() {
+
97  // Write the Cues to the end of the file.
+
98  index_start_ = writer_->Position();
+
99  seek_head()->set_cues_pos(index_start_ - segment_payload_pos());
+
100  if (!cues()->Write(writer_.get()))
+
101  return Status(error::FILE_FAILURE, "Error writing Cues data.");
+
102 
+
103  // The WebM index is at the end of the file.
+
104  index_end_ = writer_->Position() - 1;
+
105  writer_->Position(0);
+
106 
+
107  Status status = WriteSegmentHeader(index_end_ + 1, writer_.get());
+
108  status.Update(writer_->Close());
+
109  return status;
+
110 }
+
111 
+
112 Status SingleSegmentSegmenter::NewSegment(uint64_t start_timestamp,
+
113  bool is_subsegment) {
+
114  // No-op for subsegment in single segment mode.
+
115  if (is_subsegment)
+
116  return Status::OK;
+
117  // Create a new Cue point.
+
118  uint64_t position = writer_->Position();
+
119  uint64_t start_timecode = FromBmffTimestamp(start_timestamp);
+
120 
+
121  mkvmuxer::CuePoint* cue_point = new mkvmuxer::CuePoint;
+
122  cue_point->set_time(start_timecode);
+
123  cue_point->set_track(track_id());
+
124  cue_point->set_cluster_pos(position - segment_payload_pos());
+
125  if (!cues()->AddCue(cue_point))
+
126  return Status(error::INTERNAL_ERROR, "Error adding CuePoint.");
+
127 
+
128  return SetCluster(start_timecode, position, writer_.get());
+
129 }
+
130 
+
131 } // namespace webm
+
132 } // namespace media
+
133 } // namespace shaka
+ +
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d8/df7/classshaka_1_1media_1_1SegmentTestBase-members.html b/docs/d8/df7/classshaka_1_1media_1_1SegmentTestBase-members.html index b0d1f76efd..03ab50d0e7 100644 --- a/docs/d8/df7/classshaka_1_1media_1_1SegmentTestBase-members.html +++ b/docs/d8/df7/classshaka_1_1media_1_1SegmentTestBase-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d8/df8/classshaka_1_1media_1_1TextPadder.html b/docs/d8/df8/classshaka_1_1media_1_1TextPadder.html index 188f408615..d04ba6ca64 100644 --- a/docs/d8/df8/classshaka_1_1media_1_1TextPadder.html +++ b/docs/d8/df8/classshaka_1_1media_1_1TextPadder.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::TextPadder Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::MediaHandler - -
+ + @@ -104,9 +107,9 @@ bool  - - + + @@ -205,9 +208,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/d8/dfa/nal__unit__to__byte__stream__converter_8h_source.html b/docs/d8/dfa/nal__unit__to__byte__stream__converter_8h_source.html index 6c548402c0..745873dea5 100644 --- a/docs/d8/dfa/nal__unit__to__byte__stream__converter_8h_source.html +++ b/docs/d8/dfa/nal__unit__to__byte__stream__converter_8h_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/codecs/nal_unit_to_byte_stream_converter.h Source File @@ -29,18 +29,21 @@

Public Member Functions

Additional Inherited Members

- Static Public Member Functions inherited from shaka::media::MediaHandler
-static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
 
+static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
 
- Protected Member Functions inherited from shaka::media::MediaHandler
virtual Status OnFlushRequest (size_t input_stream_index)
- + +/* @license-end */
nal_unit_to_byte_stream_converter.h
-
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_CODECS_NAL_UNIT_TO_BYTE_STREAM_CONVERTER_H_
8 #define PACKAGER_MEDIA_CODECS_NAL_UNIT_TO_BYTE_STREAM_CONVERTER_H_
9 
10 #include <stdint.h>
11 #include <vector>
12 
13 #include "packager/base/macros.h"
14 #include "packager/media/base/decrypt_config.h"
15 #include "packager/media/codecs/avc_decoder_configuration_record.h"
16 
17 namespace shaka {
18 namespace media {
19 
20 class BufferWriter;
21 class VideoStreamInfo;
22 
30 void EscapeNalByteSequence(const uint8_t* input,
31  size_t input_size,
32  BufferWriter* output);
33 
34 // Methods are virtual for mocking.
36  public:
39 
45  virtual bool Initialize(const uint8_t* decoder_configuration_data,
46  size_t decoder_configuration_data_size);
47 
56  virtual bool ConvertUnitToByteStream(const uint8_t* sample,
57  size_t sample_size,
58  bool is_key_frame,
59  std::vector<uint8_t>* output);
60 
76  const uint8_t* sample,
77  size_t sample_size,
78  bool is_key_frame,
79  bool escape_encrypted_nalu,
80  std::vector<uint8_t>* output,
81  std::vector<SubsampleEntry>* subsamples);
82 
83  private:
84  friend class NalUnitToByteStreamConverterTest;
85 
86  int nalu_length_size_;
87  AVCDecoderConfigurationRecord decoder_config_;
88  std::vector<uint8_t> decoder_configuration_in_byte_stream_;
89 
90  DISALLOW_COPY_AND_ASSIGN(NalUnitToByteStreamConverter);
91 };
92 
93 } // namespace media
94 } // namespace shaka
95 
96 #endif // PACKAGER_MEDIA_CODECS_NAL_UNIT_TO_BYTE_STREAM_CONVERTER_H_
virtual bool ConvertUnitToByteStream(const uint8_t *sample, size_t sample_size, bool is_key_frame, std::vector< uint8_t > *output)
-
virtual bool Initialize(const uint8_t *decoder_configuration_data, size_t decoder_configuration_data_size)
-
All the methods that are virtual are virtual for mocking.
-
virtual bool ConvertUnitToByteStreamWithSubsamples(const uint8_t *sample, size_t sample_size, bool is_key_frame, bool escape_encrypted_nalu, std::vector< uint8_t > *output, std::vector< SubsampleEntry > *subsamples)
-
Class for parsing AVC decoder configuration record.
- +
1 // Copyright 2016 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_CODECS_NAL_UNIT_TO_BYTE_STREAM_CONVERTER_H_
+
8 #define PACKAGER_MEDIA_CODECS_NAL_UNIT_TO_BYTE_STREAM_CONVERTER_H_
+
9 
+
10 #include <stdint.h>
+
11 #include <vector>
+
12 
+
13 #include "packager/base/macros.h"
+
14 #include "packager/media/base/decrypt_config.h"
+
15 #include "packager/media/codecs/avc_decoder_configuration_record.h"
+
16 
+
17 namespace shaka {
+
18 namespace media {
+
19 
+
20 class BufferWriter;
+
21 class VideoStreamInfo;
+
22 
+
30 void EscapeNalByteSequence(const uint8_t* input,
+
31  size_t input_size,
+
32  BufferWriter* output);
+
33 
+
34 // Methods are virtual for mocking.
+ +
36  public:
+ + +
39 
+
45  virtual bool Initialize(const uint8_t* decoder_configuration_data,
+
46  size_t decoder_configuration_data_size);
+
47 
+
56  virtual bool ConvertUnitToByteStream(const uint8_t* sample,
+
57  size_t sample_size,
+
58  bool is_key_frame,
+
59  std::vector<uint8_t>* output);
+
60 
+ +
76  const uint8_t* sample,
+
77  size_t sample_size,
+
78  bool is_key_frame,
+
79  bool escape_encrypted_nalu,
+
80  std::vector<uint8_t>* output,
+
81  std::vector<SubsampleEntry>* subsamples);
+
82 
+
83  private:
+
84  friend class NalUnitToByteStreamConverterTest;
+
85 
+
86  int nalu_length_size_;
+
87  AVCDecoderConfigurationRecord decoder_config_;
+
88  std::vector<uint8_t> decoder_configuration_in_byte_stream_;
+
89 
+
90  DISALLOW_COPY_AND_ASSIGN(NalUnitToByteStreamConverter);
+
91 };
+
92 
+
93 } // namespace media
+
94 } // namespace shaka
+
95 
+
96 #endif // PACKAGER_MEDIA_CODECS_NAL_UNIT_TO_BYTE_STREAM_CONVERTER_H_
+
Class for parsing AVC decoder configuration record.
+ +
virtual bool Initialize(const uint8_t *decoder_configuration_data, size_t decoder_configuration_data_size)
+
virtual bool ConvertUnitToByteStream(const uint8_t *sample, size_t sample_size, bool is_key_frame, std::vector< uint8_t > *output)
+
virtual bool ConvertUnitToByteStreamWithSubsamples(const uint8_t *sample, size_t sample_size, bool is_key_frame, bool escape_encrypted_nalu, std::vector< uint8_t > *output, std::vector< SubsampleEntry > *subsamples)
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d9/d00/structshaka_1_1media_1_1OnMediaEndParameters-members.html b/docs/d9/d00/structshaka_1_1media_1_1OnMediaEndParameters-members.html index fd78e7123f..f884b183e3 100644 --- a/docs/d9/d00/structshaka_1_1media_1_1OnMediaEndParameters-members.html +++ b/docs/d9/d00/structshaka_1_1media_1_1OnMediaEndParameters-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d9/d01/mp4_2single__segment__segmenter_8h_source.html b/docs/d9/d01/mp4_2single__segment__segmenter_8h_source.html index e4bc8a29fe..3ce97f69b9 100644 --- a/docs/d9/d01/mp4_2single__segment__segmenter_8h_source.html +++ b/docs/d9/d01/mp4_2single__segment__segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/single_segment_segmenter.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
single_segment_segmenter.h
-
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_SINGLE_SEGMENT_SEGMENTER_H_
8 #define PACKAGER_MEDIA_FORMATS_MP4_SINGLE_SEGMENT_SEGMENTER_H_
9 
10 #include "packager/file/file_closer.h"
11 #include "packager/media/event/muxer_listener.h"
12 #include "packager/media/formats/mp4/segmenter.h"
13 
14 namespace shaka {
15 namespace media {
16 namespace mp4 {
17 
30  public:
31  SingleSegmentSegmenter(const MuxerOptions& options,
32  std::unique_ptr<FileType> ftyp,
33  std::unique_ptr<Movie> moov);
34  ~SingleSegmentSegmenter() override;
35 
38  bool GetInitRange(size_t* offset, size_t* size) override;
39  bool GetIndexRange(size_t* offset, size_t* size) override;
40  std::vector<Range> GetSegmentRanges() override;
42 
43  private:
44  // Segmenter implementation overrides.
45  Status DoInitialize() override;
46  Status DoFinalize() override;
47  Status DoFinalizeSegment() override;
48 
49  std::unique_ptr<SegmentIndex> vod_sidx_;
50  std::string temp_file_name_;
51  std::unique_ptr<File, FileCloser> temp_file_;
52 
53  DISALLOW_COPY_AND_ASSIGN(SingleSegmentSegmenter);
54 };
55 
56 } // namespace mp4
57 } // namespace media
58 } // namespace shaka
59 
60 #endif // PACKAGER_MEDIA_FORMATS_MP4_SINGLE_SEGMENT_SEGMENTER_H_
bool GetIndexRange(size_t *offset, size_t *size) override
-
All the methods that are virtual are virtual for mocking.
-
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
- - - -
bool GetInitRange(size_t *offset, size_t *size) override
+
1 // Copyright 2014 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_SINGLE_SEGMENT_SEGMENTER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_MP4_SINGLE_SEGMENT_SEGMENTER_H_
+
9 
+
10 #include "packager/file/file_closer.h"
+
11 #include "packager/media/event/muxer_listener.h"
+
12 #include "packager/media/formats/mp4/segmenter.h"
+
13 
+
14 namespace shaka {
+
15 namespace media {
+
16 namespace mp4 {
+
17 
+ +
29  public:
+
30  SingleSegmentSegmenter(const MuxerOptions& options,
+
31  std::unique_ptr<FileType> ftyp,
+
32  std::unique_ptr<Movie> moov);
+
33  ~SingleSegmentSegmenter() override;
+
34 
+
37  bool GetInitRange(size_t* offset, size_t* size) override;
+
38  bool GetIndexRange(size_t* offset, size_t* size) override;
+
39  std::vector<Range> GetSegmentRanges() override;
+
41 
+
42  private:
+
43  // Segmenter implementation overrides.
+
44  Status DoInitialize() override;
+
45  Status DoFinalize() override;
+
46  Status DoFinalizeSegment() override;
+
47 
+
48  std::unique_ptr<SegmentIndex> vod_sidx_;
+
49  std::string temp_file_name_;
+
50  std::unique_ptr<File, FileCloser> temp_file_;
+
51 
+
52  DISALLOW_COPY_AND_ASSIGN(SingleSegmentSegmenter);
+
53 };
+
54 
+
55 } // namespace mp4
+
56 } // namespace media
+
57 } // namespace shaka
+
58 
+
59 #endif // PACKAGER_MEDIA_FORMATS_MP4_SINGLE_SEGMENT_SEGMENTER_H_
+ + + +
bool GetIndexRange(size_t *offset, size_t *size) override
+
bool GetInitRange(size_t *offset, size_t *size) override
+
All the methods that are virtual are virtual for mocking.
+
This structure contains the list of configuration options for Muxer.
Definition: muxer_options.h:20
diff --git a/docs/d9/d08/mock__mpd__builder_8h_source.html b/docs/d9/d08/mock__mpd__builder_8h_source.html index c74a7cbbb9..a130fb3dbf 100644 --- a/docs/d9/d08/mock__mpd__builder_8h_source.html +++ b/docs/d9/d08/mock__mpd__builder_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mock_mpd_builder.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
mock_mpd_builder.h
-
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef MPD_BASE_MOCK_MPD_BUILDER_H_
8 #define MPD_BASE_MOCK_MPD_BUILDER_H_
9 
10 #include <gmock/gmock.h>
11 
12 #include "packager/base/compiler_specific.h"
13 #include "packager/base/synchronization/lock.h"
14 #include "packager/mpd/base/adaptation_set.h"
15 #include "packager/mpd/base/content_protection_element.h"
16 #include "packager/mpd/base/mpd_builder.h"
17 #include "packager/mpd/base/period.h"
18 #include "packager/mpd/base/representation.h"
19 
20 namespace shaka {
21 
22 class MockMpdBuilder : public MpdBuilder {
23  public:
25  ~MockMpdBuilder() override;
26 
27  MOCK_METHOD1(GetOrCreatePeriod, Period*(double start_time_in_seconds));
28  MOCK_METHOD1(ToString, bool(std::string* output));
29 };
30 
31 class MockPeriod : public Period {
32  public:
33  MockPeriod(uint32_t period_id, double start_time_in_seconds);
34 
35  MOCK_METHOD2(GetOrCreateAdaptationSet,
36  AdaptationSet*(const MediaInfo& media_info,
37  bool content_protection_in_adaptation_set));
38 
39  private:
40  // Only for constructing the super class. Not used for testing.
41  uint32_t sequence_counter_ = 0;
42 };
43 
45  public:
47  ~MockAdaptationSet() override;
48 
49  MOCK_METHOD1(AddRepresentation, Representation*(const MediaInfo& media_info));
50  MOCK_METHOD1(CopyRepresentation,
51  Representation*(const Representation& representation));
52  MOCK_METHOD1(AddContentProtectionElement,
53  void(const ContentProtectionElement& element));
54  MOCK_METHOD2(UpdateContentProtectionPssh,
55  void(const std::string& drm_uuid, const std::string& pssh));
56  MOCK_METHOD1(AddRole, void(AdaptationSet::Role role));
57  MOCK_METHOD1(ForceSetSegmentAlignment, void(bool segment_alignment));
58  MOCK_METHOD1(AddAdaptationSetSwitching,
59  void(const AdaptationSet* adaptation_set));
60  MOCK_METHOD1(AddTrickPlayReference,
61  void(const AdaptationSet* adaptation_set));
62 
63  private:
64  // Only for constructing the super class. Not used for testing.
65  uint32_t sequence_counter_ = 0;
66 };
67 
69  public:
70  // |representation_id| is the numeric ID for the <Representation>.
71  explicit MockRepresentation(uint32_t representation_id);
72  ~MockRepresentation() override;
73 
74  MOCK_METHOD1(AddContentProtectionElement,
75  void(const ContentProtectionElement& element));
76  MOCK_METHOD2(UpdateContentProtectionPssh,
77  void(const std::string& drm_uuid, const std::string& pssh));
78  MOCK_METHOD3(AddNewSegment,
79  void(int64_t start_time, int64_t duration, uint64_t size));
80  MOCK_METHOD1(SetSampleDuration, void(uint32_t sample_duration));
81  MOCK_CONST_METHOD0(GetMediaInfo, const MediaInfo&());
82 };
83 
84 } // namespace shaka
85 
86 #endif // MPD_BASE_MOCK_MPD_BUILDER_H_
- -
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:37
- -
All the methods that are virtual are virtual for mocking.
- -
virtual Period * GetOrCreatePeriod(double start_time_in_seconds)
Definition: mpd_builder.cc:143
-
virtual bool ToString(std::string *output)
Definition: mpd_builder.cc:157
- - - - +
1 // Copyright 2015 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef MPD_BASE_MOCK_MPD_BUILDER_H_
+
8 #define MPD_BASE_MOCK_MPD_BUILDER_H_
+
9 
+
10 #include <gmock/gmock.h>
+
11 
+
12 #include "packager/base/compiler_specific.h"
+
13 #include "packager/base/synchronization/lock.h"
+
14 #include "packager/mpd/base/adaptation_set.h"
+
15 #include "packager/mpd/base/content_protection_element.h"
+
16 #include "packager/mpd/base/mpd_builder.h"
+
17 #include "packager/mpd/base/period.h"
+
18 #include "packager/mpd/base/representation.h"
+
19 
+
20 namespace shaka {
+
21 
+
22 class MockMpdBuilder : public MpdBuilder {
+
23  public:
+ +
25  ~MockMpdBuilder() override;
+
26 
+
27  MOCK_METHOD1(GetOrCreatePeriod, Period*(double start_time_in_seconds));
+
28  MOCK_METHOD1(ToString, bool(std::string* output));
+
29 };
+
30 
+
31 class MockPeriod : public Period {
+
32  public:
+
33  MockPeriod(uint32_t period_id, double start_time_in_seconds);
+
34 
+
35  MOCK_METHOD2(GetOrCreateAdaptationSet,
+
36  AdaptationSet*(const MediaInfo& media_info,
+
37  bool content_protection_in_adaptation_set));
+
38 
+
39  private:
+
40  // Only for constructing the super class. Not used for testing.
+
41  uint32_t sequence_counter_ = 0;
+
42 };
+
43 
+ +
45  public:
+ +
47  ~MockAdaptationSet() override;
+
48 
+
49  MOCK_METHOD1(AddRepresentation, Representation*(const MediaInfo& media_info));
+
50  MOCK_METHOD1(CopyRepresentation,
+
51  Representation*(const Representation& representation));
+
52  MOCK_METHOD1(AddContentProtectionElement,
+
53  void(const ContentProtectionElement& element));
+
54  MOCK_METHOD2(UpdateContentProtectionPssh,
+
55  void(const std::string& drm_uuid, const std::string& pssh));
+
56  MOCK_METHOD1(AddRole, void(AdaptationSet::Role role));
+
57  MOCK_METHOD1(ForceSetSegmentAlignment, void(bool segment_alignment));
+
58  MOCK_METHOD1(AddAdaptationSetSwitching,
+
59  void(const AdaptationSet* adaptation_set));
+
60  MOCK_METHOD1(AddTrickPlayReference,
+
61  void(const AdaptationSet* adaptation_set));
+
62 
+
63  private:
+
64  // Only for constructing the super class. Not used for testing.
+
65  uint32_t sequence_counter_ = 0;
+
66 };
+
67 
+ +
69  public:
+
70  // |representation_id| is the numeric ID for the <Representation>.
+
71  explicit MockRepresentation(uint32_t representation_id);
+
72  ~MockRepresentation() override;
+
73 
+
74  MOCK_METHOD1(AddContentProtectionElement,
+
75  void(const ContentProtectionElement& element));
+
76  MOCK_METHOD2(UpdateContentProtectionPssh,
+
77  void(const std::string& drm_uuid, const std::string& pssh));
+
78  MOCK_METHOD3(AddNewSegment,
+
79  void(int64_t start_time, int64_t duration, uint64_t size));
+
80  MOCK_METHOD1(SetSampleDuration, void(uint32_t sample_duration));
+
81  MOCK_CONST_METHOD0(GetMediaInfo, const MediaInfo&());
+
82 };
+
83 
+
84 } // namespace shaka
+
85 
+
86 #endif // MPD_BASE_MOCK_MPD_BUILDER_H_
+ +
virtual Representation * AddRepresentation(const MediaInfo &media_info)
+
virtual void AddContentProtectionElement(const ContentProtectionElement &element)
+
virtual void ForceSetSegmentAlignment(bool segment_alignment)
+
virtual Representation * CopyRepresentation(const Representation &representation)
+
virtual void AddTrickPlayReference(const AdaptationSet *adaptation_set)
+
virtual void AddAdaptationSetSwitching(const AdaptationSet *adaptation_set)
+
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
+
virtual void AddRole(Role role)
+ + + + +
This class generates DASH MPDs (Media Presentation Descriptions).
Definition: mpd_builder.h:36
+
virtual bool ToString(std::string *output) WARN_UNUSED_RESULT
Definition: mpd_builder.cc:159
+
virtual Period * GetOrCreatePeriod(double start_time_in_seconds)
Definition: mpd_builder.cc:145
+ +
virtual AdaptationSet * GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)
Definition: period.cc:74
+
double start_time_in_seconds() const
Definition: period.h:55
+ +
virtual void SetSampleDuration(uint32_t sample_duration)
+
virtual void AddContentProtectionElement(const ContentProtectionElement &element)
+
virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
+
virtual const MediaInfo & GetMediaInfo() const
+
virtual void AddNewSegment(int64_t start_time, int64_t duration, uint64_t size)
+
All the methods that are virtual are virtual for mocking.
+
diff --git a/docs/d9/d0b/classshaka_1_1media_1_1HlsNotifyMuxerListener-members.html b/docs/d9/d0b/classshaka_1_1media_1_1HlsNotifyMuxerListener-members.html index 2e3d83668c..a66ff8ae5a 100644 --- a/docs/d9/d0b/classshaka_1_1media_1_1HlsNotifyMuxerListener-members.html +++ b/docs/d9/d0b/classshaka_1_1media_1_1HlsNotifyMuxerListener-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d9/d0c/classshaka_1_1media_1_1RsaPublicKey.html b/docs/d9/d0c/classshaka_1_1media_1_1RsaPublicKey.html index c4001ea5c6..84fbbe8c13 100644 --- a/docs/d9/d0c/classshaka_1_1media_1_1RsaPublicKey.html +++ b/docs/d9/d0c/classshaka_1_1media_1_1RsaPublicKey.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::RsaPublicKey Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-

Create an RsaPublicKey object using a DER encoded PKCS#1 RSAPublicKey.

Returns
The created RsaPrivateKey object on success, NULL otherwise.
+

Create an RsaPublicKey object using a DER encoded PKCS#1 RSAPublicKey.

Returns
The created RsaPrivateKey object on success, NULL otherwise.

Definition at line 171 of file rsa_key.cc.

@@ -197,9 +200,7 @@ Static Public Member Functions
diff --git a/docs/d9/d12/chunking__handler_8cc_source.html b/docs/d9/d12/chunking__handler_8cc_source.html index 0b7977c8d4..b39c406744 100644 --- a/docs/d9/d12/chunking__handler_8cc_source.html +++ b/docs/d9/d12/chunking__handler_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking/chunking_handler.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
chunking_handler.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/media/chunking/chunking_handler.h"
8 
9 #include <algorithm>
10 
11 #include "packager/base/logging.h"
12 #include "packager/media/base/media_sample.h"
13 #include "packager/status_macros.h"
14 
15 namespace shaka {
16 namespace media {
17 namespace {
18 const size_t kStreamIndex = 0;
19 
20 bool IsNewSegmentIndex(int64_t new_index, int64_t current_index) {
21  return new_index != current_index &&
22  // Index is calculated from pts, which could decrease. We do not expect
23  // it to decrease by more than one segment though, which could happen
24  // only if there is a big overlap in the timeline, in which case, we
25  // will create a new segment and leave it to the player to handle it.
26  new_index != current_index - 1;
27 }
28 
29 } // namespace
30 
31 ChunkingHandler::ChunkingHandler(const ChunkingParams& chunking_params)
32  : chunking_params_(chunking_params) {
33  CHECK_NE(chunking_params.segment_duration_in_seconds, 0u);
34 }
35 
37  if (num_input_streams() != 1 || next_output_stream_index() != 1) {
38  return Status(error::INVALID_ARGUMENT,
39  "Expects exactly one input and one output.");
40  }
41  return Status::OK;
42 }
43 
44 Status ChunkingHandler::Process(std::unique_ptr<StreamData> stream_data) {
45  switch (stream_data->stream_data_type) {
46  case StreamDataType::kStreamInfo:
47  return OnStreamInfo(std::move(stream_data->stream_info));
48  case StreamDataType::kCueEvent:
49  return OnCueEvent(std::move(stream_data->cue_event));
50  case StreamDataType::kSegmentInfo:
51  VLOG(3) << "Droppping existing segment info.";
52  return Status::OK;
53  case StreamDataType::kMediaSample:
54  return OnMediaSample(std::move(stream_data->media_sample));
55  default:
56  VLOG(3) << "Stream data type "
57  << static_cast<int>(stream_data->stream_data_type) << " ignored.";
58  return Dispatch(std::move(stream_data));
59  }
60 }
61 
62 Status ChunkingHandler::OnFlushRequest(size_t input_stream_index) {
63  RETURN_IF_ERROR(EndSegmentIfStarted());
64  return FlushDownstream(kStreamIndex);
65 }
66 
67 Status ChunkingHandler::OnStreamInfo(std::shared_ptr<const StreamInfo> info) {
68  time_scale_ = info->time_scale();
69  segment_duration_ =
70  chunking_params_.segment_duration_in_seconds * time_scale_;
71  subsegment_duration_ =
72  chunking_params_.subsegment_duration_in_seconds * time_scale_;
73  return DispatchStreamInfo(kStreamIndex, std::move(info));
74 }
75 
76 Status ChunkingHandler::OnCueEvent(std::shared_ptr<const CueEvent> event) {
77  RETURN_IF_ERROR(EndSegmentIfStarted());
78  const double event_time_in_seconds = event->time_in_seconds;
79  RETURN_IF_ERROR(DispatchCueEvent(kStreamIndex, std::move(event)));
80 
81  // Force start new segment after cue event.
82  segment_start_time_ = base::nullopt;
83  // |cue_offset_| will be applied to sample timestamp so the segment after cue
84  // point have duration ~= |segment_duration_|.
85  cue_offset_ = event_time_in_seconds * time_scale_;
86  return Status::OK;
87 }
88 
89 Status ChunkingHandler::OnMediaSample(
90  std::shared_ptr<const MediaSample> sample) {
91  DCHECK_NE(time_scale_, 0u) << "kStreamInfo should arrive before kMediaSample";
92 
93  const int64_t timestamp = sample->pts();
94 
95  bool started_new_segment = false;
96  const bool can_start_new_segment =
97  sample->is_key_frame() || !chunking_params_.segment_sap_aligned;
98  if (can_start_new_segment) {
99  const int64_t segment_index =
100  timestamp < cue_offset_ ? 0
101  : (timestamp - cue_offset_) / segment_duration_;
102  if (!segment_start_time_ ||
103  IsNewSegmentIndex(segment_index, current_segment_index_)) {
104  current_segment_index_ = segment_index;
105  // Reset subsegment index.
106  current_subsegment_index_ = 0;
107 
108  RETURN_IF_ERROR(EndSegmentIfStarted());
109  segment_start_time_ = timestamp;
110  subsegment_start_time_ = timestamp;
111  max_segment_time_ = timestamp + sample->duration();
112  started_new_segment = true;
113  }
114  }
115  if (!started_new_segment && IsSubsegmentEnabled()) {
116  const bool can_start_new_subsegment =
117  sample->is_key_frame() || !chunking_params_.subsegment_sap_aligned;
118  if (can_start_new_subsegment) {
119  const int64_t subsegment_index =
120  (timestamp - segment_start_time_.value()) / subsegment_duration_;
121  if (IsNewSegmentIndex(subsegment_index, current_subsegment_index_)) {
122  current_subsegment_index_ = subsegment_index;
123 
124  RETURN_IF_ERROR(EndSubsegmentIfStarted());
125  subsegment_start_time_ = timestamp;
126  }
127  }
128  }
129 
130  VLOG(3) << "Sample ts: " << timestamp << " "
131  << " duration: " << sample->duration() << " scale: " << time_scale_
132  << (segment_start_time_ ? " dispatch " : " discard ");
133  if (!segment_start_time_) {
134  DCHECK(!subsegment_start_time_);
135  // Discard samples before segment start. If the segment has started,
136  // |segment_start_time_| won't be null.
137  return Status::OK;
138  }
139 
140  segment_start_time_ = std::min(segment_start_time_.value(), timestamp);
141  subsegment_start_time_ = std::min(subsegment_start_time_.value(), timestamp);
142  max_segment_time_ =
143  std::max(max_segment_time_, timestamp + sample->duration());
144  return DispatchMediaSample(kStreamIndex, std::move(sample));
145 }
146 
147 Status ChunkingHandler::EndSegmentIfStarted() const {
148  if (!segment_start_time_)
149  return Status::OK;
150 
151  auto segment_info = std::make_shared<SegmentInfo>();
152  segment_info->start_timestamp = segment_start_time_.value();
153  segment_info->duration = max_segment_time_ - segment_start_time_.value();
154  return DispatchSegmentInfo(kStreamIndex, std::move(segment_info));
155 }
156 
157 Status ChunkingHandler::EndSubsegmentIfStarted() const {
158  if (!subsegment_start_time_)
159  return Status::OK;
160 
161  auto subsegment_info = std::make_shared<SegmentInfo>();
162  subsegment_info->start_timestamp = subsegment_start_time_.value();
163  subsegment_info->duration =
164  max_segment_time_ - subsegment_start_time_.value();
165  subsegment_info->is_subsegment = true;
166  return DispatchSegmentInfo(kStreamIndex, std::move(subsegment_info));
167 }
168 
169 } // namespace media
170 } // namespace shaka
Status Process(std::unique_ptr< StreamData > stream_data) override
-
Status InitializeInternal() override
-
All the methods that are virtual are virtual for mocking.
- -
Status OnFlushRequest(size_t input_stream_index) override
Event handler for flush request at the specific input stream index.
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #include "packager/media/chunking/chunking_handler.h"
+
8 
+
9 #include <algorithm>
+
10 
+
11 #include "packager/base/logging.h"
+
12 #include "packager/media/base/media_sample.h"
+
13 #include "packager/status_macros.h"
+
14 
+
15 namespace shaka {
+
16 namespace media {
+
17 namespace {
+
18 const size_t kStreamIndex = 0;
+
19 
+
20 bool IsNewSegmentIndex(int64_t new_index, int64_t current_index) {
+
21  return new_index != current_index &&
+
22  // Index is calculated from pts, which could decrease. We do not expect
+
23  // it to decrease by more than one segment though, which could happen
+
24  // only if there is a big overlap in the timeline, in which case, we
+
25  // will create a new segment and leave it to the player to handle it.
+
26  new_index != current_index - 1;
+
27 }
+
28 
+
29 } // namespace
+
30 
+
31 ChunkingHandler::ChunkingHandler(const ChunkingParams& chunking_params)
+
32  : chunking_params_(chunking_params) {
+
33  CHECK_NE(chunking_params.segment_duration_in_seconds, 0u);
+
34 }
+
35 
+
36 Status ChunkingHandler::InitializeInternal() {
+
37  if (num_input_streams() != 1 || next_output_stream_index() != 1) {
+
38  return Status(error::INVALID_ARGUMENT,
+
39  "Expects exactly one input and one output.");
+
40  }
+
41  return Status::OK;
+
42 }
+
43 
+
44 Status ChunkingHandler::Process(std::unique_ptr<StreamData> stream_data) {
+
45  switch (stream_data->stream_data_type) {
+
46  case StreamDataType::kStreamInfo:
+
47  return OnStreamInfo(std::move(stream_data->stream_info));
+
48  case StreamDataType::kCueEvent:
+
49  return OnCueEvent(std::move(stream_data->cue_event));
+
50  case StreamDataType::kSegmentInfo:
+
51  VLOG(3) << "Droppping existing segment info.";
+
52  return Status::OK;
+
53  case StreamDataType::kMediaSample:
+
54  return OnMediaSample(std::move(stream_data->media_sample));
+
55  default:
+
56  VLOG(3) << "Stream data type "
+
57  << static_cast<int>(stream_data->stream_data_type) << " ignored.";
+
58  return Dispatch(std::move(stream_data));
+
59  }
+
60 }
+
61 
+
62 Status ChunkingHandler::OnFlushRequest(size_t input_stream_index) {
+
63  RETURN_IF_ERROR(EndSegmentIfStarted());
+
64  return FlushDownstream(kStreamIndex);
+
65 }
+
66 
+
67 Status ChunkingHandler::OnStreamInfo(std::shared_ptr<const StreamInfo> info) {
+
68  time_scale_ = info->time_scale();
+
69  segment_duration_ =
+
70  chunking_params_.segment_duration_in_seconds * time_scale_;
+
71  subsegment_duration_ =
+
72  chunking_params_.subsegment_duration_in_seconds * time_scale_;
+
73  return DispatchStreamInfo(kStreamIndex, std::move(info));
+
74 }
+
75 
+
76 Status ChunkingHandler::OnCueEvent(std::shared_ptr<const CueEvent> event) {
+
77  RETURN_IF_ERROR(EndSegmentIfStarted());
+
78  const double event_time_in_seconds = event->time_in_seconds;
+
79  RETURN_IF_ERROR(DispatchCueEvent(kStreamIndex, std::move(event)));
+
80 
+
81  // Force start new segment after cue event.
+
82  segment_start_time_ = base::nullopt;
+
83  // |cue_offset_| will be applied to sample timestamp so the segment after cue
+
84  // point have duration ~= |segment_duration_|.
+
85  cue_offset_ = event_time_in_seconds * time_scale_;
+
86  return Status::OK;
+
87 }
+
88 
+
89 Status ChunkingHandler::OnMediaSample(
+
90  std::shared_ptr<const MediaSample> sample) {
+
91  DCHECK_NE(time_scale_, 0u) << "kStreamInfo should arrive before kMediaSample";
+
92 
+
93  const int64_t timestamp = sample->pts();
+
94 
+
95  bool started_new_segment = false;
+
96  const bool can_start_new_segment =
+
97  sample->is_key_frame() || !chunking_params_.segment_sap_aligned;
+
98  if (can_start_new_segment) {
+
99  const int64_t segment_index =
+
100  timestamp < cue_offset_ ? 0
+
101  : (timestamp - cue_offset_) / segment_duration_;
+
102  if (!segment_start_time_ ||
+
103  IsNewSegmentIndex(segment_index, current_segment_index_)) {
+
104  current_segment_index_ = segment_index;
+
105  // Reset subsegment index.
+
106  current_subsegment_index_ = 0;
+
107 
+
108  RETURN_IF_ERROR(EndSegmentIfStarted());
+
109  segment_start_time_ = timestamp;
+
110  subsegment_start_time_ = timestamp;
+
111  max_segment_time_ = timestamp + sample->duration();
+
112  started_new_segment = true;
+
113  }
+
114  }
+
115  if (!started_new_segment && IsSubsegmentEnabled()) {
+
116  const bool can_start_new_subsegment =
+
117  sample->is_key_frame() || !chunking_params_.subsegment_sap_aligned;
+
118  if (can_start_new_subsegment) {
+
119  const int64_t subsegment_index =
+
120  (timestamp - segment_start_time_.value()) / subsegment_duration_;
+
121  if (IsNewSegmentIndex(subsegment_index, current_subsegment_index_)) {
+
122  current_subsegment_index_ = subsegment_index;
+
123 
+
124  RETURN_IF_ERROR(EndSubsegmentIfStarted());
+
125  subsegment_start_time_ = timestamp;
+
126  }
+
127  }
+
128  }
+
129 
+
130  VLOG(3) << "Sample ts: " << timestamp << " "
+
131  << " duration: " << sample->duration() << " scale: " << time_scale_
+
132  << (segment_start_time_ ? " dispatch " : " discard ");
+
133  if (!segment_start_time_) {
+
134  DCHECK(!subsegment_start_time_);
+
135  // Discard samples before segment start. If the segment has started,
+
136  // |segment_start_time_| won't be null.
+
137  return Status::OK;
+
138  }
+
139 
+
140  segment_start_time_ = std::min(segment_start_time_.value(), timestamp);
+
141  subsegment_start_time_ = std::min(subsegment_start_time_.value(), timestamp);
+
142  max_segment_time_ =
+
143  std::max(max_segment_time_, timestamp + sample->duration());
+
144  return DispatchMediaSample(kStreamIndex, std::move(sample));
+
145 }
+
146 
+
147 Status ChunkingHandler::EndSegmentIfStarted() const {
+
148  if (!segment_start_time_)
+
149  return Status::OK;
+
150 
+
151  auto segment_info = std::make_shared<SegmentInfo>();
+
152  segment_info->start_timestamp = segment_start_time_.value();
+
153  segment_info->duration = max_segment_time_ - segment_start_time_.value();
+
154  return DispatchSegmentInfo(kStreamIndex, std::move(segment_info));
+
155 }
+
156 
+
157 Status ChunkingHandler::EndSubsegmentIfStarted() const {
+
158  if (!subsegment_start_time_)
+
159  return Status::OK;
+
160 
+
161  auto subsegment_info = std::make_shared<SegmentInfo>();
+
162  subsegment_info->start_timestamp = subsegment_start_time_.value();
+
163  subsegment_info->duration =
+
164  max_segment_time_ - subsegment_start_time_.value();
+
165  subsegment_info->is_subsegment = true;
+
166  return DispatchSegmentInfo(kStreamIndex, std::move(subsegment_info));
+
167 }
+
168 
+
169 } // namespace media
+
170 } // namespace shaka
+ +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d9/d13/classshaka_1_1media_1_1BufferReader.html b/docs/d9/d13/classshaka_1_1media_1_1BufferReader.html index 077ab867c1..f3af44fb81 100644 --- a/docs/d9/d13/classshaka_1_1media_1_1BufferReader.html +++ b/docs/d9/d13/classshaka_1_1media_1_1BufferReader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::BufferReader Class Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
-shaka::media::mp4::BoxReader - -
+shaka::media::mp4::BoxReader + + @@ -95,6 +98,10 @@ bool  + + +

Public Member Functions

ReadToVector (std
bool ReadToString (std::string *str, size_t size) WARN_UNUSED_RESULT
 
+bool ReadCString (std::string *str) WARN_UNUSED_RESULT
 Reads a null-terminated string.
 
bool SkipBytes (size_t num_bytes) WARN_UNUSED_RESULT
 
@@ -246,7 +253,7 @@ bool ReadNBytesInto8s

Advance the stream by this many bytes.

Returns
false if there are not enough bytes in the buffer, true otherwise.
-

Definition at line 65 of file buffer_reader.cc.

+

Definition at line 77 of file buffer_reader.cc.

@@ -257,9 +264,7 @@ bool 
ReadNBytesInto8s diff --git a/docs/d9/d14/protection__system__flags_8cc_source.html b/docs/d9/d14/protection__system__flags_8cc_source.html index 5ba10e5bc6..8c38f46c77 100644 --- a/docs/d9/d14/protection__system__flags_8cc_source.html +++ b/docs/d9/d14/protection__system__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/protection_system_flags.cc Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
protection_system_flags.cc
-
1 // Copyright 2017 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 //
7 // Defines command line flags for protection systems.
8 
9 #include "packager/app/protection_system_flags.h"
10 
11 DEFINE_string(
12  protection_systems,
13  "",
14  "Protection systems to be generated. Supported protection systems include "
15  "Widevine, PlayReady, FairPlay, Marlin and "
16  "CommonSystem (https://goo.gl/s8RIhr).");
+
1 // Copyright 2017 Google Inc. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 //
+
7 // Defines command line flags for protection systems.
+
8 
+
9 #include "packager/app/protection_system_flags.h"
+
10 
+
11 DEFINE_string(
+
12  protection_systems,
+
13  "",
+
14  "Protection systems to be generated. Supported protection systems include "
+
15  "Widevine, PlayReady, FairPlay, Marlin and "
+
16  "CommonSystem (https://goo.gl/s8RIhr).");
+
diff --git a/docs/d9/d1f/structshaka_1_1media_1_1mp4_1_1MovieFragment.html b/docs/d9/d1f/structshaka_1_1media_1_1mp4_1_1MovieFragment.html index e8f94b241e..cd077113cc 100644 --- a/docs/d9/d1f/structshaka_1_1media_1_1mp4_1_1MovieFragment.html +++ b/docs/d9/d1f/structshaka_1_1media_1_1mp4_1_1MovieFragment.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MovieFragment Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -118,7 +121,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 753 of file box_definitions.h.

+

Definition at line 771 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -146,7 +149,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2616 of file box_definitions.cc.

+

Definition at line 2705 of file box_definitions.cc.

@@ -157,9 +160,7 @@ Additional Inherited Members diff --git a/docs/d9/d26/classshaka_1_1media_1_1AesEncryptor-members.html b/docs/d9/d26/classshaka_1_1media_1_1AesEncryptor-members.html index 753fcf52c3..9b279da112 100644 --- a/docs/d9/d26/classshaka_1_1media_1_1AesEncryptor-members.html +++ b/docs/d9/d26/classshaka_1_1media_1_1AesEncryptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
diff --git a/docs/d9/d26/classshaka_1_1media_1_1mp4_1_1Segmenter.html b/docs/d9/d26/classshaka_1_1media_1_1mp4_1_1Segmenter.html index 38e45a8f21..30a7754678 100644 --- a/docs/d9/d26/classshaka_1_1media_1_1mp4_1_1Segmenter.html +++ b/docs/d9/d26/classshaka_1_1media_1_1mp4_1_1Segmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Segmenter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::MultiSegmentSegmenter shaka::media::mp4::SingleSegmentSegmenter - -
+ + @@ -115,7 +118,7 @@ uint32_t  - + @@ -428,9 +431,7 @@ void 

Public Member Functions

GetReferenceTimeS Protected Member Functions
void UpdateProgress (uint64_t progress)
 Update segmentation progress using ProgressListener.
 Update segmentation progress using ProgressListener.
 
void SetComplete ()
set_progress_target diff --git a/docs/d9/d28/classshaka_1_1media_1_1DvbImageBuilder.html b/docs/d9/d28/classshaka_1_1media_1_1DvbImageBuilder.html new file mode 100644 index 0000000000..5af92b7203 --- /dev/null +++ b/docs/d9/d28/classshaka_1_1media_1_1DvbImageBuilder.html @@ -0,0 +1,171 @@ + + + + + + + +Shaka Packager SDK: shaka::media::DvbImageBuilder Class Reference + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
shaka::media::DvbImageBuilder Class Reference
+
+
+ +

#include <dvb_image.h>

+ + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

DvbImageBuilder (const DvbImageColorSpace *color_space, const RgbaColor &default_color, uint16_t max_width, uint16_t max_height)
 
DvbImageBuilder (const DvbImageBuilder &)=delete
 
+DvbImageBuilderoperator= (const DvbImageBuilder &)=delete
 
+uint16_t max_width () const
 
+uint16_t max_height () const
 
+bool AddPixel (BitDepth bit_depth, uint8_t byte_code, bool is_top_rows)
 
+void NewRow (bool is_top_rows)
 
+void MirrorToBottomRows ()
 Copies the top-rows to the bottom rows.
 
bool GetPixels (const RgbaColor **pixels, uint16_t *width, uint16_t *height) const
 
+

Detailed Description

+

Defines a builder that generates an image from a DVB-sub byte stream. This allocates a single buffer big enough to hold the max-sized image and fills it in series. The NewRow() method must be called to start a new line of the image.

+

This adds pixels in an interlaced format. Adding pixels and new rows on top-rows doesn't affect the bottom-rows. Top-rows refers to even-indexed lines (e.g. 0,2,4).

+ +

Definition at line 89 of file dvb_image.h.

+

Member Function Documentation

+ +

◆ GetPixels()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool shaka::media::DvbImageBuilder::GetPixels (const RgbaColor ** pixels,
uint16_t * width,
uint16_t * height 
) const
+
+

Gets the pixel buffer. Each row is based on the max_width field, but the max filled row with will be given in width. This assumes that NewRow was called recently and we are at the beginning of the rows.

+
Parameters
+ + + + +
pixelsA pointer to a RgbaColor* variable that will be set to the pixel data pointer.
widthWill be filled with the max width of all rows.
heightWill be filled with the number of rows set.
+
+
+
Returns
True on success, false on error.
+ +

Definition at line 244 of file dvb_image.cc.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/docs/d9/d2e/packed__audio__segmenter_8h_source.html b/docs/d9/d2e/packed__audio__segmenter_8h_source.html index 11c5dd6656..77af021cc1 100644 --- a/docs/d9/d2e/packed__audio__segmenter_8h_source.html +++ b/docs/d9/d2e/packed__audio__segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/packed_audio/packed_audio_segmenter.h Source File @@ -29,18 +29,21 @@
- + +/* @license-end */
packed_audio_segmenter.h
-
1 // Copyright 2018 Google LLC. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #ifndef PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_SEGMENTER_H_
8 #define PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_SEGMENTER_H_
9 
10 #include <memory>
11 
12 #include "packager/media/base/buffer_writer.h"
13 #include "packager/media/base/stream_info.h"
14 #include "packager/status.h"
15 
16 namespace shaka {
17 namespace media {
18 
19 class AACAudioSpecificConfig;
20 class Id3Tag;
21 class MediaSample;
22 
24 constexpr double kPackedAudioTimescale = 90000;
25 
28 constexpr char kTimestampOwnerIdentifier[] =
29  "com.apple.streaming.transportStreamTimestamp";
30 
33 constexpr char kAudioDescriptionOwnerIdentifier[] =
34  "com.apple.streaming.audioDescription";
35 
41  public:
45  explicit PackedAudioSegmenter(uint32_t transport_stream_timestamp_offset);
46  virtual ~PackedAudioSegmenter();
47 
51  // This function is made virtual for testing.
52  virtual Status Initialize(const StreamInfo& stream_info);
53 
56  // This function is made virtual for testing.
57  virtual Status AddSample(const MediaSample& sample);
58 
62  // This function is made virtual for testing.
63  virtual Status FinalizeSegment();
64 
67  // This function is made virtual for testing.
68  virtual double TimescaleScale() const;
69 
71  BufferWriter* segment_buffer() { return &segment_buffer_; }
72 
73  private:
75  PackedAudioSegmenter& operator=(const PackedAudioSegmenter&) = delete;
76 
77  // These functions is made virtual for testing.
78  virtual std::unique_ptr<AACAudioSpecificConfig> CreateAdtsConverter();
79  virtual std::unique_ptr<Id3Tag> CreateId3Tag();
80 
81  Status EncryptionAudioSetup(const MediaSample& sample);
82  Status StartNewSegment(const MediaSample& first_sample);
83 
84  const uint32_t transport_stream_timestamp_offset_ = 0;
85  // Codec for the stream.
86  Codec codec_ = kUnknownCodec;
87  std::vector<uint8_t> audio_codec_config_;
88  // Calculated by output stream's timescale / input stream's timescale. This is
89  // used to scale the timestamps.
90  double timescale_scale_ = 0.0;
91  // Whether it is the start of a new segment.
92  bool start_of_new_segment_ = true;
93 
94  // Audio setup information for encrypted segment.
95  std::string audio_setup_information_;
96  // AAC is carried in ADTS.
97  std::unique_ptr<AACAudioSpecificConfig> adts_converter_;
98 
99  BufferWriter segment_buffer_;
100 };
101 
102 } // namespace media
103 } // namespace shaka
104 
105 #endif // PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_SEGMENTER_H_
Abstract class holds stream information.
Definition: stream_info.h:62
-
All the methods that are virtual are virtual for mocking.
- - -
virtual Status Initialize(const StreamInfo &stream_info)
- -
Class to hold a media sample.
Definition: media_sample.h:22
-
PackedAudioSegmenter(uint32_t transport_stream_timestamp_offset)
-
virtual Status AddSample(const MediaSample &sample)
- - - +
1 // Copyright 2018 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_SEGMENTER_H_
+
8 #define PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_SEGMENTER_H_
+
9 
+
10 #include <memory>
+
11 
+
12 #include "packager/media/base/buffer_writer.h"
+
13 #include "packager/media/base/stream_info.h"
+
14 #include "packager/status.h"
+
15 
+
16 namespace shaka {
+
17 namespace media {
+
18 
+
19 class AACAudioSpecificConfig;
+
20 class Id3Tag;
+
21 class MediaSample;
+
22 
+
24 constexpr double kPackedAudioTimescale = 90000;
+
25 
+
28 constexpr char kTimestampOwnerIdentifier[] =
+
29  "com.apple.streaming.transportStreamTimestamp";
+
30 
+
33 constexpr char kAudioDescriptionOwnerIdentifier[] =
+
34  "com.apple.streaming.audioDescription";
+
35 
+ +
41  public:
+
45  explicit PackedAudioSegmenter(uint32_t transport_stream_timestamp_offset);
+
46  virtual ~PackedAudioSegmenter();
+
47 
+
51  // This function is made virtual for testing.
+
52  virtual Status Initialize(const StreamInfo& stream_info);
+
53 
+
56  // This function is made virtual for testing.
+
57  virtual Status AddSample(const MediaSample& sample);
+
58 
+
62  // This function is made virtual for testing.
+
63  virtual Status FinalizeSegment();
+
64 
+
67  // This function is made virtual for testing.
+
68  virtual double TimescaleScale() const;
+
69 
+
71  BufferWriter* segment_buffer() { return &segment_buffer_; }
+
72 
+
73  private:
+ +
75  PackedAudioSegmenter& operator=(const PackedAudioSegmenter&) = delete;
+
76 
+
77  // These functions is made virtual for testing.
+
78  virtual std::unique_ptr<AACAudioSpecificConfig> CreateAdtsConverter();
+
79  virtual std::unique_ptr<Id3Tag> CreateId3Tag();
+
80 
+
81  Status EncryptionAudioSetup(const MediaSample& sample);
+
82  Status StartNewSegment(const MediaSample& first_sample);
+
83 
+
84  const uint32_t transport_stream_timestamp_offset_ = 0;
+
85  // Codec for the stream.
+
86  Codec codec_ = kUnknownCodec;
+
87  std::vector<uint8_t> audio_codec_config_;
+
88  // Calculated by output stream's timescale / input stream's timescale. This is
+
89  // used to scale the timestamps.
+
90  double timescale_scale_ = 0.0;
+
91  // Whether it is the start of a new segment.
+
92  bool start_of_new_segment_ = true;
+
93 
+
94  // Audio setup information for encrypted segment.
+
95  std::string audio_setup_information_;
+
96  // AAC is carried in ADTS.
+
97  std::unique_ptr<AACAudioSpecificConfig> adts_converter_;
+
98 
+
99  BufferWriter segment_buffer_;
+
100 };
+
101 
+
102 } // namespace media
+
103 } // namespace shaka
+
104 
+
105 #endif // PACKAGER_MEDIA_FORMATS_PACKED_AUDIO_PACKED_AUDIO_SEGMENTER_H_
+ + +
Class to hold a media sample.
Definition: media_sample.h:22
+ + +
PackedAudioSegmenter(uint32_t transport_stream_timestamp_offset)
+
virtual Status Initialize(const StreamInfo &stream_info)
+
virtual Status AddSample(const MediaSample &sample)
+ + +
Abstract class holds stream information.
Definition: stream_info.h:65
+
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d9/d2f/http__file_8h_source.html b/docs/d9/d2f/http__file_8h_source.html new file mode 100644 index 0000000000..caf0d9afbf --- /dev/null +++ b/docs/d9/d2f/http__file_8h_source.html @@ -0,0 +1,172 @@ + + + + + + + +Shaka Packager SDK: packager/file/http_file.h Source File + + + + + + + + + +
+
+ + + + + + +
+
Shaka Packager SDK +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
http_file.h
+
+
+
1 // Copyright 2020 Google LLC. All rights reserved.
+
2 //
+
3 // Use of this source code is governed by a BSD-style
+
4 // license that can be found in the LICENSE file or at
+
5 // https://developers.google.com/open-source/licenses/bsd
+
6 
+
7 #ifndef PACKAGER_FILE_HTTP_H_
+
8 #define PACKAGER_FILE_HTTP_H_
+
9 
+
10 #include <memory>
+
11 #include <string>
+
12 
+
13 #include "packager/base/synchronization/waitable_event.h"
+
14 #include "packager/file/file.h"
+
15 #include "packager/file/io_cache.h"
+
16 #include "packager/status.h"
+
17 
+
18 typedef void CURL;
+
19 struct curl_slist;
+
20 
+
21 namespace shaka {
+
22 
+
23 enum class HttpMethod {
+
24  kGet,
+
25  kPost,
+
26  kPut,
+
27 };
+
28 
+
38 class HttpFile : public File {
+
39  public:
+
40  HttpFile(HttpMethod method, const std::string& url);
+
41  HttpFile(HttpMethod method,
+
42  const std::string& url,
+
43  const std::string& upload_content_type,
+
44  const std::vector<std::string>& headers,
+
45  uint32_t timeout_in_seconds);
+
46 
+
47  HttpFile(const HttpFile&) = delete;
+
48  HttpFile& operator=(const HttpFile&) = delete;
+
49 
+
50  Status CloseWithStatus();
+
51 
+
54  bool Close() override;
+
55  int64_t Read(void* buffer, uint64_t length) override;
+
56  int64_t Write(const void* buffer, uint64_t length) override;
+
57  int64_t Size() override;
+
58  bool Flush() override;
+
59  bool Seek(uint64_t position) override;
+
60  bool Tell(uint64_t* position) override;
+
61  bool Open() override;
+
63 
+
64  protected:
+
65  ~HttpFile() override;
+
66 
+
67  private:
+
68  struct CurlDelete {
+
69  void operator()(CURL* curl);
+
70  void operator()(curl_slist* headers);
+
71  };
+
72 
+
73  void SetupRequest();
+
74  void ThreadMain();
+
75 
+
76  const std::string url_;
+
77  const std::string upload_content_type_;
+
78  const uint32_t timeout_in_seconds_;
+
79  const HttpMethod method_;
+
80  IoCache download_cache_;
+
81  IoCache upload_cache_;
+
82  std::unique_ptr<CURL, CurlDelete> curl_;
+
83  // The headers need to remain alive for the duration of the request.
+
84  std::unique_ptr<curl_slist, CurlDelete> request_headers_;
+
85  Status status_;
+
86 
+
87  // Signaled when the "curl easy perform" task completes.
+
88  base::WaitableEvent task_exit_event_;
+
89 };
+
90 
+
91 } // namespace shaka
+
92 
+
93 #endif // PACKAGER_FILE_HTTP_H_
+
Define an abstract file interface.
Definition: file.h:27
+ +
bool Seek(uint64_t position) override
Definition: http_file.cc:248
+
bool Open() override
Internal open. Should not be used directly.
Definition: http_file.cc:191
+
bool Close() override
Definition: http_file.cc:224
+
int64_t Write(const void *buffer, uint64_t length) override
Definition: http_file.cc:233
+
int64_t Read(void *buffer, uint64_t length) override
Definition: http_file.cc:228
+
bool Tell(uint64_t *position) override
Definition: http_file.cc:253
+
int64_t Size() override
Definition: http_file.cc:238
+
bool Flush() override
Definition: http_file.cc:243
+
Declaration of class which implements a thread-safe circular buffer.
Definition: io_cache.h:19
+ +
All the methods that are virtual are virtual for mocking.
+
+ + + + diff --git a/docs/d9/d36/classshaka_1_1media_1_1TracksBuilder-members.html b/docs/d9/d36/classshaka_1_1media_1_1TracksBuilder-members.html index 515ed28730..a228fa4e94 100644 --- a/docs/d9/d36/classshaka_1_1media_1_1TracksBuilder-members.html +++ b/docs/d9/d36/classshaka_1_1media_1_1TracksBuilder-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
- + +/* @license-end */
diff --git a/docs/d9/d3b/webm__content__encodings_8h_source.html b/docs/d9/d3b/webm__content__encodings_8h_source.html index 9e08d7f312..d7b7b7a979 100644 --- a/docs/d9/d3b/webm__content__encodings_8h_source.html +++ b/docs/d9/d3b/webm__content__encodings_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_content_encodings.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
webm_content_encodings.h
-
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_H_
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_H_
7 
8 #include <stdint.h>
9 #include <memory>
10 #include <string>
11 
12 namespace shaka {
13 namespace media {
14 
16  public:
19 
20  static const int kOrderInvalid = -1;
21 
22  enum Scope {
23  kScopeInvalid = 0,
24  kScopeAllFrameContents = 1,
25  kScopeTrackPrivateData = 2,
26  kScopeNextContentEncodingData = 4,
27  kScopeMax = 7,
28  };
29 
30  enum Type {
31  kTypeInvalid = -1,
32  kTypeCompression = 0,
33  kTypeEncryption = 1,
34  };
35 
36  enum EncryptionAlgo {
37  kEncAlgoInvalid = -1,
38  kEncAlgoNotEncrypted = 0,
39  kEncAlgoDes = 1,
40  kEncAlgo3des = 2,
41  kEncAlgoTwofish = 3,
42  kEncAlgoBlowfish = 4,
43  kEncAlgoAes = 5,
44  };
45 
46  enum CipherMode {
47  kCipherModeInvalid = 0,
48  kCipherModeCtr = 1,
49  };
50 
52  ~ContentEncoding();
53 
54  int64_t order() const { return order_; }
55  void set_order(int64_t order) { order_ = order; }
56 
57  Scope scope() const { return scope_; }
58  void set_scope(Scope scope) { scope_ = scope; }
59 
60  Type type() const { return type_; }
61  void set_type(Type type) { type_ = type; }
62 
63  EncryptionAlgo encryption_algo() const { return encryption_algo_; }
64  void set_encryption_algo(EncryptionAlgo encryption_algo) {
65  encryption_algo_ = encryption_algo;
66  }
67 
68  const std::string& encryption_key_id() const { return encryption_key_id_; }
69  void SetEncryptionKeyId(const uint8_t* encryption_key_id, int size);
70 
71  CipherMode cipher_mode() const { return cipher_mode_; }
72  void set_cipher_mode(CipherMode mode) { cipher_mode_ = mode; }
73 
74  private:
75  ContentEncoding(const ContentEncoding&) = delete;
76  ContentEncoding& operator=(const ContentEncoding&) = delete;
77 
78  int64_t order_;
79  Scope scope_;
80  Type type_;
81  EncryptionAlgo encryption_algo_;
82  std::string encryption_key_id_;
83  CipherMode cipher_mode_;
84 };
85 
86 } // namespace media
87 } // namespace shaka
88 
89 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_H_
-
All the methods that are virtual are virtual for mocking.
- +
1 // Copyright 2014 The Chromium Authors. All rights reserved.
+
2 // Use of this source code is governed by a BSD-style license that can be
+
3 // found in the LICENSE file.
+
4 
+
5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_H_
+
6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_H_
+
7 
+
8 #include <stdint.h>
+
9 #include <memory>
+
10 #include <string>
+
11 
+
12 namespace shaka {
+
13 namespace media {
+
14 
+ +
16  public:
+
19 
+
20  static const int kOrderInvalid = -1;
+
21 
+
22  enum Scope {
+
23  kScopeInvalid = 0,
+
24  kScopeAllFrameContents = 1,
+
25  kScopeTrackPrivateData = 2,
+
26  kScopeNextContentEncodingData = 4,
+
27  kScopeMax = 7,
+
28  };
+
29 
+
30  enum Type {
+
31  kTypeInvalid = -1,
+
32  kTypeCompression = 0,
+
33  kTypeEncryption = 1,
+
34  };
+
35 
+
36  enum EncryptionAlgo {
+
37  kEncAlgoInvalid = -1,
+
38  kEncAlgoNotEncrypted = 0,
+
39  kEncAlgoDes = 1,
+
40  kEncAlgo3des = 2,
+
41  kEncAlgoTwofish = 3,
+
42  kEncAlgoBlowfish = 4,
+
43  kEncAlgoAes = 5,
+
44  };
+
45 
+
46  enum CipherMode {
+
47  kCipherModeInvalid = 0,
+
48  kCipherModeCtr = 1,
+
49  };
+
50 
+
51  ContentEncoding();
+
52  ~ContentEncoding();
+
53 
+
54  int64_t order() const { return order_; }
+
55  void set_order(int64_t order) { order_ = order; }
+
56 
+
57  Scope scope() const { return scope_; }
+
58  void set_scope(Scope scope) { scope_ = scope; }
+
59 
+
60  Type type() const { return type_; }
+
61  void set_type(Type type) { type_ = type; }
+
62 
+
63  EncryptionAlgo encryption_algo() const { return encryption_algo_; }
+
64  void set_encryption_algo(EncryptionAlgo encryption_algo) {
+
65  encryption_algo_ = encryption_algo;
+
66  }
+
67 
+
68  const std::string& encryption_key_id() const { return encryption_key_id_; }
+
69  void SetEncryptionKeyId(const uint8_t* encryption_key_id, int size);
+
70 
+
71  CipherMode cipher_mode() const { return cipher_mode_; }
+
72  void set_cipher_mode(CipherMode mode) { cipher_mode_ = mode; }
+
73 
+
74  private:
+
75  ContentEncoding(const ContentEncoding&) = delete;
+
76  ContentEncoding& operator=(const ContentEncoding&) = delete;
+
77 
+
78  int64_t order_;
+
79  Scope scope_;
+
80  Type type_;
+
81  EncryptionAlgo encryption_algo_;
+
82  std::string encryption_key_id_;
+
83  CipherMode cipher_mode_;
+
84 };
+
85 
+
86 } // namespace media
+
87 } // namespace shaka
+
88 
+
89 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CONTENT_ENCODINGS_H_
+ + +
All the methods that are virtual are virtual for mocking.
diff --git a/docs/d9/d3c/structshaka_1_1media_1_1mp4_1_1VTTEmptyCueBox.html b/docs/d9/d3c/structshaka_1_1media_1_1mp4_1_1VTTEmptyCueBox.html index e49d8a0deb..8e719a7ccf 100644 --- a/docs/d9/d3c/structshaka_1_1media_1_1mp4_1_1VTTEmptyCueBox.html +++ b/docs/d9/d3c/structshaka_1_1media_1_1mp4_1_1VTTEmptyCueBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::VTTEmptyCueBox Struct Reference @@ -29,18 +29,21 @@
- + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -105,7 +108,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 834 of file box_definitions.h.

+

Definition at line 852 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -133,7 +136,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2812 of file box_definitions.cc.

+

Definition at line 2916 of file box_definitions.cc.

@@ -144,9 +147,7 @@ Additional Inherited Members diff --git a/docs/d9/d3e/structshaka_1_1media_1_1mp4_1_1CueSourceIDBox.html b/docs/d9/d3e/structshaka_1_1media_1_1mp4_1_1CueSourceIDBox.html index c28a6b6ef1..a572b06c47 100644 --- a/docs/d9/d3e/structshaka_1_1media_1_1mp4_1_1CueSourceIDBox.html +++ b/docs/d9/d3e/structshaka_1_1media_1_1mp4_1_1CueSourceIDBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CueSourceIDBox Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
shaka::media::mp4::Box - -
+ + @@ -112,7 +115,7 @@ Additional Inherited Members

Public Member Functions

Detailed Description

-

Definition at line 804 of file box_definitions.h.

+

Definition at line 822 of file box_definitions.h.

Member Function Documentation

◆ BoxType()

@@ -140,7 +143,7 @@ Additional Inherited Members

Implements shaka::media::mp4::Box.

-

Definition at line 2719 of file box_definitions.cc.

+

Definition at line 2823 of file box_definitions.cc.

@@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/d9/d40/classshaka_1_1media_1_1WebVttParser.html b/docs/d9/d40/classshaka_1_1media_1_1WebVttParser.html index 7143eef99d..42a0218633 100644 --- a/docs/d9/d40/classshaka_1_1media_1_1WebVttParser.html +++ b/docs/d9/d40/classshaka_1_1media_1_1WebVttParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebVttParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
-shaka::media::OriginHandler -shaka::media::MediaHandler - -
+shaka::media::MediaParser + + - - - - - - - - - - - - - - - - - - + + + + + +

Public Member Functions

WebVttParser (std::unique_ptr< FileReader > source, const std::string &language)
 
-Status Run () override
 
-void Cancel () override
 
- Public Member Functions inherited from shaka::media::MediaHandler
-Status SetHandler (size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
 Connect downstream handler at the specified output stream index.
 
-Status AddHandler (std::shared_ptr< MediaHandler > handler)
 Connect downstream handler to the next available output stream index.
 
Status Initialize ()
 
-bool IsConnected ()
 Validate if the handler is connected to its upstream handler.
 
void Init (const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
 
bool Flush () override
 
bool Parse (const uint8_t *buf, int size) override
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + +

Additional Inherited Members

- Static Public Member Functions inherited from shaka::media::MediaHandler
-static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
 
- Protected Member Functions inherited from shaka::media::MediaHandler
-virtual Status OnFlushRequest (size_t input_stream_index)
 Event handler for flush request at the specific input stream index.
 
Status Dispatch (std::unique_ptr< StreamData > stream_data) const
 
-Status DispatchStreamInfo (size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
 Dispatch the stream info to downstream handlers.
 
-Status DispatchMediaSample (size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
 Dispatch the media sample to downstream handlers.
 
-Status DispatchTextSample (size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
 Dispatch the text sample to downstream handlers.
 
-Status DispatchSegmentInfo (size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) const
 Dispatch the segment info to downstream handlers.
 
-Status DispatchScte35Event (size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) const
 Dispatch the scte35 event to downstream handlers.
 
-Status DispatchCueEvent (size_t stream_index, std::shared_ptr< const CueEvent > cue_event) const
 Dispatch the cue event to downstream handlers.
 
-Status FlushDownstream (size_t output_stream_index)
 Flush the downstream connected at the specified output stream index.
 
-Status FlushAllDownstreams ()
 Flush all connected downstream handlers.
 
-bool initialized ()
 
-size_t num_input_streams () const
 
-size_t next_output_stream_index () const
 
-const std::map< size_t, std::pair< std::shared_ptr< MediaHandler >, size_t > > & output_handlers ()
 
- Public Types inherited from shaka::media::MediaParser
typedef base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
 
typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
 
typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
 

Detailed Description

-

Definition at line 21 of file webvtt_parser.h.

-

The documentation for this class was generated from the following files:
    +

    Definition at line 23 of file webvtt_parser.h.

    +

    Member Function Documentation

    + +

    ◆ Flush()

    + +
    +
    + + + + + +
    + + + + + + + +
    bool shaka::media::WebVttParser::Flush ()
    +
    +overridevirtual
    +
    +

    Flush data currently in the parser and put the parser in a state where it can receive data for a new seek point.

    Returns
    true if successful, false otherwise.
    + +

    Implements shaka::media::MediaParser.

    + +

    Definition at line 212 of file webvtt_parser.cc.

    + +
    +
    + +

    ◆ Init()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    void shaka::media::WebVttParser::Init (const InitCBinit_cb,
    const NewMediaSampleCBnew_media_sample_cb,
    const NewTextSampleCBnew_text_sample_cb,
    KeySourcedecryption_key_source 
    )
    +
    +overridevirtual
    +
    +

    Initialize the parser with necessary callbacks. Must be called before any data is passed to Parse().

    Parameters
    + + + + + +
    init_cbwill be called once enough data has been parsed to determine the initial stream configurations.
    new_media_sample_cbwill be called each time a new media sample is available from the parser.
    new_text_sample_cbwill be called each time a new text sample is available from the parser.
    decryption_key_sourcethe key source to decrypt the frames. May be NULL, and caller retains ownership.
    +
    +
    + +

    Implements shaka::media::MediaParser.

    + +

    Definition at line 199 of file webvtt_parser.cc.

    + +
    +
    + +

    ◆ Parse()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + +
    bool shaka::media::WebVttParser::Parse (const uint8_t * buf,
    int size 
    )
    +
    +overridevirtual
    +
    +

    Should be called when there is new data to parse.

    Returns
    true if successful.
    + +

    Implements shaka::media::MediaParser.

    + +

    Definition at line 217 of file webvtt_parser.cc.

    + +
    +
    +
    The documentation for this class was generated from the following files: diff --git a/docs/d9/d40/classshaka_1_1media_1_1WebVttParser.png b/docs/d9/d40/classshaka_1_1media_1_1WebVttParser.png index 2530f9ee9b8ac2e88cace7a01dfe2f44224983c5..673800ab045e9adc03282f769daa60ecb53cb7fc 100644 GIT binary patch delta 672 zcmZ3=ah6rFGr-TCmrII^fq{Y7)59eQNUs3m01jp#xhv${r-_PI^-M9IE{-7;jBn@O zUiVmm$5q@q=>Px8>gG+nCX?CwuVmEtZHqe87kNXiHZ^kEQ{JSBOYVm^c?B&I3Yny2 z+92ln_LH*btgNkH&soVm+A5v;d-4)>F6OCE)(J0EE?ivuVak=JcaEnef8TgBlX3Uw zs{z+noLhOeq0TUFL22FmvW2(n?RZ`YrW9W(xO#H}e{*Evub$dZ_cGekuHBp2WVS-; zanUXP!$oVq_T)0X>fPqqvvtq1`@ii8ZrXiKI&A;jK+mJ6zrEOeX?sl^v%jVF8M9uqYj-N9-rG~} zb!X-I`2n84)V%^cyFy?-+uEdedea^UhKIix_BiG<{;i2~`XzQ@>Sx&{>lx1m^9!tI zVeJTMVsg=PWK^2EfMKFnK!b;>hQkse5rrU5E`gOu(qHSFrv;soc47Qc3sWJxVtL(; z_N&*dw-?q=?Jlj6@z1$lH;?h(GKGKxvHgzn`j;KP&s}@?@y+6rHECvhfA^+-_Rn>* z`y_dNkM!BY?grxjZ$;mJ^>XFwYbV=kBzSIpnfY;cVXxrci%)mmd+AuabKTmVuf8;% zaSwm_c)$6#1!Lec1w5Zl>67^-^@|&ym6b^6PV~2JYD@<);T3K0RT!* BKP3PF delta 1019 zcmX@hx|Bn)Gr-TCmrII^fq{Y7)59eQNUs9o4i07@>2Ri@ccP+IJ@Xb%7srqa#~7!kQ$^xD*FSC4ITL@aH1@f`YL&AKoTe_x5nZK{ zy4pEbW$WSXDwZko0>j=0ecdYcBYtt)(x+T6Cr8zaet6B4VYyd&o^e%Tu2y~S zni~?lVs9C~CQecO`$6oZfb=zDI&g=t&}3n|sft{$_3bwYs3gAVF-Eisjqy_rCpSzGBOHy0GfmlG2Yq zcRrd^zWx8gw|2Jk<@@~~Te>;#Wvdqa@FFkZyg~RD?H9Ij#xo)k{!V&Tt@D{H{N44dC-(>BGPbNp zKOks2C(7PfH>7vHMo2@EIC zQ`g#nL2A{?@aZeV4Cl`a?Bwb%Z#dVyYvQ>>R)Se?85n*N5ty*B{%`wglg??GB*qzz zuwd{1wT@LFYxCE0>Axp+m(J;vJD*&?m2qE)nAU^7{Ka+k63x5L=Vi<9J%7z`-pn8O z4o1wY|92tniSqoyvtgN5@&{x7n4Q%AvsHojL)EPX{LPKrzk9-unYw*(oBsawxsF%j zZ|BX6UTinTvh;QBpRdQ{u3lNCKWkyjF{T~Y7cabZ>3uv$yt?8l<9p7t*32?oH!Ev$ zN5J72*5c32J>7Sot}x!`@b=itc}KS168_HP$oM0QH_&%&Am8i*Kcx6rKZi1InRAc# zyyRPkwC0R}Job$8^XtkPXY4%+N}8-cypaRud~HSKv{bggO!uz394)D5y#UP544$rj JF6*2UngBPS-pK#} diff --git a/docs/d9/d44/classshaka_1_1media_1_1MultiCodecMuxerListener.html b/docs/d9/d44/classshaka_1_1media_1_1MultiCodecMuxerListener.html new file mode 100644 index 0000000000..9b342402c1 --- /dev/null +++ b/docs/d9/d44/classshaka_1_1media_1_1MultiCodecMuxerListener.html @@ -0,0 +1,207 @@ + + + + + + + +Shaka Packager SDK: shaka::media::MultiCodecMuxerListener Class Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::MultiCodecMuxerListener Class Reference
    +
    +
    + +

    #include <multi_codec_muxer_listener.h>

    +
    +Inheritance diagram for shaka::media::MultiCodecMuxerListener:
    +
    +
    + + +shaka::media::CombinedMuxerListener +shaka::media::MuxerListener + +
    + + + + + + + + + + + + + + + + + + + + + + +

    +Public Member Functions

    CombinedMuxerListener implementation overrides.
    void OnMediaStart (const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
     
    - Public Member Functions inherited from shaka::media::CombinedMuxerListener
    +void AddListener (std::unique_ptr< MuxerListener > listener)
     
    void OnEncryptionInfoReady (bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
     
    void OnEncryptionStart () override
     
    void OnSampleDurationReady (uint32_t sample_duration) override
     
    void OnMediaEnd (const MediaRanges &media_ranges, float duration_seconds) override
     
    void OnNewSegment (const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
     
    void OnKeyFrame (int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
     
    void OnCueEvent (int64_t timestamp, const std::string &cue_data) override
     
    + + + + + + + + + +

    +Additional Inherited Members

    - Public Types inherited from shaka::media::MuxerListener
    enum  ContainerType {
    +  kContainerUnknown = 0 +, kContainerMp4 +, kContainerMpeg2ts +, kContainerWebM +,
    +  kContainerText +, kContainerPackedAudio +
    + }
     
    - Protected Member Functions inherited from shaka::media::CombinedMuxerListener
    void LimitNumOfMuxerListners (size_t num)
     
    MuxerListenerMuxerListenerAt (size_t index)
     
    +

    Detailed Description

    +

    MultiCodecMuxerListener is a variant of CombinedMuxerListener. It is designed to handle the case that a stream can be signalled in multiple different codecs. Like a normal CombinedMuxerListener, it contains multiple child MuxerListeners, with one child per codec. If there are more child MuxerListeners than the number of codecs, the extra child MuxerListeners are removed; on the other hand, if there are more codecs than the number of child MuxerListeners, the extra codecs are not handled.

    + +

    Definition at line 22 of file multi_codec_muxer_listener.h.

    +

    Member Function Documentation

    + +

    ◆ OnMediaStart()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    void shaka::media::MultiCodecMuxerListener::OnMediaStart (const MuxerOptionsmuxer_options,
    const StreamInfostream_info,
    uint32_t time_scale,
    ContainerType container_type 
    )
    +
    +overridevirtual
    +
    +

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    + + + + + +
    muxer_optionsis the options for Muxer.
    stream_infois the information of this media.
    time_scaleis a reference time scale that overrides the time scale specified in stream_info.
    container_typeis the container of this media.
    +
    +
    + +

    Reimplemented from shaka::media::CombinedMuxerListener.

    + +

    Definition at line 16 of file multi_codec_muxer_listener.cc.

    + +
    +
    +
    The documentation for this class was generated from the following files: +
    + + + + diff --git a/docs/d9/d44/classshaka_1_1media_1_1MultiCodecMuxerListener.png b/docs/d9/d44/classshaka_1_1media_1_1MultiCodecMuxerListener.png new file mode 100644 index 0000000000000000000000000000000000000000..3bcbe4bb08d8fe965a37e167bd80a25337e285c6 GIT binary patch literal 1236 zcmeAS@N?(olHy`uVBq!ia0vp^uYtIOgBeH~Zh0dNq$C1-LR|m<{|{uoc=NTi|Ih>= z3ycpOIKbL@M;^%KC<*clW&kPzfvcxNj2IYLl097fd|qn5hFoXT|Dt)%cXnE+W^${pR$03|W$KczUld;}uC%XH@mwgk z?PBEd^-5Fn&whHAHA&?4^a$0R&v)FL`d=mU+TDL1m-@fhy*6IIcuDz`i^h%F0m7@6 zN8Gdf*PAnUYs*^JfV8XOrCC3Nu5XPjS*^17!tFKTVX8aXqUu)0>u>QBKey5N`FFN+ zx^I%sqodM14dlD}TC`uMpjUbkyWg-hS% z9(*|^k~urNnj`DXq%U*rUiuz9<`@0?T&d27gJRdV&3?wE#q}%j@~F;Fe04bZVc792?X?GYrM=no!`)QJ^M5+r|5MgX+A_~9 z+4lVBJI)OI*XuX5X;)+Z*q8n*KI8(B&1@@O8=>hS!>rjMsuUF|Api z!W!X!l54}fNumk1s@eyt&=mX$p8LEqPsz{omeWZsPoOr{Ok379?Mwdsn5fcPbtCQh z#~%}yI6jS)xOt><>nDjvYjyrBtyZzLz0WGYuTkT-aNgzE4*3mskL6Qmz79C$c3Zeg zLd&D{m|5|@vZ%-hmYckT7lKH3G@|Ui)s}T~oeJ`LzG}(hqxg2s6LV zH447m_3m|tjKh)dIV)ye3wFEq+dIMUm`VG+ltWT=h4OYQ9`19J{&6EvzAU%u)r-Bq zcS*@U{=&rjYlD8o^`7Mu*8kt?!4fBJz++?`HEdtkFNgv6ZCo8##vYWDyys$|K3=s4~mc* zGe1|y7wb7~C^Fc8n0NZ&iuBJXZe7oxZE^LuNSWSwxo@%8G%i@|zczRJT#;i&$9A?w z+m?mh_CCWH4~&g_V)MT1X7`Jq)Bicu)h7FNt;eYu$M2OydzL@968n+xyQef~UHRwc zU!Qa9cq}*H3rXYn_-fy;7&mugSHVZ0w0#eSl?5Cw7k|B1>fOZK2afmr`Vdla?P5@w zuKByekN>RX|J_u2_D0~HD+UKnAt&X_X={!b%2dCw?=g + - + Shaka Packager SDK: shaka::media::KeyFrameEvent Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    size diff --git a/docs/d9/d57/classshaka_1_1media_1_1mp4_1_1ChunkInfoIterator.html b/docs/d9/d57/classshaka_1_1media_1_1mp4_1_1ChunkInfoIterator.html index d969b60424..4d77155b6c 100644 --- a/docs/d9/d57/classshaka_1_1media_1_1mp4_1_1ChunkInfoIterator.html +++ b/docs/d9/d57/classshaka_1_1media_1_1mp4_1_1ChunkInfoIterator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::ChunkInfoIterator Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d9/d65/classshaka_1_1media_1_1SingleThreadJobManager.html b/docs/d9/d65/classshaka_1_1media_1_1SingleThreadJobManager.html new file mode 100644 index 0000000000..8d5f3db8a4 --- /dev/null +++ b/docs/d9/d65/classshaka_1_1media_1_1SingleThreadJobManager.html @@ -0,0 +1,143 @@ + + + + + + + +Shaka Packager SDK: shaka::media::SingleThreadJobManager Class Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::SingleThreadJobManager Class Reference
    +
    +
    +
    +Inheritance diagram for shaka::media::SingleThreadJobManager:
    +
    +
    + + +shaka::media::JobManager + +
    + + + + + + + + + + + + + + + + + +

    +Public Member Functions

    SingleThreadJobManager (std::unique_ptr< SyncPointQueue > sync_points)
     
    +Status InitializeJobs () override
     
    +Status RunJobs () override
     
    - Public Member Functions inherited from shaka::media::JobManager
    JobManager (std::unique_ptr< SyncPointQueue > sync_points)
     
    +void Add (const std::string &name, std::shared_ptr< OriginHandler > handler)
     
    +void CancelJobs ()
     
    +SyncPointQueuesync_points ()
     
    + + + + + + + + + + + + + +

    +Additional Inherited Members

    - Protected Member Functions inherited from shaka::media::JobManager
    JobManager (const JobManager &)=delete
     
    +JobManageroperator= (const JobManager &)=delete
     
    - Protected Attributes inherited from shaka::media::JobManager
    +std::vector< JobEntryjob_entries_
     
    +std::vector< std::unique_ptr< Job > > jobs_
     
    +std::unique_ptr< SyncPointQueuesync_points_
     
    +

    Detailed Description

    +
    +

    Definition at line 18 of file single_thread_job_manager.h.

    +

    The documentation for this class was generated from the following files: +
    + + + + diff --git a/docs/d9/d65/classshaka_1_1media_1_1SingleThreadJobManager.png b/docs/d9/d65/classshaka_1_1media_1_1SingleThreadJobManager.png new file mode 100644 index 0000000000000000000000000000000000000000..7c124e8e2c7452ebdbe722a3f6e51d9a9607a8a2 GIT binary patch literal 855 zcmeAS@N?(olHy`uVBq!ia0vp^Z-F>~gBeI3I?f~pq$C1-LR|m<{|{uoc=NTi|Ih>= z3ycpOIKbL@M;^%KC<*clW&kPzfvcxNj2IZ0o_V@BhEy=Vo%^=$wE_=oyKv_H{}c1g z8xuZXRNH$yOx45oG!vW64U787X{kGVB2-=~&Dt`_WSQDpmEM)<8O=-ne75z>dX;u< z)0yOt`%MZ8qCKtFm0$7-S~;sMJ6YMYe#PW1tA!PR2_@y1mb_Lu9<1{C#oPSDI)=+? zw;j8%i*x_=d)8A~o@ba(uRrg3Zuw`U?`a7?W@Y<4TDH+dj`MYA(s~YEPxsPUW|LLZ zzkhyXzqDO$L)E#jPeZp~++z20&-~L*Y?+PUUenB6-0A(peT&+LvaRor&W-o3R+rd& zV_N3BGw&{adzM>UubO+jo6YU{+PjOtij^D09#DO`;h*v3;*{@w?zvZ=Y;yQL>yEX; zw^g%rJl(&Z`5rdOZq@SrN8{bA?P~X1ZF3ErzU1()Q$Ev{EH}wi&Ghk&@{|fTzm*y} zZ8gUO=3k6Edh}d>e=b(N<9+d7f__W2?ybnljBZz#uu23^7E1ssZ!k2?WIT3-kU-p8 z0jC{391P+YVJbzp$o+lbdgqMR>8%Xgj&=JVY&L$BW2VLC*Y>JEgYkQGd(`Q-5!YWZ zyuEge?ZE`2+@7P`4$95kYB+n{w_{JP@5@X(bkDeFOJUXAt;>&#o;2FI#kB33uSj;V zeqM@sO#kVgOrzp_wqtLf&8j%FZ*^=o&v)d0|GYhxW z_pE+6X(zThT2{lnGG`RqC8*H1FJYPP$y z{Tj=)$m;D~NtvrdzOz+t)V+LX=GV;CTA|0c&b9Tu<$i5n&yVuk1#A6p*Y(BT`nH?3 zDg5(W)A`Tu-nN)}(sEPv@x|M`awo=}+ZgA&?a$72$GTpy7yG{Zc`Nevzk5u3{PJy9 z)!w?D5xa + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d9/d66/classshaka_1_1media_1_1PackedAudioSegmenter.html b/docs/d9/d66/classshaka_1_1media_1_1PackedAudioSegmenter.html index 1698a04e2d..01d6d2a76f 100644 --- a/docs/d9/d66/classshaka_1_1media_1_1PackedAudioSegmenter.html +++ b/docs/d9/d66/classshaka_1_1media_1_1PackedAudioSegmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::PackedAudioSegmenter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d9/d67/structshaka_1_1media_1_1H265VuiParameters.html b/docs/d9/d67/structshaka_1_1media_1_1H265VuiParameters.html index ee9452db7e..bc9701adcd 100644 --- a/docs/d9/d67/structshaka_1_1media_1_1H265VuiParameters.html +++ b/docs/d9/d67/structshaka_1_1media_1_1H265VuiParameters.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265VuiParameters Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    min_spatial_segmentati
    diff --git a/docs/d9/d68/classshaka_1_1media_1_1CombinedMuxerListener.html b/docs/d9/d68/classshaka_1_1media_1_1CombinedMuxerListener.html index a4a644d7c5..c33611ec88 100644 --- a/docs/d9/d68/classshaka_1_1media_1_1CombinedMuxerListener.html +++ b/docs/d9/d68/classshaka_1_1media_1_1CombinedMuxerListener.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::CombinedMuxerListener Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::CombinedMuxerListener Class Reference
    + +

    #include <combined_muxer_listener.h>

    Inheritance diagram for shaka::media::CombinedMuxerListener:
    -shaka::media::MuxerListener - -
    +shaka::media::MuxerListener +shaka::media::MultiCodecMuxerListener + +
    + @@ -101,25 +109,91 @@ void 

    Public Member Functions

    void AddListener (std::unique_ptr< MuxerListener > listener)
     
    MuxerListener implementation overrides.
    void OnEncryptionInfoReady (bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
     
    void OnEncryptionStart () override
    AddListener (std:
    void OnCueEvent (int64_t timestamp, const std::string &cue_data) override
     
    + + + + + +

    +Protected Member Functions

    void LimitNumOfMuxerListners (size_t num)
     
    MuxerListenerMuxerListenerAt (size_t index)
     

    Additional Inherited Members

    - Public Types inherited from shaka::media::MuxerListener
    enum  ContainerType {
    -  kContainerUnknown = 0, -kContainerMp4, -kContainerMpeg2ts, -kContainerWebM, -
    -  kContainerText, -kContainerPackedAudio +  kContainerUnknown = 0 +, kContainerMp4 +, kContainerMpeg2ts +, kContainerWebM +,
    +  kContainerText +, kContainerPackedAudio
    }
     

    Detailed Description

    -
    -

    Definition at line 18 of file combined_muxer_listener.h.

    +

    This class supports a group of MuxerListeners. All events are forwarded to every individual MuxerListeners contained in this CombinedMuxerListener.

    + +

    Definition at line 20 of file combined_muxer_listener.h.

    Member Function Documentation

    + +

    ◆ LimitNumOfMuxerListners()

    + +
    +
    + + + + + +
    + + + + + + + + +
    void shaka::media::CombinedMuxerListener::LimitNumOfMuxerListners (size_t num)
    +
    +inlineprotected
    +
    +

    Limit the number of children MuxerListeners. It can only be used to reduce the number of children. @num is the number to set to. It is a no-op if num is equal or greater than the existing number of children MuxerListeners.

    + +

    Definition at line 55 of file combined_muxer_listener.h.

    + +
    +
    + +

    ◆ MuxerListenerAt()

    + +
    +
    + + + + + +
    + + + + + + + + +
    MuxerListener* shaka::media::CombinedMuxerListener::MuxerListenerAt (size_t index)
    +
    +inlineprotected
    +
    +
    Returns
    MuxerListener at the specified index or nullptr if the index is out of range.
    + +

    Definition at line 61 of file combined_muxer_listener.h.

    + +
    +

    ◆ OnCueEvent()

    @@ -410,7 +484,7 @@ Additional Inherited Members
    -

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    +

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    @@ -422,6 +496,8 @@ Additional Inherited Members

    Implements shaka::media::MuxerListener.

    +

    Reimplemented in shaka::media::MultiCodecMuxerListener.

    +

    Definition at line 36 of file combined_muxer_listener.cc.

    @@ -530,9 +606,7 @@ Additional Inherited Members diff --git a/docs/d9/d68/classshaka_1_1media_1_1CombinedMuxerListener.png b/docs/d9/d68/classshaka_1_1media_1_1CombinedMuxerListener.png index 4af70dd2fe6394be57d99d411a46470b4b481612..57853c5ad18dfc5e3ddcf8af2f7814d20e73cd5b 100644 GIT binary patch delta 1206 zcmdnVc8^oBGr-TCmrII^fq{Y7)59eQNWTW+4i07@X}IN$@I*zcdX`*I7srqa#*#_t%_lXDL#fdCT`I>$W?_&AKgoCb#x4nQ}=<$@7xXtu>QO=9{fn zIlG)clHc>~M`cg0uRO1nPyYyQ`?I!f&(2vYM}G;eR{1V-efJ;lNp5%F_N)B$dcS#I zsqD@@%Khh<);Vgfn3GiZ`;TO6z3H_%+awguYpp+Z<m4W|v+yf69xYS~(N)mh??>6EAMR&&0N?9Siw=8eHh&M8Z# z|GIJbYJcxnsV{3Rk3`;WXI(xyy>w0KTfLQ>)0WKt;+fB7R(2z*eBIuIyEk08oj1!k zq<+em#mm0FtbIGtxg-4h)y-SH^XAG{{CJmCbNukyO;#UFU27{0@;W7cZ7^SxeQaG< z{gXt`U-sFXy)M-tLg8pcuvaE8V@*7NgXyy>VLOeOQM{UBijr!g-ftyW%&@`#FF8I<3zydN!z+oHJCc ze{|TOcwbpm+yj}LOTFeDi(3BF_eA~GMeFNTKTqG)<(+wY!CJg; z6MOGkrdjZm<+mj#uRpZ2DRz?KkG`!_pUGa0?c3*eSnOEwgL$`E6tllJPLBPmH@!Uf z$-`IfuQk|X{T^}^hW+Qwp1-`I>e`$;o45UbFnPv<-Sv z?OgZYHfI+&%71GsJzL@N^Vk3I2F_!8nms0EalSmAar(mEb&lrya{@Yn+2Ybq z@0GWoty(zMw0ceC+g0mTj6o5UoZk0-@AH_pgr^C0&9C*^J7t@zuWhTld*q+3&?%zhgi zsJ7$1?{>dk*4OVnh`o`%rnY$RZ22GOxBs+zdZOy_8G%PvYrk&&B50~{O5nD>Ip^y) z2M(8uzqaMyex~$6u^TXt%GhoA(sN99zgp>H7PL&a(=g6pNBzxhxz#&vsJy%w)icRtzu01x zv+KoHRqNM@sWnp->sKq9hfiJ-Sbsp{r0vU!>GhtMR&1`FxMX{2f8l!d zr<;Q0-g3(~2YFa-{qyasF;{kdk7cgq2bO8B?9 z#&&{KsKxPfGWVr5wr@CX$mV@%>N_K|dAnXV_qP?@sWnNoP5#(9eXgvUY2&1lRonMO z)n1qAcRWACdCt<>hytm~u;UTe-%Xm8;JNG4-Fd<}Pc}?_CsVClp1836u1Wd=jhFRr z)4rUmeG_>2(fW6b(=(>uu(J5@>L%-t`n|WbRx!tWUkPV#p4PE&eO2RY@zjl_`o_l+qZo~eo;s*|YW$cNMKi~d`;h6ZN$BOoigc6c!KUrS<{5#KGCP*>U`_e1TUc23Wo-;xdC zb>eAemFvRZ1=mDB)i-3ac>BJI|Gvol@2Yp^Z5GKlcvl&Jc=0ZqTl;Sb-+b(QV*d|= zGjo>DohE+6y=>*A<%ZWXCGGx)a@$QiQy>3IOD~mgYw#y2)B1lmGWr>uMb8!9)6IWv zGF$W1<+mLt!xzRJ)H^A0$9UVMJ;hd^zi*XXW-za%+E2Kp=j)xhZ&s!6JoEG&Fx=DU zK2A8jPG0fcCHurTpG6$b&zM|&>{<2vBP`!-pO=K6KesXc$4kqyLh*a=CH%V!UB7(a z=+4`f-2Z+efA-!*={DxOEjf#SMo(NAu3uAsc(rb^?2kEt@uj)tFD|T|ZKeOMa+YB8 zzE{03XT6?a^zT2%2Mb-dhM!v{7@u7Sg^>KA89`p>uhn;bGGK4#J~9)S!WleW{an^L HB{Ts5ko + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    muxer_optionsis the options for Muxer.
    stream_infois the information of this media.
    - + +/* @license-end */
    field_pic_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader first_mb_in_slice (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader frame_num (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - H264SliceHeader() (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - header_bit_size (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - idr_pic_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - idr_pic_id (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - IsBSlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - IsISlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - IsPSlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - IsSISlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - IsSPSlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - kBSlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - kISlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - kPSlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - kRefListModSize enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - kRefListSize enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - kSISlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - kSPSlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - long_term_reference_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - luma_log2_weight_denom (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - nal_ref_idc (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - nalu_data (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - nalu_size (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - no_output_of_prior_pics_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - num_ref_idx_active_override_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - num_ref_idx_l0_active_minus1 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - num_ref_idx_l1_active_minus1 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - pic_order_cnt_lsb (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - pic_parameter_set_id (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - pred_weight_table_l0 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - pred_weight_table_l1 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - redundant_pic_cnt (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - ref_list_l0_modifications (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - ref_list_l1_modifications (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - ref_pic_list_modification_flag_l0 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - ref_pic_list_modification_flag_l1 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - ref_pic_marking (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - slice_alpha_c0_offset_div2 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - slice_beta_offset_div2 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - slice_qp_delta (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - slice_qs_delta (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - slice_type (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - sp_for_switch_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader - Type enum name (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + header_bit_size (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + idr_pic_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + idr_pic_id (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + IsBSlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + IsISlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + IsPSlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + IsSISlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + IsSPSlice() const (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + kBSlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + kISlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + kPSlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + kRefListModSize enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + kRefListSize enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + kSISlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + kSPSlice enum value (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + long_term_reference_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + luma_log2_weight_denom (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + nal_ref_idc (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + nalu_data (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + nalu_size (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + no_output_of_prior_pics_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + num_ref_idx_active_override_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + num_ref_idx_l0_active_minus1 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + num_ref_idx_l1_active_minus1 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + pic_order_cnt_lsb (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + pic_parameter_set_id (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + pred_weight_table_l0 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + pred_weight_table_l1 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + redundant_pic_cnt (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + ref_list_l0_modifications (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + ref_list_l1_modifications (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + ref_pic_list_modification_flag_l0 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + ref_pic_list_modification_flag_l1 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + ref_pic_marking (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + slice_alpha_c0_offset_div2 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + slice_beta_offset_div2 (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + slice_qp_delta (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + slice_qs_delta (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + slice_type (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + sp_for_switch_flag (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader + Type enum name (defined in shaka::media::H264SliceHeader)shaka::media::H264SliceHeader
    diff --git a/docs/d9/d76/ts__muxer_8cc_source.html b/docs/d9/d76/ts__muxer_8cc_source.html index 7affaa6ceb..3bbfd9ab7f 100644 --- a/docs/d9/d76/ts__muxer_8cc_source.html +++ b/docs/d9/d76/ts__muxer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_muxer.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    ts_muxer.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp2t/ts_muxer.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 namespace mp2t {
    12 
    13 namespace {
    14 const uint32_t kTsTimescale = 90000;
    15 } // namespace
    16 
    17 TsMuxer::TsMuxer(const MuxerOptions& muxer_options) : Muxer(muxer_options) {}
    18 TsMuxer::~TsMuxer() {}
    19 
    20 Status TsMuxer::InitializeMuxer() {
    21  if (streams().size() > 1u)
    22  return Status(error::MUXER_FAILURE, "Cannot handle more than one streams.");
    23 
    24  segmenter_.reset(new TsSegmenter(options(), muxer_listener()));
    25  Status status = segmenter_->Initialize(*streams()[0]);
    26  FireOnMediaStartEvent();
    27  return status;
    28 }
    29 
    30 Status TsMuxer::Finalize() {
    31  FireOnMediaEndEvent();
    32  return segmenter_->Finalize();
    33 }
    34 
    35 Status TsMuxer::AddSample(size_t stream_id, const MediaSample& sample) {
    36  DCHECK_EQ(stream_id, 0u);
    37  return segmenter_->AddSample(sample);
    38 }
    39 
    40 Status TsMuxer::FinalizeSegment(size_t stream_id,
    41  const SegmentInfo& segment_info) {
    42  DCHECK_EQ(stream_id, 0u);
    43  return segment_info.is_subsegment
    44  ? Status::OK
    45  : segmenter_->FinalizeSegment(segment_info.start_timestamp,
    46  segment_info.duration);
    47 }
    48 
    49 void TsMuxer::FireOnMediaStartEvent() {
    50  if (!muxer_listener())
    51  return;
    52  muxer_listener()->OnMediaStart(options(), *streams().front(), kTsTimescale,
    53  MuxerListener::kContainerMpeg2ts);
    54 }
    55 
    56 void TsMuxer::FireOnMediaEndEvent() {
    57  if (!muxer_listener())
    58  return;
    59 
    60  // For now, there is no single file TS segmenter. So all the values passed
    61  // here are left empty.
    62  MuxerListener::MediaRanges range;
    63  muxer_listener()->OnMediaEnd(range, 0);
    64 }
    65 
    66 } // namespace mp2t
    67 } // namespace media
    68 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/ts_muxer.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 namespace mp2t {
    +
    12 
    +
    13 namespace {
    +
    14 const uint32_t kTsTimescale = 90000;
    +
    15 } // namespace
    +
    16 
    +
    17 TsMuxer::TsMuxer(const MuxerOptions& muxer_options) : Muxer(muxer_options) {}
    +
    18 TsMuxer::~TsMuxer() {}
    +
    19 
    +
    20 Status TsMuxer::InitializeMuxer() {
    +
    21  if (streams().size() > 1u)
    +
    22  return Status(error::MUXER_FAILURE, "Cannot handle more than one streams.");
    +
    23 
    +
    24  segmenter_.reset(new TsSegmenter(options(), muxer_listener()));
    +
    25  Status status = segmenter_->Initialize(*streams()[0]);
    +
    26  FireOnMediaStartEvent();
    +
    27  return status;
    +
    28 }
    +
    29 
    +
    30 Status TsMuxer::Finalize() {
    +
    31  FireOnMediaEndEvent();
    +
    32  return segmenter_->Finalize();
    +
    33 }
    +
    34 
    +
    35 Status TsMuxer::AddMediaSample(size_t stream_id, const MediaSample& sample) {
    +
    36  DCHECK_EQ(stream_id, 0u);
    +
    37  if (num_samples_ < 2) {
    +
    38  sample_durations_[num_samples_] =
    +
    39  sample.duration() * kTsTimescale / streams().front()->time_scale();
    +
    40  if (num_samples_ == 1 && muxer_listener())
    +
    41  muxer_listener()->OnSampleDurationReady(sample_durations_[num_samples_]);
    +
    42  num_samples_++;
    +
    43  }
    +
    44  return segmenter_->AddSample(sample);
    +
    45 }
    +
    46 
    +
    47 Status TsMuxer::FinalizeSegment(size_t stream_id,
    +
    48  const SegmentInfo& segment_info) {
    +
    49  DCHECK_EQ(stream_id, 0u);
    +
    50  return segment_info.is_subsegment
    +
    51  ? Status::OK
    +
    52  : segmenter_->FinalizeSegment(segment_info.start_timestamp,
    +
    53  segment_info.duration);
    +
    54 }
    +
    55 
    +
    56 void TsMuxer::FireOnMediaStartEvent() {
    +
    57  if (!muxer_listener())
    +
    58  return;
    +
    59  muxer_listener()->OnMediaStart(options(), *streams().front(), kTsTimescale,
    +
    60  MuxerListener::kContainerMpeg2ts);
    +
    61 }
    +
    62 
    +
    63 void TsMuxer::FireOnMediaEndEvent() {
    +
    64  if (!muxer_listener())
    +
    65  return;
    +
    66 
    +
    67  // For now, there is no single file TS segmenter. So all the values passed
    +
    68  // here are left empty.
    +
    69  MuxerListener::MediaRanges range;
    +
    70  muxer_listener()->OnMediaEnd(range, 0);
    +
    71 }
    +
    72 
    +
    73 } // namespace mp2t
    +
    74 } // namespace media
    +
    75 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/d7e/classshaka_1_1media_1_1BaseDescriptor-members.html b/docs/d9/d7e/classshaka_1_1media_1_1BaseDescriptor-members.html index 71e6dee5f0..baba63ce2b 100644 --- a/docs/d9/d7e/classshaka_1_1media_1_1BaseDescriptor-members.html +++ b/docs/d9/d7e/classshaka_1_1media_1_1BaseDescriptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d9/d81/classshaka_1_1media_1_1ClosureThread-members.html b/docs/d9/d81/classshaka_1_1media_1_1ClosureThread-members.html index 4ad4d09d4d..4e91d81312 100644 --- a/docs/d9/d81/classshaka_1_1media_1_1ClosureThread-members.html +++ b/docs/d9/d81/classshaka_1_1media_1_1ClosureThread-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d9/d86/limits_8h_source.html b/docs/d9/d86/limits_8h_source.html index 7533e96849..a63f9d1a27 100644 --- a/docs/d9/d86/limits_8h_source.html +++ b/docs/d9/d86/limits_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/limits.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    limits.h
    -
    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 // Contains limit definition constants for the media subsystem.
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_LIMITS_H_
    8 #define PACKAGER_MEDIA_BASE_LIMITS_H_
    9 
    10 namespace shaka {
    11 namespace media {
    12 
    13 namespace limits {
    14 
    15 enum {
    16  // Maximum possible dimension (width or height) for any video.
    17  kMaxDimension = (1 << 15) - 1, // 32767
    18 
    19  // Maximum possible canvas size (width multiplied by height) for any video.
    20  kMaxCanvas = (1 << (14 * 2)), // 16384 x 16384
    21 
    22  // Total number of video frames which are populating in the pipeline.
    23  kMaxVideoFrames = 4,
    24 
    25  // The following limits are used by AudioParameters::IsValid().
    26  //
    27  // A few notes on sample rates of common formats:
    28  // - AAC files are limited to 96 kHz.
    29  // - MP3 files are limited to 48 kHz.
    30  // - Vorbis used to be limited to 96 KHz, but no longer has that
    31  // restriction.
    32  // - Most PC audio hardware is limited to 192 KHz.
    33  kMaxSampleRate = 192000,
    34  kMinSampleRate = 3000,
    35  kMaxChannels = 32,
    36  kMaxBytesPerSample = 4,
    37  kMaxBitsPerSample = kMaxBytesPerSample * 8,
    38  kMaxSamplesPerPacket = kMaxSampleRate,
    39  kMaxPacketSizeInBytes =
    40  kMaxBytesPerSample * kMaxChannels * kMaxSamplesPerPacket,
    41 
    42  // This limit is used by ParamTraits<VideoCaptureParams>.
    43  kMaxFramesPerSecond = 1000,
    44 };
    45 
    46 } // namespace limits
    47 
    48 } // namespace media
    49 } // namespace shaka
    50 
    51 #endif // PACKAGER_MEDIA_BASE_LIMITS_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 // Contains limit definition constants for the media subsystem.
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_LIMITS_H_
    +
    8 #define PACKAGER_MEDIA_BASE_LIMITS_H_
    +
    9 
    +
    10 namespace shaka {
    +
    11 namespace media {
    +
    12 
    +
    13 namespace limits {
    +
    14 
    +
    15 enum {
    +
    16  // Maximum possible dimension (width or height) for any video.
    +
    17  kMaxDimension = (1 << 15) - 1, // 32767
    +
    18 
    +
    19  // Maximum possible canvas size (width multiplied by height) for any video.
    +
    20  kMaxCanvas = (1 << (14 * 2)), // 16384 x 16384
    +
    21 
    +
    22  // Total number of video frames which are populating in the pipeline.
    +
    23  kMaxVideoFrames = 4,
    +
    24 
    +
    25  // The following limits are used by AudioParameters::IsValid().
    +
    26  //
    +
    27  // A few notes on sample rates of common formats:
    +
    28  // - AAC files are limited to 96 kHz.
    +
    29  // - MP3 files are limited to 48 kHz.
    +
    30  // - Vorbis used to be limited to 96 KHz, but no longer has that
    +
    31  // restriction.
    +
    32  // - Most PC audio hardware is limited to 192 KHz.
    +
    33  kMaxSampleRate = 192000,
    +
    34  kMinSampleRate = 3000,
    +
    35  kMaxChannels = 32,
    +
    36  kMaxBytesPerSample = 4,
    +
    37  kMaxBitsPerSample = kMaxBytesPerSample * 8,
    +
    38  kMaxSamplesPerPacket = kMaxSampleRate,
    +
    39  kMaxPacketSizeInBytes =
    +
    40  kMaxBytesPerSample * kMaxChannels * kMaxSamplesPerPacket,
    +
    41 
    +
    42  // This limit is used by ParamTraits<VideoCaptureParams>.
    +
    43  kMaxFramesPerSecond = 1000,
    +
    44 };
    +
    45 
    +
    46 } // namespace limits
    +
    47 
    +
    48 } // namespace media
    +
    49 } // namespace shaka
    +
    50 
    +
    51 #endif // PACKAGER_MEDIA_BASE_LIMITS_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/d87/classshaka_1_1media_1_1WebMContentEncodingsClient.html b/docs/d9/d87/classshaka_1_1media_1_1WebMContentEncodingsClient.html index 2cc0c9b18c..94f7680580 100644 --- a/docs/d9/d87/classshaka_1_1media_1_1WebMContentEncodingsClient.html +++ b/docs/d9/d87/classshaka_1_1media_1_1WebMContentEncodingsClient.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMContentEncodingsClient Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::WebMParserClient - -
    + + @@ -128,9 +131,7 @@ Additional Inherited Members diff --git a/docs/d9/d8c/classshaka_1_1media_1_1AesRequestSigner.html b/docs/d9/d8c/classshaka_1_1media_1_1AesRequestSigner.html index c78e54b8d4..d846c6cdbb 100644 --- a/docs/d9/d8c/classshaka_1_1media_1_1AesRequestSigner.html +++ b/docs/d9/d8c/classshaka_1_1media_1_1AesRequestSigner.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::AesRequestSigner Class Reference @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    -

    AesRequestSigner uses AES-CBC signing. +

    AesRequestSigner uses AES-CBC signing. More...

    #include <request_signer.h>

    @@ -81,15 +84,15 @@ Inheritance diagram for shaka::media::AesRequestSigner:
    -shaka::media::RequestSigner - -
    +shaka::media::RequestSigner + + - +

    Public Member Functions

    bool GenerateSignature (const std::string &message, std::string *signature) override
     RequestSigner implementation override.
     RequestSigner implementation override.
     
    - Public Member Functions inherited from shaka::media::RequestSigner
    @@ -109,7 +112,7 @@ Additional Inherited Members
     

    Detailed Description

    -

    AesRequestSigner uses AES-CBC signing.

    +

    AesRequestSigner uses AES-CBC signing.

    Definition at line 45 of file request_signer.h.

    Member Function Documentation

    @@ -152,7 +155,7 @@ Additional Inherited Members
    -

    Create an AesSigner object from key and iv.

    Returns
    The created AesRequestSigner object on success, NULL otherwise.
    +

    Create an AesSigner object from key and iv.

    Returns
    The created AesRequestSigner object on success, NULL otherwise.

    Definition at line 28 of file request_signer.cc.

    @@ -165,9 +168,7 @@ Additional Inherited Members
    diff --git a/docs/d9/d90/text__track_8h_source.html b/docs/d9/d90/text__track_8h_source.html index e97b64975a..bcd914bf93 100644 --- a/docs/d9/d90/text__track_8h_source.html +++ b/docs/d9/d90/text__track_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/text_track.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    text_track.h
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_BASE_TEXT_TRACK_H_
    6 #define PACKAGER_MEDIA_BASE_TEXT_TRACK_H_
    7 
    8 #include <memory>
    9 #include <string>
    10 
    11 #include "packager/base/callback.h"
    12 #include "packager/base/time/time.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    18 enum TextKind {
    19  kTextSubtitles,
    20  kTextCaptions,
    21  kTextDescriptions,
    22  kTextMetadata,
    23  kTextNone
    24 };
    25 
    26 class TextTrack {
    27  public:
    28  ~TextTrack() override {}
    29  virtual void addWebVTTCue(const base::TimeDelta& start,
    30  const base::TimeDelta& end,
    31  const std::string& id,
    32  const std::string& content,
    33  const std::string& settings) = 0;
    34 };
    35 
    36 typedef base::Callback<std::unique_ptr<TextTrack>(TextKind kind,
    37  const std::string& label,
    38  const std::string& language)>
    39  AddTextTrackCB;
    40 
    41 } // namespace media
    42 } // namespace shaka
    43 
    44 #endif // PACKAGER_MEDIA_BASE_TEXT_TRACK_H_
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_BASE_TEXT_TRACK_H_
    +
    6 #define PACKAGER_MEDIA_BASE_TEXT_TRACK_H_
    +
    7 
    +
    8 #include <memory>
    +
    9 #include <string>
    +
    10 
    +
    11 #include "packager/base/callback.h"
    +
    12 #include "packager/base/time/time.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    18 enum TextKind {
    +
    19  kTextSubtitles,
    +
    20  kTextCaptions,
    +
    21  kTextDescriptions,
    +
    22  kTextMetadata,
    +
    23  kTextNone
    +
    24 };
    +
    25 
    +
    26 class TextTrack {
    +
    27  public:
    +
    28  ~TextTrack() override {}
    +
    29  virtual void addWebVTTCue(const base::TimeDelta& start,
    +
    30  const base::TimeDelta& end,
    +
    31  const std::string& id,
    +
    32  const std::string& content,
    +
    33  const std::string& settings) = 0;
    +
    34 };
    +
    35 
    +
    36 typedef base::Callback<std::unique_ptr<TextTrack>(TextKind kind,
    +
    37  const std::string& label,
    +
    38  const std::string& language)>
    +
    39  AddTextTrackCB;
    +
    40 
    +
    41 } // namespace media
    +
    42 } // namespace shaka
    +
    43 
    +
    44 #endif // PACKAGER_MEDIA_BASE_TEXT_TRACK_H_
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/d9b/classshaka_1_1hls_1_1MediaPlaylistFactory.html b/docs/d9/d9b/classshaka_1_1hls_1_1MediaPlaylistFactory.html index a5090030fa..7778fce6d4 100644 --- a/docs/d9/d9b/classshaka_1_1hls_1_1MediaPlaylistFactory.html +++ b/docs/d9/d9b/classshaka_1_1hls_1_1MediaPlaylistFactory.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::hls::MediaPlaylistFactory Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
     

    Detailed Description

    -

    For testing. Creates MediaPlaylist. Mock this and return mock MediaPlaylist.

    +

    For testing. Creates MediaPlaylist. Mock this and return mock MediaPlaylist.

    Definition at line 28 of file simple_hls_notifier.h.


    The documentation for this class was generated from the following files:
      @@ -89,9 +92,7 @@ virtual std::unique_ptr< diff --git a/docs/d9/d9b/sample__aes__ec3__cryptor_8cc_source.html b/docs/d9/d9b/sample__aes__ec3__cryptor_8cc_source.html index d119e003e0..501f9a90b9 100644 --- a/docs/d9/d9b/sample__aes__ec3__cryptor_8cc_source.html +++ b/docs/d9/d9b/sample__aes__ec3__cryptor_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto/sample_aes_ec3_cryptor.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    sample_aes_ec3_cryptor.cc
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/crypto/sample_aes_ec3_cryptor.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/media/base/buffer_reader.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 namespace {
    17 
    18 bool ExtractEac3SyncframeSizes(const uint8_t* source,
    19  size_t source_size,
    20  std::vector<size_t>* syncframe_sizes) {
    21  DCHECK(source);
    22  DCHECK(syncframe_sizes);
    23 
    24  syncframe_sizes->clear();
    25  BufferReader frame(source, source_size);
    26  // ASTC Standard A/52:2012 Annex E: Enhanced AC-3.
    27  while (frame.HasBytes(1)) {
    28  uint16_t syncword;
    29  if (!frame.Read2(&syncword)) {
    30  LOG(ERROR) << "Not enough bytes for syncword.";
    31  return false;
    32  }
    33  if (syncword != 0x0B77) {
    34  LOG(ERROR) << "Invalid E-AC3 frame. Seeing 0x" << std::hex << syncword
    35  << std::dec
    36  << ". The sync frame does not start with "
    37  "the valid syncword 0x0B77.";
    38  return false;
    39  }
    40  uint16_t stream_type_and_syncframe_size;
    41  if (!frame.Read2(&stream_type_and_syncframe_size)) {
    42  LOG(ERROR) << "Not enough bytes for syncframe size.";
    43  return false;
    44  }
    45  // frmsiz = least significant 11 bits. syncframe_size is (frmsiz + 1) * 2.
    46  const size_t syncframe_size =
    47  ((stream_type_and_syncframe_size & 0x7FF) + 1) * 2;
    48  if (!frame.SkipBytes(syncframe_size - sizeof(syncword) -
    49  sizeof(stream_type_and_syncframe_size))) {
    50  LOG(ERROR) << "Not enough bytes for syncframe. Expecting "
    51  << syncframe_size << " bytes.";
    52  return false;
    53  }
    54  syncframe_sizes->push_back(syncframe_size);
    55  }
    56  return true;
    57 }
    58 
    59 } // namespace
    60 
    61 SampleAesEc3Cryptor::SampleAesEc3Cryptor(std::unique_ptr<AesCryptor> cryptor)
    62  : AesCryptor(AesCryptor::kUseConstantIv), cryptor_(std::move(cryptor)) {
    63  DCHECK(cryptor_);
    64  DCHECK(!cryptor_->use_constant_iv());
    65 }
    66 
    67 bool SampleAesEc3Cryptor::InitializeWithIv(const std::vector<uint8_t>& key,
    68  const std::vector<uint8_t>& iv) {
    69  return SetIv(iv) && cryptor_->InitializeWithIv(key, iv);
    70 }
    71 
    72 bool SampleAesEc3Cryptor::CryptInternal(const uint8_t* text,
    73  size_t text_size,
    74  uint8_t* crypt_text,
    75  size_t* crypt_text_size) {
    76  // |crypt_text_size| is the same as |text_size|.
    77  if (*crypt_text_size < text_size) {
    78  LOG(ERROR) << "Expecting output size of at least " << text_size
    79  << " bytes.";
    80  return false;
    81  }
    82  *crypt_text_size = text_size;
    83 
    84  std::vector<size_t> syncframe_sizes;
    85  if (!ExtractEac3SyncframeSizes(text, text_size, &syncframe_sizes))
    86  return false;
    87 
    88  // MPEG-2 Stream Encryption Format for HTTP Live Streaming 2.3.1.3 Enhanced
    89  // AC-3: The first 16 bytes, starting with the syncframe() header, are not
    90  // encrypted.
    91  const size_t kLeadingClearBytesSize = 16u;
    92 
    93  for (size_t syncframe_size : syncframe_sizes) {
    94  memcpy(crypt_text, text, std::min(syncframe_size, kLeadingClearBytesSize));
    95  if (syncframe_size > kLeadingClearBytesSize) {
    96  // The residual block is left untouched (copied without
    97  // encryption/decryption). No need to do special handling here.
    98  if (!cryptor_->Crypt(text + kLeadingClearBytesSize,
    99  syncframe_size - kLeadingClearBytesSize,
    100  crypt_text + kLeadingClearBytesSize)) {
    101  return false;
    102  }
    103  }
    104  text += syncframe_size;
    105  crypt_text += syncframe_size;
    106  }
    107  return true;
    108 }
    109 
    110 void SampleAesEc3Cryptor::SetIvInternal() {
    111  CHECK(cryptor_->SetIv(iv()));
    112 }
    113 
    114 } // namespace media
    115 } // namespace shaka
    -
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    -
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    -
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    -
    SampleAesEc3Cryptor(std::unique_ptr< AesCryptor > cryptor)
    -
    bool SetIv(const std::vector< uint8_t > &iv)
    Definition: aes_cryptor.cc:70
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/crypto/sample_aes_ec3_cryptor.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/buffer_reader.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 namespace {
    +
    17 
    +
    18 bool ExtractEac3SyncframeSizes(const uint8_t* source,
    +
    19  size_t source_size,
    +
    20  std::vector<size_t>* syncframe_sizes) {
    +
    21  DCHECK(source);
    +
    22  DCHECK(syncframe_sizes);
    +
    23 
    +
    24  syncframe_sizes->clear();
    +
    25  BufferReader frame(source, source_size);
    +
    26  // ASTC Standard A/52:2012 Annex E: Enhanced AC-3.
    +
    27  while (frame.HasBytes(1)) {
    +
    28  uint16_t syncword;
    +
    29  if (!frame.Read2(&syncword)) {
    +
    30  LOG(ERROR) << "Not enough bytes for syncword.";
    +
    31  return false;
    +
    32  }
    +
    33  if (syncword != 0x0B77) {
    +
    34  LOG(ERROR) << "Invalid E-AC3 frame. Seeing 0x" << std::hex << syncword
    +
    35  << std::dec
    +
    36  << ". The sync frame does not start with "
    +
    37  "the valid syncword 0x0B77.";
    +
    38  return false;
    +
    39  }
    +
    40  uint16_t stream_type_and_syncframe_size;
    +
    41  if (!frame.Read2(&stream_type_and_syncframe_size)) {
    +
    42  LOG(ERROR) << "Not enough bytes for syncframe size.";
    +
    43  return false;
    +
    44  }
    +
    45  // frmsiz = least significant 11 bits. syncframe_size is (frmsiz + 1) * 2.
    +
    46  const size_t syncframe_size =
    +
    47  ((stream_type_and_syncframe_size & 0x7FF) + 1) * 2;
    +
    48  if (!frame.SkipBytes(syncframe_size - sizeof(syncword) -
    +
    49  sizeof(stream_type_and_syncframe_size))) {
    +
    50  LOG(ERROR) << "Not enough bytes for syncframe. Expecting "
    +
    51  << syncframe_size << " bytes.";
    +
    52  return false;
    +
    53  }
    +
    54  syncframe_sizes->push_back(syncframe_size);
    +
    55  }
    +
    56  return true;
    +
    57 }
    +
    58 
    +
    59 } // namespace
    +
    60 
    +
    61 SampleAesEc3Cryptor::SampleAesEc3Cryptor(std::unique_ptr<AesCryptor> cryptor)
    +
    62  : AesCryptor(AesCryptor::kUseConstantIv), cryptor_(std::move(cryptor)) {
    +
    63  DCHECK(cryptor_);
    +
    64  DCHECK(!cryptor_->use_constant_iv());
    +
    65 }
    +
    66 
    +
    67 bool SampleAesEc3Cryptor::InitializeWithIv(const std::vector<uint8_t>& key,
    +
    68  const std::vector<uint8_t>& iv) {
    +
    69  return SetIv(iv) && cryptor_->InitializeWithIv(key, iv);
    +
    70 }
    +
    71 
    +
    72 bool SampleAesEc3Cryptor::CryptInternal(const uint8_t* text,
    +
    73  size_t text_size,
    +
    74  uint8_t* crypt_text,
    +
    75  size_t* crypt_text_size) {
    +
    76  // |crypt_text_size| is the same as |text_size|.
    +
    77  if (*crypt_text_size < text_size) {
    +
    78  LOG(ERROR) << "Expecting output size of at least " << text_size
    +
    79  << " bytes.";
    +
    80  return false;
    +
    81  }
    +
    82  *crypt_text_size = text_size;
    +
    83 
    +
    84  std::vector<size_t> syncframe_sizes;
    +
    85  if (!ExtractEac3SyncframeSizes(text, text_size, &syncframe_sizes))
    +
    86  return false;
    +
    87 
    +
    88  // MPEG-2 Stream Encryption Format for HTTP Live Streaming 2.3.1.3 Enhanced
    +
    89  // AC-3: The first 16 bytes, starting with the syncframe() header, are not
    +
    90  // encrypted.
    +
    91  const size_t kLeadingClearBytesSize = 16u;
    +
    92 
    +
    93  for (size_t syncframe_size : syncframe_sizes) {
    +
    94  memcpy(crypt_text, text, std::min(syncframe_size, kLeadingClearBytesSize));
    +
    95  if (syncframe_size > kLeadingClearBytesSize) {
    +
    96  // The residual block is left untouched (copied without
    +
    97  // encryption/decryption). No need to do special handling here.
    +
    98  if (!cryptor_->Crypt(text + kLeadingClearBytesSize,
    +
    99  syncframe_size - kLeadingClearBytesSize,
    +
    100  crypt_text + kLeadingClearBytesSize)) {
    +
    101  return false;
    +
    102  }
    +
    103  }
    +
    104  text += syncframe_size;
    +
    105  crypt_text += syncframe_size;
    +
    106  }
    +
    107  return true;
    +
    108 }
    +
    109 
    +
    110 void SampleAesEc3Cryptor::SetIvInternal() {
    +
    111  CHECK(cryptor_->SetIv(iv()));
    +
    112 }
    +
    113 
    +
    114 } // namespace media
    +
    115 } // namespace shaka
    + +
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    +
    bool SetIv(const std::vector< uint8_t > &iv)
    Definition: aes_cryptor.cc:70
    +
    SampleAesEc3Cryptor(std::unique_ptr< AesCryptor > cryptor)
    +
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/da0/classshaka_1_1media_1_1SampleAesEc3Cryptor.html b/docs/d9/da0/classshaka_1_1media_1_1SampleAesEc3Cryptor.html index ebf8f08d83..ae7aff18cc 100644 --- a/docs/d9/da0/classshaka_1_1media_1_1SampleAesEc3Cryptor.html +++ b/docs/d9/da0/classshaka_1_1media_1_1SampleAesEc3Cryptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SampleAesEc3Cryptor Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::AesCryptor - -
    + + @@ -114,8 +117,8 @@ bool  - @@ -217,9 +220,7 @@ AES_KEY * 

    Public Member Functions

    Crypt (const uint

    Additional Inherited Members

    - Public Types inherited from shaka::media::AesCryptor
    enum  ConstantIvFlag { kUseConstantIv, -kDontUseConstantIv +
    enum  ConstantIvFlag { kUseConstantIv +, kDontUseConstantIv }
     
    - Static Public Member Functions inherited from shaka::media::AesCryptor
    mutable_aes_key< diff --git a/docs/d9/da4/stream__descriptor_8h_source.html b/docs/d9/da4/stream__descriptor_8h_source.html index ac491c04be..5c955547b8 100644 --- a/docs/d9/da4/stream__descriptor_8h_source.html +++ b/docs/d9/da4/stream__descriptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/stream_descriptor.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    stream_descriptor.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef APP_STREAM_DESCRIPTOR_H_
    8 #define APP_STREAM_DESCRIPTOR_H_
    9 
    10 #include <string>
    11 
    12 #include "packager/base/optional.h"
    13 #include "packager/packager.h"
    14 
    15 namespace shaka {
    16 
    24 base::Optional<StreamDescriptor> ParseStreamDescriptor(
    25  const std::string& descriptor_string);
    26 
    27 } // namespace shaka
    28 
    29 #endif // APP_STREAM_DESCRIPTOR_H_
    base::Optional< StreamDescriptor > ParseStreamDescriptor(const std::string &descriptor_string)
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef APP_STREAM_DESCRIPTOR_H_
    +
    8 #define APP_STREAM_DESCRIPTOR_H_
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 #include "packager/base/optional.h"
    +
    13 #include "packager/packager.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 
    +
    24 base::Optional<StreamDescriptor> ParseStreamDescriptor(
    +
    25  const std::string& descriptor_string);
    +
    26 
    +
    27 } // namespace shaka
    +
    28 
    +
    29 #endif // APP_STREAM_DESCRIPTOR_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    base::Optional< StreamDescriptor > ParseStreamDescriptor(const std::string &descriptor_string)
    diff --git a/docs/d9/da5/classshaka_1_1media_1_1MpdNotifyMuxerListener.html b/docs/d9/da5/classshaka_1_1media_1_1MpdNotifyMuxerListener.html index 8165860a1f..a8929b448b 100644 --- a/docs/d9/da5/classshaka_1_1media_1_1MpdNotifyMuxerListener.html +++ b/docs/d9/da5/classshaka_1_1media_1_1MpdNotifyMuxerListener.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MpdNotifyMuxerListener Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::MuxerListener - -
    + + @@ -111,13 +114,13 @@ void  @@ -204,7 +207,7 @@ Additional Inherited Members

    Implements shaka::media::MuxerListener.

    -

    Definition at line 197 of file mpd_notify_muxer_listener.cc.

    +

    Definition at line 204 of file mpd_notify_muxer_listener.cc.

    @@ -355,7 +358,7 @@ Additional Inherited Members

    Implements shaka::media::MuxerListener.

    -

    Definition at line 191 of file mpd_notify_muxer_listener.cc.

    +

    Definition at line 198 of file mpd_notify_muxer_listener.cc.

    @@ -402,7 +405,7 @@ Additional Inherited Members

    Implements shaka::media::MuxerListener.

    -

    Definition at line 125 of file mpd_notify_muxer_listener.cc.

    +

    Definition at line 132 of file mpd_notify_muxer_listener.cc.

    @@ -451,7 +454,7 @@ Additional Inherited Members

    Public Member Functions

    set_roles (const Additional Inherited Members
    - Public Types inherited from shaka::media::MuxerListener
    enum  ContainerType {
    -  kContainerUnknown = 0, -kContainerMp4, -kContainerMpeg2ts, -kContainerWebM, -
    -  kContainerText, -kContainerPackedAudio +  kContainerUnknown = 0 +, kContainerMp4 +, kContainerMpeg2ts +, kContainerWebM +,
    +  kContainerText +, kContainerPackedAudio
    }
     
    -

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    +

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    @@ -524,7 +527,7 @@ Additional Inherited Members

    Implements shaka::media::MuxerListener.

    -

    Definition at line 174 of file mpd_notify_muxer_listener.cc.

    +

    Definition at line 181 of file mpd_notify_muxer_listener.cc.

    @@ -560,7 +563,7 @@ Additional Inherited Members

    Implements shaka::media::MuxerListener.

    -

    Definition at line 104 of file mpd_notify_muxer_listener.cc.

    +

    Definition at line 111 of file mpd_notify_muxer_listener.cc.

    @@ -571,9 +574,7 @@ Additional Inherited Members diff --git a/docs/d9/da7/classshaka_1_1media_1_1mp4_1_1Segmenter-members.html b/docs/d9/da7/classshaka_1_1media_1_1mp4_1_1Segmenter-members.html index ce87cf3c5b..59bf193c4b 100644 --- a/docs/d9/da7/classshaka_1_1media_1_1mp4_1_1Segmenter-members.html +++ b/docs/d9/da7/classshaka_1_1media_1_1mp4_1_1Segmenter-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    muxer_optionsis the options for Muxer.
    stream_infois the information of this media.
    - + +/* @license-end */
    diff --git a/docs/d9/da8/structshaka_1_1BufferCallbackParams.html b/docs/d9/da8/structshaka_1_1BufferCallbackParams.html index 03b4d762e2..1db8d6bd39 100644 --- a/docs/d9/da8/structshaka_1_1BufferCallbackParams.html +++ b/docs/d9/da8/structshaka_1_1BufferCallbackParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::BufferCallbackParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -

    If this function is specified, packager treats StreamDescriptor.input as a label and call this function with name set to StreamDescriptor.input.

    +

    If this function is specified, packager treats StreamDescriptor.input as a label and call this function with name set to StreamDescriptor.input.

    Definition at line 20 of file buffer_callback_params.h.

    @@ -115,7 +118,7 @@ Public Attributes
    -

    If this function is specified, packager treats the output files specified in PackagingParams and StreamDescriptors as labels and calls this function with name set. This applies to PackagingParams.MpdParams.mpd_output, PackagingParams.HlsParams.master_playlist_output, StreamDescriptor.output, StreamDescriptor.segment_template, StreamDescriptor.hls_playlist_name.

    +

    If this function is specified, packager treats the output files specified in PackagingParams and StreamDescriptors as labels and calls this function with name set. This applies to PackagingParams.MpdParams.mpd_output, PackagingParams.HlsParams.master_playlist_output, StreamDescriptor.output, StreamDescriptor.segment_template, StreamDescriptor.hls_playlist_name.

    Definition at line 30 of file buffer_callback_params.h.

    @@ -127,9 +130,7 @@ Public Attributes
    diff --git a/docs/d9/dae/text__muxer_8h_source.html b/docs/d9/dae/text__muxer_8h_source.html new file mode 100644 index 0000000000..52d087896e --- /dev/null +++ b/docs/d9/dae/text__muxer_8h_source.html @@ -0,0 +1,128 @@ + + + + + + + +Shaka Packager SDK: packager/media/base/text_muxer.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    text_muxer.h
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_TEXT_MUXER_H_
    +
    8 #define PACKAGER_MEDIA_BASE_TEXT_MUXER_H_
    +
    9 
    +
    10 #include "packager/media/base/muxer.h"
    +
    11 #include "packager/media/base/text_sample.h"
    +
    12 #include "packager/media/base/text_stream_info.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    20 class TextMuxer : public Muxer {
    +
    21  public:
    +
    22  explicit TextMuxer(const MuxerOptions& options);
    +
    23  ~TextMuxer() override;
    +
    24 
    +
    25  private:
    +
    26  // Muxer implementation overrides.
    +
    27  Status InitializeMuxer() override;
    +
    28  Status Finalize() override;
    +
    29  Status AddTextSample(size_t stream_id, const TextSample& sample) override;
    +
    30  Status FinalizeSegment(size_t stream_id,
    +
    31  const SegmentInfo& segment_info) override;
    +
    32 
    +
    33  virtual Status InitializeStream(TextStreamInfo* stream) = 0;
    +
    34  virtual Status AddTextSampleInternal(const TextSample& sample) = 0;
    +
    37  virtual Status WriteToFile(const std::string& filename, uint64_t* size) = 0;
    +
    38 
    +
    39  uint64_t total_duration_ms_ = 0;
    +
    40  uint64_t last_cue_ms_ = 0;
    +
    41  uint32_t segment_index_ = 0;
    +
    42 };
    +
    43 
    +
    44 } // namespace media
    +
    45 } // namespace shaka
    +
    46 
    +
    47 #endif // PACKAGER_MEDIA_BASE_TEXT_MUXER_H_
    + + + + + +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    + +
    + + + + diff --git a/docs/d9/db2/classshaka_1_1media_1_1mp4_1_1CompositionOffsetIterator-members.html b/docs/d9/db2/classshaka_1_1media_1_1mp4_1_1CompositionOffsetIterator-members.html index c5eef0c45b..377fd0862a 100644 --- a/docs/d9/db2/classshaka_1_1media_1_1mp4_1_1CompositionOffsetIterator-members.html +++ b/docs/d9/db2/classshaka_1_1media_1_1mp4_1_1CompositionOffsetIterator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d9/db9/content__protection__element_8cc_source.html b/docs/d9/db9/content__protection__element_8cc_source.html index 3663cf16a2..35e2ce4121 100644 --- a/docs/d9/db9/content__protection__element_8cc_source.html +++ b/docs/d9/db9/content__protection__element_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/content_protection_element.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    content_protection_element.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/mpd/base/content_protection_element.h"
    8 
    9 namespace shaka {
    10 Element::Element() {}
    11 Element::~Element() {}
    12 ContentProtectionElement::ContentProtectionElement() {}
    13 ContentProtectionElement::~ContentProtectionElement() {}
    14 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/mpd/base/content_protection_element.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 Element::Element() {}
    +
    11 Element::~Element() {}
    +
    12 ContentProtectionElement::ContentProtectionElement() {}
    +
    13 ContentProtectionElement::~ContentProtectionElement() {}
    +
    14 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/db9/muxer_8cc_source.html b/docs/d9/db9/muxer_8cc_source.html index 888186dc06..01e08a2ae0 100644 --- a/docs/d9/db9/muxer_8cc_source.html +++ b/docs/d9/db9/muxer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/muxer.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    muxer.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/muxer.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/media/base/media_sample.h"
    12 #include "packager/media/base/muxer_util.h"
    13 #include "packager/status_macros.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 namespace {
    18 const bool kInitialEncryptionInfo = true;
    19 const int64_t kStartTime = 0;
    20 } // namespace
    21 
    22 Muxer::Muxer(const MuxerOptions& options) : options_(options) {
    23  // "$" is only allowed if the output file name is a template, which is used to
    24  // support one file per Representation per Period when there are Ad Cues.
    25  if (options_.output_file_name.find("$") != std::string::npos)
    26  output_file_template_ = options_.output_file_name;
    27 }
    28 
    29 Muxer::~Muxer() {}
    30 
    31 void Muxer::Cancel() {
    32  cancelled_ = true;
    33 }
    34 
    35 void Muxer::SetMuxerListener(std::unique_ptr<MuxerListener> muxer_listener) {
    36  muxer_listener_ = std::move(muxer_listener);
    37 }
    38 
    40  std::unique_ptr<ProgressListener> progress_listener) {
    41  progress_listener_ = std::move(progress_listener);
    42 }
    43 
    44 Status Muxer::Process(std::unique_ptr<StreamData> stream_data) {
    45  Status status;
    46  switch (stream_data->stream_data_type) {
    47  case StreamDataType::kStreamInfo:
    48  streams_.push_back(std::move(stream_data->stream_info));
    49  return ReinitializeMuxer(kStartTime);
    50  case StreamDataType::kSegmentInfo: {
    51  const auto& segment_info = *stream_data->segment_info;
    52  if (muxer_listener_ && segment_info.is_encrypted) {
    53  const EncryptionConfig* encryption_config =
    54  segment_info.key_rotation_encryption_config.get();
    55  // Only call OnEncryptionInfoReady again when key updates.
    56  if (encryption_config && encryption_config->key_id != current_key_id_) {
    57  muxer_listener_->OnEncryptionInfoReady(
    58  !kInitialEncryptionInfo, encryption_config->protection_scheme,
    59  encryption_config->key_id, encryption_config->constant_iv,
    60  encryption_config->key_system_info);
    61  current_key_id_ = encryption_config->key_id;
    62  }
    63  if (!encryption_started_) {
    64  encryption_started_ = true;
    65  muxer_listener_->OnEncryptionStart();
    66  }
    67  }
    68  return FinalizeSegment(stream_data->stream_index, segment_info);
    69  }
    70  case StreamDataType::kMediaSample:
    71  return AddSample(stream_data->stream_index, *stream_data->media_sample);
    72  case StreamDataType::kCueEvent:
    73  if (muxer_listener_) {
    74  const int64_t time_scale =
    75  streams_[stream_data->stream_index]->time_scale();
    76  const double time_in_seconds = stream_data->cue_event->time_in_seconds;
    77  const int64_t scaled_time =
    78  static_cast<int64_t>(time_in_seconds * time_scale);
    79  muxer_listener_->OnCueEvent(scaled_time,
    80  stream_data->cue_event->cue_data);
    81 
    82  // Finalize and re-initialize Muxer to generate different content files.
    83  if (!output_file_template_.empty()) {
    84  RETURN_IF_ERROR(Finalize());
    85  RETURN_IF_ERROR(ReinitializeMuxer(scaled_time));
    86  }
    87  }
    88  break;
    89  default:
    90  VLOG(3) << "Stream data type "
    91  << static_cast<int>(stream_data->stream_data_type) << " ignored.";
    92  break;
    93  }
    94  // No dispatch for muxer.
    95  return Status::OK;
    96 }
    97 
    98 Status Muxer::OnFlushRequest(size_t input_stream_index) {
    99  return Finalize();
    100 }
    101 
    102 Status Muxer::ReinitializeMuxer(int64_t timestamp) {
    103  if (muxer_listener_ && streams_.back()->is_encrypted()) {
    104  const EncryptionConfig& encryption_config =
    105  streams_.back()->encryption_config();
    106  muxer_listener_->OnEncryptionInfoReady(
    107  kInitialEncryptionInfo, encryption_config.protection_scheme,
    108  encryption_config.key_id, encryption_config.constant_iv,
    109  encryption_config.key_system_info);
    110  current_key_id_ = encryption_config.key_id;
    111  }
    112  if (!output_file_template_.empty()) {
    113  // Update |output_file_name| with an actual file name, which will be used by
    114  // the subclasses.
    115  options_.output_file_name =
    116  GetSegmentName(output_file_template_, timestamp, output_file_index_++,
    117  options_.bandwidth);
    118  }
    119  return InitializeMuxer();
    120 }
    121 
    122 } // namespace media
    123 } // namespace shaka
    -
    Status OnFlushRequest(size_t input_stream_index) override
    Event handler for flush request at the specific input stream index.
    Definition: muxer.cc:98
    - -
    All the methods that are virtual are virtual for mocking.
    - - -
    void SetProgressListener(std::unique_ptr< ProgressListener > progress_listener)
    Definition: muxer.cc:39
    -
    Status Process(std::unique_ptr< StreamData > stream_data) override
    Definition: muxer.cc:44
    - -
    void SetMuxerListener(std::unique_ptr< MuxerListener > muxer_listener)
    Definition: muxer.cc:35
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/muxer.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/media/base/media_sample.h"
    +
    12 #include "packager/media/base/muxer_util.h"
    +
    13 #include "packager/status_macros.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 namespace {
    +
    18 const bool kInitialEncryptionInfo = true;
    +
    19 const int64_t kStartTime = 0;
    +
    20 } // namespace
    +
    21 
    +
    22 Muxer::Muxer(const MuxerOptions& options) : options_(options) {
    +
    23  // "$" is only allowed if the output file name is a template, which is used to
    +
    24  // support one file per Representation per Period when there are Ad Cues.
    +
    25  if (options_.output_file_name.find("$") != std::string::npos)
    +
    26  output_file_template_ = options_.output_file_name;
    +
    27 }
    +
    28 
    +
    29 Muxer::~Muxer() {}
    +
    30 
    +
    31 void Muxer::Cancel() {
    +
    32  cancelled_ = true;
    +
    33 }
    +
    34 
    +
    35 void Muxer::SetMuxerListener(std::unique_ptr<MuxerListener> muxer_listener) {
    +
    36  muxer_listener_ = std::move(muxer_listener);
    +
    37 }
    +
    38 
    +
    39 void Muxer::SetProgressListener(
    +
    40  std::unique_ptr<ProgressListener> progress_listener) {
    +
    41  progress_listener_ = std::move(progress_listener);
    +
    42 }
    +
    43 
    +
    44 Status Muxer::Process(std::unique_ptr<StreamData> stream_data) {
    +
    45  Status status;
    +
    46  switch (stream_data->stream_data_type) {
    +
    47  case StreamDataType::kStreamInfo:
    +
    48  streams_.push_back(std::move(stream_data->stream_info));
    +
    49  return ReinitializeMuxer(kStartTime);
    +
    50  case StreamDataType::kSegmentInfo: {
    +
    51  const auto& segment_info = *stream_data->segment_info;
    +
    52  if (muxer_listener_ && segment_info.is_encrypted) {
    +
    53  const EncryptionConfig* encryption_config =
    +
    54  segment_info.key_rotation_encryption_config.get();
    +
    55  // Only call OnEncryptionInfoReady again when key updates.
    +
    56  if (encryption_config && encryption_config->key_id != current_key_id_) {
    +
    57  muxer_listener_->OnEncryptionInfoReady(
    +
    58  !kInitialEncryptionInfo, encryption_config->protection_scheme,
    +
    59  encryption_config->key_id, encryption_config->constant_iv,
    +
    60  encryption_config->key_system_info);
    +
    61  current_key_id_ = encryption_config->key_id;
    +
    62  }
    +
    63  if (!encryption_started_) {
    +
    64  encryption_started_ = true;
    +
    65  muxer_listener_->OnEncryptionStart();
    +
    66  }
    +
    67  }
    +
    68  return FinalizeSegment(stream_data->stream_index, segment_info);
    +
    69  }
    +
    70  case StreamDataType::kMediaSample:
    +
    71  return AddMediaSample(stream_data->stream_index,
    +
    72  *stream_data->media_sample);
    +
    73  case StreamDataType::kTextSample:
    +
    74  return AddTextSample(stream_data->stream_index,
    +
    75  *stream_data->text_sample);
    +
    76  case StreamDataType::kCueEvent:
    +
    77  if (muxer_listener_) {
    +
    78  const int64_t time_scale =
    +
    79  streams_[stream_data->stream_index]->time_scale();
    +
    80  const double time_in_seconds = stream_data->cue_event->time_in_seconds;
    +
    81  const int64_t scaled_time =
    +
    82  static_cast<int64_t>(time_in_seconds * time_scale);
    +
    83  muxer_listener_->OnCueEvent(scaled_time,
    +
    84  stream_data->cue_event->cue_data);
    +
    85 
    +
    86  // Finalize and re-initialize Muxer to generate different content files.
    +
    87  if (!output_file_template_.empty()) {
    +
    88  RETURN_IF_ERROR(Finalize());
    +
    89  RETURN_IF_ERROR(ReinitializeMuxer(scaled_time));
    +
    90  }
    +
    91  }
    +
    92  break;
    +
    93  default:
    +
    94  VLOG(3) << "Stream data type "
    +
    95  << static_cast<int>(stream_data->stream_data_type) << " ignored.";
    +
    96  break;
    +
    97  }
    +
    98  // No dispatch for muxer.
    +
    99  return Status::OK;
    +
    100 }
    +
    101 
    +
    102 Status Muxer::OnFlushRequest(size_t input_stream_index) {
    +
    103  return Finalize();
    +
    104 }
    +
    105 
    +
    106 Status Muxer::AddMediaSample(size_t stream_id, const MediaSample& sample) {
    +
    107  return Status::OK;
    +
    108 }
    +
    109 
    +
    110 Status Muxer::AddTextSample(size_t stream_id, const TextSample& sample) {
    +
    111  return Status::OK;
    +
    112 }
    +
    113 
    +
    114 Status Muxer::ReinitializeMuxer(int64_t timestamp) {
    +
    115  if (muxer_listener_ && streams_.back()->is_encrypted()) {
    +
    116  const EncryptionConfig& encryption_config =
    +
    117  streams_.back()->encryption_config();
    +
    118  muxer_listener_->OnEncryptionInfoReady(
    +
    119  kInitialEncryptionInfo, encryption_config.protection_scheme,
    +
    120  encryption_config.key_id, encryption_config.constant_iv,
    +
    121  encryption_config.key_system_info);
    +
    122  current_key_id_ = encryption_config.key_id;
    +
    123  }
    +
    124  if (!output_file_template_.empty()) {
    +
    125  // Update |output_file_name| with an actual file name, which will be used by
    +
    126  // the subclasses.
    +
    127  options_.output_file_name =
    +
    128  GetSegmentName(output_file_template_, timestamp, output_file_index_++,
    +
    129  options_.bandwidth);
    +
    130  }
    +
    131  return InitializeMuxer();
    +
    132 }
    +
    133 
    +
    134 } // namespace media
    +
    135 } // namespace shaka
    + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/d9/dc4/classshaka_1_1media_1_1BufferReader-members.html b/docs/d9/dc4/classshaka_1_1media_1_1BufferReader-members.html index 72ab284972..8d82c78410 100644 --- a/docs/d9/dc4/classshaka_1_1media_1_1BufferReader-members.html +++ b/docs/d9/dc4/classshaka_1_1media_1_1BufferReader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    Read4s(int32_t *v) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader Read8(uint64_t *v) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader Read8s(int64_t *v) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader - ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULTshaka::media::BufferReader - ReadNBytesInto8s(int64_t *v, size_t num_bytes) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader - ReadToString(std::string *str, size_t size) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader - ReadToVector(std::vector< uint8_t > *t, size_t count) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader - set_size(size_t size) (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline - size() const (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline - SkipBytes(size_t num_bytes) WARN_UNUSED_RESULTshaka::media::BufferReader - ~BufferReader() (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline + ReadCString(std::string *str) WARN_UNUSED_RESULTshaka::media::BufferReader + ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULTshaka::media::BufferReader + ReadNBytesInto8s(int64_t *v, size_t num_bytes) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader + ReadToString(std::string *str, size_t size) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader + ReadToVector(std::vector< uint8_t > *t, size_t count) WARN_UNUSED_RESULT (defined in shaka::media::BufferReader)shaka::media::BufferReader + set_size(size_t size) (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline + size() const (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline + SkipBytes(size_t num_bytes) WARN_UNUSED_RESULTshaka::media::BufferReader + ~BufferReader() (defined in shaka::media::BufferReader)shaka::media::BufferReaderinline
    diff --git a/docs/d9/dc4/structshaka_1_1media_1_1mp4_1_1SampleEncryptionEntry-members.html b/docs/d9/dc4/structshaka_1_1media_1_1mp4_1_1SampleEncryptionEntry-members.html index a9d9dfff20..16f810b47f 100644 --- a/docs/d9/dc4/structshaka_1_1media_1_1mp4_1_1SampleEncryptionEntry-members.html +++ b/docs/d9/dc4/structshaka_1_1media_1_1mp4_1_1SampleEncryptionEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d9/dc7/classshaka_1_1media_1_1BitWriter-members.html b/docs/d9/dc7/classshaka_1_1media_1_1BitWriter-members.html index 7d2afdc50e..d36a63be80 100644 --- a/docs/d9/dc7/classshaka_1_1media_1_1BitWriter-members.html +++ b/docs/d9/dc7/classshaka_1_1media_1_1BitWriter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/d9/dc8/webm__constants_8cc_source.html b/docs/d9/dc8/webm__constants_8cc_source.html index 5652621069..7ff530a692 100644 --- a/docs/d9/dc8/webm__constants_8cc_source.html +++ b/docs/d9/dc8/webm__constants_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_constants.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webm_constants.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/webm/webm_constants.h"
    6 
    7 namespace shaka {
    8 namespace media {
    9 
    10 const char kWebMCodecSubtitles[] = "D_WEBVTT/SUBTITLES";
    11 const char kWebMCodecCaptions[] = "D_WEBVTT/CAPTIONS";
    12 const char kWebMCodecDescriptions[] = "D_WEBVTT/DESCRIPTIONS";
    13 const char kWebMCodecMetadata[] = "D_WEBVTT/METADATA";
    14 
    15 } // namespace media
    16 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/webm/webm_constants.h"
    +
    6 
    +
    7 namespace shaka {
    +
    8 namespace media {
    +
    9 
    +
    10 const char kWebMCodecSubtitles[] = "D_WEBVTT/SUBTITLES";
    +
    11 const char kWebMCodecCaptions[] = "D_WEBVTT/CAPTIONS";
    +
    12 const char kWebMCodecDescriptions[] = "D_WEBVTT/DESCRIPTIONS";
    +
    13 const char kWebMCodecMetadata[] = "D_WEBVTT/METADATA";
    +
    14 
    +
    15 } // namespace media
    +
    16 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/dca/ttml__to__mp4__handler_8h_source.html b/docs/d9/dca/ttml__to__mp4__handler_8h_source.html new file mode 100644 index 0000000000..4634990628 --- /dev/null +++ b/docs/d9/dca/ttml__to__mp4__handler_8h_source.html @@ -0,0 +1,126 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/ttml/ttml_to_mp4_handler.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    ttml_to_mp4_handler.h
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_TTML_TTML_TO_MP4_HANDLER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_TTML_TTML_TO_MP4_HANDLER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 
    +
    12 #include "packager/media/base/media_handler.h"
    +
    13 #include "packager/media/formats/ttml/ttml_generator.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 namespace ttml {
    +
    18 
    +
    19 // A media handler that should come after the cue aligner and segmenter and
    +
    20 // should come before the muxer. This handler is to convert text samples
    +
    21 // to media samples so that they can be sent to a mp4 muxer.
    + +
    23  public:
    +
    24  TtmlToMp4Handler() = default;
    +
    25  ~TtmlToMp4Handler() override = default;
    +
    26 
    +
    27  private:
    +
    28  Status InitializeInternal() override;
    +
    29  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    30 
    +
    31  Status OnStreamInfo(std::unique_ptr<StreamData> stream_data);
    +
    32  Status OnCueEvent(std::unique_ptr<StreamData> stream_data);
    +
    33  Status OnSegmentInfo(std::unique_ptr<StreamData> stream_data);
    +
    34  Status OnTextSample(std::unique_ptr<StreamData> stream_data);
    +
    35 
    +
    36  TtmlGenerator generator_;
    +
    37 };
    +
    38 
    +
    39 } // namespace ttml
    +
    40 } // namespace media
    +
    41 } // namespace shaka
    +
    42 
    +
    43 #endif // PACKAGER_MEDIA_FORMATS_TTML_TTML_TO_MP4_HANDLER_H_
    + + + + +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/d9/dcc/webm__video__client_8h_source.html b/docs/d9/dcc/webm__video__client_8h_source.html index 4a6a34a19c..498e410211 100644 --- a/docs/d9/dcc/webm__video__client_8h_source.html +++ b/docs/d9/dcc/webm__video__client_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_video_client.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    webm_video_client.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_VIDEO_CLIENT_H_
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_VIDEO_CLIENT_H_
    7 
    8 #include <memory>
    9 #include <string>
    10 #include <vector>
    11 
    12 #include "packager/media/base/video_stream_info.h"
    13 #include "packager/media/codecs/vp_codec_configuration_record.h"
    14 #include "packager/media/formats/webm/webm_parser.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 class VideoDecoderConfig;
    19 
    22  public:
    24  ~WebMVideoClient() override;
    25 
    27  void Reset();
    28 
    35  std::shared_ptr<VideoStreamInfo> GetVideoStreamInfo(
    36  int64_t track_num,
    37  const std::string& codec_id,
    38  const std::vector<uint8_t>& codec_private,
    39  bool is_encrypted);
    40 
    44  const std::vector<uint8_t>& codec_private);
    45 
    46  private:
    47  // WebMParserClient implementation.
    48  WebMParserClient* OnListStart(int id) override;
    49  bool OnListEnd(int id) override;
    50  bool OnUInt(int id, int64_t val) override;
    51  bool OnBinary(int id, const uint8_t* data, int size) override;
    52  bool OnFloat(int id, double val) override;
    53 
    54  int64_t pixel_width_ = -1;
    55  int64_t pixel_height_ = -1;
    56  int64_t crop_bottom_ = -1;
    57  int64_t crop_top_ = -1;
    58  int64_t crop_left_ = -1;
    59  int64_t crop_right_ = -1;
    60  int64_t display_width_ = -1;
    61  int64_t display_height_ = -1;
    62  int64_t display_unit_ = -1;
    63  int64_t alpha_mode_ = -1;
    64 
    65  int64_t matrix_coefficients_ = -1;
    66  int64_t bits_per_channel_ = -1;
    67  int64_t chroma_subsampling_horz_ = -1;
    68  int64_t chroma_subsampling_vert_ = -1;
    69  int64_t chroma_siting_horz_ = -1;
    70  int64_t chroma_siting_vert_ = -1;
    71  int64_t color_range_ = -1;
    72  int64_t transfer_characteristics_ = -1;
    73  int64_t color_primaries_ = -1;
    74 
    75  DISALLOW_COPY_AND_ASSIGN(WebMVideoClient);
    76 };
    77 
    78 } // namespace media
    79 } // namespace shaka
    80 
    81 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_VIDEO_CLIENT_H_
    std::shared_ptr< VideoStreamInfo > GetVideoStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, bool is_encrypted)
    -
    VPCodecConfigurationRecord GetVpCodecConfig(const std::vector< uint8_t > &codec_private)
    -
    void Reset()
    Reset this object&#39;s state so it can process a new video track element.
    -
    Class for parsing or writing VP codec configuration record.
    -
    All the methods that are virtual are virtual for mocking.
    -
    Helper class used to parse a Video element inside a TrackEntry element.
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_VIDEO_CLIENT_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_VIDEO_CLIENT_H_
    +
    7 
    +
    8 #include <memory>
    +
    9 #include <string>
    +
    10 #include <vector>
    +
    11 
    +
    12 #include "packager/media/base/video_stream_info.h"
    +
    13 #include "packager/media/codecs/vp_codec_configuration_record.h"
    +
    14 #include "packager/media/formats/webm/webm_parser.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 class VideoDecoderConfig;
    +
    19 
    + +
    22  public:
    + +
    24  ~WebMVideoClient() override;
    +
    25 
    +
    27  void Reset();
    +
    28 
    +
    35  std::shared_ptr<VideoStreamInfo> GetVideoStreamInfo(
    +
    36  int64_t track_num,
    +
    37  const std::string& codec_id,
    +
    38  const std::vector<uint8_t>& codec_private,
    +
    39  bool is_encrypted);
    +
    40 
    + +
    44  const std::vector<uint8_t>& codec_private);
    +
    45 
    +
    46  private:
    +
    47  // WebMParserClient implementation.
    +
    48  WebMParserClient* OnListStart(int id) override;
    +
    49  bool OnListEnd(int id) override;
    +
    50  bool OnUInt(int id, int64_t val) override;
    +
    51  bool OnBinary(int id, const uint8_t* data, int size) override;
    +
    52  bool OnFloat(int id, double val) override;
    +
    53 
    +
    54  int64_t pixel_width_ = -1;
    +
    55  int64_t pixel_height_ = -1;
    +
    56  int64_t crop_bottom_ = -1;
    +
    57  int64_t crop_top_ = -1;
    +
    58  int64_t crop_left_ = -1;
    +
    59  int64_t crop_right_ = -1;
    +
    60  int64_t display_width_ = -1;
    +
    61  int64_t display_height_ = -1;
    +
    62  int64_t display_unit_ = -1;
    +
    63  int64_t alpha_mode_ = -1;
    +
    64 
    +
    65  int64_t matrix_coefficients_ = -1;
    +
    66  int64_t bits_per_channel_ = -1;
    +
    67  int64_t chroma_subsampling_horz_ = -1;
    +
    68  int64_t chroma_subsampling_vert_ = -1;
    +
    69  int64_t chroma_siting_horz_ = -1;
    +
    70  int64_t chroma_siting_vert_ = -1;
    +
    71  int64_t color_range_ = -1;
    +
    72  int64_t transfer_characteristics_ = -1;
    +
    73  int64_t color_primaries_ = -1;
    +
    74 
    +
    75  DISALLOW_COPY_AND_ASSIGN(WebMVideoClient);
    +
    76 };
    +
    77 
    +
    78 } // namespace media
    +
    79 } // namespace shaka
    +
    80 
    +
    81 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_VIDEO_CLIENT_H_
    +
    Class for parsing or writing VP codec configuration record.
    + +
    Helper class used to parse a Video element inside a TrackEntry element.
    +
    std::shared_ptr< VideoStreamInfo > GetVideoStreamInfo(int64_t track_num, const std::string &codec_id, const std::vector< uint8_t > &codec_private, bool is_encrypted)
    +
    VPCodecConfigurationRecord GetVpCodecConfig(const std::vector< uint8_t > &codec_private)
    +
    void Reset()
    Reset this object's state so it can process a new video track element.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/dd2/structshaka_1_1WidevineEncryptionParams.html b/docs/d9/dd2/structshaka_1_1WidevineEncryptionParams.html index 518d82a406..65b58ea8f6 100644 --- a/docs/d9/dd2/structshaka_1_1WidevineEncryptionParams.html +++ b/docs/d9/dd2/structshaka_1_1WidevineEncryptionParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::WidevineEncryptionParams Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Detailed Description

    Widevine encryption parameters.

    -

    Definition at line 51 of file crypto_params.h.

    +

    Definition at line 88 of file crypto_params.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/d9/dda/ac3__header_8cc_source.html b/docs/d9/dda/ac3__header_8cc_source.html index f5d2db9b54..bc885865ae 100644 --- a/docs/d9/dda/ac3__header_8cc_source.html +++ b/docs/d9/dda/ac3__header_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ac3_header.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    ac3_header.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp2t/ac3_header.h"
    8 
    9 #include "packager/media/base/bit_reader.h"
    10 #include "packager/media/base/bit_writer.h"
    11 #include "packager/media/formats/mp2t/mp2t_common.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace mp2t {
    16 namespace {
    17 
    18 // ASTC Standard A/52:2012 Table 5.6 Sample Rate Codes.
    19 const uint32_t kAc3SampleRateTable[] = {48000, 44100, 32000};
    20 
    21 // ASTC Standard A/52:2012 Table 5.8 Audio Coding Mode.
    22 const uint8_t kAc3NumChannelsTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
    23 
    24 // ATSC Standard A/52:2012 Table 5.18 Frame Size Code Table
    25 // (in words = 16 bits).
    26 const size_t kFrameSizeCodeTable[][3] = {
    27  // {32kHz, 44.1kHz, 48kHz}
    28  {96, 69, 64}, {96, 70, 64}, {120, 87, 80},
    29  {120, 88, 80}, {144, 104, 96}, {144, 105, 96},
    30  {168, 121, 112}, {168, 122, 112}, {192, 139, 128},
    31  {192, 140, 128}, {240, 174, 160}, {240, 175, 160},
    32  {288, 208, 192}, {288, 209, 192}, {336, 243, 224},
    33  {336, 244, 224}, {384, 278, 256}, {384, 279, 256},
    34  {480, 348, 320}, {480, 349, 320}, {576, 417, 384},
    35  {576, 418, 384}, {672, 487, 448}, {672, 488, 448},
    36  {768, 557, 512}, {768, 558, 512}, {960, 696, 640},
    37  {960, 697, 640}, {1152, 835, 768}, {1152, 836, 768},
    38  {1344, 975, 896}, {1344, 976, 896}, {1536, 1114, 1024},
    39  {1536, 1115, 1024}, {1728, 1253, 1152}, {1728, 1254, 1152},
    40  {1920, 1393, 1280}, {1920, 1394, 1280},
    41 };
    42 
    43 // Calculate the size of the frame from the sample rate code and the
    44 // frame size code.
    45 // @return the size of the frame (header + payload).
    46 size_t CalcFrameSize(uint8_t fscod, uint8_t frmsizecod) {
    47  const size_t kNumFscode = arraysize(kAc3SampleRateTable);
    48  DCHECK_LT(fscod, kNumFscode);
    49  DCHECK_LT(frmsizecod, arraysize(kFrameSizeCodeTable));
    50  // The order of frequencies are reversed in |kFrameSizeCodeTable| compared to
    51  // |kAc3SampleRateTable|.
    52  const int index = kNumFscode - 1 - fscod;
    53  return kFrameSizeCodeTable[frmsizecod][index] * 2;
    54 }
    55 
    56 } // namespace
    57 
    58 bool Ac3Header::IsSyncWord(const uint8_t* buf) const {
    59  DCHECK(buf);
    60  // ATSC Standard A/52:2012 5.4.1 syncinfo: Synchronization Information.
    61  return buf[0] == 0x0B && buf[1] == 0x77;
    62 }
    63 
    65  // Arbitrary. Actual frame size starts with 96 words.
    66  const size_t kMinAc3FrameSize = 10u;
    67  return kMinAc3FrameSize;
    68 }
    69 
    71  // ATSC Standard A/52:2012
    72  // Annex A: AC-3 Elementary Streams in the MPEG-2 Multiplex.
    73  const size_t kSamplesPerAc3Frame = 1536;
    74  return kSamplesPerAc3Frame;
    75 }
    76 
    77 bool Ac3Header::Parse(const uint8_t* audio_frame, size_t audio_frame_size) {
    78  BitReader frame(audio_frame, audio_frame_size);
    79 
    80  // ASTC Standard A/52:2012 5. BIT STREAM SYNTAX.
    81  // syncinfo: synchronization information section.
    82  uint16_t syncword;
    83  RCHECK(frame.ReadBits(16, &syncword));
    84  RCHECK(syncword == 0x0B77);
    85  uint16_t crc1;
    86  RCHECK(frame.ReadBits(16, &crc1));
    87  RCHECK(frame.ReadBits(2, &fscod_));
    88  RCHECK(fscod_ < arraysize(kAc3SampleRateTable));
    89  RCHECK(frame.ReadBits(6, &frmsizecod_));
    90  RCHECK(frmsizecod_ < arraysize(kFrameSizeCodeTable));
    91 
    92  // bsi: bit stream information section.
    93  RCHECK(frame.ReadBits(5, &bsid_));
    94  RCHECK(frame.ReadBits(3, &bsmod_));
    95 
    96  RCHECK(frame.ReadBits(3, &acmod_));
    97  RCHECK(acmod_ < arraysize(kAc3NumChannelsTable));
    98  // If 3 front channels.
    99  if ((acmod_ & 0x01) && (acmod_ != 0x01))
    100  RCHECK(frame.SkipBits(2)); // cmixlev.
    101  // If a surround channel exists.
    102  if (acmod_ & 0x04)
    103  RCHECK(frame.SkipBits(2)); // surmixlev.
    104  // If in 2/0 mode.
    105  if (acmod_ == 0x02)
    106  RCHECK(frame.SkipBits(2)); // dsurmod.
    107 
    108  RCHECK(frame.ReadBits(1, &lfeon_));
    109 
    110  return true;
    111 }
    112 
    113 size_t Ac3Header::GetHeaderSize() const {
    114  // Unlike ADTS, for AC3, the whole frame is included in the media sample, so
    115  // return 0 header size.
    116  return 0;
    117 }
    118 
    119 size_t Ac3Header::GetFrameSize() const {
    120  return CalcFrameSize(fscod_, frmsizecod_);
    121 }
    122 
    123 size_t Ac3Header::GetFrameSizeWithoutParsing(const uint8_t* data,
    124  size_t num_bytes) const {
    125  DCHECK_GT(num_bytes, static_cast<size_t>(4));
    126  uint8_t fscod = data[4] >> 6;
    127  uint8_t frmsizecod = data[4] & 0x3f;
    128  return CalcFrameSize(fscod, frmsizecod);
    129 }
    130 
    131 void Ac3Header::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
    132  DCHECK(buffer);
    133  buffer->clear();
    134  BitWriter config(buffer);
    135  // Accoding to ETSI TS 102 366 V1.3.1 (2014-08) F.4 AC3SpecificBox.
    136  config.WriteBits(fscod_, 2);
    137  config.WriteBits(bsid_, 5);
    138  config.WriteBits(bsmod_, 3);
    139  config.WriteBits(acmod_, 3);
    140  config.WriteBits(lfeon_, 1);
    141  const uint8_t bit_rate_code = frmsizecod_ >> 1;
    142  config.WriteBits(bit_rate_code, 5);
    143  config.Flush();
    144 }
    145 
    146 uint8_t Ac3Header::GetObjectType() const {
    147  // Only useful for AAC. Return a dummy value instead.
    148  return 0;
    149 }
    150 
    152  DCHECK_LT(fscod_, arraysize(kAc3SampleRateTable));
    153  return kAc3SampleRateTable[fscod_];
    154 }
    155 
    156 uint8_t Ac3Header::GetNumChannels() const {
    157  DCHECK_LT(acmod_, arraysize(kAc3NumChannelsTable));
    158  return kAc3NumChannelsTable[acmod_] + (lfeon_ ? 1 : 0);
    159 }
    160 
    161 } // namespace mp2t
    162 } // namespace media
    163 } // namespace shaka
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    -
    size_t GetHeaderSize() const override
    Definition: ac3_header.cc:113
    -
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    Definition: ac3_header.cc:123
    -
    A class to read bit streams.
    Definition: bit_reader.h:17
    -
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: ac3_header.cc:58
    -
    All the methods that are virtual are virtual for mocking.
    - -
    size_t GetMinFrameSize() const override
    Definition: ac3_header.cc:64
    -
    uint32_t GetSamplingFrequency() const override
    Definition: ac3_header.cc:151
    -
    size_t GetFrameSize() const override
    Definition: ac3_header.cc:119
    -
    bool SkipBits(size_t num_bits)
    Definition: bit_reader.cc:24
    -
    uint8_t GetObjectType() const override
    Definition: ac3_header.cc:146
    -
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: ac3_header.cc:77
    -
    void WriteBits(uint32_t bits, size_t number_of_bits)
    Definition: bit_writer.cc:15
    -
    size_t GetSamplesPerFrame() const override
    Definition: ac3_header.cc:70
    -
    uint8_t GetNumChannels() const override
    Definition: ac3_header.cc:156
    -
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: ac3_header.cc:131
    -
    void Flush()
    Write pending bits, and align bitstream with extra zero bits.
    Definition: bit_writer.cc:31
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/ac3_header.h"
    +
    8 
    +
    9 #include "packager/media/base/bit_reader.h"
    +
    10 #include "packager/media/base/bit_writer.h"
    +
    11 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace mp2t {
    +
    16 namespace {
    +
    17 
    +
    18 // ASTC Standard A/52:2012 Table 5.6 Sample Rate Codes.
    +
    19 const uint32_t kAc3SampleRateTable[] = {48000, 44100, 32000};
    +
    20 
    +
    21 // ASTC Standard A/52:2012 Table 5.8 Audio Coding Mode.
    +
    22 const uint8_t kAc3NumChannelsTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
    +
    23 
    +
    24 // ATSC Standard A/52:2012 Table 5.18 Frame Size Code Table
    +
    25 // (in words = 16 bits).
    +
    26 const size_t kFrameSizeCodeTable[][3] = {
    +
    27  // {32kHz, 44.1kHz, 48kHz}
    +
    28  {96, 69, 64}, {96, 70, 64}, {120, 87, 80},
    +
    29  {120, 88, 80}, {144, 104, 96}, {144, 105, 96},
    +
    30  {168, 121, 112}, {168, 122, 112}, {192, 139, 128},
    +
    31  {192, 140, 128}, {240, 174, 160}, {240, 175, 160},
    +
    32  {288, 208, 192}, {288, 209, 192}, {336, 243, 224},
    +
    33  {336, 244, 224}, {384, 278, 256}, {384, 279, 256},
    +
    34  {480, 348, 320}, {480, 349, 320}, {576, 417, 384},
    +
    35  {576, 418, 384}, {672, 487, 448}, {672, 488, 448},
    +
    36  {768, 557, 512}, {768, 558, 512}, {960, 696, 640},
    +
    37  {960, 697, 640}, {1152, 835, 768}, {1152, 836, 768},
    +
    38  {1344, 975, 896}, {1344, 976, 896}, {1536, 1114, 1024},
    +
    39  {1536, 1115, 1024}, {1728, 1253, 1152}, {1728, 1254, 1152},
    +
    40  {1920, 1393, 1280}, {1920, 1394, 1280},
    +
    41 };
    +
    42 
    +
    43 // Calculate the size of the frame from the sample rate code and the
    +
    44 // frame size code.
    +
    45 // @return the size of the frame (header + payload).
    +
    46 size_t CalcFrameSize(uint8_t fscod, uint8_t frmsizecod) {
    +
    47  const size_t kNumFscode = arraysize(kAc3SampleRateTable);
    +
    48  DCHECK_LT(fscod, kNumFscode);
    +
    49  DCHECK_LT(frmsizecod, arraysize(kFrameSizeCodeTable));
    +
    50  // The order of frequencies are reversed in |kFrameSizeCodeTable| compared to
    +
    51  // |kAc3SampleRateTable|.
    +
    52  const int index = kNumFscode - 1 - fscod;
    +
    53  return kFrameSizeCodeTable[frmsizecod][index] * 2;
    +
    54 }
    +
    55 
    +
    56 } // namespace
    +
    57 
    +
    58 bool Ac3Header::IsSyncWord(const uint8_t* buf) const {
    +
    59  DCHECK(buf);
    +
    60  // ATSC Standard A/52:2012 5.4.1 syncinfo: Synchronization Information.
    +
    61  return buf[0] == 0x0B && buf[1] == 0x77;
    +
    62 }
    +
    63 
    + +
    65  // Arbitrary. Actual frame size starts with 96 words.
    +
    66  const size_t kMinAc3FrameSize = 10u;
    +
    67  return kMinAc3FrameSize;
    +
    68 }
    +
    69 
    + +
    71  // ATSC Standard A/52:2012
    +
    72  // Annex A: AC-3 Elementary Streams in the MPEG-2 Multiplex.
    +
    73  const size_t kSamplesPerAc3Frame = 1536;
    +
    74  return kSamplesPerAc3Frame;
    +
    75 }
    +
    76 
    +
    77 bool Ac3Header::Parse(const uint8_t* audio_frame, size_t audio_frame_size) {
    +
    78  BitReader frame(audio_frame, audio_frame_size);
    +
    79 
    +
    80  // ASTC Standard A/52:2012 5. BIT STREAM SYNTAX.
    +
    81  // syncinfo: synchronization information section.
    +
    82  uint16_t syncword;
    +
    83  RCHECK(frame.ReadBits(16, &syncword));
    +
    84  RCHECK(syncword == 0x0B77);
    +
    85  uint16_t crc1;
    +
    86  RCHECK(frame.ReadBits(16, &crc1));
    +
    87  RCHECK(frame.ReadBits(2, &fscod_));
    +
    88  RCHECK(fscod_ < arraysize(kAc3SampleRateTable));
    +
    89  RCHECK(frame.ReadBits(6, &frmsizecod_));
    +
    90  RCHECK(frmsizecod_ < arraysize(kFrameSizeCodeTable));
    +
    91 
    +
    92  // bsi: bit stream information section.
    +
    93  RCHECK(frame.ReadBits(5, &bsid_));
    +
    94  RCHECK(frame.ReadBits(3, &bsmod_));
    +
    95 
    +
    96  RCHECK(frame.ReadBits(3, &acmod_));
    +
    97  RCHECK(acmod_ < arraysize(kAc3NumChannelsTable));
    +
    98  // If 3 front channels.
    +
    99  if ((acmod_ & 0x01) && (acmod_ != 0x01))
    +
    100  RCHECK(frame.SkipBits(2)); // cmixlev.
    +
    101  // If a surround channel exists.
    +
    102  if (acmod_ & 0x04)
    +
    103  RCHECK(frame.SkipBits(2)); // surmixlev.
    +
    104  // If in 2/0 mode.
    +
    105  if (acmod_ == 0x02)
    +
    106  RCHECK(frame.SkipBits(2)); // dsurmod.
    +
    107 
    +
    108  RCHECK(frame.ReadBits(1, &lfeon_));
    +
    109 
    +
    110  return true;
    +
    111 }
    +
    112 
    +
    113 size_t Ac3Header::GetHeaderSize() const {
    +
    114  // Unlike ADTS, for AC3, the whole frame is included in the media sample, so
    +
    115  // return 0 header size.
    +
    116  return 0;
    +
    117 }
    +
    118 
    +
    119 size_t Ac3Header::GetFrameSize() const {
    +
    120  return CalcFrameSize(fscod_, frmsizecod_);
    +
    121 }
    +
    122 
    +
    123 size_t Ac3Header::GetFrameSizeWithoutParsing(const uint8_t* data,
    +
    124  size_t num_bytes) const {
    +
    125  DCHECK_GT(num_bytes, static_cast<size_t>(4));
    +
    126  uint8_t fscod = data[4] >> 6;
    +
    127  uint8_t frmsizecod = data[4] & 0x3f;
    +
    128  return CalcFrameSize(fscod, frmsizecod);
    +
    129 }
    +
    130 
    +
    131 void Ac3Header::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
    +
    132  DCHECK(buffer);
    +
    133  buffer->clear();
    +
    134  BitWriter config(buffer);
    +
    135  // Accoding to ETSI TS 102 366 V1.3.1 (2014-08) F.4 AC3SpecificBox.
    +
    136  config.WriteBits(fscod_, 2);
    +
    137  config.WriteBits(bsid_, 5);
    +
    138  config.WriteBits(bsmod_, 3);
    +
    139  config.WriteBits(acmod_, 3);
    +
    140  config.WriteBits(lfeon_, 1);
    +
    141  const uint8_t bit_rate_code = frmsizecod_ >> 1;
    +
    142  config.WriteBits(bit_rate_code, 5);
    +
    143  config.Flush();
    +
    144 }
    +
    145 
    +
    146 uint8_t Ac3Header::GetObjectType() const {
    +
    147  // Only useful for AAC. Return a dummy value instead.
    +
    148  return 0;
    +
    149 }
    +
    150 
    + +
    152  DCHECK_LT(fscod_, arraysize(kAc3SampleRateTable));
    +
    153  return kAc3SampleRateTable[fscod_];
    +
    154 }
    +
    155 
    +
    156 uint8_t Ac3Header::GetNumChannels() const {
    +
    157  DCHECK_LT(acmod_, arraysize(kAc3NumChannelsTable));
    +
    158  return kAc3NumChannelsTable[acmod_] + (lfeon_ ? 1 : 0);
    +
    159 }
    +
    160 
    +
    161 } // namespace mp2t
    +
    162 } // namespace media
    +
    163 } // namespace shaka
    +
    A class to read bit streams.
    Definition: bit_reader.h:17
    +
    bool SkipBits(size_t num_bits)
    Definition: bit_reader.cc:24
    +
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    + +
    void Flush()
    Write pending bits, and align bitstream with extra zero bits.
    Definition: bit_writer.cc:31
    +
    void WriteBits(uint32_t bits, size_t number_of_bits)
    Definition: bit_writer.cc:15
    +
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: ac3_header.cc:77
    +
    size_t GetMinFrameSize() const override
    Definition: ac3_header.cc:64
    +
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: ac3_header.cc:58
    +
    uint8_t GetObjectType() const override
    Definition: ac3_header.cc:146
    +
    size_t GetHeaderSize() const override
    Definition: ac3_header.cc:113
    +
    size_t GetFrameSize() const override
    Definition: ac3_header.cc:119
    +
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    Definition: ac3_header.cc:123
    +
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: ac3_header.cc:131
    +
    uint32_t GetSamplingFrequency() const override
    Definition: ac3_header.cc:151
    +
    uint8_t GetNumChannels() const override
    Definition: ac3_header.cc:156
    +
    size_t GetSamplesPerFrame() const override
    Definition: ac3_header.cc:70
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/de0/structshaka_1_1media_1_1Range.html b/docs/d9/de0/structshaka_1_1media_1_1Range.html index 0a4c8fb90f..713780974c 100644 --- a/docs/d9/de0/structshaka_1_1media_1_1Range.html +++ b/docs/d9/de0/structshaka_1_1media_1_1Range.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::Range Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    end
    diff --git a/docs/d9/de2/mock__media__playlist_8cc_source.html b/docs/d9/de2/mock__media__playlist_8cc_source.html index 1b7c92b72f..0183ec521b 100644 --- a/docs/d9/de2/mock__media__playlist_8cc_source.html +++ b/docs/d9/de2/mock__media__playlist_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/mock_media_playlist.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    mock_media_playlist.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/hls/base/mock_media_playlist.h"
    8 
    9 #include "packager/hls/public/hls_params.h"
    10 
    11 namespace shaka {
    12 namespace hls {
    13 
    14 MockMediaPlaylist::MockMediaPlaylist(const std::string& file_name,
    15  const std::string& name,
    16  const std::string& group_id)
    17  : MediaPlaylist(HlsParams(), file_name, name, group_id) {}
    18 MockMediaPlaylist::~MockMediaPlaylist() {}
    19 
    20 } // namespace hls
    21 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/hls/base/mock_media_playlist.h"
    +
    8 
    +
    9 #include "packager/hls/public/hls_params.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 namespace hls {
    +
    13 
    +
    14 MockMediaPlaylist::MockMediaPlaylist(const std::string& file_name,
    +
    15  const std::string& name,
    +
    16  const std::string& group_id)
    +
    17  : MediaPlaylist(HlsParams(), file_name, name, group_id) {}
    +
    18 MockMediaPlaylist::~MockMediaPlaylist() {}
    +
    19 
    +
    20 } // namespace hls
    +
    21 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/de3/muxer__listener__internal_8cc_source.html b/docs/d9/de3/muxer__listener__internal_8cc_source.html index e62d9c39a2..6c25616711 100644 --- a/docs/d9/de3/muxer__listener__internal_8cc_source.html +++ b/docs/d9/de3/muxer__listener__internal_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/muxer_listener_internal.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    muxer_listener_internal.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/event/muxer_listener_internal.h"
    8 
    9 #include <google/protobuf/util/message_differencer.h>
    10 #include <math.h>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/base/strings/string_util.h"
    15 #include "packager/media/base/audio_stream_info.h"
    16 #include "packager/media/base/muxer_options.h"
    17 #include "packager/media/base/protection_system_specific_info.h"
    18 #include "packager/media/base/text_stream_info.h"
    19 #include "packager/media/base/video_stream_info.h"
    20 #include "packager/media/codecs/ec3_audio_util.h"
    21 #include "packager/mpd/base/media_info.pb.h"
    22 
    23 using ::google::protobuf::util::MessageDifferencer;
    24 
    25 namespace shaka {
    26 namespace media {
    27 namespace internal {
    28 
    29 namespace {
    30 
    31 // TODO(rkuroiwa): There is shaka::Range in MediaInfo proto and
    32 // shaka::media::Range in media/base. Find better names.
    33 void SetRange(uint64_t begin, uint64_t end, shaka::Range* range) {
    34  DCHECK(range);
    35  range->set_begin(begin);
    36  range->set_end(end);
    37 }
    38 
    39 void SetMediaInfoContainerType(MuxerListener::ContainerType container_type,
    40  MediaInfo* media_info) {
    41  DCHECK(media_info);
    42  switch (container_type) {
    43  case MuxerListener::kContainerUnknown:
    44  media_info->set_container_type(MediaInfo::CONTAINER_UNKNOWN);
    45  break;
    46  case MuxerListener::kContainerMp4:
    47  media_info->set_container_type(MediaInfo::CONTAINER_MP4);
    48  break;
    49  case MuxerListener::kContainerMpeg2ts:
    50  media_info->set_container_type(MediaInfo::CONTAINER_MPEG2_TS);
    51  break;
    52  case MuxerListener::kContainerPackedAudio:
    53  media_info->set_container_type(MediaInfo::CONTAINER_PACKED_AUDIO);
    54  break;
    55  case MuxerListener::kContainerWebM:
    56  media_info->set_container_type(MediaInfo::CONTAINER_WEBM);
    57  break;
    58  case MuxerListener::kContainerText:
    59  media_info->set_container_type(MediaInfo::CONTAINER_TEXT);
    60  break;
    61  default:
    62  NOTREACHED() << "Unknown container type " << container_type;
    63  }
    64 }
    65 
    66 void AddVideoInfo(const VideoStreamInfo* video_stream_info,
    67  MediaInfo* media_info) {
    68  DCHECK(video_stream_info);
    69  DCHECK(media_info);
    70  MediaInfo_VideoInfo* video_info = media_info->mutable_video_info();
    71  video_info->set_codec(video_stream_info->codec_string());
    72  video_info->set_width(video_stream_info->width());
    73  video_info->set_height(video_stream_info->height());
    74  video_info->set_time_scale(video_stream_info->time_scale());
    75 
    76  if (video_stream_info->pixel_width() > 0)
    77  video_info->set_pixel_width(video_stream_info->pixel_width());
    78 
    79  if (video_stream_info->pixel_height() > 0)
    80  video_info->set_pixel_height(video_stream_info->pixel_height());
    81 
    82  const std::vector<uint8_t>& codec_config = video_stream_info->codec_config();
    83  if (!codec_config.empty()) {
    84  video_info->set_decoder_config(&codec_config[0], codec_config.size());
    85  }
    86 
    87  if (video_stream_info->playback_rate() > 0) {
    88  video_info->set_playback_rate(video_stream_info->playback_rate());
    89  }
    90  if (video_stream_info->transfer_characteristics() > 0) {
    91  video_info->set_transfer_characteristics(
    92  video_stream_info->transfer_characteristics());
    93  }
    94 }
    95 
    96 void AddAudioInfo(const AudioStreamInfo* audio_stream_info,
    97  MediaInfo* media_info) {
    98  DCHECK(audio_stream_info);
    99  DCHECK(media_info);
    100  MediaInfo_AudioInfo* audio_info = media_info->mutable_audio_info();
    101  audio_info->set_codec(audio_stream_info->codec_string());
    102  audio_info->set_sampling_frequency(audio_stream_info->sampling_frequency());
    103  audio_info->set_time_scale(audio_stream_info->time_scale());
    104  audio_info->set_num_channels(audio_stream_info->num_channels());
    105 
    106  const std::string& language = audio_stream_info->language();
    107  // ISO-639-2/T defines language "und" which we also want to ignore.
    108  if (!language.empty() && language != "und") {
    109  audio_info->set_language(language);
    110  }
    111 
    112  const std::vector<uint8_t>& codec_config = audio_stream_info->codec_config();
    113  if (!codec_config.empty()) {
    114  audio_info->set_decoder_config(&codec_config[0], codec_config.size());
    115  }
    116 
    117  if (audio_stream_info->codec_string() == "ec-3") {
    118  uint32_t ec3_channel_map;
    119  if (!CalculateEC3ChannelMap(codec_config, &ec3_channel_map)) {
    120  LOG(ERROR) << "Failed to calculate EC3 channel map.";
    121  return;
    122  }
    123  audio_info->mutable_codec_specific_data()->set_ec3_channel_map(
    124  ec3_channel_map);
    125  }
    126 }
    127 
    128 void AddTextInfo(const TextStreamInfo& text_stream_info,
    129  MediaInfo* media_info) {
    130  // For now, set everything as subtitle.
    131  MediaInfo::TextInfo* text_info = media_info->mutable_text_info();
    132  text_info->set_type(MediaInfo::TextInfo::SUBTITLE);
    133  text_info->set_codec(text_stream_info.codec_string());
    134  text_info->set_language(text_stream_info.language());
    135 }
    136 
    137 void SetMediaInfoStreamInfo(const StreamInfo& stream_info,
    138  MediaInfo* media_info) {
    139  if (stream_info.stream_type() == kStreamAudio) {
    140  AddAudioInfo(static_cast<const AudioStreamInfo*>(&stream_info), media_info);
    141  } else if (stream_info.stream_type() == kStreamText) {
    142  AddTextInfo(static_cast<const TextStreamInfo&>(stream_info), media_info);
    143  } else {
    144  DCHECK_EQ(stream_info.stream_type(), kStreamVideo);
    145  AddVideoInfo(static_cast<const VideoStreamInfo*>(&stream_info), media_info);
    146  }
    147  if (stream_info.duration() > 0) {
    148  // |stream_info.duration()| contains the media duration from the original
    149  // media header, which is usually good enough.
    150  media_info->set_media_duration_seconds(
    151  static_cast<double>(stream_info.duration()) / stream_info.time_scale());
    152  }
    153 }
    154 
    155 void SetMediaInfoMuxerOptions(const MuxerOptions& muxer_options,
    156  MediaInfo* media_info) {
    157  DCHECK(media_info);
    158  if (muxer_options.segment_template.empty()) {
    159  media_info->set_media_file_name(muxer_options.output_file_name);
    160  } else {
    161  if (!muxer_options.output_file_name.empty())
    162  media_info->set_init_segment_name(muxer_options.output_file_name);
    163  media_info->set_segment_template(muxer_options.segment_template);
    164  }
    165 }
    166 
    167 // Adjust MediaInfo for compatibility comparison. MediaInfos are considered to
    168 // be compatible if codec and container are the same.
    169 MediaInfo GetCompatibleComparisonMediaInfo(const MediaInfo& media_info) {
    170  MediaInfo adjusted_media_info;
    171  adjusted_media_info.set_reference_time_scale(
    172  media_info.reference_time_scale());
    173  adjusted_media_info.set_container_type(media_info.container_type());
    174  if (media_info.has_video_info()) {
    175  *adjusted_media_info.mutable_video_info() = media_info.video_info();
    176  adjusted_media_info.mutable_video_info()->clear_frame_duration();
    177  }
    178  if (media_info.has_audio_info()) {
    179  *adjusted_media_info.mutable_audio_info() = media_info.audio_info();
    180  }
    181  if (media_info.has_text_info()) {
    182  *adjusted_media_info.mutable_text_info() = media_info.text_info();
    183  }
    184  return adjusted_media_info;
    185 }
    186 
    187 } // namespace
    188 
    189 bool GenerateMediaInfo(const MuxerOptions& muxer_options,
    190  const StreamInfo& stream_info,
    191  uint32_t reference_time_scale,
    192  MuxerListener::ContainerType container_type,
    193  MediaInfo* media_info) {
    194  DCHECK(media_info);
    195 
    196  SetMediaInfoMuxerOptions(muxer_options, media_info);
    197  SetMediaInfoStreamInfo(stream_info, media_info);
    198  media_info->set_reference_time_scale(reference_time_scale);
    199  SetMediaInfoContainerType(container_type, media_info);
    200  if (muxer_options.bandwidth > 0)
    201  media_info->set_bandwidth(muxer_options.bandwidth);
    202 
    203  return true;
    204 }
    205 
    206 bool IsMediaInfoCompatible(const MediaInfo& media_info1,
    207  const MediaInfo& media_info2) {
    208  return MessageDifferencer::Equals(
    209  GetCompatibleComparisonMediaInfo(media_info1),
    210  GetCompatibleComparisonMediaInfo(media_info2));
    211 }
    212 
    213 bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges,
    214  float duration_seconds,
    215  MediaInfo* media_info) {
    216  DCHECK(media_info);
    217 
    218  if (duration_seconds <= 0.0f) {
    219  // Non positive second media must be invalid media.
    220  LOG(ERROR) << "Duration is not positive: " << duration_seconds;
    221  return false;
    222  }
    223 
    224  if (media_ranges.init_range) {
    225  SetRange(media_ranges.init_range->start, media_ranges.init_range->end,
    226  media_info->mutable_init_range());
    227  }
    228 
    229  if (media_ranges.index_range) {
    230  SetRange(media_ranges.index_range->start, media_ranges.index_range->end,
    231  media_info->mutable_index_range());
    232  }
    233 
    234  media_info->set_media_duration_seconds(duration_seconds);
    235 
    236  return true;
    237 }
    238 
    239 void SetContentProtectionFields(
    240  FourCC protection_scheme,
    241  const std::vector<uint8_t>& default_key_id,
    242  const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
    243  MediaInfo* media_info) {
    244  DCHECK(media_info);
    245  MediaInfo::ProtectedContent* protected_content =
    246  media_info->mutable_protected_content();
    247  protected_content->set_protection_scheme(FourCCToString(protection_scheme));
    248 
    249  if (!default_key_id.empty()) {
    250  protected_content->set_default_key_id(default_key_id.data(),
    251  default_key_id.size());
    252  }
    253 
    254  for (const ProtectionSystemSpecificInfo& info : key_system_info) {
    255  MediaInfo::ProtectedContent::ContentProtectionEntry* entry =
    256  protected_content->add_content_protection_entry();
    257  entry->set_uuid(CreateUUIDString(info.system_id));
    258 
    259  const std::vector<uint8_t>& pssh = info.psshs;
    260  entry->set_pssh(pssh.data(), pssh.size());
    261  }
    262 }
    263 
    264 std::string CreateUUIDString(const std::vector<uint8_t>& data) {
    265  DCHECK_EQ(16u, data.size());
    266  std::string uuid =
    267  base::ToLowerASCII(base::HexEncode(data.data(), data.size()));
    268  uuid.insert(20, "-");
    269  uuid.insert(16, "-");
    270  uuid.insert(12, "-");
    271  uuid.insert(8, "-");
    272  return uuid;
    273 }
    274 
    275 } // namespace internal
    276 } // namespace media
    277 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/event/muxer_listener_internal.h"
    +
    8 
    +
    9 #include <google/protobuf/util/message_differencer.h>
    +
    10 #include <math.h>
    +
    11 
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/base/strings/string_number_conversions.h"
    +
    14 #include "packager/base/strings/string_util.h"
    +
    15 #include "packager/media/base/audio_stream_info.h"
    +
    16 #include "packager/media/base/muxer_options.h"
    +
    17 #include "packager/media/base/protection_system_specific_info.h"
    +
    18 #include "packager/media/base/text_stream_info.h"
    +
    19 #include "packager/media/base/video_stream_info.h"
    +
    20 #include "packager/media/codecs/ec3_audio_util.h"
    +
    21 #include "packager/media/codecs/ac4_audio_util.h"
    +
    22 #include "packager/mpd/base/media_info.pb.h"
    +
    23 
    +
    24 using ::google::protobuf::util::MessageDifferencer;
    +
    25 
    +
    26 namespace shaka {
    +
    27 namespace media {
    +
    28 namespace internal {
    +
    29 
    +
    30 namespace {
    +
    31 
    +
    32 // TODO(rkuroiwa): There is shaka::Range in MediaInfo proto and
    +
    33 // shaka::media::Range in media/base. Find better names.
    +
    34 void SetRange(uint64_t begin, uint64_t end, shaka::Range* range) {
    +
    35  DCHECK(range);
    +
    36  range->set_begin(begin);
    +
    37  range->set_end(end);
    +
    38 }
    +
    39 
    +
    40 void SetMediaInfoContainerType(MuxerListener::ContainerType container_type,
    +
    41  MediaInfo* media_info) {
    +
    42  DCHECK(media_info);
    +
    43  switch (container_type) {
    +
    44  case MuxerListener::kContainerUnknown:
    +
    45  media_info->set_container_type(MediaInfo::CONTAINER_UNKNOWN);
    +
    46  break;
    +
    47  case MuxerListener::kContainerMp4:
    +
    48  media_info->set_container_type(MediaInfo::CONTAINER_MP4);
    +
    49  break;
    +
    50  case MuxerListener::kContainerMpeg2ts:
    +
    51  media_info->set_container_type(MediaInfo::CONTAINER_MPEG2_TS);
    +
    52  break;
    +
    53  case MuxerListener::kContainerPackedAudio:
    +
    54  media_info->set_container_type(MediaInfo::CONTAINER_PACKED_AUDIO);
    +
    55  break;
    +
    56  case MuxerListener::kContainerWebM:
    +
    57  media_info->set_container_type(MediaInfo::CONTAINER_WEBM);
    +
    58  break;
    +
    59  case MuxerListener::kContainerText:
    +
    60  media_info->set_container_type(MediaInfo::CONTAINER_TEXT);
    +
    61  break;
    +
    62  default:
    +
    63  NOTREACHED() << "Unknown container type " << container_type;
    +
    64  }
    +
    65 }
    +
    66 
    +
    67 void AddVideoInfo(const VideoStreamInfo* video_stream_info,
    +
    68  MediaInfo* media_info) {
    +
    69  DCHECK(video_stream_info);
    +
    70  DCHECK(media_info);
    +
    71  MediaInfo_VideoInfo* video_info = media_info->mutable_video_info();
    +
    72  video_info->set_codec(video_stream_info->codec_string());
    +
    73  video_info->set_width(video_stream_info->width());
    +
    74  video_info->set_height(video_stream_info->height());
    +
    75  video_info->set_time_scale(video_stream_info->time_scale());
    +
    76 
    +
    77  if (video_stream_info->pixel_width() > 0)
    +
    78  video_info->set_pixel_width(video_stream_info->pixel_width());
    +
    79 
    +
    80  if (video_stream_info->pixel_height() > 0)
    +
    81  video_info->set_pixel_height(video_stream_info->pixel_height());
    +
    82 
    +
    83  const std::vector<uint8_t>& codec_config = video_stream_info->codec_config();
    +
    84  if (!codec_config.empty()) {
    +
    85  video_info->set_decoder_config(&codec_config[0], codec_config.size());
    +
    86  }
    +
    87 
    +
    88  if (video_stream_info->playback_rate() > 0) {
    +
    89  video_info->set_playback_rate(video_stream_info->playback_rate());
    +
    90  }
    +
    91  if (video_stream_info->transfer_characteristics() > 0) {
    +
    92  video_info->set_transfer_characteristics(
    +
    93  video_stream_info->transfer_characteristics());
    +
    94  }
    +
    95 }
    +
    96 
    +
    97 void AddAudioInfo(const AudioStreamInfo* audio_stream_info,
    +
    98  MediaInfo* media_info) {
    +
    99  DCHECK(audio_stream_info);
    +
    100  DCHECK(media_info);
    +
    101  MediaInfo_AudioInfo* audio_info = media_info->mutable_audio_info();
    +
    102  audio_info->set_codec(audio_stream_info->codec_string());
    +
    103  audio_info->set_sampling_frequency(audio_stream_info->sampling_frequency());
    +
    104  audio_info->set_time_scale(audio_stream_info->time_scale());
    +
    105  audio_info->set_num_channels(audio_stream_info->num_channels());
    +
    106 
    +
    107  const std::string& language = audio_stream_info->language();
    +
    108  // ISO-639-2/T defines language "und" which we also want to ignore.
    +
    109  if (!language.empty() && language != "und") {
    +
    110  audio_info->set_language(language);
    +
    111  }
    +
    112 
    +
    113  const std::vector<uint8_t>& codec_config = audio_stream_info->codec_config();
    +
    114  if (!codec_config.empty()) {
    +
    115  audio_info->set_decoder_config(&codec_config[0], codec_config.size());
    +
    116  }
    +
    117 
    +
    118  if (audio_stream_info->codec_string() == "ec-3") {
    +
    119  uint32_t ec3_channel_map;
    +
    120  if (!CalculateEC3ChannelMap(codec_config, &ec3_channel_map)) {
    +
    121  LOG(ERROR) << "Failed to calculate EC3 channel map.";
    +
    122  return;
    +
    123  }
    +
    124  auto* codec_data = audio_info->mutable_codec_specific_data();
    +
    125  codec_data->set_channel_mask(ec3_channel_map);
    +
    126  uint32_t ec3_channel_mpeg_value;
    +
    127  if (!CalculateEC3ChannelMPEGValue(codec_config, &ec3_channel_mpeg_value)) {
    +
    128  LOG(ERROR) << "Failed to calculate EC3 channel configuration "
    +
    129  << "descriptor value with MPEG scheme.";
    +
    130  return;
    +
    131  }
    +
    132  codec_data->set_channel_mpeg_value(ec3_channel_mpeg_value);
    +
    133  uint32_t ec3_joc_complexity = 0;
    +
    134  if (!GetEc3JocComplexity(codec_config, &ec3_joc_complexity)) {
    +
    135  LOG(ERROR) << "Failed to obtain DD+JOC Information.";
    +
    136  return;
    +
    137  }
    +
    138  codec_data->set_ec3_joc_complexity(ec3_joc_complexity);
    +
    139  }
    +
    140 
    +
    141  if (audio_stream_info->codec() == kCodecAC4) {
    +
    142  uint32_t ac4_channel_mask;
    +
    143  if (!CalculateAC4ChannelMask(codec_config, &ac4_channel_mask)) {
    +
    144  LOG(ERROR) << "Failed to calculate AC4 channel mask.";
    +
    145  return;
    +
    146  }
    +
    147  auto* codec_data = audio_info->mutable_codec_specific_data();
    +
    148  codec_data->set_channel_mask(ac4_channel_mask);
    +
    149  uint32_t ac4_channel_mpeg_value;
    +
    150  if (!CalculateAC4ChannelMPEGValue(codec_config, &ac4_channel_mpeg_value)) {
    +
    151  LOG(ERROR) << "Failed to calculate AC4 channel configuration "
    +
    152  << "descriptor value with MPEG scheme.";
    +
    153  return;
    +
    154  }
    +
    155  codec_data->set_channel_mpeg_value(ac4_channel_mpeg_value);
    +
    156  bool ac4_ims_flag;
    +
    157  bool ac4_cbi_flag;
    +
    158  if (!GetAc4ImmersiveInfo(codec_config, &ac4_ims_flag, &ac4_cbi_flag)) {
    +
    159  LOG(ERROR) << "Failed to obtain AC4 IMS flag and CBI flag.";
    +
    160  return;
    +
    161  }
    +
    162  codec_data->set_ac4_ims_flag(ac4_ims_flag);
    +
    163  codec_data->set_ac4_cbi_flag(ac4_cbi_flag);
    +
    164  }
    +
    165 }
    +
    166 
    +
    167 void AddTextInfo(const TextStreamInfo& text_stream_info,
    +
    168  MediaInfo* media_info) {
    +
    169  // TODO(modmaker): Set kind.
    +
    170  MediaInfo::TextInfo* text_info = media_info->mutable_text_info();
    +
    171  text_info->set_codec(text_stream_info.codec_string());
    +
    172  text_info->set_language(text_stream_info.language());
    +
    173 }
    +
    174 
    +
    175 void SetMediaInfoStreamInfo(const StreamInfo& stream_info,
    +
    176  MediaInfo* media_info) {
    +
    177  if (stream_info.stream_type() == kStreamAudio) {
    +
    178  AddAudioInfo(static_cast<const AudioStreamInfo*>(&stream_info), media_info);
    +
    179  } else if (stream_info.stream_type() == kStreamText) {
    +
    180  AddTextInfo(static_cast<const TextStreamInfo&>(stream_info), media_info);
    +
    181  } else {
    +
    182  DCHECK_EQ(stream_info.stream_type(), kStreamVideo);
    +
    183  AddVideoInfo(static_cast<const VideoStreamInfo*>(&stream_info), media_info);
    +
    184  }
    +
    185  if (stream_info.duration() > 0) {
    +
    186  // |stream_info.duration()| contains the media duration from the original
    +
    187  // media header, which is usually good enough.
    +
    188  media_info->set_media_duration_seconds(
    +
    189  static_cast<double>(stream_info.duration()) / stream_info.time_scale());
    +
    190  }
    +
    191 }
    +
    192 
    +
    193 void SetMediaInfoMuxerOptions(const MuxerOptions& muxer_options,
    +
    194  MediaInfo* media_info) {
    +
    195  DCHECK(media_info);
    +
    196  if (muxer_options.segment_template.empty()) {
    +
    197  media_info->set_media_file_name(muxer_options.output_file_name);
    +
    198  } else {
    +
    199  if (!muxer_options.output_file_name.empty())
    +
    200  media_info->set_init_segment_name(muxer_options.output_file_name);
    +
    201  media_info->set_segment_template(muxer_options.segment_template);
    +
    202  }
    +
    203 }
    +
    204 
    +
    205 // Adjust MediaInfo for compatibility comparison. MediaInfos are considered to
    +
    206 // be compatible if codec and container are the same.
    +
    207 MediaInfo GetCompatibleComparisonMediaInfo(const MediaInfo& media_info) {
    +
    208  MediaInfo adjusted_media_info;
    +
    209  adjusted_media_info.set_reference_time_scale(
    +
    210  media_info.reference_time_scale());
    +
    211  adjusted_media_info.set_container_type(media_info.container_type());
    +
    212  if (media_info.has_video_info()) {
    +
    213  *adjusted_media_info.mutable_video_info() = media_info.video_info();
    +
    214  adjusted_media_info.mutable_video_info()->clear_frame_duration();
    +
    215  }
    +
    216  if (media_info.has_audio_info()) {
    +
    217  *adjusted_media_info.mutable_audio_info() = media_info.audio_info();
    +
    218  }
    +
    219  if (media_info.has_text_info()) {
    +
    220  *adjusted_media_info.mutable_text_info() = media_info.text_info();
    +
    221  }
    +
    222  return adjusted_media_info;
    +
    223 }
    +
    224 
    +
    225 } // namespace
    +
    226 
    +
    227 bool GenerateMediaInfo(const MuxerOptions& muxer_options,
    +
    228  const StreamInfo& stream_info,
    +
    229  uint32_t reference_time_scale,
    +
    230  MuxerListener::ContainerType container_type,
    +
    231  MediaInfo* media_info) {
    +
    232  DCHECK(media_info);
    +
    233 
    +
    234  SetMediaInfoMuxerOptions(muxer_options, media_info);
    +
    235  SetMediaInfoStreamInfo(stream_info, media_info);
    +
    236  SetMediaInfoContainerType(container_type, media_info);
    +
    237  if (reference_time_scale > 0)
    +
    238  media_info->set_reference_time_scale(reference_time_scale);
    +
    239  if (muxer_options.bandwidth > 0)
    +
    240  media_info->set_bandwidth(muxer_options.bandwidth);
    +
    241 
    +
    242  return true;
    +
    243 }
    +
    244 
    +
    245 bool IsMediaInfoCompatible(const MediaInfo& media_info1,
    +
    246  const MediaInfo& media_info2) {
    +
    247  return MessageDifferencer::Equals(
    +
    248  GetCompatibleComparisonMediaInfo(media_info1),
    +
    249  GetCompatibleComparisonMediaInfo(media_info2));
    +
    250 }
    +
    251 
    +
    252 bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges,
    +
    253  float duration_seconds,
    +
    254  MediaInfo* media_info) {
    +
    255  DCHECK(media_info);
    +
    256 
    +
    257  if (duration_seconds <= 0.0f) {
    +
    258  // Non positive second media must be invalid media.
    +
    259  LOG(ERROR) << "Duration is not positive: " << duration_seconds;
    +
    260  return false;
    +
    261  }
    +
    262 
    +
    263  if (media_ranges.init_range) {
    +
    264  SetRange(media_ranges.init_range->start, media_ranges.init_range->end,
    +
    265  media_info->mutable_init_range());
    +
    266  }
    +
    267 
    +
    268  if (media_ranges.index_range) {
    +
    269  SetRange(media_ranges.index_range->start, media_ranges.index_range->end,
    +
    270  media_info->mutable_index_range());
    +
    271  }
    +
    272 
    +
    273  media_info->set_media_duration_seconds(duration_seconds);
    +
    274 
    +
    275  return true;
    +
    276 }
    +
    277 
    +
    278 void SetContentProtectionFields(
    +
    279  FourCC protection_scheme,
    +
    280  const std::vector<uint8_t>& default_key_id,
    +
    281  const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
    +
    282  MediaInfo* media_info) {
    +
    283  DCHECK(media_info);
    +
    284  MediaInfo::ProtectedContent* protected_content =
    +
    285  media_info->mutable_protected_content();
    +
    286  protected_content->set_protection_scheme(FourCCToString(protection_scheme));
    +
    287 
    +
    288  if (!default_key_id.empty()) {
    +
    289  protected_content->set_default_key_id(default_key_id.data(),
    +
    290  default_key_id.size());
    +
    291  }
    +
    292 
    +
    293  for (const ProtectionSystemSpecificInfo& info : key_system_info) {
    +
    294  MediaInfo::ProtectedContent::ContentProtectionEntry* entry =
    +
    295  protected_content->add_content_protection_entry();
    +
    296  entry->set_uuid(CreateUUIDString(info.system_id));
    +
    297 
    +
    298  const std::vector<uint8_t>& pssh = info.psshs;
    +
    299  entry->set_pssh(pssh.data(), pssh.size());
    +
    300  }
    +
    301 }
    +
    302 
    +
    303 std::string CreateUUIDString(const std::vector<uint8_t>& data) {
    +
    304  DCHECK_EQ(16u, data.size());
    +
    305  std::string uuid =
    +
    306  base::ToLowerASCII(base::HexEncode(data.data(), data.size()));
    +
    307  uuid.insert(20, "-");
    +
    308  uuid.insert(16, "-");
    +
    309  uuid.insert(12, "-");
    +
    310  uuid.insert(8, "-");
    +
    311  return uuid;
    +
    312 }
    +
    313 
    +
    314 } // namespace internal
    +
    315 } // namespace media
    +
    316 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/deb/classshaka_1_1hls_1_1HlsNotifier.html b/docs/d9/deb/classshaka_1_1hls_1_1HlsNotifier.html index 07adc1e296..18dcd1ade4 100644 --- a/docs/d9/deb/classshaka_1_1hls_1_1HlsNotifier.html +++ b/docs/d9/deb/classshaka_1_1hls_1_1HlsNotifier.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::hls::HlsNotifier Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::hls::SimpleHlsNotifier - -
    +shaka::hls::SimpleHlsNotifier + + @@ -554,9 +557,7 @@ Public Member Functions diff --git a/docs/d9/ded/aac__audio__specific__config_8cc_source.html b/docs/d9/ded/aac__audio__specific__config_8cc_source.html index 375b249698..3b9b1067f2 100644 --- a/docs/d9/ded/aac__audio__specific__config_8cc_source.html +++ b/docs/d9/ded/aac__audio__specific__config_8cc_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/codecs/aac_audio_specific_config.cc Source File @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    aac_audio_specific_config.cc
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/codecs/aac_audio_specific_config.h"
    6 
    7 #include <algorithm>
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/media/base/bit_reader.h"
    11 #include "packager/media/base/rcheck.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace {
    16 
    17 // Sampling Frequency Index table, from ISO 14496-3 Table 1.16
    18 static const uint32_t kSampleRates[] = {96000, 88200, 64000, 48000, 44100,
    19  32000, 24000, 22050, 16000, 12000,
    20  11025, 8000, 7350};
    21 
    22 // Channel Configuration table, from ISO 14496-3 Table 1.17
    23 const uint8_t kChannelConfigs[] = {0, 1, 2, 3, 4, 5, 6, 8};
    24 
    25 // ISO 14496-3 Table 4.2 – Syntax of program_config_element()
    26 // program_config_element()
    27 // ...
    28 // element_is_cpe[i]; 1 bslbf
    29 // element_tag_select[i]; 4 uimsbf
    30 bool CountChannels(uint8_t num_elements,
    31  uint8_t* num_channels,
    32  BitReader* bit_reader) {
    33  for (uint8_t i = 0; i < num_elements; ++i) {
    34  bool is_pair = false;
    35  RCHECK(bit_reader->ReadBits(1, &is_pair));
    36  *num_channels += is_pair ? 2 : 1;
    37  RCHECK(bit_reader->SkipBits(4));
    38  }
    39  return true;
    40 }
    41 
    42 } // namespace
    43 
    44 AACAudioSpecificConfig::AACAudioSpecificConfig() {}
    45 
    46 AACAudioSpecificConfig::~AACAudioSpecificConfig() {}
    47 
    48 bool AACAudioSpecificConfig::Parse(const std::vector<uint8_t>& data) {
    49  if (data.empty())
    50  return false;
    51 
    52  BitReader reader(&data[0], data.size());
    53  uint8_t extension_type = AOT_NULL;
    54  uint8_t extension_frequency_index = 0xff;
    55 
    56  sbr_present_ = false;
    57  ps_present_ = false;
    58  frequency_ = 0;
    59  extension_frequency_ = 0;
    60 
    61  // The following code is written according to ISO 14496 Part 3 Table 1.13 -
    62  // Syntax of AudioSpecificConfig.
    63 
    64  // Read base configuration.
    65  // Audio Object Types specified in ISO 14496-3, Table 1.15.
    66  RCHECK(reader.ReadBits(5, &audio_object_type_));
    67  // Audio objects type >=31 is not supported yet.
    68  RCHECK(audio_object_type_ < 31);
    69  RCHECK(reader.ReadBits(4, &frequency_index_));
    70  if (frequency_index_ == 0xf)
    71  RCHECK(reader.ReadBits(24, &frequency_));
    72  RCHECK(reader.ReadBits(4, &channel_config_));
    73 
    74  RCHECK(channel_config_ < arraysize(kChannelConfigs));
    75  num_channels_ = kChannelConfigs[channel_config_];
    76 
    77  // Read extension configuration.
    78  if (audio_object_type_ == AOT_SBR || audio_object_type_ == AOT_PS) {
    79  sbr_present_ = audio_object_type_ == AOT_SBR;
    80  ps_present_ = audio_object_type_ == AOT_PS;
    81  extension_type = AOT_SBR;
    82  RCHECK(reader.ReadBits(4, &extension_frequency_index));
    83  if (extension_frequency_index == 0xf)
    84  RCHECK(reader.ReadBits(24, &extension_frequency_));
    85  RCHECK(reader.ReadBits(5, &audio_object_type_));
    86  // Audio objects type >=31 is not supported yet.
    87  RCHECK(audio_object_type_ < 31);
    88  }
    89 
    90  RCHECK(ParseDecoderGASpecificConfig(&reader));
    91  RCHECK(SkipErrorSpecificConfig());
    92 
    93  // Read extension configuration again
    94  // Note: The check for 16 available bits comes from the AAC spec.
    95  if (extension_type != AOT_SBR && reader.bits_available() >= 16) {
    96  uint16_t sync_extension_type;
    97  uint8_t sbr_present_flag;
    98  uint8_t ps_present_flag;
    99 
    100  if (reader.ReadBits(11, &sync_extension_type) &&
    101  sync_extension_type == 0x2b7) {
    102  if (reader.ReadBits(5, &extension_type) && extension_type == 5) {
    103  RCHECK(reader.ReadBits(1, &sbr_present_flag));
    104  sbr_present_ = sbr_present_flag != 0;
    105 
    106  if (sbr_present_flag) {
    107  RCHECK(reader.ReadBits(4, &extension_frequency_index));
    108 
    109  if (extension_frequency_index == 0xf)
    110  RCHECK(reader.ReadBits(24, &extension_frequency_));
    111 
    112  // Note: The check for 12 available bits comes from the AAC spec.
    113  if (reader.bits_available() >= 12) {
    114  RCHECK(reader.ReadBits(11, &sync_extension_type));
    115  if (sync_extension_type == 0x548) {
    116  RCHECK(reader.ReadBits(1, &ps_present_flag));
    117  ps_present_ = ps_present_flag != 0;
    118  }
    119  }
    120  }
    121  }
    122  }
    123  }
    124 
    125  if (frequency_ == 0) {
    126  RCHECK(frequency_index_ < arraysize(kSampleRates));
    127  frequency_ = kSampleRates[frequency_index_];
    128  }
    129 
    130  if (extension_frequency_ == 0 && extension_frequency_index != 0xff) {
    131  RCHECK(extension_frequency_index < arraysize(kSampleRates));
    132  extension_frequency_ = kSampleRates[extension_frequency_index];
    133  }
    134 
    135  return frequency_ != 0 && num_channels_ != 0 && audio_object_type_ >= 1 &&
    136  audio_object_type_ <= 4 && frequency_index_ != 0xf &&
    137  channel_config_ <= 7;
    138 }
    139 
    141  const uint8_t* data,
    142  size_t data_size,
    143  std::vector<uint8_t>* audio_frame) const {
    144  DCHECK(audio_object_type_ >= 1 && audio_object_type_ <= 4 &&
    145  frequency_index_ != 0xf && channel_config_ <= 7);
    146 
    147  size_t size = kADTSHeaderSize + data_size;
    148 
    149  // ADTS header uses 13 bits for packet size.
    150  if (size >= (1 << 13))
    151  return false;
    152 
    153  audio_frame->reserve(size);
    154  audio_frame->resize(kADTSHeaderSize);
    155 
    156  audio_frame->at(0) = 0xff;
    157  audio_frame->at(1) = 0xf1;
    158  audio_frame->at(2) = ((audio_object_type_ - 1) << 6) +
    159  (frequency_index_ << 2) + (channel_config_ >> 2);
    160  audio_frame->at(3) =
    161  ((channel_config_ & 0x3) << 6) + static_cast<uint8_t>(size >> 11);
    162  audio_frame->at(4) = static_cast<uint8_t>((size & 0x7ff) >> 3);
    163  audio_frame->at(5) = static_cast<uint8_t>(((size & 7) << 5) + 0x1f);
    164  audio_frame->at(6) = 0xfc;
    165 
    166  audio_frame->insert(audio_frame->end(), data, data + data_size);
    167 
    168  return true;
    169 }
    170 
    171 AACAudioSpecificConfig::AudioObjectType
    173  if (ps_present_)
    174  return AOT_PS;
    175  if (sbr_present_)
    176  return AOT_SBR;
    177  return audio_object_type_;
    178 }
    179 
    181  if (extension_frequency_ > 0)
    182  return extension_frequency_;
    183 
    184  if (!sbr_present_)
    185  return frequency_;
    186 
    187  // The following code is written according to ISO 14496 Part 3 Table 1.11 and
    188  // Table 1.22. (Table 1.11 refers to the capping to 48000, Table 1.22 refers
    189  // to SBR doubling the AAC sample rate.)
    190  DCHECK_GT(frequency_, 0u);
    191  return std::min(2 * frequency_, 48000u);
    192 }
    193 
    195  // Check for implicit signalling of HE-AAC and indicate stereo output
    196  // if the mono channel configuration is signalled.
    197  // See ISO-14496-3 Section 1.6.6.1.2 for details about this special casing.
    198  if (sbr_present_ && channel_config_ == 1)
    199  return 2; // CHANNEL_LAYOUT_STEREO
    200 
    201  // When Parametric Stereo is on, mono will be played as stereo.
    202  if (ps_present_ && channel_config_ == 1)
    203  return 2; // CHANNEL_LAYOUT_STEREO
    204 
    205  return num_channels_;
    206 }
    207 
    208 // Currently this function only support GASpecificConfig defined in
    209 // ISO 14496 Part 3 Table 4.1 - Syntax of GASpecificConfig()
    210 bool AACAudioSpecificConfig::ParseDecoderGASpecificConfig(
    211  BitReader* bit_reader) {
    212  switch (audio_object_type_) {
    213  case 1:
    214  case 2:
    215  case 3:
    216  case 4:
    217  case 6:
    218  case 7:
    219  case 17:
    220  case 19:
    221  case 20:
    222  case 21:
    223  case 22:
    224  case 23:
    225  return ParseGASpecificConfig(bit_reader);
    226  default:
    227  break;
    228  }
    229 
    230  return false;
    231 }
    232 
    233 bool AACAudioSpecificConfig::SkipErrorSpecificConfig() const {
    234  switch (audio_object_type_) {
    235  case 17:
    236  case 19:
    237  case 20:
    238  case 21:
    239  case 22:
    240  case 23:
    241  case 24:
    242  case 25:
    243  case 26:
    244  case 27:
    245  return false;
    246  default:
    247  break;
    248  }
    249 
    250  return true;
    251 }
    252 
    253 // The following code is written according to ISO 14496 part 3 Table 4.1 -
    254 // GASpecificConfig.
    255 bool AACAudioSpecificConfig::ParseGASpecificConfig(BitReader* bit_reader) {
    256  uint8_t extension_flag = 0;
    257  uint8_t depends_on_core_coder;
    258  uint16_t dummy;
    259 
    260  RCHECK(bit_reader->ReadBits(1, &dummy)); // frameLengthFlag
    261  RCHECK(bit_reader->ReadBits(1, &depends_on_core_coder));
    262  if (depends_on_core_coder == 1)
    263  RCHECK(bit_reader->ReadBits(14, &dummy)); // coreCoderDelay
    264 
    265  RCHECK(bit_reader->ReadBits(1, &extension_flag));
    266  if (channel_config_ == 0)
    267  RCHECK(ParseProgramConfigElement(bit_reader));
    268 
    269  if (audio_object_type_ == 6 || audio_object_type_ == 20)
    270  RCHECK(bit_reader->ReadBits(3, &dummy)); // layerNr
    271 
    272  if (extension_flag) {
    273  if (audio_object_type_ == 22) {
    274  RCHECK(bit_reader->ReadBits(5, &dummy)); // numOfSubFrame
    275  RCHECK(bit_reader->ReadBits(11, &dummy)); // layer_length
    276  }
    277 
    278  if (audio_object_type_ == 17 || audio_object_type_ == 19 ||
    279  audio_object_type_ == 20 || audio_object_type_ == 23) {
    280  RCHECK(bit_reader->ReadBits(3, &dummy)); // resilience flags
    281  }
    282 
    283  RCHECK(bit_reader->ReadBits(1, &dummy)); // extensionFlag3
    284  }
    285 
    286  return true;
    287 }
    288 
    289 // ISO 14496-3 Table 4.2 – Syntax of program_config_element()
    290 // program_config_element()
    291 // {
    292 // element_instance_tag; 4 uimsbf
    293 // object_type; 2 uimsbf
    294 // sampling_frequency_index; 4 uimsbf
    295 // num_front_channel_elements; 4 uimsbf
    296 // num_side_channel_elements; 4 uimsbf
    297 // num_back_channel_elements; 4 uimsbf
    298 // num_lfe_channel_elements; 2 uimsbf
    299 // num_assoc_data_elements; 3 uimsbf
    300 // num_valid_cc_elements; 4 uimsbf
    301 // mono_mixdown_present; 1 uimsbf
    302 // if (mono_mixdown_present == 1)
    303 // mono_mixdown_element_number; 4 uimsbf
    304 // stereo_mixdown_present; 1 uimsbf
    305 // if (stereo_mixdown_present == 1)
    306 // stereo_mixdown_element_number; 4 uimsbf
    307 // matrix_mixdown_idx_present; 1 uimsbf
    308 // if (matrix_mixdown_idx_present == 1) {
    309 // matrix_mixdown_idx ; 2 uimsbf
    310 // pseudo_surround_enable; 1 uimsbf
    311 // }
    312 // for (i = 0; i < num_front_channel_elements; i++) {
    313 // front_element_is_cpe[i]; 1 bslbf
    314 // front_element_tag_select[i]; 4 uimsbf
    315 // }
    316 // for (i = 0; i < num_side_channel_elements; i++) {
    317 // side_element_is_cpe[i]; 1 bslbf
    318 // side_element_tag_select[i]; 4 uimsbf
    319 // }
    320 // for (i = 0; i < num_back_channel_elements; i++) {
    321 // back_element_is_cpe[i]; 1 bslbf
    322 // back_element_tag_select[i]; 4 uimsbf
    323 // }
    324 // for (i = 0; i < num_lfe_channel_elements; i++)
    325 // lfe_element_tag_select[i]; 4 uimsbf
    326 // for ( i = 0; i < num_assoc_data_elements; i++)
    327 // assoc_data_element_tag_select[i]; 4 uimsbf
    328 // for (i = 0; i < num_valid_cc_elements; i++) {
    329 // cc_element_is_ind_sw[i]; 1 uimsbf
    330 // valid_cc_element_tag_select[i]; 4 uimsbf
    331 // }
    332 // byte_alignment(); Note 1
    333 // comment_field_bytes; 8 uimsbf
    334 // for (i = 0; i < comment_field_bytes; i++)
    335 // comment_field_data[i]; 8 uimsbf
    336 // }
    337 // Note 1: If called from within an AudioSpecificConfig(), this
    338 // byte_alignment shall be relative to the start of the AudioSpecificConfig().
    339 bool AACAudioSpecificConfig::ParseProgramConfigElement(BitReader* bit_reader) {
    340  // element_instance_tag (4), object_type (2), sampling_frequency_index (4).
    341  RCHECK(bit_reader->SkipBits(4 + 2 + 4));
    342 
    343  uint8_t num_front_channel_elements = 0;
    344  uint8_t num_side_channel_elements = 0;
    345  uint8_t num_back_channel_elements = 0;
    346  uint8_t num_lfe_channel_elements = 0;
    347  RCHECK(bit_reader->ReadBits(4, &num_front_channel_elements));
    348  RCHECK(bit_reader->ReadBits(4, &num_side_channel_elements));
    349  RCHECK(bit_reader->ReadBits(4, &num_back_channel_elements));
    350  RCHECK(bit_reader->ReadBits(2, &num_lfe_channel_elements));
    351 
    352  uint8_t num_assoc_data_elements = 0;
    353  RCHECK(bit_reader->ReadBits(3, &num_assoc_data_elements));
    354  uint8_t num_valid_cc_elements = 0;
    355  RCHECK(bit_reader->ReadBits(4, &num_valid_cc_elements));
    356 
    357  RCHECK(bit_reader->SkipBitsConditional(true, 4)); // mono_mixdown
    358  RCHECK(bit_reader->SkipBitsConditional(true, 4)); // stereo_mixdown
    359  RCHECK(bit_reader->SkipBitsConditional(true, 3)); // matrix_mixdown_idx
    360 
    361  num_channels_ = 0;
    362  RCHECK(CountChannels(num_front_channel_elements, &num_channels_, bit_reader));
    363  RCHECK(CountChannels(num_side_channel_elements, &num_channels_, bit_reader));
    364  RCHECK(CountChannels(num_back_channel_elements, &num_channels_, bit_reader));
    365  num_channels_ += num_lfe_channel_elements;
    366 
    367  RCHECK(bit_reader->SkipBits(4 * num_lfe_channel_elements));
    368  RCHECK(bit_reader->SkipBits(4 * num_assoc_data_elements));
    369  RCHECK(bit_reader->SkipBits(5 * num_valid_cc_elements));
    370 
    371  bit_reader->SkipToNextByte();
    372 
    373  uint8_t comment_field_bytes = 0;
    374  RCHECK(bit_reader->ReadBits(8, &comment_field_bytes));
    375  RCHECK(bit_reader->SkipBytes(comment_field_bytes));
    376  return true;
    377 }
    378 
    379 } // namespace media
    380 } // namespace shaka
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    - -
    A class to read bit streams.
    Definition: bit_reader.h:17
    - -
    virtual bool Parse(const std::vector< uint8_t > &data)
    -
    bool SkipBitsConditional(bool condition, size_t num_bits)
    Definition: bit_reader.h:69
    -
    All the methods that are virtual are virtual for mocking.
    - -
    bool SkipBits(size_t num_bits)
    Definition: bit_reader.cc:24
    - -
    bool SkipBytes(size_t num_bytes)
    Definition: bit_reader.cc:63
    -
    static const size_t kADTSHeaderSize
    Size in bytes of the ADTS header added by ConvertEsdsToADTS().
    -
    virtual bool ConvertToADTS(const uint8_t *data, size_t data_size, std::vector< uint8_t > *audio_frame) const
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/codecs/aac_audio_specific_config.h"
    +
    6 
    +
    7 #include <algorithm>
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/media/base/bit_reader.h"
    +
    11 #include "packager/media/base/rcheck.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace {
    +
    16 
    +
    17 // Sampling Frequency Index table, from ISO 14496-3 Table 1.16
    +
    18 static const uint32_t kSampleRates[] = {96000, 88200, 64000, 48000, 44100,
    +
    19  32000, 24000, 22050, 16000, 12000,
    +
    20  11025, 8000, 7350};
    +
    21 
    +
    22 // Channel Configuration table, from ISO 14496-3 Table 1.17
    +
    23 const uint8_t kChannelConfigs[] = {0, 1, 2, 3, 4, 5, 6, 8};
    +
    24 
    +
    25 // ISO 14496-3 Table 4.2 – Syntax of program_config_element()
    +
    26 // program_config_element()
    +
    27 // ...
    +
    28 // element_is_cpe[i]; 1 bslbf
    +
    29 // element_tag_select[i]; 4 uimsbf
    +
    30 bool CountChannels(uint8_t num_elements,
    +
    31  uint8_t* num_channels,
    +
    32  BitReader* bit_reader) {
    +
    33  for (uint8_t i = 0; i < num_elements; ++i) {
    +
    34  bool is_pair = false;
    +
    35  RCHECK(bit_reader->ReadBits(1, &is_pair));
    +
    36  *num_channels += is_pair ? 2 : 1;
    +
    37  RCHECK(bit_reader->SkipBits(4));
    +
    38  }
    +
    39  return true;
    +
    40 }
    +
    41 
    +
    42 } // namespace
    +
    43 
    +
    44 AACAudioSpecificConfig::AACAudioSpecificConfig() {}
    +
    45 
    +
    46 AACAudioSpecificConfig::~AACAudioSpecificConfig() {}
    +
    47 
    +
    48 bool AACAudioSpecificConfig::Parse(const std::vector<uint8_t>& data) {
    +
    49  if (data.empty())
    +
    50  return false;
    +
    51 
    +
    52  BitReader reader(&data[0], data.size());
    +
    53  uint8_t extension_type = AOT_NULL;
    +
    54  uint8_t extension_frequency_index = 0xff;
    +
    55 
    +
    56  sbr_present_ = false;
    +
    57  ps_present_ = false;
    +
    58  frequency_ = 0;
    +
    59  extension_frequency_ = 0;
    +
    60 
    +
    61  // The following code is written according to ISO 14496 Part 3 Table 1.13 -
    +
    62  // Syntax of AudioSpecificConfig.
    +
    63 
    +
    64  // Read base configuration.
    +
    65  // Audio Object Types specified in ISO 14496-3, Table 1.15.
    +
    66  RCHECK(reader.ReadBits(5, &audio_object_type_));
    +
    67  // Audio objects type >=31 is not supported yet.
    +
    68  RCHECK(audio_object_type_ < 31);
    +
    69  RCHECK(reader.ReadBits(4, &frequency_index_));
    +
    70  if (frequency_index_ == 0xf)
    +
    71  RCHECK(reader.ReadBits(24, &frequency_));
    +
    72  RCHECK(reader.ReadBits(4, &channel_config_));
    +
    73 
    +
    74  RCHECK(channel_config_ < arraysize(kChannelConfigs));
    +
    75  num_channels_ = kChannelConfigs[channel_config_];
    +
    76 
    +
    77  // Read extension configuration.
    +
    78  if (audio_object_type_ == AOT_SBR || audio_object_type_ == AOT_PS) {
    +
    79  sbr_present_ = audio_object_type_ == AOT_SBR;
    +
    80  ps_present_ = audio_object_type_ == AOT_PS;
    +
    81  extension_type = AOT_SBR;
    +
    82  RCHECK(reader.ReadBits(4, &extension_frequency_index));
    +
    83  if (extension_frequency_index == 0xf)
    +
    84  RCHECK(reader.ReadBits(24, &extension_frequency_));
    +
    85  RCHECK(reader.ReadBits(5, &audio_object_type_));
    +
    86  // Audio objects type >=31 is not supported yet.
    +
    87  RCHECK(audio_object_type_ < 31);
    +
    88  }
    +
    89 
    +
    90  RCHECK(ParseDecoderGASpecificConfig(&reader));
    +
    91  RCHECK(SkipErrorSpecificConfig());
    +
    92 
    +
    93  // Read extension configuration again
    +
    94  // Note: The check for 16 available bits comes from the AAC spec.
    +
    95  if (extension_type != AOT_SBR && reader.bits_available() >= 16) {
    +
    96  uint16_t sync_extension_type;
    +
    97  uint8_t sbr_present_flag;
    +
    98  uint8_t ps_present_flag;
    +
    99 
    +
    100  if (reader.ReadBits(11, &sync_extension_type) &&
    +
    101  sync_extension_type == 0x2b7) {
    +
    102  if (reader.ReadBits(5, &extension_type) && extension_type == 5) {
    +
    103  RCHECK(reader.ReadBits(1, &sbr_present_flag));
    +
    104  sbr_present_ = sbr_present_flag != 0;
    +
    105 
    +
    106  if (sbr_present_flag) {
    +
    107  RCHECK(reader.ReadBits(4, &extension_frequency_index));
    +
    108 
    +
    109  if (extension_frequency_index == 0xf)
    +
    110  RCHECK(reader.ReadBits(24, &extension_frequency_));
    +
    111 
    +
    112  // Note: The check for 12 available bits comes from the AAC spec.
    +
    113  if (reader.bits_available() >= 12) {
    +
    114  RCHECK(reader.ReadBits(11, &sync_extension_type));
    +
    115  if (sync_extension_type == 0x548) {
    +
    116  RCHECK(reader.ReadBits(1, &ps_present_flag));
    +
    117  ps_present_ = ps_present_flag != 0;
    +
    118  }
    +
    119  }
    +
    120  }
    +
    121  }
    +
    122  }
    +
    123  }
    +
    124 
    +
    125  if (frequency_ == 0) {
    +
    126  RCHECK(frequency_index_ < arraysize(kSampleRates));
    +
    127  frequency_ = kSampleRates[frequency_index_];
    +
    128  }
    +
    129 
    +
    130  if (extension_frequency_ == 0 && extension_frequency_index != 0xff) {
    +
    131  RCHECK(extension_frequency_index < arraysize(kSampleRates));
    +
    132  extension_frequency_ = kSampleRates[extension_frequency_index];
    +
    133  }
    +
    134 
    +
    135  return frequency_ != 0 && num_channels_ != 0 && audio_object_type_ >= 1 &&
    +
    136  audio_object_type_ <= 4 && frequency_index_ != 0xf &&
    +
    137  channel_config_ <= 7;
    +
    138 }
    +
    139 
    + +
    141  const uint8_t* data,
    +
    142  size_t data_size,
    +
    143  std::vector<uint8_t>* audio_frame) const {
    +
    144  DCHECK(audio_object_type_ >= 1 && audio_object_type_ <= 4 &&
    +
    145  frequency_index_ != 0xf && channel_config_ <= 7);
    +
    146 
    +
    147  size_t size = kADTSHeaderSize + data_size;
    +
    148 
    +
    149  // ADTS header uses 13 bits for packet size.
    +
    150  if (size >= (1 << 13))
    +
    151  return false;
    +
    152 
    +
    153  audio_frame->reserve(size);
    +
    154  audio_frame->resize(kADTSHeaderSize);
    +
    155 
    +
    156  audio_frame->at(0) = 0xff;
    +
    157  audio_frame->at(1) = 0xf1;
    +
    158  audio_frame->at(2) = ((audio_object_type_ - 1) << 6) +
    +
    159  (frequency_index_ << 2) + (channel_config_ >> 2);
    +
    160  audio_frame->at(3) =
    +
    161  ((channel_config_ & 0x3) << 6) + static_cast<uint8_t>(size >> 11);
    +
    162  audio_frame->at(4) = static_cast<uint8_t>((size & 0x7ff) >> 3);
    +
    163  audio_frame->at(5) = static_cast<uint8_t>(((size & 7) << 5) + 0x1f);
    +
    164  audio_frame->at(6) = 0xfc;
    +
    165 
    +
    166  audio_frame->insert(audio_frame->end(), data, data + data_size);
    +
    167 
    +
    168  return true;
    +
    169 }
    +
    170 
    +
    171 AACAudioSpecificConfig::AudioObjectType
    + +
    173  if (ps_present_)
    +
    174  return AOT_PS;
    +
    175  if (sbr_present_)
    +
    176  return AOT_SBR;
    +
    177  return audio_object_type_;
    +
    178 }
    +
    179 
    + +
    181  if (extension_frequency_ > 0)
    +
    182  return extension_frequency_;
    +
    183 
    +
    184  if (!sbr_present_)
    +
    185  return frequency_;
    +
    186 
    +
    187  // The following code is written according to ISO 14496 Part 3 Table 1.11 and
    +
    188  // Table 1.22. (Table 1.11 refers to the capping to 48000, Table 1.22 refers
    +
    189  // to SBR doubling the AAC sample rate.)
    +
    190  DCHECK_GT(frequency_, 0u);
    +
    191  return std::min(2 * frequency_, 48000u);
    +
    192 }
    +
    193 
    + +
    195  // Check for implicit signalling of HE-AAC and indicate stereo output
    +
    196  // if the mono channel configuration is signalled.
    +
    197  // See ISO-14496-3 Section 1.6.6.1.2 for details about this special casing.
    +
    198  if (sbr_present_ && channel_config_ == 1)
    +
    199  return 2; // CHANNEL_LAYOUT_STEREO
    +
    200 
    +
    201  // When Parametric Stereo is on, mono will be played as stereo.
    +
    202  if (ps_present_ && channel_config_ == 1)
    +
    203  return 2; // CHANNEL_LAYOUT_STEREO
    +
    204 
    +
    205  return num_channels_;
    +
    206 }
    +
    207 
    +
    208 // Currently this function only support GASpecificConfig defined in
    +
    209 // ISO 14496 Part 3 Table 4.1 - Syntax of GASpecificConfig()
    +
    210 bool AACAudioSpecificConfig::ParseDecoderGASpecificConfig(
    +
    211  BitReader* bit_reader) {
    +
    212  switch (audio_object_type_) {
    +
    213  case 1:
    +
    214  case 2:
    +
    215  case 3:
    +
    216  case 4:
    +
    217  case 6:
    +
    218  case 7:
    +
    219  case 17:
    +
    220  case 19:
    +
    221  case 20:
    +
    222  case 21:
    +
    223  case 22:
    +
    224  case 23:
    +
    225  return ParseGASpecificConfig(bit_reader);
    +
    226  default:
    +
    227  break;
    +
    228  }
    +
    229 
    +
    230  return false;
    +
    231 }
    +
    232 
    +
    233 bool AACAudioSpecificConfig::SkipErrorSpecificConfig() const {
    +
    234  switch (audio_object_type_) {
    +
    235  case 17:
    +
    236  case 19:
    +
    237  case 20:
    +
    238  case 21:
    +
    239  case 22:
    +
    240  case 23:
    +
    241  case 24:
    +
    242  case 25:
    +
    243  case 26:
    +
    244  case 27:
    +
    245  return false;
    +
    246  default:
    +
    247  break;
    +
    248  }
    +
    249 
    +
    250  return true;
    +
    251 }
    +
    252 
    +
    253 // The following code is written according to ISO 14496 part 3 Table 4.1 -
    +
    254 // GASpecificConfig.
    +
    255 bool AACAudioSpecificConfig::ParseGASpecificConfig(BitReader* bit_reader) {
    +
    256  uint8_t extension_flag = 0;
    +
    257  uint8_t depends_on_core_coder;
    +
    258  uint16_t dummy;
    +
    259 
    +
    260  RCHECK(bit_reader->ReadBits(1, &dummy)); // frameLengthFlag
    +
    261  RCHECK(bit_reader->ReadBits(1, &depends_on_core_coder));
    +
    262  if (depends_on_core_coder == 1)
    +
    263  RCHECK(bit_reader->ReadBits(14, &dummy)); // coreCoderDelay
    +
    264 
    +
    265  RCHECK(bit_reader->ReadBits(1, &extension_flag));
    +
    266  if (channel_config_ == 0)
    +
    267  RCHECK(ParseProgramConfigElement(bit_reader));
    +
    268 
    +
    269  if (audio_object_type_ == 6 || audio_object_type_ == 20)
    +
    270  RCHECK(bit_reader->ReadBits(3, &dummy)); // layerNr
    +
    271 
    +
    272  if (extension_flag) {
    +
    273  if (audio_object_type_ == 22) {
    +
    274  RCHECK(bit_reader->ReadBits(5, &dummy)); // numOfSubFrame
    +
    275  RCHECK(bit_reader->ReadBits(11, &dummy)); // layer_length
    +
    276  }
    +
    277 
    +
    278  if (audio_object_type_ == 17 || audio_object_type_ == 19 ||
    +
    279  audio_object_type_ == 20 || audio_object_type_ == 23) {
    +
    280  RCHECK(bit_reader->ReadBits(3, &dummy)); // resilience flags
    +
    281  }
    +
    282 
    +
    283  RCHECK(bit_reader->ReadBits(1, &dummy)); // extensionFlag3
    +
    284  }
    +
    285 
    +
    286  return true;
    +
    287 }
    +
    288 
    +
    289 // ISO 14496-3 Table 4.2 – Syntax of program_config_element()
    +
    290 // program_config_element()
    +
    291 // {
    +
    292 // element_instance_tag; 4 uimsbf
    +
    293 // object_type; 2 uimsbf
    +
    294 // sampling_frequency_index; 4 uimsbf
    +
    295 // num_front_channel_elements; 4 uimsbf
    +
    296 // num_side_channel_elements; 4 uimsbf
    +
    297 // num_back_channel_elements; 4 uimsbf
    +
    298 // num_lfe_channel_elements; 2 uimsbf
    +
    299 // num_assoc_data_elements; 3 uimsbf
    +
    300 // num_valid_cc_elements; 4 uimsbf
    +
    301 // mono_mixdown_present; 1 uimsbf
    +
    302 // if (mono_mixdown_present == 1)
    +
    303 // mono_mixdown_element_number; 4 uimsbf
    +
    304 // stereo_mixdown_present; 1 uimsbf
    +
    305 // if (stereo_mixdown_present == 1)
    +
    306 // stereo_mixdown_element_number; 4 uimsbf
    +
    307 // matrix_mixdown_idx_present; 1 uimsbf
    +
    308 // if (matrix_mixdown_idx_present == 1) {
    +
    309 // matrix_mixdown_idx ; 2 uimsbf
    +
    310 // pseudo_surround_enable; 1 uimsbf
    +
    311 // }
    +
    312 // for (i = 0; i < num_front_channel_elements; i++) {
    +
    313 // front_element_is_cpe[i]; 1 bslbf
    +
    314 // front_element_tag_select[i]; 4 uimsbf
    +
    315 // }
    +
    316 // for (i = 0; i < num_side_channel_elements; i++) {
    +
    317 // side_element_is_cpe[i]; 1 bslbf
    +
    318 // side_element_tag_select[i]; 4 uimsbf
    +
    319 // }
    +
    320 // for (i = 0; i < num_back_channel_elements; i++) {
    +
    321 // back_element_is_cpe[i]; 1 bslbf
    +
    322 // back_element_tag_select[i]; 4 uimsbf
    +
    323 // }
    +
    324 // for (i = 0; i < num_lfe_channel_elements; i++)
    +
    325 // lfe_element_tag_select[i]; 4 uimsbf
    +
    326 // for ( i = 0; i < num_assoc_data_elements; i++)
    +
    327 // assoc_data_element_tag_select[i]; 4 uimsbf
    +
    328 // for (i = 0; i < num_valid_cc_elements; i++) {
    +
    329 // cc_element_is_ind_sw[i]; 1 uimsbf
    +
    330 // valid_cc_element_tag_select[i]; 4 uimsbf
    +
    331 // }
    +
    332 // byte_alignment(); Note 1
    +
    333 // comment_field_bytes; 8 uimsbf
    +
    334 // for (i = 0; i < comment_field_bytes; i++)
    +
    335 // comment_field_data[i]; 8 uimsbf
    +
    336 // }
    +
    337 // Note 1: If called from within an AudioSpecificConfig(), this
    +
    338 // byte_alignment shall be relative to the start of the AudioSpecificConfig().
    +
    339 bool AACAudioSpecificConfig::ParseProgramConfigElement(BitReader* bit_reader) {
    +
    340  // element_instance_tag (4), object_type (2), sampling_frequency_index (4).
    +
    341  RCHECK(bit_reader->SkipBits(4 + 2 + 4));
    +
    342 
    +
    343  uint8_t num_front_channel_elements = 0;
    +
    344  uint8_t num_side_channel_elements = 0;
    +
    345  uint8_t num_back_channel_elements = 0;
    +
    346  uint8_t num_lfe_channel_elements = 0;
    +
    347  RCHECK(bit_reader->ReadBits(4, &num_front_channel_elements));
    +
    348  RCHECK(bit_reader->ReadBits(4, &num_side_channel_elements));
    +
    349  RCHECK(bit_reader->ReadBits(4, &num_back_channel_elements));
    +
    350  RCHECK(bit_reader->ReadBits(2, &num_lfe_channel_elements));
    +
    351 
    +
    352  uint8_t num_assoc_data_elements = 0;
    +
    353  RCHECK(bit_reader->ReadBits(3, &num_assoc_data_elements));
    +
    354  uint8_t num_valid_cc_elements = 0;
    +
    355  RCHECK(bit_reader->ReadBits(4, &num_valid_cc_elements));
    +
    356 
    +
    357  RCHECK(bit_reader->SkipBitsConditional(true, 4)); // mono_mixdown
    +
    358  RCHECK(bit_reader->SkipBitsConditional(true, 4)); // stereo_mixdown
    +
    359  RCHECK(bit_reader->SkipBitsConditional(true, 3)); // matrix_mixdown_idx
    +
    360 
    +
    361  num_channels_ = 0;
    +
    362  RCHECK(CountChannels(num_front_channel_elements, &num_channels_, bit_reader));
    +
    363  RCHECK(CountChannels(num_side_channel_elements, &num_channels_, bit_reader));
    +
    364  RCHECK(CountChannels(num_back_channel_elements, &num_channels_, bit_reader));
    +
    365  num_channels_ += num_lfe_channel_elements;
    +
    366 
    +
    367  RCHECK(bit_reader->SkipBits(4 * num_lfe_channel_elements));
    +
    368  RCHECK(bit_reader->SkipBits(4 * num_assoc_data_elements));
    +
    369  RCHECK(bit_reader->SkipBits(5 * num_valid_cc_elements));
    +
    370 
    +
    371  bit_reader->SkipToNextByte();
    +
    372 
    +
    373  uint8_t comment_field_bytes = 0;
    +
    374  RCHECK(bit_reader->ReadBits(8, &comment_field_bytes));
    +
    375  RCHECK(bit_reader->SkipBytes(comment_field_bytes));
    +
    376  return true;
    +
    377 }
    +
    378 
    +
    379 } // namespace media
    +
    380 } // namespace shaka
    +
    static const size_t kADTSHeaderSize
    Size in bytes of the ADTS header added by ConvertEsdsToADTS().
    +
    virtual bool ConvertToADTS(const uint8_t *data, size_t data_size, std::vector< uint8_t > *audio_frame) const
    +
    virtual bool Parse(const std::vector< uint8_t > &data)
    + + + +
    A class to read bit streams.
    Definition: bit_reader.h:17
    +
    size_t bits_available() const
    Definition: bit_reader.h:89
    +
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/df8/structshaka_1_1media_1_1mp4_1_1TrackFragmentDecodeTime-members.html b/docs/d9/df8/structshaka_1_1media_1_1mp4_1_1TrackFragmentDecodeTime-members.html index c5c0db355d..ea0440833a 100644 --- a/docs/d9/df8/structshaka_1_1media_1_1mp4_1_1TrackFragmentDecodeTime-members.html +++ b/docs/d9/df8/structshaka_1_1media_1_1mp4_1_1TrackFragmentDecodeTime-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/d9/df9/classshaka_1_1media_1_1OffsetByteQueue.html b/docs/d9/df9/classshaka_1_1media_1_1OffsetByteQueue.html index df870f7d0f..ca6a4a7768 100644 --- a/docs/d9/df9/classshaka_1_1media_1_1OffsetByteQueue.html +++ b/docs/d9/df9/classshaka_1_1media_1_1OffsetByteQueue.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::OffsetByteQueue Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    max_offset > diff --git a/docs/d9/dfc/hls__audio__util_8cc_source.html b/docs/d9/dfc/hls__audio__util_8cc_source.html index b12691d231..197b9e5c53 100644 --- a/docs/d9/dfc/hls__audio__util_8cc_source.html +++ b/docs/d9/dfc/hls__audio__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/hls_audio_util.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    hls_audio_util.cc
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/hls_audio_util.h"
    8 
    9 #include "packager/media/base/buffer_writer.h"
    10 #include "packager/media/base/fourccs.h"
    11 #include "packager/media/codecs/aac_audio_specific_config.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 bool WriteAudioSetupInformation(Codec codec,
    17  const uint8_t* audio_specific_config,
    18  size_t audio_specific_config_size,
    19  BufferWriter* audio_setup_information) {
    20  uint32_t audio_type = FOURCC_NULL;
    21  switch (codec) {
    22  case kCodecAAC: {
    23  AACAudioSpecificConfig config;
    24  const bool result = config.Parse(std::vector<uint8_t>(
    25  audio_specific_config,
    26  audio_specific_config + audio_specific_config_size));
    27 
    28  AACAudioSpecificConfig::AudioObjectType audio_object_type;
    29  if (!result) {
    30  LOG(WARNING) << "Failed to parse config. Assuming AAC-LC.";
    31  audio_object_type = AACAudioSpecificConfig::AOT_AAC_LC;
    32  } else {
    33  audio_object_type = config.GetAudioObjectType();
    34  }
    35 
    36  switch (audio_object_type) {
    37  case AACAudioSpecificConfig::AOT_AAC_LC:
    38  audio_type = FOURCC_zaac;
    39  break;
    40  case AACAudioSpecificConfig::AOT_SBR:
    41  audio_type = FOURCC_zach;
    42  break;
    43  case AACAudioSpecificConfig::AOT_PS:
    44  audio_type = FOURCC_zacp;
    45  break;
    46  default:
    47  LOG(ERROR) << "Unknown object type for aac " << audio_object_type;
    48  return false;
    49  }
    50  } break;
    51  case kCodecAC3:
    52  audio_type = FOURCC_zac3;
    53  break;
    54  case kCodecEAC3:
    55  audio_type = FOURCC_zec3;
    56  break;
    57  default:
    58  LOG(ERROR) << "Codec " << codec << " is not supported in encrypted TS.";
    59  return false;
    60  }
    61 
    62  DCHECK_NE(audio_type, FOURCC_NULL);
    63  audio_setup_information->AppendInt(audio_type);
    64  // Priming. Since no info from encoder, set it to 0x0000.
    65  audio_setup_information->AppendInt(static_cast<uint16_t>(0x0000));
    66  // Version is always 0x01.
    67  audio_setup_information->AppendInt(static_cast<uint8_t>(0x01));
    68 
    69  // Size is one byte.
    70  if (audio_specific_config_size > 0xFF) {
    71  LOG(ERROR) << "Audio specific config should not be larger than one byte "
    72  << audio_specific_config_size;
    73  return false;
    74  }
    75  audio_setup_information->AppendInt(
    76  static_cast<uint8_t>(audio_specific_config_size));
    77 
    78  audio_setup_information->AppendArray(audio_specific_config,
    79  audio_specific_config_size);
    80  return true;
    81 }
    82 
    83 } // namespace media
    84 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/hls_audio_util.h"
    +
    8 
    +
    9 #include "packager/media/base/buffer_writer.h"
    +
    10 #include "packager/media/base/fourccs.h"
    +
    11 #include "packager/media/codecs/aac_audio_specific_config.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 bool WriteAudioSetupInformation(Codec codec,
    +
    17  const uint8_t* audio_specific_config,
    +
    18  size_t audio_specific_config_size,
    +
    19  BufferWriter* audio_setup_information) {
    +
    20  uint32_t audio_type = FOURCC_NULL;
    +
    21  switch (codec) {
    +
    22  case kCodecAAC: {
    +
    23  AACAudioSpecificConfig config;
    +
    24  const bool result = config.Parse(std::vector<uint8_t>(
    +
    25  audio_specific_config,
    +
    26  audio_specific_config + audio_specific_config_size));
    +
    27 
    +
    28  AACAudioSpecificConfig::AudioObjectType audio_object_type;
    +
    29  if (!result) {
    +
    30  LOG(WARNING) << "Failed to parse config. Assuming AAC-LC.";
    +
    31  audio_object_type = AACAudioSpecificConfig::AOT_AAC_LC;
    +
    32  } else {
    +
    33  audio_object_type = config.GetAudioObjectType();
    +
    34  }
    +
    35 
    +
    36  switch (audio_object_type) {
    +
    37  case AACAudioSpecificConfig::AOT_AAC_LC:
    +
    38  audio_type = FOURCC_zaac;
    +
    39  break;
    +
    40  case AACAudioSpecificConfig::AOT_SBR:
    +
    41  audio_type = FOURCC_zach;
    +
    42  break;
    +
    43  case AACAudioSpecificConfig::AOT_PS:
    +
    44  audio_type = FOURCC_zacp;
    +
    45  break;
    +
    46  default:
    +
    47  LOG(ERROR) << "Unknown object type for aac " << audio_object_type;
    +
    48  return false;
    +
    49  }
    +
    50  } break;
    +
    51  case kCodecAC3:
    +
    52  audio_type = FOURCC_zac3;
    +
    53  break;
    +
    54  case kCodecEAC3:
    +
    55  audio_type = FOURCC_zec3;
    +
    56  break;
    +
    57  default:
    +
    58  LOG(ERROR) << "Codec " << codec << " is not supported in encrypted TS.";
    +
    59  return false;
    +
    60  }
    +
    61 
    +
    62  DCHECK_NE(audio_type, FOURCC_NULL);
    +
    63  audio_setup_information->AppendInt(audio_type);
    +
    64  // Priming. Since no info from encoder, set it to 0x0000.
    +
    65  audio_setup_information->AppendInt(static_cast<uint16_t>(0x0000));
    +
    66  // Version is always 0x01.
    +
    67  audio_setup_information->AppendInt(static_cast<uint8_t>(0x01));
    +
    68 
    +
    69  // Size is one byte.
    +
    70  if (audio_specific_config_size > 0xFF) {
    +
    71  LOG(ERROR) << "Audio specific config should not be larger than one byte "
    +
    72  << audio_specific_config_size;
    +
    73  return false;
    +
    74  }
    +
    75  audio_setup_information->AppendInt(
    +
    76  static_cast<uint8_t>(audio_specific_config_size));
    +
    77 
    +
    78  audio_setup_information->AppendArray(audio_specific_config,
    +
    79  audio_specific_config_size);
    +
    80  return true;
    +
    81 }
    +
    82 
    +
    83 } // namespace media
    +
    84 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/d9/dfe/classshaka_1_1UdpOptions.html b/docs/d9/dfe/classshaka_1_1UdpOptions.html index 2d958539a9..4d82e057fd 100644 --- a/docs/d9/dfe/classshaka_1_1UdpOptions.html +++ b/docs/d9/dfe/classshaka_1_1UdpOptions.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::UdpOptions Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -
    Returns
    a UdpOptions object on success, nullptr otherwise.
    +
    Returns
    a UdpOptions object on success, nullptr otherwise.

    Definition at line 75 of file udp_options.cc.

    @@ -155,9 +158,7 @@ Static Public Member Functions
    diff --git a/docs/d9/dff/structshaka_1_1media_1_1H264ModificationOfPicNum.html b/docs/d9/dff/structshaka_1_1media_1_1H264ModificationOfPicNum.html index 35ed8ef57d..8882a7c288 100644 --- a/docs/d9/dff/structshaka_1_1media_1_1H264ModificationOfPicNum.html +++ b/docs/d9/dff/structshaka_1_1media_1_1H264ModificationOfPicNum.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264ModificationOfPicNum Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

    Detailed Description

    -

    Definition at line 121 of file h264_parser.h.

    +

    Definition at line 117 of file h264_parser.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/da/d02/classshaka_1_1media_1_1Id3Tag-members.html b/docs/da/d02/classshaka_1_1media_1_1Id3Tag-members.html index bc115d68d2..1f0773fec4 100644 --- a/docs/da/d02/classshaka_1_1media_1_1Id3Tag-members.html +++ b/docs/da/d02/classshaka_1_1media_1_1Id3Tag-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/d04/audio__stream__info_8cc_source.html b/docs/da/d04/audio__stream__info_8cc_source.html index 674a468ea8..c997a5686f 100644 --- a/docs/da/d04/audio__stream__info_8cc_source.html +++ b/docs/da/d04/audio__stream__info_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/audio_stream_info.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    audio_stream_info.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/audio_stream_info.h"
    8 
    9 #include <inttypes.h>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/base/strings/string_number_conversions.h"
    13 #include "packager/base/strings/stringprintf.h"
    14 #include "packager/media/base/limits.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 namespace {
    20 std::string AudioCodecToString(Codec codec) {
    21  switch (codec) {
    22  case kCodecAAC:
    23  return "AAC";
    24  case kCodecAC3:
    25  return "AC3";
    26  case kCodecDTSC:
    27  return "DTSC";
    28  case kCodecDTSE:
    29  return "DTSE";
    30  case kCodecDTSH:
    31  return "DTSH";
    32  case kCodecDTSL:
    33  return "DTSL";
    34  case kCodecDTSM:
    35  return "DTS-";
    36  case kCodecDTSP:
    37  return "DTS+";
    38  case kCodecEAC3:
    39  return "EAC3";
    40  case kCodecFlac:
    41  return "FLAC";
    42  case kCodecOpus:
    43  return "Opus";
    44  case kCodecVorbis:
    45  return "Vorbis";
    46  default:
    47  NOTIMPLEMENTED() << "Unknown Audio Codec: " << codec;
    48  return "UnknownCodec";
    49  }
    50 }
    51 } // namespace
    52 
    54  int track_id, uint32_t time_scale, uint64_t duration, Codec codec,
    55  const std::string& codec_string, const uint8_t* codec_config,
    56  size_t codec_config_size, uint8_t sample_bits, uint8_t num_channels,
    57  uint32_t sampling_frequency, uint64_t seek_preroll_ns,
    58  uint64_t codec_delay_ns, uint32_t max_bitrate, uint32_t avg_bitrate,
    59  const std::string& language, bool is_encrypted)
    60  : StreamInfo(kStreamAudio, track_id, time_scale, duration, codec,
    61  codec_string, codec_config, codec_config_size, language,
    62  is_encrypted),
    63  sample_bits_(sample_bits),
    64  num_channels_(num_channels),
    65  sampling_frequency_(sampling_frequency),
    66  seek_preroll_ns_(seek_preroll_ns),
    67  codec_delay_ns_(codec_delay_ns),
    68  max_bitrate_(max_bitrate),
    69  avg_bitrate_(avg_bitrate) {}
    70 
    71 AudioStreamInfo::~AudioStreamInfo() {}
    72 
    74  return codec() != kUnknownCodec && num_channels_ != 0 &&
    75  num_channels_ <= limits::kMaxChannels && sample_bits_ > 0 &&
    76  sample_bits_ <= limits::kMaxBitsPerSample && sampling_frequency_ > 0 &&
    77  sampling_frequency_ <= limits::kMaxSampleRate;
    78 }
    79 
    80 std::string AudioStreamInfo::ToString() const {
    81  std::string str = base::StringPrintf(
    82  "%s codec: %s\n sample_bits: %d\n num_channels: %d\n "
    83  "sampling_frequency: %d\n language: %s\n",
    84  StreamInfo::ToString().c_str(), AudioCodecToString(codec()).c_str(),
    85  sample_bits_, num_channels_, sampling_frequency_, language().c_str());
    86  if (seek_preroll_ns_ != 0) {
    87  base::StringAppendF(&str, " seek_preroll_ns: %" PRIu64 "\n",
    88  seek_preroll_ns_);
    89  }
    90  if (codec_delay_ns_ != 0) {
    91  base::StringAppendF(&str, " codec_delay_ns: %" PRIu64 "\n",
    92  codec_delay_ns_);
    93  }
    94  return str;
    95 }
    96 
    97 std::unique_ptr<StreamInfo> AudioStreamInfo::Clone() const {
    98  return std::unique_ptr<StreamInfo>(new AudioStreamInfo(*this));
    99 }
    100 
    101 std::string AudioStreamInfo::GetCodecString(Codec codec,
    102  uint8_t audio_object_type) {
    103  switch (codec) {
    104  case kCodecAAC:
    105  return "mp4a.40." + base::UintToString(audio_object_type);
    106  case kCodecAC3:
    107  return "ac-3";
    108  case kCodecDTSC:
    109  return "dtsc";
    110  case kCodecDTSE:
    111  return "dtse";
    112  case kCodecDTSH:
    113  return "dtsh";
    114  case kCodecDTSL:
    115  return "dtsl";
    116  case kCodecDTSM:
    117  return "dts-";
    118  case kCodecDTSP:
    119  return "dts+";
    120  case kCodecEAC3:
    121  return "ec-3";
    122  case kCodecFlac:
    123  return "flac";
    124  case kCodecOpus:
    125  return "opus";
    126  case kCodecVorbis:
    127  return "vorbis";
    128  default:
    129  NOTIMPLEMENTED() << "Codec: " << codec;
    130  return "unknown";
    131  }
    132 }
    133 
    134 } // namespace media
    135 } // namespace shaka
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    virtual std::string ToString() const
    Definition: stream_info.cc:58
    -
    std::string ToString() const override
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool IsValidConfig() const override
    -
    static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
    -
    std::unique_ptr< StreamInfo > Clone() const override
    -
    AudioStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const uint8_t *codec_config, size_t codec_config_size, uint8_t sample_bits, uint8_t num_channels, uint32_t sampling_frequency, uint64_t seek_preroll_ns, uint64_t codec_delay_ns, uint32_t max_bitrate, uint32_t avg_bitrate, const std::string &language, bool is_encrypted)
    Construct an initialized audio stream info object.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/audio_stream_info.h"
    +
    8 
    +
    9 #include <inttypes.h>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/base/strings/string_number_conversions.h"
    +
    13 #include "packager/base/strings/stringprintf.h"
    +
    14 #include "packager/media/base/limits.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 namespace {
    +
    20 std::string AudioCodecToString(Codec codec) {
    +
    21  switch (codec) {
    +
    22  case kCodecAAC:
    +
    23  return "AAC";
    +
    24  case kCodecAC3:
    +
    25  return "AC3";
    +
    26  case kCodecDTSC:
    +
    27  return "DTSC";
    +
    28  case kCodecDTSE:
    +
    29  return "DTSE";
    +
    30  case kCodecDTSH:
    +
    31  return "DTSH";
    +
    32  case kCodecDTSL:
    +
    33  return "DTSL";
    +
    34  case kCodecDTSM:
    +
    35  return "DTS-";
    +
    36  case kCodecDTSP:
    +
    37  return "DTS+";
    +
    38  case kCodecEAC3:
    +
    39  return "EAC3";
    +
    40  case kCodecAC4:
    +
    41  return "AC4";
    +
    42  case kCodecFlac:
    +
    43  return "FLAC";
    +
    44  case kCodecOpus:
    +
    45  return "Opus";
    +
    46  case kCodecVorbis:
    +
    47  return "Vorbis";
    +
    48  case kCodecMP3:
    +
    49  return "MP3";
    +
    50  default:
    +
    51  NOTIMPLEMENTED() << "Unknown Audio Codec: " << codec;
    +
    52  return "UnknownCodec";
    +
    53  }
    +
    54 }
    +
    55 } // namespace
    +
    56 
    + +
    58  int track_id, uint32_t time_scale, uint64_t duration, Codec codec,
    +
    59  const std::string& codec_string, const uint8_t* codec_config,
    +
    60  size_t codec_config_size, uint8_t sample_bits, uint8_t num_channels,
    +
    61  uint32_t sampling_frequency, uint64_t seek_preroll_ns,
    +
    62  uint64_t codec_delay_ns, uint32_t max_bitrate, uint32_t avg_bitrate,
    +
    63  const std::string& language, bool is_encrypted)
    +
    64  : StreamInfo(kStreamAudio, track_id, time_scale, duration, codec,
    +
    65  codec_string, codec_config, codec_config_size, language,
    +
    66  is_encrypted),
    +
    67  sample_bits_(sample_bits),
    +
    68  num_channels_(num_channels),
    +
    69  sampling_frequency_(sampling_frequency),
    +
    70  seek_preroll_ns_(seek_preroll_ns),
    +
    71  codec_delay_ns_(codec_delay_ns),
    +
    72  max_bitrate_(max_bitrate),
    +
    73  avg_bitrate_(avg_bitrate) {}
    +
    74 
    +
    75 AudioStreamInfo::~AudioStreamInfo() {}
    +
    76 
    + +
    78  return codec() != kUnknownCodec && num_channels_ != 0 &&
    +
    79  num_channels_ <= limits::kMaxChannels && sample_bits_ > 0 &&
    +
    80  sample_bits_ <= limits::kMaxBitsPerSample && sampling_frequency_ > 0 &&
    +
    81  sampling_frequency_ <= limits::kMaxSampleRate;
    +
    82 }
    +
    83 
    +
    84 std::string AudioStreamInfo::ToString() const {
    +
    85  std::string str = base::StringPrintf(
    +
    86  "%s codec: %s\n sample_bits: %d\n num_channels: %d\n "
    +
    87  "sampling_frequency: %d\n language: %s\n",
    +
    88  StreamInfo::ToString().c_str(), AudioCodecToString(codec()).c_str(),
    +
    89  sample_bits_, num_channels_, sampling_frequency_, language().c_str());
    +
    90  if (seek_preroll_ns_ != 0) {
    +
    91  base::StringAppendF(&str, " seek_preroll_ns: %" PRIu64 "\n",
    +
    92  seek_preroll_ns_);
    +
    93  }
    +
    94  if (codec_delay_ns_ != 0) {
    +
    95  base::StringAppendF(&str, " codec_delay_ns: %" PRIu64 "\n",
    +
    96  codec_delay_ns_);
    +
    97  }
    +
    98  return str;
    +
    99 }
    +
    100 
    +
    101 std::unique_ptr<StreamInfo> AudioStreamInfo::Clone() const {
    +
    102  return std::unique_ptr<StreamInfo>(new AudioStreamInfo(*this));
    +
    103 }
    +
    104 
    +
    105 std::string AudioStreamInfo::GetCodecString(Codec codec,
    +
    106  uint8_t audio_object_type) {
    +
    107  switch (codec) {
    +
    108  case kCodecAAC:
    +
    109  return "mp4a.40." + base::UintToString(audio_object_type);
    +
    110  case kCodecAC3:
    +
    111  return "ac-3";
    +
    112  case kCodecDTSC:
    +
    113  return "dtsc";
    +
    114  case kCodecDTSE:
    +
    115  return "dtse";
    +
    116  case kCodecDTSH:
    +
    117  return "dtsh";
    +
    118  case kCodecDTSL:
    +
    119  return "dtsl";
    +
    120  case kCodecDTSM:
    +
    121  return "dts-";
    +
    122  case kCodecDTSP:
    +
    123  return "dts+";
    +
    124  case kCodecEAC3:
    +
    125  return "ec-3";
    +
    126  case kCodecAC4:
    +
    127  // ETSI TS 103 190-2 Digital Audio Compression (AC-4) Standard; Part 2:
    +
    128  // Immersive and personalized audio E.13. audio_object_type is composed of
    +
    129  // bitstream_version (3bits), presentation_version (2bits) and
    +
    130  // mdcompat (3bits).
    +
    131  return base::StringPrintf(
    +
    132  "ac-4.%02d.%02d.%02d", (audio_object_type & 0xE0) >> 5,
    +
    133  (audio_object_type & 0x18) >> 3, audio_object_type & 0x7);
    +
    134  case kCodecFlac:
    +
    135  return "flac";
    +
    136  case kCodecOpus:
    +
    137  return "opus";
    +
    138  case kCodecMP3:
    +
    139  return "mp3";
    +
    140  case kCodecVorbis:
    +
    141  return "vorbis";
    +
    142  default:
    +
    143  NOTIMPLEMENTED() << "Codec: " << codec;
    +
    144  return "unknown";
    +
    145  }
    +
    146 }
    +
    147 
    +
    148 } // namespace media
    +
    149 } // namespace shaka
    +
    AudioStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const uint8_t *codec_config, size_t codec_config_size, uint8_t sample_bits, uint8_t num_channels, uint32_t sampling_frequency, uint64_t seek_preroll_ns, uint64_t codec_delay_ns, uint32_t max_bitrate, uint32_t avg_bitrate, const std::string &language, bool is_encrypted)
    Construct an initialized audio stream info object.
    +
    std::unique_ptr< StreamInfo > Clone() const override
    +
    bool IsValidConfig() const override
    +
    std::string ToString() const override
    +
    static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    virtual std::string ToString() const
    Definition: stream_info.cc:59
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/d05/classshaka_1_1hls_1_1MediaPlaylist-members.html b/docs/da/d05/classshaka_1_1hls_1_1MediaPlaylist-members.html index 7c597d515f..c57a0720c8 100644 --- a/docs/da/d05/classshaka_1_1hls_1_1MediaPlaylist-members.html +++ b/docs/da/d05/classshaka_1_1hls_1_1MediaPlaylist-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    codec() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline EncryptionMethod enum name (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylist file_name() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline + GetAC4CbiFlag() constshaka::hls::MediaPlaylistvirtual + GetAC4ImsFlag() constshaka::hls::MediaPlaylistvirtual GetDisplayResolution(uint32_t *width, uint32_t *height) constshaka::hls::MediaPlaylistvirtual - GetFrameRate() constshaka::hls::MediaPlaylistvirtual - GetLongestSegmentDuration() constshaka::hls::MediaPlaylistvirtual - GetNumChannels() constshaka::hls::MediaPlaylistvirtual - GetVideoRange() constshaka::hls::MediaPlaylistvirtual - group_id() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline + GetEC3JocComplexity() constshaka::hls::MediaPlaylistvirtual + GetFrameRate() constshaka::hls::MediaPlaylistvirtual + GetLongestSegmentDuration() constshaka::hls::MediaPlaylistvirtual + GetNumChannels() constshaka::hls::MediaPlaylistvirtual + GetVideoRange() constshaka::hls::MediaPlaylistvirtual + group_id() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline + is_dvs() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline language() constshaka::hls::MediaPlaylistinline MaxBitrate() constshaka::hls::MediaPlaylistvirtual MediaPlaylist(const HlsParams &hls_params, const std::string &file_name, const std::string &name, const std::string &group_id)shaka::hls::MediaPlaylist @@ -102,9 +109,7 @@ $(function() {
    diff --git a/docs/da/d10/classshaka_1_1media_1_1mp2t_1_1EsParser.html b/docs/da/d10/classshaka_1_1media_1_1mp2t_1_1EsParser.html index 37ca4c6ee0..b22f9c48c1 100644 --- a/docs/da/d10/classshaka_1_1media_1_1mp2t_1_1EsParser.html +++ b/docs/da/d10/classshaka_1_1media_1_1mp2t_1_1EsParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::EsParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp2t::EsParserAudio -shaka::media::mp2t::EsParserH26x -shaka::media::mp2t::EsParserH264 -shaka::media::mp2t::EsParserH265 - -
    +shaka::media::mp2t::EsParserDvb +shaka::media::mp2t::EsParserH26x +shaka::media::mp2t::EsParserH264 +shaka::media::mp2t::EsParserH265 + + - - - - + + + + + +

    Public Types

    -typedef base::Callback< void(const std::shared_ptr< StreamInfo > &)> NewStreamInfoCB
     
    -typedef base::Callback< void(uint32_t, const std::shared_ptr< MediaSample > &)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< StreamInfo >)> NewStreamInfoCB
     
    +typedef base::Callback< void(std::shared_ptr< MediaSample >)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< TextSample >)> EmitTextSampleCB
     
    @@ -100,9 +107,9 @@ Public Member Functions - - + + @@ -112,16 +119,14 @@ uint32_t 

    Detailed Description

    -

    Definition at line 20 of file es_parser.h.

    +

    Definition at line 21 of file es_parser.h.


    The documentation for this class was generated from the following file: diff --git a/docs/da/d10/classshaka_1_1media_1_1mp2t_1_1EsParser.png b/docs/da/d10/classshaka_1_1media_1_1mp2t_1_1EsParser.png index 2dc8ce02688053e96571d440b8bdd045b1e05f3e..6381399924ce24278adcab0cae69133c80c28aec 100644 GIT binary patch literal 2196 zcmb7Gdo)|=7LQ)9Rw=CxQ;)Pm>-P5H(V{3Ztx)4N#kpxmP%&gYB4ZHm$DO%F=t$Ml z4kczrD{YX-gcyRjC89K<6Oj<9meqPjsCtzo_oTDt{&9O})}6D~`Ofd`Z-3`}d+*VKb$a#5eH zVdgYDDlgwBG_gF1{<#7QOUoGrsMhLY^U^A1_2H`$b)~lJ>=-Zvb64e{CF`n#W0bZPFnYEe@ z%aPL@5d_D|TIoYDuem#^6vXp_5o0y)}`*QGSw=-Z|)^r)ilil^O@!P&t zZq&iaIJLVBYZ(O{BKe027_A7!A(%K}2UdxFk@(5o%q@pXC|Ae*HAI!FUYzzY zjApj$O+a`Kh@0S`QGP&t#9jHH8Qxs7bBemU_OeUW5%)Zbss@=uGqZYX8LFBrZQXQj zznC`!nx8A(k?*Yzc>jUFnXb7F&8#|A@n%*d@*v@L;uas2z74c=SBXb_0jJRLOG}i? zdCz-!76#%MwjXJj;zfD{gX7OH_2SZQTvGG;h|v@2vFF@=nwhypV0USublLd-UHao- zZ+?VvSa-T{{tFFDT7+@F?D-o0U;EAk11UX$MPzcqCd^V3=6mk}IU^I?gx?x1<>>AYz6UF^>O zrYrSaTg;WRsVr8^1L304A?qb1^<;Q-(!2|Um5Xy^SP#zoqqGKMGeob;b^x)F9rr|+ zf`V{rk#(6cma?EVO0lPKkk)7RsO=F2WE*^+}Zf3vM_9>mRg)@+R1lE`e@ zVnWdJ%+|;+w?h*@t6Z2S-M<>lS`kz}lnK{2cnPL<#jM%&OuQMI_lg#@NF5IY*5qeh z{tm45ERLyghYi!{*!s9@F<2{tfw-PbR29(mLOhlHRug0nS4Tx118Perc^dDLMj_A^nuGege6YEsgkH^;@702EdDYnl;x&)O)W(oV&X7#2GoHD=M_np z&ll&118b6#&R|vp=uzOfv6_khIFEV&B)sa2TdQLJJFwEDqW4XqN*otdof8zouPyZV i0oP{lMX%($qFijcP-ds5;SBylK)m7p9+V5$zWz7JMP`%$ literal 1900 zcmbuAe>hWn9LK+_ONDZECyUB0s%Irpte=zAvb9njG@|GV$)WuC1?E|}dr+z1+t1_^tWA0m=#QjqBL$>;NRE_IkA z>GW{O#T6h$+N0&E+bRHb)ugSP-AmZ<%TR@=D7Gq=zj2bvJW*f2;fK3$a8BC_Gf8Lg;wNx9va;D6b}wBmMG>q5PF*oAKTq@aGgc|kXz{^&a%&yC60?n_4x*5R8e+| z1;c(a+@n4XKj!W4<1r6MGfJK^T!<1BP7sREhT#)l%Cy}O)WnF5`Hvku59muMiK=2N zLR1$^l`67Ru^NRCh)U|Q+bh;6^Igmwo6xQL+ui9wt20|~Q4&7)5@KG)9r<__TYL%_siZhGJI*;}Mm)!Cn@A+7iSXsSLz<~K z4{GZ=?P5;jke1EJDBrm0T8WQjH6hK_LICq~&DW9_lqKH=Fmd{gC=Bq!0t0^fof2c9 zEsfJNTuRl6D@Fs|Kj<02#_>1ScS||g-xl%l2R<0jlFG#ppbEZz>^EI}U+R6HN0Y8> zETc(d&S-r7fH^xOUz$Q*Nc!_3M3msHwDg>}%vpe}NQ)3_i_viS=~?M{spvfiNKi&y z5yK)|9!NA*l`CT}Ehn88QX8rL{#bEkSg96S4 z7*0Gu!=<%8)D@)E2h_KXwva)Uf}K=fUm6|5@RrwA2McOVX2sUN>?uq;{x<5~RsSeY z)!bXI6xP~_);y^Dg0a*5MTF{fW`w+kJsvof>+R0OUNrW)tR|dVaDo{(P&vHD__7d!{X+;g2Z8 zZ4sS#lntns^D0WvKueEq{Qne6E={V^52s0aKCd=C$M7!(E$+j0BO9X?eYvr^FJ48? z?-s1XmV|T)?ABwe?0L){n+spSTdRFuZ-@8xIdAl7PIfUAmLx#l$NYo>%4b+-o3taa z1|r-NE9wv6x`&S=H#9Zx@EGaX3>nm#+?g{ui)_xwE<7+FS9NT3^`v!R&b4&y{F^vB za_CCwh!{pwI-k$T?=^W>BI#%e4eV1e-TW^V;E_R?Z8gLwxw3R|WLGzX+nUt3pYfV& zwtQd1LFkcg-GgVG*WncZ0 z^gIo4UP5!Yr3@RS&-T2{Mc}l@a^6wdTinqvGE|{ui8)U6ep_tY{(>~ZfcK^oEgd_9 z2j3HS4L-Y( + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    virtual bool Parse (const uint8_t *buf, int size, int64_t pts, int64_t dts)=0
     
    -virtual void Flush ()=0
     
    +virtual bool Flush ()=0
     
    virtual void Reset ()=0
     
    pid ()
    - + +/* @license-end */
    diff --git a/docs/da/d1a/structshaka_1_1media_1_1mp4_1_1Language.html b/docs/da/d1a/structshaka_1_1media_1_1mp4_1_1Language.html index 01c1aa06da..a17ee67764 100644 --- a/docs/da/d1a/structshaka_1_1media_1_1mp4_1_1Language.html +++ b/docs/da/d1a/structshaka_1_1media_1_1mp4_1_1Language.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Language Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    code<

    Detailed Description

    -

    Definition at line 233 of file box_definitions.h.

    +

    Definition at line 234 of file box_definitions.h.


    The documentation for this struct was generated from the following files:
    diff --git a/docs/da/d1c/classshaka_1_1media_1_1mp2t_1_1TsSection.html b/docs/da/d1c/classshaka_1_1media_1_1mp2t_1_1TsSection.html index da56e1fa4a..2ae61bab97 100644 --- a/docs/da/d1c/classshaka_1_1media_1_1mp2t_1_1TsSection.html +++ b/docs/da/d1c/classshaka_1_1media_1_1mp2t_1_1TsSection.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::TsSection Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp2t::TsSectionPsi shaka::media::mp2t::TsSectionPat shaka::media::mp2t::TsSectionPmt - -
    + + @@ -101,9 +104,9 @@ Public Member Functions - - + + @@ -117,9 +120,7 @@ virtual void 

    Public Types

    enum  SpecialPid {
    -  kPidPat = 0x0, -kPidCat = 0x1, -kPidTsdt = 0x2, -kPidNullPacket = 0x1fff, -
    +  kPidPat = 0x0 +, kPidCat = 0x1 +, kPidTsdt = 0x2 +, kPidNullPacket = 0x1fff +,
      kPidMax = 0x1fff
    }
    virtual bool Parse (bool payload_unit_start_indicator, const uint8_t *buf, int size)=0
     
    -virtual void Flush ()=0
     
    +virtual bool Flush ()=0
     
    virtual void Reset ()=0
     
    Reset ()= diff --git a/docs/da/d1d/udp__options_8cc_source.html b/docs/da/d1d/udp__options_8cc_source.html index 1c9ee9cbf9..2445962226 100644 --- a/docs/da/d1d/udp__options_8cc_source.html +++ b/docs/da/d1d/udp__options_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/udp_options.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    udp_options.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/file/udp_options.h"
    8 
    9 #include <gflags/gflags.h>
    10 
    11 #include "packager/base/strings/string_number_conversions.h"
    12 #include "packager/base/strings/string_split.h"
    13 
    14 DEFINE_string(udp_interface_address,
    15  "",
    16  "IP address of the interface over which to receive UDP unicast"
    17  " or multicast streams");
    18 
    19 namespace shaka {
    20 
    21 namespace {
    22 
    23 enum FieldType {
    24  kUnknownField = 0,
    25  kBufferSizeField,
    26  kInterfaceAddressField,
    27  kMulticastSourceField,
    28  kReuseField,
    29  kTimeoutField,
    30 };
    31 
    32 struct FieldNameToTypeMapping {
    33  const char* field_name;
    34  FieldType field_type;
    35 };
    36 
    37 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
    38  {"buffer_size", kBufferSizeField},
    39  {"interface", kInterfaceAddressField},
    40  {"reuse", kReuseField},
    41  {"source", kMulticastSourceField},
    42  {"timeout", kTimeoutField},
    43 };
    44 
    45 FieldType GetFieldType(const std::string& field_name) {
    46  for (size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
    47  if (field_name == kFieldNameTypeMappings[idx].field_name)
    48  return kFieldNameTypeMappings[idx].field_type;
    49  }
    50  return kUnknownField;
    51 }
    52 
    53 bool StringToAddressAndPort(base::StringPiece addr_and_port,
    54  std::string* addr,
    55  uint16_t* port) {
    56  DCHECK(addr);
    57  DCHECK(port);
    58 
    59  const size_t colon_pos = addr_and_port.find(':');
    60  if (colon_pos == base::StringPiece::npos) {
    61  return false;
    62  }
    63  *addr = addr_and_port.substr(0, colon_pos).as_string();
    64  unsigned port_value;
    65  if (!base::StringToUint(addr_and_port.substr(colon_pos + 1), &port_value) ||
    66  (port_value > 65535)) {
    67  return false;
    68  }
    69  *port = port_value;
    70  return true;
    71 }
    72 
    73 } // namespace
    74 
    75 std::unique_ptr<UdpOptions> UdpOptions::ParseFromString(
    76  base::StringPiece udp_url) {
    77  std::unique_ptr<UdpOptions> options(new UdpOptions);
    78 
    79  const size_t question_mark_pos = udp_url.find('?');
    80  base::StringPiece address_str = udp_url.substr(0, question_mark_pos);
    81 
    82  if (question_mark_pos != base::StringPiece::npos) {
    83  base::StringPiece options_str = udp_url.substr(question_mark_pos + 1);
    84 
    85  base::StringPairs pairs;
    86  if (!base::SplitStringIntoKeyValuePairs(options_str, '=', '&', &pairs)) {
    87  LOG(ERROR) << "Invalid udp options name/value pairs " << options_str;
    88  return nullptr;
    89  }
    90  for (const auto& pair : pairs) {
    91  switch (GetFieldType(pair.first)) {
    92  case kBufferSizeField:
    93  if (!base::StringToInt(pair.second, &options->buffer_size_)) {
    94  LOG(ERROR) << "Invalid udp option for buffer_size field "
    95  << pair.second;
    96  return nullptr;
    97  }
    98  break;
    99  case kInterfaceAddressField:
    100  options->interface_address_ = pair.second;
    101  break;
    102  case kMulticastSourceField:
    103  options->source_address_ = pair.second;
    104  options->is_source_specific_multicast_ = true;
    105  break;
    106  case kReuseField: {
    107  int reuse_value = 0;
    108  if (!base::StringToInt(pair.second, &reuse_value)) {
    109  LOG(ERROR) << "Invalid udp option for reuse field " << pair.second;
    110  return nullptr;
    111  }
    112  options->reuse_ = reuse_value > 0;
    113  break;
    114  }
    115  case kTimeoutField:
    116  if (!base::StringToUint(pair.second, &options->timeout_us_)) {
    117  LOG(ERROR) << "Invalid udp option for timeout field "
    118  << pair.second;
    119  return nullptr;
    120  }
    121  break;
    122  default:
    123  LOG(ERROR) << "Unknown field in udp options (\"" << pair.first
    124  << "\").";
    125  return nullptr;
    126  }
    127  }
    128  }
    129 
    130  if (!FLAGS_udp_interface_address.empty()) {
    131  LOG(WARNING) << "--udp_interface_address is deprecated. Consider switching "
    132  "to udp options instead, something like "
    133  "udp:://ip:port?interface=interface_ip.";
    134  options->interface_address_ = FLAGS_udp_interface_address;
    135  }
    136 
    137  if (!StringToAddressAndPort(address_str, &options->address_,
    138  &options->port_)) {
    139  LOG(ERROR) << "Malformed address:port UDP url " << address_str;
    140  return nullptr;
    141  }
    142  return options;
    143 }
    144 
    145 } // namespace shaka
    static std::unique_ptr< UdpOptions > ParseFromString(base::StringPiece udp_url)
    Definition: udp_options.cc:75
    -
    All the methods that are virtual are virtual for mocking.
    -
    Options parsed from UDP url string of the form: udp://ip:port[?options].
    Definition: udp_options.h:15
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/file/udp_options.h"
    +
    8 
    +
    9 #include <gflags/gflags.h>
    +
    10 
    +
    11 #include "packager/base/strings/string_number_conversions.h"
    +
    12 #include "packager/base/strings/string_split.h"
    +
    13 
    +
    14 DEFINE_string(udp_interface_address,
    +
    15  "",
    +
    16  "IP address of the interface over which to receive UDP unicast"
    +
    17  " or multicast streams");
    +
    18 
    +
    19 namespace shaka {
    +
    20 
    +
    21 namespace {
    +
    22 
    +
    23 enum FieldType {
    +
    24  kUnknownField = 0,
    +
    25  kBufferSizeField,
    +
    26  kInterfaceAddressField,
    +
    27  kMulticastSourceField,
    +
    28  kReuseField,
    +
    29  kTimeoutField,
    +
    30 };
    +
    31 
    +
    32 struct FieldNameToTypeMapping {
    +
    33  const char* field_name;
    +
    34  FieldType field_type;
    +
    35 };
    +
    36 
    +
    37 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
    +
    38  {"buffer_size", kBufferSizeField},
    +
    39  {"interface", kInterfaceAddressField},
    +
    40  {"reuse", kReuseField},
    +
    41  {"source", kMulticastSourceField},
    +
    42  {"timeout", kTimeoutField},
    +
    43 };
    +
    44 
    +
    45 FieldType GetFieldType(const std::string& field_name) {
    +
    46  for (size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
    +
    47  if (field_name == kFieldNameTypeMappings[idx].field_name)
    +
    48  return kFieldNameTypeMappings[idx].field_type;
    +
    49  }
    +
    50  return kUnknownField;
    +
    51 }
    +
    52 
    +
    53 bool StringToAddressAndPort(base::StringPiece addr_and_port,
    +
    54  std::string* addr,
    +
    55  uint16_t* port) {
    +
    56  DCHECK(addr);
    +
    57  DCHECK(port);
    +
    58 
    +
    59  const size_t colon_pos = addr_and_port.find(':');
    +
    60  if (colon_pos == base::StringPiece::npos) {
    +
    61  return false;
    +
    62  }
    +
    63  *addr = addr_and_port.substr(0, colon_pos).as_string();
    +
    64  unsigned port_value;
    +
    65  if (!base::StringToUint(addr_and_port.substr(colon_pos + 1), &port_value) ||
    +
    66  (port_value > 65535)) {
    +
    67  return false;
    +
    68  }
    +
    69  *port = port_value;
    +
    70  return true;
    +
    71 }
    +
    72 
    +
    73 } // namespace
    +
    74 
    +
    75 std::unique_ptr<UdpOptions> UdpOptions::ParseFromString(
    +
    76  base::StringPiece udp_url) {
    +
    77  std::unique_ptr<UdpOptions> options(new UdpOptions);
    +
    78 
    +
    79  const size_t question_mark_pos = udp_url.find('?');
    +
    80  base::StringPiece address_str = udp_url.substr(0, question_mark_pos);
    +
    81 
    +
    82  if (question_mark_pos != base::StringPiece::npos) {
    +
    83  base::StringPiece options_str = udp_url.substr(question_mark_pos + 1);
    +
    84 
    +
    85  base::StringPairs pairs;
    +
    86  if (!base::SplitStringIntoKeyValuePairs(options_str, '=', '&', &pairs)) {
    +
    87  LOG(ERROR) << "Invalid udp options name/value pairs " << options_str;
    +
    88  return nullptr;
    +
    89  }
    +
    90  for (const auto& pair : pairs) {
    +
    91  switch (GetFieldType(pair.first)) {
    +
    92  case kBufferSizeField:
    +
    93  if (!base::StringToInt(pair.second, &options->buffer_size_)) {
    +
    94  LOG(ERROR) << "Invalid udp option for buffer_size field "
    +
    95  << pair.second;
    +
    96  return nullptr;
    +
    97  }
    +
    98  break;
    +
    99  case kInterfaceAddressField:
    +
    100  options->interface_address_ = pair.second;
    +
    101  break;
    +
    102  case kMulticastSourceField:
    +
    103  options->source_address_ = pair.second;
    +
    104  options->is_source_specific_multicast_ = true;
    +
    105  break;
    +
    106  case kReuseField: {
    +
    107  int reuse_value = 0;
    +
    108  if (!base::StringToInt(pair.second, &reuse_value)) {
    +
    109  LOG(ERROR) << "Invalid udp option for reuse field " << pair.second;
    +
    110  return nullptr;
    +
    111  }
    +
    112  options->reuse_ = reuse_value > 0;
    +
    113  break;
    +
    114  }
    +
    115  case kTimeoutField:
    +
    116  if (!base::StringToUint(pair.second, &options->timeout_us_)) {
    +
    117  LOG(ERROR) << "Invalid udp option for timeout field "
    +
    118  << pair.second;
    +
    119  return nullptr;
    +
    120  }
    +
    121  break;
    +
    122  default:
    +
    123  LOG(ERROR) << "Unknown field in udp options (\"" << pair.first
    +
    124  << "\").";
    +
    125  return nullptr;
    +
    126  }
    +
    127  }
    +
    128  }
    +
    129 
    +
    130  if (!FLAGS_udp_interface_address.empty()) {
    +
    131  LOG(WARNING) << "--udp_interface_address is deprecated. Consider switching "
    +
    132  "to udp options instead, something like "
    +
    133  "udp:://ip:port?interface=interface_ip.";
    +
    134  options->interface_address_ = FLAGS_udp_interface_address;
    +
    135  }
    +
    136 
    +
    137  if (!StringToAddressAndPort(address_str, &options->address_,
    +
    138  &options->port_)) {
    +
    139  LOG(ERROR) << "Malformed address:port UDP url " << address_str;
    +
    140  return nullptr;
    +
    141  }
    +
    142  return options;
    +
    143 }
    +
    144 
    +
    145 } // namespace shaka
    +
    Options parsed from UDP url string of the form: udp://ip:port[?options].
    Definition: udp_options.h:15
    +
    static std::unique_ptr< UdpOptions > ParseFromString(base::StringPiece udp_url)
    Definition: udp_options.cc:75
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/d23/classshaka_1_1media_1_1mp2t_1_1EsParserH26x.html b/docs/da/d23/classshaka_1_1media_1_1mp2t_1_1EsParserH26x.html index 6ae1f95cc3..21d0c0af13 100644 --- a/docs/da/d23/classshaka_1_1media_1_1mp2t_1_1EsParserH26x.html +++ b/docs/da/d23/classshaka_1_1media_1_1mp2t_1_1EsParserH26x.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::EsParserH26x Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp2t::EsParser shaka::media::mp2t::EsParserH264 shaka::media::mp2t::EsParserH265 - -
    + + @@ -96,9 +99,9 @@ Public Member Functions - - + + @@ -119,12 +122,15 @@ const - - - - + + + + + +

    Classes

    bool Parse (const uint8_t *buf, int size, int64_t pts, int64_t dts) override
     
    -void Flush () override
     
    +bool Flush () override
     
    void Reset () override
     

    Additional Inherited Members

    - Public Types inherited from shaka::media::mp2t::EsParser
    -typedef base::Callback< void(const std::shared_ptr< StreamInfo > &)> NewStreamInfoCB
     
    -typedef base::Callback< void(uint32_t, const std::shared_ptr< MediaSample > &)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< StreamInfo >)> NewStreamInfoCB
     
    +typedef base::Callback< void(std::shared_ptr< MediaSample >)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< TextSample >)> EmitTextSampleCB
     

    Detailed Description

    @@ -136,9 +142,7 @@ typedef base::Callback< void(uint32_t, const std::shared_ptr< diff --git a/docs/da/d23/ts__muxer_8h_source.html b/docs/da/d23/ts__muxer_8h_source.html index 352ee86b82..8d7490c586 100644 --- a/docs/da/d23/ts__muxer_8h_source.html +++ b/docs/da/d23/ts__muxer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_muxer.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    ts_muxer.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_MUXER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_MUXER_H_
    9 
    10 #include "packager/base/macros.h"
    11 #include "packager/media/base/muxer.h"
    12 #include "packager/media/formats/mp2t/ts_segmenter.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 namespace mp2t {
    17 
    20 class TsMuxer : public Muxer {
    21  public:
    22  explicit TsMuxer(const MuxerOptions& muxer_options);
    23  ~TsMuxer() override;
    24 
    25  private:
    26  // Muxer implementation.
    27  Status InitializeMuxer() override;
    28  Status Finalize() override;
    29  Status AddSample(size_t stream_id,
    30  const MediaSample& sample) override;
    31  Status FinalizeSegment(size_t stream_id,
    32  const SegmentInfo& sample) override;
    33 
    34  void FireOnMediaStartEvent();
    35  void FireOnMediaEndEvent();
    36 
    37  std::unique_ptr<TsSegmenter> segmenter_;
    38 
    39  DISALLOW_COPY_AND_ASSIGN(TsMuxer);
    40 };
    41 
    42 } // namespace mp2t
    43 } // namespace media
    44 } // namespace shaka
    45 
    46 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_MUXER_H_
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_MUXER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_MUXER_H_
    +
    9 
    +
    10 #include "packager/base/macros.h"
    +
    11 #include "packager/media/base/muxer.h"
    +
    12 #include "packager/media/formats/mp2t/ts_segmenter.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 namespace mp2t {
    +
    17 
    +
    20 class TsMuxer : public Muxer {
    +
    21  public:
    +
    22  explicit TsMuxer(const MuxerOptions& muxer_options);
    +
    23  ~TsMuxer() override;
    +
    24 
    +
    25  private:
    +
    26  // Muxer implementation.
    +
    27  Status InitializeMuxer() override;
    +
    28  Status Finalize() override;
    +
    29  Status AddMediaSample(size_t stream_id, const MediaSample& sample) override;
    +
    30  Status FinalizeSegment(size_t stream_id,
    +
    31  const SegmentInfo& sample) override;
    +
    32 
    +
    33  void FireOnMediaStartEvent();
    +
    34  void FireOnMediaEndEvent();
    +
    35 
    +
    36  std::unique_ptr<TsSegmenter> segmenter_;
    +
    37  int64_t sample_durations_[2];
    +
    38  int64_t num_samples_ = 0;
    +
    39 
    +
    40  DISALLOW_COPY_AND_ASSIGN(TsMuxer);
    +
    41 };
    +
    42 
    +
    43 } // namespace mp2t
    +
    44 } // namespace media
    +
    45 } // namespace shaka
    +
    46 
    +
    47 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_MUXER_H_
    + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    + + +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    diff --git a/docs/da/d24/h265__parser_8h_source.html b/docs/da/d24/h265__parser_8h_source.html index a75d797a72..8fdc816781 100644 --- a/docs/da/d24/h265__parser_8h_source.html +++ b/docs/da/d24/h265__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h265_parser.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    h265_parser.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_H265_PARSER_H_
    8 #define PACKAGER_MEDIA_CODECS_H265_PARSER_H_
    9 
    10 #include <map>
    11 #include <memory>
    12 #include <vector>
    13 
    14 #include "packager/media/codecs/h26x_bit_reader.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 class Nalu;
    20 
    21 enum H265SliceType { kBSlice = 0, kPSlice = 1, kISlice = 2 };
    22 
    23 const int kMaxRefPicSetCount = 16;
    24 
    25 // On success, |coded_width| and |coded_height| contains coded resolution after
    26 // cropping; |pixel_width:pixel_height| contains pixel aspect ratio, 1:1 is
    27 // assigned if it is not present in SPS.
    28 struct H265Sps;
    29 bool ExtractResolutionFromSps(const H265Sps& sps,
    30  uint32_t* coded_width,
    31  uint32_t* coded_height,
    32  uint32_t* pixel_width,
    33  uint32_t* pixel_height);
    34 
    36  int delta_poc_s0[kMaxRefPicSetCount];
    37  int delta_poc_s1[kMaxRefPicSetCount];
    38  bool used_by_curr_pic_s0[kMaxRefPicSetCount];
    39  bool used_by_curr_pic_s1[kMaxRefPicSetCount];
    40 
    41  int num_negative_pics;
    42  int num_positive_pics;
    43  int num_delta_pocs;
    44 };
    45 
    47  enum { kExtendedSar = 255 };
    48 
    49  bool aspect_ratio_info_present_flag = false;
    50  int aspect_ratio_idc = 0;
    51  int sar_width = 0;
    52  int sar_height = 0;
    53  int transfer_characteristics = 0;
    54 
    55  bool bitstream_restriction_flag = false;
    56  int min_spatial_segmentation_idc = 0;
    57 
    58  // Incomplete...
    59 };
    60 
    61 struct H265Pps {
    62  H265Pps();
    63  ~H265Pps();
    64 
    65  // Many of the fields here are required when parsing so the default here may
    66  // not be valid.
    67 
    68  int pic_parameter_set_id = 0;
    69  int seq_parameter_set_id = 0;
    70 
    71  bool dependent_slice_segments_enabled_flag = false;
    72  bool output_flag_present_flag = false;
    73  int num_extra_slice_header_bits = 0;
    74  bool sign_data_hiding_enabled_flag = false;
    75  bool cabac_init_present_flag = false;
    76 
    77  int num_ref_idx_l0_default_active_minus1 = 0;
    78  int num_ref_idx_l1_default_active_minus1 = 0;
    79  int init_qp_minus26 = 0;
    80  bool constrained_intra_pred_flag = false;
    81  bool transform_skip_enabled_flag = false;
    82 
    83  bool cu_qp_delta_enabled_flag = 0;
    84  int diff_cu_qp_delta_depth = 0;
    85  int cb_qp_offset = 0;
    86  int cr_qp_offset = 0;
    87 
    88  bool slice_chroma_qp_offsets_present_flag = false;
    89  bool weighted_pred_flag = false;
    90  bool weighted_bipred_flag = false;
    91  bool transquant_bypass_enabled_flag = false;
    92  bool tiles_enabled_flag = false;
    93  bool entropy_coding_sync_enabled_flag = false;
    94 
    95  int num_tile_columns_minus1 = 0;
    96  int num_tile_rows_minus1 = 0;
    97  bool uniform_spacing_flag = true;
    98  std::vector<int> column_width_minus1;
    99  std::vector<int> row_height_minus1;
    100  bool loop_filter_across_tiles_enabled_flag = true;
    101 
    102  bool loop_filter_across_slices_enabled_flag = false;
    103  bool deblocking_filter_control_present_flag = false;
    104  bool deblocking_filter_override_enabled_flag = false;
    105  bool deblocking_filter_disabled_flag = false;
    106  int beta_offset_div2 = 0;
    107  int tc_offset_div2 = 0;
    108 
    109  bool scaling_list_data_present_flag = false;
    110  // Ignored: scaling_list_data( )
    111 
    112  bool lists_modification_present_flag = false;
    113  int log2_parallel_merge_level_minus2 = 0;
    114  bool slice_segment_header_extension_present_flag = false;
    115 
    116  // Incomplete: pps_range_extension:
    117  bool chroma_qp_offset_list_enabled_flag = false;
    118 
    119  // Ignored: extensions...
    120 };
    121 
    122 struct H265Sps {
    123  H265Sps();
    124  ~H265Sps();
    125 
    126  int GetPicSizeInCtbsY() const;
    127  int GetChromaArrayType() const;
    128 
    129  // Many of the fields here are required when parsing so the default here may
    130  // not be valid.
    131 
    132  int video_parameter_set_id = 0;
    133  int max_sub_layers_minus1 = 0;
    134  bool temporal_id_nesting_flag = false;
    135 
    136  // general_profile_space (2), general_tier_flag (1), general_profile_idc (5),
    137  // general_profile_compatibility_flags (32),
    138  // general_constraint_indicator_flags (48), general_level_idc (8).
    139  int general_profile_tier_level_data[12] = {};
    140 
    141  int seq_parameter_set_id = 0;
    142 
    143  int chroma_format_idc = 0;
    144  bool separate_colour_plane_flag = false;
    145  int pic_width_in_luma_samples = 0;
    146  int pic_height_in_luma_samples = 0;
    147 
    148  bool conformance_window_flag = false;
    149  int conf_win_left_offset = 0;
    150  int conf_win_right_offset = 0;
    151  int conf_win_top_offset = 0;
    152  int conf_win_bottom_offset = 0;
    153 
    154  int bit_depth_luma_minus8 = 0;
    155  int bit_depth_chroma_minus8 = 0;
    156  int log2_max_pic_order_cnt_lsb_minus4 = 0;
    157 
    158  bool sub_layer_ordering_info_present_flag = false;
    159  int max_dec_pic_buffering_minus1[8];
    160  int max_num_reorder_pics[8];
    161  int max_latency_increase_plus1[8];
    162 
    163  int log2_min_luma_coding_block_size_minus3 = 0;
    164  int log2_diff_max_min_luma_coding_block_size = 0;
    165  int log2_min_luma_transform_block_size_minus2 = 0;
    166  int log2_diff_max_min_luma_transform_block_size = 0;
    167  int max_transform_hierarchy_depth_inter = 0;
    168  int max_transform_hierarchy_depth_intra = 0;
    169 
    170  bool scaling_list_enabled_flag = false;
    171  bool scaling_list_data_present_flag = false;
    172  // Ignored: scaling_list_data()
    173 
    174  bool amp_enabled_flag = false;
    175  bool sample_adaptive_offset_enabled_flag = false;
    176  bool pcm_enabled_flag = false;
    177  int pcm_sample_bit_depth_luma_minus1 = 0;
    178  int pcm_sample_bit_depth_chroma_minus1 = 0;
    179  int log2_min_pcm_luma_coding_block_size_minus3 = 0;
    180  int log2_diff_max_min_pcm_luma_coding_block_size = 0;
    181  bool pcm_loop_filter_disabled_flag = false;
    182 
    183  int num_short_term_ref_pic_sets = 0;
    184  std::vector<H265ReferencePictureSet> st_ref_pic_sets;
    185 
    186  bool long_term_ref_pic_present_flag = false;
    187  int num_long_term_ref_pics = 0;
    188  std::vector<int> lt_ref_pic_poc_lsb;
    189  std::vector<bool> used_by_curr_pic_lt_flag;
    190 
    191  bool temporal_mvp_enabled_flag = false;
    192  bool strong_intra_smoothing_enabled_flag = false;
    193 
    194  bool vui_parameters_present = false;
    195  H265VuiParameters vui_parameters;
    196 
    197  // Ignored: extensions...
    198 };
    199 
    203 
    204  bool ref_pic_list_modification_flag_l0 = false;
    205  std::vector<int> list_entry_l0;
    206 
    207  bool ref_pic_list_modification_flag_l1 = false;
    208  std::vector<int> list_entry_l1;
    209 };
    210 
    212  H265SliceHeader();
    213  ~H265SliceHeader();
    214 
    216  bool delta_poc_msb_present_flag;
    217  int delta_poc_msb_cycle_lt;
    218  };
    219  // This is the value UsedByCurrPicLt for the current slice segment. This
    220  // value is calulated from the LongTermPicsInfo during parsing.
    221  int used_by_curr_pic_lt = 0;
    222 
    223  // Many of the fields here are required when parsing so the default here may
    224  // not be valid.
    225 
    226  // This is the size of the slice header not including the nalu header byte.
    227  // Sturcture: |NALU Header | Slice Header | Slice Data |
    228  // Size: |<- 16bits ->|<- header_bit_size ->|<- Rest of nalu ->|
    229  // Note that this is not a field in the H.265 spec.
    230  size_t header_bit_size = 0;
    231 
    232  bool first_slice_segment_in_pic_flag = false;
    233  bool no_output_of_prior_pics_flag = false;
    234  int pic_parameter_set_id = 0;
    235 
    236  bool dependent_slice_segment_flag = false;
    237  int segment_address = 0;
    238  int slice_type = 0;
    239  bool pic_output_flag = true;
    240  int colour_plane_id = 0;
    241  int slice_pic_order_cnt_lsb = 0;
    242 
    243  bool short_term_ref_pic_set_sps_flag = false;
    244  H265ReferencePictureSet st_ref_pic_set;
    245  int short_term_ref_pic_set_idx = 0;
    246 
    247  int num_long_term_sps = 0;
    248  int num_long_term_pics = 0;
    249  std::vector<LongTermPicsInfo> long_term_pics_info;
    250 
    251  bool slice_temporal_mvp_enabled_flag = false;
    252  bool slice_sao_luma_flag = false;
    253  bool slice_sao_chroma_flag = false;
    254 
    255  bool num_ref_idx_active_override_flag = false;
    256  int num_ref_idx_l0_active_minus1 = 0;
    257  int num_ref_idx_l1_active_minus1 = 0;
    258 
    259  H265ReferencePictureListModifications ref_pic_lists_modification;
    260 
    261  bool mvd_l1_zero_flag = false;
    262  bool cabac_init_flag = false;
    263  bool collocated_from_l0 = true;
    264  int collocated_ref_idx = 0;
    265 
    266  int five_minus_max_num_merge_cand = 0;
    267  int slice_qp_delta = 0;
    268  int slice_cb_qp_offset = 0;
    269  int slice_cr_qp_offset = 0;
    270 
    271  bool cu_chroma_qp_offset_enabled_flag = false;
    272  bool deblocking_filter_override_flag = false;
    273  bool slice_deblocking_filter_disabled_flag = false;
    274  int slice_beta_offset_div2 = 0;
    275  int slice_tc_offset_div2 = 0;
    276  bool slice_loop_filter_across_slices_enabled_flag = false;
    277 
    278  int num_entry_point_offsets = 0;
    279  int offset_len_minus1 = 0;
    280  std::vector<int> entry_point_offset_minus1;
    281 };
    282 
    286 class H265Parser {
    287  public:
    288  enum Result {
    289  kOk,
    290  kInvalidStream, // error in stream
    291  kUnsupportedStream, // stream not supported by the parser
    292  kEOStream, // end of stream
    293  };
    294 
    295  H265Parser();
    296  ~H265Parser();
    297 
    301  Result ParseSliceHeader(const Nalu& nalu, H265SliceHeader* slice_header);
    302 
    305  Result ParsePps(const Nalu& nalu, int* pps_id);
    308  Result ParseSps(const Nalu& nalu, int* sps_id);
    309 
    311  const H265Pps* GetPps(int pps_id);
    313  const H265Sps* GetSps(int sps_id);
    314 
    315  private:
    316  Result ParseVuiParameters(int max_num_sub_layers_minus1,
    317  H26xBitReader* br,
    318  H265VuiParameters* vui);
    319 
    320  Result ParseReferencePictureSet(
    321  int num_short_term_ref_pic_sets,
    322  int st_rpx_idx,
    323  const std::vector<H265ReferencePictureSet>& ref_pic_sets,
    324  H26xBitReader* br,
    325  H265ReferencePictureSet* st_ref_pic_set);
    326 
    327  Result SkipReferencePictureListModification(
    328  const H265SliceHeader& slice_header,
    329  const H265Pps& pps,
    330  int num_pic_total_curr,
    331  H26xBitReader* br);
    332 
    333  Result SkipPredictionWeightTablePart(int num_ref_idx_minus1,
    334  int chroma_array_type,
    335  H26xBitReader* br);
    336 
    337  Result SkipPredictionWeightTable(bool is_b_slice,
    338  const H265Sps& sps,
    339  const H265SliceHeader& slice_header,
    340  H26xBitReader* br);
    341 
    342  Result ReadProfileTierLevel(bool profile_present,
    343  int max_num_sub_layers_minus1,
    344  H26xBitReader* br,
    345  H265Sps* sps);
    346 
    347  Result SkipScalingListData(H26xBitReader* br);
    348 
    349  Result SkipHrdParameters(int max_num_sub_layers_minus1, H26xBitReader* br);
    350 
    351  Result SkipSubLayerHrdParameters(int cpb_cnt_minus1,
    352  bool sub_pic_hdr_params_present_flag,
    353  H26xBitReader* br);
    354 
    355  Result ByteAlignment(H26xBitReader* br);
    356 
    357  typedef std::map<int, std::unique_ptr<H265Sps>> SpsById;
    358  typedef std::map<int, std::unique_ptr<H265Pps>> PpsById;
    359 
    360  SpsById active_spses_;
    361  PpsById active_ppses_;
    362 
    363  DISALLOW_COPY_AND_ASSIGN(H265Parser);
    364 };
    365 
    366 } // namespace media
    367 } // namespace shaka
    368 
    369 #endif // PACKAGER_MEDIA_CODECS_H265_PARSER_H_
    - - - -
    All the methods that are virtual are virtual for mocking.
    - - - - - - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_H265_PARSER_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_H265_PARSER_H_
    +
    9 
    +
    10 #include <map>
    +
    11 #include <memory>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/media/codecs/h26x_bit_reader.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 class Nalu;
    +
    20 
    +
    21 enum H265SliceType { kBSlice = 0, kPSlice = 1, kISlice = 2 };
    +
    22 
    +
    23 const int kMaxRefPicSetCount = 16;
    +
    24 
    +
    25 // On success, |coded_width| and |coded_height| contains coded resolution after
    +
    26 // cropping; |pixel_width:pixel_height| contains pixel aspect ratio, 1:1 is
    +
    27 // assigned if it is not present in SPS.
    +
    28 struct H265Sps;
    +
    29 bool ExtractResolutionFromSps(const H265Sps& sps,
    +
    30  uint32_t* coded_width,
    +
    31  uint32_t* coded_height,
    +
    32  uint32_t* pixel_width,
    +
    33  uint32_t* pixel_height);
    +
    34 
    + +
    36  int delta_poc_s0[kMaxRefPicSetCount];
    +
    37  int delta_poc_s1[kMaxRefPicSetCount];
    +
    38  bool used_by_curr_pic_s0[kMaxRefPicSetCount];
    +
    39  bool used_by_curr_pic_s1[kMaxRefPicSetCount];
    +
    40 
    +
    41  int num_negative_pics;
    +
    42  int num_positive_pics;
    +
    43  int num_delta_pocs;
    +
    44 };
    +
    45 
    + +
    47  enum { kExtendedSar = 255 };
    +
    48 
    +
    49  bool aspect_ratio_info_present_flag = false;
    +
    50  int aspect_ratio_idc = 0;
    +
    51  int sar_width = 0;
    +
    52  int sar_height = 0;
    +
    53  int transfer_characteristics = 0;
    +
    54 
    +
    55  bool bitstream_restriction_flag = false;
    +
    56  int min_spatial_segmentation_idc = 0;
    +
    57 
    +
    58  // Incomplete...
    +
    59 };
    +
    60 
    +
    61 struct H265Pps {
    +
    62  H265Pps();
    +
    63  ~H265Pps();
    +
    64 
    +
    65  // Many of the fields here are required when parsing so the default here may
    +
    66  // not be valid.
    +
    67 
    +
    68  int pic_parameter_set_id = 0;
    +
    69  int seq_parameter_set_id = 0;
    +
    70 
    +
    71  bool dependent_slice_segments_enabled_flag = false;
    +
    72  bool output_flag_present_flag = false;
    +
    73  int num_extra_slice_header_bits = 0;
    +
    74  bool sign_data_hiding_enabled_flag = false;
    +
    75  bool cabac_init_present_flag = false;
    +
    76 
    +
    77  int num_ref_idx_l0_default_active_minus1 = 0;
    +
    78  int num_ref_idx_l1_default_active_minus1 = 0;
    +
    79  int init_qp_minus26 = 0;
    +
    80  bool constrained_intra_pred_flag = false;
    +
    81  bool transform_skip_enabled_flag = false;
    +
    82 
    +
    83  bool cu_qp_delta_enabled_flag = 0;
    +
    84  int diff_cu_qp_delta_depth = 0;
    +
    85  int cb_qp_offset = 0;
    +
    86  int cr_qp_offset = 0;
    +
    87 
    +
    88  bool slice_chroma_qp_offsets_present_flag = false;
    +
    89  bool weighted_pred_flag = false;
    +
    90  bool weighted_bipred_flag = false;
    +
    91  bool transquant_bypass_enabled_flag = false;
    +
    92  bool tiles_enabled_flag = false;
    +
    93  bool entropy_coding_sync_enabled_flag = false;
    +
    94 
    +
    95  int num_tile_columns_minus1 = 0;
    +
    96  int num_tile_rows_minus1 = 0;
    +
    97  bool uniform_spacing_flag = true;
    +
    98  std::vector<int> column_width_minus1;
    +
    99  std::vector<int> row_height_minus1;
    +
    100  bool loop_filter_across_tiles_enabled_flag = true;
    +
    101 
    +
    102  bool loop_filter_across_slices_enabled_flag = false;
    +
    103  bool deblocking_filter_control_present_flag = false;
    +
    104  bool deblocking_filter_override_enabled_flag = false;
    +
    105  bool deblocking_filter_disabled_flag = false;
    +
    106  int beta_offset_div2 = 0;
    +
    107  int tc_offset_div2 = 0;
    +
    108 
    +
    109  bool scaling_list_data_present_flag = false;
    +
    110  // Ignored: scaling_list_data( )
    +
    111 
    +
    112  bool lists_modification_present_flag = false;
    +
    113  int log2_parallel_merge_level_minus2 = 0;
    +
    114  bool slice_segment_header_extension_present_flag = false;
    +
    115 
    +
    116  // Incomplete: pps_range_extension:
    +
    117  bool chroma_qp_offset_list_enabled_flag = false;
    +
    118 
    +
    119  // Ignored: extensions...
    +
    120 };
    +
    121 
    +
    122 struct H265Sps {
    +
    123  H265Sps();
    +
    124  ~H265Sps();
    +
    125 
    +
    126  int GetPicSizeInCtbsY() const;
    +
    127  int GetChromaArrayType() const;
    +
    128 
    +
    129  // Many of the fields here are required when parsing so the default here may
    +
    130  // not be valid.
    +
    131 
    +
    132  int video_parameter_set_id = 0;
    +
    133  int max_sub_layers_minus1 = 0;
    +
    134  bool temporal_id_nesting_flag = false;
    +
    135 
    +
    136  // general_profile_space (2), general_tier_flag (1), general_profile_idc (5),
    +
    137  // general_profile_compatibility_flags (32),
    +
    138  // general_constraint_indicator_flags (48), general_level_idc (8).
    +
    139  int general_profile_tier_level_data[12] = {};
    +
    140 
    +
    141  int seq_parameter_set_id = 0;
    +
    142 
    +
    143  int chroma_format_idc = 0;
    +
    144  bool separate_colour_plane_flag = false;
    +
    145  int pic_width_in_luma_samples = 0;
    +
    146  int pic_height_in_luma_samples = 0;
    +
    147 
    +
    148  bool conformance_window_flag = false;
    +
    149  int conf_win_left_offset = 0;
    +
    150  int conf_win_right_offset = 0;
    +
    151  int conf_win_top_offset = 0;
    +
    152  int conf_win_bottom_offset = 0;
    +
    153 
    +
    154  int bit_depth_luma_minus8 = 0;
    +
    155  int bit_depth_chroma_minus8 = 0;
    +
    156  int log2_max_pic_order_cnt_lsb_minus4 = 0;
    +
    157 
    +
    158  bool sub_layer_ordering_info_present_flag = false;
    +
    159  int max_dec_pic_buffering_minus1[8];
    +
    160  int max_num_reorder_pics[8];
    +
    161  int max_latency_increase_plus1[8];
    +
    162 
    +
    163  int log2_min_luma_coding_block_size_minus3 = 0;
    +
    164  int log2_diff_max_min_luma_coding_block_size = 0;
    +
    165  int log2_min_luma_transform_block_size_minus2 = 0;
    +
    166  int log2_diff_max_min_luma_transform_block_size = 0;
    +
    167  int max_transform_hierarchy_depth_inter = 0;
    +
    168  int max_transform_hierarchy_depth_intra = 0;
    +
    169 
    +
    170  bool scaling_list_enabled_flag = false;
    +
    171  bool scaling_list_data_present_flag = false;
    +
    172  // Ignored: scaling_list_data()
    +
    173 
    +
    174  bool amp_enabled_flag = false;
    +
    175  bool sample_adaptive_offset_enabled_flag = false;
    +
    176  bool pcm_enabled_flag = false;
    +
    177  int pcm_sample_bit_depth_luma_minus1 = 0;
    +
    178  int pcm_sample_bit_depth_chroma_minus1 = 0;
    +
    179  int log2_min_pcm_luma_coding_block_size_minus3 = 0;
    +
    180  int log2_diff_max_min_pcm_luma_coding_block_size = 0;
    +
    181  bool pcm_loop_filter_disabled_flag = false;
    +
    182 
    +
    183  int num_short_term_ref_pic_sets = 0;
    +
    184  std::vector<H265ReferencePictureSet> st_ref_pic_sets;
    +
    185 
    +
    186  bool long_term_ref_pic_present_flag = false;
    +
    187  int num_long_term_ref_pics = 0;
    +
    188  std::vector<int> lt_ref_pic_poc_lsb;
    +
    189  std::vector<bool> used_by_curr_pic_lt_flag;
    +
    190 
    +
    191  bool temporal_mvp_enabled_flag = false;
    +
    192  bool strong_intra_smoothing_enabled_flag = false;
    +
    193 
    +
    194  bool vui_parameters_present = false;
    +
    195  H265VuiParameters vui_parameters;
    +
    196 
    +
    197  // Ignored: extensions...
    +
    198 };
    +
    199 
    + + + +
    203 
    +
    204  bool ref_pic_list_modification_flag_l0 = false;
    +
    205  std::vector<int> list_entry_l0;
    +
    206 
    +
    207  bool ref_pic_list_modification_flag_l1 = false;
    +
    208  std::vector<int> list_entry_l1;
    +
    209 };
    +
    210 
    + +
    212  H265SliceHeader();
    +
    213  ~H265SliceHeader();
    +
    214 
    + +
    216  bool delta_poc_msb_present_flag;
    +
    217  int delta_poc_msb_cycle_lt;
    +
    218  };
    +
    219  // This is the value UsedByCurrPicLt for the current slice segment. This
    +
    220  // value is calulated from the LongTermPicsInfo during parsing.
    +
    221  int used_by_curr_pic_lt = 0;
    +
    222 
    +
    223  // Many of the fields here are required when parsing so the default here may
    +
    224  // not be valid.
    +
    225 
    +
    226  // This is the size of the slice header not including the nalu header byte.
    +
    227  // Sturcture: |NALU Header | Slice Header | Slice Data |
    +
    228  // Size: |<- 16bits ->|<- header_bit_size ->|<- Rest of nalu ->|
    +
    229  // Note that this is not a field in the H.265 spec.
    +
    230  size_t header_bit_size = 0;
    +
    231 
    +
    232  bool first_slice_segment_in_pic_flag = false;
    +
    233  bool no_output_of_prior_pics_flag = false;
    +
    234  int pic_parameter_set_id = 0;
    +
    235 
    +
    236  bool dependent_slice_segment_flag = false;
    +
    237  int segment_address = 0;
    +
    238  int slice_type = 0;
    +
    239  bool pic_output_flag = true;
    +
    240  int colour_plane_id = 0;
    +
    241  int slice_pic_order_cnt_lsb = 0;
    +
    242 
    +
    243  bool short_term_ref_pic_set_sps_flag = false;
    +
    244  H265ReferencePictureSet st_ref_pic_set;
    +
    245  int short_term_ref_pic_set_idx = 0;
    +
    246 
    +
    247  int num_long_term_sps = 0;
    +
    248  int num_long_term_pics = 0;
    +
    249  std::vector<LongTermPicsInfo> long_term_pics_info;
    +
    250 
    +
    251  bool slice_temporal_mvp_enabled_flag = false;
    +
    252  bool slice_sao_luma_flag = false;
    +
    253  bool slice_sao_chroma_flag = false;
    +
    254 
    +
    255  bool num_ref_idx_active_override_flag = false;
    +
    256  int num_ref_idx_l0_active_minus1 = 0;
    +
    257  int num_ref_idx_l1_active_minus1 = 0;
    +
    258 
    +
    259  H265ReferencePictureListModifications ref_pic_lists_modification;
    +
    260 
    +
    261  bool mvd_l1_zero_flag = false;
    +
    262  bool cabac_init_flag = false;
    +
    263  bool collocated_from_l0 = true;
    +
    264  int collocated_ref_idx = 0;
    +
    265 
    +
    266  int five_minus_max_num_merge_cand = 0;
    +
    267  int slice_qp_delta = 0;
    +
    268  int slice_cb_qp_offset = 0;
    +
    269  int slice_cr_qp_offset = 0;
    +
    270 
    +
    271  bool cu_chroma_qp_offset_enabled_flag = false;
    +
    272  bool deblocking_filter_override_flag = false;
    +
    273  bool slice_deblocking_filter_disabled_flag = false;
    +
    274  int slice_beta_offset_div2 = 0;
    +
    275  int slice_tc_offset_div2 = 0;
    +
    276  bool slice_loop_filter_across_slices_enabled_flag = false;
    +
    277 
    +
    278  int num_entry_point_offsets = 0;
    +
    279  int offset_len_minus1 = 0;
    +
    280  std::vector<int> entry_point_offset_minus1;
    +
    281 };
    +
    282 
    +
    286 class H265Parser {
    +
    287  public:
    +
    288  enum Result {
    +
    289  kOk,
    +
    290  kInvalidStream, // error in stream
    +
    291  kUnsupportedStream, // stream not supported by the parser
    +
    292  kEOStream, // end of stream
    +
    293  };
    +
    294 
    +
    295  H265Parser();
    +
    296  ~H265Parser();
    +
    297 
    +
    301  Result ParseSliceHeader(const Nalu& nalu, H265SliceHeader* slice_header);
    +
    302 
    +
    305  Result ParsePps(const Nalu& nalu, int* pps_id);
    +
    308  Result ParseSps(const Nalu& nalu, int* sps_id);
    +
    309 
    +
    311  const H265Pps* GetPps(int pps_id);
    +
    313  const H265Sps* GetSps(int sps_id);
    +
    314 
    +
    315  private:
    +
    316  Result ParseVuiParameters(int max_num_sub_layers_minus1,
    +
    317  H26xBitReader* br,
    +
    318  H265VuiParameters* vui);
    +
    319 
    +
    320  Result ParseReferencePictureSet(
    +
    321  int num_short_term_ref_pic_sets,
    +
    322  int st_rpx_idx,
    +
    323  const std::vector<H265ReferencePictureSet>& ref_pic_sets,
    +
    324  H26xBitReader* br,
    +
    325  H265ReferencePictureSet* st_ref_pic_set);
    +
    326 
    +
    327  Result SkipReferencePictureListModification(
    +
    328  const H265SliceHeader& slice_header,
    +
    329  const H265Pps& pps,
    +
    330  int num_pic_total_curr,
    +
    331  H26xBitReader* br);
    +
    332 
    +
    333  Result SkipPredictionWeightTablePart(int num_ref_idx_minus1,
    +
    334  int chroma_array_type,
    +
    335  H26xBitReader* br);
    +
    336 
    +
    337  Result SkipPredictionWeightTable(bool is_b_slice,
    +
    338  const H265Sps& sps,
    +
    339  const H265SliceHeader& slice_header,
    +
    340  H26xBitReader* br);
    +
    341 
    +
    342  Result ReadProfileTierLevel(bool profile_present,
    +
    343  int max_num_sub_layers_minus1,
    +
    344  H26xBitReader* br,
    +
    345  H265Sps* sps);
    +
    346 
    +
    347  Result SkipScalingListData(H26xBitReader* br);
    +
    348 
    +
    349  Result SkipHrdParameters(int max_num_sub_layers_minus1, H26xBitReader* br);
    +
    350 
    +
    351  Result SkipSubLayerHrdParameters(int cpb_cnt_minus1,
    +
    352  bool sub_pic_hdr_params_present_flag,
    +
    353  H26xBitReader* br);
    +
    354 
    +
    355  Result ByteAlignment(H26xBitReader* br);
    +
    356 
    +
    357  typedef std::map<int, std::unique_ptr<H265Sps>> SpsById;
    +
    358  typedef std::map<int, std::unique_ptr<H265Pps>> PpsById;
    +
    359 
    +
    360  SpsById active_spses_;
    +
    361  PpsById active_ppses_;
    +
    362 
    +
    363  DISALLOW_COPY_AND_ASSIGN(H265Parser);
    +
    364 };
    +
    365 
    +
    366 } // namespace media
    +
    367 } // namespace shaka
    +
    368 
    +
    369 #endif // PACKAGER_MEDIA_CODECS_H265_PARSER_H_
    + +
    Result ParseSps(const Nalu &nalu, int *sps_id)
    Definition: h265_parser.cc:509
    +
    Result ParsePps(const Nalu &nalu, int *pps_id)
    Definition: h265_parser.cc:401
    +
    const H265Sps * GetSps(int sps_id)
    Definition: h265_parser.cc:630
    +
    Result ParseSliceHeader(const Nalu &nalu, H265SliceHeader *slice_header)
    Definition: h265_parser.cc:183
    +
    const H265Pps * GetPps(int pps_id)
    Definition: h265_parser.cc:626
    + + +
    All the methods that are virtual are virtual for mocking.
    + + + + + + +
    diff --git a/docs/da/d2a/classshaka_1_1media_1_1MuxerFactory.html b/docs/da/d2a/classshaka_1_1media_1_1MuxerFactory.html index 88ee258004..96f88a9b7a 100644 --- a/docs/da/d2a/classshaka_1_1media_1_1MuxerFactory.html +++ b/docs/da/d2a/classshaka_1_1media_1_1MuxerFactory.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MuxerFactory Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
      void OverrideClock (base::Clock *clock)   + +void SetTsStreamOffset (uint32_t offset_ms) + 

    Detailed Description

    To make it easier to create muxers, this factory allows for all configuration to be set at the factory level so that when a function needs a muxer, it can easily create one with local information.

    @@ -114,7 +120,7 @@ Public Member Functions

    Create a new muxer using the factory's settings for the given stream.

    -

    Definition at line 27 of file muxer_factory.cc.

    +

    Definition at line 29 of file muxer_factory.cc.

    @@ -135,7 +141,7 @@ Public Member Functions

    For testing, if you need to replace the clock that muxers work with this will replace the clock for all muxers created after this call.

    -

    Definition at line 74 of file muxer_factory.cc.

    +

    Definition at line 83 of file muxer_factory.cc.

    @@ -146,9 +152,7 @@ Public Member Functions diff --git a/docs/da/d2a/text__stream__info_8h_source.html b/docs/da/d2a/text__stream__info_8h_source.html index d48421b54d..e7cb32afed 100644 --- a/docs/da/d2a/text__stream__info_8h_source.html +++ b/docs/da/d2a/text__stream__info_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/text_stream_info.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    text_stream_info.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_TEXT_STREAM_INFO_H_
    8 #define PACKAGER_MEDIA_BASE_TEXT_STREAM_INFO_H_
    9 
    10 #include "packager/media/base/stream_info.h"
    11 
    12 #include <string>
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 class TextStreamInfo : public StreamInfo {
    18  public:
    31  TextStreamInfo(int track_id, uint32_t time_scale, uint64_t duration,
    32  Codec codec,
    33  const std::string& codec_string,
    34  const std::string& codec_config, uint16_t width,
    35  uint16_t height, const std::string& language);
    36 
    37  ~TextStreamInfo() override;
    38 
    39  bool IsValidConfig() const override;
    40 
    41  std::unique_ptr<StreamInfo> Clone() const override;
    42 
    43  uint16_t width() const { return width_; }
    44  uint16_t height() const { return height_; }
    45 
    46  private:
    47  uint16_t width_;
    48  uint16_t height_;
    49 
    50  // Allow copying. This is very light weight.
    51 };
    52 
    53 } // namespace media
    54 } // namespace shaka
    55 
    56 #endif // PACKAGER_MEDIA_BASE_TEXT_STREAM_INFO_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    All the methods that are virtual are virtual for mocking.
    -
    TextStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const std::string &codec_config, uint16_t width, uint16_t height, const std::string &language)
    -
    bool IsValidConfig() const override
    -
    std::unique_ptr< StreamInfo > Clone() const override
    - +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_TEXT_STREAM_INFO_H_
    +
    8 #define PACKAGER_MEDIA_BASE_TEXT_STREAM_INFO_H_
    +
    9 
    +
    10 #include "packager/media/base/stream_info.h"
    +
    11 #include "packager/media/base/text_sample.h"
    +
    12 
    +
    13 #include <map>
    +
    14 #include <string>
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 struct TextRegion {
    +
    21  TextNumber width{100, TextUnitType::kPercent};
    +
    23  TextNumber height{100, TextUnitType::kPercent};
    +
    24 
    +
    28  TextNumber window_anchor_x{0, TextUnitType::kPercent};
    +
    29  TextNumber window_anchor_y{0, TextUnitType::kPercent};
    +
    35  TextNumber region_anchor_x{0, TextUnitType::kPercent};
    +
    36  TextNumber region_anchor_y{0, TextUnitType::kPercent};
    +
    37 
    +
    40  bool scroll = false;
    +
    41 };
    +
    42 
    + +
    46  std::string language;
    +
    47 };
    +
    48 
    +
    49 class TextStreamInfo : public StreamInfo {
    +
    50  public:
    +
    63  TextStreamInfo(int track_id, uint32_t time_scale, uint64_t duration,
    +
    64  Codec codec,
    +
    65  const std::string& codec_string,
    +
    66  const std::string& codec_config, uint16_t width,
    +
    67  uint16_t height, const std::string& language);
    +
    68 
    +
    69  ~TextStreamInfo() override;
    +
    70 
    +
    71  bool IsValidConfig() const override;
    +
    72 
    +
    73  std::string ToString() const override;
    +
    74  std::unique_ptr<StreamInfo> Clone() const override;
    +
    75 
    +
    76  uint16_t width() const { return width_; }
    +
    77  uint16_t height() const { return height_; }
    +
    78  const std::map<std::string, TextRegion>& regions() const { return regions_; }
    +
    79  void AddRegion(const std::string& id, const TextRegion& region) {
    +
    80  regions_[id] = region;
    +
    81  }
    +
    82  const std::string& css_styles() const { return css_styles_; }
    +
    83  void set_css_styles(const std::string& styles) { css_styles_ = styles; }
    +
    84 
    +
    85  void AddSubStream(uint16_t index, TextSubStreamInfo info) {
    +
    86  sub_streams_.emplace(index, std::move(info));
    +
    87  }
    +
    88  const std::map<uint16_t, TextSubStreamInfo>& sub_streams() const {
    +
    89  return sub_streams_;
    +
    90  }
    +
    91 
    +
    92  private:
    +
    93  std::map<std::string, TextRegion> regions_;
    +
    94  std::map<uint16_t, TextSubStreamInfo> sub_streams_;
    +
    95  std::string css_styles_;
    +
    96  uint16_t width_;
    +
    97  uint16_t height_;
    +
    98 
    +
    99  // Allow copying. This is very light weight.
    +
    100 };
    +
    101 
    +
    102 } // namespace media
    +
    103 } // namespace shaka
    +
    104 
    +
    105 #endif // PACKAGER_MEDIA_BASE_TEXT_STREAM_INFO_H_
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    + +
    TextStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const std::string &codec_config, uint16_t width, uint16_t height, const std::string &language)
    +
    std::string ToString() const override
    +
    std::unique_ptr< StreamInfo > Clone() const override
    +
    bool IsValidConfig() const override
    +
    All the methods that are virtual are virtual for mocking.
    + + + + +
    TextNumber width
    The width of the region; percent units are relative to the window.
    + +
    TextNumber height
    The height of the region; percent units are relative to the window.
    +
    diff --git a/docs/da/d2c/classshaka_1_1BandwidthEstimator.html b/docs/da/d2c/classshaka_1_1BandwidthEstimator.html index 2191ea400c..eaf2fab129 100644 --- a/docs/da/d2c/classshaka_1_1BandwidthEstimator.html +++ b/docs/da/d2c/classshaka_1_1BandwidthEstimator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::BandwidthEstimator Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/da/d2d/classshaka_1_1media_1_1webm_1_1WebMMuxer-members.html b/docs/da/d2d/classshaka_1_1media_1_1webm_1_1WebMMuxer-members.html index 60f3a4a5c8..3d0a8bd075 100644 --- a/docs/da/d2d/classshaka_1_1media_1_1webm_1_1WebMMuxer-members.html +++ b/docs/da/d2d/classshaka_1_1media_1_1webm_1_1WebMMuxer-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline Cancel()shaka::media::Muxer - Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic + Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic clock() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected @@ -109,9 +112,7 @@ $(function() {
    diff --git a/docs/da/d33/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer.html b/docs/da/d33/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer.html new file mode 100644 index 0000000000..03f07ced77 --- /dev/null +++ b/docs/da/d33/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer.html @@ -0,0 +1,226 @@ + + + + + + + +Shaka Packager SDK: shaka::media::webvtt::WebVttMuxer Class Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::webvtt::WebVttMuxer Class Reference
    +
    +
    + +

    Implements WebVtt Muxer. + More...

    + +

    #include <webvtt_muxer.h>

    +
    +Inheritance diagram for shaka::media::webvtt::WebVttMuxer:
    +
    +
    + + +shaka::media::TextMuxer +shaka::media::Muxer +shaka::media::MediaHandler + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Public Member Functions

    WebVttMuxer (const MuxerOptions &options)
     Create a WebMMuxer object from MuxerOptions.
     
    - Public Member Functions inherited from shaka::media::TextMuxer
    TextMuxer (const MuxerOptions &options)
     
    - Public Member Functions inherited from shaka::media::Muxer
    Muxer (const MuxerOptions &options)
     
    void Cancel ()
     
    void SetMuxerListener (std::unique_ptr< MuxerListener > muxer_listener)
     
    void SetProgressListener (std::unique_ptr< ProgressListener > progress_listener)
     
    +const std::vector< std::shared_ptr< const StreamInfo > > & streams () const
     
    void set_clock (base::Clock *clock)
     
    - Public Member Functions inherited from shaka::media::MediaHandler
    +Status SetHandler (size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
     Connect downstream handler at the specified output stream index.
     
    +Status AddHandler (std::shared_ptr< MediaHandler > handler)
     Connect downstream handler to the next available output stream index.
     
    Status Initialize ()
     
    +bool IsConnected ()
     Validate if the handler is connected to its upstream handler.
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::Muxer
    +const MuxerOptionsoptions () const
     
    +MuxerListenermuxer_listener ()
     
    +ProgressListenerprogress_listener ()
     
    +base::Clock * clock ()
     
    Status InitializeInternal () override
     
    Status Process (std::unique_ptr< StreamData > stream_data) override
     
    +Status OnFlushRequest (size_t input_stream_index) override
     Event handler for flush request at the specific input stream index.
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    +virtual bool ValidateOutputStreamIndex (size_t stream_index) const
     Validate if the stream at the specified index actually exists.
     
    Status Dispatch (std::unique_ptr< StreamData > stream_data) const
     
    +Status DispatchStreamInfo (size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
     Dispatch the stream info to downstream handlers.
     
    +Status DispatchMediaSample (size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
     Dispatch the media sample to downstream handlers.
     
    +Status DispatchTextSample (size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
     Dispatch the text sample to downstream handlers.
     
    +Status DispatchSegmentInfo (size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) const
     Dispatch the segment info to downstream handlers.
     
    +Status DispatchScte35Event (size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) const
     Dispatch the scte35 event to downstream handlers.
     
    +Status DispatchCueEvent (size_t stream_index, std::shared_ptr< const CueEvent > cue_event) const
     Dispatch the cue event to downstream handlers.
     
    +Status FlushDownstream (size_t output_stream_index)
     Flush the downstream connected at the specified output stream index.
     
    +Status FlushAllDownstreams ()
     Flush all connected downstream handlers.
     
    +bool initialized ()
     
    +size_t num_input_streams () const
     
    +size_t next_output_stream_index () const
     
    +const std::map< size_t, std::pair< std::shared_ptr< MediaHandler >, size_t > > & output_handlers ()
     
    +

    Detailed Description

    +

    Implements WebVtt Muxer.

    + +

    Definition at line 20 of file webvtt_muxer.h.

    +

    The documentation for this class was generated from the following files: +
    + + + + diff --git a/docs/da/d33/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer.png b/docs/da/d33/classshaka_1_1media_1_1webvtt_1_1WebVttMuxer.png new file mode 100644 index 0000000000000000000000000000000000000000..e81c74040da9fdbe2368fcaf30f86cb29459e999 GIT binary patch literal 1440 zcmeAS@N?(olHy`uVBq!ia0vp^7l8Nx2Q!d#S|fWGNJ#|vgt-3y{~ySF@#br3|Dg#$ z78oBmaDcV*jy#adQ4-`A%m7pb0#{Fk7%?!g>U+94hEy=Vo%?puV;z2%{@JVU{8!!I z$NS8CvPEV2^NT^Vy!?AEPb+bFuz$&vOI}Kzm#nxHJU^{rn51&Pihqmes`+&)p3BN^ zztDNC8Mn7EZl-2W!z7c}?-@N`*+uJpcipp}uSDg35pT4dY~y*ylcAfQ?*3hW`WnOE zgf$MSf1D2_>v(RCW1Q?fSj>G0*rLvOcO_6qTk-d_Qz2 zSo&VpDb+Ul_Bf$BcTUu~sDeU)$oaXh)c&TkJ?o!f-SF$rrM{S4TX;p! zTl%zF)X6o$ev^Fm*7JK_vR?x7CEUAFf*MPwhzT87|AKMDq%h_x8!_c5-i+sw-5Hh( zES@sdXg4s}kbw6EdTFjznWVCIG2E8?Ml;W^m-|&tUdfZ5n_6Ssq_X!~J~J>RZ&&Kq zdtUm#Qoo_^N%XqJ(~B41C=Te-e?9U2yZ^e;tfvxB2R&PE7rXm>3G$>3U4@5IX`Vn^umqu?6Yrn#m}pYf4^|z=`~-j%Du9f-Fw~aQT^p2)4!%KGS>v> zz1sX}hM%S9FNgd4+Eq?2W%8H=3<8ytn?a0h*9B98qC6P(FJeF76~+7FV?4LfG zx{IDRJetD%VJ!pGhc(3GA8wjUw@mVww51Pjiyh-Fm8<^tlT?Ct=N9BWpTFeU@r%d^F|&V9{0ar7B55gra}=&L>&*CZcr zdE0f?`gaTNF)!nL<$LtHXFJ(!drME5wm+yi zHTBo*IAdVYRxS6x=RE029MDJeL>(qQi3BmWDg}6H>Z&xvUt~^DUCZ{RLdR{3)P-}K z#V!^(6rN)I5yrq+K?1H>oO^rQ)FW&g`j|KlYzASr1@qpiz0RwCKIc)K`8;vgx!?a- ztv$>9-uSPeLPPj3W{1ie`4=1B9ZvpZbAJ7i=LqT$-)?L2qvfXdzzT>w)Z`zVyxy({8`{my6yP{v^SDm$Zdgi;pf&D1SQ?zkg e?rpJ4{~0W_YJD!2p0ETKrwpF1elF{r5}E)p0H)ah literal 0 HcmV?d00001 diff --git a/docs/da/d3e/structshaka_1_1media_1_1mp4_1_1PixelAspectRatio-members.html b/docs/da/d3e/structshaka_1_1media_1_1mp4_1_1PixelAspectRatio-members.html index 33cda63538..6c7c939aab 100644 --- a/docs/da/d3e/structshaka_1_1media_1_1mp4_1_1PixelAspectRatio-members.html +++ b/docs/da/d3e/structshaka_1_1media_1_1mp4_1_1PixelAspectRatio-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/d41/mp4_2multi__segment__segmenter_8h_source.html b/docs/da/d41/mp4_2multi__segment__segmenter_8h_source.html index dadc889b15..3ad04a81b7 100644 --- a/docs/da/d41/mp4_2multi__segment__segmenter_8h_source.html +++ b/docs/da/d41/mp4_2multi__segment__segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/multi_segment_segmenter.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    multi_segment_segmenter.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_MULTI_SEGMENT_SEGMENTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_MULTI_SEGMENT_SEGMENTER_H_
    9 
    10 #include "packager/media/formats/mp4/segmenter.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 namespace mp4 {
    15 
    16 struct SegmentType;
    17 
    24  public:
    25  MultiSegmentSegmenter(const MuxerOptions& options,
    26  std::unique_ptr<FileType> ftyp,
    27  std::unique_ptr<Movie> moov);
    28  ~MultiSegmentSegmenter() override;
    29 
    32  bool GetInitRange(size_t* offset, size_t* size) override;
    33  bool GetIndexRange(size_t* offset, size_t* size) override;
    34  std::vector<Range> GetSegmentRanges() override;
    36 
    37  private:
    38  // Segmenter implementation overrides.
    39  Status DoInitialize() override;
    40  Status DoFinalize() override;
    41  Status DoFinalizeSegment() override;
    42 
    43  // Write segment to file.
    44  Status WriteInitSegment();
    45  Status WriteSegment();
    46 
    47  std::unique_ptr<SegmentType> styp_;
    48  uint32_t num_segments_;
    49 
    50  DISALLOW_COPY_AND_ASSIGN(MultiSegmentSegmenter);
    51 };
    52 
    53 } // namespace mp4
    54 } // namespace media
    55 } // namespace shaka
    56 
    57 #endif // PACKAGER_MEDIA_FORMATS_MP4_MULTI_SEGMENT_SEGMENTER_H_
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    bool GetInitRange(size_t *offset, size_t *size) override
    -
    bool GetIndexRange(size_t *offset, size_t *size) override
    - - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_MULTI_SEGMENT_SEGMENTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_MULTI_SEGMENT_SEGMENTER_H_
    +
    9 
    +
    10 #include "packager/media/formats/mp4/segmenter.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 namespace mp4 {
    +
    15 
    +
    16 struct SegmentType;
    +
    17 
    + +
    24  public:
    +
    25  MultiSegmentSegmenter(const MuxerOptions& options,
    +
    26  std::unique_ptr<FileType> ftyp,
    +
    27  std::unique_ptr<Movie> moov);
    +
    28  ~MultiSegmentSegmenter() override;
    +
    29 
    +
    32  bool GetInitRange(size_t* offset, size_t* size) override;
    +
    33  bool GetIndexRange(size_t* offset, size_t* size) override;
    +
    34  std::vector<Range> GetSegmentRanges() override;
    +
    36 
    +
    37  private:
    +
    38  // Segmenter implementation overrides.
    +
    39  Status DoInitialize() override;
    +
    40  Status DoFinalize() override;
    +
    41  Status DoFinalizeSegment() override;
    +
    42 
    +
    43  // Write segment to file.
    +
    44  Status WriteInitSegment();
    +
    45  Status WriteSegment();
    +
    46 
    +
    47  std::unique_ptr<SegmentType> styp_;
    +
    48  uint32_t num_segments_;
    +
    49 
    +
    50  DISALLOW_COPY_AND_ASSIGN(MultiSegmentSegmenter);
    +
    51 };
    +
    52 
    +
    53 } // namespace mp4
    +
    54 } // namespace media
    +
    55 } // namespace shaka
    +
    56 
    +
    57 #endif // PACKAGER_MEDIA_FORMATS_MP4_MULTI_SEGMENT_SEGMENTER_H_
    + + +
    bool GetInitRange(size_t *offset, size_t *size) override
    +
    bool GetIndexRange(size_t *offset, size_t *size) override
    + +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/da/d43/structshaka_1_1ContentProtectionElement.html b/docs/da/d43/structshaka_1_1ContentProtectionElement.html index 06e5d2b145..dad5624e79 100644 --- a/docs/da/d43/structshaka_1_1ContentProtectionElement.html +++ b/docs/da/d43/structshaka_1_1ContentProtectionElement.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::ContentProtectionElement Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    El
    diff --git a/docs/da/d4a/media__playlist_8h_source.html b/docs/da/d4a/media__playlist_8h_source.html index f15d3422fb..2a9e4ceee6 100644 --- a/docs/da/d4a/media__playlist_8h_source.html +++ b/docs/da/d4a/media__playlist_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/media_playlist.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    media_playlist.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_
    8 #define PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_
    9 
    10 #include <list>
    11 #include <memory>
    12 #include <string>
    13 #include <vector>
    14 
    15 #include "packager/base/macros.h"
    16 #include "packager/hls/public/hls_params.h"
    17 #include "packager/mpd/base/bandwidth_estimator.h"
    18 #include "packager/mpd/base/media_info.pb.h"
    19 
    20 namespace shaka {
    21 
    22 class File;
    23 
    24 namespace hls {
    25 
    26 class HlsEntry {
    27  public:
    28  enum class EntryType {
    29  kExtInf,
    30  kExtKey,
    31  kExtDiscontinuity,
    32  kExtPlacementOpportunity,
    33  };
    34  virtual ~HlsEntry();
    35 
    36  EntryType type() const { return type_; }
    37  virtual std::string ToString() = 0;
    38 
    39  protected:
    40  explicit HlsEntry(EntryType type);
    41 
    42  private:
    43  EntryType type_;
    44 };
    45 
    48  public:
    49  enum class MediaPlaylistStreamType {
    50  kUnknown,
    51  kAudio,
    52  kVideo,
    53  kVideoIFramesOnly,
    54  kSubtitle,
    55  };
    56  enum class EncryptionMethod {
    57  kNone, // No encryption, i.e. clear.
    58  kAes128, // Completely encrypted using AES-CBC.
    59  kSampleAes, // Encrypted using SAMPLE-AES method.
    60  kSampleAesCenc, // 'cenc' encrypted content.
    61  };
    62 
    71  MediaPlaylist(const HlsParams& hls_params,
    72  const std::string& file_name,
    73  const std::string& name,
    74  const std::string& group_id);
    75  virtual ~MediaPlaylist();
    76 
    77  const std::string& file_name() const { return file_name_; }
    78  const std::string& name() const { return name_; }
    79  const std::string& group_id() const { return group_id_; }
    80  MediaPlaylistStreamType stream_type() const { return stream_type_; }
    81  const std::string& codec() const { return codec_; }
    82 
    84  void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type);
    85 
    87  void SetCodecForTesting(const std::string& codec);
    88 
    90  void SetLanguageForTesting(const std::string& language);
    91 
    93  void SetCharacteristicsForTesting(
    94  const std::vector<std::string>& characteristics);
    95 
    100  virtual bool SetMediaInfo(const MediaInfo& media_info);
    101 
    106  virtual void SetSampleDuration(uint32_t sample_duration);
    107 
    115  virtual void AddSegment(const std::string& file_name,
    116  int64_t start_time,
    117  int64_t duration,
    118  uint64_t start_byte_offset,
    119  uint64_t size);
    120 
    127  virtual void AddKeyFrame(int64_t timestamp,
    128  uint64_t start_byte_offset,
    129  uint64_t size);
    130 
    142  virtual void AddEncryptionInfo(EncryptionMethod method,
    143  const std::string& url,
    144  const std::string& key_id,
    145  const std::string& iv,
    146  const std::string& key_format,
    147  const std::string& key_format_versions);
    148 
    151  virtual void AddPlacementOpportunity();
    152 
    163  virtual bool WriteToFile(const std::string& file_path);
    164 
    168  virtual uint64_t MaxBitrate() const;
    169 
    173  virtual uint64_t AvgBitrate() const;
    174 
    177  virtual double GetLongestSegmentDuration() const;
    178 
    186  virtual void SetTargetDuration(uint32_t target_duration);
    187 
    189  virtual int GetNumChannels() const;
    190 
    193  virtual bool GetDisplayResolution(uint32_t* width, uint32_t* height) const;
    194 
    196  virtual std::string GetVideoRange() const;
    197 
    199  virtual double GetFrameRate() const;
    200 
    203  const std::string& language() const { return language_; }
    204 
    205  const std::vector<std::string>& characteristics() const {
    206  return characteristics_;
    207  }
    208 
    209  private:
    210  // Add a SegmentInfoEntry (#EXTINF).
    211  void AddSegmentInfoEntry(const std::string& segment_file_name,
    212  int64_t start_time,
    213  int64_t duration,
    214  uint64_t start_byte_offset,
    215  uint64_t size);
    216  // Adjust the duration of the last SegmentInfoEntry to end on
    217  // |next_timestamp|.
    218  void AdjustLastSegmentInfoEntryDuration(int64_t next_timestamp);
    219  // Remove elements from |entries_| for live profile. Increments
    220  // |sequence_number_| by the number of segments removed.
    221  void SlideWindow();
    222  // Remove the segment specified by |start_time|. The actual deletion can
    223  // happen at a later time depending on the value of
    224  // |preserved_segment_outside_live_window| in |hls_params_|.
    225  void RemoveOldSegment(int64_t start_time);
    226 
    227  const HlsParams& hls_params_;
    228  // Mainly for MasterPlaylist to use these values.
    229  const std::string file_name_;
    230  const std::string name_;
    231  const std::string group_id_;
    232  MediaInfo media_info_;
    233  MediaPlaylistStreamType stream_type_ = MediaPlaylistStreamType::kUnknown;
    234  // Whether to use byte range for SegmentInfoEntry.
    235  bool use_byte_range_ = false;
    236  std::string codec_;
    237  std::string language_;
    238  std::vector<std::string> characteristics_;
    239  int media_sequence_number_ = 0;
    240  bool inserted_discontinuity_tag_ = false;
    241  int discontinuity_sequence_number_ = 0;
    242 
    243  double longest_segment_duration_seconds_ = 0.0;
    244  uint32_t time_scale_ = 0;
    245 
    246  BandwidthEstimator bandwidth_estimator_;
    247 
    248  // Cache the previous calls AddSegment() end offset. This is used to construct
    249  // SegmentInfoEntry.
    250  uint64_t previous_segment_end_offset_ = 0;
    251 
    252  // See SetTargetDuration() comments.
    253  bool target_duration_set_ = false;
    254  uint32_t target_duration_ = 0;
    255 
    256  // TODO(kqyang): This could be managed better by a separate class, than having
    257  // all them managed in MediaPlaylist.
    258  std::list<std::unique_ptr<HlsEntry>> entries_;
    259  double current_buffer_depth_ = 0;
    260  // A list to hold the file names of the segments to be removed temporarily.
    261  // Once a file is actually removed, it is removed from the list.
    262  std::list<std::string> segments_to_be_removed_;
    263 
    264  // Used by kVideoIFrameOnly playlists to track the i-frames (key frames).
    265  struct KeyFrameInfo {
    266  int64_t timestamp;
    267  uint64_t start_byte_offset;
    268  uint64_t size;
    269  std::string segment_file_name;
    270  };
    271  std::list<KeyFrameInfo> key_frames_;
    272 
    273  DISALLOW_COPY_AND_ASSIGN(MediaPlaylist);
    274 };
    275 
    276 } // namespace hls
    277 } // namespace shaka
    278 
    279 #endif // PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_
    -
    HLS related parameters.
    Definition: hls_params.h:23
    -
    const std::string & language() const
    -
    All the methods that are virtual are virtual for mocking.
    - -
    Methods are virtual for mocking.
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_
    +
    8 #define PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_
    +
    9 
    +
    10 #include <list>
    +
    11 #include <memory>
    +
    12 #include <string>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/base/macros.h"
    +
    16 #include "packager/hls/public/hls_params.h"
    +
    17 #include "packager/mpd/base/bandwidth_estimator.h"
    +
    18 #include "packager/mpd/base/media_info.pb.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 
    +
    22 class File;
    +
    23 
    +
    24 namespace hls {
    +
    25 
    +
    26 class HlsEntry {
    +
    27  public:
    +
    28  enum class EntryType {
    +
    29  kExtInf,
    +
    30  kExtKey,
    +
    31  kExtDiscontinuity,
    +
    32  kExtPlacementOpportunity,
    +
    33  };
    +
    34  virtual ~HlsEntry();
    +
    35 
    +
    36  EntryType type() const { return type_; }
    +
    37  virtual std::string ToString() = 0;
    +
    38 
    +
    39  protected:
    +
    40  explicit HlsEntry(EntryType type);
    +
    41 
    +
    42  private:
    +
    43  EntryType type_;
    +
    44 };
    +
    45 
    + +
    48  public:
    +
    49  enum class MediaPlaylistStreamType {
    +
    50  kUnknown,
    +
    51  kAudio,
    +
    52  kVideo,
    +
    53  kVideoIFramesOnly,
    +
    54  kSubtitle,
    +
    55  };
    +
    56  enum class EncryptionMethod {
    +
    57  kNone, // No encryption, i.e. clear.
    +
    58  kAes128, // Completely encrypted using AES-CBC.
    +
    59  kSampleAes, // Encrypted using SAMPLE-AES method.
    +
    60  kSampleAesCenc, // 'cenc' encrypted content.
    +
    61  };
    +
    62 
    +
    71  MediaPlaylist(const HlsParams& hls_params,
    +
    72  const std::string& file_name,
    +
    73  const std::string& name,
    +
    74  const std::string& group_id);
    +
    75  virtual ~MediaPlaylist();
    +
    76 
    +
    77  const std::string& file_name() const { return file_name_; }
    +
    78  const std::string& name() const { return name_; }
    +
    79  const std::string& group_id() const { return group_id_; }
    +
    80  MediaPlaylistStreamType stream_type() const { return stream_type_; }
    +
    81  const std::string& codec() const { return codec_; }
    +
    82 
    +
    84  void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type);
    +
    85 
    +
    87  void SetCodecForTesting(const std::string& codec);
    +
    88 
    +
    90  void SetLanguageForTesting(const std::string& language);
    +
    91 
    + +
    94  const std::vector<std::string>& characteristics);
    +
    95 
    +
    100  virtual bool SetMediaInfo(const MediaInfo& media_info);
    +
    101 
    +
    106  virtual void SetSampleDuration(uint32_t sample_duration);
    +
    107 
    +
    115  virtual void AddSegment(const std::string& file_name,
    +
    116  int64_t start_time,
    +
    117  int64_t duration,
    +
    118  uint64_t start_byte_offset,
    +
    119  uint64_t size);
    +
    120 
    +
    127  virtual void AddKeyFrame(int64_t timestamp,
    +
    128  uint64_t start_byte_offset,
    +
    129  uint64_t size);
    +
    130 
    +
    142  virtual void AddEncryptionInfo(EncryptionMethod method,
    +
    143  const std::string& url,
    +
    144  const std::string& key_id,
    +
    145  const std::string& iv,
    +
    146  const std::string& key_format,
    +
    147  const std::string& key_format_versions);
    +
    148 
    +
    151  virtual void AddPlacementOpportunity();
    +
    152 
    +
    163  virtual bool WriteToFile(const std::string& file_path);
    +
    164 
    +
    168  virtual uint64_t MaxBitrate() const;
    +
    169 
    +
    173  virtual uint64_t AvgBitrate() const;
    +
    174 
    +
    177  virtual double GetLongestSegmentDuration() const;
    +
    178 
    +
    186  virtual void SetTargetDuration(uint32_t target_duration);
    +
    187 
    +
    189  virtual int GetNumChannels() const;
    +
    190 
    +
    194  virtual int GetEC3JocComplexity() const;
    +
    195 
    +
    199  virtual bool GetAC4ImsFlag() const;
    +
    200 
    +
    204  virtual bool GetAC4CbiFlag() const;
    +
    205 
    +
    208  virtual bool GetDisplayResolution(uint32_t* width, uint32_t* height) const;
    +
    209 
    +
    211  virtual std::string GetVideoRange() const;
    +
    212 
    +
    214  virtual double GetFrameRate() const;
    +
    215 
    +
    218  const std::string& language() const { return language_; }
    +
    219 
    +
    220  const std::vector<std::string>& characteristics() const {
    +
    221  return characteristics_;
    +
    222  }
    +
    223 
    +
    224  bool is_dvs() const {
    +
    225  // HLS Authoring Specification for Apple Devices
    +
    226  // https://developer.apple.com/documentation/http_live_streaming/hls_authoring_specification_for_apple_devices#overview
    +
    227  // Section 2.12.
    +
    228  const char DVS_CHARACTERISTICS[] = "public.accessibility.describes-video";
    +
    229  return characteristics_.size() == 1 &&
    +
    230  characteristics_[0] == DVS_CHARACTERISTICS;
    +
    231  }
    +
    232 
    +
    233  private:
    +
    234  // Add a SegmentInfoEntry (#EXTINF).
    +
    235  void AddSegmentInfoEntry(const std::string& segment_file_name,
    +
    236  int64_t start_time,
    +
    237  int64_t duration,
    +
    238  uint64_t start_byte_offset,
    +
    239  uint64_t size);
    +
    240  // Adjust the duration of the last SegmentInfoEntry to end on
    +
    241  // |next_timestamp|.
    +
    242  void AdjustLastSegmentInfoEntryDuration(int64_t next_timestamp);
    +
    243  // Remove elements from |entries_| for live profile. Increments
    +
    244  // |sequence_number_| by the number of segments removed.
    +
    245  void SlideWindow();
    +
    246  // Remove the segment specified by |start_time|. The actual deletion can
    +
    247  // happen at a later time depending on the value of
    +
    248  // |preserved_segment_outside_live_window| in |hls_params_|.
    +
    249  void RemoveOldSegment(int64_t start_time);
    +
    250 
    +
    251  const HlsParams& hls_params_;
    +
    252  // Mainly for MasterPlaylist to use these values.
    +
    253  const std::string file_name_;
    +
    254  const std::string name_;
    +
    255  const std::string group_id_;
    +
    256  MediaInfo media_info_;
    +
    257  MediaPlaylistStreamType stream_type_ = MediaPlaylistStreamType::kUnknown;
    +
    258  // Whether to use byte range for SegmentInfoEntry.
    +
    259  bool use_byte_range_ = false;
    +
    260  std::string codec_;
    +
    261  std::string language_;
    +
    262  std::vector<std::string> characteristics_;
    +
    263  uint32_t media_sequence_number_ = 0;
    +
    264  bool inserted_discontinuity_tag_ = false;
    +
    265  int discontinuity_sequence_number_ = 0;
    +
    266 
    +
    267  double longest_segment_duration_seconds_ = 0.0;
    +
    268  uint32_t time_scale_ = 0;
    +
    269 
    +
    270  BandwidthEstimator bandwidth_estimator_;
    +
    271 
    +
    272  // Cache the previous calls AddSegment() end offset. This is used to construct
    +
    273  // SegmentInfoEntry.
    +
    274  uint64_t previous_segment_end_offset_ = 0;
    +
    275 
    +
    276  // See SetTargetDuration() comments.
    +
    277  bool target_duration_set_ = false;
    +
    278  uint32_t target_duration_ = 0;
    +
    279 
    +
    280  // TODO(kqyang): This could be managed better by a separate class, than having
    +
    281  // all them managed in MediaPlaylist.
    +
    282  std::list<std::unique_ptr<HlsEntry>> entries_;
    +
    283  double current_buffer_depth_ = 0;
    +
    284  // A list to hold the file names of the segments to be removed temporarily.
    +
    285  // Once a file is actually removed, it is removed from the list.
    +
    286  std::list<std::string> segments_to_be_removed_;
    +
    287 
    +
    288  // Used by kVideoIFrameOnly playlists to track the i-frames (key frames).
    +
    289  struct KeyFrameInfo {
    +
    290  int64_t timestamp;
    +
    291  uint64_t start_byte_offset;
    +
    292  uint64_t size;
    +
    293  std::string segment_file_name;
    +
    294  };
    +
    295  std::list<KeyFrameInfo> key_frames_;
    +
    296 
    +
    297  DISALLOW_COPY_AND_ASSIGN(MediaPlaylist);
    +
    298 };
    +
    299 
    +
    300 } // namespace hls
    +
    301 } // namespace shaka
    +
    302 
    +
    303 #endif // PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_
    + +
    Methods are virtual for mocking.
    +
    virtual bool WriteToFile(const std::string &file_path)
    +
    virtual bool GetAC4ImsFlag() const
    +
    void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type)
    For testing only.
    +
    virtual void SetSampleDuration(uint32_t sample_duration)
    +
    const std::string & language() const
    +
    virtual void AddEncryptionInfo(EncryptionMethod method, const std::string &url, const std::string &key_id, const std::string &iv, const std::string &key_format, const std::string &key_format_versions)
    +
    void SetCharacteristicsForTesting(const std::vector< std::string > &characteristics)
    For testing only.
    +
    virtual void AddKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    +
    virtual double GetFrameRate() const
    +
    virtual uint64_t AvgBitrate() const
    +
    virtual bool GetDisplayResolution(uint32_t *width, uint32_t *height) const
    +
    virtual double GetLongestSegmentDuration() const
    +
    virtual int GetEC3JocComplexity() const
    +
    virtual uint64_t MaxBitrate() const
    +
    void SetLanguageForTesting(const std::string &language)
    For testing only.
    +
    virtual int GetNumChannels() const
    +
    virtual std::string GetVideoRange() const
    +
    void SetCodecForTesting(const std::string &codec)
    For testing only.
    +
    virtual void AddPlacementOpportunity()
    +
    virtual bool SetMediaInfo(const MediaInfo &media_info)
    +
    MediaPlaylist(const HlsParams &hls_params, const std::string &file_name, const std::string &name, const std::string &group_id)
    +
    virtual bool GetAC4CbiFlag() const
    +
    virtual void SetTargetDuration(uint32_t target_duration)
    +
    virtual void AddSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t start_byte_offset, uint64_t size)
    +
    All the methods that are virtual are virtual for mocking.
    +
    HLS related parameters.
    Definition: hls_params.h:23
    diff --git a/docs/da/d4e/classshaka_1_1media_1_1AudioStreamInfo.html b/docs/da/d4e/classshaka_1_1media_1_1AudioStreamInfo.html index 01f1c3025b..faf8557ecc 100644 --- a/docs/da/d4e/classshaka_1_1media_1_1AudioStreamInfo.html +++ b/docs/da/d4e/classshaka_1_1media_1_1AudioStreamInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AudioStreamInfo Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::media::StreamInfo - -
    +shaka::media::StreamInfo + + @@ -226,7 +229,7 @@ Static Public Member Functions

    Implements shaka::media::StreamInfo.

    -

    Definition at line 97 of file audio_stream_info.cc.

    +

    Definition at line 101 of file audio_stream_info.cc.

    @@ -271,7 +274,7 @@ Static Public Member Functions
    Returns
    The codec string.
    -

    Definition at line 101 of file audio_stream_info.cc.

    +

    Definition at line 105 of file audio_stream_info.cc.

    @@ -301,7 +304,7 @@ Static Public Member Functions

    Implements shaka::media::StreamInfo.

    -

    Definition at line 73 of file audio_stream_info.cc.

    +

    Definition at line 77 of file audio_stream_info.cc.

    @@ -331,7 +334,7 @@ Static Public Member Functions

    Reimplemented from shaka::media::StreamInfo.

    -

    Definition at line 80 of file audio_stream_info.cc.

    +

    Definition at line 84 of file audio_stream_info.cc.

    @@ -342,9 +345,7 @@ Static Public Member Functions diff --git a/docs/da/d50/structshaka_1_1media_1_1mp4_1_1MovieExtendsHeader.html b/docs/da/d50/structshaka_1_1media_1_1mp4_1_1MovieExtendsHeader.html index bb0b2769b8..bd13fc7968 100644 --- a/docs/da/d50/structshaka_1_1media_1_1mp4_1_1MovieExtendsHeader.html +++ b/docs/da/d50/structshaka_1_1media_1_1mp4_1_1MovieExtendsHeader.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::mp4::MovieExtendsHeader Struct Reference @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 644 of file box_definitions.h.

    +

    Definition at line 662 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2235 of file box_definitions.cc.

    +

    Definition at line 2316 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/da/d52/classshaka_1_1media_1_1MuxerListenerFactory-members.html b/docs/da/d52/classshaka_1_1media_1_1MuxerListenerFactory-members.html index 63b4003a92..2c22db98fe 100644 --- a/docs/da/d52/classshaka_1_1media_1_1MuxerListenerFactory-members.html +++ b/docs/da/d52/classshaka_1_1media_1_1MuxerListenerFactory-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/d53/es__parser__h265_8cc_source.html b/docs/da/d53/es__parser__h265_8cc_source.html index e8cdbafa70..b1a03be003 100644 --- a/docs/da/d53/es__parser__h265_8cc_source.html +++ b/docs/da/d53/es__parser__h265_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser_h265.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    es_parser_h265.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp2t/es_parser_h265.h"
    8 
    9 #include <stdint.h>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/media/base/media_sample.h"
    13 #include "packager/media/base/offset_byte_queue.h"
    14 #include "packager/media/base/timestamp.h"
    15 #include "packager/media/base/video_stream_info.h"
    16 #include "packager/media/codecs/h265_byte_to_unit_stream_converter.h"
    17 #include "packager/media/codecs/h265_parser.h"
    18 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
    19 #include "packager/media/formats/mp2t/mp2t_common.h"
    20 
    21 namespace shaka {
    22 namespace media {
    23 namespace mp2t {
    24 
    25 EsParserH265::EsParserH265(uint32_t pid,
    26  const NewStreamInfoCB& new_stream_info_cb,
    27  const EmitSampleCB& emit_sample_cb)
    28  : EsParserH26x(Nalu::kH265,
    29  std::unique_ptr<H26xByteToUnitStreamConverter>(
    30  new H265ByteToUnitStreamConverter()),
    31  pid,
    32  emit_sample_cb),
    33  new_stream_info_cb_(new_stream_info_cb),
    34  decoder_config_check_pending_(false),
    35  h265_parser_(new H265Parser()) {}
    36 
    37 EsParserH265::~EsParserH265() {}
    38 
    39 void EsParserH265::Reset() {
    40  DVLOG(1) << "EsParserH265::Reset";
    41  h265_parser_.reset(new H265Parser());
    42  last_video_decoder_config_ = std::shared_ptr<VideoStreamInfo>();
    43  decoder_config_check_pending_ = false;
    44  EsParserH26x::Reset();
    45 }
    46 
    47 bool EsParserH265::ProcessNalu(const Nalu& nalu,
    48  VideoSliceInfo* video_slice_info) {
    49  video_slice_info->valid = false;
    50  switch (nalu.type()) {
    51  case Nalu::H265_AUD: {
    52  DVLOG(LOG_LEVEL_ES) << "Nalu: AUD";
    53  break;
    54  }
    55  case Nalu::H265_SPS: {
    56  DVLOG(LOG_LEVEL_ES) << "Nalu: SPS";
    57  int sps_id;
    58  if (h265_parser_->ParseSps(nalu, &sps_id) != H265Parser::kOk)
    59  return false;
    60  decoder_config_check_pending_ = true;
    61  break;
    62  }
    63  case Nalu::H265_PPS: {
    64  DVLOG(LOG_LEVEL_ES) << "Nalu: PPS";
    65  int pps_id;
    66  if (h265_parser_->ParsePps(nalu, &pps_id) != H265Parser::kOk) {
    67  // Allow PPS parsing to fail if waiting for SPS.
    68  if (last_video_decoder_config_)
    69  return false;
    70  } else {
    71  decoder_config_check_pending_ = true;
    72  }
    73  break;
    74  }
    75  default: {
    76  if (nalu.is_vcl() && nalu.nuh_layer_id() == 0) {
    77  const bool is_key_frame = nalu.type() == Nalu::H265_IDR_W_RADL ||
    78  nalu.type() == Nalu::H265_IDR_N_LP;
    79  DVLOG(LOG_LEVEL_ES) << "Nalu: slice KeyFrame=" << is_key_frame;
    80  H265SliceHeader shdr;
    81  if (h265_parser_->ParseSliceHeader(nalu, &shdr) != H265Parser::kOk) {
    82  // Only accept an invalid SPS/PPS at the beginning when the stream
    83  // does not necessarily start with an SPS/PPS/IDR.
    84  if (last_video_decoder_config_)
    85  return false;
    86  } else {
    87  video_slice_info->valid = true;
    88  video_slice_info->is_key_frame = is_key_frame;
    89  video_slice_info->frame_num = 0; // frame_num is only for H264.
    90  video_slice_info->pps_id = shdr.pic_parameter_set_id;
    91  }
    92  } else {
    93  DVLOG(LOG_LEVEL_ES) << "Nalu: " << nalu.type();
    94  }
    95  }
    96  }
    97 
    98  return true;
    99 }
    100 
    101 bool EsParserH265::UpdateVideoDecoderConfig(int pps_id) {
    102  // Update the video decoder configuration if needed.
    103  if (!decoder_config_check_pending_)
    104  return true;
    105 
    106  const H265Pps* pps = h265_parser_->GetPps(pps_id);
    107  const H265Sps* sps;
    108  if (!pps) {
    109  // Only accept an invalid PPS at the beginning when the stream
    110  // does not necessarily start with an SPS/PPS/IDR.
    111  // In this case, the initial frames are conveyed to the upper layer with
    112  // an invalid VideoDecoderConfig and it's up to the upper layer
    113  // to process this kind of frame accordingly.
    114  return last_video_decoder_config_ == nullptr;
    115  } else {
    116  sps = h265_parser_->GetSps(pps->seq_parameter_set_id);
    117  if (!sps)
    118  return false;
    119  decoder_config_check_pending_ = false;
    120  }
    121 
    122  std::vector<uint8_t> decoder_config_record;
    123  HEVCDecoderConfigurationRecord decoder_config;
    124  if (!stream_converter()->GetDecoderConfigurationRecord(
    125  &decoder_config_record) ||
    126  !decoder_config.Parse(decoder_config_record)) {
    127  DLOG(ERROR) << "Failure to construct an HEVCDecoderConfigurationRecord";
    128  return false;
    129  }
    130 
    131  if (last_video_decoder_config_) {
    132  if (last_video_decoder_config_->codec_config() != decoder_config_record) {
    133  // Video configuration has changed. Issue warning.
    134  // TODO(tinskip): Check the nature of the configuration change. Only
    135  // minor configuration changes (such as frame ordering) can be handled
    136  // gracefully by decoders without notification. Major changes (such as
    137  // video resolution changes) should be treated as errors.
    138  LOG(WARNING) << "H.265 decoder configuration has changed.";
    139  last_video_decoder_config_->set_codec_config(decoder_config_record);
    140  }
    141  return true;
    142  }
    143 
    144  uint32_t coded_width = 0;
    145  uint32_t coded_height = 0;
    146  uint32_t pixel_width = 0;
    147  uint32_t pixel_height = 0;
    148  if (!ExtractResolutionFromSps(*sps, &coded_width, &coded_height, &pixel_width,
    149  &pixel_height)) {
    150  LOG(ERROR) << "Failed to parse SPS.";
    151  return false;
    152  }
    153 
    154  const uint8_t nalu_length_size =
    155  H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize;
    156  const H26xStreamFormat stream_format = stream_converter()->stream_format();
    157  const FourCC codec_fourcc =
    158  stream_format == H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    159  ? FOURCC_hev1
    160  : FOURCC_hvc1;
    161  last_video_decoder_config_ = std::make_shared<VideoStreamInfo>(
    162  pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH265, stream_format,
    163  decoder_config.GetCodecString(codec_fourcc), decoder_config_record.data(),
    164  decoder_config_record.size(), coded_width, coded_height, pixel_width,
    165  pixel_height, sps->vui_parameters.transfer_characteristics, 0,
    166  nalu_length_size, std::string(), false);
    167 
    168  // Video config notification.
    169  new_stream_info_cb_.Run(last_video_decoder_config_);
    170 
    171  return true;
    172 }
    173 
    174 } // namespace mp2t
    175 } // namespace media
    176 } // namespace shaka
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/es_parser_h265.h"
    +
    8 
    +
    9 #include <stdint.h>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/media_sample.h"
    +
    13 #include "packager/media/base/offset_byte_queue.h"
    +
    14 #include "packager/media/base/timestamp.h"
    +
    15 #include "packager/media/base/video_stream_info.h"
    +
    16 #include "packager/media/codecs/h265_byte_to_unit_stream_converter.h"
    +
    17 #include "packager/media/codecs/h265_parser.h"
    +
    18 #include "packager/media/codecs/hevc_decoder_configuration_record.h"
    +
    19 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    20 
    +
    21 namespace shaka {
    +
    22 namespace media {
    +
    23 namespace mp2t {
    +
    24 
    +
    25 EsParserH265::EsParserH265(uint32_t pid,
    +
    26  const NewStreamInfoCB& new_stream_info_cb,
    +
    27  const EmitSampleCB& emit_sample_cb)
    +
    28  : EsParserH26x(Nalu::kH265,
    +
    29  std::unique_ptr<H26xByteToUnitStreamConverter>(
    +
    30  new H265ByteToUnitStreamConverter()),
    +
    31  pid,
    +
    32  emit_sample_cb),
    +
    33  new_stream_info_cb_(new_stream_info_cb),
    +
    34  decoder_config_check_pending_(false),
    +
    35  h265_parser_(new H265Parser()) {}
    +
    36 
    +
    37 EsParserH265::~EsParserH265() {}
    +
    38 
    +
    39 void EsParserH265::Reset() {
    +
    40  DVLOG(1) << "EsParserH265::Reset";
    +
    41  h265_parser_.reset(new H265Parser());
    +
    42  last_video_decoder_config_ = std::shared_ptr<VideoStreamInfo>();
    +
    43  decoder_config_check_pending_ = false;
    +
    44  EsParserH26x::Reset();
    +
    45 }
    +
    46 
    +
    47 bool EsParserH265::ProcessNalu(const Nalu& nalu,
    +
    48  VideoSliceInfo* video_slice_info) {
    +
    49  video_slice_info->valid = false;
    +
    50  switch (nalu.type()) {
    +
    51  case Nalu::H265_AUD: {
    +
    52  DVLOG(LOG_LEVEL_ES) << "Nalu: AUD";
    +
    53  break;
    +
    54  }
    +
    55  case Nalu::H265_SPS: {
    +
    56  DVLOG(LOG_LEVEL_ES) << "Nalu: SPS";
    +
    57  int sps_id;
    +
    58  auto status = h265_parser_->ParseSps(nalu, &sps_id);
    +
    59  if (status == H265Parser::kOk)
    +
    60  decoder_config_check_pending_ = true;
    +
    61  else if (status == H265Parser::kUnsupportedStream)
    +
    62  // Indicate the stream can't be parsed.
    +
    63  new_stream_info_cb_.Run(nullptr);
    +
    64  else
    +
    65  return false;
    +
    66  break;
    +
    67  }
    +
    68  case Nalu::H265_PPS: {
    +
    69  DVLOG(LOG_LEVEL_ES) << "Nalu: PPS";
    +
    70  int pps_id;
    +
    71  auto status = h265_parser_->ParsePps(nalu, &pps_id);
    +
    72  if (status == H265Parser::kOk) {
    +
    73  decoder_config_check_pending_ = true;
    +
    74  } else if (status == H265Parser::kUnsupportedStream) {
    +
    75  // Indicate the stream can't be parsed.
    +
    76  new_stream_info_cb_.Run(nullptr);
    +
    77  } else {
    +
    78  // Allow PPS parsing to fail if waiting for SPS.
    +
    79  if (last_video_decoder_config_)
    +
    80  return false;
    +
    81  }
    +
    82  break;
    +
    83  }
    +
    84  default: {
    +
    85  if (nalu.is_vcl() && nalu.nuh_layer_id() == 0) {
    +
    86  const bool is_key_frame = nalu.type() == Nalu::H265_IDR_W_RADL ||
    +
    87  nalu.type() == Nalu::H265_IDR_N_LP;
    +
    88  DVLOG(LOG_LEVEL_ES) << "Nalu: slice KeyFrame=" << is_key_frame;
    +
    89  H265SliceHeader shdr;
    +
    90  auto status = h265_parser_->ParseSliceHeader(nalu, &shdr);
    +
    91  if (status == H265Parser::kOk) {
    +
    92  video_slice_info->valid = true;
    +
    93  video_slice_info->is_key_frame = is_key_frame;
    +
    94  video_slice_info->frame_num = 0; // frame_num is only for H264.
    +
    95  video_slice_info->pps_id = shdr.pic_parameter_set_id;
    +
    96  } else if (status == H265Parser::kUnsupportedStream) {
    +
    97  // Indicate the stream can't be parsed.
    +
    98  new_stream_info_cb_.Run(nullptr);
    +
    99  } else {
    +
    100  // Only accept an invalid SPS/PPS at the beginning when the stream
    +
    101  // does not necessarily start with an SPS/PPS/IDR.
    +
    102  if (last_video_decoder_config_)
    +
    103  return false;
    +
    104  }
    +
    105  } else {
    +
    106  DVLOG(LOG_LEVEL_ES) << "Nalu: " << nalu.type();
    +
    107  }
    +
    108  }
    +
    109  }
    +
    110 
    +
    111  return true;
    +
    112 }
    +
    113 
    +
    114 bool EsParserH265::UpdateVideoDecoderConfig(int pps_id) {
    +
    115  // Update the video decoder configuration if needed.
    +
    116  if (!decoder_config_check_pending_)
    +
    117  return true;
    +
    118 
    +
    119  const H265Pps* pps = h265_parser_->GetPps(pps_id);
    +
    120  const H265Sps* sps;
    +
    121  if (!pps) {
    +
    122  // Only accept an invalid PPS at the beginning when the stream
    +
    123  // does not necessarily start with an SPS/PPS/IDR.
    +
    124  // In this case, the initial frames are conveyed to the upper layer with
    +
    125  // an invalid VideoDecoderConfig and it's up to the upper layer
    +
    126  // to process this kind of frame accordingly.
    +
    127  return last_video_decoder_config_ == nullptr;
    +
    128  } else {
    +
    129  sps = h265_parser_->GetSps(pps->seq_parameter_set_id);
    +
    130  if (!sps)
    +
    131  return false;
    +
    132  decoder_config_check_pending_ = false;
    +
    133  }
    +
    134 
    +
    135  std::vector<uint8_t> decoder_config_record;
    +
    136  HEVCDecoderConfigurationRecord decoder_config;
    +
    137  if (!stream_converter()->GetDecoderConfigurationRecord(
    +
    138  &decoder_config_record) ||
    +
    139  !decoder_config.Parse(decoder_config_record)) {
    +
    140  DLOG(ERROR) << "Failure to construct an HEVCDecoderConfigurationRecord";
    +
    141  return false;
    +
    142  }
    +
    143 
    +
    144  if (last_video_decoder_config_) {
    +
    145  if (last_video_decoder_config_->codec_config() != decoder_config_record) {
    +
    146  // Video configuration has changed. Issue warning.
    +
    147  // TODO(tinskip): Check the nature of the configuration change. Only
    +
    148  // minor configuration changes (such as frame ordering) can be handled
    +
    149  // gracefully by decoders without notification. Major changes (such as
    +
    150  // video resolution changes) should be treated as errors.
    +
    151  LOG(WARNING) << "H.265 decoder configuration has changed.";
    +
    152  last_video_decoder_config_->set_codec_config(decoder_config_record);
    +
    153  }
    +
    154  return true;
    +
    155  }
    +
    156 
    +
    157  uint32_t coded_width = 0;
    +
    158  uint32_t coded_height = 0;
    +
    159  uint32_t pixel_width = 0;
    +
    160  uint32_t pixel_height = 0;
    +
    161  if (!ExtractResolutionFromSps(*sps, &coded_width, &coded_height, &pixel_width,
    +
    162  &pixel_height)) {
    +
    163  LOG(ERROR) << "Failed to parse SPS.";
    +
    164  return false;
    +
    165  }
    +
    166 
    +
    167  const uint8_t nalu_length_size =
    +
    168  H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize;
    +
    169  const H26xStreamFormat stream_format = stream_converter()->stream_format();
    +
    170  const FourCC codec_fourcc =
    +
    171  stream_format == H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    +
    172  ? FOURCC_hev1
    +
    173  : FOURCC_hvc1;
    +
    174  last_video_decoder_config_ = std::make_shared<VideoStreamInfo>(
    +
    175  pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH265, stream_format,
    +
    176  decoder_config.GetCodecString(codec_fourcc), decoder_config_record.data(),
    +
    177  decoder_config_record.size(), coded_width, coded_height, pixel_width,
    +
    178  pixel_height, sps->vui_parameters.transfer_characteristics, 0,
    +
    179  nalu_length_size, std::string(), false);
    +
    180 
    +
    181  // Video config notification.
    +
    182  new_stream_info_cb_.Run(last_video_decoder_config_);
    +
    183 
    +
    184  return true;
    +
    185 }
    +
    186 
    +
    187 } // namespace mp2t
    +
    188 } // namespace media
    +
    189 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/d55/simple__hls__notifier_8h_source.html b/docs/da/d55/simple__hls__notifier_8h_source.html index 5639cd9352..0cfafd9336 100644 --- a/docs/da/d55/simple__hls__notifier_8h_source.html +++ b/docs/da/d55/simple__hls__notifier_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/simple_hls_notifier.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    simple_hls_notifier.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
    8 #define PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
    9 
    10 #include <list>
    11 #include <map>
    12 #include <memory>
    13 #include <string>
    14 #include <vector>
    15 
    16 #include "packager/base/macros.h"
    17 #include "packager/base/synchronization/lock.h"
    18 #include "packager/hls/base/hls_notifier.h"
    19 #include "packager/hls/base/master_playlist.h"
    20 #include "packager/hls/base/media_playlist.h"
    21 #include "packager/hls/public/hls_params.h"
    22 
    23 namespace shaka {
    24 namespace hls {
    25 
    29  public:
    30  virtual ~MediaPlaylistFactory();
    31  virtual std::unique_ptr<MediaPlaylist> Create(const HlsParams& hls_params,
    32  const std::string& file_name,
    33  const std::string& name,
    34  const std::string& group_id);
    35 };
    36 
    39  public:
    41  explicit SimpleHlsNotifier(const HlsParams& hls_params);
    42  ~SimpleHlsNotifier() override;
    43 
    46  bool Init() override;
    47  bool NotifyNewStream(const MediaInfo& media_info,
    48  const std::string& playlist_name,
    49  const std::string& stream_name,
    50  const std::string& group_id,
    51  uint32_t* stream_id) override;
    52  bool NotifySampleDuration(uint32_t stream_id,
    53  uint32_t sample_duration) override;
    54  bool NotifyNewSegment(uint32_t stream_id,
    55  const std::string& segment_name,
    56  uint64_t start_time,
    57  uint64_t duration,
    58  uint64_t start_byte_offset,
    59  uint64_t size) override;
    60  bool NotifyKeyFrame(uint32_t stream_id,
    61  uint64_t timestamp,
    62  uint64_t start_byte_offset,
    63  uint64_t size) override;
    64  bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override;
    65  bool NotifyEncryptionUpdate(
    66  uint32_t stream_id,
    67  const std::vector<uint8_t>& key_id,
    68  const std::vector<uint8_t>& system_id,
    69  const std::vector<uint8_t>& iv,
    70  const std::vector<uint8_t>& protection_system_specific_data) override;
    71  bool Flush() override;
    73 
    74  private:
    75  friend class SimpleHlsNotifierTest;
    76 
    77  struct StreamEntry {
    78  std::unique_ptr<MediaPlaylist> media_playlist;
    79  MediaPlaylist::EncryptionMethod encryption_method;
    80  };
    81 
    82  std::string master_playlist_dir_;
    83  uint32_t target_duration_ = 0;
    84 
    85  std::unique_ptr<MediaPlaylistFactory> media_playlist_factory_;
    86  std::unique_ptr<MasterPlaylist> master_playlist_;
    87 
    88  // Maps to unique_ptr because StreamEntry also holds unique_ptr
    89  std::map<uint32_t, std::unique_ptr<StreamEntry>> stream_map_;
    90  std::list<MediaPlaylist*> media_playlists_;
    91 
    92  uint32_t sequence_number_ = 0;
    93 
    94  base::Lock lock_;
    95 
    96  DISALLOW_COPY_AND_ASSIGN(SimpleHlsNotifier);
    97 };
    98 
    99 } // namespace hls
    100 } // namespace shaka
    101 
    102 #endif // PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
    - -
    HLS related parameters.
    Definition: hls_params.h:23
    -
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
    +
    8 #define PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
    +
    9 
    +
    10 #include <list>
    +
    11 #include <map>
    +
    12 #include <memory>
    +
    13 #include <string>
    +
    14 #include <vector>
    +
    15 
    +
    16 #include "packager/base/macros.h"
    +
    17 #include "packager/base/synchronization/lock.h"
    +
    18 #include "packager/hls/base/hls_notifier.h"
    +
    19 #include "packager/hls/base/master_playlist.h"
    +
    20 #include "packager/hls/base/media_playlist.h"
    +
    21 #include "packager/hls/public/hls_params.h"
    +
    22 
    +
    23 namespace shaka {
    +
    24 namespace hls {
    +
    25 
    + +
    29  public:
    +
    30  virtual ~MediaPlaylistFactory();
    +
    31  virtual std::unique_ptr<MediaPlaylist> Create(const HlsParams& hls_params,
    +
    32  const std::string& file_name,
    +
    33  const std::string& name,
    +
    34  const std::string& group_id);
    +
    35 };
    +
    36 
    + +
    39  public:
    +
    41  explicit SimpleHlsNotifier(const HlsParams& hls_params);
    +
    42  ~SimpleHlsNotifier() override;
    +
    43 
    +
    46  bool Init() override;
    +
    47  bool NotifyNewStream(const MediaInfo& media_info,
    +
    48  const std::string& playlist_name,
    +
    49  const std::string& stream_name,
    +
    50  const std::string& group_id,
    +
    51  uint32_t* stream_id) override;
    +
    52  bool NotifySampleDuration(uint32_t stream_id,
    +
    53  uint32_t sample_duration) override;
    +
    54  bool NotifyNewSegment(uint32_t stream_id,
    +
    55  const std::string& segment_name,
    +
    56  uint64_t start_time,
    +
    57  uint64_t duration,
    +
    58  uint64_t start_byte_offset,
    +
    59  uint64_t size) override;
    +
    60  bool NotifyKeyFrame(uint32_t stream_id,
    +
    61  uint64_t timestamp,
    +
    62  uint64_t start_byte_offset,
    +
    63  uint64_t size) override;
    +
    64  bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override;
    + +
    66  uint32_t stream_id,
    +
    67  const std::vector<uint8_t>& key_id,
    +
    68  const std::vector<uint8_t>& system_id,
    +
    69  const std::vector<uint8_t>& iv,
    +
    70  const std::vector<uint8_t>& protection_system_specific_data) override;
    +
    71  bool Flush() override;
    +
    73 
    +
    74  private:
    +
    75  friend class SimpleHlsNotifierTest;
    +
    76 
    +
    77  struct StreamEntry {
    +
    78  std::unique_ptr<MediaPlaylist> media_playlist;
    +
    79  MediaPlaylist::EncryptionMethod encryption_method;
    +
    80  };
    +
    81 
    +
    82  std::string master_playlist_dir_;
    +
    83  uint32_t target_duration_ = 0;
    +
    84 
    +
    85  std::unique_ptr<MediaPlaylistFactory> media_playlist_factory_;
    +
    86  std::unique_ptr<MasterPlaylist> master_playlist_;
    +
    87 
    +
    88  // Maps to unique_ptr because StreamEntry also holds unique_ptr
    +
    89  std::map<uint32_t, std::unique_ptr<StreamEntry>> stream_map_;
    +
    90  std::list<MediaPlaylist*> media_playlists_;
    +
    91 
    +
    92  uint32_t sequence_number_ = 0;
    +
    93 
    +
    94  base::Lock lock_;
    +
    95 
    +
    96  DISALLOW_COPY_AND_ASSIGN(SimpleHlsNotifier);
    +
    97 };
    +
    98 
    +
    99 } // namespace hls
    +
    100 } // namespace shaka
    +
    101 
    +
    102 #endif // PACKAGER_HLS_BASE_SIMPLE_HLS_NOTIFIER_H_
    + +
    const HlsParams & hls_params() const
    Definition: hls_notifier.h:104
    + + + +
    bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp) override
    +
    SimpleHlsNotifier(const HlsParams &hls_params)
    +
    bool NotifyKeyFrame(uint32_t stream_id, uint64_t timestamp, uint64_t start_byte_offset, uint64_t size) override
    + +
    bool NotifyNewStream(const MediaInfo &media_info, const std::string &playlist_name, const std::string &stream_name, const std::string &group_id, uint32_t *stream_id) override
    + +
    bool NotifySampleDuration(uint32_t stream_id, uint32_t sample_duration) override
    +
    bool NotifyEncryptionUpdate(uint32_t stream_id, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &system_id, const std::vector< uint8_t > &iv, const std::vector< uint8_t > &protection_system_specific_data) override
    +
    bool NotifyNewSegment(uint32_t stream_id, const std::string &segment_name, uint64_t start_time, uint64_t duration, uint64_t start_byte_offset, uint64_t size) override
    +
    All the methods that are virtual are virtual for mocking.
    +
    HLS related parameters.
    Definition: hls_params.h:23
    diff --git a/docs/da/d59/structshaka_1_1media_1_1mp4_1_1CompactSampleSize.html b/docs/da/d59/structshaka_1_1media_1_1mp4_1_1CompactSampleSize.html index 9e2d3a2dc1..a6c7dcb0d8 100644 --- a/docs/da/d59/structshaka_1_1media_1_1mp4_1_1CompactSampleSize.html +++ b/docs/da/d59/structshaka_1_1media_1_1mp4_1_1CompactSampleSize.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CompactSampleSize Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -124,7 +127,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 470 of file box_definitions.h.

    +

    Definition at line 483 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -152,7 +155,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 819 of file box_definitions.cc.

    +

    Definition at line 832 of file box_definitions.cc.

    @@ -163,9 +166,7 @@ Additional Inherited Members diff --git a/docs/da/d5c/widevine__key__source_8h_source.html b/docs/da/d5c/widevine__key__source_8h_source.html index 221b4fc2d1..d5a5fbb4c2 100644 --- a/docs/da/d5c/widevine__key__source_8h_source.html +++ b/docs/da/d5c/widevine__key__source_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/widevine_key_source.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    widevine_key_source.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_WIDEVINE_KEY_SOURCE_H_
    8 #define PACKAGER_MEDIA_BASE_WIDEVINE_KEY_SOURCE_H_
    9 
    10 #include <map>
    11 #include <memory>
    12 #include "packager/base/synchronization/waitable_event.h"
    13 #include "packager/media/base/closure_thread.h"
    14 #include "packager/media/base/fourccs.h"
    15 #include "packager/media/base/key_source.h"
    16 
    17 namespace shaka {
    18 
    19 class CommonEncryptionRequest;
    20 
    21 namespace media {
    22 
    23 class KeyFetcher;
    24 class RequestSigner;
    25 template <class T> class ProducerConsumerQueue;
    26 
    29 class WidevineKeySource : public KeySource {
    30  public:
    37  WidevineKeySource(const std::string& server_url,
    38  int protection_systems_flags,
    39  FourCC protection_scheme);
    40 
    41  ~WidevineKeySource() override;
    42 
    45  Status FetchKeys(EmeInitDataType init_data_type,
    46  const std::vector<uint8_t>& init_data) override;
    47  Status GetKey(const std::string& stream_label, EncryptionKey* key) override;
    48  Status GetKey(const std::vector<uint8_t>& key_id,
    49  EncryptionKey* key) override;
    50  Status GetCryptoPeriodKey(uint32_t crypto_period_index,
    51  uint32_t crypto_period_duration_in_seconds,
    52  const std::string& stream_label,
    53  EncryptionKey* key) override;
    55 
    60  Status FetchKeys(const std::vector<uint8_t>& content_id,
    61  const std::string& policy);
    62 
    65  void set_signer(std::unique_ptr<RequestSigner> signer);
    66 
    69  void set_key_fetcher(std::unique_ptr<KeyFetcher> key_fetcher);
    70 
    71  void set_group_id(const std::vector<uint8_t>& group_id) {
    72  group_id_ = group_id;
    73  }
    74  void set_enable_entitlement_license(bool enable_entitlement_license) {
    75  enable_entitlement_license_ = enable_entitlement_license;
    76  }
    77 
    78  private:
    81 
    82  // Internal routine for getting keys.
    83  Status GetKeyInternal(uint32_t crypto_period_index,
    84  const std::string& stream_label,
    85  EncryptionKey* key);
    86 
    87  // The closure task to fetch keys repeatedly.
    88  void FetchKeysTask();
    89 
    90  // Fetch keys from server.
    91  Status FetchKeysInternal(bool enable_key_rotation,
    92  uint32_t first_crypto_period_index,
    93  bool widevine_classic);
    94 
    95  // Fill |request| with necessary fields for Widevine encryption request.
    96  // |request| should not be NULL.
    97  void FillRequest(bool enable_key_rotation,
    98  uint32_t first_crypto_period_index,
    99  CommonEncryptionRequest* request);
    100  // Get request in JSON string. Optionally sign the request if a signer is
    101  // provided. |message| should not be NULL. Return OK on success.
    102  Status GenerateKeyMessage(const CommonEncryptionRequest& request,
    103  std::string* message);
    104  // Extract encryption key from |response|, which is expected to be properly
    105  // formatted. |transient_error| will be set to true if it fails and the
    106  // failure is because of a transient error from the server. |transient_error|
    107  // should not be NULL.
    108  bool ExtractEncryptionKey(bool enable_key_rotation,
    109  bool widevine_classic,
    110  const std::string& response,
    111  bool* transient_error);
    112  // Push the keys to the key pool.
    113  bool PushToKeyPool(EncryptionKeyMap* encryption_key_map);
    114 
    115  // Indicates whether Widevine protection system should be generated.
    116  bool generate_widevine_protection_system_ = true;
    117 
    118  ClosureThread key_production_thread_;
    119  // The fetcher object used to fetch keys from the license service.
    120  // It is initialized to a default fetcher on class initialization.
    121  // Can be overridden using set_key_fetcher for testing or other purposes.
    122  std::unique_ptr<KeyFetcher> key_fetcher_;
    123  std::string server_url_;
    124  std::unique_ptr<RequestSigner> signer_;
    125  std::unique_ptr<CommonEncryptionRequest> common_encryption_request_;
    126 
    127  const int crypto_period_count_;
    128  FourCC protection_scheme_ = FOURCC_NULL;
    129  base::Lock lock_;
    130  bool key_production_started_ = false;
    131  base::WaitableEvent start_key_production_;
    132  uint32_t first_crypto_period_index_ = 0;
    133  uint32_t crypto_period_duration_in_seconds_ = 0;
    134  std::vector<uint8_t> group_id_;
    135  bool enable_entitlement_license_ = false;
    136  std::unique_ptr<EncryptionKeyQueue> key_pool_;
    137  EncryptionKeyMap encryption_key_map_; // For non key rotation request.
    138  Status common_encryption_request_status_;
    139 
    140  DISALLOW_COPY_AND_ASSIGN(WidevineKeySource);
    141 };
    142 
    143 } // namespace media
    144 } // namespace shaka
    145 
    146 #endif // PACKAGER_MEDIA_BASE_WIDEVINE_KEY_SOURCE_H_
    All the methods that are virtual are virtual for mocking.
    - - - - -
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    -
    void set_key_fetcher(std::unique_ptr< KeyFetcher > key_fetcher)
    -
    WidevineKeySource(const std::string &server_url, int protection_systems_flags, FourCC protection_scheme)
    - -
    void set_signer(std::unique_ptr< RequestSigner > signer)
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    -
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_WIDEVINE_KEY_SOURCE_H_
    +
    8 #define PACKAGER_MEDIA_BASE_WIDEVINE_KEY_SOURCE_H_
    +
    9 
    +
    10 #include <map>
    +
    11 #include <memory>
    +
    12 #include "packager/base/synchronization/waitable_event.h"
    +
    13 #include "packager/media/base/closure_thread.h"
    +
    14 #include "packager/media/base/fourccs.h"
    +
    15 #include "packager/media/base/key_source.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 
    +
    19 class CommonEncryptionRequest;
    +
    20 
    +
    21 namespace media {
    +
    22 
    +
    23 class KeyFetcher;
    +
    24 class RequestSigner;
    +
    25 template <class T> class ProducerConsumerQueue;
    +
    26 
    +
    29 class WidevineKeySource : public KeySource {
    +
    30  public:
    +
    37  WidevineKeySource(const std::string& server_url,
    +
    38  ProtectionSystem protection_systems,
    +
    39  FourCC protection_scheme);
    +
    40 
    +
    41  ~WidevineKeySource() override;
    +
    42 
    +
    45  Status FetchKeys(EmeInitDataType init_data_type,
    +
    46  const std::vector<uint8_t>& init_data) override;
    +
    47  Status GetKey(const std::string& stream_label, EncryptionKey* key) override;
    +
    48  Status GetKey(const std::vector<uint8_t>& key_id,
    +
    49  EncryptionKey* key) override;
    +
    50  Status GetCryptoPeriodKey(uint32_t crypto_period_index,
    +
    51  uint32_t crypto_period_duration_in_seconds,
    +
    52  const std::string& stream_label,
    +
    53  EncryptionKey* key) override;
    +
    55 
    +
    60  Status FetchKeys(const std::vector<uint8_t>& content_id,
    +
    61  const std::string& policy);
    +
    62 
    +
    65  void set_signer(std::unique_ptr<RequestSigner> signer);
    +
    66 
    +
    69  void set_key_fetcher(std::unique_ptr<KeyFetcher> key_fetcher);
    +
    70 
    +
    71  void set_group_id(const std::vector<uint8_t>& group_id) {
    +
    72  group_id_ = group_id;
    +
    73  }
    +
    74  void set_enable_entitlement_license(bool enable_entitlement_license) {
    +
    75  enable_entitlement_license_ = enable_entitlement_license;
    +
    76  }
    +
    77 
    +
    78  private:
    + + +
    81 
    +
    82  // Internal routine for getting keys.
    +
    83  Status GetKeyInternal(uint32_t crypto_period_index,
    +
    84  const std::string& stream_label,
    +
    85  EncryptionKey* key);
    +
    86 
    +
    87  // The closure task to fetch keys repeatedly.
    +
    88  void FetchKeysTask();
    +
    89 
    +
    90  // Fetch keys from server.
    +
    91  Status FetchKeysInternal(bool enable_key_rotation,
    +
    92  uint32_t first_crypto_period_index,
    +
    93  bool widevine_classic);
    +
    94 
    +
    95  // Fill |request| with necessary fields for Widevine encryption request.
    +
    96  // |request| should not be NULL.
    +
    97  void FillRequest(bool enable_key_rotation,
    +
    98  uint32_t first_crypto_period_index,
    +
    99  CommonEncryptionRequest* request);
    +
    100  // Get request in JSON string. Optionally sign the request if a signer is
    +
    101  // provided. |message| should not be NULL. Return OK on success.
    +
    102  Status GenerateKeyMessage(const CommonEncryptionRequest& request,
    +
    103  std::string* message);
    +
    104  // Extract encryption key from |response|, which is expected to be properly
    +
    105  // formatted. |transient_error| will be set to true if it fails and the
    +
    106  // failure is because of a transient error from the server. |transient_error|
    +
    107  // should not be NULL.
    +
    108  bool ExtractEncryptionKey(bool enable_key_rotation,
    +
    109  bool widevine_classic,
    +
    110  const std::string& response,
    +
    111  bool* transient_error);
    +
    112  // Push the keys to the key pool.
    +
    113  bool PushToKeyPool(EncryptionKeyMap* encryption_key_map);
    +
    114 
    +
    115  // Indicates whether Widevine protection system should be generated.
    +
    116  bool generate_widevine_protection_system_ = true;
    +
    117 
    +
    118  ClosureThread key_production_thread_;
    +
    119  // The fetcher object used to fetch keys from the license service.
    +
    120  // It is initialized to a default fetcher on class initialization.
    +
    121  // Can be overridden using set_key_fetcher for testing or other purposes.
    +
    122  std::unique_ptr<KeyFetcher> key_fetcher_;
    +
    123  std::string server_url_;
    +
    124  std::unique_ptr<RequestSigner> signer_;
    +
    125  std::unique_ptr<CommonEncryptionRequest> common_encryption_request_;
    +
    126 
    +
    127  const int crypto_period_count_;
    +
    128  FourCC protection_scheme_ = FOURCC_NULL;
    +
    129  base::Lock lock_;
    +
    130  bool key_production_started_ = false;
    +
    131  base::WaitableEvent start_key_production_;
    +
    132  uint32_t first_crypto_period_index_ = 0;
    +
    133  uint32_t crypto_period_duration_in_seconds_ = 0;
    +
    134  std::vector<uint8_t> group_id_;
    +
    135  bool enable_entitlement_license_ = false;
    +
    136  std::unique_ptr<EncryptionKeyQueue> key_pool_;
    +
    137  EncryptionKeyMap encryption_key_map_; // For non key rotation request.
    +
    138  Status common_encryption_request_status_;
    +
    139 
    +
    140  DISALLOW_COPY_AND_ASSIGN(WidevineKeySource);
    +
    141 };
    +
    142 
    +
    143 } // namespace media
    +
    144 } // namespace shaka
    +
    145 
    +
    146 #endif // PACKAGER_MEDIA_BASE_WIDEVINE_KEY_SOURCE_H_
    + + +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    + + +
    void set_signer(std::unique_ptr< RequestSigner > signer)
    +
    void set_key_fetcher(std::unique_ptr< KeyFetcher > key_fetcher)
    +
    WidevineKeySource(const std::string &server_url, ProtectionSystem protection_systems, FourCC protection_scheme)
    +
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    +
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    +
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    +
    All the methods that are virtual are virtual for mocking.
    +
    ProtectionSystem
    Definition: crypto_params.h:31
    +
    diff --git a/docs/da/d5e/classshaka_1_1media_1_1H264VideoSliceHeaderParser-members.html b/docs/da/d5e/classshaka_1_1media_1_1H264VideoSliceHeaderParser-members.html index 6fd8754efc..6b4426ff13 100644 --- a/docs/da/d5e/classshaka_1_1media_1_1H264VideoSliceHeaderParser-members.html +++ b/docs/da/d5e/classshaka_1_1media_1_1H264VideoSliceHeaderParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/da/d60/classshaka_1_1media_1_1mp4_1_1SingleSegmentSegmenter-members.html b/docs/da/d60/classshaka_1_1media_1_1mp4_1_1SingleSegmentSegmenter-members.html index 3db9f50758..3bf5972cb4 100644 --- a/docs/da/d60/classshaka_1_1media_1_1mp4_1_1SingleSegmentSegmenter-members.html +++ b/docs/da/d60/classshaka_1_1media_1_1mp4_1_1SingleSegmentSegmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/d6a/classshaka_1_1media_1_1mp2t_1_1VideoProgramMapTableWriter.html b/docs/da/d6a/classshaka_1_1media_1_1mp2t_1_1VideoProgramMapTableWriter.html index 3b7a5ff9e5..fe27bc0d1c 100644 --- a/docs/da/d6a/classshaka_1_1media_1_1mp2t_1_1VideoProgramMapTableWriter.html +++ b/docs/da/d6a/classshaka_1_1media_1_1mp2t_1_1VideoProgramMapTableWriter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::VideoProgramMapTableWriter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -

    ProgramMapTableWriter for video codecs. +

    ProgramMapTableWriter for video codecs. More...

    #include <program_map_table_writer.h>

    @@ -80,9 +83,9 @@ Inheritance diagram for shaka::media::mp2t::VideoProgramMapTableWriter:
    -shaka::media::mp2t::ProgramMapTableWriter - -
    +shaka::media::mp2t::ProgramMapTableWriter + + @@ -116,7 +119,7 @@ static const uint8_t 

    Public Member Functions

    kElem
     

    Detailed Description

    -

    ProgramMapTableWriter for video codecs.

    +

    ProgramMapTableWriter for video codecs.

    Definition at line 65 of file program_map_table_writer.h.


    The documentation for this class was generated from the following files:
      @@ -126,9 +129,7 @@ static const uint8_t kElem
    diff --git a/docs/da/d6e/structshaka_1_1media_1_1mp4_1_1AudioRollRecoveryEntry.html b/docs/da/d6e/structshaka_1_1media_1_1mp4_1_1AudioRollRecoveryEntry.html index e78e4fac8c..25e9fa15af 100644 --- a/docs/da/d6e/structshaka_1_1media_1_1mp4_1_1AudioRollRecoveryEntry.html +++ b/docs/da/d6e/structshaka_1_1media_1_1mp4_1_1AudioRollRecoveryEntry.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::AudioRollRecoveryEntry Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    roll_distance

    Detailed Description

    -

    Definition at line 512 of file box_definitions.h.

    +

    Definition at line 525 of file box_definitions.h.


    The documentation for this struct was generated from the following files:
    diff --git a/docs/da/d79/structshaka_1_1media_1_1AV1Parser_1_1Tile-members.html b/docs/da/d79/structshaka_1_1media_1_1AV1Parser_1_1Tile-members.html index 7142dcc6bc..1b56e85494 100644 --- a/docs/da/d79/structshaka_1_1media_1_1AV1Parser_1_1Tile-members.html +++ b/docs/da/d79/structshaka_1_1media_1_1AV1Parser_1_1Tile-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/d85/classshaka_1_1media_1_1mp2t_1_1TsSegmenter-members.html b/docs/da/d85/classshaka_1_1media_1_1mp2t_1_1TsSegmenter-members.html index 783b9a11c0..a3d87c110e 100644 --- a/docs/da/d85/classshaka_1_1media_1_1mp2t_1_1TsSegmenter-members.html +++ b/docs/da/d85/classshaka_1_1media_1_1mp2t_1_1TsSegmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */ diff --git a/docs/da/d88/mp4__muxer_8cc_source.html b/docs/da/d88/mp4__muxer_8cc_source.html index 2f662ac1c0..7f344a197c 100644 --- a/docs/da/d88/mp4__muxer_8cc_source.html +++ b/docs/da/d88/mp4__muxer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/mp4_muxer.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    mp4_muxer.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp4/mp4_muxer.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/base/strings/string_number_conversions.h"
    12 #include "packager/base/time/clock.h"
    13 #include "packager/base/time/time.h"
    14 #include "packager/file/file.h"
    15 #include "packager/media/base/aes_encryptor.h"
    16 #include "packager/media/base/audio_stream_info.h"
    17 #include "packager/media/base/fourccs.h"
    18 #include "packager/media/base/key_source.h"
    19 #include "packager/media/base/media_sample.h"
    20 #include "packager/media/base/text_stream_info.h"
    21 #include "packager/media/base/video_stream_info.h"
    22 #include "packager/media/codecs/es_descriptor.h"
    23 #include "packager/media/event/muxer_listener.h"
    24 #include "packager/media/formats/mp4/box_definitions.h"
    25 #include "packager/media/formats/mp4/multi_segment_segmenter.h"
    26 #include "packager/media/formats/mp4/single_segment_segmenter.h"
    27 #include "packager/status_macros.h"
    28 
    29 namespace shaka {
    30 namespace media {
    31 namespace mp4 {
    32 
    33 namespace {
    34 
    35 // Sets the range start and end value from offset and size.
    36 // |start| and |end| are for byte-range-spec specified in RFC2616.
    37 void SetStartAndEndFromOffsetAndSize(size_t offset,
    38  size_t size,
    39  Range* range) {
    40  DCHECK(range);
    41  range->start = static_cast<uint32_t>(offset);
    42  // Note that ranges are inclusive. So we need - 1.
    43  range->end = range->start + static_cast<uint32_t>(size) - 1;
    44 }
    45 
    46 FourCC CodecToFourCC(Codec codec, H26xStreamFormat h26x_stream_format) {
    47  switch (codec) {
    48  case kCodecAV1:
    49  return FOURCC_av01;
    50  case kCodecH264:
    51  return h26x_stream_format ==
    52  H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    53  ? FOURCC_avc3
    54  : FOURCC_avc1;
    55  case kCodecH265:
    56  return h26x_stream_format ==
    57  H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    58  ? FOURCC_hev1
    59  : FOURCC_hvc1;
    60  case kCodecH265DolbyVision:
    61  return h26x_stream_format ==
    62  H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    63  ? FOURCC_dvhe
    64  : FOURCC_dvh1;
    65  case kCodecVP8:
    66  return FOURCC_vp08;
    67  case kCodecVP9:
    68  return FOURCC_vp09;
    69  case kCodecAAC:
    70  return FOURCC_mp4a;
    71  case kCodecAC3:
    72  return FOURCC_ac_3;
    73  case kCodecDTSC:
    74  return FOURCC_dtsc;
    75  case kCodecDTSH:
    76  return FOURCC_dtsh;
    77  case kCodecDTSL:
    78  return FOURCC_dtsl;
    79  case kCodecDTSE:
    80  return FOURCC_dtse;
    81  case kCodecDTSM:
    82  return FOURCC_dtsm;
    83  case kCodecEAC3:
    84  return FOURCC_ec_3;
    85  case kCodecFlac:
    86  return FOURCC_fLaC;
    87  case kCodecOpus:
    88  return FOURCC_Opus;
    89  default:
    90  return FOURCC_NULL;
    91  }
    92 }
    93 
    94 void GenerateSinf(FourCC old_type,
    95  const EncryptionConfig& encryption_config,
    96  ProtectionSchemeInfo* sinf) {
    97  sinf->format.format = old_type;
    98 
    99  DCHECK_NE(encryption_config.protection_scheme, FOURCC_NULL);
    100  sinf->type.type = encryption_config.protection_scheme;
    101 
    102  // The version of cenc implemented here. CENC 4.
    103  const int kCencSchemeVersion = 0x00010000;
    104  sinf->type.version = kCencSchemeVersion;
    105 
    106  auto& track_encryption = sinf->info.track_encryption;
    107  track_encryption.default_is_protected = 1;
    108 
    109  track_encryption.default_crypt_byte_block =
    110  encryption_config.crypt_byte_block;
    111  track_encryption.default_skip_byte_block = encryption_config.skip_byte_block;
    112  switch (encryption_config.protection_scheme) {
    113  case FOURCC_cenc:
    114  case FOURCC_cbc1:
    115  DCHECK_EQ(track_encryption.default_crypt_byte_block, 0u);
    116  DCHECK_EQ(track_encryption.default_skip_byte_block, 0u);
    117  // CENCv3 10.1 ‘cenc’ AES-CTR scheme and 10.2 ‘cbc1’ AES-CBC scheme:
    118  // The version of the Track Encryption Box (‘tenc’) SHALL be 0.
    119  track_encryption.version = 0;
    120  break;
    121  case FOURCC_cbcs:
    122  case FOURCC_cens:
    123  // CENCv3 10.3 ‘cens’ AES-CTR subsample pattern encryption scheme and
    124  // 10.4 ‘cbcs’ AES-CBC subsample pattern encryption scheme:
    125  // The version of the Track Encryption Box (‘tenc’) SHALL be 1.
    126  track_encryption.version = 1;
    127  break;
    128  default:
    129  NOTREACHED() << "Unexpected protection scheme "
    130  << encryption_config.protection_scheme;
    131  }
    132 
    133  track_encryption.default_per_sample_iv_size =
    134  encryption_config.per_sample_iv_size;
    135  track_encryption.default_constant_iv = encryption_config.constant_iv;
    136  track_encryption.default_kid = encryption_config.key_id;
    137 }
    138 
    139 // The roll distance is expressed in sample units and always takes negative
    140 // values.
    141 int16_t GetRollDistance(uint64_t seek_preroll_ns, uint32_t sampling_frequency) {
    142  const double kNanosecondsPerSecond = 1000000000;
    143  const double preroll_in_samples =
    144  seek_preroll_ns / kNanosecondsPerSecond * sampling_frequency;
    145  // Round to closest integer.
    146  return -static_cast<int16_t>(preroll_in_samples + 0.5);
    147 }
    148 
    149 } // namespace
    150 
    151 MP4Muxer::MP4Muxer(const MuxerOptions& options) : Muxer(options) {}
    152 MP4Muxer::~MP4Muxer() {}
    153 
    154 Status MP4Muxer::InitializeMuxer() {
    155  // Muxer will be delay-initialized after seeing the first sample.
    156  to_be_initialized_ = true;
    157  return Status::OK;
    158 }
    159 
    160 Status MP4Muxer::Finalize() {
    161  // This happens on streams that are not initialized, i.e. not going through
    162  // DelayInitializeMuxer, which can only happen if there are no samples from
    163  // the stream.
    164  if (!segmenter_) {
    165  DCHECK(to_be_initialized_);
    166  LOG(INFO) << "Skip stream '" << options().output_file_name
    167  << "' which does not contain any sample.";
    168  return Status::OK;
    169  }
    170 
    171  Status segmenter_finalized = segmenter_->Finalize();
    172 
    173  if (!segmenter_finalized.ok())
    174  return segmenter_finalized;
    175 
    176  FireOnMediaEndEvent();
    177  LOG(INFO) << "MP4 file '" << options().output_file_name << "' finalized.";
    178  return Status::OK;
    179 }
    180 
    181 Status MP4Muxer::AddSample(size_t stream_id, const MediaSample& sample) {
    182  if (to_be_initialized_) {
    183  RETURN_IF_ERROR(UpdateEditListOffsetFromSample(sample));
    184  RETURN_IF_ERROR(DelayInitializeMuxer());
    185  to_be_initialized_ = false;
    186  }
    187  DCHECK(segmenter_);
    188  return segmenter_->AddSample(stream_id, sample);
    189 }
    190 
    191 Status MP4Muxer::FinalizeSegment(size_t stream_id,
    192  const SegmentInfo& segment_info) {
    193  DCHECK(segmenter_);
    194  VLOG(3) << "Finalizing " << (segment_info.is_subsegment ? "sub" : "")
    195  << "segment " << segment_info.start_timestamp << " duration "
    196  << segment_info.duration;
    197  return segmenter_->FinalizeSegment(stream_id, segment_info);
    198 }
    199 
    200 Status MP4Muxer::DelayInitializeMuxer() {
    201  DCHECK(!streams().empty());
    202 
    203  std::unique_ptr<FileType> ftyp(new FileType);
    204  std::unique_ptr<Movie> moov(new Movie);
    205 
    206  ftyp->major_brand = FOURCC_isom;
    207  ftyp->compatible_brands.push_back(FOURCC_iso8);
    208  ftyp->compatible_brands.push_back(FOURCC_mp41);
    209  ftyp->compatible_brands.push_back(FOURCC_dash);
    210 
    211  if (streams().size() == 1) {
    212  FourCC codec_fourcc = FOURCC_NULL;
    213  if (streams()[0]->stream_type() == kStreamVideo) {
    214  codec_fourcc =
    215  CodecToFourCC(streams()[0]->codec(),
    216  static_cast<const VideoStreamInfo*>(streams()[0].get())
    217  ->h26x_stream_format());
    218  if (codec_fourcc != FOURCC_NULL)
    219  ftyp->compatible_brands.push_back(codec_fourcc);
    220  }
    221 
    222  // CMAF allows only one track/stream per file.
    223  // CMAF requires single initialization switching for AVC3/HEV1, which is not
    224  // supported yet.
    225  if (codec_fourcc != FOURCC_avc3 && codec_fourcc != FOURCC_hev1)
    226  ftyp->compatible_brands.push_back(FOURCC_cmfc);
    227  }
    228 
    229  moov->header.creation_time = IsoTimeNow();
    230  moov->header.modification_time = IsoTimeNow();
    231  moov->header.next_track_id = static_cast<uint32_t>(streams().size()) + 1;
    232 
    233  moov->tracks.resize(streams().size());
    234  moov->extends.tracks.resize(streams().size());
    235 
    236  // Initialize tracks.
    237  for (uint32_t i = 0; i < streams().size(); ++i) {
    238  const StreamInfo* stream = streams()[i].get();
    239  Track& trak = moov->tracks[i];
    240  trak.header.track_id = i + 1;
    241 
    242  TrackExtends& trex = moov->extends.tracks[i];
    243  trex.track_id = trak.header.track_id;
    244  trex.default_sample_description_index = 1;
    245 
    246  bool generate_trak_result = false;
    247  switch (stream->stream_type()) {
    248  case kStreamVideo:
    249  generate_trak_result = GenerateVideoTrak(
    250  static_cast<const VideoStreamInfo*>(stream), &trak, i + 1);
    251  break;
    252  case kStreamAudio:
    253  generate_trak_result = GenerateAudioTrak(
    254  static_cast<const AudioStreamInfo*>(stream), &trak, i + 1);
    255  break;
    256  case kStreamText:
    257  generate_trak_result = GenerateTextTrak(
    258  static_cast<const TextStreamInfo*>(stream), &trak, i + 1);
    259  break;
    260  default:
    261  NOTIMPLEMENTED() << "Not implemented for stream type: "
    262  << stream->stream_type();
    263  }
    264  if (!generate_trak_result)
    265  return Status(error::MUXER_FAILURE, "Failed to generate trak.");
    266 
    267  // Generate EditList if needed. See UpdateEditListOffsetFromSample() for
    268  // more information.
    269  if (edit_list_offset_.value() > 0) {
    270  EditListEntry entry;
    271  entry.media_time = edit_list_offset_.value();
    272  entry.media_rate_integer = 1;
    273  trak.edit.list.edits.push_back(entry);
    274  }
    275 
    276  if (stream->is_encrypted() && options().mp4_params.include_pssh_in_stream) {
    277  moov->pssh.clear();
    278  const auto& key_system_info = stream->encryption_config().key_system_info;
    279  for (const ProtectionSystemSpecificInfo& system : key_system_info) {
    280  if (system.psshs.empty())
    281  continue;
    283  pssh.raw_box = system.psshs;
    284  moov->pssh.push_back(pssh);
    285  }
    286  }
    287  }
    288 
    289  if (options().segment_template.empty()) {
    290  segmenter_.reset(new SingleSegmentSegmenter(options(), std::move(ftyp),
    291  std::move(moov)));
    292  } else {
    293  segmenter_.reset(
    294  new MultiSegmentSegmenter(options(), std::move(ftyp), std::move(moov)));
    295  }
    296 
    297  const Status segmenter_initialized =
    298  segmenter_->Initialize(streams(), muxer_listener(), progress_listener());
    299  if (!segmenter_initialized.ok())
    300  return segmenter_initialized;
    301 
    302  FireOnMediaStartEvent();
    303  return Status::OK;
    304 }
    305 
    306 Status MP4Muxer::UpdateEditListOffsetFromSample(const MediaSample& sample) {
    307  if (edit_list_offset_)
    308  return Status::OK;
    309 
    310  const int64_t pts = sample.pts();
    311  const int64_t dts = sample.dts();
    312  // An EditList entry is inserted if one of the below conditions occur [4]:
    313  // (1) pts > dts for the first sample. Due to Chrome's dts bug [1], dts is
    314  // used in buffered range API, while pts is used elsewhere (players,
    315  // manifests, and Chrome's own appendWindow check etc.), this
    316  // inconsistency creates various problems, including possible stalls
    317  // during playback. Since Chrome adjusts pts only when seeing EditList
    318  // [2], we can insert an EditList with the time equal to difference of pts
    319  // and dts to make aligned buffered ranges using pts and dts. This
    320  // effectively workarounds the dts bug. It is also recommended by ISO-BMFF
    321  // specification [3].
    322  // (2) pts == dts and with pts < 0. This happens for some audio codecs where a
    323  // negative presentation timestamp signals that the sample is not supposed
    324  // to be shown, i.e. for audio priming. EditList is needed to encode
    325  // negative timestamps.
    326  // [1] https://crbug.com/718641, fixed but behind MseBufferByPts, still not
    327  // enabled as of M67.
    328  // [2] This is actually a bug, see https://crbug.com/354518. It looks like
    329  // Chrome is planning to enable the fix for [1] before addressing this
    330  // bug, so we are safe.
    331  // [3] ISO 14496-12:2015 8.6.6.1
    332  // It is recommended that such an edit be used to establish a presentation
    333  // time of 0 for the first presented sample, when composition offsets are
    334  // used.
    335  // [4] ISO 23009-19:2018 7.5.13
    336  // In two cases, an EditBox containing a single EditListBox with the
    337  // following constraints may be present in the CMAF header of a CMAF track
    338  // to adjust the presentation time of all media samples in the CMAF track.
    339  // a) The first case is a video CMAF track file using v0 TrackRunBoxes
    340  // with positive composition offsets to reorder video media samples.
    341  // b) The second case is an audio CMAF track where each media sample's
    342  // presentation time does not equal its composition time.
    343  const int64_t pts_dts_offset = pts - dts;
    344  if (pts_dts_offset > 0) {
    345  if (pts < 0) {
    346  LOG(ERROR) << "Negative presentation timestamp (" << pts
    347  << ") is not supported when there is an offset between "
    348  "presentation timestamp and decoding timestamp ("
    349  << dts << ").";
    350  return Status(error::MUXER_FAILURE,
    351  "Unsupported negative pts when there is an offset between "
    352  "pts and dts.");
    353  }
    354  edit_list_offset_ = pts_dts_offset;
    355  return Status::OK;
    356  }
    357  if (pts_dts_offset < 0) {
    358  LOG(ERROR) << "presentation timestamp (" << pts
    359  << ") is not supposed to be greater than decoding timestamp ("
    360  << dts << ").";
    361  return Status(error::MUXER_FAILURE, "Not expecting pts < dts.");
    362  }
    363  edit_list_offset_ = std::max(-sample.pts(), static_cast<int64_t>(0));
    364  return Status::OK;
    365 }
    366 
    367 void MP4Muxer::InitializeTrak(const StreamInfo* info, Track* trak) {
    368  int64_t now = IsoTimeNow();
    369  trak->header.creation_time = now;
    370  trak->header.modification_time = now;
    371  trak->header.duration = 0;
    372  trak->media.header.creation_time = now;
    373  trak->media.header.modification_time = now;
    374  trak->media.header.timescale = info->time_scale();
    375  trak->media.header.duration = 0;
    376  if (!info->language().empty()) {
    377  // Strip off the subtag, if any.
    378  std::string main_language = info->language();
    379  size_t dash = main_language.find('-');
    380  if (dash != std::string::npos) {
    381  main_language.erase(dash);
    382  }
    383 
    384  // ISO-639-2/T main language code should be 3 characters.
    385  if (main_language.size() != 3) {
    386  LOG(WARNING) << "'" << main_language << "' is not a valid ISO-639-2 "
    387  << "language code, ignoring.";
    388  } else {
    389  trak->media.header.language.code = main_language;
    390  }
    391  }
    392 }
    393 
    394 bool MP4Muxer::GenerateVideoTrak(const VideoStreamInfo* video_info,
    395  Track* trak,
    396  uint32_t track_id) {
    397  InitializeTrak(video_info, trak);
    398 
    399  // width and height specify the track's visual presentation size as
    400  // fixed-point 16.16 values.
    401  uint32_t pixel_width = video_info->pixel_width();
    402  uint32_t pixel_height = video_info->pixel_height();
    403  if (pixel_width == 0 || pixel_height == 0) {
    404  LOG(WARNING) << "pixel width/height are not set. Assuming 1:1.";
    405  pixel_width = 1;
    406  pixel_height = 1;
    407  }
    408  const double sample_aspect_ratio =
    409  static_cast<double>(pixel_width) / pixel_height;
    410  trak->header.width = video_info->width() * sample_aspect_ratio * 0x10000;
    411  trak->header.height = video_info->height() * 0x10000;
    412 
    413  VideoSampleEntry video;
    414  video.format =
    415  CodecToFourCC(video_info->codec(), video_info->h26x_stream_format());
    416  video.width = video_info->width();
    417  video.height = video_info->height();
    418  video.codec_configuration.data = video_info->codec_config();
    419  if (!video.ParseExtraCodecConfigsVector(video_info->extra_config())) {
    420  LOG(ERROR) << "Malformed extra codec configs: "
    421  << base::HexEncode(video_info->extra_config().data(),
    422  video_info->extra_config().size());
    423  return false;
    424  }
    425  if (pixel_width != 1 || pixel_height != 1) {
    426  video.pixel_aspect.h_spacing = pixel_width;
    427  video.pixel_aspect.v_spacing = pixel_height;
    428  }
    429 
    430  SampleDescription& sample_description =
    431  trak->media.information.sample_table.description;
    432  sample_description.type = kVideo;
    433  sample_description.video_entries.push_back(video);
    434 
    435  if (video_info->is_encrypted()) {
    436  if (video_info->has_clear_lead()) {
    437  // Add a second entry for clear content.
    438  sample_description.video_entries.push_back(video);
    439  }
    440  // Convert the first entry to an encrypted entry.
    441  VideoSampleEntry& entry = sample_description.video_entries[0];
    442  GenerateSinf(entry.format, video_info->encryption_config(), &entry.sinf);
    443  entry.format = FOURCC_encv;
    444  }
    445  return true;
    446 }
    447 
    448 bool MP4Muxer::GenerateAudioTrak(const AudioStreamInfo* audio_info,
    449  Track* trak,
    450  uint32_t track_id) {
    451  InitializeTrak(audio_info, trak);
    452 
    453  trak->header.volume = 0x100;
    454 
    455  AudioSampleEntry audio;
    456  audio.format =
    457  CodecToFourCC(audio_info->codec(), H26xStreamFormat::kUnSpecified);
    458  switch(audio_info->codec()){
    459  case kCodecAAC: {
    460  audio.esds.es_descriptor.set_esid(track_id);
    461  DecoderConfigDescriptor* decoder_config =
    462  audio.esds.es_descriptor.mutable_decoder_config_descriptor();
    463  decoder_config->set_object_type(ObjectType::kISO_14496_3); // MPEG4 AAC.
    464  decoder_config->set_max_bitrate(audio_info->max_bitrate());
    465  decoder_config->set_avg_bitrate(audio_info->avg_bitrate());
    466  decoder_config->mutable_decoder_specific_info_descriptor()->set_data(
    467  audio_info->codec_config());
    468  break;
    469  }
    470  case kCodecDTSC:
    471  case kCodecDTSH:
    472  case kCodecDTSL:
    473  case kCodecDTSE:
    474  case kCodecDTSM:
    475  audio.ddts.extra_data = audio_info->codec_config();
    476  audio.ddts.max_bitrate = audio_info->max_bitrate();
    477  audio.ddts.avg_bitrate = audio_info->avg_bitrate();
    478  audio.ddts.sampling_frequency = audio_info->sampling_frequency();
    479  audio.ddts.pcm_sample_depth = audio_info->sample_bits();
    480  break;
    481  case kCodecAC3:
    482  audio.dac3.data = audio_info->codec_config();
    483  break;
    484  case kCodecEAC3:
    485  audio.dec3.data = audio_info->codec_config();
    486  break;
    487  case kCodecFlac:
    488  audio.dfla.data = audio_info->codec_config();
    489  break;
    490  case kCodecOpus:
    491  audio.dops.opus_identification_header = audio_info->codec_config();
    492  break;
    493  default:
    494  NOTIMPLEMENTED() << " Unsupported audio codec " << audio_info->codec();
    495  return false;
    496  }
    497 
    498  if (audio_info->codec() == kCodecAC3 || audio_info->codec() == kCodecEAC3) {
    499  // AC3 and EC3 does not fill in actual channel count and sample size in
    500  // sample description entry. Instead, two constants are used.
    501  audio.channelcount = 2;
    502  audio.samplesize = 16;
    503  } else {
    504  audio.channelcount = audio_info->num_channels();
    505  audio.samplesize = audio_info->sample_bits();
    506  }
    507  audio.samplerate = audio_info->sampling_frequency();
    508  SampleTable& sample_table = trak->media.information.sample_table;
    509  SampleDescription& sample_description = sample_table.description;
    510  sample_description.type = kAudio;
    511  sample_description.audio_entries.push_back(audio);
    512 
    513  if (audio_info->is_encrypted()) {
    514  if (audio_info->has_clear_lead()) {
    515  // Add a second entry for clear content.
    516  sample_description.audio_entries.push_back(audio);
    517  }
    518  // Convert the first entry to an encrypted entry.
    519  AudioSampleEntry& entry = sample_description.audio_entries[0];
    520  GenerateSinf(entry.format, audio_info->encryption_config(), &entry.sinf);
    521  entry.format = FOURCC_enca;
    522  }
    523 
    524  if (audio_info->seek_preroll_ns() > 0) {
    525  sample_table.sample_group_descriptions.resize(1);
    526  SampleGroupDescription& sample_group_description =
    527  sample_table.sample_group_descriptions.back();
    528  sample_group_description.grouping_type = FOURCC_roll;
    529  sample_group_description.audio_roll_recovery_entries.resize(1);
    530  sample_group_description.audio_roll_recovery_entries[0].roll_distance =
    531  GetRollDistance(audio_info->seek_preroll_ns(), audio.samplerate);
    532  // sample to group box is not allowed in the init segment per CMAF
    533  // specification. It is put in the fragment instead.
    534  }
    535  return true;
    536 }
    537 
    538 bool MP4Muxer::GenerateTextTrak(const TextStreamInfo* text_info,
    539  Track* trak,
    540  uint32_t track_id) {
    541  InitializeTrak(text_info, trak);
    542 
    543  if (text_info->codec_string() == "wvtt") {
    544  // Handle WebVTT.
    545  TextSampleEntry webvtt;
    546  webvtt.format = FOURCC_wvtt;
    547 
    548  // 14496-30:2014 7.5 Web Video Text Tracks Sample entry format.
    549  // In the sample entry, a WebVTT configuration box must occur, carrying
    550  // exactly the lines of the WebVTT file header, i.e. all text lines up to
    551  // but excluding the 'two or more line terminators' that end the header.
    552  webvtt.config.config = "WEBVTT";
    553  // The spec does not define a way to carry STYLE and REGION information in
    554  // the mp4 container.
    555  if (!text_info->codec_config().empty()) {
    556  LOG(INFO) << "Skipping possible style / region configuration as the spec "
    557  "does not define a way to carry them inside ISO-BMFF files.";
    558  }
    559 
    560  // TODO(rkuroiwa): This should be the source file URI(s). Putting bogus
    561  // string for now so that the box will be there for samples with overlapping
    562  // cues.
    563  webvtt.label.source_label = "source_label";
    564  SampleDescription& sample_description =
    565  trak->media.information.sample_table.description;
    566  sample_description.type = kText;
    567  sample_description.text_entries.push_back(webvtt);
    568  return true;
    569  }
    570  NOTIMPLEMENTED() << text_info->codec_string()
    571  << " handling not implemented yet.";
    572  return false;
    573 }
    574 
    575 base::Optional<Range> MP4Muxer::GetInitRangeStartAndEnd() {
    576  size_t range_offset = 0;
    577  size_t range_size = 0;
    578  const bool has_range = segmenter_->GetInitRange(&range_offset, &range_size);
    579 
    580  if (!has_range)
    581  return base::nullopt;
    582 
    583  Range range;
    584  SetStartAndEndFromOffsetAndSize(range_offset, range_size, &range);
    585  return range;
    586 }
    587 
    588 base::Optional<Range> MP4Muxer::GetIndexRangeStartAndEnd() {
    589  size_t range_offset = 0;
    590  size_t range_size = 0;
    591  const bool has_range = segmenter_->GetIndexRange(&range_offset, &range_size);
    592 
    593  if (!has_range)
    594  return base::nullopt;
    595 
    596  Range range;
    597  SetStartAndEndFromOffsetAndSize(range_offset, range_size, &range);
    598  return range;
    599 }
    600 
    601 void MP4Muxer::FireOnMediaStartEvent() {
    602  if (!muxer_listener())
    603  return;
    604 
    605  if (streams().size() > 1) {
    606  LOG(ERROR) << "MuxerListener cannot take more than 1 stream.";
    607  return;
    608  }
    609  DCHECK(!streams().empty()) << "Media started without a stream.";
    610 
    611  const uint32_t timescale = segmenter_->GetReferenceTimeScale();
    612  muxer_listener()->OnMediaStart(options(), *streams().front(), timescale,
    613  MuxerListener::kContainerMp4);
    614 }
    615 
    616 void MP4Muxer::FireOnMediaEndEvent() {
    617  if (!muxer_listener())
    618  return;
    619 
    620  MuxerListener::MediaRanges media_range;
    621  media_range.init_range = GetInitRangeStartAndEnd();
    622  media_range.index_range = GetIndexRangeStartAndEnd();
    623  media_range.subsegment_ranges = segmenter_->GetSegmentRanges();
    624 
    625  const float duration_seconds = static_cast<float>(segmenter_->GetDuration());
    626  muxer_listener()->OnMediaEnd(media_range, duration_seconds);
    627 }
    628 
    629 uint64_t MP4Muxer::IsoTimeNow() {
    630  // Time in seconds from Jan. 1, 1904 to epoch time, i.e. Jan. 1, 1970.
    631  const uint64_t kIsomTimeOffset = 2082844800l;
    632  return kIsomTimeOffset +
    633  (clock() ? clock()->Now() : base::Time::Now()).ToDoubleT();
    634 }
    635 
    636 } // namespace mp4
    637 } // namespace media
    638 } // namespace shaka
    base::Optional< Range > init_range
    Range of the initialization section of a segment.
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    - - -
    base::Optional< Range > index_range
    Range of the index section of a segment.
    - - - - -
    MP4Muxer(const MuxerOptions &options)
    Create a MP4Muxer object from MuxerOptions.
    Definition: mp4_muxer.cc:151
    - -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - - -
    Mp4OutputParams mp4_params
    MP4 (ISO-BMFF) specific parameters.
    Definition: muxer_options.h:25
    - - - - - -
    virtual void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds)=0
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - - -
    virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
    - - - - - - - -
    Holds video stream information.
    - - -
    Holds audio stream information.
    - - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp4/mp4_muxer.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/strings/string_number_conversions.h"
    +
    12 #include "packager/base/time/clock.h"
    +
    13 #include "packager/base/time/time.h"
    +
    14 #include "packager/file/file.h"
    +
    15 #include "packager/media/base/aes_encryptor.h"
    +
    16 #include "packager/media/base/audio_stream_info.h"
    +
    17 #include "packager/media/base/fourccs.h"
    +
    18 #include "packager/media/base/key_source.h"
    +
    19 #include "packager/media/base/media_sample.h"
    +
    20 #include "packager/media/base/text_stream_info.h"
    +
    21 #include "packager/media/base/video_stream_info.h"
    +
    22 #include "packager/media/codecs/es_descriptor.h"
    +
    23 #include "packager/media/event/muxer_listener.h"
    +
    24 #include "packager/media/formats/mp4/box_definitions.h"
    +
    25 #include "packager/media/formats/mp4/multi_segment_segmenter.h"
    +
    26 #include "packager/media/formats/mp4/single_segment_segmenter.h"
    +
    27 #include "packager/media/formats/ttml/ttml_generator.h"
    +
    28 #include "packager/status_macros.h"
    +
    29 
    +
    30 namespace shaka {
    +
    31 namespace media {
    +
    32 namespace mp4 {
    +
    33 
    +
    34 namespace {
    +
    35 
    +
    36 // Sets the range start and end value from offset and size.
    +
    37 // |start| and |end| are for byte-range-spec specified in RFC2616.
    +
    38 void SetStartAndEndFromOffsetAndSize(size_t offset,
    +
    39  size_t size,
    +
    40  Range* range) {
    +
    41  DCHECK(range);
    +
    42  range->start = static_cast<uint32_t>(offset);
    +
    43  // Note that ranges are inclusive. So we need - 1.
    +
    44  range->end = range->start + static_cast<uint32_t>(size) - 1;
    +
    45 }
    +
    46 
    +
    47 FourCC CodecToFourCC(Codec codec, H26xStreamFormat h26x_stream_format) {
    +
    48  switch (codec) {
    +
    49  case kCodecAV1:
    +
    50  return FOURCC_av01;
    +
    51  case kCodecH264:
    +
    52  return h26x_stream_format ==
    +
    53  H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    +
    54  ? FOURCC_avc3
    +
    55  : FOURCC_avc1;
    +
    56  case kCodecH265:
    +
    57  return h26x_stream_format ==
    +
    58  H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    +
    59  ? FOURCC_hev1
    +
    60  : FOURCC_hvc1;
    +
    61  case kCodecH265DolbyVision:
    +
    62  return h26x_stream_format ==
    +
    63  H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    +
    64  ? FOURCC_dvhe
    +
    65  : FOURCC_dvh1;
    +
    66  case kCodecVP8:
    +
    67  return FOURCC_vp08;
    +
    68  case kCodecVP9:
    +
    69  return FOURCC_vp09;
    +
    70  case kCodecAAC:
    +
    71  case kCodecMP3:
    +
    72  return FOURCC_mp4a;
    +
    73  case kCodecAC3:
    +
    74  return FOURCC_ac_3;
    +
    75  case kCodecDTSC:
    +
    76  return FOURCC_dtsc;
    +
    77  case kCodecDTSH:
    +
    78  return FOURCC_dtsh;
    +
    79  case kCodecDTSL:
    +
    80  return FOURCC_dtsl;
    +
    81  case kCodecDTSE:
    +
    82  return FOURCC_dtse;
    +
    83  case kCodecDTSM:
    +
    84  return FOURCC_dtsm;
    +
    85  case kCodecEAC3:
    +
    86  return FOURCC_ec_3;
    +
    87  case kCodecAC4:
    +
    88  return FOURCC_ac_4;
    +
    89  case kCodecFlac:
    +
    90  return FOURCC_fLaC;
    +
    91  case kCodecOpus:
    +
    92  return FOURCC_Opus;
    +
    93  default:
    +
    94  return FOURCC_NULL;
    +
    95  }
    +
    96 }
    +
    97 
    +
    98 void GenerateSinf(FourCC old_type,
    +
    99  const EncryptionConfig& encryption_config,
    +
    100  ProtectionSchemeInfo* sinf) {
    +
    101  sinf->format.format = old_type;
    +
    102 
    +
    103  DCHECK_NE(encryption_config.protection_scheme, FOURCC_NULL);
    +
    104  sinf->type.type = encryption_config.protection_scheme;
    +
    105 
    +
    106  // The version of cenc implemented here. CENC 4.
    +
    107  const int kCencSchemeVersion = 0x00010000;
    +
    108  sinf->type.version = kCencSchemeVersion;
    +
    109 
    +
    110  auto& track_encryption = sinf->info.track_encryption;
    +
    111  track_encryption.default_is_protected = 1;
    +
    112 
    +
    113  track_encryption.default_crypt_byte_block =
    +
    114  encryption_config.crypt_byte_block;
    +
    115  track_encryption.default_skip_byte_block = encryption_config.skip_byte_block;
    +
    116  switch (encryption_config.protection_scheme) {
    +
    117  case FOURCC_cenc:
    +
    118  case FOURCC_cbc1:
    +
    119  DCHECK_EQ(track_encryption.default_crypt_byte_block, 0u);
    +
    120  DCHECK_EQ(track_encryption.default_skip_byte_block, 0u);
    +
    121  // CENCv3 10.1 ‘cenc’ AES-CTR scheme and 10.2 ‘cbc1’ AES-CBC scheme:
    +
    122  // The version of the Track Encryption Box (‘tenc’) SHALL be 0.
    +
    123  track_encryption.version = 0;
    +
    124  break;
    +
    125  case FOURCC_cbcs:
    +
    126  case FOURCC_cens:
    +
    127  // CENCv3 10.3 ‘cens’ AES-CTR subsample pattern encryption scheme and
    +
    128  // 10.4 ‘cbcs’ AES-CBC subsample pattern encryption scheme:
    +
    129  // The version of the Track Encryption Box (‘tenc’) SHALL be 1.
    +
    130  track_encryption.version = 1;
    +
    131  break;
    +
    132  default:
    +
    133  NOTREACHED() << "Unexpected protection scheme "
    +
    134  << encryption_config.protection_scheme;
    +
    135  }
    +
    136 
    +
    137  track_encryption.default_per_sample_iv_size =
    +
    138  encryption_config.per_sample_iv_size;
    +
    139  track_encryption.default_constant_iv = encryption_config.constant_iv;
    +
    140  track_encryption.default_kid = encryption_config.key_id;
    +
    141 }
    +
    142 
    +
    143 // The roll distance is expressed in sample units and always takes negative
    +
    144 // values.
    +
    145 int16_t GetRollDistance(uint64_t seek_preroll_ns, uint32_t sampling_frequency) {
    +
    146  const double kNanosecondsPerSecond = 1000000000;
    +
    147  const double preroll_in_samples =
    +
    148  seek_preroll_ns / kNanosecondsPerSecond * sampling_frequency;
    +
    149  // Round to closest integer.
    +
    150  return -static_cast<int16_t>(preroll_in_samples + 0.5);
    +
    151 }
    +
    152 
    +
    153 } // namespace
    +
    154 
    +
    155 MP4Muxer::MP4Muxer(const MuxerOptions& options) : Muxer(options) {}
    +
    156 MP4Muxer::~MP4Muxer() {}
    +
    157 
    +
    158 Status MP4Muxer::InitializeMuxer() {
    +
    159  // Muxer will be delay-initialized after seeing the first sample.
    +
    160  to_be_initialized_ = true;
    +
    161  return Status::OK;
    +
    162 }
    +
    163 
    +
    164 Status MP4Muxer::Finalize() {
    +
    165  // This happens on streams that are not initialized, i.e. not going through
    +
    166  // DelayInitializeMuxer, which can only happen if there are no samples from
    +
    167  // the stream.
    +
    168  if (!segmenter_) {
    +
    169  DCHECK(to_be_initialized_);
    +
    170  LOG(INFO) << "Skip stream '" << options().output_file_name
    +
    171  << "' which does not contain any sample.";
    +
    172  return Status::OK;
    +
    173  }
    +
    174 
    +
    175  Status segmenter_finalized = segmenter_->Finalize();
    +
    176 
    +
    177  if (!segmenter_finalized.ok())
    +
    178  return segmenter_finalized;
    +
    179 
    +
    180  FireOnMediaEndEvent();
    +
    181  LOG(INFO) << "MP4 file '" << options().output_file_name << "' finalized.";
    +
    182  return Status::OK;
    +
    183 }
    +
    184 
    +
    185 Status MP4Muxer::AddMediaSample(size_t stream_id, const MediaSample& sample) {
    +
    186  if (to_be_initialized_) {
    +
    187  RETURN_IF_ERROR(UpdateEditListOffsetFromSample(sample));
    +
    188  RETURN_IF_ERROR(DelayInitializeMuxer());
    +
    189  to_be_initialized_ = false;
    +
    190  }
    +
    191  DCHECK(segmenter_);
    +
    192  return segmenter_->AddSample(stream_id, sample);
    +
    193 }
    +
    194 
    +
    195 Status MP4Muxer::FinalizeSegment(size_t stream_id,
    +
    196  const SegmentInfo& segment_info) {
    +
    197  DCHECK(segmenter_);
    +
    198  VLOG(3) << "Finalizing " << (segment_info.is_subsegment ? "sub" : "")
    +
    199  << "segment " << segment_info.start_timestamp << " duration "
    +
    200  << segment_info.duration;
    +
    201  return segmenter_->FinalizeSegment(stream_id, segment_info);
    +
    202 }
    +
    203 
    +
    204 Status MP4Muxer::DelayInitializeMuxer() {
    +
    205  DCHECK(!streams().empty());
    +
    206 
    +
    207  std::unique_ptr<FileType> ftyp(new FileType);
    +
    208  std::unique_ptr<Movie> moov(new Movie);
    +
    209 
    +
    210  ftyp->major_brand = FOURCC_mp41;
    +
    211  ftyp->compatible_brands.push_back(FOURCC_iso8);
    +
    212  ftyp->compatible_brands.push_back(FOURCC_isom);
    +
    213  ftyp->compatible_brands.push_back(FOURCC_mp41);
    +
    214  ftyp->compatible_brands.push_back(FOURCC_dash);
    +
    215 
    +
    216  if (streams().size() == 1) {
    +
    217  FourCC codec_fourcc = FOURCC_NULL;
    +
    218  if (streams()[0]->stream_type() == kStreamVideo) {
    +
    219  codec_fourcc =
    +
    220  CodecToFourCC(streams()[0]->codec(),
    +
    221  static_cast<const VideoStreamInfo*>(streams()[0].get())
    +
    222  ->h26x_stream_format());
    +
    223  if (codec_fourcc != FOURCC_NULL)
    +
    224  ftyp->compatible_brands.push_back(codec_fourcc);
    +
    225  }
    +
    226 
    +
    227  // CMAF allows only one track/stream per file.
    +
    228  // CMAF requires single initialization switching for AVC3/HEV1, which is not
    +
    229  // supported yet.
    +
    230  if (codec_fourcc != FOURCC_avc3 && codec_fourcc != FOURCC_hev1)
    +
    231  ftyp->compatible_brands.push_back(FOURCC_cmfc);
    +
    232  }
    +
    233 
    +
    234  moov->header.creation_time = IsoTimeNow();
    +
    235  moov->header.modification_time = IsoTimeNow();
    +
    236  moov->header.next_track_id = static_cast<uint32_t>(streams().size()) + 1;
    +
    237 
    +
    238  moov->tracks.resize(streams().size());
    +
    239  moov->extends.tracks.resize(streams().size());
    +
    240 
    +
    241  // Initialize tracks.
    +
    242  for (uint32_t i = 0; i < streams().size(); ++i) {
    +
    243  const StreamInfo* stream = streams()[i].get();
    +
    244  Track& trak = moov->tracks[i];
    +
    245  trak.header.track_id = i + 1;
    +
    246 
    +
    247  TrackExtends& trex = moov->extends.tracks[i];
    +
    248  trex.track_id = trak.header.track_id;
    +
    249  trex.default_sample_description_index = 1;
    +
    250 
    +
    251  bool generate_trak_result = false;
    +
    252  switch (stream->stream_type()) {
    +
    253  case kStreamVideo:
    +
    254  generate_trak_result = GenerateVideoTrak(
    +
    255  static_cast<const VideoStreamInfo*>(stream), &trak);
    +
    256  break;
    +
    257  case kStreamAudio:
    +
    258  generate_trak_result = GenerateAudioTrak(
    +
    259  static_cast<const AudioStreamInfo*>(stream), &trak);
    +
    260  break;
    +
    261  case kStreamText:
    +
    262  generate_trak_result = GenerateTextTrak(
    +
    263  static_cast<const TextStreamInfo*>(stream), &trak);
    +
    264  break;
    +
    265  default:
    +
    266  NOTIMPLEMENTED() << "Not implemented for stream type: "
    +
    267  << stream->stream_type();
    +
    268  }
    +
    269  if (!generate_trak_result)
    +
    270  return Status(error::MUXER_FAILURE, "Failed to generate trak.");
    +
    271 
    +
    272  // Generate EditList if needed. See UpdateEditListOffsetFromSample() for
    +
    273  // more information.
    +
    274  if (edit_list_offset_.value() > 0) {
    +
    275  EditListEntry entry;
    +
    276  entry.media_time = edit_list_offset_.value();
    +
    277  entry.media_rate_integer = 1;
    +
    278  trak.edit.list.edits.push_back(entry);
    +
    279  }
    +
    280 
    +
    281  if (stream->is_encrypted() && options().mp4_params.include_pssh_in_stream) {
    +
    282  moov->pssh.clear();
    +
    283  const auto& key_system_info = stream->encryption_config().key_system_info;
    +
    284  for (const ProtectionSystemSpecificInfo& system : key_system_info) {
    +
    285  if (system.psshs.empty())
    +
    286  continue;
    +
    287  ProtectionSystemSpecificHeader pssh;
    +
    288  pssh.raw_box = system.psshs;
    +
    289  moov->pssh.push_back(pssh);
    +
    290  }
    +
    291  }
    +
    292  }
    +
    293 
    +
    294  if (options().segment_template.empty()) {
    +
    295  segmenter_.reset(new SingleSegmentSegmenter(options(), std::move(ftyp),
    +
    296  std::move(moov)));
    +
    297  } else {
    +
    298  segmenter_.reset(
    +
    299  new MultiSegmentSegmenter(options(), std::move(ftyp), std::move(moov)));
    +
    300  }
    +
    301 
    +
    302  const Status segmenter_initialized =
    +
    303  segmenter_->Initialize(streams(), muxer_listener(), progress_listener());
    +
    304  if (!segmenter_initialized.ok())
    +
    305  return segmenter_initialized;
    +
    306 
    +
    307  FireOnMediaStartEvent();
    +
    308  return Status::OK;
    +
    309 }
    +
    310 
    +
    311 Status MP4Muxer::UpdateEditListOffsetFromSample(const MediaSample& sample) {
    +
    312  if (edit_list_offset_)
    +
    313  return Status::OK;
    +
    314 
    +
    315  const int64_t pts = sample.pts();
    +
    316  const int64_t dts = sample.dts();
    +
    317  // An EditList entry is inserted if one of the below conditions occur [4]:
    +
    318  // (1) pts > dts for the first sample. Due to Chrome's dts bug [1], dts is
    +
    319  // used in buffered range API, while pts is used elsewhere (players,
    +
    320  // manifests, and Chrome's own appendWindow check etc.), this
    +
    321  // inconsistency creates various problems, including possible stalls
    +
    322  // during playback. Since Chrome adjusts pts only when seeing EditList
    +
    323  // [2], we can insert an EditList with the time equal to difference of pts
    +
    324  // and dts to make aligned buffered ranges using pts and dts. This
    +
    325  // effectively workarounds the dts bug. It is also recommended by ISO-BMFF
    +
    326  // specification [3].
    +
    327  // (2) pts == dts and with pts < 0. This happens for some audio codecs where a
    +
    328  // negative presentation timestamp signals that the sample is not supposed
    +
    329  // to be shown, i.e. for audio priming. EditList is needed to encode
    +
    330  // negative timestamps.
    +
    331  // [1] https://crbug.com/718641, fixed but behind MseBufferByPts, still not
    +
    332  // enabled as of M67.
    +
    333  // [2] This is actually a bug, see https://crbug.com/354518. It looks like
    +
    334  // Chrome is planning to enable the fix for [1] before addressing this
    +
    335  // bug, so we are safe.
    +
    336  // [3] ISO 14496-12:2015 8.6.6.1
    +
    337  // It is recommended that such an edit be used to establish a presentation
    +
    338  // time of 0 for the first presented sample, when composition offsets are
    +
    339  // used.
    +
    340  // [4] ISO 23009-19:2018 7.5.13
    +
    341  // In two cases, an EditBox containing a single EditListBox with the
    +
    342  // following constraints may be present in the CMAF header of a CMAF track
    +
    343  // to adjust the presentation time of all media samples in the CMAF track.
    +
    344  // a) The first case is a video CMAF track file using v0 TrackRunBoxes
    +
    345  // with positive composition offsets to reorder video media samples.
    +
    346  // b) The second case is an audio CMAF track where each media sample's
    +
    347  // presentation time does not equal its composition time.
    +
    348  const int64_t pts_dts_offset = pts - dts;
    +
    349  if (pts_dts_offset > 0) {
    +
    350  if (pts < 0) {
    +
    351  LOG(ERROR) << "Negative presentation timestamp (" << pts
    +
    352  << ") is not supported when there is an offset between "
    +
    353  "presentation timestamp and decoding timestamp ("
    +
    354  << dts << ").";
    +
    355  return Status(error::MUXER_FAILURE,
    +
    356  "Unsupported negative pts when there is an offset between "
    +
    357  "pts and dts.");
    +
    358  }
    +
    359  edit_list_offset_ = pts_dts_offset;
    +
    360  return Status::OK;
    +
    361  }
    +
    362  if (pts_dts_offset < 0) {
    +
    363  LOG(ERROR) << "presentation timestamp (" << pts
    +
    364  << ") is not supposed to be greater than decoding timestamp ("
    +
    365  << dts << ").";
    +
    366  return Status(error::MUXER_FAILURE, "Not expecting pts < dts.");
    +
    367  }
    +
    368  edit_list_offset_ = std::max(-sample.pts(), static_cast<int64_t>(0));
    +
    369  return Status::OK;
    +
    370 }
    +
    371 
    +
    372 void MP4Muxer::InitializeTrak(const StreamInfo* info, Track* trak) {
    +
    373  int64_t now = IsoTimeNow();
    +
    374  trak->header.creation_time = now;
    +
    375  trak->header.modification_time = now;
    +
    376  trak->header.duration = 0;
    +
    377  trak->media.header.creation_time = now;
    +
    378  trak->media.header.modification_time = now;
    +
    379  trak->media.header.timescale = info->time_scale();
    +
    380  trak->media.header.duration = 0;
    +
    381  if (!info->language().empty()) {
    +
    382  // Strip off the subtag, if any.
    +
    383  std::string main_language = info->language();
    +
    384  size_t dash = main_language.find('-');
    +
    385  if (dash != std::string::npos) {
    +
    386  main_language.erase(dash);
    +
    387  }
    +
    388 
    +
    389  // ISO-639-2/T main language code should be 3 characters.
    +
    390  if (main_language.size() != 3) {
    +
    391  LOG(WARNING) << "'" << main_language << "' is not a valid ISO-639-2 "
    +
    392  << "language code, ignoring.";
    +
    393  } else {
    +
    394  trak->media.header.language.code = main_language;
    +
    395  }
    +
    396  }
    +
    397 }
    +
    398 
    +
    399 bool MP4Muxer::GenerateVideoTrak(const VideoStreamInfo* video_info,
    +
    400  Track* trak) {
    +
    401  InitializeTrak(video_info, trak);
    +
    402 
    +
    403  // width and height specify the track's visual presentation size as
    +
    404  // fixed-point 16.16 values.
    +
    405  uint32_t pixel_width = video_info->pixel_width();
    +
    406  uint32_t pixel_height = video_info->pixel_height();
    +
    407  if (pixel_width == 0 || pixel_height == 0) {
    +
    408  LOG(WARNING) << "pixel width/height are not set. Assuming 1:1.";
    +
    409  pixel_width = 1;
    +
    410  pixel_height = 1;
    +
    411  }
    +
    412  const double sample_aspect_ratio =
    +
    413  static_cast<double>(pixel_width) / pixel_height;
    +
    414  trak->header.width = video_info->width() * sample_aspect_ratio * 0x10000;
    +
    415  trak->header.height = video_info->height() * 0x10000;
    +
    416 
    +
    417  VideoSampleEntry video;
    +
    418  video.format =
    +
    419  CodecToFourCC(video_info->codec(), video_info->h26x_stream_format());
    +
    420  video.width = video_info->width();
    +
    421  video.height = video_info->height();
    +
    422  video.codec_configuration.data = video_info->codec_config();
    +
    423  if (!video.ParseExtraCodecConfigsVector(video_info->extra_config())) {
    +
    424  LOG(ERROR) << "Malformed extra codec configs: "
    +
    425  << base::HexEncode(video_info->extra_config().data(),
    +
    426  video_info->extra_config().size());
    +
    427  return false;
    +
    428  }
    +
    429  if (pixel_width != 1 || pixel_height != 1) {
    +
    430  video.pixel_aspect.h_spacing = pixel_width;
    +
    431  video.pixel_aspect.v_spacing = pixel_height;
    +
    432  }
    +
    433 
    +
    434  SampleDescription& sample_description =
    +
    435  trak->media.information.sample_table.description;
    +
    436  sample_description.type = kVideo;
    +
    437  sample_description.video_entries.push_back(video);
    +
    438 
    +
    439  if (video_info->is_encrypted()) {
    +
    440  if (video_info->has_clear_lead()) {
    +
    441  // Add a second entry for clear content.
    +
    442  sample_description.video_entries.push_back(video);
    +
    443  }
    +
    444  // Convert the first entry to an encrypted entry.
    +
    445  VideoSampleEntry& entry = sample_description.video_entries[0];
    +
    446  GenerateSinf(entry.format, video_info->encryption_config(), &entry.sinf);
    +
    447  entry.format = FOURCC_encv;
    +
    448  }
    +
    449  return true;
    +
    450 }
    +
    451 
    +
    452 bool MP4Muxer::GenerateAudioTrak(const AudioStreamInfo* audio_info,
    +
    453  Track* trak) {
    +
    454  InitializeTrak(audio_info, trak);
    +
    455 
    +
    456  trak->header.volume = 0x100;
    +
    457 
    +
    458  AudioSampleEntry audio;
    +
    459  audio.format =
    +
    460  CodecToFourCC(audio_info->codec(), H26xStreamFormat::kUnSpecified);
    +
    461  switch(audio_info->codec()){
    +
    462  case kCodecAAC: {
    +
    463  DecoderConfigDescriptor* decoder_config =
    +
    464  audio.esds.es_descriptor.mutable_decoder_config_descriptor();
    +
    465  decoder_config->set_object_type(ObjectType::kISO_14496_3); // MPEG4 AAC.
    +
    466  decoder_config->set_max_bitrate(audio_info->max_bitrate());
    +
    467  decoder_config->set_avg_bitrate(audio_info->avg_bitrate());
    +
    468  decoder_config->mutable_decoder_specific_info_descriptor()->set_data(
    +
    469  audio_info->codec_config());
    +
    470  break;
    +
    471  }
    +
    472  case kCodecDTSC:
    +
    473  case kCodecDTSH:
    +
    474  case kCodecDTSL:
    +
    475  case kCodecDTSE:
    +
    476  case kCodecDTSM:
    +
    477  audio.ddts.extra_data = audio_info->codec_config();
    +
    478  audio.ddts.max_bitrate = audio_info->max_bitrate();
    +
    479  audio.ddts.avg_bitrate = audio_info->avg_bitrate();
    +
    480  audio.ddts.sampling_frequency = audio_info->sampling_frequency();
    +
    481  audio.ddts.pcm_sample_depth = audio_info->sample_bits();
    +
    482  break;
    +
    483  case kCodecAC3:
    +
    484  audio.dac3.data = audio_info->codec_config();
    +
    485  break;
    +
    486  case kCodecEAC3:
    +
    487  audio.dec3.data = audio_info->codec_config();
    +
    488  break;
    +
    489  case kCodecAC4:
    +
    490  audio.dac4.data = audio_info->codec_config();
    +
    491  break;
    +
    492  case kCodecFlac:
    +
    493  audio.dfla.data = audio_info->codec_config();
    +
    494  break;
    +
    495  case kCodecMP3: {
    +
    496  DecoderConfigDescriptor* decoder_config =
    +
    497  audio.esds.es_descriptor.mutable_decoder_config_descriptor();
    +
    498  uint32_t samplerate = audio_info->sampling_frequency();
    +
    499  if (samplerate < 32000)
    +
    500  decoder_config->set_object_type(ObjectType::kISO_13818_3_MPEG1);
    +
    501  else
    +
    502  decoder_config->set_object_type(ObjectType::kISO_11172_3_MPEG1);
    +
    503  decoder_config->set_max_bitrate(audio_info->max_bitrate());
    +
    504  decoder_config->set_avg_bitrate(audio_info->avg_bitrate());
    +
    505 
    +
    506  // For values of DecoderConfigDescriptor.objectTypeIndication
    +
    507  // that refer to streams complying with ISO/IEC 11172-3 or
    +
    508  // ISO/IEC 13818-3 the decoder specific information is empty
    +
    509  // since all necessary data is contained in the bitstream frames
    +
    510  // itself.
    +
    511  break;
    +
    512  }
    +
    513  case kCodecOpus:
    +
    514  audio.dops.opus_identification_header = audio_info->codec_config();
    +
    515  break;
    +
    516  default:
    +
    517  NOTIMPLEMENTED() << " Unsupported audio codec " << audio_info->codec();
    +
    518  return false;
    +
    519  }
    +
    520 
    +
    521  if (audio_info->codec() == kCodecAC3 || audio_info->codec() == kCodecEAC3) {
    +
    522  // AC3 and EC3 does not fill in actual channel count and sample size in
    +
    523  // sample description entry. Instead, two constants are used.
    +
    524  audio.channelcount = 2;
    +
    525  audio.samplesize = 16;
    +
    526  } else if (audio_info->codec() == kCodecAC4) {
    +
    527  //ETSI TS 103 190-2, E.4.5 channelcount should be set to the total number of
    +
    528  //audio outputchannels of the default audio presentation of that track
    +
    529  audio.channelcount = audio_info->num_channels();
    +
    530  //ETSI TS 103 190-2, E.4.6 samplesize shall be set to 16.
    +
    531  audio.samplesize = 16;
    +
    532  } else {
    +
    533  audio.channelcount = audio_info->num_channels();
    +
    534  audio.samplesize = audio_info->sample_bits();
    +
    535  }
    +
    536  audio.samplerate = audio_info->sampling_frequency();
    +
    537  SampleTable& sample_table = trak->media.information.sample_table;
    +
    538  SampleDescription& sample_description = sample_table.description;
    +
    539  sample_description.type = kAudio;
    +
    540  sample_description.audio_entries.push_back(audio);
    +
    541 
    +
    542  if (audio_info->is_encrypted()) {
    +
    543  if (audio_info->has_clear_lead()) {
    +
    544  // Add a second entry for clear content.
    +
    545  sample_description.audio_entries.push_back(audio);
    +
    546  }
    +
    547  // Convert the first entry to an encrypted entry.
    +
    548  AudioSampleEntry& entry = sample_description.audio_entries[0];
    +
    549  GenerateSinf(entry.format, audio_info->encryption_config(), &entry.sinf);
    +
    550  entry.format = FOURCC_enca;
    +
    551  }
    +
    552 
    +
    553  if (audio_info->seek_preroll_ns() > 0) {
    +
    554  sample_table.sample_group_descriptions.resize(1);
    +
    555  SampleGroupDescription& sample_group_description =
    +
    556  sample_table.sample_group_descriptions.back();
    +
    557  sample_group_description.grouping_type = FOURCC_roll;
    +
    558  sample_group_description.audio_roll_recovery_entries.resize(1);
    +
    559  sample_group_description.audio_roll_recovery_entries[0].roll_distance =
    +
    560  GetRollDistance(audio_info->seek_preroll_ns(), audio.samplerate);
    +
    561  // sample to group box is not allowed in the init segment per CMAF
    +
    562  // specification. It is put in the fragment instead.
    +
    563  }
    +
    564  return true;
    +
    565 }
    +
    566 
    +
    567 bool MP4Muxer::GenerateTextTrak(const TextStreamInfo* text_info,
    +
    568  Track* trak) {
    +
    569  InitializeTrak(text_info, trak);
    +
    570 
    +
    571  if (text_info->codec_string() == "wvtt") {
    +
    572  // Handle WebVTT.
    +
    573  TextSampleEntry webvtt;
    +
    574  webvtt.format = FOURCC_wvtt;
    +
    575 
    +
    576  // 14496-30:2014 7.5 Web Video Text Tracks Sample entry format.
    +
    577  // In the sample entry, a WebVTT configuration box must occur, carrying
    +
    578  // exactly the lines of the WebVTT file header, i.e. all text lines up to
    +
    579  // but excluding the 'two or more line terminators' that end the header.
    +
    580  webvtt.config.config = "WEBVTT";
    +
    581  // The spec does not define a way to carry STYLE and REGION information in
    +
    582  // the mp4 container.
    +
    583  if (!text_info->regions().empty() || !text_info->css_styles().empty()) {
    +
    584  LOG(INFO) << "Skipping possible style / region configuration as the spec "
    +
    585  "does not define a way to carry them inside ISO-BMFF files.";
    +
    586  }
    +
    587 
    +
    588  // TODO(rkuroiwa): This should be the source file URI(s). Putting bogus
    +
    589  // string for now so that the box will be there for samples with overlapping
    +
    590  // cues.
    +
    591  webvtt.label.source_label = "source_label";
    +
    592  SampleDescription& sample_description =
    +
    593  trak->media.information.sample_table.description;
    +
    594  sample_description.type = kText;
    +
    595  sample_description.text_entries.push_back(webvtt);
    +
    596  return true;
    +
    597  } else if (text_info->codec_string() == "ttml") {
    +
    598  // Handle TTML.
    +
    599  TextSampleEntry ttml;
    +
    600  ttml.format = FOURCC_stpp;
    +
    601  ttml.namespace_ = ttml::TtmlGenerator::kTtNamespace;
    +
    602 
    +
    603  SampleDescription& sample_description =
    +
    604  trak->media.information.sample_table.description;
    +
    605  sample_description.type = kSubtitle;
    +
    606  sample_description.text_entries.push_back(ttml);
    +
    607  return true;
    +
    608  }
    +
    609  NOTIMPLEMENTED() << text_info->codec_string()
    +
    610  << " handling not implemented yet.";
    +
    611  return false;
    +
    612 }
    +
    613 
    +
    614 base::Optional<Range> MP4Muxer::GetInitRangeStartAndEnd() {
    +
    615  size_t range_offset = 0;
    +
    616  size_t range_size = 0;
    +
    617  const bool has_range = segmenter_->GetInitRange(&range_offset, &range_size);
    +
    618 
    +
    619  if (!has_range)
    +
    620  return base::nullopt;
    +
    621 
    +
    622  Range range;
    +
    623  SetStartAndEndFromOffsetAndSize(range_offset, range_size, &range);
    +
    624  return range;
    +
    625 }
    +
    626 
    +
    627 base::Optional<Range> MP4Muxer::GetIndexRangeStartAndEnd() {
    +
    628  size_t range_offset = 0;
    +
    629  size_t range_size = 0;
    +
    630  const bool has_range = segmenter_->GetIndexRange(&range_offset, &range_size);
    +
    631 
    +
    632  if (!has_range)
    +
    633  return base::nullopt;
    +
    634 
    +
    635  Range range;
    +
    636  SetStartAndEndFromOffsetAndSize(range_offset, range_size, &range);
    +
    637  return range;
    +
    638 }
    +
    639 
    +
    640 void MP4Muxer::FireOnMediaStartEvent() {
    +
    641  if (!muxer_listener())
    +
    642  return;
    +
    643 
    +
    644  if (streams().size() > 1) {
    +
    645  LOG(ERROR) << "MuxerListener cannot take more than 1 stream.";
    +
    646  return;
    +
    647  }
    +
    648  DCHECK(!streams().empty()) << "Media started without a stream.";
    +
    649 
    +
    650  const uint32_t timescale = segmenter_->GetReferenceTimeScale();
    +
    651  muxer_listener()->OnMediaStart(options(), *streams().front(), timescale,
    +
    652  MuxerListener::kContainerMp4);
    +
    653 }
    +
    654 
    +
    655 void MP4Muxer::FireOnMediaEndEvent() {
    +
    656  if (!muxer_listener())
    +
    657  return;
    +
    658 
    +
    659  MuxerListener::MediaRanges media_range;
    +
    660  media_range.init_range = GetInitRangeStartAndEnd();
    +
    661  media_range.index_range = GetIndexRangeStartAndEnd();
    +
    662  media_range.subsegment_ranges = segmenter_->GetSegmentRanges();
    +
    663 
    +
    664  const float duration_seconds = static_cast<float>(segmenter_->GetDuration());
    +
    665  muxer_listener()->OnMediaEnd(media_range, duration_seconds);
    +
    666 }
    +
    667 
    +
    668 uint64_t MP4Muxer::IsoTimeNow() {
    +
    669  // Time in seconds from Jan. 1, 1904 to epoch time, i.e. Jan. 1, 1970.
    +
    670  const uint64_t kIsomTimeOffset = 2082844800l;
    +
    671  return kIsomTimeOffset +
    +
    672  (clock() ? clock()->Now() : base::Time::Now()).ToDoubleT();
    +
    673 }
    +
    674 
    +
    675 } // namespace mp4
    +
    676 } // namespace media
    +
    677 } // namespace shaka
    + +
    virtual void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds)=0
    +
    virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
    + +
    MP4Muxer(const MuxerOptions &options)
    Create a MP4Muxer object from MuxerOptions.
    Definition: mp4_muxer.cc:155
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    diff --git a/docs/da/d8b/classshaka_1_1media_1_1WebMMediaParser-members.html b/docs/da/d8b/classshaka_1_1media_1_1WebMMediaParser-members.html index 549de28a6c..791aaeb7b6 100644 --- a/docs/da/d8b/classshaka_1_1media_1_1WebMMediaParser-members.html +++ b/docs/da/d8b/classshaka_1_1media_1_1WebMMediaParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::WebMMediaParser, including all inherited members.

    - + - - - - - + + + + + +
    Flush() override WARN_UNUSED_RESULTshaka::media::WebMMediaParservirtual
    Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) overrideshaka::media::WebMMediaParservirtual
    Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) overrideshaka::media::WebMMediaParservirtual
    InitCB typedefshaka::media::MediaParser
    MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinline
    NewSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULTshaka::media::WebMMediaParservirtual
    WebMMediaParser() (defined in shaka::media::WebMMediaParser)shaka::media::WebMMediaParser
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    ~WebMMediaParser() override (defined in shaka::media::WebMMediaParser)shaka::media::WebMMediaParser
    NewMediaSampleCB typedefshaka::media::MediaParser
    NewTextSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULTshaka::media::WebMMediaParservirtual
    WebMMediaParser() (defined in shaka::media::WebMMediaParser)shaka::media::WebMMediaParser
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    ~WebMMediaParser() override (defined in shaka::media::WebMMediaParser)shaka::media::WebMMediaParser
    diff --git a/docs/da/d8e/container__names_8cc_source.html b/docs/da/d8e/container__names_8cc_source.html index eb9ba1ca2e..62c58b287d 100644 --- a/docs/da/d8e/container__names_8cc_source.html +++ b/docs/da/d8e/container__names_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/container_names.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    container_names.cc
    -
    1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/base/container_names.h"
    6 
    7 #include <libxml/parser.h>
    8 #include <libxml/tree.h>
    9 #include <stdint.h>
    10 
    11 #include <cctype>
    12 #include <limits>
    13 
    14 #include "packager/base/logging.h"
    15 #include "packager/base/strings/string_util.h"
    16 #include "packager/media/base/bit_reader.h"
    17 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
    18 
    19 namespace shaka {
    20 namespace media {
    21 
    22 #define TAG(a, b, c, d) \
    23  ((static_cast<uint32_t>(static_cast<uint8_t>(a)) << 24) | \
    24  (static_cast<uint8_t>(b) << 16) | (static_cast<uint8_t>(c) << 8) | \
    25  (static_cast<uint8_t>(d)))
    26 
    27 #define RCHECK(x) \
    28  do { \
    29  if (!(x)) \
    30  return false; \
    31  } while (0)
    32 
    33 #define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
    34 
    35 // Helper function to read 2 bytes (16 bits, big endian) from a buffer.
    36 static int Read16(const uint8_t* p) {
    37  return p[0] << 8 | p[1];
    38 }
    39 
    40 // Helper function to read 3 bytes (24 bits, big endian) from a buffer.
    41 static uint32_t Read24(const uint8_t* p) {
    42  return p[0] << 16 | p[1] << 8 | p[2];
    43 }
    44 
    45 // Helper function to read 4 bytes (32 bits, big endian) from a buffer.
    46 static uint32_t Read32(const uint8_t* p) {
    47  return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
    48 }
    49 
    50 // Helper function to read 4 bytes (32 bits, little endian) from a buffer.
    51 static uint32_t Read32LE(const uint8_t* p) {
    52  return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
    53 }
    54 
    55 // Helper function to do buffer comparisons with a string without going off the
    56 // end of the buffer.
    57 static bool StartsWith(const uint8_t* buffer,
    58  size_t buffer_size,
    59  const char* prefix) {
    60  size_t prefix_size = strlen(prefix);
    61  return (prefix_size <= buffer_size &&
    62  memcmp(buffer, prefix, prefix_size) == 0);
    63 }
    64 
    65 // Helper function to do buffer comparisons with another buffer (to allow for
    66 // embedded \0 in the comparison) without going off the end of the buffer.
    67 static bool StartsWith(const uint8_t* buffer,
    68  size_t buffer_size,
    69  const uint8_t* prefix,
    70  size_t prefix_size) {
    71  return (prefix_size <= buffer_size &&
    72  memcmp(buffer, prefix, prefix_size) == 0);
    73 }
    74 
    75 // Helper function to read up to 64 bits from a bit stream.
    76 static uint64_t ReadBits(BitReader* reader, int num_bits) {
    77  DCHECK_GE(static_cast<int>(reader->bits_available()), num_bits);
    78  DCHECK((num_bits > 0) && (num_bits <= 64));
    79  uint64_t value;
    80  reader->ReadBits(num_bits, &value);
    81  return value;
    82 }
    83 
    84 const int kAc3FrameSizeTable[38][3] = {
    85  { 128, 138, 192 }, { 128, 140, 192 }, { 160, 174, 240 }, { 160, 176, 240 },
    86  { 192, 208, 288 }, { 192, 210, 288 }, { 224, 242, 336 }, { 224, 244, 336 },
    87  { 256, 278, 384 }, { 256, 280, 384 }, { 320, 348, 480 }, { 320, 350, 480 },
    88  { 384, 416, 576 }, { 384, 418, 576 }, { 448, 486, 672 }, { 448, 488, 672 },
    89  { 512, 556, 768 }, { 512, 558, 768 }, { 640, 696, 960 }, { 640, 698, 960 },
    90  { 768, 834, 1152 }, { 768, 836, 1152 }, { 896, 974, 1344 },
    91  { 896, 976, 1344 }, { 1024, 1114, 1536 }, { 1024, 1116, 1536 },
    92  { 1280, 1392, 1920 }, { 1280, 1394, 1920 }, { 1536, 1670, 2304 },
    93  { 1536, 1672, 2304 }, { 1792, 1950, 2688 }, { 1792, 1952, 2688 },
    94  { 2048, 2228, 3072 }, { 2048, 2230, 3072 }, { 2304, 2506, 3456 },
    95  { 2304, 2508, 3456 }, { 2560, 2768, 3840 }, { 2560, 2770, 3840 }
    96 };
    97 
    98 // Checks for an ADTS AAC container.
    99 static bool CheckAac(const uint8_t* buffer, int buffer_size) {
    100  // Audio Data Transport Stream (ADTS) header is 7 or 9 bytes
    101  // (from http://wiki.multimedia.cx/index.php?title=ADTS)
    102  RCHECK(buffer_size > 6);
    103 
    104  int offset = 0;
    105  while (offset + 6 < buffer_size) {
    106  BitReader reader(buffer + offset, 6);
    107 
    108  // Syncword must be 0xfff.
    109  RCHECK(ReadBits(&reader, 12) == 0xfff);
    110 
    111  // Skip MPEG version.
    112  reader.SkipBits(1);
    113 
    114  // Layer is always 0.
    115  RCHECK(ReadBits(&reader, 2) == 0);
    116 
    117  // Skip protection + profile.
    118  reader.SkipBits(1 + 2);
    119 
    120  // Check sampling frequency index.
    121  RCHECK(ReadBits(&reader, 4) != 15); // Forbidden.
    122 
    123  // Skip private stream, channel configuration, originality, home,
    124  // copyrighted stream, and copyright_start.
    125  reader.SkipBits(1 + 3 + 1 + 1 + 1 + 1);
    126 
    127  // Get frame length (includes header).
    128  int size = ReadBits(&reader, 13);
    129  RCHECK(size > 0);
    130  offset += size;
    131  }
    132  return true;
    133 }
    134 
    135 const uint16_t kAc3SyncWord = 0x0b77;
    136 
    137 // Checks for an AC3 container.
    138 static bool CheckAc3(const uint8_t* buffer, int buffer_size) {
    139  // Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
    140  // Doc. A/52:2012
    141  // (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
    142 
    143  // AC3 container looks like syncinfo | bsi | audblk * 6 | aux | check.
    144  RCHECK(buffer_size > 6);
    145 
    146  int offset = 0;
    147  while (offset + 6 < buffer_size) {
    148  BitReader reader(buffer + offset, 6);
    149 
    150  // Check syncinfo.
    151  RCHECK(ReadBits(&reader, 16) == kAc3SyncWord);
    152 
    153  // Skip crc1.
    154  reader.SkipBits(16);
    155 
    156  // Verify fscod.
    157  int sample_rate_code = ReadBits(&reader, 2);
    158  RCHECK(sample_rate_code != 3); // Reserved.
    159 
    160  // Verify frmsizecod.
    161  int frame_size_code = ReadBits(&reader, 6);
    162  RCHECK(frame_size_code < 38); // Undefined.
    163 
    164  // Verify bsid.
    165  RCHECK(ReadBits(&reader, 5) < 10); // Normally 8 or 6, 16 used by EAC3.
    166 
    167  offset += kAc3FrameSizeTable[frame_size_code][sample_rate_code];
    168  }
    169  return true;
    170 }
    171 
    172 // Checks for an EAC3 container (very similar to AC3)
    173 static bool CheckEac3(const uint8_t* buffer, int buffer_size) {
    174  // Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
    175  // Doc. A/52:2012
    176  // (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
    177 
    178  // EAC3 container looks like syncinfo | bsi | audfrm | audblk* | aux | check.
    179  RCHECK(buffer_size > 6);
    180 
    181  int offset = 0;
    182  while (offset + 6 < buffer_size) {
    183  BitReader reader(buffer + offset, 6);
    184 
    185  // Check syncinfo.
    186  RCHECK(ReadBits(&reader, 16) == kAc3SyncWord);
    187 
    188  // Verify strmtyp.
    189  RCHECK(ReadBits(&reader, 2) != 3);
    190 
    191  // Skip substreamid.
    192  reader.SkipBits(3);
    193 
    194  // Get frmsize. Include syncinfo size and convert to bytes.
    195  int frame_size = (ReadBits(&reader, 11) + 1) * 2;
    196  RCHECK(frame_size >= 7);
    197 
    198  // Skip fscod, fscod2, acmod, and lfeon.
    199  reader.SkipBits(2 + 2 + 3 + 1);
    200 
    201  // Verify bsid.
    202  int bit_stream_id = ReadBits(&reader, 5);
    203  RCHECK(bit_stream_id >= 11 && bit_stream_id <= 16);
    204 
    205  offset += frame_size;
    206  }
    207  return true;
    208 }
    209 
    210 // Additional checks for a BINK container.
    211 static bool CheckBink(const uint8_t* buffer, int buffer_size) {
    212  // Reference: http://wiki.multimedia.cx/index.php?title=Bink_Container
    213  RCHECK(buffer_size >= 44);
    214 
    215  // Verify number of frames specified.
    216  RCHECK(Read32LE(buffer + 8) > 0);
    217 
    218  // Verify width in range.
    219  int width = Read32LE(buffer + 20);
    220  RCHECK(width > 0 && width <= 32767);
    221 
    222  // Verify height in range.
    223  int height = Read32LE(buffer + 24);
    224  RCHECK(height > 0 && height <= 32767);
    225 
    226  // Verify frames per second specified.
    227  RCHECK(Read32LE(buffer + 28) > 0);
    228 
    229  // Verify video frames per second specified.
    230  RCHECK(Read32LE(buffer + 32) > 0);
    231 
    232  // Number of audio tracks must be 256 or less.
    233  return (Read32LE(buffer + 40) <= 256);
    234 }
    235 
    236 // Additional checks for a CAF container.
    237 static bool CheckCaf(const uint8_t* buffer, int buffer_size) {
    238  // Reference: Apple Core Audio Format Specification 1.0
    239  // (https://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html)
    240  RCHECK(buffer_size >= 52);
    241  BitReader reader(buffer, buffer_size);
    242 
    243  // mFileType should be "caff".
    244  RCHECK(ReadBits(&reader, 32) == TAG('c', 'a', 'f', 'f'));
    245 
    246  // mFileVersion should be 1.
    247  RCHECK(ReadBits(&reader, 16) == 1);
    248 
    249  // Skip mFileFlags.
    250  reader.SkipBits(16);
    251 
    252  // First chunk should be Audio Description chunk, size 32l.
    253  RCHECK(ReadBits(&reader, 32) == TAG('d', 'e', 's', 'c'));
    254  RCHECK(ReadBits(&reader, 64) == 32);
    255 
    256  // CAFAudioFormat.mSampleRate(float64) not 0
    257  RCHECK(ReadBits(&reader, 64) != 0);
    258 
    259  // CAFAudioFormat.mFormatID not 0
    260  RCHECK(ReadBits(&reader, 32) != 0);
    261 
    262  // Skip CAFAudioFormat.mBytesPerPacket and mFramesPerPacket.
    263  reader.SkipBits(32 + 32);
    264 
    265  // CAFAudioFormat.mChannelsPerFrame not 0
    266  RCHECK(ReadBits(&reader, 32) != 0);
    267  return true;
    268 }
    269 
    270 static bool kSamplingFrequencyValid[16] = { false, true, true, true, false,
    271  false, true, true, true, false,
    272  false, true, true, true, false,
    273  false };
    274 static bool kExtAudioIdValid[8] = { true, false, true, false, false, false,
    275  true, false };
    276 
    277 // Additional checks for a DTS container.
    278 static bool CheckDts(const uint8_t* buffer, int buffer_size) {
    279  // Reference: ETSI TS 102 114 V1.3.1 (2011-08)
    280  // (http://www.etsi.org/deliver/etsi_ts/102100_102199/102114/01.03.01_60/ts_102114v010301p.pdf)
    281  RCHECK(buffer_size > 11);
    282 
    283  int offset = 0;
    284  while (offset + 11 < buffer_size) {
    285  BitReader reader(buffer + offset, 11);
    286 
    287  // Verify sync word.
    288  RCHECK(ReadBits(&reader, 32) == 0x7ffe8001);
    289 
    290  // Skip frame type and deficit sample count.
    291  reader.SkipBits(1 + 5);
    292 
    293  // Verify CRC present flag.
    294  RCHECK(ReadBits(&reader, 1) == 0); // CPF must be 0.
    295 
    296  // Verify number of PCM sample blocks.
    297  RCHECK(ReadBits(&reader, 7) >= 5);
    298 
    299  // Verify primary frame byte size.
    300  int frame_size = ReadBits(&reader, 14);
    301  RCHECK(frame_size >= 95);
    302 
    303  // Skip audio channel arrangement.
    304  reader.SkipBits(6);
    305 
    306  // Verify core audio sampling frequency is an allowed value.
    307  RCHECK(kSamplingFrequencyValid[ReadBits(&reader, 4)]);
    308 
    309  // Verify transmission bit rate is valid.
    310  RCHECK(ReadBits(&reader, 5) <= 25);
    311 
    312  // Verify reserved field is 0.
    313  RCHECK(ReadBits(&reader, 1) == 0);
    314 
    315  // Skip dynamic range flag, time stamp flag, auxiliary data flag, and HDCD.
    316  reader.SkipBits(1 + 1 + 1 + 1);
    317 
    318  // Verify extension audio descriptor flag is an allowed value.
    319  RCHECK(kExtAudioIdValid[ReadBits(&reader, 3)]);
    320 
    321  // Skip extended coding flag and audio sync word insertion flag.
    322  reader.SkipBits(1 + 1);
    323 
    324  // Verify low frequency effects flag is an allowed value.
    325  RCHECK(ReadBits(&reader, 2) != 3);
    326 
    327  offset += frame_size + 1;
    328  }
    329  return true;
    330 }
    331 
    332 // Checks for a DV container.
    333 static bool CheckDV(const uint8_t* buffer, int buffer_size) {
    334  // Reference: SMPTE 314M (Annex A has differences with IEC 61834).
    335  // (http://standards.smpte.org/content/978-1-61482-454-1/st-314-2005/SEC1.body.pdf)
    336  RCHECK(buffer_size > 11);
    337 
    338  int offset = 0;
    339  int current_sequence_number = -1;
    340  int last_block_number[6];
    341  while (offset + 11 < buffer_size) {
    342  BitReader reader(buffer + offset, 11);
    343 
    344  // Decode ID data. Sections 5, 6, and 7 are reserved.
    345  int section = ReadBits(&reader, 3);
    346  RCHECK(section < 5);
    347 
    348  // Next bit must be 1.
    349  RCHECK(ReadBits(&reader, 1) == 1);
    350 
    351  // Skip arbitrary bits.
    352  reader.SkipBits(4);
    353 
    354  int sequence_number = ReadBits(&reader, 4);
    355 
    356  // Skip FSC.
    357  reader.SkipBits(1);
    358 
    359  // Next 3 bits must be 1.
    360  RCHECK(ReadBits(&reader, 3) == 7);
    361 
    362  int block_number = ReadBits(&reader, 8);
    363 
    364  if (section == 0) { // Header.
    365  // Validate the reserved bits in the next 8 bytes.
    366  reader.SkipBits(1);
    367  RCHECK(ReadBits(&reader, 1) == 0);
    368  RCHECK(ReadBits(&reader, 11) == 0x7ff);
    369  reader.SkipBits(4);
    370  RCHECK(ReadBits(&reader, 4) == 0xf);
    371  reader.SkipBits(4);
    372  RCHECK(ReadBits(&reader, 4) == 0xf);
    373  reader.SkipBits(4);
    374  RCHECK(ReadBits(&reader, 4) == 0xf);
    375  reader.SkipBits(3);
    376  RCHECK(ReadBits(&reader, 24) == 0xffffff);
    377  current_sequence_number = sequence_number;
    378  for (size_t i = 0; i < arraysize(last_block_number); ++i)
    379  last_block_number[i] = -1;
    380  } else {
    381  // Sequence number must match (this will also fail if no header seen).
    382  RCHECK(sequence_number == current_sequence_number);
    383  // Block number should be increasing.
    384  RCHECK(block_number > last_block_number[section]);
    385  last_block_number[section] = block_number;
    386  }
    387 
    388  // Move to next block.
    389  offset += 80;
    390  }
    391  return true;
    392 }
    393 
    394 
    395 // Checks for a GSM container.
    396 static bool CheckGsm(const uint8_t* buffer, int buffer_size) {
    397  // Reference: ETSI EN 300 961 V8.1.1
    398  // (http://www.etsi.org/deliver/etsi_en/300900_300999/300961/08.01.01_60/en_300961v080101p.pdf)
    399  // also http://tools.ietf.org/html/rfc3551#page-24
    400  // GSM files have a 33 byte block, only first 4 bits are fixed.
    401  RCHECK(buffer_size >= 1024); // Need enough data to do a decent check.
    402 
    403  int offset = 0;
    404  while (offset < buffer_size) {
    405  // First 4 bits of each block are xD.
    406  RCHECK((buffer[offset] & 0xf0) == 0xd0);
    407  offset += 33;
    408  }
    409  return true;
    410 }
    411 
    412 // Advance to the first set of |num_bits| bits that match |start_code|. |offset|
    413 // is the current location in the buffer, and is updated. |bytes_needed| is the
    414 // number of bytes that must remain in the buffer when |start_code| is found.
    415 // Returns true if start_code found (and enough space in the buffer after it),
    416 // false otherwise.
    417 static bool AdvanceToStartCode(const uint8_t* buffer,
    418  int buffer_size,
    419  int* offset,
    420  int bytes_needed,
    421  int num_bits,
    422  uint32_t start_code) {
    423  DCHECK_GE(bytes_needed, 3);
    424  DCHECK_LE(num_bits, 24); // Only supports up to 24 bits.
    425 
    426  // Create a mask to isolate |num_bits| bits, once shifted over.
    427  uint32_t bits_to_shift = 24 - num_bits;
    428  uint32_t mask = (1 << num_bits) - 1;
    429  while (*offset + bytes_needed < buffer_size) {
    430  uint32_t next = Read24(buffer + *offset);
    431  if (((next >> bits_to_shift) & mask) == start_code)
    432  return true;
    433  ++(*offset);
    434  }
    435  return false;
    436 }
    437 
    438 // Checks for an H.261 container.
    439 static bool CheckH261(const uint8_t* buffer, int buffer_size) {
    440  // Reference: ITU-T Recommendation H.261 (03/1993)
    441  // (http://www.itu.int/rec/T-REC-H.261-199303-I/en)
    442  RCHECK(buffer_size > 16);
    443 
    444  int offset = 0;
    445  bool seen_start_code = false;
    446  while (true) {
    447  // Advance to picture_start_code, if there is one.
    448  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 4, 20, 0x10)) {
    449  // No start code found (or off end of buffer), so success if
    450  // there was at least one valid header.
    451  return seen_start_code;
    452  }
    453 
    454  // Now verify the block. AdvanceToStartCode() made sure that there are
    455  // at least 4 bytes remaining in the buffer.
    456  BitReader reader(buffer + offset, buffer_size - offset);
    457  RCHECK(ReadBits(&reader, 20) == 0x10);
    458 
    459  // Skip the temporal reference and PTYPE.
    460  reader.SkipBits(5 + 6);
    461 
    462  // Skip any extra insertion information. Since this is open-ended, if we run
    463  // out of bits assume that the buffer is correctly formatted.
    464  int extra = ReadBits(&reader, 1);
    465  while (extra == 1) {
    466  if (!reader.SkipBits(8))
    467  return seen_start_code;
    468  if (!reader.ReadBits(1, &extra))
    469  return seen_start_code;
    470  }
    471 
    472  // Next should be a Group of Blocks start code. Again, if we run out of
    473  // bits, then assume that the buffer up to here is correct, and the buffer
    474  // just happened to end in the middle of a header.
    475  int next;
    476  if (!reader.ReadBits(16, &next))
    477  return seen_start_code;
    478  RCHECK(next == 1);
    479 
    480  // Move to the next block.
    481  seen_start_code = true;
    482  offset += 4;
    483  }
    484 }
    485 
    486 // Checks for an H.263 container.
    487 static bool CheckH263(const uint8_t* buffer, int buffer_size) {
    488  // Reference: ITU-T Recommendation H.263 (01/2005)
    489  // (http://www.itu.int/rec/T-REC-H.263-200501-I/en)
    490  // header is PSC(22b) + TR(8b) + PTYPE(8+b).
    491  RCHECK(buffer_size > 16);
    492 
    493  int offset = 0;
    494  bool seen_start_code = false;
    495  while (true) {
    496  // Advance to picture_start_code, if there is one.
    497  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 9, 22, 0x20)) {
    498  // No start code found (or off end of buffer), so success if
    499  // there was at least one valid header.
    500  return seen_start_code;
    501  }
    502 
    503  // Now verify the block. AdvanceToStartCode() made sure that there are
    504  // at least 9 bytes remaining in the buffer.
    505  BitReader reader(buffer + offset, 9);
    506  RCHECK(ReadBits(&reader, 22) == 0x20);
    507 
    508  // Skip the temporal reference.
    509  reader.SkipBits(8);
    510 
    511  // Verify that the first 2 bits of PTYPE are 10b.
    512  RCHECK(ReadBits(&reader, 2) == 2);
    513 
    514  // Skip the split screen indicator, document camera indicator, and full
    515  // picture freeze release.
    516  reader.SkipBits(1 + 1 + 1);
    517 
    518  // Verify Source Format.
    519  int format = ReadBits(&reader, 3);
    520  RCHECK(format != 0 && format != 6); // Forbidden or reserved.
    521 
    522  if (format == 7) {
    523  // Verify full extended PTYPE.
    524  int ufep = ReadBits(&reader, 3);
    525  if (ufep == 1) {
    526  // Verify the optional part of PLUSPTYPE.
    527  format = ReadBits(&reader, 3);
    528  RCHECK(format != 0 && format != 7); // Reserved.
    529  reader.SkipBits(11);
    530  // Next 4 bits should be b1000.
    531  RCHECK(ReadBits(&reader, 4) == 8); // Not allowed.
    532  } else {
    533  RCHECK(ufep == 0); // Only 0 and 1 allowed.
    534  }
    535 
    536  // Verify picture type code is not a reserved value.
    537  int picture_type_code = ReadBits(&reader, 3);
    538  RCHECK(picture_type_code != 6 && picture_type_code != 7); // Reserved.
    539 
    540  // Skip picture resampling mode, reduced resolution mode,
    541  // and rounding type.
    542  reader.SkipBits(1 + 1 + 1);
    543 
    544  // Next 3 bits should be b001.
    545  RCHECK(ReadBits(&reader, 3) == 1); // Not allowed.
    546  }
    547 
    548  // Move to the next block.
    549  seen_start_code = true;
    550  offset += 9;
    551  }
    552 }
    553 
    554 // Checks for an H.264 container.
    555 static bool CheckH264(const uint8_t* buffer, int buffer_size) {
    556  // Reference: ITU-T Recommendation H.264 (01/2012)
    557  // (http://www.itu.int/rec/T-REC-H.264)
    558  // Section B.1: Byte stream NAL unit syntax and semantics.
    559  RCHECK(buffer_size > 4);
    560 
    561  int offset = 0;
    562  int parameter_count = 0;
    563  while (true) {
    564  // Advance to picture_start_code, if there is one.
    565  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 4, 24, 1)) {
    566  // No start code found (or off end of buffer), so success if
    567  // there was at least one valid header.
    568  return parameter_count > 0;
    569  }
    570 
    571  // Now verify the block. AdvanceToStartCode() made sure that there are
    572  // at least 4 bytes remaining in the buffer.
    573  BitReader reader(buffer + offset, 4);
    574  RCHECK(ReadBits(&reader, 24) == 1);
    575 
    576  // Verify forbidden_zero_bit.
    577  RCHECK(ReadBits(&reader, 1) == 0);
    578 
    579  // Extract nal_ref_idc and nal_unit_type.
    580  int nal_ref_idc = ReadBits(&reader, 2);
    581  int nal_unit_type = ReadBits(&reader, 5);
    582 
    583  switch (nal_unit_type) {
    584  case 5: // Coded slice of an IDR picture.
    585  RCHECK(nal_ref_idc != 0);
    586  break;
    587  case 6: // Supplemental enhancement information (SEI).
    588  case 9: // Access unit delimiter.
    589  case 10: // End of sequence.
    590  case 11: // End of stream.
    591  case 12: // Filler data.
    592  RCHECK(nal_ref_idc == 0);
    593  break;
    594  case 7: // Sequence parameter set.
    595  case 8: // Picture parameter set.
    596  ++parameter_count;
    597  break;
    598  }
    599 
    600  // Skip the current start_code_prefix and move to the next.
    601  offset += 4;
    602  }
    603 }
    604 
    605 static const char kHlsSignature[] = "#EXTM3U";
    606 static const char kHls1[] = "#EXT-X-STREAM-INF:";
    607 static const char kHls2[] = "#EXT-X-TARGETDURATION:";
    608 static const char kHls3[] = "#EXT-X-MEDIA-SEQUENCE:";
    609 
    610 // Additional checks for a HLS container.
    611 static bool CheckHls(const uint8_t* buffer, int buffer_size) {
    612  // HLS is simply a play list used for Apple HTTP Live Streaming.
    613  // Reference: Apple HTTP Live Streaming Overview
    614  // (http://goo.gl/MIwxj)
    615 
    616  if (StartsWith(buffer, buffer_size, kHlsSignature)) {
    617  // Need to find "#EXT-X-STREAM-INF:", "#EXT-X-TARGETDURATION:", or
    618  // "#EXT-X-MEDIA-SEQUENCE:" somewhere in the buffer. Other playlists (like
    619  // WinAmp) only have additional lines with #EXTINF
    620  // (http://en.wikipedia.org/wiki/M3U).
    621  int offset = strlen(kHlsSignature);
    622  while (offset < buffer_size) {
    623  if (buffer[offset] == '#') {
    624  if (StartsWith(buffer + offset, buffer_size - offset, kHls1) ||
    625  StartsWith(buffer + offset, buffer_size - offset, kHls2) ||
    626  StartsWith(buffer + offset, buffer_size - offset, kHls3)) {
    627  return true;
    628  }
    629  }
    630  ++offset;
    631  }
    632  }
    633  return false;
    634 }
    635 
    636 // Checks for a MJPEG stream.
    637 static bool CheckMJpeg(const uint8_t* buffer, int buffer_size) {
    638  // Reference: ISO/IEC 10918-1 : 1993(E), Annex B
    639  // (http://www.w3.org/Graphics/JPEG/itu-t81.pdf)
    640  RCHECK(buffer_size >= 16);
    641 
    642  int offset = 0;
    643  int last_restart = -1;
    644  int num_codes = 0;
    645  while (offset + 5 < buffer_size) {
    646  // Marker codes are always a two byte code with the first byte xFF.
    647  RCHECK(buffer[offset] == 0xff);
    648  uint8_t code = buffer[offset + 1];
    649  RCHECK(code >= 0xc0 || code == 1);
    650 
    651  // Skip sequences of xFF.
    652  if (code == 0xff) {
    653  ++offset;
    654  continue;
    655  }
    656 
    657  // Success if the next marker code is EOI (end of image)
    658  if (code == 0xd9)
    659  return true;
    660 
    661  // Check remaining codes.
    662  if (code == 0xd8 || code == 1) {
    663  // SOI (start of image) / TEM (private use). No other data with header.
    664  offset += 2;
    665  } else if (code >= 0xd0 && code <= 0xd7) {
    666  // RST (restart) codes must be in sequence. No other data with header.
    667  int restart = code & 0x07;
    668  if (last_restart >= 0)
    669  RCHECK(restart == (last_restart + 1) % 8);
    670  last_restart = restart;
    671  offset += 2;
    672  } else {
    673  // All remaining marker codes are followed by a length of the header.
    674  int length = Read16(buffer + offset + 2) + 2;
    675 
    676  // Special handling of SOS (start of scan) marker since the entropy
    677  // coded data follows the SOS. Any xFF byte in the data block must be
    678  // followed by x00 in the data.
    679  if (code == 0xda) {
    680  int number_components = buffer[offset + 4];
    681  RCHECK(length == 8 + 2 * number_components);
    682 
    683  // Advance to the next marker.
    684  offset += length;
    685  while (offset + 2 < buffer_size) {
    686  if (buffer[offset] == 0xff && buffer[offset + 1] != 0)
    687  break;
    688  ++offset;
    689  }
    690  } else {
    691  // Skip over the marker data for the other marker codes.
    692  offset += length;
    693  }
    694  }
    695  ++num_codes;
    696  }
    697  return (num_codes > 1);
    698 }
    699 
    700 enum Mpeg2StartCodes {
    701  PROGRAM_END_CODE = 0xb9,
    702  PACK_START_CODE = 0xba
    703 };
    704 
    705 // Checks for a MPEG2 Program Stream.
    706 static bool CheckMpeg2ProgramStream(const uint8_t* buffer, int buffer_size) {
    707  // Reference: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
    708  RCHECK(buffer_size > 14);
    709 
    710  int offset = 0;
    711  while (offset + 14 < buffer_size) {
    712  BitReader reader(buffer + offset, 14);
    713 
    714  // Must start with pack_start_code.
    715  RCHECK(ReadBits(&reader, 24) == 1);
    716  RCHECK(ReadBits(&reader, 8) == PACK_START_CODE);
    717 
    718  // Determine MPEG version (MPEG1 has b0010, while MPEG2 has b01).
    719  int mpeg_version = ReadBits(&reader, 2);
    720  if (mpeg_version == 0) {
    721  // MPEG1, 10 byte header
    722  // Validate rest of version code
    723  RCHECK(ReadBits(&reader, 2) == 2);
    724  } else {
    725  RCHECK(mpeg_version == 1);
    726  }
    727 
    728  // Skip system_clock_reference_base [32..30].
    729  reader.SkipBits(3);
    730 
    731  // Verify marker bit.
    732  RCHECK(ReadBits(&reader, 1) == 1);
    733 
    734  // Skip system_clock_reference_base [29..15].
    735  reader.SkipBits(15);
    736 
    737  // Verify next marker bit.
    738  RCHECK(ReadBits(&reader, 1) == 1);
    739 
    740  // Skip system_clock_reference_base [14..0].
    741  reader.SkipBits(15);
    742 
    743  // Verify next marker bit.
    744  RCHECK(ReadBits(&reader, 1) == 1);
    745 
    746  if (mpeg_version == 0) {
    747  // Verify second marker bit.
    748  RCHECK(ReadBits(&reader, 1) == 1);
    749 
    750  // Skip mux_rate.
    751  reader.SkipBits(22);
    752 
    753  // Verify next marker bit.
    754  RCHECK(ReadBits(&reader, 1) == 1);
    755 
    756  // Update offset to be after this header.
    757  offset += 12;
    758  } else {
    759  // Must be MPEG2.
    760  // Skip program_mux_rate.
    761  reader.SkipBits(22);
    762 
    763  // Verify pair of marker bits.
    764  RCHECK(ReadBits(&reader, 2) == 3);
    765 
    766  // Skip reserved.
    767  reader.SkipBits(5);
    768 
    769  // Update offset to be after this header.
    770  int pack_stuffing_length = ReadBits(&reader, 3);
    771  offset += 14 + pack_stuffing_length;
    772  }
    773 
    774  // Check for system headers and PES_packets.
    775  while (offset + 6 < buffer_size && Read24(buffer + offset) == 1) {
    776  // Next 8 bits determine stream type.
    777  int stream_id = buffer[offset + 3];
    778 
    779  // Some stream types are reserved and shouldn't occur.
    780  if (mpeg_version == 0)
    781  RCHECK(stream_id != 0xbc && stream_id < 0xf0);
    782  else
    783  RCHECK(stream_id != 0xfc && stream_id != 0xfd && stream_id != 0xfe);
    784 
    785  // Some stream types are used for pack headers.
    786  if (stream_id == PACK_START_CODE) // back to outer loop.
    787  break;
    788  if (stream_id == PROGRAM_END_CODE) // end of stream.
    789  return true;
    790 
    791  int pes_length = Read16(buffer + offset + 4);
    792  RCHECK(pes_length > 0);
    793  offset = offset + 6 + pes_length;
    794  }
    795  }
    796  // Success as we are off the end of the buffer and liked everything
    797  // in the buffer.
    798  return true;
    799 }
    800 
    801 const uint8_t kMpeg2SyncWord = 0x47;
    802 
    803 // Checks for a MPEG2 Transport Stream.
    804 static bool CheckMpeg2TransportStream(const uint8_t* buffer, int buffer_size) {
    805  // Spec: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
    806  // Normal packet size is 188 bytes. However, some systems add various error
    807  // correction data at the end, resulting in packet of length 192/204/208
    808  // (https://en.wikipedia.org/wiki/MPEG_transport_stream). Determine the
    809  // length with the first packet.
    810  RCHECK(buffer_size >= 250); // Want more than 1 packet to check.
    811 
    812  int offset = 0;
    813  int packet_length = -1;
    814  while (buffer[offset] != kMpeg2SyncWord && offset < 20) {
    815  // Skip over any header in the first 20 bytes.
    816  ++offset;
    817  }
    818 
    819  while (offset + 6 < buffer_size) {
    820  BitReader reader(buffer + offset, 6);
    821 
    822  // Must start with sync byte.
    823  RCHECK(ReadBits(&reader, 8) == kMpeg2SyncWord);
    824 
    825  // Skip transport_error_indicator, payload_unit_start_indicator, and
    826  // transport_priority.
    827  reader.SkipBits(1 + 1 + 1);
    828 
    829  // Verify the pid is not a reserved value.
    830  int pid = ReadBits(&reader, 13);
    831  RCHECK(pid < 3 || pid > 15);
    832 
    833  // Skip transport_scrambling_control.
    834  reader.SkipBits(2);
    835 
    836  // Adaptation_field_control can not be 0.
    837  int adaptation_field_control = ReadBits(&reader, 2);
    838  RCHECK(adaptation_field_control != 0);
    839 
    840  // If there is an adaptation_field, verify it.
    841  if (adaptation_field_control >= 2) {
    842  // Skip continuity_counter.
    843  reader.SkipBits(4);
    844 
    845  // Get adaptation_field_length and verify it.
    846  int adaptation_field_length = ReadBits(&reader, 8);
    847  if (adaptation_field_control == 2)
    848  RCHECK(adaptation_field_length == 183);
    849  else
    850  RCHECK(adaptation_field_length <= 182);
    851  }
    852 
    853  // Attempt to determine the packet length on the first packet.
    854  if (packet_length < 0) {
    855  if (buffer[offset + 188] == kMpeg2SyncWord)
    856  packet_length = 188;
    857  else if (buffer[offset + 192] == kMpeg2SyncWord)
    858  packet_length = 192;
    859  else if (buffer[offset + 204] == kMpeg2SyncWord)
    860  packet_length = 204;
    861  else
    862  packet_length = 208;
    863  }
    864  offset += packet_length;
    865  }
    866  return true;
    867 }
    868 
    869 enum Mpeg4StartCodes {
    870  VISUAL_OBJECT_SEQUENCE_START_CODE = 0xb0,
    871  VISUAL_OBJECT_SEQUENCE_END_CODE = 0xb1,
    872  VISUAL_OBJECT_START_CODE = 0xb5,
    873  VOP_START_CODE = 0xb6
    874 };
    875 
    876 // Checks for a raw MPEG4 bitstream container.
    877 static bool CheckMpeg4BitStream(const uint8_t* buffer, int buffer_size) {
    878  // Defined in ISO/IEC 14496-2:2001.
    879  // However, no length ... simply scan for start code values.
    880  // Note tags are very similar to H.264.
    881  RCHECK(buffer_size > 4);
    882 
    883  int offset = 0;
    884  int sequence_start_count = 0;
    885  int sequence_end_count = 0;
    886  int visual_object_count = 0;
    887  int vop_count = 0;
    888  while (true) {
    889  // Advance to start_code, if there is one.
    890  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 6, 24, 1)) {
    891  // Not a complete sequence in memory, so return true if we've seen a
    892  // visual_object_sequence_start_code and a visual_object_start_code.
    893  return (sequence_start_count > 0 && visual_object_count > 0);
    894  }
    895 
    896  // Now verify the block. AdvanceToStartCode() made sure that there are
    897  // at least 6 bytes remaining in the buffer.
    898  BitReader reader(buffer + offset, 6);
    899  RCHECK(ReadBits(&reader, 24) == 1);
    900 
    901  int start_code = ReadBits(&reader, 8);
    902  RCHECK(start_code < 0x30 || start_code > 0xaf); // 30..AF and
    903  RCHECK(start_code < 0xb7 || start_code > 0xb9); // B7..B9 reserved
    904 
    905  switch (start_code) {
    906  case VISUAL_OBJECT_SEQUENCE_START_CODE: {
    907  ++sequence_start_count;
    908  // Verify profile in not one of many reserved values.
    909  int profile = ReadBits(&reader, 8);
    910  RCHECK(profile > 0);
    911  RCHECK(profile < 0x04 || profile > 0x10);
    912  RCHECK(profile < 0x13 || profile > 0x20);
    913  RCHECK(profile < 0x23 || profile > 0x31);
    914  RCHECK(profile < 0x35 || profile > 0x41);
    915  RCHECK(profile < 0x43 || profile > 0x60);
    916  RCHECK(profile < 0x65 || profile > 0x70);
    917  RCHECK(profile < 0x73 || profile > 0x80);
    918  RCHECK(profile < 0x83 || profile > 0x90);
    919  RCHECK(profile < 0x95 || profile > 0xa0);
    920  RCHECK(profile < 0xa4 || profile > 0xb0);
    921  RCHECK(profile < 0xb5 || profile > 0xc0);
    922  RCHECK(profile < 0xc3 || profile > 0xd0);
    923  RCHECK(profile < 0xe4);
    924  break;
    925  }
    926 
    927  case VISUAL_OBJECT_SEQUENCE_END_CODE:
    928  RCHECK(++sequence_end_count == sequence_start_count);
    929  break;
    930 
    931  case VISUAL_OBJECT_START_CODE: {
    932  ++visual_object_count;
    933  if (ReadBits(&reader, 1) == 1) {
    934  int visual_object_verid = ReadBits(&reader, 4);
    935  RCHECK(visual_object_verid > 0 && visual_object_verid < 3);
    936  RCHECK(ReadBits(&reader, 3) != 0);
    937  }
    938  int visual_object_type = ReadBits(&reader, 4);
    939  RCHECK(visual_object_type > 0 && visual_object_type < 6);
    940  break;
    941  }
    942 
    943  case VOP_START_CODE:
    944  RCHECK(++vop_count <= visual_object_count);
    945  break;
    946  }
    947  // Skip this block.
    948  offset += 6;
    949  }
    950 }
    951 
    952 // Additional checks for a MOV/QuickTime/MPEG4 container.
    953 static bool CheckMov(const uint8_t* buffer, int buffer_size) {
    954  // Reference: ISO/IEC 14496-12:2005(E).
    955  // (http://standards.iso.org/ittf/PubliclyAvailableStandards/c061988_ISO_IEC_14496-12_2012.zip)
    956  RCHECK(buffer_size > 8);
    957 
    958  int offset = 0;
    959  int boxes_seen = 0;
    960  while (offset + 8 < buffer_size) {
    961  int atomsize = Read32(buffer + offset);
    962  uint32_t atomtype = Read32(buffer + offset + 4);
    963  // Only need to check for ones that are valid at the top level.
    964  switch (atomtype) {
    965  case TAG('f','t','y','p'):
    966  case TAG('p','d','i','n'):
    967  case TAG('b','l','o','c'):
    968  case TAG('m','o','o','v'):
    969  case TAG('m','o','o','f'):
    970  case TAG('m','f','r','a'):
    971  case TAG('m','d','a','t'):
    972  case TAG('f','r','e','e'):
    973  case TAG('s','k','i','p'):
    974  case TAG('m','e','t','a'):
    975  case TAG('m','e','c','o'):
    976  case TAG('s','t','y','p'):
    977  case TAG('s','i','d','x'):
    978  case TAG('s','s','i','x'):
    979  case TAG('p','r','f','t'):
    980  case TAG('u','u','i','d'):
    981  // Assumes that it is an iso-bmff file after seeing two known boxes.
    982  // Note that it is correct only for our use cases as we support only
    983  // a limited number of containers, and there is no other container
    984  // has this behavior.
    985  if (++boxes_seen >= 2)
    986  return true;
    987  break;
    988  default:
    989  // Ignore unrecognized box.
    990  break;
    991  }
    992  if (atomsize == 1) {
    993  // Indicates that the length is the next 64bits.
    994  if (offset + 16 > buffer_size)
    995  break;
    996  if (Read32(buffer + offset + 8) != 0)
    997  break; // Offset is way past buffer size.
    998  atomsize = Read32(buffer + offset + 12);
    999  }
    1000  if (atomsize <= 0)
    1001  break; // Indicates the last atom or length too big.
    1002  offset += atomsize;
    1003  }
    1004  return false;
    1005 }
    1006 
    1007 enum MPEGVersion {
    1008  VERSION_25 = 0,
    1009  VERSION_RESERVED,
    1010  VERSION_2,
    1011  VERSION_1
    1012 };
    1013 enum MPEGLayer {
    1014  L_RESERVED = 0,
    1015  LAYER_3,
    1016  LAYER_2,
    1017  LAYER_1
    1018 };
    1019 
    1020 static int kSampleRateTable[4][4] = { { 11025, 12000, 8000, 0 }, // v2.5
    1021  { 0, 0, 0, 0 }, // not used
    1022  { 22050, 24000, 16000, 0 }, // v2
    1023  { 44100, 48000, 32000, 0 } // v1
    1024 };
    1025 
    1026 static int kBitRateTableV1L1[16] = { 0, 32, 64, 96, 128, 160, 192, 224, 256,
    1027  288, 320, 352, 384, 416, 448, 0 };
    1028 static int kBitRateTableV1L2[16] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160,
    1029  192, 224, 256, 320, 384, 0 };
    1030 static int kBitRateTableV1L3[16] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128,
    1031  160, 192, 224, 256, 320, 0 };
    1032 static int kBitRateTableV2L1[16] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
    1033  160, 176, 192, 224, 256, 0 };
    1034 static int kBitRateTableV2L23[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,
    1035  112, 128, 144, 160, 0 };
    1036 
    1037 static bool ValidMpegAudioFrameHeader(const uint8_t* header,
    1038  int header_size,
    1039  int* framesize) {
    1040  // Reference: http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm.
    1041  DCHECK_GE(header_size, 4);
    1042  *framesize = 0;
    1043  BitReader reader(header, 4); // Header can only be 4 bytes long.
    1044 
    1045  // Verify frame sync (11 bits) are all set.
    1046  RCHECK(ReadBits(&reader, 11) == 0x7ff);
    1047 
    1048  // Verify MPEG audio version id.
    1049  int version = ReadBits(&reader, 2);
    1050  RCHECK(version != 1); // Reserved.
    1051 
    1052  // Verify layer.
    1053  int layer = ReadBits(&reader, 2);
    1054  RCHECK(layer != 0);
    1055 
    1056  // Skip protection bit.
    1057  reader.SkipBits(1);
    1058 
    1059  // Verify bitrate index.
    1060  int bitrate_index = ReadBits(&reader, 4);
    1061  RCHECK(bitrate_index != 0xf);
    1062 
    1063  // Verify sampling rate frequency index.
    1064  int sampling_index = ReadBits(&reader, 2);
    1065  RCHECK(sampling_index != 3);
    1066 
    1067  // Get padding bit.
    1068  int padding = ReadBits(&reader, 1);
    1069 
    1070  // Frame size:
    1071  // For Layer I files = (12 * BitRate / SampleRate + Padding) * 4
    1072  // For others = 144 * BitRate / SampleRate + Padding
    1073  // Unfortunately, BitRate and SampleRate are coded.
    1074  int sampling_rate = kSampleRateTable[version][sampling_index];
    1075  int bitrate;
    1076  if (version == VERSION_1) {
    1077  if (layer == LAYER_1)
    1078  bitrate = kBitRateTableV1L1[bitrate_index];
    1079  else if (layer == LAYER_2)
    1080  bitrate = kBitRateTableV1L2[bitrate_index];
    1081  else
    1082  bitrate = kBitRateTableV1L3[bitrate_index];
    1083  } else {
    1084  if (layer == LAYER_1)
    1085  bitrate = kBitRateTableV2L1[bitrate_index];
    1086  else
    1087  bitrate = kBitRateTableV2L23[bitrate_index];
    1088  }
    1089  if (layer == LAYER_1)
    1090  *framesize = ((12000 * bitrate) / sampling_rate + padding) * 4;
    1091  else
    1092  *framesize = (144000 * bitrate) / sampling_rate + padding;
    1093  return (bitrate > 0 && sampling_rate > 0);
    1094 }
    1095 
    1096 // Extract a size encoded the MP3 way.
    1097 static int GetMp3HeaderSize(const uint8_t* buffer, int buffer_size) {
    1098  DCHECK_GE(buffer_size, 9);
    1099  int size = ((buffer[6] & 0x7f) << 21) + ((buffer[7] & 0x7f) << 14) +
    1100  ((buffer[8] & 0x7f) << 7) + (buffer[9] & 0x7f) + 10;
    1101  if (buffer[5] & 0x10) // Footer added?
    1102  size += 10;
    1103  return size;
    1104 }
    1105 
    1106 // Additional checks for a MP3 container.
    1107 static bool CheckMp3(const uint8_t* buffer, int buffer_size, bool seenHeader) {
    1108  RCHECK(buffer_size >= 10); // Must be enough to read the initial header.
    1109 
    1110  int framesize;
    1111  int numSeen = 0;
    1112  int offset = 0;
    1113  if (seenHeader) {
    1114  offset = GetMp3HeaderSize(buffer, buffer_size);
    1115  } else {
    1116  // Skip over leading 0's.
    1117  while (offset < buffer_size && buffer[offset] == 0)
    1118  ++offset;
    1119  }
    1120 
    1121  while (offset + 3 < buffer_size) {
    1122  RCHECK(ValidMpegAudioFrameHeader(
    1123  buffer + offset, buffer_size - offset, &framesize));
    1124 
    1125  // Have we seen enough valid headers?
    1126  if (++numSeen > 10)
    1127  return true;
    1128  offset += framesize;
    1129  }
    1130  // Off the end of the buffer, return success if a few valid headers seen.
    1131  return numSeen > 2;
    1132 }
    1133 
    1134 // Check that the next characters in |buffer| represent a number. The format
    1135 // accepted is optional whitespace followed by 1 or more digits. |max_digits|
    1136 // specifies the maximum number of digits to process. Returns true if a valid
    1137 // number is found, false otherwise.
    1138 static bool VerifyNumber(const uint8_t* buffer,
    1139  int buffer_size,
    1140  int* offset,
    1141  int max_digits) {
    1142  RCHECK(*offset < buffer_size);
    1143 
    1144  // Skip over any leading space.
    1145  while (isspace(buffer[*offset])) {
    1146  ++(*offset);
    1147  RCHECK(*offset < buffer_size);
    1148  }
    1149 
    1150  // Need to process up to max_digits digits.
    1151  int numSeen = 0;
    1152  while (--max_digits >= 0 && isdigit(buffer[*offset])) {
    1153  ++numSeen;
    1154  ++(*offset);
    1155  if (*offset >= buffer_size)
    1156  return true; // Out of space but seen a digit.
    1157  }
    1158 
    1159  // Success if at least one digit seen.
    1160  return (numSeen > 0);
    1161 }
    1162 
    1163 // Check that the next character in |buffer| is one of |c1| or |c2|. |c2| is
    1164 // optional. Returns true if there is a match, false if no match or out of
    1165 // space.
    1166 static inline bool VerifyCharacters(const uint8_t* buffer,
    1167  int buffer_size,
    1168  int* offset,
    1169  char c1,
    1170  char c2) {
    1171  RCHECK(*offset < buffer_size);
    1172  char c = static_cast<char>(buffer[(*offset)++]);
    1173  return (c == c1 || (c == c2 && c2 != 0));
    1174 }
    1175 
    1176 // Checks for a SRT container.
    1177 static bool CheckSrt(const uint8_t* buffer, int buffer_size) {
    1178  // Reference: http://en.wikipedia.org/wiki/SubRip
    1179  RCHECK(buffer_size > 20);
    1180 
    1181  // First line should just be the subtitle sequence number.
    1182  int offset = StartsWith(buffer, buffer_size, UTF8_BYTE_ORDER_MARK) ? 3 : 0;
    1183  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 100));
    1184  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, '\n', '\r'));
    1185 
    1186  // Skip any additional \n\r.
    1187  while (VerifyCharacters(buffer, buffer_size, &offset, '\n', '\r')) {}
    1188  --offset; // Since VerifyCharacters() gobbled up the next non-CR/LF.
    1189 
    1190  // Second line should look like the following:
    1191  // 00:00:10,500 --> 00:00:13,000
    1192  // Units separator can be , or .
    1193  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 100));
    1194  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ':', 0));
    1195  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 2));
    1196  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ':', 0));
    1197  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 2));
    1198  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ',', '.'));
    1199  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 3));
    1200  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ' ', 0));
    1201  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, '-', 0));
    1202  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, '-', 0));
    1203  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, '>', 0));
    1204  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ' ', 0));
    1205  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 100));
    1206  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ':', 0));
    1207  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 2));
    1208  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ':', 0));
    1209  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 2));
    1210  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ',', '.'));
    1211  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 3));
    1212  return true;
    1213 }
    1214 
    1215 // Read a Matroska Element Id.
    1216 static int GetElementId(BitReader* reader) {
    1217  // Element ID is coded with the leading zero bits (max 3) determining size.
    1218  // If it is an invalid encoding or the end of the buffer is reached,
    1219  // return -1 as a tag that won't be expected.
    1220  if (reader->bits_available() >= 8) {
    1221  int num_bits_to_read = 0;
    1222  static int prefix[] = { 0x80, 0x4000, 0x200000, 0x10000000 };
    1223  for (int i = 0; i < 4; ++i) {
    1224  num_bits_to_read += 7;
    1225  if (ReadBits(reader, 1) == 1) {
    1226  if (static_cast<int>(reader->bits_available()) < num_bits_to_read)
    1227  break;
    1228  // prefix[] adds back the bits read individually.
    1229  return ReadBits(reader, num_bits_to_read) | prefix[i];
    1230  }
    1231  }
    1232  }
    1233  // Invalid encoding, return something not expected.
    1234  return -1;
    1235 }
    1236 
    1237 // Read a Matroska Unsigned Integer (VINT).
    1238 static uint64_t GetVint(BitReader* reader) {
    1239  // Values are coded with the leading zero bits (max 7) determining size.
    1240  // If it is an invalid coding or the end of the buffer is reached,
    1241  // return something that will go off the end of the buffer.
    1242  if (reader->bits_available() >= 8) {
    1243  int num_bits_to_read = 0;
    1244  for (int i = 0; i < 8; ++i) {
    1245  num_bits_to_read += 7;
    1246  if (ReadBits(reader, 1) == 1) {
    1247  if (static_cast<int>(reader->bits_available()) < num_bits_to_read)
    1248  break;
    1249  return ReadBits(reader, num_bits_to_read);
    1250  }
    1251  }
    1252  }
    1253  // Incorrect format (more than 7 leading 0's) or off the end of the buffer.
    1254  // Since the return value is used as a byte size, return a value that will
    1255  // cause a failure when used.
    1256  return (reader->bits_available() / 8) + 2;
    1257 }
    1258 
    1259 // Additional checks for a WEBM container.
    1260 static bool CheckWebm(const uint8_t* buffer, int buffer_size) {
    1261  // Reference: http://www.matroska.org/technical/specs/index.html
    1262  RCHECK(buffer_size > 12);
    1263 
    1264  BitReader reader(buffer, buffer_size);
    1265 
    1266  // Verify starting Element Id.
    1267  RCHECK(GetElementId(&reader) == 0x1a45dfa3);
    1268 
    1269  // Get the header size, and ensure there are enough bits to check.
    1270  int header_size = GetVint(&reader);
    1271  RCHECK(static_cast<int>(reader.bits_available()) / 8 >= header_size);
    1272 
    1273  // Loop through the header.
    1274  while (reader.bits_available() > 0) {
    1275  int tag = GetElementId(&reader);
    1276  int tagsize = GetVint(&reader);
    1277  switch (tag) {
    1278  case 0x4286: // EBMLVersion
    1279  case 0x42f7: // EBMLReadVersion
    1280  case 0x42f2: // EBMLMaxIdLength
    1281  case 0x42f3: // EBMLMaxSizeLength
    1282  case 0x4287: // DocTypeVersion
    1283  case 0x4285: // DocTypeReadVersion
    1284  case 0xec: // void
    1285  case 0xbf: // CRC32
    1286  RCHECK(reader.SkipBits(tagsize * 8));
    1287  break;
    1288 
    1289  case 0x4282: // EBMLDocType
    1290  // Need to see "webm" or "matroska" next.
    1291  switch (ReadBits(&reader, 32)) {
    1292  case TAG('w', 'e', 'b', 'm') :
    1293  return true;
    1294  case TAG('m', 'a', 't', 'r') :
    1295  return (ReadBits(&reader, 32) == TAG('o', 's', 'k', 'a'));
    1296  }
    1297  return false;
    1298 
    1299  default: // Unrecognized tag
    1300  return false;
    1301  }
    1302  }
    1303  return false;
    1304 }
    1305 
    1306 enum VC1StartCodes {
    1307  VC1_FRAME_START_CODE = 0x0d,
    1308  VC1_ENTRY_POINT_START_CODE = 0x0e,
    1309  VC1_SEQUENCE_START_CODE = 0x0f
    1310 };
    1311 
    1312 // Checks for a VC1 bitstream container.
    1313 static bool CheckVC1(const uint8_t* buffer, int buffer_size) {
    1314  // Reference: SMPTE 421M
    1315  // (http://standards.smpte.org/content/978-1-61482-555-5/st-421-2006/SEC1.body.pdf)
    1316  // However, no length ... simply scan for start code values.
    1317  // Expect to see SEQ | [ [ ENTRY ] PIC* ]*
    1318  // Note tags are very similar to H.264.
    1319 
    1320  RCHECK(buffer_size >= 24);
    1321 
    1322  // First check for Bitstream Metadata Serialization (Annex L)
    1323  if (buffer[0] == 0xc5 &&
    1324  Read32(buffer + 4) == 0x04 &&
    1325  Read32(buffer + 20) == 0x0c) {
    1326  // Verify settings in STRUCT_C and STRUCT_A
    1327  BitReader reader(buffer + 8, 12);
    1328 
    1329  int profile = ReadBits(&reader, 4);
    1330  if (profile == 0 || profile == 4) { // simple or main
    1331  // Skip FRMRTQ_POSTPROC, BITRTQ_POSTPROC, and LOOPFILTER.
    1332  reader.SkipBits(3 + 5 + 1);
    1333 
    1334  // Next bit must be 0.
    1335  RCHECK(ReadBits(&reader, 1) == 0);
    1336 
    1337  // Skip MULTIRES.
    1338  reader.SkipBits(1);
    1339 
    1340  // Next bit must be 1.
    1341  RCHECK(ReadBits(&reader, 1) == 1);
    1342 
    1343  // Skip FASTUVMC, EXTENDED_MV, DQUANT, and VSTRANSFORM.
    1344  reader.SkipBits(1 + 1 + 2 + 1);
    1345 
    1346  // Next bit must be 0.
    1347  RCHECK(ReadBits(&reader, 1) == 0);
    1348 
    1349  // Skip OVERLAP, SYNCMARKER, RANGERED, MAXBFRAMES, QUANTIZER, and
    1350  // FINTERPFLAG.
    1351  reader.SkipBits(1 + 1 + 1 + 3 + 2 + 1);
    1352 
    1353  // Next bit must be 1.
    1354  RCHECK(ReadBits(&reader, 1) == 1);
    1355 
    1356  } else {
    1357  RCHECK(profile == 12); // Other profile values not allowed.
    1358  RCHECK(ReadBits(&reader, 28) == 0);
    1359  }
    1360 
    1361  // Now check HORIZ_SIZE and VERT_SIZE, which must be 8192 or less.
    1362  RCHECK(ReadBits(&reader, 32) <= 8192);
    1363  RCHECK(ReadBits(&reader, 32) <= 8192);
    1364  return true;
    1365  }
    1366 
    1367  // Buffer isn't Bitstream Metadata, so scan for start codes.
    1368  int offset = 0;
    1369  int sequence_start_code = 0;
    1370  int frame_start_code = 0;
    1371  while (true) {
    1372  // Advance to start_code, if there is one.
    1373  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 5, 24, 1)) {
    1374  // Not a complete sequence in memory, so return true if we've seen a
    1375  // sequence start and a frame start (not checking entry points since
    1376  // they only occur in advanced profiles).
    1377  return (sequence_start_code > 0 && frame_start_code > 0);
    1378  }
    1379 
    1380  // Now verify the block. AdvanceToStartCode() made sure that there are
    1381  // at least 5 bytes remaining in the buffer.
    1382  BitReader reader(buffer + offset, 5);
    1383  RCHECK(ReadBits(&reader, 24) == 1);
    1384 
    1385  // Keep track of the number of certain types received.
    1386  switch (ReadBits(&reader, 8)) {
    1387  case VC1_SEQUENCE_START_CODE: {
    1388  ++sequence_start_code;
    1389  switch (ReadBits(&reader, 2)) {
    1390  case 0: // simple
    1391  case 1: // main
    1392  RCHECK(ReadBits(&reader, 2) == 0);
    1393  break;
    1394  case 2: // complex
    1395  return false;
    1396  case 3: // advanced
    1397  RCHECK(ReadBits(&reader, 3) <= 4); // Verify level = 0..4
    1398  RCHECK(ReadBits(&reader, 2) == 1); // Verify colordiff_format = 1
    1399  break;
    1400  }
    1401  break;
    1402  }
    1403 
    1404  case VC1_ENTRY_POINT_START_CODE:
    1405  // No fields in entry data to check. However, it must occur after
    1406  // sequence header.
    1407  RCHECK(sequence_start_code > 0);
    1408  break;
    1409 
    1410  case VC1_FRAME_START_CODE:
    1411  ++frame_start_code;
    1412  break;
    1413  }
    1414  offset += 5;
    1415  }
    1416 }
    1417 
    1418 // For some formats the signature is a bunch of characters. They are defined
    1419 // below. Note that the first 4 characters of the string may be used as a TAG
    1420 // in LookupContainerByFirst4. For signatures that contain embedded \0, use
    1421 // uint8_t[].
    1422 static const char kAmrSignature[] = "#!AMR";
    1423 static const uint8_t kAsfSignature[] = {0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66,
    1424  0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa,
    1425  0x00, 0x62, 0xce, 0x6c};
    1426 static const char kAssSignature[] = "[Script Info]";
    1427 static const char kAssBomSignature[] = UTF8_BYTE_ORDER_MARK "[Script Info]";
    1428 static const uint8_t kWtvSignature[] = {0xb7, 0xd8, 0x00, 0x20, 0x37, 0x49,
    1429  0xda, 0x11, 0xa6, 0x4e, 0x00, 0x07,
    1430  0xe9, 0x5e, 0xad, 0x8d};
    1431 
    1432 // Attempt to determine the container type from the buffer provided. This is
    1433 // a simple pass, that uses the first 4 bytes of the buffer as an index to get
    1434 // a rough idea of the container format.
    1435 static MediaContainerName LookupContainerByFirst4(const uint8_t* buffer,
    1436  int buffer_size) {
    1437  // Minimum size that the code expects to exist without checking size.
    1438  if (buffer_size < 12)
    1439  return CONTAINER_UNKNOWN;
    1440 
    1441  uint32_t first4 = Read32(buffer);
    1442  switch (first4) {
    1443  case 0x1a45dfa3:
    1444  if (CheckWebm(buffer, buffer_size))
    1445  return CONTAINER_WEBM;
    1446  break;
    1447 
    1448  case 0x3026b275:
    1449  if (StartsWith(buffer,
    1450  buffer_size,
    1451  kAsfSignature,
    1452  sizeof(kAsfSignature))) {
    1453  return CONTAINER_ASF;
    1454  }
    1455  break;
    1456 
    1457  case TAG('#','!','A','M'):
    1458  if (StartsWith(buffer, buffer_size, kAmrSignature))
    1459  return CONTAINER_AMR;
    1460  break;
    1461 
    1462  case TAG('#','E','X','T'):
    1463  if (CheckHls(buffer, buffer_size))
    1464  return CONTAINER_HLS;
    1465  break;
    1466 
    1467  case TAG('.','R','M','F'):
    1468  if (buffer[4] == 0 && buffer[5] == 0)
    1469  return CONTAINER_RM;
    1470  break;
    1471 
    1472  case TAG('.','r','a','\xfd'):
    1473  return CONTAINER_RM;
    1474 
    1475  case TAG('B','I','K','b'):
    1476  case TAG('B','I','K','d'):
    1477  case TAG('B','I','K','f'):
    1478  case TAG('B','I','K','g'):
    1479  case TAG('B','I','K','h'):
    1480  case TAG('B','I','K','i'):
    1481  if (CheckBink(buffer, buffer_size))
    1482  return CONTAINER_BINK;
    1483  break;
    1484 
    1485  case TAG('c','a','f','f'):
    1486  if (CheckCaf(buffer, buffer_size))
    1487  return CONTAINER_CAF;
    1488  break;
    1489 
    1490  case TAG('D','E','X','A'):
    1491  if (buffer_size > 15 &&
    1492  Read16(buffer + 11) <= 2048 &&
    1493  Read16(buffer + 13) <= 2048) {
    1494  return CONTAINER_DXA;
    1495  }
    1496  break;
    1497 
    1498  case TAG('D','T','S','H'):
    1499  if (Read32(buffer + 4) == TAG('D','H','D','R'))
    1500  return CONTAINER_DTSHD;
    1501  break;
    1502 
    1503  case 0x64a30100:
    1504  case 0x64a30200:
    1505  case 0x64a30300:
    1506  case 0x64a30400:
    1507  case 0x0001a364:
    1508  case 0x0002a364:
    1509  case 0x0003a364:
    1510  if (Read32(buffer + 4) != 0 && Read32(buffer + 8) != 0)
    1511  return CONTAINER_IRCAM;
    1512  break;
    1513 
    1514  case TAG('f','L','a','C'):
    1515  return CONTAINER_FLAC;
    1516 
    1517  case TAG('F','L','V',0):
    1518  case TAG('F','L','V',1):
    1519  case TAG('F','L','V',2):
    1520  case TAG('F','L','V',3):
    1521  case TAG('F','L','V',4):
    1522  if (buffer[5] == 0 && Read32(buffer + 5) > 8)
    1523  return CONTAINER_FLV;
    1524  break;
    1525 
    1526  case TAG('F','O','R','M'):
    1527  switch (Read32(buffer + 8)) {
    1528  case TAG('A','I','F','F'):
    1529  case TAG('A','I','F','C'):
    1530  return CONTAINER_AIFF;
    1531  }
    1532  break;
    1533 
    1534  case TAG('M','A','C',' '):
    1535  return CONTAINER_APE;
    1536 
    1537  case TAG('O','N','2',' '):
    1538  if (Read32(buffer + 8) == TAG('O','N','2','f'))
    1539  return CONTAINER_AVI;
    1540  break;
    1541 
    1542  case TAG('O','g','g','S'):
    1543  if (buffer[5] <= 7)
    1544  return CONTAINER_OGG;
    1545  break;
    1546 
    1547  case TAG('R','F','6','4'):
    1548  if (buffer_size > 16 && Read32(buffer + 12) == TAG('d','s','6','4'))
    1549  return CONTAINER_WAV;
    1550  break;
    1551 
    1552  case TAG('R','I','F','F'):
    1553  switch (Read32(buffer + 8)) {
    1554  case TAG('A','V','I',' '):
    1555  case TAG('A','V','I','X'):
    1556  case TAG('A','V','I','\x19'):
    1557  case TAG('A','M','V',' '):
    1558  return CONTAINER_AVI;
    1559  case TAG('W','A','V','E'):
    1560  return CONTAINER_WAV;
    1561  }
    1562  break;
    1563 
    1564  case TAG('[','S','c','r'):
    1565  if (StartsWith(buffer, buffer_size, kAssSignature))
    1566  return CONTAINER_ASS;
    1567  break;
    1568 
    1569  case TAG('\xef','\xbb','\xbf','['):
    1570  if (StartsWith(buffer, buffer_size, kAssBomSignature))
    1571  return CONTAINER_ASS;
    1572  break;
    1573 
    1574  case 0x7ffe8001:
    1575  case 0xfe7f0180:
    1576  case 0x1fffe800:
    1577  case 0xff1f00e8:
    1578  if (CheckDts(buffer, buffer_size))
    1579  return CONTAINER_DTS;
    1580  break;
    1581 
    1582  case 0xb7d80020:
    1583  if (StartsWith(buffer,
    1584  buffer_size,
    1585  kWtvSignature,
    1586  sizeof(kWtvSignature))) {
    1587  return CONTAINER_WTV;
    1588  }
    1589  break;
    1590  case 0x000001ba:
    1591  return CONTAINER_MPEG2PS;
    1592  }
    1593 
    1594  // Now try a few different ones that look at something other
    1595  // than the first 4 bytes.
    1596  uint32_t first3 = first4 & 0xffffff00;
    1597  switch (first3) {
    1598  case TAG('C','W','S',0):
    1599  case TAG('F','W','S',0):
    1600  return CONTAINER_SWF;
    1601 
    1602  case TAG('I','D','3',0):
    1603  if (CheckMp3(buffer, buffer_size, true))
    1604  return CONTAINER_MP3;
    1605  break;
    1606  }
    1607 
    1608  // Maybe the first 2 characters are something we can use.
    1609  uint32_t first2 = Read16(buffer);
    1610  switch (first2) {
    1611  case kAc3SyncWord:
    1612  if (CheckAc3(buffer, buffer_size))
    1613  return CONTAINER_AC3;
    1614  if (CheckEac3(buffer, buffer_size))
    1615  return CONTAINER_EAC3;
    1616  break;
    1617 
    1618  case 0xfff0:
    1619  case 0xfff1:
    1620  case 0xfff8:
    1621  case 0xfff9:
    1622  if (CheckAac(buffer, buffer_size))
    1623  return CONTAINER_AAC;
    1624  break;
    1625  }
    1626 
    1627  // Check if the file is in MP3 format without the header.
    1628  if (CheckMp3(buffer, buffer_size, false))
    1629  return CONTAINER_MP3;
    1630 
    1631  return CONTAINER_UNKNOWN;
    1632 }
    1633 
    1634 namespace {
    1635 const char kWebVtt[] = "WEBVTT";
    1636 
    1637 bool CheckWebVtt(const uint8_t* buffer, int buffer_size) {
    1638  const int offset =
    1639  StartsWith(buffer, buffer_size, UTF8_BYTE_ORDER_MARK) ? 3 : 0;
    1640 
    1641  return StartsWith(buffer + offset, buffer_size - offset,
    1642  reinterpret_cast<const uint8_t*>(kWebVtt),
    1643  arraysize(kWebVtt) - 1);
    1644 }
    1645 
    1646 bool CheckTtml(const uint8_t* buffer, int buffer_size) {
    1647  // Sanity check first before reading the entire thing.
    1648  if (!StartsWith(buffer, buffer_size, "<?xml"))
    1649  return false;
    1650 
    1651  // Make sure that it can be parsed so that it doesn't error later in the
    1652  // process. Not doing a schema check to allow TTMLs that makes some sense but
    1653  // not necessarily compliant to the schema.
    1654  xml::scoped_xml_ptr<xmlDoc> doc(
    1655  xmlParseMemory(reinterpret_cast<const char*>(buffer), buffer_size));
    1656  if (!doc)
    1657  return false;
    1658 
    1659  xmlNodePtr root_node = xmlDocGetRootElement(doc.get());
    1660  std::string root_node_name(reinterpret_cast<const char*>(root_node->name));
    1661  // "tt" is supposed to be the top level element for ttml.
    1662  return root_node_name == "tt";
    1663 }
    1664 
    1665 } // namespace
    1666 
    1667 // Attempt to determine the container name from the buffer provided.
    1668 MediaContainerName DetermineContainer(const uint8_t* buffer, int buffer_size) {
    1669  DCHECK(buffer);
    1670 
    1671  // Since MOV/QuickTime/MPEG4 streams are common, check for them first.
    1672  if (CheckMov(buffer, buffer_size))
    1673  return CONTAINER_MOV;
    1674 
    1675  // Next attempt the simple checks, that typically look at just the
    1676  // first few bytes of the file.
    1677  MediaContainerName result = LookupContainerByFirst4(buffer, buffer_size);
    1678  if (result != CONTAINER_UNKNOWN)
    1679  return result;
    1680 
    1681  // WebVTT check only checks for the first few bytes.
    1682  if (CheckWebVtt(buffer, buffer_size))
    1683  return CONTAINER_WEBVTT;
    1684 
    1685  // Additional checks that may scan a portion of the buffer.
    1686  if (CheckMpeg2ProgramStream(buffer, buffer_size))
    1687  return CONTAINER_MPEG2PS;
    1688  if (CheckMpeg2TransportStream(buffer, buffer_size))
    1689  return CONTAINER_MPEG2TS;
    1690  if (CheckMJpeg(buffer, buffer_size))
    1691  return CONTAINER_MJPEG;
    1692  if (CheckDV(buffer, buffer_size))
    1693  return CONTAINER_DV;
    1694  if (CheckH261(buffer, buffer_size))
    1695  return CONTAINER_H261;
    1696  if (CheckH263(buffer, buffer_size))
    1697  return CONTAINER_H263;
    1698  if (CheckH264(buffer, buffer_size))
    1699  return CONTAINER_H264;
    1700  if (CheckMpeg4BitStream(buffer, buffer_size))
    1701  return CONTAINER_MPEG4BS;
    1702  if (CheckVC1(buffer, buffer_size))
    1703  return CONTAINER_VC1;
    1704  if (CheckSrt(buffer, buffer_size))
    1705  return CONTAINER_SRT;
    1706  if (CheckGsm(buffer, buffer_size))
    1707  return CONTAINER_GSM;
    1708 
    1709  // AC3/EAC3 might not start at the beginning of the stream,
    1710  // so scan for a start code.
    1711  int offset = 1; // No need to start at byte 0 due to First4 check.
    1712  if (AdvanceToStartCode(buffer, buffer_size, &offset, 4, 16, kAc3SyncWord)) {
    1713  if (CheckAc3(buffer + offset, buffer_size - offset))
    1714  return CONTAINER_AC3;
    1715  if (CheckEac3(buffer + offset, buffer_size - offset))
    1716  return CONTAINER_EAC3;
    1717  }
    1718 
    1719  // To do a TTML check, it parses the XML which requires scanning
    1720  // the whole content.
    1721  if (CheckTtml(buffer, buffer_size))
    1722  return CONTAINER_TTML;
    1723 
    1724  return CONTAINER_UNKNOWN;
    1725 }
    1726 
    1727 MediaContainerName DetermineContainerFromFormatName(
    1728  const std::string& format_name) {
    1729  if (base::EqualsCaseInsensitiveASCII(format_name, "aac") ||
    1730  base::EqualsCaseInsensitiveASCII(format_name, "adts")) {
    1731  return CONTAINER_AAC;
    1732  } else if (base::EqualsCaseInsensitiveASCII(format_name, "ac3")) {
    1733  return CONTAINER_AC3;
    1734  } else if (base::EqualsCaseInsensitiveASCII(format_name, "ec3") ||
    1735  base::EqualsCaseInsensitiveASCII(format_name, "eac3")) {
    1736  return CONTAINER_EAC3;
    1737  } else if (base::EqualsCaseInsensitiveASCII(format_name, "webm")) {
    1738  return CONTAINER_WEBM;
    1739  } else if (base::EqualsCaseInsensitiveASCII(format_name, "cmfa") ||
    1740  base::EqualsCaseInsensitiveASCII(format_name, "cmft") ||
    1741  base::EqualsCaseInsensitiveASCII(format_name, "cmfv") ||
    1742  base::EqualsCaseInsensitiveASCII(format_name, "m4a") ||
    1743  base::EqualsCaseInsensitiveASCII(format_name, "m4s") ||
    1744  base::EqualsCaseInsensitiveASCII(format_name, "m4v") ||
    1745  base::EqualsCaseInsensitiveASCII(format_name, "mov") ||
    1746  base::EqualsCaseInsensitiveASCII(format_name, "mp4")) {
    1747  return CONTAINER_MOV;
    1748  } else if (base::EqualsCaseInsensitiveASCII(format_name, "ts") ||
    1749  base::EqualsCaseInsensitiveASCII(format_name, "mpeg2ts")) {
    1750  return CONTAINER_MPEG2TS;
    1751  } else if (base::EqualsCaseInsensitiveASCII(format_name, "wvm")) {
    1752  return CONTAINER_WVM;
    1753  } else if (base::EqualsCaseInsensitiveASCII(format_name, "vtt") ||
    1754  base::EqualsCaseInsensitiveASCII(format_name, "webvtt")) {
    1755  return CONTAINER_WEBVTT;
    1756  } else if (base::EqualsCaseInsensitiveASCII(format_name, "ttml") ||
    1757  // Treat xml as ttml.
    1758  base::EqualsCaseInsensitiveASCII(format_name, "xml")) {
    1759  return CONTAINER_TTML;
    1760  }
    1761  return CONTAINER_UNKNOWN;
    1762 }
    1763 
    1764 MediaContainerName DetermineContainerFromFileName(
    1765  const std::string& file_name) {
    1766  const size_t pos = file_name.rfind('.');
    1767  if (pos == std::string::npos)
    1768  return CONTAINER_UNKNOWN;
    1769  const std::string& file_extension = file_name.substr(pos + 1);
    1770  return DetermineContainerFromFormatName(file_extension);
    1771 }
    1772 
    1773 } // namespace media
    1774 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/base/container_names.h"
    +
    6 
    +
    7 #include <libxml/parser.h>
    +
    8 #include <libxml/tree.h>
    +
    9 #include <stdint.h>
    +
    10 
    +
    11 #include <cctype>
    +
    12 #include <limits>
    +
    13 
    +
    14 #include "packager/base/logging.h"
    +
    15 #include "packager/base/strings/string_util.h"
    +
    16 #include "packager/media/base/bit_reader.h"
    +
    17 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 
    +
    22 #define TAG(a, b, c, d) \
    +
    23  ((static_cast<uint32_t>(static_cast<uint8_t>(a)) << 24) | \
    +
    24  (static_cast<uint8_t>(b) << 16) | (static_cast<uint8_t>(c) << 8) | \
    +
    25  (static_cast<uint8_t>(d)))
    +
    26 
    +
    27 #define RCHECK(x) \
    +
    28  do { \
    +
    29  if (!(x)) \
    +
    30  return false; \
    +
    31  } while (0)
    +
    32 
    +
    33 #define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
    +
    34 
    +
    35 // Helper function to read 2 bytes (16 bits, big endian) from a buffer.
    +
    36 static int Read16(const uint8_t* p) {
    +
    37  return p[0] << 8 | p[1];
    +
    38 }
    +
    39 
    +
    40 // Helper function to read 3 bytes (24 bits, big endian) from a buffer.
    +
    41 static uint32_t Read24(const uint8_t* p) {
    +
    42  return p[0] << 16 | p[1] << 8 | p[2];
    +
    43 }
    +
    44 
    +
    45 // Helper function to read 4 bytes (32 bits, big endian) from a buffer.
    +
    46 static uint32_t Read32(const uint8_t* p) {
    +
    47  return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
    +
    48 }
    +
    49 
    +
    50 // Helper function to read 4 bytes (32 bits, little endian) from a buffer.
    +
    51 static uint32_t Read32LE(const uint8_t* p) {
    +
    52  return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
    +
    53 }
    +
    54 
    +
    55 // Helper function to do buffer comparisons with a string without going off the
    +
    56 // end of the buffer.
    +
    57 static bool StartsWith(const uint8_t* buffer,
    +
    58  size_t buffer_size,
    +
    59  const char* prefix) {
    +
    60  size_t prefix_size = strlen(prefix);
    +
    61  return (prefix_size <= buffer_size &&
    +
    62  memcmp(buffer, prefix, prefix_size) == 0);
    +
    63 }
    +
    64 
    +
    65 // Helper function to do buffer comparisons with another buffer (to allow for
    +
    66 // embedded \0 in the comparison) without going off the end of the buffer.
    +
    67 static bool StartsWith(const uint8_t* buffer,
    +
    68  size_t buffer_size,
    +
    69  const uint8_t* prefix,
    +
    70  size_t prefix_size) {
    +
    71  return (prefix_size <= buffer_size &&
    +
    72  memcmp(buffer, prefix, prefix_size) == 0);
    +
    73 }
    +
    74 
    +
    75 // Helper function to read up to 64 bits from a bit stream.
    +
    76 static uint64_t ReadBits(BitReader* reader, int num_bits) {
    +
    77  DCHECK_GE(static_cast<int>(reader->bits_available()), num_bits);
    +
    78  DCHECK((num_bits > 0) && (num_bits <= 64));
    +
    79  uint64_t value;
    +
    80  reader->ReadBits(num_bits, &value);
    +
    81  return value;
    +
    82 }
    +
    83 
    +
    84 const int kAc3FrameSizeTable[38][3] = {
    +
    85  { 128, 138, 192 }, { 128, 140, 192 }, { 160, 174, 240 }, { 160, 176, 240 },
    +
    86  { 192, 208, 288 }, { 192, 210, 288 }, { 224, 242, 336 }, { 224, 244, 336 },
    +
    87  { 256, 278, 384 }, { 256, 280, 384 }, { 320, 348, 480 }, { 320, 350, 480 },
    +
    88  { 384, 416, 576 }, { 384, 418, 576 }, { 448, 486, 672 }, { 448, 488, 672 },
    +
    89  { 512, 556, 768 }, { 512, 558, 768 }, { 640, 696, 960 }, { 640, 698, 960 },
    +
    90  { 768, 834, 1152 }, { 768, 836, 1152 }, { 896, 974, 1344 },
    +
    91  { 896, 976, 1344 }, { 1024, 1114, 1536 }, { 1024, 1116, 1536 },
    +
    92  { 1280, 1392, 1920 }, { 1280, 1394, 1920 }, { 1536, 1670, 2304 },
    +
    93  { 1536, 1672, 2304 }, { 1792, 1950, 2688 }, { 1792, 1952, 2688 },
    +
    94  { 2048, 2228, 3072 }, { 2048, 2230, 3072 }, { 2304, 2506, 3456 },
    +
    95  { 2304, 2508, 3456 }, { 2560, 2768, 3840 }, { 2560, 2770, 3840 }
    +
    96 };
    +
    97 
    +
    98 // Checks for an ADTS AAC container.
    +
    99 static bool CheckAac(const uint8_t* buffer, int buffer_size) {
    +
    100  // Audio Data Transport Stream (ADTS) header is 7 or 9 bytes
    +
    101  // (from http://wiki.multimedia.cx/index.php?title=ADTS)
    +
    102  RCHECK(buffer_size > 6);
    +
    103 
    +
    104  int offset = 0;
    +
    105  while (offset + 6 < buffer_size) {
    +
    106  BitReader reader(buffer + offset, 6);
    +
    107 
    +
    108  // Syncword must be 0xfff.
    +
    109  RCHECK(ReadBits(&reader, 12) == 0xfff);
    +
    110 
    +
    111  // Skip MPEG version.
    +
    112  reader.SkipBits(1);
    +
    113 
    +
    114  // Layer is always 0.
    +
    115  RCHECK(ReadBits(&reader, 2) == 0);
    +
    116 
    +
    117  // Skip protection + profile.
    +
    118  reader.SkipBits(1 + 2);
    +
    119 
    +
    120  // Check sampling frequency index.
    +
    121  RCHECK(ReadBits(&reader, 4) != 15); // Forbidden.
    +
    122 
    +
    123  // Skip private stream, channel configuration, originality, home,
    +
    124  // copyrighted stream, and copyright_start.
    +
    125  reader.SkipBits(1 + 3 + 1 + 1 + 1 + 1);
    +
    126 
    +
    127  // Get frame length (includes header).
    +
    128  int size = ReadBits(&reader, 13);
    +
    129  RCHECK(size > 0);
    +
    130  offset += size;
    +
    131  }
    +
    132  return true;
    +
    133 }
    +
    134 
    +
    135 const uint16_t kAc3SyncWord = 0x0b77;
    +
    136 
    +
    137 // Checks for an AC3 container.
    +
    138 static bool CheckAc3(const uint8_t* buffer, int buffer_size) {
    +
    139  // Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
    +
    140  // Doc. A/52:2012
    +
    141  // (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
    +
    142 
    +
    143  // AC3 container looks like syncinfo | bsi | audblk * 6 | aux | check.
    +
    144  RCHECK(buffer_size > 6);
    +
    145 
    +
    146  int offset = 0;
    +
    147  while (offset + 6 < buffer_size) {
    +
    148  BitReader reader(buffer + offset, 6);
    +
    149 
    +
    150  // Check syncinfo.
    +
    151  RCHECK(ReadBits(&reader, 16) == kAc3SyncWord);
    +
    152 
    +
    153  // Skip crc1.
    +
    154  reader.SkipBits(16);
    +
    155 
    +
    156  // Verify fscod.
    +
    157  int sample_rate_code = ReadBits(&reader, 2);
    +
    158  RCHECK(sample_rate_code != 3); // Reserved.
    +
    159 
    +
    160  // Verify frmsizecod.
    +
    161  int frame_size_code = ReadBits(&reader, 6);
    +
    162  RCHECK(frame_size_code < 38); // Undefined.
    +
    163 
    +
    164  // Verify bsid.
    +
    165  RCHECK(ReadBits(&reader, 5) < 10); // Normally 8 or 6, 16 used by EAC3.
    +
    166 
    +
    167  offset += kAc3FrameSizeTable[frame_size_code][sample_rate_code];
    +
    168  }
    +
    169  return true;
    +
    170 }
    +
    171 
    +
    172 // Checks for an EAC3 container (very similar to AC3)
    +
    173 static bool CheckEac3(const uint8_t* buffer, int buffer_size) {
    +
    174  // Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
    +
    175  // Doc. A/52:2012
    +
    176  // (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
    +
    177 
    +
    178  // EAC3 container looks like syncinfo | bsi | audfrm | audblk* | aux | check.
    +
    179  RCHECK(buffer_size > 6);
    +
    180 
    +
    181  int offset = 0;
    +
    182  while (offset + 6 < buffer_size) {
    +
    183  BitReader reader(buffer + offset, 6);
    +
    184 
    +
    185  // Check syncinfo.
    +
    186  RCHECK(ReadBits(&reader, 16) == kAc3SyncWord);
    +
    187 
    +
    188  // Verify strmtyp.
    +
    189  RCHECK(ReadBits(&reader, 2) != 3);
    +
    190 
    +
    191  // Skip substreamid.
    +
    192  reader.SkipBits(3);
    +
    193 
    +
    194  // Get frmsize. Include syncinfo size and convert to bytes.
    +
    195  int frame_size = (ReadBits(&reader, 11) + 1) * 2;
    +
    196  RCHECK(frame_size >= 7);
    +
    197 
    +
    198  // Skip fscod, fscod2, acmod, and lfeon.
    +
    199  reader.SkipBits(2 + 2 + 3 + 1);
    +
    200 
    +
    201  // Verify bsid.
    +
    202  int bit_stream_id = ReadBits(&reader, 5);
    +
    203  RCHECK(bit_stream_id >= 11 && bit_stream_id <= 16);
    +
    204 
    +
    205  offset += frame_size;
    +
    206  }
    +
    207  return true;
    +
    208 }
    +
    209 
    +
    210 // Additional checks for a BINK container.
    +
    211 static bool CheckBink(const uint8_t* buffer, int buffer_size) {
    +
    212  // Reference: http://wiki.multimedia.cx/index.php?title=Bink_Container
    +
    213  RCHECK(buffer_size >= 44);
    +
    214 
    +
    215  // Verify number of frames specified.
    +
    216  RCHECK(Read32LE(buffer + 8) > 0);
    +
    217 
    +
    218  // Verify width in range.
    +
    219  int width = Read32LE(buffer + 20);
    +
    220  RCHECK(width > 0 && width <= 32767);
    +
    221 
    +
    222  // Verify height in range.
    +
    223  int height = Read32LE(buffer + 24);
    +
    224  RCHECK(height > 0 && height <= 32767);
    +
    225 
    +
    226  // Verify frames per second specified.
    +
    227  RCHECK(Read32LE(buffer + 28) > 0);
    +
    228 
    +
    229  // Verify video frames per second specified.
    +
    230  RCHECK(Read32LE(buffer + 32) > 0);
    +
    231 
    +
    232  // Number of audio tracks must be 256 or less.
    +
    233  return (Read32LE(buffer + 40) <= 256);
    +
    234 }
    +
    235 
    +
    236 // Additional checks for a CAF container.
    +
    237 static bool CheckCaf(const uint8_t* buffer, int buffer_size) {
    +
    238  // Reference: Apple Core Audio Format Specification 1.0
    +
    239  // (https://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html)
    +
    240  RCHECK(buffer_size >= 52);
    +
    241  BitReader reader(buffer, buffer_size);
    +
    242 
    +
    243  // mFileType should be "caff".
    +
    244  RCHECK(ReadBits(&reader, 32) == TAG('c', 'a', 'f', 'f'));
    +
    245 
    +
    246  // mFileVersion should be 1.
    +
    247  RCHECK(ReadBits(&reader, 16) == 1);
    +
    248 
    +
    249  // Skip mFileFlags.
    +
    250  reader.SkipBits(16);
    +
    251 
    +
    252  // First chunk should be Audio Description chunk, size 32l.
    +
    253  RCHECK(ReadBits(&reader, 32) == TAG('d', 'e', 's', 'c'));
    +
    254  RCHECK(ReadBits(&reader, 64) == 32);
    +
    255 
    +
    256  // CAFAudioFormat.mSampleRate(float64) not 0
    +
    257  RCHECK(ReadBits(&reader, 64) != 0);
    +
    258 
    +
    259  // CAFAudioFormat.mFormatID not 0
    +
    260  RCHECK(ReadBits(&reader, 32) != 0);
    +
    261 
    +
    262  // Skip CAFAudioFormat.mBytesPerPacket and mFramesPerPacket.
    +
    263  reader.SkipBits(32 + 32);
    +
    264 
    +
    265  // CAFAudioFormat.mChannelsPerFrame not 0
    +
    266  RCHECK(ReadBits(&reader, 32) != 0);
    +
    267  return true;
    +
    268 }
    +
    269 
    +
    270 static bool kSamplingFrequencyValid[16] = { false, true, true, true, false,
    +
    271  false, true, true, true, false,
    +
    272  false, true, true, true, false,
    +
    273  false };
    +
    274 static bool kExtAudioIdValid[8] = { true, false, true, false, false, false,
    +
    275  true, false };
    +
    276 
    +
    277 // Additional checks for a DTS container.
    +
    278 static bool CheckDts(const uint8_t* buffer, int buffer_size) {
    +
    279  // Reference: ETSI TS 102 114 V1.3.1 (2011-08)
    +
    280  // (http://www.etsi.org/deliver/etsi_ts/102100_102199/102114/01.03.01_60/ts_102114v010301p.pdf)
    +
    281  RCHECK(buffer_size > 11);
    +
    282 
    +
    283  int offset = 0;
    +
    284  while (offset + 11 < buffer_size) {
    +
    285  BitReader reader(buffer + offset, 11);
    +
    286 
    +
    287  // Verify sync word.
    +
    288  RCHECK(ReadBits(&reader, 32) == 0x7ffe8001);
    +
    289 
    +
    290  // Skip frame type and deficit sample count.
    +
    291  reader.SkipBits(1 + 5);
    +
    292 
    +
    293  // Verify CRC present flag.
    +
    294  RCHECK(ReadBits(&reader, 1) == 0); // CPF must be 0.
    +
    295 
    +
    296  // Verify number of PCM sample blocks.
    +
    297  RCHECK(ReadBits(&reader, 7) >= 5);
    +
    298 
    +
    299  // Verify primary frame byte size.
    +
    300  int frame_size = ReadBits(&reader, 14);
    +
    301  RCHECK(frame_size >= 95);
    +
    302 
    +
    303  // Skip audio channel arrangement.
    +
    304  reader.SkipBits(6);
    +
    305 
    +
    306  // Verify core audio sampling frequency is an allowed value.
    +
    307  RCHECK(kSamplingFrequencyValid[ReadBits(&reader, 4)]);
    +
    308 
    +
    309  // Verify transmission bit rate is valid.
    +
    310  RCHECK(ReadBits(&reader, 5) <= 25);
    +
    311 
    +
    312  // Verify reserved field is 0.
    +
    313  RCHECK(ReadBits(&reader, 1) == 0);
    +
    314 
    +
    315  // Skip dynamic range flag, time stamp flag, auxiliary data flag, and HDCD.
    +
    316  reader.SkipBits(1 + 1 + 1 + 1);
    +
    317 
    +
    318  // Verify extension audio descriptor flag is an allowed value.
    +
    319  RCHECK(kExtAudioIdValid[ReadBits(&reader, 3)]);
    +
    320 
    +
    321  // Skip extended coding flag and audio sync word insertion flag.
    +
    322  reader.SkipBits(1 + 1);
    +
    323 
    +
    324  // Verify low frequency effects flag is an allowed value.
    +
    325  RCHECK(ReadBits(&reader, 2) != 3);
    +
    326 
    +
    327  offset += frame_size + 1;
    +
    328  }
    +
    329  return true;
    +
    330 }
    +
    331 
    +
    332 // Checks for a DV container.
    +
    333 static bool CheckDV(const uint8_t* buffer, int buffer_size) {
    +
    334  // Reference: SMPTE 314M (Annex A has differences with IEC 61834).
    +
    335  // (http://standards.smpte.org/content/978-1-61482-454-1/st-314-2005/SEC1.body.pdf)
    +
    336  RCHECK(buffer_size > 11);
    +
    337 
    +
    338  int offset = 0;
    +
    339  int current_sequence_number = -1;
    +
    340  int last_block_number[6];
    +
    341  while (offset + 11 < buffer_size) {
    +
    342  BitReader reader(buffer + offset, 11);
    +
    343 
    +
    344  // Decode ID data. Sections 5, 6, and 7 are reserved.
    +
    345  int section = ReadBits(&reader, 3);
    +
    346  RCHECK(section < 5);
    +
    347 
    +
    348  // Next bit must be 1.
    +
    349  RCHECK(ReadBits(&reader, 1) == 1);
    +
    350 
    +
    351  // Skip arbitrary bits.
    +
    352  reader.SkipBits(4);
    +
    353 
    +
    354  int sequence_number = ReadBits(&reader, 4);
    +
    355 
    +
    356  // Skip FSC.
    +
    357  reader.SkipBits(1);
    +
    358 
    +
    359  // Next 3 bits must be 1.
    +
    360  RCHECK(ReadBits(&reader, 3) == 7);
    +
    361 
    +
    362  int block_number = ReadBits(&reader, 8);
    +
    363 
    +
    364  if (section == 0) { // Header.
    +
    365  // Validate the reserved bits in the next 8 bytes.
    +
    366  reader.SkipBits(1);
    +
    367  RCHECK(ReadBits(&reader, 1) == 0);
    +
    368  RCHECK(ReadBits(&reader, 11) == 0x7ff);
    +
    369  reader.SkipBits(4);
    +
    370  RCHECK(ReadBits(&reader, 4) == 0xf);
    +
    371  reader.SkipBits(4);
    +
    372  RCHECK(ReadBits(&reader, 4) == 0xf);
    +
    373  reader.SkipBits(4);
    +
    374  RCHECK(ReadBits(&reader, 4) == 0xf);
    +
    375  reader.SkipBits(3);
    +
    376  RCHECK(ReadBits(&reader, 24) == 0xffffff);
    +
    377  current_sequence_number = sequence_number;
    +
    378  for (size_t i = 0; i < arraysize(last_block_number); ++i)
    +
    379  last_block_number[i] = -1;
    +
    380  } else {
    +
    381  // Sequence number must match (this will also fail if no header seen).
    +
    382  RCHECK(sequence_number == current_sequence_number);
    +
    383  // Block number should be increasing.
    +
    384  RCHECK(block_number > last_block_number[section]);
    +
    385  last_block_number[section] = block_number;
    +
    386  }
    +
    387 
    +
    388  // Move to next block.
    +
    389  offset += 80;
    +
    390  }
    +
    391  return true;
    +
    392 }
    +
    393 
    +
    394 
    +
    395 // Checks for a GSM container.
    +
    396 static bool CheckGsm(const uint8_t* buffer, int buffer_size) {
    +
    397  // Reference: ETSI EN 300 961 V8.1.1
    +
    398  // (http://www.etsi.org/deliver/etsi_en/300900_300999/300961/08.01.01_60/en_300961v080101p.pdf)
    +
    399  // also http://tools.ietf.org/html/rfc3551#page-24
    +
    400  // GSM files have a 33 byte block, only first 4 bits are fixed.
    +
    401  RCHECK(buffer_size >= 1024); // Need enough data to do a decent check.
    +
    402 
    +
    403  int offset = 0;
    +
    404  while (offset < buffer_size) {
    +
    405  // First 4 bits of each block are xD.
    +
    406  RCHECK((buffer[offset] & 0xf0) == 0xd0);
    +
    407  offset += 33;
    +
    408  }
    +
    409  return true;
    +
    410 }
    +
    411 
    +
    412 // Advance to the first set of |num_bits| bits that match |start_code|. |offset|
    +
    413 // is the current location in the buffer, and is updated. |bytes_needed| is the
    +
    414 // number of bytes that must remain in the buffer when |start_code| is found.
    +
    415 // Returns true if start_code found (and enough space in the buffer after it),
    +
    416 // false otherwise.
    +
    417 static bool AdvanceToStartCode(const uint8_t* buffer,
    +
    418  int buffer_size,
    +
    419  int* offset,
    +
    420  int bytes_needed,
    +
    421  int num_bits,
    +
    422  uint32_t start_code) {
    +
    423  DCHECK_GE(bytes_needed, 3);
    +
    424  DCHECK_LE(num_bits, 24); // Only supports up to 24 bits.
    +
    425 
    +
    426  // Create a mask to isolate |num_bits| bits, once shifted over.
    +
    427  uint32_t bits_to_shift = 24 - num_bits;
    +
    428  uint32_t mask = (1 << num_bits) - 1;
    +
    429  while (*offset + bytes_needed < buffer_size) {
    +
    430  uint32_t next = Read24(buffer + *offset);
    +
    431  if (((next >> bits_to_shift) & mask) == start_code)
    +
    432  return true;
    +
    433  ++(*offset);
    +
    434  }
    +
    435  return false;
    +
    436 }
    +
    437 
    +
    438 // Checks for an H.261 container.
    +
    439 static bool CheckH261(const uint8_t* buffer, int buffer_size) {
    +
    440  // Reference: ITU-T Recommendation H.261 (03/1993)
    +
    441  // (http://www.itu.int/rec/T-REC-H.261-199303-I/en)
    +
    442  RCHECK(buffer_size > 16);
    +
    443 
    +
    444  int offset = 0;
    +
    445  bool seen_start_code = false;
    +
    446  while (true) {
    +
    447  // Advance to picture_start_code, if there is one.
    +
    448  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 4, 20, 0x10)) {
    +
    449  // No start code found (or off end of buffer), so success if
    +
    450  // there was at least one valid header.
    +
    451  return seen_start_code;
    +
    452  }
    +
    453 
    +
    454  // Now verify the block. AdvanceToStartCode() made sure that there are
    +
    455  // at least 4 bytes remaining in the buffer.
    +
    456  BitReader reader(buffer + offset, buffer_size - offset);
    +
    457  RCHECK(ReadBits(&reader, 20) == 0x10);
    +
    458 
    +
    459  // Skip the temporal reference and PTYPE.
    +
    460  reader.SkipBits(5 + 6);
    +
    461 
    +
    462  // Skip any extra insertion information. Since this is open-ended, if we run
    +
    463  // out of bits assume that the buffer is correctly formatted.
    +
    464  int extra = ReadBits(&reader, 1);
    +
    465  while (extra == 1) {
    +
    466  if (!reader.SkipBits(8))
    +
    467  return seen_start_code;
    +
    468  if (!reader.ReadBits(1, &extra))
    +
    469  return seen_start_code;
    +
    470  }
    +
    471 
    +
    472  // Next should be a Group of Blocks start code. Again, if we run out of
    +
    473  // bits, then assume that the buffer up to here is correct, and the buffer
    +
    474  // just happened to end in the middle of a header.
    +
    475  int next;
    +
    476  if (!reader.ReadBits(16, &next))
    +
    477  return seen_start_code;
    +
    478  RCHECK(next == 1);
    +
    479 
    +
    480  // Move to the next block.
    +
    481  seen_start_code = true;
    +
    482  offset += 4;
    +
    483  }
    +
    484 }
    +
    485 
    +
    486 // Checks for an H.263 container.
    +
    487 static bool CheckH263(const uint8_t* buffer, int buffer_size) {
    +
    488  // Reference: ITU-T Recommendation H.263 (01/2005)
    +
    489  // (http://www.itu.int/rec/T-REC-H.263-200501-I/en)
    +
    490  // header is PSC(22b) + TR(8b) + PTYPE(8+b).
    +
    491  RCHECK(buffer_size > 16);
    +
    492 
    +
    493  int offset = 0;
    +
    494  bool seen_start_code = false;
    +
    495  while (true) {
    +
    496  // Advance to picture_start_code, if there is one.
    +
    497  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 9, 22, 0x20)) {
    +
    498  // No start code found (or off end of buffer), so success if
    +
    499  // there was at least one valid header.
    +
    500  return seen_start_code;
    +
    501  }
    +
    502 
    +
    503  // Now verify the block. AdvanceToStartCode() made sure that there are
    +
    504  // at least 9 bytes remaining in the buffer.
    +
    505  BitReader reader(buffer + offset, 9);
    +
    506  RCHECK(ReadBits(&reader, 22) == 0x20);
    +
    507 
    +
    508  // Skip the temporal reference.
    +
    509  reader.SkipBits(8);
    +
    510 
    +
    511  // Verify that the first 2 bits of PTYPE are 10b.
    +
    512  RCHECK(ReadBits(&reader, 2) == 2);
    +
    513 
    +
    514  // Skip the split screen indicator, document camera indicator, and full
    +
    515  // picture freeze release.
    +
    516  reader.SkipBits(1 + 1 + 1);
    +
    517 
    +
    518  // Verify Source Format.
    +
    519  int format = ReadBits(&reader, 3);
    +
    520  RCHECK(format != 0 && format != 6); // Forbidden or reserved.
    +
    521 
    +
    522  if (format == 7) {
    +
    523  // Verify full extended PTYPE.
    +
    524  int ufep = ReadBits(&reader, 3);
    +
    525  if (ufep == 1) {
    +
    526  // Verify the optional part of PLUSPTYPE.
    +
    527  format = ReadBits(&reader, 3);
    +
    528  RCHECK(format != 0 && format != 7); // Reserved.
    +
    529  reader.SkipBits(11);
    +
    530  // Next 4 bits should be b1000.
    +
    531  RCHECK(ReadBits(&reader, 4) == 8); // Not allowed.
    +
    532  } else {
    +
    533  RCHECK(ufep == 0); // Only 0 and 1 allowed.
    +
    534  }
    +
    535 
    +
    536  // Verify picture type code is not a reserved value.
    +
    537  int picture_type_code = ReadBits(&reader, 3);
    +
    538  RCHECK(picture_type_code != 6 && picture_type_code != 7); // Reserved.
    +
    539 
    +
    540  // Skip picture resampling mode, reduced resolution mode,
    +
    541  // and rounding type.
    +
    542  reader.SkipBits(1 + 1 + 1);
    +
    543 
    +
    544  // Next 3 bits should be b001.
    +
    545  RCHECK(ReadBits(&reader, 3) == 1); // Not allowed.
    +
    546  }
    +
    547 
    +
    548  // Move to the next block.
    +
    549  seen_start_code = true;
    +
    550  offset += 9;
    +
    551  }
    +
    552 }
    +
    553 
    +
    554 // Checks for an H.264 container.
    +
    555 static bool CheckH264(const uint8_t* buffer, int buffer_size) {
    +
    556  // Reference: ITU-T Recommendation H.264 (01/2012)
    +
    557  // (http://www.itu.int/rec/T-REC-H.264)
    +
    558  // Section B.1: Byte stream NAL unit syntax and semantics.
    +
    559  RCHECK(buffer_size > 4);
    +
    560 
    +
    561  int offset = 0;
    +
    562  int parameter_count = 0;
    +
    563  while (true) {
    +
    564  // Advance to picture_start_code, if there is one.
    +
    565  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 4, 24, 1)) {
    +
    566  // No start code found (or off end of buffer), so success if
    +
    567  // there was at least one valid header.
    +
    568  return parameter_count > 0;
    +
    569  }
    +
    570 
    +
    571  // Now verify the block. AdvanceToStartCode() made sure that there are
    +
    572  // at least 4 bytes remaining in the buffer.
    +
    573  BitReader reader(buffer + offset, 4);
    +
    574  RCHECK(ReadBits(&reader, 24) == 1);
    +
    575 
    +
    576  // Verify forbidden_zero_bit.
    +
    577  RCHECK(ReadBits(&reader, 1) == 0);
    +
    578 
    +
    579  // Extract nal_ref_idc and nal_unit_type.
    +
    580  int nal_ref_idc = ReadBits(&reader, 2);
    +
    581  int nal_unit_type = ReadBits(&reader, 5);
    +
    582 
    +
    583  switch (nal_unit_type) {
    +
    584  case 5: // Coded slice of an IDR picture.
    +
    585  RCHECK(nal_ref_idc != 0);
    +
    586  break;
    +
    587  case 6: // Supplemental enhancement information (SEI).
    +
    588  case 9: // Access unit delimiter.
    +
    589  case 10: // End of sequence.
    +
    590  case 11: // End of stream.
    +
    591  case 12: // Filler data.
    +
    592  RCHECK(nal_ref_idc == 0);
    +
    593  break;
    +
    594  case 7: // Sequence parameter set.
    +
    595  case 8: // Picture parameter set.
    +
    596  ++parameter_count;
    +
    597  break;
    +
    598  }
    +
    599 
    +
    600  // Skip the current start_code_prefix and move to the next.
    +
    601  offset += 4;
    +
    602  }
    +
    603 }
    +
    604 
    +
    605 static const char kHlsSignature[] = "#EXTM3U";
    +
    606 static const char kHls1[] = "#EXT-X-STREAM-INF:";
    +
    607 static const char kHls2[] = "#EXT-X-TARGETDURATION:";
    +
    608 static const char kHls3[] = "#EXT-X-MEDIA-SEQUENCE:";
    +
    609 
    +
    610 // Additional checks for a HLS container.
    +
    611 static bool CheckHls(const uint8_t* buffer, int buffer_size) {
    +
    612  // HLS is simply a play list used for Apple HTTP Live Streaming.
    +
    613  // Reference: Apple HTTP Live Streaming Overview
    +
    614  // (http://goo.gl/MIwxj)
    +
    615 
    +
    616  if (StartsWith(buffer, buffer_size, kHlsSignature)) {
    +
    617  // Need to find "#EXT-X-STREAM-INF:", "#EXT-X-TARGETDURATION:", or
    +
    618  // "#EXT-X-MEDIA-SEQUENCE:" somewhere in the buffer. Other playlists (like
    +
    619  // WinAmp) only have additional lines with #EXTINF
    +
    620  // (http://en.wikipedia.org/wiki/M3U).
    +
    621  int offset = strlen(kHlsSignature);
    +
    622  while (offset < buffer_size) {
    +
    623  if (buffer[offset] == '#') {
    +
    624  if (StartsWith(buffer + offset, buffer_size - offset, kHls1) ||
    +
    625  StartsWith(buffer + offset, buffer_size - offset, kHls2) ||
    +
    626  StartsWith(buffer + offset, buffer_size - offset, kHls3)) {
    +
    627  return true;
    +
    628  }
    +
    629  }
    +
    630  ++offset;
    +
    631  }
    +
    632  }
    +
    633  return false;
    +
    634 }
    +
    635 
    +
    636 // Checks for a MJPEG stream.
    +
    637 static bool CheckMJpeg(const uint8_t* buffer, int buffer_size) {
    +
    638  // Reference: ISO/IEC 10918-1 : 1993(E), Annex B
    +
    639  // (http://www.w3.org/Graphics/JPEG/itu-t81.pdf)
    +
    640  RCHECK(buffer_size >= 16);
    +
    641 
    +
    642  int offset = 0;
    +
    643  int last_restart = -1;
    +
    644  int num_codes = 0;
    +
    645  while (offset + 5 < buffer_size) {
    +
    646  // Marker codes are always a two byte code with the first byte xFF.
    +
    647  RCHECK(buffer[offset] == 0xff);
    +
    648  uint8_t code = buffer[offset + 1];
    +
    649  RCHECK(code >= 0xc0 || code == 1);
    +
    650 
    +
    651  // Skip sequences of xFF.
    +
    652  if (code == 0xff) {
    +
    653  ++offset;
    +
    654  continue;
    +
    655  }
    +
    656 
    +
    657  // Success if the next marker code is EOI (end of image)
    +
    658  if (code == 0xd9)
    +
    659  return true;
    +
    660 
    +
    661  // Check remaining codes.
    +
    662  if (code == 0xd8 || code == 1) {
    +
    663  // SOI (start of image) / TEM (private use). No other data with header.
    +
    664  offset += 2;
    +
    665  } else if (code >= 0xd0 && code <= 0xd7) {
    +
    666  // RST (restart) codes must be in sequence. No other data with header.
    +
    667  int restart = code & 0x07;
    +
    668  if (last_restart >= 0)
    +
    669  RCHECK(restart == (last_restart + 1) % 8);
    +
    670  last_restart = restart;
    +
    671  offset += 2;
    +
    672  } else {
    +
    673  // All remaining marker codes are followed by a length of the header.
    +
    674  int length = Read16(buffer + offset + 2) + 2;
    +
    675 
    +
    676  // Special handling of SOS (start of scan) marker since the entropy
    +
    677  // coded data follows the SOS. Any xFF byte in the data block must be
    +
    678  // followed by x00 in the data.
    +
    679  if (code == 0xda) {
    +
    680  int number_components = buffer[offset + 4];
    +
    681  RCHECK(length == 8 + 2 * number_components);
    +
    682 
    +
    683  // Advance to the next marker.
    +
    684  offset += length;
    +
    685  while (offset + 2 < buffer_size) {
    +
    686  if (buffer[offset] == 0xff && buffer[offset + 1] != 0)
    +
    687  break;
    +
    688  ++offset;
    +
    689  }
    +
    690  } else {
    +
    691  // Skip over the marker data for the other marker codes.
    +
    692  offset += length;
    +
    693  }
    +
    694  }
    +
    695  ++num_codes;
    +
    696  }
    +
    697  return (num_codes > 1);
    +
    698 }
    +
    699 
    +
    700 enum Mpeg2StartCodes {
    +
    701  PROGRAM_END_CODE = 0xb9,
    +
    702  PACK_START_CODE = 0xba
    +
    703 };
    +
    704 
    +
    705 // Checks for a MPEG2 Program Stream.
    +
    706 static bool CheckMpeg2ProgramStream(const uint8_t* buffer, int buffer_size) {
    +
    707  // Reference: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
    +
    708  RCHECK(buffer_size > 14);
    +
    709 
    +
    710  int offset = 0;
    +
    711  while (offset + 14 < buffer_size) {
    +
    712  BitReader reader(buffer + offset, 14);
    +
    713 
    +
    714  // Must start with pack_start_code.
    +
    715  RCHECK(ReadBits(&reader, 24) == 1);
    +
    716  RCHECK(ReadBits(&reader, 8) == PACK_START_CODE);
    +
    717 
    +
    718  // Determine MPEG version (MPEG1 has b0010, while MPEG2 has b01).
    +
    719  int mpeg_version = ReadBits(&reader, 2);
    +
    720  if (mpeg_version == 0) {
    +
    721  // MPEG1, 10 byte header
    +
    722  // Validate rest of version code
    +
    723  RCHECK(ReadBits(&reader, 2) == 2);
    +
    724  } else {
    +
    725  RCHECK(mpeg_version == 1);
    +
    726  }
    +
    727 
    +
    728  // Skip system_clock_reference_base [32..30].
    +
    729  reader.SkipBits(3);
    +
    730 
    +
    731  // Verify marker bit.
    +
    732  RCHECK(ReadBits(&reader, 1) == 1);
    +
    733 
    +
    734  // Skip system_clock_reference_base [29..15].
    +
    735  reader.SkipBits(15);
    +
    736 
    +
    737  // Verify next marker bit.
    +
    738  RCHECK(ReadBits(&reader, 1) == 1);
    +
    739 
    +
    740  // Skip system_clock_reference_base [14..0].
    +
    741  reader.SkipBits(15);
    +
    742 
    +
    743  // Verify next marker bit.
    +
    744  RCHECK(ReadBits(&reader, 1) == 1);
    +
    745 
    +
    746  if (mpeg_version == 0) {
    +
    747  // Verify second marker bit.
    +
    748  RCHECK(ReadBits(&reader, 1) == 1);
    +
    749 
    +
    750  // Skip mux_rate.
    +
    751  reader.SkipBits(22);
    +
    752 
    +
    753  // Verify next marker bit.
    +
    754  RCHECK(ReadBits(&reader, 1) == 1);
    +
    755 
    +
    756  // Update offset to be after this header.
    +
    757  offset += 12;
    +
    758  } else {
    +
    759  // Must be MPEG2.
    +
    760  // Skip program_mux_rate.
    +
    761  reader.SkipBits(22);
    +
    762 
    +
    763  // Verify pair of marker bits.
    +
    764  RCHECK(ReadBits(&reader, 2) == 3);
    +
    765 
    +
    766  // Skip reserved.
    +
    767  reader.SkipBits(5);
    +
    768 
    +
    769  // Update offset to be after this header.
    +
    770  int pack_stuffing_length = ReadBits(&reader, 3);
    +
    771  offset += 14 + pack_stuffing_length;
    +
    772  }
    +
    773 
    +
    774  // Check for system headers and PES_packets.
    +
    775  while (offset + 6 < buffer_size && Read24(buffer + offset) == 1) {
    +
    776  // Next 8 bits determine stream type.
    +
    777  int stream_id = buffer[offset + 3];
    +
    778 
    +
    779  // Some stream types are reserved and shouldn't occur.
    +
    780  if (mpeg_version == 0)
    +
    781  RCHECK(stream_id != 0xbc && stream_id < 0xf0);
    +
    782  else
    +
    783  RCHECK(stream_id != 0xfc && stream_id != 0xfd && stream_id != 0xfe);
    +
    784 
    +
    785  // Some stream types are used for pack headers.
    +
    786  if (stream_id == PACK_START_CODE) // back to outer loop.
    +
    787  break;
    +
    788  if (stream_id == PROGRAM_END_CODE) // end of stream.
    +
    789  return true;
    +
    790 
    +
    791  int pes_length = Read16(buffer + offset + 4);
    +
    792  RCHECK(pes_length > 0);
    +
    793  offset = offset + 6 + pes_length;
    +
    794  }
    +
    795  }
    +
    796  // Success as we are off the end of the buffer and liked everything
    +
    797  // in the buffer.
    +
    798  return true;
    +
    799 }
    +
    800 
    +
    801 const uint8_t kMpeg2SyncWord = 0x47;
    +
    802 
    +
    803 // Checks for a MPEG2 Transport Stream.
    +
    804 static bool CheckMpeg2TransportStream(const uint8_t* buffer, int buffer_size) {
    +
    805  // Spec: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
    +
    806  // Normal packet size is 188 bytes. However, some systems add various error
    +
    807  // correction data at the end, resulting in packet of length 192/204/208
    +
    808  // (https://en.wikipedia.org/wiki/MPEG_transport_stream). Determine the
    +
    809  // length with the first packet.
    +
    810  RCHECK(buffer_size >= 250); // Want more than 1 packet to check.
    +
    811 
    +
    812  int offset = 0;
    +
    813  int packet_length = -1;
    +
    814  while (buffer[offset] != kMpeg2SyncWord && offset < 20) {
    +
    815  // Skip over any header in the first 20 bytes.
    +
    816  ++offset;
    +
    817  }
    +
    818 
    +
    819  while (offset + 6 < buffer_size) {
    +
    820  BitReader reader(buffer + offset, 6);
    +
    821 
    +
    822  // Must start with sync byte.
    +
    823  RCHECK(ReadBits(&reader, 8) == kMpeg2SyncWord);
    +
    824 
    +
    825  // Skip transport_error_indicator, payload_unit_start_indicator, and
    +
    826  // transport_priority.
    +
    827  reader.SkipBits(1 + 1 + 1);
    +
    828 
    +
    829  // Verify the pid is not a reserved value.
    +
    830  int pid = ReadBits(&reader, 13);
    +
    831  RCHECK(pid < 3 || pid > 15);
    +
    832 
    +
    833  // Skip transport_scrambling_control.
    +
    834  reader.SkipBits(2);
    +
    835 
    +
    836  // Adaptation_field_control can not be 0.
    +
    837  int adaptation_field_control = ReadBits(&reader, 2);
    +
    838  RCHECK(adaptation_field_control != 0);
    +
    839 
    +
    840  // If there is an adaptation_field, verify it.
    +
    841  if (adaptation_field_control >= 2) {
    +
    842  // Skip continuity_counter.
    +
    843  reader.SkipBits(4);
    +
    844 
    +
    845  // Get adaptation_field_length and verify it.
    +
    846  int adaptation_field_length = ReadBits(&reader, 8);
    +
    847  if (adaptation_field_control == 2)
    +
    848  RCHECK(adaptation_field_length == 183);
    +
    849  else
    +
    850  RCHECK(adaptation_field_length <= 182);
    +
    851  }
    +
    852 
    +
    853  // Attempt to determine the packet length on the first packet.
    +
    854  if (packet_length < 0) {
    +
    855  if (buffer[offset + 188] == kMpeg2SyncWord)
    +
    856  packet_length = 188;
    +
    857  else if (buffer[offset + 192] == kMpeg2SyncWord)
    +
    858  packet_length = 192;
    +
    859  else if (buffer[offset + 204] == kMpeg2SyncWord)
    +
    860  packet_length = 204;
    +
    861  else
    +
    862  packet_length = 208;
    +
    863  }
    +
    864  offset += packet_length;
    +
    865  }
    +
    866  return true;
    +
    867 }
    +
    868 
    +
    869 enum Mpeg4StartCodes {
    +
    870  VISUAL_OBJECT_SEQUENCE_START_CODE = 0xb0,
    +
    871  VISUAL_OBJECT_SEQUENCE_END_CODE = 0xb1,
    +
    872  VISUAL_OBJECT_START_CODE = 0xb5,
    +
    873  VOP_START_CODE = 0xb6
    +
    874 };
    +
    875 
    +
    876 // Checks for a raw MPEG4 bitstream container.
    +
    877 static bool CheckMpeg4BitStream(const uint8_t* buffer, int buffer_size) {
    +
    878  // Defined in ISO/IEC 14496-2:2001.
    +
    879  // However, no length ... simply scan for start code values.
    +
    880  // Note tags are very similar to H.264.
    +
    881  RCHECK(buffer_size > 4);
    +
    882 
    +
    883  int offset = 0;
    +
    884  int sequence_start_count = 0;
    +
    885  int sequence_end_count = 0;
    +
    886  int visual_object_count = 0;
    +
    887  int vop_count = 0;
    +
    888  while (true) {
    +
    889  // Advance to start_code, if there is one.
    +
    890  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 6, 24, 1)) {
    +
    891  // Not a complete sequence in memory, so return true if we've seen a
    +
    892  // visual_object_sequence_start_code and a visual_object_start_code.
    +
    893  return (sequence_start_count > 0 && visual_object_count > 0);
    +
    894  }
    +
    895 
    +
    896  // Now verify the block. AdvanceToStartCode() made sure that there are
    +
    897  // at least 6 bytes remaining in the buffer.
    +
    898  BitReader reader(buffer + offset, 6);
    +
    899  RCHECK(ReadBits(&reader, 24) == 1);
    +
    900 
    +
    901  int start_code = ReadBits(&reader, 8);
    +
    902  RCHECK(start_code < 0x30 || start_code > 0xaf); // 30..AF and
    +
    903  RCHECK(start_code < 0xb7 || start_code > 0xb9); // B7..B9 reserved
    +
    904 
    +
    905  switch (start_code) {
    +
    906  case VISUAL_OBJECT_SEQUENCE_START_CODE: {
    +
    907  ++sequence_start_count;
    +
    908  // Verify profile in not one of many reserved values.
    +
    909  int profile = ReadBits(&reader, 8);
    +
    910  RCHECK(profile > 0);
    +
    911  RCHECK(profile < 0x04 || profile > 0x10);
    +
    912  RCHECK(profile < 0x13 || profile > 0x20);
    +
    913  RCHECK(profile < 0x23 || profile > 0x31);
    +
    914  RCHECK(profile < 0x35 || profile > 0x41);
    +
    915  RCHECK(profile < 0x43 || profile > 0x60);
    +
    916  RCHECK(profile < 0x65 || profile > 0x70);
    +
    917  RCHECK(profile < 0x73 || profile > 0x80);
    +
    918  RCHECK(profile < 0x83 || profile > 0x90);
    +
    919  RCHECK(profile < 0x95 || profile > 0xa0);
    +
    920  RCHECK(profile < 0xa4 || profile > 0xb0);
    +
    921  RCHECK(profile < 0xb5 || profile > 0xc0);
    +
    922  RCHECK(profile < 0xc3 || profile > 0xd0);
    +
    923  RCHECK(profile < 0xe4);
    +
    924  break;
    +
    925  }
    +
    926 
    +
    927  case VISUAL_OBJECT_SEQUENCE_END_CODE:
    +
    928  RCHECK(++sequence_end_count == sequence_start_count);
    +
    929  break;
    +
    930 
    +
    931  case VISUAL_OBJECT_START_CODE: {
    +
    932  ++visual_object_count;
    +
    933  if (ReadBits(&reader, 1) == 1) {
    +
    934  int visual_object_verid = ReadBits(&reader, 4);
    +
    935  RCHECK(visual_object_verid > 0 && visual_object_verid < 3);
    +
    936  RCHECK(ReadBits(&reader, 3) != 0);
    +
    937  }
    +
    938  int visual_object_type = ReadBits(&reader, 4);
    +
    939  RCHECK(visual_object_type > 0 && visual_object_type < 6);
    +
    940  break;
    +
    941  }
    +
    942 
    +
    943  case VOP_START_CODE:
    +
    944  RCHECK(++vop_count <= visual_object_count);
    +
    945  break;
    +
    946  }
    +
    947  // Skip this block.
    +
    948  offset += 6;
    +
    949  }
    +
    950 }
    +
    951 
    +
    952 // Additional checks for a MOV/QuickTime/MPEG4 container.
    +
    953 static bool CheckMov(const uint8_t* buffer, int buffer_size) {
    +
    954  // Reference: ISO/IEC 14496-12:2005(E).
    +
    955  // (http://standards.iso.org/ittf/PubliclyAvailableStandards/c061988_ISO_IEC_14496-12_2012.zip)
    +
    956  RCHECK(buffer_size > 8);
    +
    957 
    +
    958  int offset = 0;
    +
    959  int boxes_seen = 0;
    +
    960  while (offset + 8 < buffer_size) {
    +
    961  int atomsize = Read32(buffer + offset);
    +
    962  uint32_t atomtype = Read32(buffer + offset + 4);
    +
    963  // Only need to check for ones that are valid at the top level.
    +
    964  switch (atomtype) {
    +
    965  case TAG('f','t','y','p'):
    +
    966  case TAG('p','d','i','n'):
    +
    967  case TAG('b','l','o','c'):
    +
    968  case TAG('m','o','o','v'):
    +
    969  case TAG('m','o','o','f'):
    +
    970  case TAG('m','f','r','a'):
    +
    971  case TAG('m','d','a','t'):
    +
    972  case TAG('f','r','e','e'):
    +
    973  case TAG('s','k','i','p'):
    +
    974  case TAG('m','e','t','a'):
    +
    975  case TAG('m','e','c','o'):
    +
    976  case TAG('s','t','y','p'):
    +
    977  case TAG('s','i','d','x'):
    +
    978  case TAG('s','s','i','x'):
    +
    979  case TAG('p','r','f','t'):
    +
    980  case TAG('u','u','i','d'):
    +
    981  // Assumes that it is an iso-bmff file after seeing two known boxes.
    +
    982  // Note that it is correct only for our use cases as we support only
    +
    983  // a limited number of containers, and there is no other container
    +
    984  // has this behavior.
    +
    985  if (++boxes_seen >= 2)
    +
    986  return true;
    +
    987  break;
    +
    988  default:
    +
    989  // Ignore unrecognized box.
    +
    990  break;
    +
    991  }
    +
    992  if (atomsize == 1) {
    +
    993  // Indicates that the length is the next 64bits.
    +
    994  if (offset + 16 > buffer_size)
    +
    995  break;
    +
    996  if (Read32(buffer + offset + 8) != 0)
    +
    997  break; // Offset is way past buffer size.
    +
    998  atomsize = Read32(buffer + offset + 12);
    +
    999  }
    +
    1000  if (atomsize <= 0)
    +
    1001  break; // Indicates the last atom or length too big.
    +
    1002  offset += atomsize;
    +
    1003  }
    +
    1004  return false;
    +
    1005 }
    +
    1006 
    +
    1007 enum MPEGVersion {
    +
    1008  VERSION_25 = 0,
    +
    1009  VERSION_RESERVED,
    +
    1010  VERSION_2,
    +
    1011  VERSION_1
    +
    1012 };
    +
    1013 enum MPEGLayer {
    +
    1014  L_RESERVED = 0,
    +
    1015  LAYER_3,
    +
    1016  LAYER_2,
    +
    1017  LAYER_1
    +
    1018 };
    +
    1019 
    +
    1020 static int kSampleRateTable[4][4] = { { 11025, 12000, 8000, 0 }, // v2.5
    +
    1021  { 0, 0, 0, 0 }, // not used
    +
    1022  { 22050, 24000, 16000, 0 }, // v2
    +
    1023  { 44100, 48000, 32000, 0 } // v1
    +
    1024 };
    +
    1025 
    +
    1026 static int kBitRateTableV1L1[16] = { 0, 32, 64, 96, 128, 160, 192, 224, 256,
    +
    1027  288, 320, 352, 384, 416, 448, 0 };
    +
    1028 static int kBitRateTableV1L2[16] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160,
    +
    1029  192, 224, 256, 320, 384, 0 };
    +
    1030 static int kBitRateTableV1L3[16] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128,
    +
    1031  160, 192, 224, 256, 320, 0 };
    +
    1032 static int kBitRateTableV2L1[16] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
    +
    1033  160, 176, 192, 224, 256, 0 };
    +
    1034 static int kBitRateTableV2L23[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,
    +
    1035  112, 128, 144, 160, 0 };
    +
    1036 
    +
    1037 static bool ValidMpegAudioFrameHeader(const uint8_t* header,
    +
    1038  int header_size,
    +
    1039  int* framesize) {
    +
    1040  // Reference: http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm.
    +
    1041  DCHECK_GE(header_size, 4);
    +
    1042  *framesize = 0;
    +
    1043  BitReader reader(header, 4); // Header can only be 4 bytes long.
    +
    1044 
    +
    1045  // Verify frame sync (11 bits) are all set.
    +
    1046  RCHECK(ReadBits(&reader, 11) == 0x7ff);
    +
    1047 
    +
    1048  // Verify MPEG audio version id.
    +
    1049  int version = ReadBits(&reader, 2);
    +
    1050  RCHECK(version != 1); // Reserved.
    +
    1051 
    +
    1052  // Verify layer.
    +
    1053  int layer = ReadBits(&reader, 2);
    +
    1054  RCHECK(layer != 0);
    +
    1055 
    +
    1056  // Skip protection bit.
    +
    1057  reader.SkipBits(1);
    +
    1058 
    +
    1059  // Verify bitrate index.
    +
    1060  int bitrate_index = ReadBits(&reader, 4);
    +
    1061  RCHECK(bitrate_index != 0xf);
    +
    1062 
    +
    1063  // Verify sampling rate frequency index.
    +
    1064  int sampling_index = ReadBits(&reader, 2);
    +
    1065  RCHECK(sampling_index != 3);
    +
    1066 
    +
    1067  // Get padding bit.
    +
    1068  int padding = ReadBits(&reader, 1);
    +
    1069 
    +
    1070  // Frame size:
    +
    1071  // For Layer I files = (12 * BitRate / SampleRate + Padding) * 4
    +
    1072  // For others = 144 * BitRate / SampleRate + Padding
    +
    1073  // Unfortunately, BitRate and SampleRate are coded.
    +
    1074  int sampling_rate = kSampleRateTable[version][sampling_index];
    +
    1075  int bitrate;
    +
    1076  if (version == VERSION_1) {
    +
    1077  if (layer == LAYER_1)
    +
    1078  bitrate = kBitRateTableV1L1[bitrate_index];
    +
    1079  else if (layer == LAYER_2)
    +
    1080  bitrate = kBitRateTableV1L2[bitrate_index];
    +
    1081  else
    +
    1082  bitrate = kBitRateTableV1L3[bitrate_index];
    +
    1083  } else {
    +
    1084  if (layer == LAYER_1)
    +
    1085  bitrate = kBitRateTableV2L1[bitrate_index];
    +
    1086  else
    +
    1087  bitrate = kBitRateTableV2L23[bitrate_index];
    +
    1088  }
    +
    1089  if (layer == LAYER_1)
    +
    1090  *framesize = ((12000 * bitrate) / sampling_rate + padding) * 4;
    +
    1091  else
    +
    1092  *framesize = (144000 * bitrate) / sampling_rate + padding;
    +
    1093  return (bitrate > 0 && sampling_rate > 0);
    +
    1094 }
    +
    1095 
    +
    1096 // Extract a size encoded the MP3 way.
    +
    1097 static int GetMp3HeaderSize(const uint8_t* buffer, int buffer_size) {
    +
    1098  DCHECK_GE(buffer_size, 9);
    +
    1099  int size = ((buffer[6] & 0x7f) << 21) + ((buffer[7] & 0x7f) << 14) +
    +
    1100  ((buffer[8] & 0x7f) << 7) + (buffer[9] & 0x7f) + 10;
    +
    1101  if (buffer[5] & 0x10) // Footer added?
    +
    1102  size += 10;
    +
    1103  return size;
    +
    1104 }
    +
    1105 
    +
    1106 // Additional checks for a MP3 container.
    +
    1107 static bool CheckMp3(const uint8_t* buffer, int buffer_size, bool seenHeader) {
    +
    1108  RCHECK(buffer_size >= 10); // Must be enough to read the initial header.
    +
    1109 
    +
    1110  int framesize;
    +
    1111  int numSeen = 0;
    +
    1112  int offset = 0;
    +
    1113  if (seenHeader) {
    +
    1114  offset = GetMp3HeaderSize(buffer, buffer_size);
    +
    1115  } else {
    +
    1116  // Skip over leading 0's.
    +
    1117  while (offset < buffer_size && buffer[offset] == 0)
    +
    1118  ++offset;
    +
    1119  }
    +
    1120 
    +
    1121  while (offset + 3 < buffer_size) {
    +
    1122  RCHECK(ValidMpegAudioFrameHeader(
    +
    1123  buffer + offset, buffer_size - offset, &framesize));
    +
    1124 
    +
    1125  // Have we seen enough valid headers?
    +
    1126  if (++numSeen > 10)
    +
    1127  return true;
    +
    1128  offset += framesize;
    +
    1129  }
    +
    1130  // Off the end of the buffer, return success if a few valid headers seen.
    +
    1131  return numSeen > 2;
    +
    1132 }
    +
    1133 
    +
    1134 // Check that the next characters in |buffer| represent a number. The format
    +
    1135 // accepted is optional whitespace followed by 1 or more digits. |max_digits|
    +
    1136 // specifies the maximum number of digits to process. Returns true if a valid
    +
    1137 // number is found, false otherwise.
    +
    1138 static bool VerifyNumber(const uint8_t* buffer,
    +
    1139  int buffer_size,
    +
    1140  int* offset,
    +
    1141  int max_digits) {
    +
    1142  RCHECK(*offset < buffer_size);
    +
    1143 
    +
    1144  // Skip over any leading space.
    +
    1145  while (isspace(buffer[*offset])) {
    +
    1146  ++(*offset);
    +
    1147  RCHECK(*offset < buffer_size);
    +
    1148  }
    +
    1149 
    +
    1150  // Need to process up to max_digits digits.
    +
    1151  int numSeen = 0;
    +
    1152  while (--max_digits >= 0 && isdigit(buffer[*offset])) {
    +
    1153  ++numSeen;
    +
    1154  ++(*offset);
    +
    1155  if (*offset >= buffer_size)
    +
    1156  return true; // Out of space but seen a digit.
    +
    1157  }
    +
    1158 
    +
    1159  // Success if at least one digit seen.
    +
    1160  return (numSeen > 0);
    +
    1161 }
    +
    1162 
    +
    1163 // Check that the next character in |buffer| is one of |c1| or |c2|. |c2| is
    +
    1164 // optional. Returns true if there is a match, false if no match or out of
    +
    1165 // space.
    +
    1166 static inline bool VerifyCharacters(const uint8_t* buffer,
    +
    1167  int buffer_size,
    +
    1168  int* offset,
    +
    1169  char c1,
    +
    1170  char c2) {
    +
    1171  RCHECK(*offset < buffer_size);
    +
    1172  char c = static_cast<char>(buffer[(*offset)++]);
    +
    1173  return (c == c1 || (c == c2 && c2 != 0));
    +
    1174 }
    +
    1175 
    +
    1176 // Checks for a SRT container.
    +
    1177 static bool CheckSrt(const uint8_t* buffer, int buffer_size) {
    +
    1178  // Reference: http://en.wikipedia.org/wiki/SubRip
    +
    1179  RCHECK(buffer_size > 20);
    +
    1180 
    +
    1181  // First line should just be the subtitle sequence number.
    +
    1182  int offset = StartsWith(buffer, buffer_size, UTF8_BYTE_ORDER_MARK) ? 3 : 0;
    +
    1183  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 100));
    +
    1184  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, '\n', '\r'));
    +
    1185 
    +
    1186  // Skip any additional \n\r.
    +
    1187  while (VerifyCharacters(buffer, buffer_size, &offset, '\n', '\r')) {}
    +
    1188  --offset; // Since VerifyCharacters() gobbled up the next non-CR/LF.
    +
    1189 
    +
    1190  // Second line should look like the following:
    +
    1191  // 00:00:10,500 --> 00:00:13,000
    +
    1192  // Units separator can be , or .
    +
    1193  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 100));
    +
    1194  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ':', 0));
    +
    1195  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 2));
    +
    1196  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ':', 0));
    +
    1197  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 2));
    +
    1198  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ',', '.'));
    +
    1199  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 3));
    +
    1200  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ' ', 0));
    +
    1201  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, '-', 0));
    +
    1202  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, '-', 0));
    +
    1203  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, '>', 0));
    +
    1204  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ' ', 0));
    +
    1205  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 100));
    +
    1206  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ':', 0));
    +
    1207  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 2));
    +
    1208  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ':', 0));
    +
    1209  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 2));
    +
    1210  RCHECK(VerifyCharacters(buffer, buffer_size, &offset, ',', '.'));
    +
    1211  RCHECK(VerifyNumber(buffer, buffer_size, &offset, 3));
    +
    1212  return true;
    +
    1213 }
    +
    1214 
    +
    1215 // Read a Matroska Element Id.
    +
    1216 static int GetElementId(BitReader* reader) {
    +
    1217  // Element ID is coded with the leading zero bits (max 3) determining size.
    +
    1218  // If it is an invalid encoding or the end of the buffer is reached,
    +
    1219  // return -1 as a tag that won't be expected.
    +
    1220  if (reader->bits_available() >= 8) {
    +
    1221  int num_bits_to_read = 0;
    +
    1222  static int prefix[] = { 0x80, 0x4000, 0x200000, 0x10000000 };
    +
    1223  for (int i = 0; i < 4; ++i) {
    +
    1224  num_bits_to_read += 7;
    +
    1225  if (ReadBits(reader, 1) == 1) {
    +
    1226  if (static_cast<int>(reader->bits_available()) < num_bits_to_read)
    +
    1227  break;
    +
    1228  // prefix[] adds back the bits read individually.
    +
    1229  return ReadBits(reader, num_bits_to_read) | prefix[i];
    +
    1230  }
    +
    1231  }
    +
    1232  }
    +
    1233  // Invalid encoding, return something not expected.
    +
    1234  return -1;
    +
    1235 }
    +
    1236 
    +
    1237 // Read a Matroska Unsigned Integer (VINT).
    +
    1238 static uint64_t GetVint(BitReader* reader) {
    +
    1239  // Values are coded with the leading zero bits (max 7) determining size.
    +
    1240  // If it is an invalid coding or the end of the buffer is reached,
    +
    1241  // return something that will go off the end of the buffer.
    +
    1242  if (reader->bits_available() >= 8) {
    +
    1243  int num_bits_to_read = 0;
    +
    1244  for (int i = 0; i < 8; ++i) {
    +
    1245  num_bits_to_read += 7;
    +
    1246  if (ReadBits(reader, 1) == 1) {
    +
    1247  if (static_cast<int>(reader->bits_available()) < num_bits_to_read)
    +
    1248  break;
    +
    1249  return ReadBits(reader, num_bits_to_read);
    +
    1250  }
    +
    1251  }
    +
    1252  }
    +
    1253  // Incorrect format (more than 7 leading 0's) or off the end of the buffer.
    +
    1254  // Since the return value is used as a byte size, return a value that will
    +
    1255  // cause a failure when used.
    +
    1256  return (reader->bits_available() / 8) + 2;
    +
    1257 }
    +
    1258 
    +
    1259 // Additional checks for a WEBM container.
    +
    1260 static bool CheckWebm(const uint8_t* buffer, int buffer_size) {
    +
    1261  // Reference: http://www.matroska.org/technical/specs/index.html
    +
    1262  RCHECK(buffer_size > 12);
    +
    1263 
    +
    1264  BitReader reader(buffer, buffer_size);
    +
    1265 
    +
    1266  // Verify starting Element Id.
    +
    1267  RCHECK(GetElementId(&reader) == 0x1a45dfa3);
    +
    1268 
    +
    1269  // Get the header size, and ensure there are enough bits to check.
    +
    1270  int header_size = GetVint(&reader);
    +
    1271  RCHECK(static_cast<int>(reader.bits_available()) / 8 >= header_size);
    +
    1272 
    +
    1273  // Loop through the header.
    +
    1274  while (reader.bits_available() > 0) {
    +
    1275  int tag = GetElementId(&reader);
    +
    1276  int tagsize = GetVint(&reader);
    +
    1277  switch (tag) {
    +
    1278  case 0x4286: // EBMLVersion
    +
    1279  case 0x42f7: // EBMLReadVersion
    +
    1280  case 0x42f2: // EBMLMaxIdLength
    +
    1281  case 0x42f3: // EBMLMaxSizeLength
    +
    1282  case 0x4287: // DocTypeVersion
    +
    1283  case 0x4285: // DocTypeReadVersion
    +
    1284  case 0xec: // void
    +
    1285  case 0xbf: // CRC32
    +
    1286  RCHECK(reader.SkipBits(tagsize * 8));
    +
    1287  break;
    +
    1288 
    +
    1289  case 0x4282: // EBMLDocType
    +
    1290  // Need to see "webm" or "matroska" next.
    +
    1291  switch (ReadBits(&reader, 32)) {
    +
    1292  case TAG('w', 'e', 'b', 'm') :
    +
    1293  return true;
    +
    1294  case TAG('m', 'a', 't', 'r') :
    +
    1295  return (ReadBits(&reader, 32) == TAG('o', 's', 'k', 'a'));
    +
    1296  }
    +
    1297  return false;
    +
    1298 
    +
    1299  default: // Unrecognized tag
    +
    1300  return false;
    +
    1301  }
    +
    1302  }
    +
    1303  return false;
    +
    1304 }
    +
    1305 
    +
    1306 enum VC1StartCodes {
    +
    1307  VC1_FRAME_START_CODE = 0x0d,
    +
    1308  VC1_ENTRY_POINT_START_CODE = 0x0e,
    +
    1309  VC1_SEQUENCE_START_CODE = 0x0f
    +
    1310 };
    +
    1311 
    +
    1312 // Checks for a VC1 bitstream container.
    +
    1313 static bool CheckVC1(const uint8_t* buffer, int buffer_size) {
    +
    1314  // Reference: SMPTE 421M
    +
    1315  // (http://standards.smpte.org/content/978-1-61482-555-5/st-421-2006/SEC1.body.pdf)
    +
    1316  // However, no length ... simply scan for start code values.
    +
    1317  // Expect to see SEQ | [ [ ENTRY ] PIC* ]*
    +
    1318  // Note tags are very similar to H.264.
    +
    1319 
    +
    1320  RCHECK(buffer_size >= 24);
    +
    1321 
    +
    1322  // First check for Bitstream Metadata Serialization (Annex L)
    +
    1323  if (buffer[0] == 0xc5 &&
    +
    1324  Read32(buffer + 4) == 0x04 &&
    +
    1325  Read32(buffer + 20) == 0x0c) {
    +
    1326  // Verify settings in STRUCT_C and STRUCT_A
    +
    1327  BitReader reader(buffer + 8, 12);
    +
    1328 
    +
    1329  int profile = ReadBits(&reader, 4);
    +
    1330  if (profile == 0 || profile == 4) { // simple or main
    +
    1331  // Skip FRMRTQ_POSTPROC, BITRTQ_POSTPROC, and LOOPFILTER.
    +
    1332  reader.SkipBits(3 + 5 + 1);
    +
    1333 
    +
    1334  // Next bit must be 0.
    +
    1335  RCHECK(ReadBits(&reader, 1) == 0);
    +
    1336 
    +
    1337  // Skip MULTIRES.
    +
    1338  reader.SkipBits(1);
    +
    1339 
    +
    1340  // Next bit must be 1.
    +
    1341  RCHECK(ReadBits(&reader, 1) == 1);
    +
    1342 
    +
    1343  // Skip FASTUVMC, EXTENDED_MV, DQUANT, and VSTRANSFORM.
    +
    1344  reader.SkipBits(1 + 1 + 2 + 1);
    +
    1345 
    +
    1346  // Next bit must be 0.
    +
    1347  RCHECK(ReadBits(&reader, 1) == 0);
    +
    1348 
    +
    1349  // Skip OVERLAP, SYNCMARKER, RANGERED, MAXBFRAMES, QUANTIZER, and
    +
    1350  // FINTERPFLAG.
    +
    1351  reader.SkipBits(1 + 1 + 1 + 3 + 2 + 1);
    +
    1352 
    +
    1353  // Next bit must be 1.
    +
    1354  RCHECK(ReadBits(&reader, 1) == 1);
    +
    1355 
    +
    1356  } else {
    +
    1357  RCHECK(profile == 12); // Other profile values not allowed.
    +
    1358  RCHECK(ReadBits(&reader, 28) == 0);
    +
    1359  }
    +
    1360 
    +
    1361  // Now check HORIZ_SIZE and VERT_SIZE, which must be 8192 or less.
    +
    1362  RCHECK(ReadBits(&reader, 32) <= 8192);
    +
    1363  RCHECK(ReadBits(&reader, 32) <= 8192);
    +
    1364  return true;
    +
    1365  }
    +
    1366 
    +
    1367  // Buffer isn't Bitstream Metadata, so scan for start codes.
    +
    1368  int offset = 0;
    +
    1369  int sequence_start_code = 0;
    +
    1370  int frame_start_code = 0;
    +
    1371  while (true) {
    +
    1372  // Advance to start_code, if there is one.
    +
    1373  if (!AdvanceToStartCode(buffer, buffer_size, &offset, 5, 24, 1)) {
    +
    1374  // Not a complete sequence in memory, so return true if we've seen a
    +
    1375  // sequence start and a frame start (not checking entry points since
    +
    1376  // they only occur in advanced profiles).
    +
    1377  return (sequence_start_code > 0 && frame_start_code > 0);
    +
    1378  }
    +
    1379 
    +
    1380  // Now verify the block. AdvanceToStartCode() made sure that there are
    +
    1381  // at least 5 bytes remaining in the buffer.
    +
    1382  BitReader reader(buffer + offset, 5);
    +
    1383  RCHECK(ReadBits(&reader, 24) == 1);
    +
    1384 
    +
    1385  // Keep track of the number of certain types received.
    +
    1386  switch (ReadBits(&reader, 8)) {
    +
    1387  case VC1_SEQUENCE_START_CODE: {
    +
    1388  ++sequence_start_code;
    +
    1389  switch (ReadBits(&reader, 2)) {
    +
    1390  case 0: // simple
    +
    1391  case 1: // main
    +
    1392  RCHECK(ReadBits(&reader, 2) == 0);
    +
    1393  break;
    +
    1394  case 2: // complex
    +
    1395  return false;
    +
    1396  case 3: // advanced
    +
    1397  RCHECK(ReadBits(&reader, 3) <= 4); // Verify level = 0..4
    +
    1398  RCHECK(ReadBits(&reader, 2) == 1); // Verify colordiff_format = 1
    +
    1399  break;
    +
    1400  }
    +
    1401  break;
    +
    1402  }
    +
    1403 
    +
    1404  case VC1_ENTRY_POINT_START_CODE:
    +
    1405  // No fields in entry data to check. However, it must occur after
    +
    1406  // sequence header.
    +
    1407  RCHECK(sequence_start_code > 0);
    +
    1408  break;
    +
    1409 
    +
    1410  case VC1_FRAME_START_CODE:
    +
    1411  ++frame_start_code;
    +
    1412  break;
    +
    1413  }
    +
    1414  offset += 5;
    +
    1415  }
    +
    1416 }
    +
    1417 
    +
    1418 // For some formats the signature is a bunch of characters. They are defined
    +
    1419 // below. Note that the first 4 characters of the string may be used as a TAG
    +
    1420 // in LookupContainerByFirst4. For signatures that contain embedded \0, use
    +
    1421 // uint8_t[].
    +
    1422 static const char kAmrSignature[] = "#!AMR";
    +
    1423 static const uint8_t kAsfSignature[] = {0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66,
    +
    1424  0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa,
    +
    1425  0x00, 0x62, 0xce, 0x6c};
    +
    1426 static const char kAssSignature[] = "[Script Info]";
    +
    1427 static const char kAssBomSignature[] = UTF8_BYTE_ORDER_MARK "[Script Info]";
    +
    1428 static const uint8_t kWtvSignature[] = {0xb7, 0xd8, 0x00, 0x20, 0x37, 0x49,
    +
    1429  0xda, 0x11, 0xa6, 0x4e, 0x00, 0x07,
    +
    1430  0xe9, 0x5e, 0xad, 0x8d};
    +
    1431 
    +
    1432 // Attempt to determine the container type from the buffer provided. This is
    +
    1433 // a simple pass, that uses the first 4 bytes of the buffer as an index to get
    +
    1434 // a rough idea of the container format.
    +
    1435 static MediaContainerName LookupContainerByFirst4(const uint8_t* buffer,
    +
    1436  int buffer_size) {
    +
    1437  // Minimum size that the code expects to exist without checking size.
    +
    1438  if (buffer_size < 12)
    +
    1439  return CONTAINER_UNKNOWN;
    +
    1440 
    +
    1441  uint32_t first4 = Read32(buffer);
    +
    1442  switch (first4) {
    +
    1443  case 0x1a45dfa3:
    +
    1444  if (CheckWebm(buffer, buffer_size))
    +
    1445  return CONTAINER_WEBM;
    +
    1446  break;
    +
    1447 
    +
    1448  case 0x3026b275:
    +
    1449  if (StartsWith(buffer,
    +
    1450  buffer_size,
    +
    1451  kAsfSignature,
    +
    1452  sizeof(kAsfSignature))) {
    +
    1453  return CONTAINER_ASF;
    +
    1454  }
    +
    1455  break;
    +
    1456 
    +
    1457  case TAG('#','!','A','M'):
    +
    1458  if (StartsWith(buffer, buffer_size, kAmrSignature))
    +
    1459  return CONTAINER_AMR;
    +
    1460  break;
    +
    1461 
    +
    1462  case TAG('#','E','X','T'):
    +
    1463  if (CheckHls(buffer, buffer_size))
    +
    1464  return CONTAINER_HLS;
    +
    1465  break;
    +
    1466 
    +
    1467  case TAG('.','R','M','F'):
    +
    1468  if (buffer[4] == 0 && buffer[5] == 0)
    +
    1469  return CONTAINER_RM;
    +
    1470  break;
    +
    1471 
    +
    1472  case TAG('.','r','a','\xfd'):
    +
    1473  return CONTAINER_RM;
    +
    1474 
    +
    1475  case TAG('B','I','K','b'):
    +
    1476  case TAG('B','I','K','d'):
    +
    1477  case TAG('B','I','K','f'):
    +
    1478  case TAG('B','I','K','g'):
    +
    1479  case TAG('B','I','K','h'):
    +
    1480  case TAG('B','I','K','i'):
    +
    1481  if (CheckBink(buffer, buffer_size))
    +
    1482  return CONTAINER_BINK;
    +
    1483  break;
    +
    1484 
    +
    1485  case TAG('c','a','f','f'):
    +
    1486  if (CheckCaf(buffer, buffer_size))
    +
    1487  return CONTAINER_CAF;
    +
    1488  break;
    +
    1489 
    +
    1490  case TAG('D','E','X','A'):
    +
    1491  if (buffer_size > 15 &&
    +
    1492  Read16(buffer + 11) <= 2048 &&
    +
    1493  Read16(buffer + 13) <= 2048) {
    +
    1494  return CONTAINER_DXA;
    +
    1495  }
    +
    1496  break;
    +
    1497 
    +
    1498  case TAG('D','T','S','H'):
    +
    1499  if (Read32(buffer + 4) == TAG('D','H','D','R'))
    +
    1500  return CONTAINER_DTSHD;
    +
    1501  break;
    +
    1502 
    +
    1503  case 0x64a30100:
    +
    1504  case 0x64a30200:
    +
    1505  case 0x64a30300:
    +
    1506  case 0x64a30400:
    +
    1507  case 0x0001a364:
    +
    1508  case 0x0002a364:
    +
    1509  case 0x0003a364:
    +
    1510  if (Read32(buffer + 4) != 0 && Read32(buffer + 8) != 0)
    +
    1511  return CONTAINER_IRCAM;
    +
    1512  break;
    +
    1513 
    +
    1514  case TAG('f','L','a','C'):
    +
    1515  return CONTAINER_FLAC;
    +
    1516 
    +
    1517  case TAG('F','L','V',0):
    +
    1518  case TAG('F','L','V',1):
    +
    1519  case TAG('F','L','V',2):
    +
    1520  case TAG('F','L','V',3):
    +
    1521  case TAG('F','L','V',4):
    +
    1522  if (buffer[5] == 0 && Read32(buffer + 5) > 8)
    +
    1523  return CONTAINER_FLV;
    +
    1524  break;
    +
    1525 
    +
    1526  case TAG('F','O','R','M'):
    +
    1527  switch (Read32(buffer + 8)) {
    +
    1528  case TAG('A','I','F','F'):
    +
    1529  case TAG('A','I','F','C'):
    +
    1530  return CONTAINER_AIFF;
    +
    1531  }
    +
    1532  break;
    +
    1533 
    +
    1534  case TAG('M','A','C',' '):
    +
    1535  return CONTAINER_APE;
    +
    1536 
    +
    1537  case TAG('O','N','2',' '):
    +
    1538  if (Read32(buffer + 8) == TAG('O','N','2','f'))
    +
    1539  return CONTAINER_AVI;
    +
    1540  break;
    +
    1541 
    +
    1542  case TAG('O','g','g','S'):
    +
    1543  if (buffer[5] <= 7)
    +
    1544  return CONTAINER_OGG;
    +
    1545  break;
    +
    1546 
    +
    1547  case TAG('R','F','6','4'):
    +
    1548  if (buffer_size > 16 && Read32(buffer + 12) == TAG('d','s','6','4'))
    +
    1549  return CONTAINER_WAV;
    +
    1550  break;
    +
    1551 
    +
    1552  case TAG('R','I','F','F'):
    +
    1553  switch (Read32(buffer + 8)) {
    +
    1554  case TAG('A','V','I',' '):
    +
    1555  case TAG('A','V','I','X'):
    +
    1556  case TAG('A','V','I','\x19'):
    +
    1557  case TAG('A','M','V',' '):
    +
    1558  return CONTAINER_AVI;
    +
    1559  case TAG('W','A','V','E'):
    +
    1560  return CONTAINER_WAV;
    +
    1561  }
    +
    1562  break;
    +
    1563 
    +
    1564  case TAG('[','S','c','r'):
    +
    1565  if (StartsWith(buffer, buffer_size, kAssSignature))
    +
    1566  return CONTAINER_ASS;
    +
    1567  break;
    +
    1568 
    +
    1569  case TAG('\xef','\xbb','\xbf','['):
    +
    1570  if (StartsWith(buffer, buffer_size, kAssBomSignature))
    +
    1571  return CONTAINER_ASS;
    +
    1572  break;
    +
    1573 
    +
    1574  case 0x7ffe8001:
    +
    1575  case 0xfe7f0180:
    +
    1576  case 0x1fffe800:
    +
    1577  case 0xff1f00e8:
    +
    1578  if (CheckDts(buffer, buffer_size))
    +
    1579  return CONTAINER_DTS;
    +
    1580  break;
    +
    1581 
    +
    1582  case 0xb7d80020:
    +
    1583  if (StartsWith(buffer,
    +
    1584  buffer_size,
    +
    1585  kWtvSignature,
    +
    1586  sizeof(kWtvSignature))) {
    +
    1587  return CONTAINER_WTV;
    +
    1588  }
    +
    1589  break;
    +
    1590  case 0x000001ba:
    +
    1591  return CONTAINER_MPEG2PS;
    +
    1592  }
    +
    1593 
    +
    1594  // Now try a few different ones that look at something other
    +
    1595  // than the first 4 bytes.
    +
    1596  uint32_t first3 = first4 & 0xffffff00;
    +
    1597  switch (first3) {
    +
    1598  case TAG('C','W','S',0):
    +
    1599  case TAG('F','W','S',0):
    +
    1600  return CONTAINER_SWF;
    +
    1601 
    +
    1602  case TAG('I','D','3',0):
    +
    1603  if (CheckMp3(buffer, buffer_size, true))
    +
    1604  return CONTAINER_MP3;
    +
    1605  break;
    +
    1606  }
    +
    1607 
    +
    1608  // Maybe the first 2 characters are something we can use.
    +
    1609  uint32_t first2 = Read16(buffer);
    +
    1610  switch (first2) {
    +
    1611  case kAc3SyncWord:
    +
    1612  if (CheckAc3(buffer, buffer_size))
    +
    1613  return CONTAINER_AC3;
    +
    1614  if (CheckEac3(buffer, buffer_size))
    +
    1615  return CONTAINER_EAC3;
    +
    1616  break;
    +
    1617 
    +
    1618  case 0xfff0:
    +
    1619  case 0xfff1:
    +
    1620  case 0xfff8:
    +
    1621  case 0xfff9:
    +
    1622  if (CheckAac(buffer, buffer_size))
    +
    1623  return CONTAINER_AAC;
    +
    1624  break;
    +
    1625  }
    +
    1626 
    +
    1627  // Check if the file is in MP3 format without the header.
    +
    1628  if (CheckMp3(buffer, buffer_size, false))
    +
    1629  return CONTAINER_MP3;
    +
    1630 
    +
    1631  return CONTAINER_UNKNOWN;
    +
    1632 }
    +
    1633 
    +
    1634 namespace {
    +
    1635 const char kWebVtt[] = "WEBVTT";
    +
    1636 
    +
    1637 bool CheckWebVtt(const uint8_t* buffer, int buffer_size) {
    +
    1638  const int offset =
    +
    1639  StartsWith(buffer, buffer_size, UTF8_BYTE_ORDER_MARK) ? 3 : 0;
    +
    1640 
    +
    1641  return StartsWith(buffer + offset, buffer_size - offset,
    +
    1642  reinterpret_cast<const uint8_t*>(kWebVtt),
    +
    1643  arraysize(kWebVtt) - 1);
    +
    1644 }
    +
    1645 
    +
    1646 bool CheckTtml(const uint8_t* buffer, int buffer_size) {
    +
    1647  // Sanity check first before reading the entire thing.
    +
    1648  if (!StartsWith(buffer, buffer_size, "<?xml"))
    +
    1649  return false;
    +
    1650 
    +
    1651  // Make sure that it can be parsed so that it doesn't error later in the
    +
    1652  // process. Not doing a schema check to allow TTMLs that makes some sense but
    +
    1653  // not necessarily compliant to the schema.
    +
    1654  xml::scoped_xml_ptr<xmlDoc> doc(
    +
    1655  xmlParseMemory(reinterpret_cast<const char*>(buffer), buffer_size));
    +
    1656  if (!doc)
    +
    1657  return false;
    +
    1658 
    +
    1659  xmlNodePtr root_node = xmlDocGetRootElement(doc.get());
    +
    1660  std::string root_node_name(reinterpret_cast<const char*>(root_node->name));
    +
    1661  // "tt" is supposed to be the top level element for ttml.
    +
    1662  return root_node_name == "tt";
    +
    1663 }
    +
    1664 
    +
    1665 } // namespace
    +
    1666 
    +
    1667 // Attempt to determine the container name from the buffer provided.
    +
    1668 MediaContainerName DetermineContainer(const uint8_t* buffer, int buffer_size) {
    +
    1669  DCHECK(buffer);
    +
    1670 
    +
    1671  // Since MOV/QuickTime/MPEG4 streams are common, check for them first.
    +
    1672  if (CheckMov(buffer, buffer_size))
    +
    1673  return CONTAINER_MOV;
    +
    1674 
    +
    1675  // Next attempt the simple checks, that typically look at just the
    +
    1676  // first few bytes of the file.
    +
    1677  MediaContainerName result = LookupContainerByFirst4(buffer, buffer_size);
    +
    1678  if (result != CONTAINER_UNKNOWN)
    +
    1679  return result;
    +
    1680 
    +
    1681  // WebVTT check only checks for the first few bytes.
    +
    1682  if (CheckWebVtt(buffer, buffer_size))
    +
    1683  return CONTAINER_WEBVTT;
    +
    1684 
    +
    1685  // Additional checks that may scan a portion of the buffer.
    +
    1686  if (CheckMpeg2ProgramStream(buffer, buffer_size))
    +
    1687  return CONTAINER_MPEG2PS;
    +
    1688  if (CheckMpeg2TransportStream(buffer, buffer_size))
    +
    1689  return CONTAINER_MPEG2TS;
    +
    1690  if (CheckMJpeg(buffer, buffer_size))
    +
    1691  return CONTAINER_MJPEG;
    +
    1692  if (CheckDV(buffer, buffer_size))
    +
    1693  return CONTAINER_DV;
    +
    1694  if (CheckH261(buffer, buffer_size))
    +
    1695  return CONTAINER_H261;
    +
    1696  if (CheckH263(buffer, buffer_size))
    +
    1697  return CONTAINER_H263;
    +
    1698  if (CheckH264(buffer, buffer_size))
    +
    1699  return CONTAINER_H264;
    +
    1700  if (CheckMpeg4BitStream(buffer, buffer_size))
    +
    1701  return CONTAINER_MPEG4BS;
    +
    1702  if (CheckVC1(buffer, buffer_size))
    +
    1703  return CONTAINER_VC1;
    +
    1704  if (CheckSrt(buffer, buffer_size))
    +
    1705  return CONTAINER_SRT;
    +
    1706  if (CheckGsm(buffer, buffer_size))
    +
    1707  return CONTAINER_GSM;
    +
    1708 
    +
    1709  // AC3/EAC3 might not start at the beginning of the stream,
    +
    1710  // so scan for a start code.
    +
    1711  int offset = 1; // No need to start at byte 0 due to First4 check.
    +
    1712  if (AdvanceToStartCode(buffer, buffer_size, &offset, 4, 16, kAc3SyncWord)) {
    +
    1713  if (CheckAc3(buffer + offset, buffer_size - offset))
    +
    1714  return CONTAINER_AC3;
    +
    1715  if (CheckEac3(buffer + offset, buffer_size - offset))
    +
    1716  return CONTAINER_EAC3;
    +
    1717  }
    +
    1718 
    +
    1719  // To do a TTML check, it parses the XML which requires scanning
    +
    1720  // the whole content.
    +
    1721  if (CheckTtml(buffer, buffer_size))
    +
    1722  return CONTAINER_TTML;
    +
    1723 
    +
    1724  return CONTAINER_UNKNOWN;
    +
    1725 }
    +
    1726 
    +
    1727 MediaContainerName DetermineContainerFromFormatName(
    +
    1728  const std::string& format_name) {
    +
    1729  if (base::EqualsCaseInsensitiveASCII(format_name, "aac") ||
    +
    1730  base::EqualsCaseInsensitiveASCII(format_name, "adts")) {
    +
    1731  return CONTAINER_AAC;
    +
    1732  } else if (base::EqualsCaseInsensitiveASCII(format_name, "ac3")) {
    +
    1733  return CONTAINER_AC3;
    +
    1734  } else if (base::EqualsCaseInsensitiveASCII(format_name, "ec3") ||
    +
    1735  base::EqualsCaseInsensitiveASCII(format_name, "eac3")) {
    +
    1736  return CONTAINER_EAC3;
    +
    1737  } else if (base::EqualsCaseInsensitiveASCII(format_name, "mp3")) {
    +
    1738  return CONTAINER_MP3;
    +
    1739  } else if (base::EqualsCaseInsensitiveASCII(format_name, "webm")) {
    +
    1740  return CONTAINER_WEBM;
    +
    1741  } else if (base::EqualsCaseInsensitiveASCII(format_name, "cmfa") ||
    +
    1742  base::EqualsCaseInsensitiveASCII(format_name, "cmft") ||
    +
    1743  base::EqualsCaseInsensitiveASCII(format_name, "cmfv") ||
    +
    1744  base::EqualsCaseInsensitiveASCII(format_name, "m4a") ||
    +
    1745  base::EqualsCaseInsensitiveASCII(format_name, "m4s") ||
    +
    1746  base::EqualsCaseInsensitiveASCII(format_name, "m4v") ||
    +
    1747  base::EqualsCaseInsensitiveASCII(format_name, "mov") ||
    +
    1748  base::EqualsCaseInsensitiveASCII(format_name, "mp4") ||
    +
    1749  base::EqualsCaseInsensitiveASCII(format_name, "ttml+mp4") ||
    +
    1750  base::EqualsCaseInsensitiveASCII(format_name, "webvtt+mp4") ||
    +
    1751  base::EqualsCaseInsensitiveASCII(format_name, "vtt+mp4")) {
    +
    1752  return CONTAINER_MOV;
    +
    1753  } else if (base::EqualsCaseInsensitiveASCII(format_name, "ts") ||
    +
    1754  base::EqualsCaseInsensitiveASCII(format_name, "mpeg2ts")) {
    +
    1755  return CONTAINER_MPEG2TS;
    +
    1756  } else if (base::EqualsCaseInsensitiveASCII(format_name, "wvm")) {
    +
    1757  return CONTAINER_WVM;
    +
    1758  } else if (base::EqualsCaseInsensitiveASCII(format_name, "vtt") ||
    +
    1759  base::EqualsCaseInsensitiveASCII(format_name, "webvtt")) {
    +
    1760  return CONTAINER_WEBVTT;
    +
    1761  } else if (base::EqualsCaseInsensitiveASCII(format_name, "ttml") ||
    +
    1762  // Treat xml as ttml.
    +
    1763  base::EqualsCaseInsensitiveASCII(format_name, "xml")) {
    +
    1764  return CONTAINER_TTML;
    +
    1765  }
    +
    1766  return CONTAINER_UNKNOWN;
    +
    1767 }
    +
    1768 
    +
    1769 MediaContainerName DetermineContainerFromFileName(
    +
    1770  const std::string& file_name) {
    +
    1771  const size_t pos = file_name.rfind('.');
    +
    1772  if (pos == std::string::npos)
    +
    1773  return CONTAINER_UNKNOWN;
    +
    1774  const std::string& file_extension = file_name.substr(pos + 1);
    +
    1775  return DetermineContainerFromFormatName(file_extension);
    +
    1776 }
    +
    1777 
    +
    1778 } // namespace media
    +
    1779 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/d93/origin__handler_8cc_source.html b/docs/da/d93/origin__handler_8cc_source.html index c5ea1aa27a..42cfc3d3e2 100644 --- a/docs/da/d93/origin__handler_8cc_source.html +++ b/docs/da/d93/origin__handler_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/origin/origin_handler.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    origin_handler.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/origin/origin_handler.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 
    12 // Origin handlers are always at the start of a pipeline (chain or handlers)
    13 // and therefore should never receive input via |Process|.
    14 Status OriginHandler::Process(std::unique_ptr<StreamData> stream_data) {
    15  return Status(error::INTERNAL_ERROR,
    16  "An origin handlers should never be a downstream handler.");
    17 }
    18 
    19 } // namespace media
    20 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/origin/origin_handler.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 
    +
    12 // Origin handlers are always at the start of a pipeline (chain or handlers)
    +
    13 // and therefore should never receive input via |Process|.
    +
    14 Status OriginHandler::Process(std::unique_ptr<StreamData> stream_data) {
    +
    15  return Status(error::INTERNAL_ERROR,
    +
    16  "An origin handlers should never be a downstream handler.");
    +
    17 }
    +
    18 
    +
    19 } // namespace media
    +
    20 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/d93/structshaka_1_1media_1_1CueEvent.html b/docs/da/d93/structshaka_1_1media_1_1CueEvent.html index 66b6a0b0be..e81397187d 100644 --- a/docs/da/d93/structshaka_1_1media_1_1CueEvent.html +++ b/docs/da/d93/structshaka_1_1media_1_1CueEvent.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::CueEvent Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    cue_data diff --git a/docs/da/d9b/structshaka_1_1media_1_1mp4_1_1CompositionOffset-members.html b/docs/da/d9b/structshaka_1_1media_1_1mp4_1_1CompositionOffset-members.html index 6229dee027..a52ca7f5a4 100644 --- a/docs/da/d9b/structshaka_1_1media_1_1mp4_1_1CompositionOffset-members.html +++ b/docs/da/d9b/structshaka_1_1media_1_1mp4_1_1CompositionOffset-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/da/d9d/structshaka_1_1media_1_1mp4_1_1EC3Specific-members.html b/docs/da/d9d/structshaka_1_1media_1_1mp4_1_1EC3Specific-members.html index 7aad87fbb1..0d2f86445a 100644 --- a/docs/da/d9d/structshaka_1_1media_1_1mp4_1_1EC3Specific-members.html +++ b/docs/da/d9d/structshaka_1_1media_1_1mp4_1_1EC3Specific-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/d9f/classshaka_1_1MpdNotifierFactory-members.html b/docs/da/d9f/classshaka_1_1MpdNotifierFactory-members.html index 9e6720dd13..54b670bb85 100644 --- a/docs/da/d9f/classshaka_1_1MpdNotifierFactory-members.html +++ b/docs/da/d9f/classshaka_1_1MpdNotifierFactory-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/d9f/classshaka_1_1media_1_1MockMuxerListener-members.html b/docs/da/d9f/classshaka_1_1media_1_1MockMuxerListener-members.html index acff8082eb..ed1132534e 100644 --- a/docs/da/d9f/classshaka_1_1media_1_1MockMuxerListener-members.html +++ b/docs/da/d9f/classshaka_1_1media_1_1MockMuxerListener-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/da1/classshaka_1_1media_1_1mp2t_1_1TsPacket.html b/docs/da/da1/classshaka_1_1media_1_1mp2t_1_1TsPacket.html index 4efc40bef7..7477b336c5 100644 --- a/docs/da/da1/classshaka_1_1media_1_1mp2t_1_1TsPacket.html +++ b/docs/da/da1/classshaka_1_1media_1_1mp2t_1_1TsPacket.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::TsPacket Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    kPacketSi
    diff --git a/docs/da/dab/classshaka_1_1media_1_1CueAlignmentHandler.html b/docs/da/dab/classshaka_1_1media_1_1CueAlignmentHandler.html index ee7ab0e4aa..4ad442f44e 100644 --- a/docs/da/dab/classshaka_1_1media_1_1CueAlignmentHandler.html +++ b/docs/da/dab/classshaka_1_1media_1_1CueAlignmentHandler.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::CueAlignmentHandler Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MediaHandler - -
    + + @@ -106,9 +109,9 @@ bool  - - + + @@ -162,7 +165,7 @@ const std::map< size_t, std::pair< std::shared_ptr<

    Public Member Functions

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    virtual bool ValidateOutputStreamIndex (size_t stream_index) const
     

    Detailed Description

    -

    The cue alignment handler is a N-to-N handler that will inject CueEvents into all streams. It will align the cues across streams (and handlers) using a shared SyncPointQueue.

    +

    The cue alignment handler is a N-to-N handler that will inject CueEvents into all streams. It will align the cues across streams (and handlers) using a shared SyncPointQueue.

    There should be a cue alignment handler per demuxer/thread and not per stream. A cue alignment handler must be one per thread in order to properly manage blocking.

    Definition at line 25 of file cue_alignment_handler.h.

    @@ -173,9 +176,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/da/db2/classshaka_1_1Representation-members.html b/docs/da/db2/classshaka_1_1Representation-members.html index f04e06c3df..1edfcb92a8 100644 --- a/docs/da/db2/classshaka_1_1Representation-members.html +++ b/docs/da/db2/classshaka_1_1Representation-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    AddNewSegment(int64_t start_time, int64_t duration, uint64_t size)shaka::Representationvirtual GetMediaInfo() constshaka::Representationvirtual GetStartAndEndTimestamps(double *start_timestamp_seconds, double *end_timestamp_seconds) constshaka::Representation - GetXml()shaka::Representation + GetXml()shaka::Representation id() constshaka::Representationinline Init()shaka::Representation kSuppressFrameRate enum value (defined in shaka::Representation)shaka::Representation @@ -93,9 +96,7 @@ $(function() {
    diff --git a/docs/da/db3/webvtt__file__buffer_8cc_source.html b/docs/da/db3/webvtt__file__buffer_8cc_source.html index 708f64b2b2..fef114587c 100644 --- a/docs/da/db3/webvtt__file__buffer_8cc_source.html +++ b/docs/da/db3/webvtt__file__buffer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/webvtt_file_buffer.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    webvtt_file_buffer.cc
    -
    1 // Copyright 2018 Google LLC All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/webvtt/webvtt_file_buffer.h"
    8 
    9 #include "packager/base/strings/stringprintf.h"
    10 #include "packager/media/base/text_sample.h"
    11 #include "packager/media/formats/webvtt/webvtt_timestamp.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace {
    16 const char* kHeader = "WEBVTT\n";
    17 const int kTsTimescale = 90000;
    18 } // namespace
    19 
    20 WebVttFileBuffer::WebVttFileBuffer(
    21  uint32_t transport_stream_timestamp_offset_ms,
    22  const std::string& style_region_config)
    23  : transport_stream_timestamp_offset_(transport_stream_timestamp_offset_ms *
    24  kTsTimescale / 1000),
    25  style_region_config_(style_region_config) {
    26  // Make sure we start with the same state that we would end up with if
    27  // the caller reset our state.
    28  Reset();
    29 }
    30 
    31 void WebVttFileBuffer::Reset() {
    32  sample_count_ = 0;
    33 
    34  buffer_.clear();
    35  buffer_.append(kHeader);
    36  if (transport_stream_timestamp_offset_ > 0) {
    37  // https://tools.ietf.org/html/rfc8216#section-3.5 WebVTT.
    38  base::StringAppendF(&buffer_,
    39  "X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:%d\n",
    40  transport_stream_timestamp_offset_);
    41  }
    42  buffer_.append("\n"); // end of header.
    43  if (!style_region_config_.empty()) {
    44  buffer_.append(style_region_config_);
    45  buffer_.append("\n\n");
    46  }
    47 }
    48 
    49 void WebVttFileBuffer::Append(const TextSample& sample) {
    50  DCHECK_GT(buffer_.size(), 0u) << "The buffer should at least have a header";
    51 
    52  sample_count_++;
    53 
    54  // Ids are optional
    55  if (sample.id().length()) {
    56  buffer_.append(sample.id());
    57  buffer_.append("\n"); // end of id
    58  }
    59 
    60  // Write the times that the sample elapses.
    61  buffer_.append(MsToWebVttTimestamp(sample.start_time()));
    62  buffer_.append(" --> ");
    63  buffer_.append(MsToWebVttTimestamp(sample.EndTime()));
    64 
    65  // Settings are optional
    66  if (sample.settings().length()) {
    67  buffer_.append(" ");
    68  buffer_.append(sample.settings());
    69  }
    70  buffer_.append("\n"); // end of time & settings
    71 
    72  buffer_.append(sample.payload());
    73  buffer_.append("\n"); // end of payload
    74  buffer_.append("\n"); // end of sample
    75 }
    76 
    77 bool WebVttFileBuffer::WriteTo(File* file) {
    78  DCHECK(file);
    79  DCHECK_GT(buffer_.size(), 0u) << "The buffer should at least have a header";
    80 
    81  const int written = file->Write(buffer_.c_str(), buffer_.size());
    82  if (written < 0) {
    83  return false;
    84  }
    85 
    86  return static_cast<size_t>(written) == buffer_.size();
    87 }
    88 } // namespace media
    89 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2018 Google LLC All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webvtt/webvtt_file_buffer.h"
    +
    8 
    +
    9 #include "packager/base/strings/stringprintf.h"
    +
    10 #include "packager/media/base/text_sample.h"
    +
    11 #include "packager/media/formats/webvtt/webvtt_utils.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace {
    +
    16 const char* kHeader = "WEBVTT\n";
    +
    17 const int kTsTimescale = 90000;
    +
    18 } // namespace
    +
    19 
    +
    20 WebVttFileBuffer::WebVttFileBuffer(
    +
    21  uint32_t transport_stream_timestamp_offset_ms,
    +
    22  const std::string& style_region_config)
    +
    23  : transport_stream_timestamp_offset_(transport_stream_timestamp_offset_ms *
    +
    24  kTsTimescale / 1000),
    +
    25  style_region_config_(style_region_config) {
    +
    26  // Make sure we start with the same state that we would end up with if
    +
    27  // the caller reset our state.
    +
    28  Reset();
    +
    29 }
    +
    30 
    +
    31 void WebVttFileBuffer::Reset() {
    +
    32  sample_count_ = 0;
    +
    33 
    +
    34  buffer_.clear();
    +
    35  buffer_.append(kHeader);
    +
    36  if (transport_stream_timestamp_offset_ > 0) {
    +
    37  // https://tools.ietf.org/html/rfc8216#section-3.5 WebVTT.
    +
    38  base::StringAppendF(&buffer_,
    +
    39  "X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:%d\n",
    +
    40  transport_stream_timestamp_offset_);
    +
    41  }
    +
    42  buffer_.append("\n"); // end of header.
    +
    43  if (!style_region_config_.empty()) {
    +
    44  buffer_.append(style_region_config_);
    +
    45  buffer_.append("\n\n");
    +
    46  }
    +
    47 }
    +
    48 
    +
    49 void WebVttFileBuffer::Append(const TextSample& sample) {
    +
    50  DCHECK_GT(buffer_.size(), 0u) << "The buffer should at least have a header";
    +
    51 
    +
    52  sample_count_++;
    +
    53 
    +
    54  // Ids are optional
    +
    55  if (sample.id().length()) {
    +
    56  buffer_.append(sample.id());
    +
    57  buffer_.append("\n"); // end of id
    +
    58  }
    +
    59 
    +
    60  // Write the times that the sample elapses.
    +
    61  buffer_.append(MsToWebVttTimestamp(sample.start_time()));
    +
    62  buffer_.append(" --> ");
    +
    63  buffer_.append(MsToWebVttTimestamp(sample.EndTime()));
    +
    64  const std::string settings = WebVttSettingsToString(sample.settings());
    +
    65  if (!settings.empty()) {
    +
    66  buffer_.append(" ");
    +
    67  buffer_.append(settings);
    +
    68  }
    +
    69  buffer_.append("\n"); // end of time & settings
    +
    70 
    +
    71  buffer_.append(WebVttFragmentToString(sample.body()));
    +
    72  buffer_.append("\n"); // end of payload
    +
    73  buffer_.append("\n"); // end of sample
    +
    74 }
    +
    75 
    +
    76 bool WebVttFileBuffer::WriteTo(File* file, uint64_t* size) {
    +
    77  DCHECK(file);
    +
    78  DCHECK_GT(buffer_.size(), 0u) << "The buffer should at least have a header";
    +
    79 
    +
    80  if (size)
    +
    81  *size = buffer_.size();
    +
    82  const int written = file->Write(buffer_.c_str(), buffer_.size());
    +
    83  if (written < 0) {
    +
    84  return false;
    +
    85  }
    +
    86 
    +
    87  return static_cast<size_t>(written) == buffer_.size();
    +
    88 }
    +
    89 } // namespace media
    +
    90 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/dbb/classshaka_1_1media_1_1DOVIDecoderConfigurationRecord.html b/docs/da/dbb/classshaka_1_1media_1_1DOVIDecoderConfigurationRecord.html index 4fd66ea3bb..acafa4d98b 100644 --- a/docs/da/dbb/classshaka_1_1media_1_1DOVIDecoderConfigurationRecord.html +++ b/docs/da/dbb/classshaka_1_1media_1_1DOVIDecoderConfigurationRecord.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::DOVIDecoderConfigurationRecord Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/da/dbb/structshaka_1_1media_1_1mp4_1_1HandlerReference.html b/docs/da/dbb/structshaka_1_1media_1_1mp4_1_1HandlerReference.html index 6362c92123..0746bf449e 100644 --- a/docs/da/dbb/structshaka_1_1media_1_1mp4_1_1HandlerReference.html +++ b/docs/da/dbb/structshaka_1_1media_1_1mp4_1_1HandlerReference.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::HandlerReference Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 227 of file box_definitions.h.

    +

    Definition at line 228 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1265 of file box_definitions.cc.

    +

    Definition at line 1283 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/da/dc3/classshaka_1_1media_1_1AV1Parser-members.html b/docs/da/dc3/classshaka_1_1media_1_1AV1Parser-members.html index 7f418922d8..6e42825a82 100644 --- a/docs/da/dc3/classshaka_1_1media_1_1AV1Parser-members.html +++ b/docs/da/dc3/classshaka_1_1media_1_1AV1Parser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/dc3/status_8cc_source.html b/docs/da/dc3/status_8cc_source.html index a97ef1943c..091740be67 100644 --- a/docs/da/dc3/status_8cc_source.html +++ b/docs/da/dc3/status_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/status.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    status.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/status.h"
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/base/strings/stringprintf.h"
    11 
    12 namespace shaka {
    13 
    14 namespace error {
    15 namespace {
    16 const char* ErrorCodeToString(Code error_code) {
    17  switch (error_code) {
    18  case OK:
    19  return "OK";
    20  case UNKNOWN:
    21  return "UNKNOWN";
    22  case CANCELLED:
    23  return "CANCELLED";
    24  case INVALID_ARGUMENT:
    25  return "INVALID_ARGUMENT";
    26  case UNIMPLEMENTED:
    27  return "UNIMPLEMENTED";
    28  case FILE_FAILURE:
    29  return "FILE_FAILURE";
    30  case END_OF_STREAM:
    31  return "END_OF_STREAM";
    32  case HTTP_FAILURE:
    33  return "HTTP_FAILURE";
    34  case PARSER_FAILURE:
    35  return "PARSER_FAILURE";
    36  case ENCRYPTION_FAILURE:
    37  return "ENCRYPTION_FAILURE";
    38  case CHUNKING_ERROR:
    39  return "CHUNKING_ERROR";
    40  case MUXER_FAILURE:
    41  return "MUXER_FAILURE";
    42  case FRAGMENT_FINALIZED:
    43  return "FRAGMENT_FINALIZED";
    44  case SERVER_ERROR:
    45  return "SERVER_ERROR";
    46  case INTERNAL_ERROR:
    47  return "INTERNAL_ERROR";
    48  case STOPPED:
    49  return "STOPPED";
    50  case TIME_OUT:
    51  return "TIME_OUT";
    52  case NOT_FOUND:
    53  return "NOT_FOUND";
    54  case ALREADY_EXISTS:
    55  return "ALREADY_EXISTS";
    56  case TRICK_PLAY_ERROR:
    57  return "TRICK_PLAY_ERROR";
    58  }
    59 
    60  NOTIMPLEMENTED() << "Unknown Status Code: " << error_code;
    61  return "UNKNOWN_STATUS";
    62 }
    63 } // namespace
    64 } // namespace error
    65 
    66 const Status Status::OK = Status(error::OK, "");
    67 const Status Status::UNKNOWN = Status(error::UNKNOWN, "");
    68 
    69 Status::Status(error::Code error_code, const std::string& error_message)
    70  : error_code_(error_code) {
    71  if (!ok()) {
    72  error_message_ = error_message;
    73  if (!error_message.empty())
    74  VLOG(1) << ToString();
    75  }
    76 }
    77 
    78 void Status::Update(Status new_status) {
    79  if (ok())
    80  *this = std::move(new_status);
    81 }
    82 
    83 std::string Status::ToString() const {
    84  if (error_code_ == error::OK)
    85  return "OK";
    86 
    87  return base::StringPrintf("%d (%s): %s", error_code_,
    88  error::ErrorCodeToString(error_code_),
    89  error_message_.c_str());
    90 }
    91 
    92 std::ostream& operator<<(std::ostream& os, const Status& x) {
    93  os << x.ToString();
    94  return os;
    95 }
    96 
    97 } // namespace shaka
    std::string ToString() const
    Definition: status.cc:83
    -
    All the methods that are virtual are virtual for mocking.
    - -
    Status()
    Creates a "successful" status.
    Definition: status.h:113
    -
    void Update(Status new_status)
    Definition: status.cc:78
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/status.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/base/strings/stringprintf.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 
    +
    14 namespace error {
    +
    15 namespace {
    +
    16 const char* ErrorCodeToString(Code error_code) {
    +
    17  switch (error_code) {
    +
    18  case OK:
    +
    19  return "OK";
    +
    20  case UNKNOWN:
    +
    21  return "UNKNOWN";
    +
    22  case CANCELLED:
    +
    23  return "CANCELLED";
    +
    24  case INVALID_ARGUMENT:
    +
    25  return "INVALID_ARGUMENT";
    +
    26  case UNIMPLEMENTED:
    +
    27  return "UNIMPLEMENTED";
    +
    28  case FILE_FAILURE:
    +
    29  return "FILE_FAILURE";
    +
    30  case END_OF_STREAM:
    +
    31  return "END_OF_STREAM";
    +
    32  case HTTP_FAILURE:
    +
    33  return "HTTP_FAILURE";
    +
    34  case PARSER_FAILURE:
    +
    35  return "PARSER_FAILURE";
    +
    36  case ENCRYPTION_FAILURE:
    +
    37  return "ENCRYPTION_FAILURE";
    +
    38  case CHUNKING_ERROR:
    +
    39  return "CHUNKING_ERROR";
    +
    40  case MUXER_FAILURE:
    +
    41  return "MUXER_FAILURE";
    +
    42  case FRAGMENT_FINALIZED:
    +
    43  return "FRAGMENT_FINALIZED";
    +
    44  case SERVER_ERROR:
    +
    45  return "SERVER_ERROR";
    +
    46  case INTERNAL_ERROR:
    +
    47  return "INTERNAL_ERROR";
    +
    48  case STOPPED:
    +
    49  return "STOPPED";
    +
    50  case TIME_OUT:
    +
    51  return "TIME_OUT";
    +
    52  case NOT_FOUND:
    +
    53  return "NOT_FOUND";
    +
    54  case ALREADY_EXISTS:
    +
    55  return "ALREADY_EXISTS";
    +
    56  case TRICK_PLAY_ERROR:
    +
    57  return "TRICK_PLAY_ERROR";
    +
    58  }
    +
    59 
    +
    60  NOTIMPLEMENTED() << "Unknown Status Code: " << error_code;
    +
    61  return "UNKNOWN_STATUS";
    +
    62 }
    +
    63 } // namespace
    +
    64 } // namespace error
    +
    65 
    +
    66 const Status Status::OK = Status(error::OK, "");
    +
    67 const Status Status::UNKNOWN = Status(error::UNKNOWN, "");
    +
    68 
    +
    69 Status::Status(error::Code error_code, const std::string& error_message)
    +
    70  : error_code_(error_code) {
    +
    71  if (!ok()) {
    +
    72  error_message_ = error_message;
    +
    73  if (!error_message.empty())
    +
    74  VLOG(1) << ToString();
    +
    75  }
    +
    76 }
    +
    77 
    +
    78 void Status::Update(Status new_status) {
    +
    79  if (ok())
    +
    80  *this = std::move(new_status);
    +
    81 }
    +
    82 
    +
    83 std::string Status::ToString() const {
    +
    84  if (error_code_ == error::OK)
    +
    85  return "OK";
    +
    86 
    +
    87  return base::StringPrintf("%d (%s): %s", error_code_,
    +
    88  error::ErrorCodeToString(error_code_),
    +
    89  error_message_.c_str());
    +
    90 }
    +
    91 
    +
    92 std::ostream& operator<<(std::ostream& os, const Status& x) {
    +
    93  os << x.ToString();
    +
    94  return os;
    +
    95 }
    +
    96 
    +
    97 } // namespace shaka
    + +
    Status()
    Creates a "successful" status.
    Definition: status.h:113
    +
    std::string ToString() const
    Definition: status.cc:83
    +
    void Update(Status new_status)
    Definition: status.cc:78
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/dc4/structshaka_1_1media_1_1mp4_1_1TrackHeader.html b/docs/da/dc4/structshaka_1_1media_1_1mp4_1_1TrackHeader.html index 9261cb914d..de19b860cb 100644 --- a/docs/da/dc4/structshaka_1_1media_1_1mp4_1_1TrackHeader.html +++ b/docs/da/dc4/structshaka_1_1media_1_1mp4_1_1TrackHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TrackHeader Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + -

    Public Types

    enum  TrackHeaderFlags { kTrackEnabled = 0x000001, -kTrackInMovie = 0x000002, -kTrackInPreview = 0x000004 +
    enum  TrackHeaderFlags { kTrackEnabled = 0x000001 +, kTrackInMovie = 0x000002 +, kTrackInPreview = 0x000004 }
     
    @@ -154,7 +157,7 @@ Additional Inherited Members

    Detailed Description

    -

    Definition at line 186 of file box_definitions.h.

    +

    Definition at line 187 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -182,7 +185,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 569 of file box_definitions.cc.

    +

    Definition at line 581 of file box_definitions.cc.

    @@ -193,9 +196,7 @@ Additional Inherited Members diff --git a/docs/da/dca/classshaka_1_1media_1_1OriginHandler-members.html b/docs/da/dca/classshaka_1_1media_1_1OriginHandler-members.html index b0047a6d5b..d58a9bb32a 100644 --- a/docs/da/dca/classshaka_1_1media_1_1OriginHandler-members.html +++ b/docs/da/dca/classshaka_1_1media_1_1OriginHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline Cancel()=0 (defined in shaka::media::OriginHandler)shaka::media::OriginHandlerpure virtual - Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic + Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected @@ -98,9 +101,7 @@ $(function() {
    diff --git a/docs/da/dcb/es__descriptor_8h_source.html b/docs/da/dcb/es__descriptor_8h_source.html index 3be176ffe4..69210fb0c2 100644 --- a/docs/da/dcb/es__descriptor_8h_source.html +++ b/docs/da/dcb/es__descriptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/es_descriptor.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    es_descriptor.h
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_CODECS_ES_DESCRIPTOR_H_
    6 #define PACKAGER_MEDIA_CODECS_ES_DESCRIPTOR_H_
    7 
    8 #include <stddef.h>
    9 #include <stdint.h>
    10 
    11 #include <vector>
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 class BitReader;
    17 class BufferWriter;
    18 
    19 // The following values are extracted from ISO 14496 Part 1 Table 5 -
    20 // objectTypeIndication Values. Only values currently in use are included.
    21 enum class ObjectType : uint8_t {
    22  kForbidden = 0,
    23  kISO_14496_3 = 0x40, // MPEG4 AAC
    24  kISO_13818_7_AAC_LC = 0x67, // MPEG2 AAC-LC
    25  kDTSC = 0xA9, // DTS Coherent Acoustics audio
    26  kDTSE = 0xAC, // DTS Express low bit rate audio
    27  kDTSH = 0xAA, // DTS-HD High Resolution Audio
    28  kDTSL = 0xAB, // DTS-HD Master Audio
    29 };
    30 
    31 enum class DescriptorTag {
    32  kForbidden = 0,
    33  kES = 0x03,
    34  kDecoderConfig = 0x04,
    35  kDecoderSpecificInfo = 0x05,
    36  kSLConfig = 0x06,
    37 };
    38 
    42  public:
    43  explicit BaseDescriptor(DescriptorTag tag) : tag_(tag) {}
    44 
    47  bool Parse(const std::vector<uint8_t>& data);
    48 
    51  bool Read(BitReader* reader);
    52 
    57  void Write(BufferWriter* writer);
    58 
    61  size_t ComputeSize();
    62 
    63  protected:
    65  void WriteHeader(BufferWriter* writer);
    66 
    68  size_t data_size() const { return data_size_; }
    69 
    70  private:
    71  // Read the descriptor data (header is already read).
    72  virtual bool ReadData(BitReader* reader) = 0;
    73  // Write the descriptor. The descriptor data size should already be updated.
    74  virtual void WriteInternal(BufferWriter* writer) = 0;
    75  // Compute the data size, with child descriptors included.
    76  virtual size_t ComputeDataSize() = 0;
    77 
    78  DescriptorTag tag_ = DescriptorTag::kForbidden;
    79  size_t data_size_ = 0;
    80 };
    81 
    85  public:
    87  : BaseDescriptor(DescriptorTag::kDecoderSpecificInfo) {}
    88 
    89  const std::vector<uint8_t>& data() const { return data_; }
    90 
    91  void set_data(const std::vector<uint8_t>& data) { data_ = data; }
    92 
    93  private:
    94  bool ReadData(BitReader* reader) override;
    95  void WriteInternal(BufferWriter* writer) override;
    96  size_t ComputeDataSize() override;
    97 
    98  std::vector<uint8_t> data_;
    99 };
    100 
    104  public:
    105  DecoderConfigDescriptor() : BaseDescriptor(DescriptorTag::kDecoderConfig) {}
    106 
    107  uint32_t buffer_size_db() const { return buffer_size_db_; }
    108  void set_buffer_size_db(uint32_t buffer_size_db) {
    109  buffer_size_db_ = buffer_size_db;
    110  }
    111 
    112  uint32_t max_bitrate() const { return max_bitrate_; }
    113  void set_max_bitrate(uint32_t max_bitrate) { max_bitrate_ = max_bitrate; }
    114 
    115  uint32_t avg_bitrate() const { return avg_bitrate_; }
    116  void set_avg_bitrate(uint32_t avg_bitrate) { avg_bitrate_ = avg_bitrate; }
    117 
    118  ObjectType object_type() const { return object_type_; }
    119  void set_object_type(ObjectType object_type) { object_type_ = object_type; }
    120 
    122  bool IsAAC() const {
    123  return object_type_ == ObjectType::kISO_14496_3 ||
    124  object_type_ == ObjectType::kISO_13818_7_AAC_LC;
    125  }
    126 
    128  bool IsDTS() const {
    129  return object_type_ == ObjectType::kDTSC ||
    130  object_type_ == ObjectType::kDTSE ||
    131  object_type_ == ObjectType::kDTSH ||
    132  object_type_ == ObjectType::kDTSL;
    133  }
    134 
    135  const DecoderSpecificInfoDescriptor& decoder_specific_info_descriptor()
    136  const {
    137  return decoder_specific_info_descriptor_;
    138  }
    139 
    140  DecoderSpecificInfoDescriptor* mutable_decoder_specific_info_descriptor() {
    141  return &decoder_specific_info_descriptor_;
    142  }
    143 
    144  private:
    145  bool ReadData(BitReader* reader) override;
    146  void WriteInternal(BufferWriter* writer) override;
    147  size_t ComputeDataSize() override;
    148 
    149  ObjectType object_type_ = ObjectType::kForbidden;
    150  uint32_t buffer_size_db_ = 0;
    151  uint32_t max_bitrate_ = 0;
    152  uint32_t avg_bitrate_ = 0;
    153  DecoderSpecificInfoDescriptor decoder_specific_info_descriptor_;
    154 };
    155 
    159  public:
    160  SLConfigDescriptor() : BaseDescriptor(DescriptorTag::kSLConfig) {}
    161 
    162  private:
    163  bool ReadData(BitReader* reader) override;
    164  void WriteInternal(BufferWriter* writer) override;
    165  size_t ComputeDataSize() override;
    166 };
    167 
    171 class ESDescriptor : public BaseDescriptor {
    172  public:
    173  ESDescriptor() : BaseDescriptor(DescriptorTag::kES) {}
    174 
    175  uint16_t esid() const { return esid_; }
    176  void set_esid(uint16_t esid) { esid_ = esid; }
    177 
    178  const DecoderConfigDescriptor& decoder_config_descriptor() const {
    179  return decoder_config_descriptor_;
    180  }
    181 
    182  DecoderConfigDescriptor* mutable_decoder_config_descriptor() {
    183  return &decoder_config_descriptor_;
    184  }
    185 
    186  private:
    187  bool ReadData(BitReader* reader) override;
    188  void WriteInternal(BufferWriter* writer) override;
    189  size_t ComputeDataSize() override;
    190 
    191  uint16_t esid_ = 0; // Elementary Stream ID.
    192 
    193  DecoderConfigDescriptor decoder_config_descriptor_;
    194  SLConfigDescriptor sl_config_descriptor_;
    195 };
    196 
    197 } // namespace media
    198 } // namespace shaka
    199 
    200 #endif // PACKAGER_MEDIA_CODECS_ES_DESCRIPTOR_H_
    -
    A class to read bit streams.
    Definition: bit_reader.h:17
    - -
    All the methods that are virtual are virtual for mocking.
    - - - - - - - +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_CODECS_ES_DESCRIPTOR_H_
    +
    6 #define PACKAGER_MEDIA_CODECS_ES_DESCRIPTOR_H_
    +
    7 
    +
    8 #include <stddef.h>
    +
    9 #include <stdint.h>
    +
    10 
    +
    11 #include <vector>
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 class BitReader;
    +
    17 class BufferWriter;
    +
    18 
    +
    19 // The following values are extracted from ISO 14496 Part 1 Table 5 -
    +
    20 // objectTypeIndication Values. Only values currently in use are included.
    +
    21 enum class ObjectType : uint8_t {
    +
    22  kForbidden = 0,
    +
    23  kISO_14496_3 = 0x40, // MPEG4 AAC
    +
    24  kISO_13818_7_AAC_LC = 0x67, // MPEG2 AAC-LC
    +
    25  kISO_13818_3_MPEG1 = 0x69, // MPEG1 ISO/IEC 13818-3, 16,22.05,24kHz
    +
    26  kISO_11172_3_MPEG1 = 0x6B, // MPEG1 ISO/IEC 11172-3, 32,44.1,48kHz
    +
    27  kDTSC = 0xA9, // DTS Coherent Acoustics audio
    +
    28  kDTSE = 0xAC, // DTS Express low bit rate audio
    +
    29  kDTSH = 0xAA, // DTS-HD High Resolution Audio
    +
    30  kDTSL = 0xAB, // DTS-HD Master Audio
    +
    31 };
    +
    32 
    +
    33 enum class DescriptorTag {
    +
    34  kForbidden = 0,
    +
    35  kES = 0x03,
    +
    36  kDecoderConfig = 0x04,
    +
    37  kDecoderSpecificInfo = 0x05,
    +
    38  kSLConfig = 0x06,
    +
    39 };
    +
    40 
    + +
    44  public:
    +
    45  explicit BaseDescriptor(DescriptorTag tag) : tag_(tag) {}
    +
    46 
    +
    49  bool Parse(const std::vector<uint8_t>& data);
    +
    50 
    +
    53  bool Read(BitReader* reader);
    +
    54 
    +
    59  void Write(BufferWriter* writer);
    +
    60 
    +
    63  size_t ComputeSize();
    +
    64 
    +
    65  protected:
    +
    67  void WriteHeader(BufferWriter* writer);
    +
    68 
    +
    70  size_t data_size() const { return data_size_; }
    +
    71 
    +
    72  private:
    +
    73  // Read the descriptor data (header is already read).
    +
    74  virtual bool ReadData(BitReader* reader) = 0;
    +
    75  // Write the descriptor. The descriptor data size should already be updated.
    +
    76  virtual void WriteInternal(BufferWriter* writer) = 0;
    +
    77  // Compute the data size, with child descriptors included.
    +
    78  virtual size_t ComputeDataSize() = 0;
    +
    79 
    +
    80  DescriptorTag tag_ = DescriptorTag::kForbidden;
    +
    81  size_t data_size_ = 0;
    +
    82 };
    +
    83 
    + +
    87  public:
    + +
    89  : BaseDescriptor(DescriptorTag::kDecoderSpecificInfo) {}
    +
    90 
    +
    91  const std::vector<uint8_t>& data() const { return data_; }
    +
    92 
    +
    93  void set_data(const std::vector<uint8_t>& data) { data_ = data; }
    +
    94 
    +
    95  private:
    +
    96  bool ReadData(BitReader* reader) override;
    +
    97  void WriteInternal(BufferWriter* writer) override;
    +
    98  size_t ComputeDataSize() override;
    +
    99 
    +
    100  std::vector<uint8_t> data_;
    +
    101 };
    +
    102 
    + +
    106  public:
    +
    107  DecoderConfigDescriptor() : BaseDescriptor(DescriptorTag::kDecoderConfig) {}
    +
    108 
    +
    109  uint32_t buffer_size_db() const { return buffer_size_db_; }
    +
    110  void set_buffer_size_db(uint32_t buffer_size_db) {
    +
    111  buffer_size_db_ = buffer_size_db;
    +
    112  }
    +
    113 
    +
    114  uint32_t max_bitrate() const { return max_bitrate_; }
    +
    115  void set_max_bitrate(uint32_t max_bitrate) { max_bitrate_ = max_bitrate; }
    +
    116 
    +
    117  uint32_t avg_bitrate() const { return avg_bitrate_; }
    +
    118  void set_avg_bitrate(uint32_t avg_bitrate) { avg_bitrate_ = avg_bitrate; }
    +
    119 
    +
    120  ObjectType object_type() const { return object_type_; }
    +
    121  void set_object_type(ObjectType object_type) { object_type_ = object_type; }
    +
    122 
    +
    124  bool IsAAC() const {
    +
    125  return object_type_ == ObjectType::kISO_14496_3 ||
    +
    126  object_type_ == ObjectType::kISO_13818_7_AAC_LC;
    +
    127  }
    +
    128 
    +
    130  bool IsDTS() const {
    +
    131  return object_type_ == ObjectType::kDTSC ||
    +
    132  object_type_ == ObjectType::kDTSE ||
    +
    133  object_type_ == ObjectType::kDTSH ||
    +
    134  object_type_ == ObjectType::kDTSL;
    +
    135  }
    +
    136 
    +
    137  const DecoderSpecificInfoDescriptor& decoder_specific_info_descriptor()
    +
    138  const {
    +
    139  return decoder_specific_info_descriptor_;
    +
    140  }
    +
    141 
    +
    142  DecoderSpecificInfoDescriptor* mutable_decoder_specific_info_descriptor() {
    +
    143  return &decoder_specific_info_descriptor_;
    +
    144  }
    +
    145 
    +
    146  private:
    +
    147  bool ReadData(BitReader* reader) override;
    +
    148  void WriteInternal(BufferWriter* writer) override;
    +
    149  size_t ComputeDataSize() override;
    +
    150 
    +
    151  ObjectType object_type_ = ObjectType::kForbidden;
    +
    152  uint32_t buffer_size_db_ = 0;
    +
    153  uint32_t max_bitrate_ = 0;
    +
    154  uint32_t avg_bitrate_ = 0;
    +
    155  DecoderSpecificInfoDescriptor decoder_specific_info_descriptor_;
    +
    156 };
    +
    157 
    + +
    161  public:
    +
    162  SLConfigDescriptor() : BaseDescriptor(DescriptorTag::kSLConfig) {}
    +
    163 
    +
    164  private:
    +
    165  bool ReadData(BitReader* reader) override;
    +
    166  void WriteInternal(BufferWriter* writer) override;
    +
    167  size_t ComputeDataSize() override;
    +
    168 };
    +
    169 
    +
    173 class ESDescriptor : public BaseDescriptor {
    +
    174  public:
    +
    175  ESDescriptor() : BaseDescriptor(DescriptorTag::kES) {}
    +
    176 
    +
    177  uint16_t esid() const { return esid_; }
    +
    178 
    +
    179  const DecoderConfigDescriptor& decoder_config_descriptor() const {
    +
    180  return decoder_config_descriptor_;
    +
    181  }
    +
    182 
    +
    183  DecoderConfigDescriptor* mutable_decoder_config_descriptor() {
    +
    184  return &decoder_config_descriptor_;
    +
    185  }
    +
    186 
    +
    187  private:
    +
    188  bool ReadData(BitReader* reader) override;
    +
    189  void WriteInternal(BufferWriter* writer) override;
    +
    190  size_t ComputeDataSize() override;
    +
    191 
    +
    192  uint16_t esid_ = 0; // Elementary Stream ID.
    +
    193 
    +
    194  DecoderConfigDescriptor decoder_config_descriptor_;
    +
    195  SLConfigDescriptor sl_config_descriptor_;
    +
    196 };
    +
    197 
    +
    198 } // namespace media
    +
    199 } // namespace shaka
    +
    200 
    +
    201 #endif // PACKAGER_MEDIA_CODECS_ES_DESCRIPTOR_H_
    + + +
    bool Parse(const std::vector< uint8_t > &data)
    +
    void WriteHeader(BufferWriter *writer)
    Write descriptor header.
    +
    bool Read(BitReader *reader)
    +
    void Write(BufferWriter *writer)
    + +
    A class to read bit streams.
    Definition: bit_reader.h:17
    + + + + + + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/dd0/playready__key__source_8cc_source.html b/docs/da/dd0/playready__key__source_8cc_source.html index 6d5a991c41..7c07d21ee4 100644 --- a/docs/da/dd0/playready__key__source_8cc_source.html +++ b/docs/da/dd0/playready__key__source_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/playready_key_source.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    playready_key_source.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/playready_key_source.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/base/base64.h"
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/base/strings/string_util.h"
    15 #include "packager/media/base/buffer_writer.h"
    16 #include "packager/media/base/http_key_fetcher.h"
    17 #include "packager/media/base/key_source.h"
    18 #include "packager/media/base/protection_system_ids.h"
    19 #include "packager/status_macros.h"
    20 
    21 namespace shaka {
    22 namespace media {
    23 
    24 namespace {
    25 
    26 const uint32_t kHttpFetchTimeout = 60; // In seconds
    27 const std::string kAcquireLicenseRequest =
    28  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    29  "<soap:Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" "
    30  "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
    31  "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
    32  "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
    33  "<soap:Body>"
    34  "<AcquirePackagingData "
    35  "xmlns=\"http://schemas.microsoft.com/DRM/2007/03/protocols\">"
    36  "<challenge "
    37  "xmlns=\"http://schemas.microsoft.com/DRM"
    38  "/2007/03/protocols/AcquirePackagingData/v1.0\">"
    39  "<ProtectionSystems>"
    40  "<ProtectionSystemId>9A04F079-9840-4286-AB92-E65BE0885F95"
    41  "</ProtectionSystemId>"
    42  "</ProtectionSystems>"
    43  "<StreamProtectionRequests>"
    44  "<StreamInformation>"
    45  "<ProgramIdentifier>$0</ProgramIdentifier>"
    46  "<OffsetFromProgramStart>P0S</OffsetFromProgramStart>"
    47  "</StreamInformation>"
    48  "</StreamProtectionRequests>"
    49  "</challenge>"
    50  "</AcquirePackagingData>"
    51  "</soap:Body>"
    52  "</soap:Envelope>";
    53 
    54 bool Base64StringToBytes(const std::string& base64_string,
    55  std::vector<uint8_t>* bytes) {
    56  DCHECK(bytes);
    57  std::string str;
    58  if (!base::Base64Decode(base64_string, &str))
    59  return false;
    60  bytes->assign(str.begin(), str.end());
    61  return true;
    62 }
    63 }
    64 
    65 PlayReadyKeySource::PlayReadyKeySource(const std::string& server_url,
    66  int protection_system_flags,
    67  FourCC protection_scheme)
    68  // PlayReady PSSH is retrived from PlayReady server response.
    69  : KeySource(protection_system_flags & ~PLAYREADY_PROTECTION_SYSTEM_FLAG,
    70  protection_scheme),
    71  generate_playready_protection_system_(
    72  // Generate PlayReady protection system if there are no other
    73  // protection system specified.
    74  protection_system_flags == NO_PROTECTION_SYSTEM_FLAG ||
    75  protection_system_flags & PLAYREADY_PROTECTION_SYSTEM_FLAG),
    76  encryption_key_(new EncryptionKey),
    77  server_url_(server_url) {}
    78 
    80  const std::string& server_url,
    81  const std::string& client_cert_file,
    82  const std::string& client_cert_private_key_file,
    83  const std::string& client_cert_private_key_password,
    84  int protection_system_flags,
    85  FourCC protection_scheme)
    86  // PlayReady PSSH is retrived from PlayReady server response.
    87  : KeySource(protection_system_flags & ~PLAYREADY_PROTECTION_SYSTEM_FLAG,
    88  protection_scheme),
    89  encryption_key_(new EncryptionKey),
    90  server_url_(server_url),
    91  client_cert_file_(client_cert_file),
    92  client_cert_private_key_file_(client_cert_private_key_file),
    93  client_cert_private_key_password_(client_cert_private_key_password) {}
    94 
    95 PlayReadyKeySource::~PlayReadyKeySource() = default;
    96 
    97 Status RetrieveTextInXMLElement(const std::string& element,
    98  const std::string& xml,
    99  std::string* value) {
    100  std::string start_tag = "<" + element + ">";
    101  std::string end_tag = "</" + element + ">";
    102  std::size_t start_pos = xml.find(start_tag);
    103  if (start_pos == std::string::npos) {
    104  return Status(error::SERVER_ERROR,
    105  "Unable to find tag: " + start_tag);
    106  }
    107  start_pos += start_tag.size();
    108  std::size_t end_pos = xml.find(end_tag);
    109  if (end_pos == std::string::npos) {
    110  return Status(error::SERVER_ERROR,
    111  "Unable to find tag: " + end_tag);
    112  }
    113  if (start_pos > end_pos) {
    114  return Status(error::SERVER_ERROR, "Invalid positions");
    115  }
    116  std::size_t segment_len = end_pos - start_pos;
    117  *value = xml.substr(start_pos, segment_len);
    118  return Status::OK;
    119 }
    120 
    121 Status SetKeyInformationFromServerResponse(
    122  const std::string& response,
    123  bool generate_playready_protection_system,
    124  EncryptionKey* encryption_key) {
    125  // TODO(robinconnell): Currently all tracks are encrypted using the same
    126  // key_id and key. Add the ability to retrieve multiple key_id/keys from
    127  // the packager response and encrypt multiple tracks using differnt
    128  // key_id/keys.
    129  std::string key_id_hex;
    130  RETURN_IF_ERROR(RetrieveTextInXMLElement("KeyId", response, &key_id_hex));
    131  key_id_hex.erase(
    132  std::remove(key_id_hex.begin(), key_id_hex.end(), '-'), key_id_hex.end());
    133  if (!base::HexStringToBytes(key_id_hex, &encryption_key->key_id)) {
    134  LOG(ERROR) << "Cannot parse key_id_hex, " << key_id_hex;
    135  return Status(error::SERVER_ERROR, "Cannot parse key_id_hex.");
    136  }
    137 
    138  std::string key_data_b64;
    139  RETURN_IF_ERROR(RetrieveTextInXMLElement("KeyData", response, &key_data_b64));
    140  if (!Base64StringToBytes(key_data_b64, &encryption_key->key)) {
    141  LOG(ERROR) << "Cannot parse key, " << key_data_b64;
    142  return Status(error::SERVER_ERROR, "Cannot parse key.");
    143  }
    144 
    145  if (generate_playready_protection_system) {
    146  std::string pssh_data_b64;
    147  RETURN_IF_ERROR(RetrieveTextInXMLElement("Data", response, &pssh_data_b64));
    148  std::vector<uint8_t> pssh_data;
    149  if (!Base64StringToBytes(pssh_data_b64, &pssh_data)) {
    150  LOG(ERROR) << "Cannot parse pssh data, " << pssh_data_b64;
    151  return Status(error::SERVER_ERROR, "Cannot parse pssh.");
    152  }
    153 
    154  PsshBoxBuilder pssh_builder;
    155  pssh_builder.add_key_id(encryption_key->key_id);
    156  pssh_builder.set_system_id(kPlayReadySystemId,
    157  arraysize(kPlayReadySystemId));
    158  pssh_builder.set_pssh_data(pssh_data);
    159  encryption_key->key_system_info.push_back(
    160  {pssh_builder.system_id(), pssh_builder.CreateBox()});
    161  }
    162  return Status::OK;
    163 }
    164 
    165 Status PlayReadyKeySource::FetchKeysWithProgramIdentifier(
    166  const std::string& program_identifier) {
    167  std::unique_ptr<EncryptionKey> encryption_key(new EncryptionKey);
    168  HttpKeyFetcher key_fetcher(kHttpFetchTimeout);
    169  if (!client_cert_file_.empty() && !client_cert_private_key_file_.empty()) {
    170  key_fetcher.SetClientCertInfo(client_cert_file_,
    171  client_cert_private_key_file_,
    172  client_cert_private_key_password_);
    173  }
    174  if (!ca_file_.empty()) {
    175  key_fetcher.SetCaFile(ca_file_);
    176  }
    177 
    178  std::string acquire_license_request = kAcquireLicenseRequest;
    179  base::ReplaceFirstSubstringAfterOffset(
    180  &acquire_license_request, 0, "$0", program_identifier);
    181  std::string acquire_license_response;
    182  Status status = key_fetcher.FetchKeys(server_url_, acquire_license_request,
    183  &acquire_license_response);
    184  VLOG(1) << "Server response: " << acquire_license_response;
    185  RETURN_IF_ERROR(status);
    186 
    187  RETURN_IF_ERROR(SetKeyInformationFromServerResponse(
    188  acquire_license_response, generate_playready_protection_system_,
    189  encryption_key.get()));
    190 
    191  // PlayReady does not specify different streams.
    192  const char kEmptyDrmLabel[] = "";
    193  EncryptionKeyMap encryption_key_map;
    194  encryption_key_map[kEmptyDrmLabel] = std::move(encryption_key);
    195  RETURN_IF_ERROR(UpdateProtectionSystemInfo(&encryption_key_map));
    196  encryption_key_ = std::move(encryption_key_map[kEmptyDrmLabel]);
    197  return Status::OK;
    198 }
    199 
    200 Status PlayReadyKeySource::FetchKeys(EmeInitDataType init_data_type,
    201  const std::vector<uint8_t>& init_data) {
    202  // Do nothing for PlayReady encryption/decryption.
    203  return Status::OK;
    204 }
    205 
    206 Status PlayReadyKeySource::GetKey(const std::string& stream_label,
    207  EncryptionKey* key) {
    208  // TODO(robinconnell): Currently all tracks are encrypted using the same
    209  // key_id and key. Add the ability to encrypt each stream_label using a
    210  // different key_id and key.
    211  DCHECK(key);
    212  DCHECK(encryption_key_);
    213  *key = *encryption_key_;
    214  return Status::OK;
    215 }
    216 
    217 Status PlayReadyKeySource::GetKey(const std::vector<uint8_t>& key_id,
    218  EncryptionKey* key) {
    219  // TODO(robinconnell): Currently all tracks are encrypted using the same
    220  // key_id and key. Add the ability to encrypt using multiple key_id/keys.
    221  DCHECK(key);
    222  DCHECK(encryption_key_);
    223  *key = *encryption_key_;
    224  return Status::OK;
    225 }
    226 
    227 Status PlayReadyKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
    228  uint32_t crypto_period_duration_in_seconds,
    229  const std::string& stream_label,
    230  EncryptionKey* key) {
    231  // TODO(robinconnell): Implement key rotation.
    232  *key = *encryption_key_;
    233  return Status::OK;
    234 }
    235 
    236 } // namespace media
    237 } // namespace shaka
    -
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    -
    void SetCaFile(const std::string &ca_file)
    -
    std::vector< uint8_t > CreateBox() const
    Creates a PSSH box for the current data.
    -
    All the methods that are virtual are virtual for mocking.
    -
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    - -
    Status UpdateProtectionSystemInfo(EncryptionKeyMap *encryption_key_map)
    Definition: key_source.cc:48
    - -
    void SetClientCertInfo(const std::string &cert_file, const std::string &private_key_file, const std::string &private_key_password)
    -
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    - -
    Status FetchKeys(const std::string &url, const std::string &request, std::string *response) override
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    PlayReadyKeySource(const std::string &server_url, int protection_systems_flags, FourCC protection_scheme)
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/playready_key_source.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/base64.h"
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/base/strings/string_number_conversions.h"
    +
    14 #include "packager/base/strings/string_util.h"
    +
    15 #include "packager/media/base/buffer_writer.h"
    +
    16 #include "packager/media/base/http_key_fetcher.h"
    +
    17 #include "packager/media/base/key_source.h"
    +
    18 #include "packager/media/base/protection_system_ids.h"
    +
    19 #include "packager/status_macros.h"
    +
    20 
    +
    21 namespace shaka {
    +
    22 namespace media {
    +
    23 
    +
    24 namespace {
    +
    25 
    +
    26 const uint32_t kHttpFetchTimeout = 60; // In seconds
    +
    27 const std::string kAcquireLicenseRequest =
    +
    28  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    +
    29  "<soap:Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" "
    +
    30  "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
    +
    31  "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
    +
    32  "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
    +
    33  "<soap:Body>"
    +
    34  "<AcquirePackagingData "
    +
    35  "xmlns=\"http://schemas.microsoft.com/DRM/2007/03/protocols\">"
    +
    36  "<challenge "
    +
    37  "xmlns=\"http://schemas.microsoft.com/DRM"
    +
    38  "/2007/03/protocols/AcquirePackagingData/v1.0\">"
    +
    39  "<ProtectionSystems>"
    +
    40  "<ProtectionSystemId>9A04F079-9840-4286-AB92-E65BE0885F95"
    +
    41  "</ProtectionSystemId>"
    +
    42  "</ProtectionSystems>"
    +
    43  "<StreamProtectionRequests>"
    +
    44  "<StreamInformation>"
    +
    45  "<ProgramIdentifier>$0</ProgramIdentifier>"
    +
    46  "<OffsetFromProgramStart>P0S</OffsetFromProgramStart>"
    +
    47  "</StreamInformation>"
    +
    48  "</StreamProtectionRequests>"
    +
    49  "</challenge>"
    +
    50  "</AcquirePackagingData>"
    +
    51  "</soap:Body>"
    +
    52  "</soap:Envelope>";
    +
    53 
    +
    54 bool Base64StringToBytes(const std::string& base64_string,
    +
    55  std::vector<uint8_t>* bytes) {
    +
    56  DCHECK(bytes);
    +
    57  std::string str;
    +
    58  if (!base::Base64Decode(base64_string, &str))
    +
    59  return false;
    +
    60  bytes->assign(str.begin(), str.end());
    +
    61  return true;
    +
    62 }
    +
    63 }
    +
    64 
    +
    65 PlayReadyKeySource::PlayReadyKeySource(const std::string& server_url,
    +
    66  ProtectionSystem protection_systems)
    +
    67  // PlayReady PSSH is retrived from PlayReady server response.
    +
    68  : generate_playready_protection_system_(
    +
    69  // Generate PlayReady protection system if there are no other
    +
    70  // protection system specified.
    +
    71  protection_systems == ProtectionSystem::kNone ||
    +
    72  has_flag(protection_systems, ProtectionSystem::kPlayReady)),
    +
    73  encryption_key_(new EncryptionKey),
    +
    74  server_url_(server_url) {}
    +
    75 
    +
    76 PlayReadyKeySource::~PlayReadyKeySource() = default;
    +
    77 
    +
    78 Status RetrieveTextInXMLElement(const std::string& element,
    +
    79  const std::string& xml,
    +
    80  std::string* value) {
    +
    81  std::string start_tag = "<" + element + ">";
    +
    82  std::string end_tag = "</" + element + ">";
    +
    83  std::size_t start_pos = xml.find(start_tag);
    +
    84  if (start_pos == std::string::npos) {
    +
    85  return Status(error::SERVER_ERROR,
    +
    86  "Unable to find tag: " + start_tag);
    +
    87  }
    +
    88  start_pos += start_tag.size();
    +
    89  std::size_t end_pos = xml.find(end_tag);
    +
    90  if (end_pos == std::string::npos) {
    +
    91  return Status(error::SERVER_ERROR,
    +
    92  "Unable to find tag: " + end_tag);
    +
    93  }
    +
    94  if (start_pos > end_pos) {
    +
    95  return Status(error::SERVER_ERROR, "Invalid positions");
    +
    96  }
    +
    97  std::size_t segment_len = end_pos - start_pos;
    +
    98  *value = xml.substr(start_pos, segment_len);
    +
    99  return Status::OK;
    +
    100 }
    +
    101 
    +
    102 Status SetKeyInformationFromServerResponse(
    +
    103  const std::string& response,
    +
    104  bool generate_playready_protection_system,
    +
    105  EncryptionKey* encryption_key) {
    +
    106  // TODO(robinconnell): Currently all tracks are encrypted using the same
    +
    107  // key_id and key. Add the ability to retrieve multiple key_id/keys from
    +
    108  // the packager response and encrypt multiple tracks using differnt
    +
    109  // key_id/keys.
    +
    110  std::string key_id_hex;
    +
    111  RETURN_IF_ERROR(RetrieveTextInXMLElement("KeyId", response, &key_id_hex));
    +
    112  key_id_hex.erase(
    +
    113  std::remove(key_id_hex.begin(), key_id_hex.end(), '-'), key_id_hex.end());
    +
    114  if (!base::HexStringToBytes(key_id_hex, &encryption_key->key_id)) {
    +
    115  LOG(ERROR) << "Cannot parse key_id_hex, " << key_id_hex;
    +
    116  return Status(error::SERVER_ERROR, "Cannot parse key_id_hex.");
    +
    117  }
    +
    118 
    +
    119  std::string key_data_b64;
    +
    120  RETURN_IF_ERROR(RetrieveTextInXMLElement("KeyData", response, &key_data_b64));
    +
    121  if (!Base64StringToBytes(key_data_b64, &encryption_key->key)) {
    +
    122  LOG(ERROR) << "Cannot parse key, " << key_data_b64;
    +
    123  return Status(error::SERVER_ERROR, "Cannot parse key.");
    +
    124  }
    +
    125  encryption_key->key_ids.emplace_back(encryption_key->key_id);
    +
    126 
    +
    127  if (generate_playready_protection_system) {
    +
    128  std::string pssh_data_b64;
    +
    129  RETURN_IF_ERROR(RetrieveTextInXMLElement("Data", response, &pssh_data_b64));
    +
    130  std::vector<uint8_t> pssh_data;
    +
    131  if (!Base64StringToBytes(pssh_data_b64, &pssh_data)) {
    +
    132  LOG(ERROR) << "Cannot parse pssh data, " << pssh_data_b64;
    +
    133  return Status(error::SERVER_ERROR, "Cannot parse pssh.");
    +
    134  }
    +
    135 
    +
    136  PsshBoxBuilder pssh_builder;
    +
    137  pssh_builder.add_key_id(encryption_key->key_id);
    +
    138  pssh_builder.set_system_id(kPlayReadySystemId,
    +
    139  arraysize(kPlayReadySystemId));
    +
    140  pssh_builder.set_pssh_data(pssh_data);
    +
    141  encryption_key->key_system_info.push_back(
    +
    142  {pssh_builder.system_id(), pssh_builder.CreateBox()});
    +
    143  }
    +
    144  return Status::OK;
    +
    145 }
    +
    146 
    +
    147 Status PlayReadyKeySource::FetchKeysWithProgramIdentifier(
    +
    148  const std::string& program_identifier) {
    +
    149  std::unique_ptr<EncryptionKey> encryption_key(new EncryptionKey);
    +
    150  HttpKeyFetcher key_fetcher(kHttpFetchTimeout);
    +
    151 
    +
    152  std::string acquire_license_request = kAcquireLicenseRequest;
    +
    153  base::ReplaceFirstSubstringAfterOffset(
    +
    154  &acquire_license_request, 0, "$0", program_identifier);
    +
    155  std::string acquire_license_response;
    +
    156  Status status = key_fetcher.FetchKeys(server_url_, acquire_license_request,
    +
    157  &acquire_license_response);
    +
    158  VLOG(1) << "Server response: " << acquire_license_response;
    +
    159  RETURN_IF_ERROR(status);
    +
    160 
    +
    161  RETURN_IF_ERROR(SetKeyInformationFromServerResponse(
    +
    162  acquire_license_response, generate_playready_protection_system_,
    +
    163  encryption_key.get()));
    +
    164 
    +
    165  // PlayReady does not specify different streams.
    +
    166  encryption_key_ = std::move(encryption_key);
    +
    167  return Status::OK;
    +
    168 }
    +
    169 
    +
    170 Status PlayReadyKeySource::FetchKeys(EmeInitDataType init_data_type,
    +
    171  const std::vector<uint8_t>& init_data) {
    +
    172  // Do nothing for PlayReady encryption/decryption.
    +
    173  return Status::OK;
    +
    174 }
    +
    175 
    +
    176 Status PlayReadyKeySource::GetKey(const std::string& stream_label,
    +
    177  EncryptionKey* key) {
    +
    178  // TODO(robinconnell): Currently all tracks are encrypted using the same
    +
    179  // key_id and key. Add the ability to encrypt each stream_label using a
    +
    180  // different key_id and key.
    +
    181  DCHECK(key);
    +
    182  DCHECK(encryption_key_);
    +
    183  *key = *encryption_key_;
    +
    184  return Status::OK;
    +
    185 }
    +
    186 
    +
    187 Status PlayReadyKeySource::GetKey(const std::vector<uint8_t>& key_id,
    +
    188  EncryptionKey* key) {
    +
    189  // TODO(robinconnell): Currently all tracks are encrypted using the same
    +
    190  // key_id and key. Add the ability to encrypt using multiple key_id/keys.
    +
    191  DCHECK(key);
    +
    192  DCHECK(encryption_key_);
    +
    193  *key = *encryption_key_;
    +
    194  return Status::OK;
    +
    195 }
    +
    196 
    +
    197 Status PlayReadyKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
    +
    198  uint32_t crypto_period_duration_in_seconds,
    +
    199  const std::string& stream_label,
    +
    200  EncryptionKey* key) {
    +
    201  // TODO(robinconnell): Implement key rotation.
    +
    202  *key = *encryption_key_;
    +
    203  return Status::OK;
    +
    204 }
    +
    205 
    +
    206 } // namespace media
    +
    207 } // namespace shaka
    + +
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    +
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    +
    PlayReadyKeySource(const std::string &server_url, ProtectionSystem protection_systems)
    +
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    +
    All the methods that are virtual are virtual for mocking.
    +
    ProtectionSystem
    Definition: crypto_params.h:31
    +
    diff --git a/docs/da/dd0/structshaka_1_1media_1_1mp4_1_1Edit.html b/docs/da/dd0/structshaka_1_1media_1_1mp4_1_1Edit.html index e1c4d29d3b..0d9bfaac9a 100644 --- a/docs/da/dd0/structshaka_1_1media_1_1mp4_1_1Edit.html +++ b/docs/da/dd0/structshaka_1_1media_1_1mp4_1_1Edit.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Edit Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -112,7 +115,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 221 of file box_definitions.h.

    +

    Definition at line 222 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -140,7 +143,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1246 of file box_definitions.cc.

    +

    Definition at line 1264 of file box_definitions.cc.

    @@ -151,9 +154,7 @@ Additional Inherited Members diff --git a/docs/da/dd0/webm__info__parser_8h_source.html b/docs/da/dd0/webm__info__parser_8h_source.html index 071cb8c32c..9d15020d72 100644 --- a/docs/da/dd0/webm__info__parser_8h_source.html +++ b/docs/da/dd0/webm__info__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_info_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webm_info_parser.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_INFO_PARSER_H_
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_INFO_PARSER_H_
    7 
    8 #include "packager/base/compiler_specific.h"
    9 #include "packager/base/time/time.h"
    10 #include "packager/media/formats/webm/webm_parser.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    17  public:
    19  ~WebMInfoParser() override;
    20 
    25  int Parse(const uint8_t* buf, int size);
    26 
    27  int64_t timecode_scale() const { return timecode_scale_; }
    28  double duration() const { return duration_; }
    29  base::Time date_utc() const { return date_utc_; }
    30 
    31  private:
    32  // WebMParserClient methods
    33  WebMParserClient* OnListStart(int id) override;
    34  bool OnListEnd(int id) override;
    35  bool OnUInt(int id, int64_t val) override;
    36  bool OnFloat(int id, double val) override;
    37  bool OnBinary(int id, const uint8_t* data, int size) override;
    38  bool OnString(int id, const std::string& str) override;
    39 
    40  int64_t timecode_scale_;
    41  double duration_;
    42  base::Time date_utc_;
    43 
    44  DISALLOW_COPY_AND_ASSIGN(WebMInfoParser);
    45 };
    46 
    47 } // namespace media
    48 } // namespace shaka
    49 
    50 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_INFO_PARSER_H_
    All the methods that are virtual are virtual for mocking.
    -
    Parser for WebM Info element.
    - -
    int Parse(const uint8_t *buf, int size)
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_INFO_PARSER_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_INFO_PARSER_H_
    +
    7 
    +
    8 #include "packager/base/compiler_specific.h"
    +
    9 #include "packager/base/time/time.h"
    +
    10 #include "packager/media/formats/webm/webm_parser.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    + +
    17  public:
    + +
    19  ~WebMInfoParser() override;
    +
    20 
    +
    25  int Parse(const uint8_t* buf, int size);
    +
    26 
    +
    27  int64_t timecode_scale() const { return timecode_scale_; }
    +
    28  double duration() const { return duration_; }
    +
    29  base::Time date_utc() const { return date_utc_; }
    +
    30 
    +
    31  private:
    +
    32  // WebMParserClient methods
    +
    33  WebMParserClient* OnListStart(int id) override;
    +
    34  bool OnListEnd(int id) override;
    +
    35  bool OnUInt(int id, int64_t val) override;
    +
    36  bool OnFloat(int id, double val) override;
    +
    37  bool OnBinary(int id, const uint8_t* data, int size) override;
    +
    38  bool OnString(int id, const std::string& str) override;
    +
    39 
    +
    40  int64_t timecode_scale_;
    +
    41  double duration_;
    +
    42  base::Time date_utc_;
    +
    43 
    +
    44  DISALLOW_COPY_AND_ASSIGN(WebMInfoParser);
    +
    45 };
    +
    46 
    +
    47 } // namespace media
    +
    48 } // namespace shaka
    +
    49 
    +
    50 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_INFO_PARSER_H_
    +
    Parser for WebM Info element.
    +
    int Parse(const uint8_t *buf, int size)
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/dd1/fragmenter_8h_source.html b/docs/da/dd1/fragmenter_8h_source.html index b71b88132f..ed2875cd1d 100644 --- a/docs/da/dd1/fragmenter_8h_source.html +++ b/docs/da/dd1/fragmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/fragmenter.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    fragmenter.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_FRAGMENTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_FRAGMENTER_H_
    9 
    10 #include <memory>
    11 #include <vector>
    12 
    13 #include "packager/base/logging.h"
    14 #include "packager/status.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 class BufferWriter;
    20 class MediaSample;
    21 class StreamInfo;
    22 
    23 namespace mp4 {
    24 
    25 struct KeyFrameInfo;
    26 struct SegmentReference;
    27 struct TrackFragment;
    28 
    31 class Fragmenter {
    32  public:
    37  Fragmenter(std::shared_ptr<const StreamInfo> info,
    38  TrackFragment* traf,
    39  int64_t edit_list_offset);
    40 
    41  ~Fragmenter();
    42 
    46  Status AddSample(const MediaSample& sample);
    47 
    52  Status InitializeFragment(int64_t first_sample_dts);
    53 
    56 
    58  void GenerateSegmentReference(SegmentReference* reference) const;
    59 
    60  void ClearFragmentFinalized() { fragment_finalized_ = false; }
    61 
    62  uint64_t fragment_duration() const { return fragment_duration_; }
    63  uint64_t first_sap_time() const { return first_sap_time_; }
    64  uint64_t earliest_presentation_time() const {
    65  return earliest_presentation_time_;
    66  }
    67  bool fragment_initialized() const { return fragment_initialized_; }
    68  bool fragment_finalized() const { return fragment_finalized_; }
    69  BufferWriter* data() { return data_.get(); }
    70  const std::vector<KeyFrameInfo>& key_frame_infos() const {
    71  return key_frame_infos_;
    72  }
    73 
    74  protected:
    75  TrackFragment* traf() { return traf_; }
    76 
    80  template <typename T>
    81  bool OptimizeSampleEntries(std::vector<T>* entries, T* default_value);
    82 
    83  private:
    84  Status FinalizeFragmentForEncryption();
    85  // Check if the current fragment starts with SAP.
    86  bool StartsWithSAP() const;
    87 
    88  std::shared_ptr<const StreamInfo> stream_info_;
    89  TrackFragment* traf_ = nullptr;
    90  int64_t edit_list_offset_ = 0;
    91  int64_t seek_preroll_ = 0;
    92  bool fragment_initialized_ = false;
    93  bool fragment_finalized_ = false;
    94  int64_t fragment_duration_ = 0;
    95  int64_t earliest_presentation_time_ = 0;
    96  int64_t first_sap_time_ = 0;
    97  std::unique_ptr<BufferWriter> data_;
    98  // Saves key frames information, for Video.
    99  std::vector<KeyFrameInfo> key_frame_infos_;
    100 
    101  DISALLOW_COPY_AND_ASSIGN(Fragmenter);
    102 };
    103 
    104 template <typename T>
    105 bool Fragmenter::OptimizeSampleEntries(std::vector<T>* entries,
    106  T* default_value) {
    107  DCHECK(entries);
    108  DCHECK(default_value);
    109  DCHECK(!entries->empty());
    110 
    111  typename std::vector<T>::const_iterator it = entries->begin();
    112  T value = *it;
    113  for (; it < entries->end(); ++it)
    114  if (value != *it)
    115  return false;
    116 
    117  // Clear |entries| if it contains only one value.
    118  entries->clear();
    119  *default_value = value;
    120  return true;
    121 }
    122 
    123 } // namespace mp4
    124 } // namespace media
    125 } // namespace shaka
    126 
    127 #endif // PACKAGER_MEDIA_FORMATS_MP4_FRAGMENTER_H_
    - -
    All the methods that are virtual are virtual for mocking.
    -
    Status InitializeFragment(int64_t first_sample_dts)
    Definition: fragmenter.cc:129
    - -
    void GenerateSegmentReference(SegmentReference *reference) const
    Fill reference with current fragment information.
    Definition: fragmenter.cc:224
    - -
    Status AddSample(const MediaSample &sample)
    Definition: fragmenter.cc:65
    - -
    Fragmenter(std::shared_ptr< const StreamInfo > info, TrackFragment *traf, int64_t edit_list_offset)
    Definition: fragmenter.cc:50
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    -
    Status FinalizeFragment()
    Finalize and optimize the fragment.
    Definition: fragmenter.cc:159
    -
    bool OptimizeSampleEntries(std::vector< T > *entries, T *default_value)
    Definition: fragmenter.h:105
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_FRAGMENTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_FRAGMENTER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <vector>
    +
    12 
    +
    13 #include "packager/base/logging.h"
    +
    14 #include "packager/status.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 class BufferWriter;
    +
    20 class MediaSample;
    +
    21 class StreamInfo;
    +
    22 
    +
    23 namespace mp4 {
    +
    24 
    +
    25 struct KeyFrameInfo;
    +
    26 struct SegmentReference;
    +
    27 struct TrackFragment;
    +
    28 
    +
    31 class Fragmenter {
    +
    32  public:
    +
    37  Fragmenter(std::shared_ptr<const StreamInfo> info,
    +
    38  TrackFragment* traf,
    +
    39  int64_t edit_list_offset);
    +
    40 
    +
    41  ~Fragmenter();
    +
    42 
    +
    46  Status AddSample(const MediaSample& sample);
    +
    47 
    +
    52  Status InitializeFragment(int64_t first_sample_dts);
    +
    53 
    + +
    56 
    +
    58  void GenerateSegmentReference(SegmentReference* reference) const;
    +
    59 
    +
    60  void ClearFragmentFinalized() { fragment_finalized_ = false; }
    +
    61 
    +
    62  uint64_t fragment_duration() const { return fragment_duration_; }
    +
    63  uint64_t first_sap_time() const { return first_sap_time_; }
    +
    64  uint64_t earliest_presentation_time() const {
    +
    65  return earliest_presentation_time_;
    +
    66  }
    +
    67  bool fragment_initialized() const { return fragment_initialized_; }
    +
    68  bool fragment_finalized() const { return fragment_finalized_; }
    +
    69  BufferWriter* data() { return data_.get(); }
    +
    70  const std::vector<KeyFrameInfo>& key_frame_infos() const {
    +
    71  return key_frame_infos_;
    +
    72  }
    +
    73 
    +
    74  protected:
    +
    75  TrackFragment* traf() { return traf_; }
    +
    76 
    +
    80  template <typename T>
    +
    81  bool OptimizeSampleEntries(std::vector<T>* entries, T* default_value);
    +
    82 
    +
    83  private:
    +
    84  Status FinalizeFragmentForEncryption();
    +
    85  // Check if the current fragment starts with SAP.
    +
    86  bool StartsWithSAP() const;
    +
    87 
    +
    88  std::shared_ptr<const StreamInfo> stream_info_;
    +
    89  TrackFragment* traf_ = nullptr;
    +
    90  int64_t edit_list_offset_ = 0;
    +
    91  int64_t seek_preroll_ = 0;
    +
    92  bool fragment_initialized_ = false;
    +
    93  bool fragment_finalized_ = false;
    +
    94  int64_t fragment_duration_ = 0;
    +
    95  int64_t earliest_presentation_time_ = 0;
    +
    96  int64_t first_sap_time_ = 0;
    +
    97  std::unique_ptr<BufferWriter> data_;
    +
    98  // Saves key frames information, for Video.
    +
    99  std::vector<KeyFrameInfo> key_frame_infos_;
    +
    100 
    +
    101  DISALLOW_COPY_AND_ASSIGN(Fragmenter);
    +
    102 };
    +
    103 
    +
    104 template <typename T>
    +
    105 bool Fragmenter::OptimizeSampleEntries(std::vector<T>* entries,
    +
    106  T* default_value) {
    +
    107  DCHECK(entries);
    +
    108  DCHECK(default_value);
    +
    109  DCHECK(!entries->empty());
    +
    110 
    +
    111  typename std::vector<T>::const_iterator it = entries->begin();
    +
    112  T value = *it;
    +
    113  for (; it < entries->end(); ++it)
    +
    114  if (value != *it)
    +
    115  return false;
    +
    116 
    +
    117  // Clear |entries| if it contains only one value.
    +
    118  entries->clear();
    +
    119  *default_value = value;
    +
    120  return true;
    +
    121 }
    +
    122 
    +
    123 } // namespace mp4
    +
    124 } // namespace media
    +
    125 } // namespace shaka
    +
    126 
    +
    127 #endif // PACKAGER_MEDIA_FORMATS_MP4_FRAGMENTER_H_
    + + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    + +
    bool OptimizeSampleEntries(std::vector< T > *entries, T *default_value)
    Definition: fragmenter.h:105
    +
    Status AddSample(const MediaSample &sample)
    Definition: fragmenter.cc:65
    +
    Status InitializeFragment(int64_t first_sample_dts)
    Definition: fragmenter.cc:129
    +
    void GenerateSegmentReference(SegmentReference *reference) const
    Fill reference with current fragment information.
    Definition: fragmenter.cc:227
    +
    Status FinalizeFragment()
    Finalize and optimize the fragment.
    Definition: fragmenter.cc:159
    +
    Fragmenter(std::shared_ptr< const StreamInfo > info, TrackFragment *traf, int64_t edit_list_offset)
    Definition: fragmenter.cc:50
    +
    All the methods that are virtual are virtual for mocking.
    + +
    diff --git a/docs/da/dd2/classshaka_1_1media_1_1mp2t_1_1TsPacket-members.html b/docs/da/dd2/classshaka_1_1media_1_1mp2t_1_1TsPacket-members.html index 8dd8cd292d..0ef74d0de9 100644 --- a/docs/da/dd2/classshaka_1_1media_1_1mp2t_1_1TsPacket-members.html +++ b/docs/da/dd2/classshaka_1_1media_1_1mp2t_1_1TsPacket-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/da/dd6/classshaka_1_1media_1_1H264ByteToUnitStreamConverter-members.html b/docs/da/dd6/classshaka_1_1media_1_1H264ByteToUnitStreamConverter-members.html index 0fc50a085c..6db85303c6 100644 --- a/docs/da/dd6/classshaka_1_1media_1_1H264ByteToUnitStreamConverter-members.html +++ b/docs/da/dd6/classshaka_1_1media_1_1H264ByteToUnitStreamConverter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/dd8/classshaka_1_1media_1_1mp2t_1_1Mp2tMediaParser-members.html b/docs/da/dd8/classshaka_1_1media_1_1mp2t_1_1Mp2tMediaParser-members.html index de51658b9a..2fe3050490 100644 --- a/docs/da/dd8/classshaka_1_1media_1_1mp2t_1_1Mp2tMediaParser-members.html +++ b/docs/da/dd8/classshaka_1_1media_1_1mp2t_1_1Mp2tMediaParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    This is the complete list of members for shaka::media::mp2t::Mp2tMediaParser, including all inherited members.

    - + - - - - + + + + +
    Flush() override WARN_UNUSED_RESULTshaka::media::mp2t::Mp2tMediaParservirtual
    Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) overrideshaka::media::mp2t::Mp2tMediaParservirtual
    Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) overrideshaka::media::mp2t::Mp2tMediaParservirtual
    InitCB typedefshaka::media::MediaParser
    MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinline
    Mp2tMediaParser() (defined in shaka::media::mp2t::Mp2tMediaParser)shaka::media::mp2t::Mp2tMediaParser
    NewSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULTshaka::media::mp2t::Mp2tMediaParservirtual
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    ~Mp2tMediaParser() override (defined in shaka::media::mp2t::Mp2tMediaParser)shaka::media::mp2t::Mp2tMediaParser
    NewMediaSampleCB typedefshaka::media::MediaParser
    NewTextSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULTshaka::media::mp2t::Mp2tMediaParservirtual
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    ~Mp2tMediaParser() override (defined in shaka::media::mp2t::Mp2tMediaParser)shaka::media::mp2t::Mp2tMediaParser
    diff --git a/docs/da/dda/structshaka_1_1media_1_1H264SEIRecoveryPoint-members.html b/docs/da/dda/structshaka_1_1media_1_1H264SEIRecoveryPoint-members.html index 36c2fd661a..036143d3c4 100644 --- a/docs/da/dda/structshaka_1_1media_1_1H264SEIRecoveryPoint-members.html +++ b/docs/da/dda/structshaka_1_1media_1_1H264SEIRecoveryPoint-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/ddd/classshaka_1_1media_1_1WidevineKeySource.html b/docs/da/ddd/classshaka_1_1media_1_1WidevineKeySource.html index fee93b6ca5..adaba8b28e 100644 --- a/docs/da/ddd/classshaka_1_1media_1_1WidevineKeySource.html +++ b/docs/da/ddd/classshaka_1_1media_1_1WidevineKeySource.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WidevineKeySource Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::media::KeySource - -
    +shaka::media::KeySource + + - - + + @@ -106,24 +109,14 @@ void  - - - -

    Public Member Functions

     WidevineKeySource (const std::string &server_url, int protection_systems_flags, FourCC protection_scheme)
     
     WidevineKeySource (const std::string &server_url, ProtectionSystem protection_systems, FourCC protection_scheme)
     
    Status FetchKeys (const std::vector< uint8_t > &content_id, const std::string &policy)
     
    void set_signer (std::unique_ptr< RequestSigner > signer)
    set_enable_entitlemen
     
    Status GetCryptoPeriodKey (uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
     
    - Public Member Functions inherited from shaka::media::KeySource
    KeySource (int protection_systems_flags, FourCC protection_scheme)
     
    - - - -

    -Additional Inherited Members

    - Protected Member Functions inherited from shaka::media::KeySource
    Status UpdateProtectionSystemInfo (EncryptionKeyMap *encryption_key_map)
     

    Detailed Description

    WidevineKeySource talks to the Widevine encryption service to acquire the encryption keys.

    Definition at line 29 of file widevine_key_source.h.

    Constructor & Destructor Documentation

    - -

    ◆ WidevineKeySource()

    + +

    ◆ WidevineKeySource()

    @@ -137,8 +130,8 @@ Additional Inherited Members - int  - protection_systems_flags, + ProtectionSystem  + protection_systems, @@ -156,7 +149,7 @@ Additional Inherited Members
    Parameters
    - +
    server_urlis the Widevine common encryption server url.
    protection_systems_flagsis the flags indicating which PSSH should be included.
    protection_systemsis the enum indicating which PSSH should be included.
    protection_schemeis the Protection Scheme to be used for encryption. It needs to be signalled in Widevine PSSH. This argument can be ignored if Widevine PSSH is not generated.
    @@ -167,8 +160,46 @@ Additional Inherited Members

    Member Function Documentation

    + +

    ◆ FetchKeys() [1/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    Status shaka::media::WidevineKeySource::FetchKeys (const std::vector< uint8_t > & content_id,
    const std::string & policy 
    )
    +
    +

    Fetch keys for CENC from the key server.

    Parameters
    + + + +
    content_idthe unique id identify the content.
    policyspecifies the DRM content rights.
    +
    +
    +
    Returns
    OK on success, an error status otherwise.
    + +

    Definition at line 118 of file widevine_key_source.cc.

    + +
    +
    -

    ◆ FetchKeys() [1/2]

    +

    ◆ FetchKeys() [2/2]

    @@ -211,45 +242,7 @@ Additional Inherited Members

    Implements shaka::media::KeySource.

    -

    Definition at line 135 of file widevine_key_source.cc.

    - -
    -
    - -

    ◆ FetchKeys() [2/2]

    - -
    -
    - - - - - - - - - - - - - - - - - - -
    Status shaka::media::WidevineKeySource::FetchKeys (const std::vector< uint8_t > & content_id,
    const std::string & policy 
    )
    -
    -

    Fetch keys for CENC from the key server.

    Parameters
    - - - -
    content_idthe unique id identify the content.
    policyspecifies the DRM content rights.
    -
    -
    -
    Returns
    OK on success, an error status otherwise.
    - -

    Definition at line 120 of file widevine_key_source.cc.

    +

    Definition at line 133 of file widevine_key_source.cc.

    @@ -311,7 +304,7 @@ Additional Inherited Members

    Implements shaka::media::KeySource.

    -

    Definition at line 221 of file widevine_key_source.cc.

    +

    Definition at line 219 of file widevine_key_source.cc.

    @@ -359,7 +352,7 @@ Additional Inherited Members

    Implements shaka::media::KeySource.

    -

    Definition at line 197 of file widevine_key_source.cc.

    +

    Definition at line 195 of file widevine_key_source.cc.

    @@ -407,7 +400,7 @@ Additional Inherited Members

    Implements shaka::media::KeySource.

    -

    Definition at line 208 of file widevine_key_source.cc.

    +

    Definition at line 206 of file widevine_key_source.cc.

    @@ -426,14 +419,14 @@ Additional Inherited Members
    -

    Inject an KeyFetcher object, mainly used for testing.

    Parameters
    +

    Inject an KeyFetcher object, mainly used for testing.

    Parameters
    - +
    key_fetcherpoints to the KeyFetcher object to be injected.
    key_fetcherpoints to the KeyFetcher object to be injected.
    -

    Definition at line 254 of file widevine_key_source.cc.

    +

    Definition at line 252 of file widevine_key_source.cc.

    @@ -459,7 +452,7 @@ Additional Inherited Members -

    Definition at line 250 of file widevine_key_source.cc.

    +

    Definition at line 248 of file widevine_key_source.cc.

    @@ -470,9 +463,7 @@ Additional Inherited Members diff --git a/docs/da/ddf/structshaka_1_1media_1_1mp4_1_1SampleDescription-members.html b/docs/da/ddf/structshaka_1_1media_1_1mp4_1_1SampleDescription-members.html index 843fdc8e06..98b1f817ad 100644 --- a/docs/da/ddf/structshaka_1_1media_1_1mp4_1_1SampleDescription-members.html +++ b/docs/da/ddf/structshaka_1_1media_1_1mp4_1_1SampleDescription-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/de2/mock__mpd__builder_8cc_source.html b/docs/da/de2/mock__mpd__builder_8cc_source.html index 6196883094..12660c571f 100644 --- a/docs/da/de2/mock__mpd__builder_8cc_source.html +++ b/docs/da/de2/mock__mpd__builder_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mock_mpd_builder.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    mock_mpd_builder.cc
    -
    1 #include "packager/mpd/base/mock_mpd_builder.h"
    2 
    3 #include "packager/mpd/base/media_info.pb.h"
    4 
    5 namespace shaka {
    6 namespace {
    7 const char kEmptyLang[] = "";
    8 const MpdOptions kDefaultMpdOptions;
    9 } // namespace
    10 
    11 // Doesn't matter what values get passed to the super class' constructor.
    12 // All methods used for testing should be mocked.
    13 MockMpdBuilder::MockMpdBuilder() : MpdBuilder(kDefaultMpdOptions) {}
    14 MockMpdBuilder::~MockMpdBuilder() {}
    15 
    16 MockPeriod::MockPeriod(uint32_t period_id, double start_time_in_seconds)
    17  : Period(period_id,
    18  start_time_in_seconds,
    19  kDefaultMpdOptions,
    20  &sequence_counter_) {}
    21 
    22 MockAdaptationSet::MockAdaptationSet()
    23  : AdaptationSet(kEmptyLang, kDefaultMpdOptions, &sequence_counter_) {}
    24 MockAdaptationSet::~MockAdaptationSet() {}
    25 
    26 MockRepresentation::MockRepresentation(uint32_t representation_id)
    27  : Representation(MediaInfo(),
    28  kDefaultMpdOptions,
    29  representation_id,
    30  std::unique_ptr<RepresentationStateChangeListener>()) {}
    31 MockRepresentation::~MockRepresentation() {}
    32 
    33 } // namespace shaka
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 #include "packager/mpd/base/mock_mpd_builder.h"
    +
    2 
    +
    3 #include "packager/mpd/base/media_info.pb.h"
    +
    4 
    +
    5 namespace shaka {
    +
    6 namespace {
    +
    7 const char kEmptyLang[] = "";
    +
    8 const MpdOptions kDefaultMpdOptions;
    +
    9 } // namespace
    +
    10 
    +
    11 // Doesn't matter what values get passed to the super class' constructor.
    +
    12 // All methods used for testing should be mocked.
    +
    13 MockMpdBuilder::MockMpdBuilder() : MpdBuilder(kDefaultMpdOptions) {}
    +
    14 MockMpdBuilder::~MockMpdBuilder() {}
    +
    15 
    +
    16 MockPeriod::MockPeriod(uint32_t period_id, double start_time_in_seconds)
    +
    17  : Period(period_id,
    +
    18  start_time_in_seconds,
    +
    19  kDefaultMpdOptions,
    +
    20  &sequence_counter_) {}
    +
    21 
    +
    22 MockAdaptationSet::MockAdaptationSet()
    +
    23  : AdaptationSet(kEmptyLang, kDefaultMpdOptions, &sequence_counter_) {}
    +
    24 
    +
    25 MockAdaptationSet::~MockAdaptationSet() {}
    +
    26 
    +
    27 MockRepresentation::MockRepresentation(uint32_t representation_id)
    +
    28  : Representation(MediaInfo(),
    +
    29  kDefaultMpdOptions,
    +
    30  representation_id,
    +
    31  std::unique_ptr<RepresentationStateChangeListener>()) {}
    +
    32 MockRepresentation::~MockRepresentation() {}
    +
    33 
    +
    34 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/de4/classshaka_1_1media_1_1WebMClusterParser.html b/docs/da/de4/classshaka_1_1media_1_1WebMClusterParser.html index 0d43e89855..8679318a3d 100644 --- a/docs/da/de4/classshaka_1_1media_1_1WebMClusterParser.html +++ b/docs/da/de4/classshaka_1_1media_1_1WebMClusterParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMClusterParser Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::WebMParserClient - -
    + + -

    Public Types

    enum  { kDefaultAudioBufferDurationInMs = 23, -kDefaultVideoBufferDurationInMs = 63 +
    enum  { kDefaultAudioBufferDurationInMs = 23 +, kDefaultVideoBufferDurationInMs = 63 }
     
    - - + + @@ -148,8 +151,8 @@ Additional Inherited Members

    Constructor & Destructor Documentation

    - -

    ◆ WebMClusterParser()

    + +

    ◆ WebMClusterParser()

    @@ -217,7 +220,7 @@ Additional Inherited Members
    - + @@ -353,9 +356,7 @@ The number of bytes parsed on success. diff --git a/docs/da/de6/structshaka_1_1media_1_1mp4_1_1SchemeType-members.html b/docs/da/de6/structshaka_1_1media_1_1mp4_1_1SchemeType-members.html index 87953bd0c8..3ac4322e7c 100644 --- a/docs/da/de6/structshaka_1_1media_1_1mp4_1_1SchemeType-members.html +++ b/docs/da/de6/structshaka_1_1media_1_1mp4_1_1SchemeType-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

     WebMClusterParser (int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)
     
     WebMClusterParser (int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewMediaSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)
     
    void Reset ()
     Resets the parser state so it can accept a new cluster.
    const MediaParser::NewSampleCBconst MediaParser::NewMediaSampleCB new_sample_cb,
    - + +/* @license-end */
    diff --git a/docs/da/de8/classshaka_1_1media_1_1AudioStreamInfo-members.html b/docs/da/de8/classshaka_1_1media_1_1AudioStreamInfo-members.html index 392e83d049..f1dbae29e7 100644 --- a/docs/da/de8/classshaka_1_1media_1_1AudioStreamInfo-members.html +++ b/docs/da/de8/classshaka_1_1media_1_1AudioStreamInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/de9/structshaka_1_1media_1_1mp4_1_1ProtectionSchemeInfo.html b/docs/da/de9/structshaka_1_1media_1_1mp4_1_1ProtectionSchemeInfo.html index 3113b60b4c..3dd4778b4a 100644 --- a/docs/da/de9/structshaka_1_1media_1_1mp4_1_1ProtectionSchemeInfo.html +++ b/docs/da/de9/structshaka_1_1media_1_1mp4_1_1ProtectionSchemeInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::ProtectionSchemeInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -118,7 +121,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 166 of file box_definitions.h.

    +

    Definition at line 167 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -146,7 +149,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 501 of file box_definitions.cc.

    +

    Definition at line 513 of file box_definitions.cc.

    @@ -157,9 +160,7 @@ Additional Inherited Members diff --git a/docs/da/df0/classshaka_1_1media_1_1H264VideoSliceHeaderParser.html b/docs/da/df0/classshaka_1_1media_1_1H264VideoSliceHeaderParser.html index 8a771152bb..bc828687f3 100644 --- a/docs/da/df0/classshaka_1_1media_1_1H264VideoSliceHeaderParser.html +++ b/docs/da/df0/classshaka_1_1media_1_1H264VideoSliceHeaderParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264VideoSliceHeaderParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::VideoSliceHeaderParser - -
    + + @@ -152,7 +155,7 @@ int64_t 

    Public Member Functions

    shaka::media::VideoSliceHeaderParser.

    -

    Definition at line 47 of file video_slice_header_parser.cc.

    +

    Definition at line 46 of file video_slice_header_parser.cc.

    @@ -163,9 +166,7 @@ int64_t 
    diff --git a/docs/da/df4/aes__decryptor_8cc_source.html b/docs/da/df4/aes__decryptor_8cc_source.html index 57ae83be91..148d29d0e1 100644 --- a/docs/da/df4/aes__decryptor_8cc_source.html +++ b/docs/da/df4/aes__decryptor_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/aes_decryptor.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    aes_decryptor.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/aes_decryptor.h"
    8 
    9 #include <openssl/aes.h>
    10 #include <algorithm>
    11 #include "packager/base/logging.h"
    12 
    13 namespace {
    14 
    15 // AES defines three key sizes: 128, 192 and 256 bits.
    16 bool IsKeySizeValidForAes(size_t key_size) {
    17  return key_size == 16 || key_size == 24 || key_size == 32;
    18 }
    19 
    20 } // namespace
    21 
    22 namespace shaka {
    23 namespace media {
    24 
    25 AesCbcDecryptor::AesCbcDecryptor(CbcPaddingScheme padding_scheme)
    26  : AesCbcDecryptor(padding_scheme, kDontUseConstantIv) {}
    27 
    28 AesCbcDecryptor::AesCbcDecryptor(CbcPaddingScheme padding_scheme,
    29  ConstantIvFlag constant_iv_flag)
    30  : AesCryptor(constant_iv_flag), padding_scheme_(padding_scheme) {
    31  if (padding_scheme_ != kNoPadding) {
    32  CHECK_EQ(constant_iv_flag, kUseConstantIv)
    33  << "non-constant iv (cipher block chain across calls) only makes sense "
    34  "if the padding_scheme is kNoPadding.";
    35  }
    36 }
    37 
    38 AesCbcDecryptor::~AesCbcDecryptor() {}
    39 
    40 bool AesCbcDecryptor::InitializeWithIv(const std::vector<uint8_t>& key,
    41  const std::vector<uint8_t>& iv) {
    42  if (!IsKeySizeValidForAes(key.size())) {
    43  LOG(ERROR) << "Invalid AES key size: " << key.size();
    44  return false;
    45  }
    46 
    47  CHECK_EQ(AES_set_decrypt_key(key.data(), key.size() * 8, mutable_aes_key()),
    48  0);
    49  return SetIv(iv);
    50 }
    51 
    52 bool AesCbcDecryptor::CryptInternal(const uint8_t* ciphertext,
    53  size_t ciphertext_size,
    54  uint8_t* plaintext,
    55  size_t* plaintext_size) {
    56  DCHECK(plaintext_size);
    57  DCHECK(aes_key());
    58  // Plaintext size is the same as ciphertext size except for pkcs5 padding.
    59  // Will update later if using pkcs5 padding. For pkcs5 padding, we still
    60  // need at least |ciphertext_size| bytes for intermediate operation.
    61  if (*plaintext_size < ciphertext_size) {
    62  LOG(ERROR) << "Expecting output size of at least " << ciphertext_size
    63  << " bytes.";
    64  return false;
    65  }
    66  *plaintext_size = ciphertext_size;
    67 
    68  if (ciphertext_size == 0) {
    69  if (padding_scheme_ == kPkcs5Padding) {
    70  LOG(ERROR) << "Expected ciphertext to be at least " << AES_BLOCK_SIZE
    71  << " bytes with Pkcs5 padding.";
    72  return false;
    73  }
    74  return true;
    75  }
    76  DCHECK(plaintext);
    77 
    78  const size_t residual_block_size = ciphertext_size % AES_BLOCK_SIZE;
    79  const size_t cbc_size = ciphertext_size - residual_block_size;
    80  if (residual_block_size == 0) {
    81  AES_cbc_encrypt(ciphertext, plaintext, ciphertext_size, aes_key(),
    82  internal_iv_.data(), AES_DECRYPT);
    83  if (padding_scheme_ != kPkcs5Padding)
    84  return true;
    85 
    86  // Strip off PKCS5 padding bytes.
    87  const uint8_t num_padding_bytes = plaintext[ciphertext_size - 1];
    88  if (num_padding_bytes > AES_BLOCK_SIZE) {
    89  LOG(ERROR) << "Padding length is too large : "
    90  << static_cast<int>(num_padding_bytes);
    91  return false;
    92  }
    93  *plaintext_size -= num_padding_bytes;
    94  return true;
    95  } else if (padding_scheme_ == kNoPadding) {
    96  AES_cbc_encrypt(ciphertext, plaintext, cbc_size, aes_key(),
    97  internal_iv_.data(), AES_DECRYPT);
    98 
    99  // The residual block is not encrypted.
    100  memcpy(plaintext + cbc_size, ciphertext + cbc_size, residual_block_size);
    101  return true;
    102  } else if (padding_scheme_ != kCtsPadding) {
    103  LOG(ERROR) << "Expecting cipher text size to be multiple of "
    104  << AES_BLOCK_SIZE << ", got " << ciphertext_size;
    105  return false;
    106  }
    107 
    108  DCHECK_EQ(padding_scheme_, kCtsPadding);
    109  if (ciphertext_size < AES_BLOCK_SIZE) {
    110  // Don't have a full block, leave unencrypted.
    111  memcpy(plaintext, ciphertext, ciphertext_size);
    112  return true;
    113  }
    114 
    115  // AES-CBC decrypt everything up to the next-to-last full block.
    116  if (cbc_size > AES_BLOCK_SIZE) {
    117  AES_cbc_encrypt(ciphertext, plaintext, cbc_size - AES_BLOCK_SIZE, aes_key(),
    118  internal_iv_.data(), AES_DECRYPT);
    119  }
    120 
    121  const uint8_t* next_to_last_ciphertext_block =
    122  ciphertext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE;
    123  uint8_t* next_to_last_plaintext_block =
    124  plaintext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE;
    125 
    126  // Determine what the last IV should be so that we can "skip ahead" in the
    127  // CBC decryption.
    128  std::vector<uint8_t> last_iv(
    129  ciphertext + ciphertext_size - residual_block_size,
    130  ciphertext + ciphertext_size);
    131  last_iv.resize(AES_BLOCK_SIZE, 0);
    132 
    133  // Decrypt the next-to-last block using the IV determined above. This decrypts
    134  // the residual block bits.
    135  AES_cbc_encrypt(next_to_last_ciphertext_block, next_to_last_plaintext_block,
    136  AES_BLOCK_SIZE, aes_key(), last_iv.data(), AES_DECRYPT);
    137 
    138  // Swap back the residual block bits and the next-to-last block.
    139  if (plaintext == ciphertext) {
    140  std::swap_ranges(next_to_last_plaintext_block,
    141  next_to_last_plaintext_block + residual_block_size,
    142  next_to_last_plaintext_block + AES_BLOCK_SIZE);
    143  } else {
    144  memcpy(next_to_last_plaintext_block + AES_BLOCK_SIZE,
    145  next_to_last_plaintext_block, residual_block_size);
    146  memcpy(next_to_last_plaintext_block,
    147  next_to_last_ciphertext_block + AES_BLOCK_SIZE, residual_block_size);
    148  }
    149 
    150  // Decrypt the next-to-last full block.
    151  AES_cbc_encrypt(next_to_last_plaintext_block, next_to_last_plaintext_block,
    152  AES_BLOCK_SIZE, aes_key(), internal_iv_.data(), AES_DECRYPT);
    153  return true;
    154 }
    155 
    156 void AesCbcDecryptor::SetIvInternal() {
    157  internal_iv_ = iv();
    158  internal_iv_.resize(AES_BLOCK_SIZE, 0);
    159 }
    160 
    161 } // namespace media
    162 } // namespace shaka
    -
    Class which implements AES-CBC (Cipher block chaining) decryption.
    Definition: aes_decryptor.h:25
    -
    All the methods that are virtual are virtual for mocking.
    -
    AesCbcDecryptor(CbcPaddingScheme padding_scheme)
    -
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    -
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    -
    bool SetIv(const std::vector< uint8_t > &iv)
    Definition: aes_cryptor.cc:70
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/aes_decryptor.h"
    +
    8 
    +
    9 #include <openssl/aes.h>
    +
    10 #include <algorithm>
    +
    11 #include "packager/base/logging.h"
    +
    12 
    +
    13 namespace {
    +
    14 
    +
    15 // AES defines three key sizes: 128, 192 and 256 bits.
    +
    16 bool IsKeySizeValidForAes(size_t key_size) {
    +
    17  return key_size == 16 || key_size == 24 || key_size == 32;
    +
    18 }
    +
    19 
    +
    20 } // namespace
    +
    21 
    +
    22 namespace shaka {
    +
    23 namespace media {
    +
    24 
    +
    25 AesCbcDecryptor::AesCbcDecryptor(CbcPaddingScheme padding_scheme)
    +
    26  : AesCbcDecryptor(padding_scheme, kDontUseConstantIv) {}
    +
    27 
    +
    28 AesCbcDecryptor::AesCbcDecryptor(CbcPaddingScheme padding_scheme,
    +
    29  ConstantIvFlag constant_iv_flag)
    +
    30  : AesCryptor(constant_iv_flag), padding_scheme_(padding_scheme) {
    +
    31  if (padding_scheme_ != kNoPadding) {
    +
    32  CHECK_EQ(constant_iv_flag, kUseConstantIv)
    +
    33  << "non-constant iv (cipher block chain across calls) only makes sense "
    +
    34  "if the padding_scheme is kNoPadding.";
    +
    35  }
    +
    36 }
    +
    37 
    +
    38 AesCbcDecryptor::~AesCbcDecryptor() {}
    +
    39 
    +
    40 bool AesCbcDecryptor::InitializeWithIv(const std::vector<uint8_t>& key,
    +
    41  const std::vector<uint8_t>& iv) {
    +
    42  if (!IsKeySizeValidForAes(key.size())) {
    +
    43  LOG(ERROR) << "Invalid AES key size: " << key.size();
    +
    44  return false;
    +
    45  }
    +
    46 
    +
    47  CHECK_EQ(AES_set_decrypt_key(key.data(), key.size() * 8, mutable_aes_key()),
    +
    48  0);
    +
    49  return SetIv(iv);
    +
    50 }
    +
    51 
    +
    52 bool AesCbcDecryptor::CryptInternal(const uint8_t* ciphertext,
    +
    53  size_t ciphertext_size,
    +
    54  uint8_t* plaintext,
    +
    55  size_t* plaintext_size) {
    +
    56  DCHECK(plaintext_size);
    +
    57  DCHECK(aes_key());
    +
    58  // Plaintext size is the same as ciphertext size except for pkcs5 padding.
    +
    59  // Will update later if using pkcs5 padding. For pkcs5 padding, we still
    +
    60  // need at least |ciphertext_size| bytes for intermediate operation.
    +
    61  if (*plaintext_size < ciphertext_size) {
    +
    62  LOG(ERROR) << "Expecting output size of at least " << ciphertext_size
    +
    63  << " bytes.";
    +
    64  return false;
    +
    65  }
    +
    66  *plaintext_size = ciphertext_size;
    +
    67 
    +
    68  if (ciphertext_size == 0) {
    +
    69  if (padding_scheme_ == kPkcs5Padding) {
    +
    70  LOG(ERROR) << "Expected ciphertext to be at least " << AES_BLOCK_SIZE
    +
    71  << " bytes with Pkcs5 padding.";
    +
    72  return false;
    +
    73  }
    +
    74  return true;
    +
    75  }
    +
    76  DCHECK(plaintext);
    +
    77 
    +
    78  const size_t residual_block_size = ciphertext_size % AES_BLOCK_SIZE;
    +
    79  const size_t cbc_size = ciphertext_size - residual_block_size;
    +
    80  if (residual_block_size == 0) {
    +
    81  AES_cbc_encrypt(ciphertext, plaintext, ciphertext_size, aes_key(),
    +
    82  internal_iv_.data(), AES_DECRYPT);
    +
    83  if (padding_scheme_ != kPkcs5Padding)
    +
    84  return true;
    +
    85 
    +
    86  // Strip off PKCS5 padding bytes.
    +
    87  const uint8_t num_padding_bytes = plaintext[ciphertext_size - 1];
    +
    88  if (num_padding_bytes > AES_BLOCK_SIZE) {
    +
    89  LOG(ERROR) << "Padding length is too large : "
    +
    90  << static_cast<int>(num_padding_bytes);
    +
    91  return false;
    +
    92  }
    +
    93  *plaintext_size -= num_padding_bytes;
    +
    94  return true;
    +
    95  } else if (padding_scheme_ == kNoPadding) {
    +
    96  AES_cbc_encrypt(ciphertext, plaintext, cbc_size, aes_key(),
    +
    97  internal_iv_.data(), AES_DECRYPT);
    +
    98 
    +
    99  // The residual block is not encrypted.
    +
    100  memcpy(plaintext + cbc_size, ciphertext + cbc_size, residual_block_size);
    +
    101  return true;
    +
    102  } else if (padding_scheme_ != kCtsPadding) {
    +
    103  LOG(ERROR) << "Expecting cipher text size to be multiple of "
    +
    104  << AES_BLOCK_SIZE << ", got " << ciphertext_size;
    +
    105  return false;
    +
    106  }
    +
    107 
    +
    108  DCHECK_EQ(padding_scheme_, kCtsPadding);
    +
    109  if (ciphertext_size < AES_BLOCK_SIZE) {
    +
    110  // Don't have a full block, leave unencrypted.
    +
    111  memcpy(plaintext, ciphertext, ciphertext_size);
    +
    112  return true;
    +
    113  }
    +
    114 
    +
    115  // AES-CBC decrypt everything up to the next-to-last full block.
    +
    116  if (cbc_size > AES_BLOCK_SIZE) {
    +
    117  AES_cbc_encrypt(ciphertext, plaintext, cbc_size - AES_BLOCK_SIZE, aes_key(),
    +
    118  internal_iv_.data(), AES_DECRYPT);
    +
    119  }
    +
    120 
    +
    121  const uint8_t* next_to_last_ciphertext_block =
    +
    122  ciphertext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE;
    +
    123  uint8_t* next_to_last_plaintext_block =
    +
    124  plaintext + ciphertext_size - residual_block_size - AES_BLOCK_SIZE;
    +
    125 
    +
    126  // Determine what the last IV should be so that we can "skip ahead" in the
    +
    127  // CBC decryption.
    +
    128  std::vector<uint8_t> last_iv(
    +
    129  ciphertext + ciphertext_size - residual_block_size,
    +
    130  ciphertext + ciphertext_size);
    +
    131  last_iv.resize(AES_BLOCK_SIZE, 0);
    +
    132 
    +
    133  // Decrypt the next-to-last block using the IV determined above. This decrypts
    +
    134  // the residual block bits.
    +
    135  AES_cbc_encrypt(next_to_last_ciphertext_block, next_to_last_plaintext_block,
    +
    136  AES_BLOCK_SIZE, aes_key(), last_iv.data(), AES_DECRYPT);
    +
    137 
    +
    138  // Swap back the residual block bits and the next-to-last block.
    +
    139  if (plaintext == ciphertext) {
    +
    140  std::swap_ranges(next_to_last_plaintext_block,
    +
    141  next_to_last_plaintext_block + residual_block_size,
    +
    142  next_to_last_plaintext_block + AES_BLOCK_SIZE);
    +
    143  } else {
    +
    144  memcpy(next_to_last_plaintext_block + AES_BLOCK_SIZE,
    +
    145  next_to_last_plaintext_block, residual_block_size);
    +
    146  memcpy(next_to_last_plaintext_block,
    +
    147  next_to_last_ciphertext_block + AES_BLOCK_SIZE, residual_block_size);
    +
    148  }
    +
    149 
    +
    150  // Decrypt the next-to-last full block.
    +
    151  AES_cbc_encrypt(next_to_last_plaintext_block, next_to_last_plaintext_block,
    +
    152  AES_BLOCK_SIZE, aes_key(), internal_iv_.data(), AES_DECRYPT);
    +
    153  return true;
    +
    154 }
    +
    155 
    +
    156 void AesCbcDecryptor::SetIvInternal() {
    +
    157  internal_iv_ = iv();
    +
    158  internal_iv_.resize(AES_BLOCK_SIZE, 0);
    +
    159 }
    +
    160 
    +
    161 } // namespace media
    +
    162 } // namespace shaka
    +
    Class which implements AES-CBC (Cipher block chaining) decryption.
    Definition: aes_decryptor.h:25
    +
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    +
    AesCbcDecryptor(CbcPaddingScheme padding_scheme)
    + +
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    +
    bool SetIv(const std::vector< uint8_t > &iv)
    Definition: aes_cryptor.cc:70
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/da/df5/structshaka_1_1media_1_1mp4_1_1SampleDescription.html b/docs/da/df5/structshaka_1_1media_1_1mp4_1_1SampleDescription.html index 260fffc3ec..b4d53eb5d5 100644 --- a/docs/da/df5/structshaka_1_1media_1_1mp4_1_1SampleDescription.html +++ b/docs/da/df5/structshaka_1_1media_1_1mp4_1_1SampleDescription.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleDescription Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -130,7 +133,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 409 of file box_definitions.h.

    +

    Definition at line 422 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -158,7 +161,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 611 of file box_definitions.cc.

    +

    Definition at line 623 of file box_definitions.cc.

    @@ -169,9 +172,7 @@ Additional Inherited Members diff --git a/docs/da/df9/classshaka_1_1media_1_1AesPatternCryptor-members.html b/docs/da/df9/classshaka_1_1media_1_1AesPatternCryptor-members.html index 83d3f1c85e..56e11a8a3b 100644 --- a/docs/da/df9/classshaka_1_1media_1_1AesPatternCryptor-members.html +++ b/docs/da/df9/classshaka_1_1media_1_1AesPatternCryptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/da/df9/classshaka_1_1media_1_1JobManager-members.html b/docs/da/df9/classshaka_1_1media_1_1JobManager-members.html index ee28af8246..a2d4338f18 100644 --- a/docs/da/df9/classshaka_1_1media_1_1JobManager-members.html +++ b/docs/da/df9/classshaka_1_1media_1_1JobManager-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    Add(const std::string &name, std::shared_ptr< OriginHandler > handler) (defined in shaka::media::JobManager)shaka::media::JobManager CancelJobs() (defined in shaka::media::JobManager)shaka::media::JobManager - InitializeJobs() (defined in shaka::media::JobManager)shaka::media::JobManager - JobManager(std::unique_ptr< SyncPointQueue > sync_points) (defined in shaka::media::JobManager)shaka::media::JobManagerexplicit - RunJobs() (defined in shaka::media::JobManager)shaka::media::JobManager + InitializeJobs() (defined in shaka::media::JobManager)shaka::media::JobManagervirtual + job_entries_ (defined in shaka::media::JobManager)shaka::media::JobManagerprotected + JobManager(std::unique_ptr< SyncPointQueue > sync_points) (defined in shaka::media::JobManager)shaka::media::JobManagerexplicit + JobManager(const JobManager &)=delete (defined in shaka::media::JobManager)shaka::media::JobManagerprotected + jobs_ (defined in shaka::media::JobManager)shaka::media::JobManagerprotected + operator=(const JobManager &)=delete (defined in shaka::media::JobManager)shaka::media::JobManagerprotected + RunJobs() (defined in shaka::media::JobManager)shaka::media::JobManagervirtual sync_points() (defined in shaka::media::JobManager)shaka::media::JobManagerinline + sync_points_ (defined in shaka::media::JobManager)shaka::media::JobManagerprotected + ~JobManager()=default (defined in shaka::media::JobManager)shaka::media::JobManagervirtual
    diff --git a/docs/da/dfd/classshaka_1_1media_1_1MediaHandler.html b/docs/da/dfd/classshaka_1_1media_1_1MediaHandler.html index 9645577236..e7b168e2a6 100644 --- a/docs/da/dfd/classshaka_1_1media_1_1MediaHandler.html +++ b/docs/da/dfd/classshaka_1_1media_1_1MediaHandler.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MediaHandler Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::CachingMediaHandler -shaka::media::ChunkingHandler -shaka::media::CueAlignmentHandler -shaka::media::EncryptionHandler -shaka::media::FakeInputMediaHandler -shaka::media::MockOutputMediaHandler -shaka::media::Muxer -shaka::media::OriginHandler -shaka::media::Replicator -shaka::media::TextChunker -shaka::media::TextPadder -shaka::media::TrickPlayHandler -shaka::media::WebVttTextOutputHandler +shaka::media::CcStreamFilter +shaka::media::ChunkingHandler +shaka::media::CueAlignmentHandler +shaka::media::EncryptionHandler +shaka::media::FakeInputMediaHandler +shaka::media::MockOutputMediaHandler +shaka::media::Muxer +shaka::media::OriginHandler +shaka::media::Replicator +shaka::media::TextChunker +shaka::media::TextPadder +shaka::media::TrickPlayHandler shaka::media::WebVttToMp4Handler - -
    +shaka::media::ttml::TtmlToMp4Handler + + @@ -115,9 +119,9 @@ bool  - - + +

    Public Member Functions

    Static Public Member Functions

    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    @@ -258,7 +262,7 @@ const std::map< size_t, std::pair< std::shared_ptr< @@ -287,7 +291,7 @@ const std::map< size_t, std::pair< std::shared_ptr< @@ -298,9 +302,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/da/dfd/classshaka_1_1media_1_1MediaHandler.png b/docs/da/dfd/classshaka_1_1media_1_1MediaHandler.png index 0db8960192731c0c0aac48eea37043715c361488..19c1b9ebbc7fc5cec70a013455da72b88a3a086e 100644 GIT binary patch delta 5146 zcmZ8lXM8&7ZCM!#i!=!~< zVWxsgxsf8ESyD&QtPlYKmqHVfln@os^H}ek-<yF`AjZaeL&o2v9!(H;@*#gZbXB@ z@6$;JV>O*Sr(UP^uK%2$tO3%`#rt&ydCrN>S*zm{spJs-W&(SGri-842tVcLLEKf|3^k$f1TWnXrphONe3R*wMxK$D-k z_a9Dx&E}FzN@`BY#d$N>6^wrnRu(5v9=Xv65OK)n`r@O_d{L$YWa8G$X~n@%aEDR5 zB}H2h>>#OAf^!!C?f|jhB0GZw6z<oSH;1<;W&5G?Yoqn_*eimky_XdDm8%T*##PP5HwB2audMhizWDu`6?boj zUl|XeOszj%h|;d;&it6HUEz+M@@ z_{=4{olq6Kdq5()ZcTu7(IO`w+tvVRGFz8T`*U`nGLhS7B)HbIlHH-hy3FG+%wonC z0q!r8pIU-{Zs_-x-H;qPGobS(hQ)_v3dQx%5jBxdUz?%&^tz=aLPHO_Jxs7ZE2}{{ zZjq&~j7CR}rm`Q}JR-}q*#7UkM^3;JKH=|`X$X>u^8hxrZ+B!RNzPlIyMFxA*ND>kB%oRCqAEZJnjbIzhuhm!WKuhwu0Y zZ*!j={uh2gy#N8dnOqVw=?65zdt={9LUq~!uaZsRuTY3+e<5$%S`;HGlvVEyw@b1# zcdgT-lHC$G5y$GrEmJnQy$o=Z9ae05%bAHFV0cZl0lPnCwZ5W_=NFdGrO<;soRucp zHYu+j({s&L&1Fa+EP^VkAA z>po2oChe1E)^5FEnEQzFyOknV7XC*PX+)UFrWCr?jo%0p%eA+zt0tN};3dRp%ON;d$6}F}X zugvxNE81n1>c&fJo?3L!F; z>ycW6kXKm|ijW8x8VW7EbMwqSJ(`rqTR`1JY3onRh{6w!1N<@N{xS^x-S0xTS>#Y# zur$UH6Oc|l271P@8=JIyy3Cg21F{adlfU-qI2k-ZC)U~9UQ26xtIikWht^Sna8CCB zV0cDoiP6cdfHq}15+=zvL3)mqe-(6wVSXmY)Ag8TYmR;-!$h3e-qOW)KDUetXANaQ6!KdlhUMGhq#u4`(y2)y19 z=jLH)Jlpo3#=DMbZqQRlr8+Cdx&m~~3X;3J=^Pj7fyGKm@49%r-fAO&MaVBu$;%0< za~Nm!Q0ixSBqNBzJ$J_8K!58|!bIn^MJY5q!T%tmOVa)xa`HIfva8^#EF}$@W4##J zD=NxiU&p9a3>Ryd(+gwf9{vhQa@jYF+$s5Lk$&?6wcD4U6YORWDRD{$ifZ-P-;Qu~ za$BUg!_|j+1{|gff?WKn-IhGhy%El_^oyzr zil^i;?*tO9*?}s&aLqpfX!$uKP?)KNE&LWS^{M75m5&lW&#P-<(o@kb&jO43B)`JU zIHyXNnFbk(F!^LJ#5_*~Vd<|0CPIwruEhI7qfVGk3w*IMA0i zAu{@blye+Op2R*8FN<^5img&-NwONfxNZbhMBTVCD5q8iD$WlR_vQRIz?xtbO&SJH zo_INv1bEg9KFITKg?I2go}G>g;(X6@=@Z?}CeEE9G;}mKctBH$KQ{ zD}GSxA<#4z@Lo3VPde%dhH}0j!oIiEuOLz<=V?jQA=aP`agGw@O+#~)wG!uHJnKgI z75N)9LnaI34TC{~lPcncU1h2f`GIIRspc5fg~p#x2u%BA)WeJn5q7o`Pc3H(l86C#Tpc3 z)VFw~r1u-rjogrTI+ai1ovi)i2$*TgAm+hb+d?MM;op);cQ+)g=Y(Xa!wJr(SzfBb z`uf63$l^l@M}W5RT1I@Sihvi?uIZj|Al&uuSs=o`xBR5hl>UAc)Iz# zP3N{JNw+0qdIAJRwi=R%c2(e(tT#|8F(cF~;gHM=d>}UvaQax2ieQIiAN6!{R~Nc3 z(RUqF$m1>YNRcG@iLXz6X2O0*B10lora0V{4B&i2S-cj?812bJFn-ndC9AWHZq1M>KU7ptjdRq>^SpS^gZk zh^#MqLfMt0XXx~$n5Es zr;iNTMCA-R57wB=f42(8^#>`=n>AZ`0>=>K#cM(B)z3t3 zabTetS}ruW{(oG}KeNOlP`Fa1r{~g*BiYbe%D1YxA#2WD<^>$C1-G>S=gXr&Pq(By zJ>dbh%pPP-huEB7@aMPs;umUd`MCN$`UP>$@uU(0YIgcqT@-e?pMYUew1?o8W$9cO zb;)tRYh6^NqZ#-Ni_H_``C660_vYhCN;A$5SSagNCoAGW?;`i&&7o_gV6eErKYuGO zZi0(oos&J>8=Pbb(1b*C4M`wRrXL4_IznI8$>H*FA09IUwYJKLuY(` znz%2mYMpTH>+mb^*-4&#zm!GDbd4O5ERMGASbP~oa%>>pgv{|-{tozpmi9dECAACn{oY10#CHcVoIr{^7UE1WZY3WT%} z(g{8Z9?Q@B1t0OJbt?f4R4pEv%moF}*s9~Gs1i#2J98#ordRr3z%BtKb=KiBOf zh@YAb|{MyJjJl6WV%&iqTq{jN3*=( zfz5-BcH8UdYy3x@1=1gxV?G*laNE6#trR;3k9W6^RXYzn`4|n|6Z7jNf}CCe!h7Gl z)BRnbf*4(n{ozy8CDr*VTn<7Ur(s5Y3tx?6#&!q&{!ZIG(PT8#*c3`SFMcyK*6fMK0-F5xCaC}mX{(429XRUF(Ne&?NrqsnECIqA3c zd`C)m2RXhO>>1#)mCJuaL%D%JqT2-I{ z2t#LacY^C)sSt2KYO1qLmLW>;;A!5N24gPtdDjh0Gb$P2sinXE0|)ra0vZ7y54#H*pWq~ac3^Fz zbb>K&L85?`5d6-&x9LRXpTGsbOep?pT)LdN1Fw3IM#-dc!6a9n zz5bWu3D&N)%adn3QceZrai{Cm2}!5x^Gj4$dQtFLACPY31;1X=ivdIWt%i<96C+he zN*`sblN@oEZd1RyfmZz;i2^F@s~!EN)#X_NP7)6iV|~PDjixs?X0>#|8k!v2uhYf8 zCzZ#+cgZM;@|M{o)x@=5yaO^8DaP;KY778eEP~8yASKjS{eA;f|-aT`a z+C4H@oq+B23^oCA{^d2J=60;1XtCcvrd#52nvAX9BIJQ7;uoxR2A#{wTNkYvKv>7} z>lu0#vT>`ftrh%FUmvD+ya{5ZQJy2E2s{0Y52sfI7Ih42nS_66z`fuLF8! z&no^1P0$f3WHSwtkK3QzI&bV6T2LpD#WK7Vd0b3xj4H!KV&eq^@i*T3eZftE4?I){ zm4rJanY@I>xG1c0H9p)}pO|?)wH;~MO}`Ebash8KIl98VHkP5BIj_yHYvS-r#xhL^ z`9CW`k=s5pE1?=O(V`i~vR&oJ#r>%h4X-0N3RaCD}13QKxIkThUOt4rV4sHk#J6un4v zrkR-tH-X7^18zkw?#LhZ492fB=mbbcf3u&6)UpEfBEdDFrK?1fB8(Ow+F1tsYZ`qJ z!DbZ>-W8f6V!P?Y;o*2xhnywO(qx+4hk z4C046tWzN&XrM;Ot#RpDnz;%`PX^zeSr0Qyx8Fsa1FQW^!yaOh-0F_xUp0*oE6i0@ zvn|-h1|s6Y;y|DoAC9T{i*r!@3GoiM=4g@6m!y2dYW0jY!dm_+W7}H?_gaJg8deB6 zZ7o5;X)DK=%?_m{G;-~AfGR8i_Tn27(9ixh>7PPRLTB$2VmffzunYX3YT;U})dDjp z`*7+V(7o(#r&TUq0iDYlyisx5^>-V41{6sDtIeE&#A+s75rK)530KQuVUzlf?*}&$ z=j3Q_n)IqfIXV=?eL80U1-wB~9YO^q#fyYCO?hneL78QURh^5@^T`u55x?x?kSHpN zkqQ*6MAj~(9xl)&$VR7j*PJ&ke?}!ZE2d`sG4*>& zK(MbagS}(|-lE`4G0U?o_8M^f+bv2|Pspgw+*51Jsj}cV11)DEdrvUCm|$jkLJQd$ zMX5ej*yIC?8`!jWm=bmdV$n4V*;<+A_bnV)-@>6wozAq_#23>HCrU!QKh#9shQ_JZ z^n$D#XLhvZk1y*9$OFA=GtuCI{gNKRYe^e4zO8!KmsYCZkN&2W_RBHw4sgW@=bw+& J{1o!re*mlg5vc$G delta 4966 zcmZ8lc~nyQ9=A=Wa+y}OR9@q>O{voenj21&=9FV;F1e(Xrs7JCxgg@LaV9GlD&|Q- z%A}dOVxgiUs99r;UX2`FKv2`LK~a+c;kvwQGjGm&^Upn;!{wgK=ll77mfsNiro%16 z4f{S>qot)~@g?)q+q>*nn;PE^Hd=H3_Q35F3t%mAo}A(QRCzlFI?t^NTSA=;{c=|; z%f-5N%Yu*ft6+-j8$-FPbt~qLdRgu9GW<|NKp^XVLRbMVvF1big6U5vs=;boFa|pJ zG-&5YP?7P7yQFGyXdsc?uP6SoXH`z-=-s68{;MGEcd=|txqH>f6|DCBojr{hW}EQK}P7zju1bBZ}Q8?H*Lfhy(psgL!7r zA$zhTt}yU#0rbFRX14SR9>YsMkI_MIm3i5;%s*V+yqi%7W^mAbj*chTZOhcYW zu1N!XvXpt9s$(-LmOK_=@oquUSSxR1D7yiEpFEa^?nYjvz2g8r45W0vowLzedu93B zfv>e5eTQ7*Gm)ATdF73Z_1B5$gB{ji$HD(n@A?Ju5#tP?j$Z{R_h<+lqvt5x z13@rv!LxQ|T}@Ra;v)D0Es(~iRL<>sjLHn_Vsy+<^5p)q$2f;atD3#)IOTq z8||n?s>JFugWtXdPJT|KAExQhk}L5kHa32=#hjnx=l40$dz+nUzJwxm0~XhqhWn5^ zv6;y3Ck1Hwp#+Qr@j!{wt(N@c53wt7QzyNc(*3&4kCt4E0u(O#<&{#*=TzUG3uU$C zEpEt)yuD;lj|BuM?q)Rw6WtSExDAAjza2|JJ|9wFocsm4xSoHASDD&%3RRIbq{$sO z>Dmcu0l%`SlyNqZD0x%gm=GqKN$jAANiFR)7U>?+Ab;zbzW6;+rK!#AYIT7e>u36S z3KF%3-uJCti)5osdP~I9647)uXDM1-)h2>^(Tr zJC0-H=+)oN4AYhCeLGy3(p&Wn;-rOYyb!Xint;( zC#2_eYQID90Ov>C7W8}!CvMD)GQ4t!TUrH-9M`v0bC6f5VZ8U*>@u|*9-_Qd9f;RW%}w*2-(ePX+Em1g7#hIq@kmvhfsVG)=xHH_K}z)zrLN#m0pL} zV3Rq>8i#7WjPVa-ImOE79+s_FXCtnmoCP$Rq%nD^u3F^blngA1k*s9x7{+~RlB@h^ z;E;{dGE!XUF>mrJcKYIXl=Cv->t0(ar6`FOLS0OPl zoMn&DUkJ2}@IU52L>VR=i+rOlk)A^r4w8g444R=A_L$`t%MIR{x$ z*!n74iZQ49o*J*|E?+{yJpC>&utGy{VMgPN0_q%jm4Ss=KZ{c^TPJc*r+SebJ*~)# zO%YeLW@)fc;ERmO6YHbN2Kt`>cENI_M=zvxQF|iBk7)RhU+<;*cAWiPCJib-iiTyF zB6L&i)DENMj=uA1kY0g_D)$DXlbt3*jf_Ao=LvUsLhLRKeXt=ennppa>O5)1K>(TO zRkM~UX3nJfDb3XIua-QTq#C+ZhOdO5Kz_Ah7l1xlY7eiN3c0@)-+~K+!r&=1{bUiD z01#AtDVNyxRp3i>V0r$r#P5(5=!*=ByDvNng1AH>9u{p#7$f{o9fsZudXiO7ehZ1ksoY%I9!v3MSZ$;CB@z7PYct!*miEJ| zZsu{KVre`4VMo?5%+qa4w~MMY&_8C;voogfVN~i)t?rS_pw_Ap+Zz#A=Kh+++&U|hm_uW6Go11$Yo!6 z7_z3qzUFTi-W-B`U|TB4;&2WIIl?-QBZgGd8dqHLT3i%|{;m&uCJ3m`vf_-XR~&N0 zE*_9!#ZiT-cL|w&qQK;6IZ_9?)82&1;1=J|ce9jm@3r7@0yc4o`?-s}+Q?GKnbl0xn<7Um9}$=OwtvyXOdcQaIVU(8#Me zdI*=6#tkgXmyhPx=c@Z>59t_e1A+1YS@rYtrB8A=M3ikNH8bI(Z{GBk$2nMaR(Chn z$NJJz5UVO4puRWi+t;KM?;Zc7-_e*btNg+rKM4H<{vGTAF<-iVHg`>)4=t#p&6Ul2Wsx{QIKSs$@ooq zh1GMeKK(V6QG&JIogi*`_#uhge>wkXlR%uQw|NEy3Qcsf51d0sIiPhOf& zE$bQEHnqcjQKa94uB1&a@#!0c^TJn2Pq}wYtZY(8g3lstVYeI)S?>d6!FZElyitGS zP1ZGT+=58>uk;Jus%3j4J&8BSm7g955K#Y_Zxj=-YZ>^z##OXswFU=^H^y)^H5^G@ z;N_S{OV?o&SSY8UanbW;<`UPQ<^X|L#d&k^YZ(Jr0IGd$A+5EnjZX99vMB5 zT(hX>&k&0hKX!Vp7a)}hB*FKUMx8DNm`QLN}AH_aOPJg^;b>qFM*@CdHMr& z9+9G+wBE^@irFGJKlks3W4Y~l&XX<~>UfNh9v;u9T#w*K=5HIaA>MvG4ei0|W1s1F z#9BS=!}FA>*D)U|xF=vM>1=*JnTtzGDpC0RA?ks9pm|A7S3v}y0>6A|RNW9#gtGcA ziAuRuy*-)nT#)=goj$qjD_5j)3U5j$b-(}6)*8|m_J^!n;`RIJiwoAR@`bj+G|vky zUkKRu(q1hr3|4Bsf?ppA6>;9qad_Y@92m*%dTnsXJpOlpXTRuN@S;ujoo&jrc5b{UHHYu~9EL?8AHerR^MPk`=YqeSjjI#UI)o!|tB0Koo1> zjG=Lg+g9K{RgRCJLRsw!eoTDT{DJcTZwh}o5%p1Myogti>wNdnDp_zLiF(dRc>QA2Ypf z9$#8E1>SdhB#PVZNxVibU$>Kdc3ZW@)xQnVa_%eOcZo)Kr;=Oq^G9%2{|QbbSFe3V zfWkw_TaC>3wMZSQzVy(($Nr5DA?cOLk>)hGur@Ev4~kqK}d z-a={HH+ zFPC<(Y<=l_VFGN`DM^{ZdDcQqyk{+ieiSTb1}Ju~JXz^V=zL2kPIjcc6LQkOBfn4y z7VwdqxXPX+3RT?wXq{#=oaD%5>z)ItU9O^PZi)T4d8{Em-x&&!U?!_F2PwjGf*Hlr z2~JNWby)91;>Oi#H3QQIR;9KDds>sE4W8UFA*y1H>2yl<_+ati`_OYHH7aV)_z z%_jqMamF^fG4CQnB*DEYw-suF`ouQef9)@Hlkht`SRu?&3G$VcHGCCrkr9~Y}}rVVR_ z*c|G4Cb^O6P>_68hib4FI0neW&i@f{+{PI`VyLo*j~LdwQE5zkX=zTB_=mO^qdbC7 zw|DJTrTsyH@ETk-#{R4tO=C%V3k|)dBlI@*UEhS{)d%In591Bbif?w5ik!TVDmXxe zQ%~I2n8U24@1d?rKY?7cU;`@v29C`CHA%R6klWW){7=U zv8%H=W(Ol;;sr#G9py+w7og`87vX~k^{xXFQ!X2uC|X11nC9Xa_%5;tAa)5knK)V? zNq>_09Qp<(u9L^pSTW+HhgE$4bj+FJ2>@y>MX4Ak2-is40msja)Nmn_#dy2GDRl?9 zD>x1jJ-vD+F|krT-Ow{$4Y%cFw=06Pe@oiA8o(gnb-0{c#9|L&MJ&v#p=NU()B^$) zaJOzP15D^(#-alZz8MUDd(uQK18TmZ^&uZ8YRqzbknn=HooNQ zI-&>S-($4}F%JS1!{^7{6*{mGw;YGz-o?}PECeu2Ddw~P4<~rB|4M}u&N_ecN8M1k VK}Oyne4eIt-1VeO^*85!_z%5|xeNdR diff --git a/docs/db/d04/webvtt__parser_8cc_source.html b/docs/db/d04/webvtt__parser_8cc_source.html index 9db1670728..3ac5b9d5d4 100644 --- a/docs/db/d04/webvtt__parser_8cc_source.html +++ b/docs/db/d04/webvtt__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/webvtt_parser.cc Source File @@ -29,18 +29,21 @@

    Protected Member Functions

    - + +/* @license-end */
    webvtt_parser.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/webvtt/webvtt_parser.h"
    8 
    9 #include <string>
    10 #include <vector>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/string_split.h"
    14 #include "packager/base/strings/string_util.h"
    15 #include "packager/media/base/text_stream_info.h"
    16 #include "packager/media/formats/webvtt/webvtt_timestamp.h"
    17 #include "packager/status_macros.h"
    18 
    19 namespace shaka {
    20 namespace media {
    21 namespace {
    22 const uint64_t kStreamIndex = 0;
    23 
    24 std::string BlockToString(const std::string* block, size_t size) {
    25  std::string out = " --- BLOCK START ---\n";
    26 
    27  for (size_t i = 0; i < size; i++) {
    28  out.append(" ");
    29  out.append(block[i]);
    30  out.append("\n");
    31  }
    32 
    33  out.append(" --- BLOCK END ---");
    34 
    35  return out;
    36 }
    37 
    38 // Comments are just blocks that are preceded by a blank line, start with the
    39 // word "NOTE" (followed by a space or newline), and end at the first blank
    40 // line.
    41 // SOURCE: https://www.w3.org/TR/webvtt1
    42 bool IsLikelyNote(const std::string& line) {
    43  return line == "NOTE" ||
    44  base::StartsWith(line, "NOTE ", base::CompareCase::SENSITIVE) ||
    45  base::StartsWith(line, "NOTE\t", base::CompareCase::SENSITIVE);
    46 }
    47 
    48 // As cue time is the only part of a WEBVTT file that is allowed to have
    49 // "-->" appear, then if the given line contains it, we can safely assume
    50 // that the line is likely to be a cue time.
    51 bool IsLikelyCueTiming(const std::string& line) {
    52  return line.find("-->") != std::string::npos;
    53 }
    54 
    55 // A WebVTT cue identifier is any sequence of one or more characters not
    56 // containing the substring "-->" (U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS,
    57 // U+003E GREATER-THAN SIGN), nor containing any U+000A LINE FEED (LF)
    58 // characters or U+000D CARRIAGE RETURN (CR) characters.
    59 // SOURCE: https://www.w3.org/TR/webvtt1/#webvtt-cue-identifier
    60 bool MaybeCueId(const std::string& line) {
    61  return line.find("-->") == std::string::npos;
    62 }
    63 
    64 // Check to see if the block is likely a style block. Style blocks are
    65 // identified as any block that starts with a line that only contains
    66 // "STYLE".
    67 // SOURCE: https://w3c.github.io/webvtt/#styling
    68 bool IsLikelyStyle(const std::string& line) {
    69  return base::TrimWhitespaceASCII(line, base::TRIM_TRAILING) == "STYLE";
    70 }
    71 
    72 // Check to see if the block is likely a region block. Region blocks are
    73 // identified as any block that starts with a line that only contains
    74 // "REGION".
    75 // SOURCE: https://w3c.github.io/webvtt/#webvtt-region
    76 bool IsLikelyRegion(const std::string& line) {
    77  return base::TrimWhitespaceASCII(line, base::TRIM_TRAILING) == "REGION";
    78 }
    79 
    80 void UpdateConfig(const std::vector<std::string>& block, std::string* config) {
    81  if (!config->empty())
    82  *config += "\n\n";
    83  *config += base::JoinString(block, "\n");
    84 }
    85 
    86 } // namespace
    87 
    88 WebVttParser::WebVttParser(std::unique_ptr<FileReader> source,
    89  const std::string& language)
    90  : reader_(std::move(source)), language_(language) {}
    91 
    92 Status WebVttParser::InitializeInternal() {
    93  return Status::OK;
    94 }
    95 
    96 bool WebVttParser::ValidateOutputStreamIndex(size_t stream_index) const {
    97  // Only support one output
    98  return stream_index == kStreamIndex;
    99 }
    100 
    101 Status WebVttParser::Run() {
    102  return Parse()
    103  ? FlushDownstream(kStreamIndex)
    104  : Status(error::INTERNAL_ERROR,
    105  "Failed to parse WebVTT source. See log for details.");
    106 }
    107 
    108 void WebVttParser::Cancel() {
    109  keep_reading_ = false;
    110 }
    111 
    112 bool WebVttParser::Parse() {
    113  std::vector<std::string> block;
    114  if (!reader_.Next(&block)) {
    115  LOG(ERROR) << "Failed to read WEBVTT HEADER - No blocks in source.";
    116  return false;
    117  }
    118 
    119  // Check the header. It is possible for a 0xFEFF BOM to come before the
    120  // header text.
    121  if (block.size() != 1) {
    122  LOG(ERROR) << "Failed to read WEBVTT header - "
    123  << "block size should be 1 but was " << block.size() << ".";
    124  return false;
    125  }
    126  if (block[0] != "WEBVTT" && block[0] != "\xEF\xBB\xBFWEBVTT") {
    127  LOG(ERROR) << "Failed to read WEBVTT header - should be WEBVTT but was "
    128  << block[0];
    129  return false;
    130  }
    131 
    132  bool saw_cue = false;
    133 
    134  while (reader_.Next(&block) && keep_reading_) {
    135  // NOTE
    136  if (IsLikelyNote(block[0])) {
    137  // We can safely ignore the whole block.
    138  continue;
    139  }
    140 
    141  // STYLE
    142  if (IsLikelyStyle(block[0])) {
    143  if (saw_cue) {
    144  LOG(WARNING)
    145  << "Found style block after seeing cue. Ignoring style block";
    146  } else {
    147  UpdateConfig(block, &style_region_config_);
    148  }
    149  continue;
    150  }
    151 
    152  // REGION
    153  if (IsLikelyRegion(block[0])) {
    154  if (saw_cue) {
    155  LOG(WARNING)
    156  << "Found region block after seeing cue. Ignoring region block";
    157  } else {
    158  UpdateConfig(block, &style_region_config_);
    159  }
    160  continue;
    161  }
    162 
    163  // CUE with ID
    164  if (block.size() >= 2 && MaybeCueId(block[0]) &&
    165  IsLikelyCueTiming(block[1]) && ParseCueWithId(block)) {
    166  saw_cue = true;
    167  continue;
    168  }
    169 
    170  // CUE with no ID
    171  if (IsLikelyCueTiming(block[0]) && ParseCueWithNoId(block)) {
    172  saw_cue = true;
    173  continue;
    174  }
    175 
    176  LOG(ERROR) << "Failed to determine block classification:\n"
    177  << BlockToString(block.data(), block.size());
    178  return false;
    179  }
    180 
    181  return keep_reading_;
    182 }
    183 
    184 bool WebVttParser::ParseCueWithNoId(const std::vector<std::string>& block) {
    185  const Status status = ParseCue("", block.data(), block.size());
    186 
    187  if (!status.ok()) {
    188  LOG(ERROR) << "Failed to parse cue: " << status.error_message();
    189  }
    190 
    191  return status.ok();
    192 }
    193 
    194 bool WebVttParser::ParseCueWithId(const std::vector<std::string>& block) {
    195  const Status status = ParseCue(block[0], block.data() + 1, block.size() - 1);
    196 
    197  if (!status.ok()) {
    198  LOG(ERROR) << "Failed to parse cue: " << status.error_message();
    199  }
    200 
    201  return status.ok();
    202 }
    203 
    204 Status WebVttParser::ParseCue(const std::string& id,
    205  const std::string* block,
    206  size_t block_size) {
    207  const std::vector<std::string> time_and_style = base::SplitString(
    208  block[0], " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    209 
    210  uint64_t start_time = 0;
    211  uint64_t end_time = 0;
    212 
    213  const bool parsed_time =
    214  time_and_style.size() >= 3 && time_and_style[1] == "-->" &&
    215  WebVttTimestampToMs(time_and_style[0], &start_time) &&
    216  WebVttTimestampToMs(time_and_style[2], &end_time);
    217 
    218  if (!parsed_time) {
    219  return Status(
    220  error::INTERNAL_ERROR,
    221  "Could not parse start time, -->, and end time from " + block[0]);
    222  }
    223 
    224  if (!stream_info_dispatched_)
    225  RETURN_IF_ERROR(DispatchTextStreamInfo());
    226 
    227  // According to the WebVTT spec end time must be greater than the start time
    228  // of the cue. Since we are seeing content with invalid times in the field, we
    229  // are going to drop the cue instead of failing to package.
    230  //
    231  // For more context see:
    232  // - https://www.w3.org/TR/webvtt1/#webvtt-cue-timings
    233  // - https://github.com/google/shaka-packager/issues/335
    234  // - https://github.com/google/shaka-packager/issues/425
    235  //
    236  // Print a warning so that those packaging content can know that their
    237  // content is not spec compliant.
    238  if (end_time <= start_time) {
    239  LOG(WARNING) << "WebVTT input is not spec compliant. Start time ("
    240  << start_time << ") should be less than end time (" << end_time
    241  << "). Skipping webvtt cue:"
    242  << BlockToString(block, block_size);
    243 
    244  return Status::OK;
    245  }
    246 
    247  std::shared_ptr<TextSample> sample = std::make_shared<TextSample>();
    248  sample->set_id(id);
    249  sample->SetTime(start_time, end_time);
    250 
    251  // The rest of time_and_style are the style tokens.
    252  for (size_t i = 3; i < time_and_style.size(); i++) {
    253  sample->AppendStyle(time_and_style[i]);
    254  }
    255 
    256  // The rest of the block is the payload.
    257  for (size_t i = 1; i < block_size; i++) {
    258  sample->AppendPayload(block[i]);
    259  }
    260 
    261  return DispatchTextSample(kStreamIndex, sample);
    262 }
    263 
    264 Status WebVttParser::DispatchTextStreamInfo() {
    265  stream_info_dispatched_ = true;
    266 
    267  const int kTrackId = 0;
    268  // The resolution of timings are in milliseconds.
    269  const int kTimescale = 1000;
    270  // The duration passed here is not very important. Also the whole file
    271  // must be read before determining the real duration which doesn't
    272  // work nicely with the current demuxer.
    273  const int kDuration = 0;
    274  const char kWebVttCodecString[] = "wvtt";
    275  const int64_t kNoWidth = 0;
    276  const int64_t kNoHeight = 0;
    277 
    278  std::shared_ptr<StreamInfo> info = std::make_shared<TextStreamInfo>(
    279  kTrackId, kTimescale, kDuration, kCodecWebVtt, kWebVttCodecString,
    280  style_region_config_, kNoWidth, kNoHeight, language_);
    281 
    282  return DispatchStreamInfo(kStreamIndex, std::move(info));
    283 }
    284 } // namespace media
    285 } // namespace shaka
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webvtt/webvtt_parser.h"
    +
    8 
    +
    9 #include <regex>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/base/strings/string_number_conversions.h"
    +
    13 #include "packager/base/strings/string_split.h"
    +
    14 #include "packager/base/strings/string_util.h"
    +
    15 #include "packager/media/base/text_stream_info.h"
    +
    16 #include "packager/media/formats/webvtt/webvtt_utils.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 namespace {
    +
    21 
    +
    22 const uint64_t kStreamIndex = 0;
    +
    23 
    +
    24 std::string BlockToString(const std::string* block, size_t size) {
    +
    25  std::string out = " --- BLOCK START ---\n";
    +
    26 
    +
    27  for (size_t i = 0; i < size; i++) {
    +
    28  out.append(" ");
    +
    29  out.append(block[i]);
    +
    30  out.append("\n");
    +
    31  }
    +
    32 
    +
    33  out.append(" --- BLOCK END ---");
    +
    34 
    +
    35  return out;
    +
    36 }
    +
    37 
    +
    38 // Comments are just blocks that are preceded by a blank line, start with the
    +
    39 // word "NOTE" (followed by a space or newline), and end at the first blank
    +
    40 // line.
    +
    41 // SOURCE: https://www.w3.org/TR/webvtt1
    +
    42 bool IsLikelyNote(const std::string& line) {
    +
    43  return line == "NOTE" ||
    +
    44  base::StartsWith(line, "NOTE ", base::CompareCase::SENSITIVE) ||
    +
    45  base::StartsWith(line, "NOTE\t", base::CompareCase::SENSITIVE);
    +
    46 }
    +
    47 
    +
    48 // As cue time is the only part of a WEBVTT file that is allowed to have
    +
    49 // "-->" appear, then if the given line contains it, we can safely assume
    +
    50 // that the line is likely to be a cue time.
    +
    51 bool IsLikelyCueTiming(const std::string& line) {
    +
    52  return line.find("-->") != std::string::npos;
    +
    53 }
    +
    54 
    +
    55 // A WebVTT cue identifier is any sequence of one or more characters not
    +
    56 // containing the substring "-->" (U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS,
    +
    57 // U+003E GREATER-THAN SIGN), nor containing any U+000A LINE FEED (LF)
    +
    58 // characters or U+000D CARRIAGE RETURN (CR) characters.
    +
    59 // SOURCE: https://www.w3.org/TR/webvtt1/#webvtt-cue-identifier
    +
    60 bool MaybeCueId(const std::string& line) {
    +
    61  return line.find("-->") == std::string::npos;
    +
    62 }
    +
    63 
    +
    64 // Check to see if the block is likely a style block. Style blocks are
    +
    65 // identified as any block that starts with a line that only contains
    +
    66 // "STYLE".
    +
    67 // SOURCE: https://w3c.github.io/webvtt/#styling
    +
    68 bool IsLikelyStyle(const std::string& line) {
    +
    69  return base::TrimWhitespaceASCII(line, base::TRIM_TRAILING) == "STYLE";
    +
    70 }
    +
    71 
    +
    72 // Check to see if the block is likely a region block. Region blocks are
    +
    73 // identified as any block that starts with a line that only contains
    +
    74 // "REGION".
    +
    75 // SOURCE: https://w3c.github.io/webvtt/#webvtt-region
    +
    76 bool IsLikelyRegion(const std::string& line) {
    +
    77  return base::TrimWhitespaceASCII(line, base::TRIM_TRAILING) == "REGION";
    +
    78 }
    +
    79 
    +
    80 bool ParsePercent(const std::string& str, float* value) {
    +
    81  // https://www.w3.org/TR/webvtt1/#webvtt-percentage
    +
    82  // E.g. "4%" or "1.5%"
    +
    83  std::regex re(R"((\d+(?:\.\d+)?)%)");
    +
    84  std::smatch match;
    +
    85  if (!std::regex_match(str, match, re)) {
    +
    86  return false;
    +
    87  }
    +
    88 
    +
    89  double temp;
    +
    90  base::StringToDouble(match[1], &temp);
    +
    91  if (temp >= 100) {
    +
    92  return false;
    +
    93  }
    +
    94  *value = temp;
    +
    95  return true;
    +
    96 }
    +
    97 
    +
    98 bool ParseDoublePercent(const std::string& str, float* a, float* b) {
    +
    99  std::regex re(R"((\d+(?:\.\d+)?)%,(\d+(?:\.\d+)?)%)");
    +
    100  std::smatch match;
    +
    101  if (!std::regex_match(str, match, re)) {
    +
    102  return false;
    +
    103  }
    +
    104 
    +
    105  double tempA, tempB;
    +
    106  base::StringToDouble(match[1], &tempA);
    +
    107  base::StringToDouble(match[2], &tempB);
    +
    108  if (tempA >= 100 || tempB >= 100) {
    +
    109  return false;
    +
    110  }
    +
    111  *a = tempA;
    +
    112  *b = tempB;
    +
    113  return true;
    +
    114 }
    +
    115 
    +
    116 void ParseSettings(const std::string& id,
    +
    117  const std::string& value,
    +
    118  TextSettings* settings) {
    +
    119  // https://www.w3.org/TR/webvtt1/#ref-for-parse-the-webvtt-cue-settings-1
    +
    120  if (id == "region") {
    +
    121  settings->region = value;
    +
    122  } else if (id == "vertical") {
    +
    123  if (value == "rl") {
    +
    124  settings->writing_direction = WritingDirection::kVerticalGrowingLeft;
    +
    125  } else if (value == "lr") {
    +
    126  settings->writing_direction = WritingDirection::kVerticalGrowingRight;
    +
    127  } else {
    +
    128  LOG(WARNING) << "Invalid WebVTT vertical setting: " << value;
    +
    129  }
    +
    130  } else if (id == "line") {
    +
    131  const auto pos = value.find(',');
    +
    132  const std::string line = value.substr(0, pos);
    +
    133  const std::string align =
    +
    134  pos != std::string::npos ? value.substr(pos + 1) : "";
    +
    135  if (pos != std::string::npos) {
    +
    136  LOG(WARNING) << "WebVTT line alignment isn't supported";
    +
    137  }
    +
    138 
    +
    139  if (!line.empty() && line[line.size() - 1] == '%') {
    +
    140  float temp;
    +
    141  if (!ParsePercent(line, &temp)) {
    +
    142  LOG(WARNING) << "Invalid WebVTT line: " << value;
    +
    143  return;
    +
    144  }
    +
    145  settings->line.emplace(temp, TextUnitType::kPercent);
    +
    146  } else {
    +
    147  double temp;
    +
    148  if (!base::StringToDouble(line, &temp)) {
    +
    149  LOG(WARNING) << "Invalid WebVTT line: " << value;
    +
    150  return;
    +
    151  }
    +
    152  settings->line.emplace(temp, TextUnitType::kLines);
    +
    153  }
    +
    154  } else if (id == "position") {
    +
    155  const auto pos = value.find(',');
    +
    156  const std::string position = value.substr(0, pos);
    +
    157  const std::string align =
    +
    158  pos != std::string::npos ? value.substr(pos + 1) : "";
    +
    159  if (pos != std::string::npos) {
    +
    160  LOG(WARNING) << "WebVTT position alignment isn't supported";
    +
    161  }
    +
    162 
    +
    163  float temp;
    +
    164  if (ParsePercent(position, &temp)) {
    +
    165  settings->position.emplace(temp, TextUnitType::kPercent);
    +
    166  } else {
    +
    167  LOG(WARNING) << "Invalid WebVTT position: " << value;
    +
    168  }
    +
    169  } else if (id == "size") {
    +
    170  float temp;
    +
    171  if (ParsePercent(value, &temp)) {
    +
    172  settings->width.emplace(temp, TextUnitType::kPercent);
    +
    173  } else {
    +
    174  LOG(WARNING) << "Invalid WebVTT size: " << value;
    +
    175  }
    +
    176  } else if (id == "align") {
    +
    177  if (value == "start") {
    +
    178  settings->text_alignment = TextAlignment::kStart;
    +
    179  } else if (value == "center" || value == "middle") {
    +
    180  settings->text_alignment = TextAlignment::kCenter;
    +
    181  } else if (value == "end") {
    +
    182  settings->text_alignment = TextAlignment::kEnd;
    +
    183  } else if (value == "left") {
    +
    184  settings->text_alignment = TextAlignment::kLeft;
    +
    185  } else if (value == "right") {
    +
    186  settings->text_alignment = TextAlignment::kRight;
    +
    187  } else {
    +
    188  LOG(WARNING) << "Invalid WebVTT align: " << value;
    +
    189  }
    +
    190  } else {
    +
    191  LOG(WARNING) << "Unknown WebVTT setting: " << id;
    +
    192  }
    +
    193 }
    +
    194 
    +
    195 } // namespace
    +
    196 
    +
    197 WebVttParser::WebVttParser() {}
    +
    198 
    +
    199 void WebVttParser::Init(const InitCB& init_cb,
    +
    200  const NewMediaSampleCB& new_media_sample_cb,
    +
    201  const NewTextSampleCB& new_text_sample_cb,
    +
    202  KeySource* decryption_key_source) {
    +
    203  DCHECK(init_cb_.is_null());
    +
    204  DCHECK(!init_cb.is_null());
    +
    205  DCHECK(!new_text_sample_cb.is_null());
    +
    206  DCHECK(!decryption_key_source) << "Encrypted WebVTT not supported";
    +
    207 
    +
    208  init_cb_ = init_cb;
    +
    209  new_text_sample_cb_ = new_text_sample_cb;
    +
    210 }
    +
    211 
    + +
    213  reader_.Flush();
    +
    214  return Parse();
    +
    215 }
    +
    216 
    +
    217 bool WebVttParser::Parse(const uint8_t* buf, int size) {
    +
    218  reader_.PushData(buf, size);
    +
    219  return Parse();
    +
    220 }
    +
    221 
    +
    222 bool WebVttParser::Parse() {
    +
    223  if (!initialized_) {
    +
    224  std::vector<std::string> block;
    +
    225  if (!reader_.Next(&block)) {
    +
    226  return true;
    +
    227  }
    +
    228 
    +
    229  // Check the header. It is possible for a 0xFEFF BOM to come before the
    +
    230  // header text.
    +
    231  if (block.size() != 1) {
    +
    232  LOG(ERROR) << "Failed to read WEBVTT header - "
    +
    233  << "block size should be 1 but was " << block.size() << ".";
    +
    234  return false;
    +
    235  }
    +
    236  if (block[0] != "WEBVTT" && block[0] != "\xEF\xBB\xBFWEBVTT") {
    +
    237  LOG(ERROR) << "Failed to read WEBVTT header - should be WEBVTT but was "
    +
    238  << block[0];
    +
    239  return false;
    +
    240  }
    +
    241  initialized_ = true;
    +
    242  }
    +
    243 
    +
    244  std::vector<std::string> block;
    +
    245  while (reader_.Next(&block)) {
    +
    246  if (!ParseBlock(block))
    +
    247  return false;
    +
    248  }
    +
    249  return true;
    +
    250 }
    +
    251 
    +
    252 bool WebVttParser::ParseBlock(const std::vector<std::string>& block) {
    +
    253  // NOTE
    +
    254  if (IsLikelyNote(block[0])) {
    +
    255  // We can safely ignore the whole block.
    +
    256  return true;
    +
    257  }
    +
    258 
    +
    259  // STYLE
    +
    260  if (IsLikelyStyle(block[0])) {
    +
    261  if (saw_cue_) {
    +
    262  LOG(WARNING)
    +
    263  << "Found style block after seeing cue. Ignoring style block";
    +
    264  } else {
    +
    265  for (size_t i = 1; i < block.size(); i++) {
    +
    266  if (!css_styles_.empty())
    +
    267  css_styles_ += "\n";
    +
    268  css_styles_ += block[i];
    +
    269  }
    +
    270  }
    +
    271  return true;
    +
    272  }
    +
    273 
    +
    274  // REGION
    +
    275  if (IsLikelyRegion(block[0])) {
    +
    276  if (saw_cue_) {
    +
    277  LOG(WARNING)
    +
    278  << "Found region block after seeing cue. Ignoring region block";
    +
    279  return true;
    +
    280  } else {
    +
    281  return ParseRegion(block);
    +
    282  }
    +
    283  }
    +
    284 
    +
    285  // CUE with ID
    +
    286  if (block.size() >= 2 && MaybeCueId(block[0]) &&
    +
    287  IsLikelyCueTiming(block[1]) && ParseCueWithId(block)) {
    +
    288  saw_cue_ = true;
    +
    289  return true;
    +
    290  }
    +
    291 
    +
    292  // CUE with no ID
    +
    293  if (IsLikelyCueTiming(block[0]) && ParseCueWithNoId(block)) {
    +
    294  saw_cue_ = true;
    +
    295  return true;
    +
    296  }
    +
    297 
    +
    298  LOG(ERROR) << "Failed to determine block classification:\n"
    +
    299  << BlockToString(block.data(), block.size());
    +
    300  return false;
    +
    301 }
    +
    302 
    +
    303 bool WebVttParser::ParseRegion(const std::vector<std::string>& block) {
    +
    304  TextRegion region;
    +
    305  std::string region_id;
    +
    306  // Fill in defaults. Some may already be this, but set them anyway.
    +
    307  // See https://www.w3.org/TR/webvtt1/#regions
    +
    308  region.width.value = 100;
    +
    309  region.width.type = TextUnitType::kPercent;
    +
    310  region.height.value = 3;
    +
    311  region.height.type = TextUnitType::kLines;
    +
    312  region.window_anchor_x.value = 0;
    +
    313  region.window_anchor_x.type = TextUnitType::kPercent;
    +
    314  region.window_anchor_y.value = 100;
    +
    315  region.window_anchor_y.type = TextUnitType::kPercent;
    +
    316  region.region_anchor_x.value = 0;
    +
    317  region.region_anchor_x.type = TextUnitType::kPercent;
    +
    318  region.region_anchor_y.value = 100;
    +
    319  region.region_anchor_y.type = TextUnitType::kPercent;
    +
    320 
    +
    321  bool first = true;
    +
    322  for (const auto& line : block) {
    +
    323  // First line is "REGION", skip.
    +
    324  if (first) {
    +
    325  first = false;
    +
    326  continue;
    +
    327  }
    +
    328 
    +
    329  base::StringPairs pairs;
    +
    330  if (!base::SplitStringIntoKeyValuePairs(line, ':', ' ', &pairs)) {
    +
    331  LOG(ERROR) << "Invalid WebVTT settings: " << line;
    +
    332  return false;
    +
    333  }
    +
    334  for (const auto& pair : pairs) {
    +
    335  const std::string& value = pair.second;
    +
    336  if (pair.first == "id") {
    +
    337  if (value.find("-->") != std::string::npos) {
    +
    338  LOG(ERROR) << "Invalid WebVTT REGION ID: " << value;
    +
    339  return false;
    +
    340  }
    +
    341  if (regions_.find(value) != regions_.end()) {
    +
    342  LOG(ERROR) << "Duplicate WebVTT REGION: " << value;
    +
    343  return false;
    +
    344  }
    +
    345  region_id = value;
    +
    346  } else if (pair.first == "width") {
    +
    347  if (!ParsePercent(value, &region.width.value)) {
    +
    348  LOG(ERROR) << "Invalid WebVTT REGION width: " << value;
    +
    349  return false;
    +
    350  }
    +
    351  } else if (pair.first == "lines") {
    +
    352  unsigned int temp;
    +
    353  if (!base::StringToUint(value, &temp)) {
    +
    354  LOG(ERROR) << "Invalid WebVTT REGION lines: " << value;
    +
    355  return false;
    +
    356  }
    +
    357  region.height.value = temp;
    +
    358  } else if (pair.first == "regionanchor") {
    +
    359  if (!ParseDoublePercent(value, &region.region_anchor_x.value,
    +
    360  &region.region_anchor_y.value)) {
    +
    361  LOG(ERROR) << "Invalid WebVTT REGION regionanchor: " << value;
    +
    362  return false;
    +
    363  }
    +
    364  } else if (pair.first == "viewportanchor") {
    +
    365  if (!ParseDoublePercent(value, &region.window_anchor_x.value,
    +
    366  &region.window_anchor_y.value)) {
    +
    367  LOG(ERROR) << "Invalid WebVTT REGION windowanchor: " << value;
    +
    368  return false;
    +
    369  }
    +
    370  } else if (pair.first == "scroll") {
    +
    371  if (value != "up") {
    +
    372  LOG(ERROR) << "Invalid WebVTT REGION scroll: " << value;
    +
    373  return false;
    +
    374  }
    +
    375  region.scroll = true;
    +
    376  } else {
    +
    377  LOG(ERROR) << "Unknown WebVTT REGION setting: " << pair.first;
    +
    378  return false;
    +
    379  }
    +
    380  }
    +
    381  }
    +
    382  if (region_id.empty()) {
    +
    383  LOG(ERROR) << "WebVTT REGION id is required";
    +
    384  return false;
    +
    385  }
    +
    386  regions_.insert(std::make_pair(region_id, std::move(region)));
    +
    387  return true;
    +
    388 }
    +
    389 
    +
    390 bool WebVttParser::ParseCueWithNoId(const std::vector<std::string>& block) {
    +
    391  return ParseCue("", block.data(), block.size());
    +
    392 }
    +
    393 
    +
    394 bool WebVttParser::ParseCueWithId(const std::vector<std::string>& block) {
    +
    395  return ParseCue(block[0], block.data() + 1, block.size() - 1);
    +
    396 }
    +
    397 
    +
    398 bool WebVttParser::ParseCue(const std::string& id,
    +
    399  const std::string* block,
    +
    400  size_t block_size) {
    +
    401  const std::vector<std::string> time_and_style = base::SplitString(
    +
    402  block[0], " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    +
    403 
    +
    404  uint64_t start_time = 0;
    +
    405  uint64_t end_time = 0;
    +
    406 
    +
    407  const bool parsed_time =
    +
    408  time_and_style.size() >= 3 && time_and_style[1] == "-->" &&
    +
    409  WebVttTimestampToMs(time_and_style[0], &start_time) &&
    +
    410  WebVttTimestampToMs(time_and_style[2], &end_time);
    +
    411 
    +
    412  if (!parsed_time) {
    +
    413  LOG(ERROR) << "Could not parse start time, -->, and end time from "
    +
    414  << block[0];
    +
    415  return false;
    +
    416  }
    +
    417 
    +
    418  if (!stream_info_dispatched_)
    +
    419  DispatchTextStreamInfo();
    +
    420 
    +
    421  // According to the WebVTT spec end time must be greater than the start time
    +
    422  // of the cue. Since we are seeing content with invalid times in the field, we
    +
    423  // are going to drop the cue instead of failing to package.
    +
    424  //
    +
    425  // For more context see:
    +
    426  // - https://www.w3.org/TR/webvtt1/#webvtt-cue-timings
    +
    427  // - https://github.com/google/shaka-packager/issues/335
    +
    428  // - https://github.com/google/shaka-packager/issues/425
    +
    429  //
    +
    430  // Print a warning so that those packaging content can know that their
    +
    431  // content is not spec compliant.
    +
    432  if (end_time <= start_time) {
    +
    433  LOG(WARNING) << "WebVTT input is not spec compliant. Start time ("
    +
    434  << start_time << ") should be less than end time (" << end_time
    +
    435  << "). Skipping webvtt cue:"
    +
    436  << BlockToString(block, block_size);
    +
    437  return true;
    +
    438  }
    +
    439 
    +
    440  TextSettings settings;
    +
    441  for (size_t i = 3; i < time_and_style.size(); i++) {
    +
    442  const auto pos = time_and_style[i].find(':');
    +
    443  if (pos == std::string::npos) {
    +
    444  continue;
    +
    445  }
    +
    446 
    +
    447  const std::string key = time_and_style[i].substr(0, pos);
    +
    448  const std::string value = time_and_style[i].substr(pos + 1);
    +
    449  ParseSettings(key, value, &settings);
    +
    450  }
    +
    451 
    +
    452  // The rest of the block is the payload.
    +
    453  // TODO: Parse tags to support <b>, <i>, etc.
    +
    454  TextFragment body;
    +
    455  TextFragmentStyle no_styles;
    +
    456  for (size_t i = 1; i < block_size; i++) {
    +
    457  if (i > 1) {
    +
    458  body.sub_fragments.emplace_back(no_styles, /* newline= */ true);
    +
    459  }
    +
    460  body.sub_fragments.emplace_back(no_styles, block[i]);
    +
    461  }
    +
    462 
    +
    463  const auto sample =
    +
    464  std::make_shared<TextSample>(id, start_time, end_time, settings, body);
    +
    465  return new_text_sample_cb_.Run(kStreamIndex, sample);
    +
    466 }
    +
    467 
    +
    468 void WebVttParser::DispatchTextStreamInfo() {
    +
    469  stream_info_dispatched_ = true;
    +
    470 
    +
    471  const int kTrackId = 0;
    +
    472  // The resolution of timings are in milliseconds.
    +
    473  const int kTimescale = 1000;
    +
    474  // The duration passed here is not very important. Also the whole file
    +
    475  // must be read before determining the real duration which doesn't
    +
    476  // work nicely with the current demuxer.
    +
    477  const int kDuration = 0;
    +
    478  const char kWebVttCodecString[] = "wvtt";
    +
    479  const int64_t kNoWidth = 0;
    +
    480  const int64_t kNoHeight = 0;
    +
    481  // The language of the stream will be overwritten by the Demuxer later.
    +
    482  const char kNoLanguage[] = "";
    +
    483 
    +
    484  const auto stream = std::make_shared<TextStreamInfo>(
    +
    485  kTrackId, kTimescale, kDuration, kCodecWebVtt, kWebVttCodecString, "",
    +
    486  kNoWidth, kNoHeight, kNoLanguage);
    +
    487  stream->set_css_styles(css_styles_);
    +
    488  for (const auto& pair : regions_)
    +
    489  stream->AddRegion(pair.first, pair.second);
    +
    490 
    +
    491  std::vector<std::shared_ptr<StreamInfo>> streams{stream};
    +
    492  init_cb_.Run(streams);
    +
    493 }
    +
    494 
    +
    495 } // namespace media
    +
    496 } // namespace shaka
    +
    void PushData(const uint8_t *data, size_t data_size)
    Pushes data onto the end of the buffer.
    Definition: text_readers.cc:73
    + +
    bool Next(std::vector< std::string > *out)
    Definition: text_readers.cc:78
    +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
    Definition: media_parser.h:53
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    + +
    void Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
    +
    bool Parse(const uint8_t *buf, int size) override
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/d05/structshaka_1_1media_1_1H265SliceHeader.html b/docs/db/d05/structshaka_1_1media_1_1H265SliceHeader.html index 3ede70ea09..ea1a38732c 100644 --- a/docs/db/d05/structshaka_1_1media_1_1H265SliceHeader.html +++ b/docs/db/d05/structshaka_1_1media_1_1H265SliceHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265SliceHeader Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    e
    diff --git a/docs/db/d11/structshaka_1_1media_1_1mp4_1_1CodecConfiguration.html b/docs/db/d11/structshaka_1_1media_1_1mp4_1_1CodecConfiguration.html index e473d8a520..d72dbfe8d4 100644 --- a/docs/db/d11/structshaka_1_1media_1_1mp4_1_1CodecConfiguration.html +++ b/docs/db/d11/structshaka_1_1media_1_1mp4_1_1CodecConfiguration.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CodecConfiguration Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -115,7 +118,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 261 of file box_definitions.h.

    +

    Definition at line 262 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -143,7 +146,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1403 of file box_definitions.cc.

    +

    Definition at line 1429 of file box_definitions.cc.

    @@ -154,9 +157,7 @@ Additional Inherited Members diff --git a/docs/db/d13/classshaka_1_1media_1_1DvbImageBuilder-members.html b/docs/db/d13/classshaka_1_1media_1_1DvbImageBuilder-members.html new file mode 100644 index 0000000000..4b54b90ac7 --- /dev/null +++ b/docs/db/d13/classshaka_1_1media_1_1DvbImageBuilder-members.html @@ -0,0 +1,91 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::DvbImageBuilder Member List
    +
    +
    + +

    This is the complete list of members for shaka::media::DvbImageBuilder, including all inherited members.

    + + + + + + + + + + + +
    AddPixel(BitDepth bit_depth, uint8_t byte_code, bool is_top_rows) (defined in shaka::media::DvbImageBuilder)shaka::media::DvbImageBuilder
    DvbImageBuilder(const DvbImageColorSpace *color_space, const RgbaColor &default_color, uint16_t max_width, uint16_t max_height) (defined in shaka::media::DvbImageBuilder)shaka::media::DvbImageBuilder
    DvbImageBuilder(const DvbImageBuilder &)=delete (defined in shaka::media::DvbImageBuilder)shaka::media::DvbImageBuilder
    GetPixels(const RgbaColor **pixels, uint16_t *width, uint16_t *height) constshaka::media::DvbImageBuilder
    max_height() const (defined in shaka::media::DvbImageBuilder)shaka::media::DvbImageBuilderinline
    max_width() const (defined in shaka::media::DvbImageBuilder)shaka::media::DvbImageBuilderinline
    MirrorToBottomRows()shaka::media::DvbImageBuilder
    NewRow(bool is_top_rows) (defined in shaka::media::DvbImageBuilder)shaka::media::DvbImageBuilder
    operator=(const DvbImageBuilder &)=delete (defined in shaka::media::DvbImageBuilder)shaka::media::DvbImageBuilder
    ~DvbImageBuilder() (defined in shaka::media::DvbImageBuilder)shaka::media::DvbImageBuilder
    + + + + diff --git a/docs/db/d14/classshaka_1_1media_1_1H265Parser-members.html b/docs/db/d14/classshaka_1_1media_1_1H265Parser-members.html index 4dc457614d..0e176c660a 100644 --- a/docs/db/d14/classshaka_1_1media_1_1H265Parser-members.html +++ b/docs/db/d14/classshaka_1_1media_1_1H265Parser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/db/d14/structshaka_1_1media_1_1H264WeightingFactors-members.html b/docs/db/d14/structshaka_1_1media_1_1H264WeightingFactors-members.html index 99f0627687..d5f2b6740b 100644 --- a/docs/db/d14/structshaka_1_1media_1_1H264WeightingFactors-members.html +++ b/docs/db/d14/structshaka_1_1media_1_1H264WeightingFactors-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/db/d19/ttml__generator_8cc_source.html b/docs/db/d19/ttml__generator_8cc_source.html new file mode 100644 index 0000000000..3a01f4a427 --- /dev/null +++ b/docs/db/d19/ttml__generator_8cc_source.html @@ -0,0 +1,319 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/ttml/ttml_generator.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    ttml_generator.cc
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/ttml/ttml_generator.h"
    +
    8 
    +
    9 #include "packager/base/base64.h"
    +
    10 #include "packager/base/strings/stringprintf.h"
    +
    11 #include "packager/media/base/rcheck.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace ttml {
    +
    16 
    +
    17 namespace {
    +
    18 
    +
    19 constexpr const char* kRegionIdPrefix = "_shaka_region_";
    +
    20 
    +
    21 std::string ToTtmlTime(int64_t time, uint32_t timescale) {
    +
    22  int64_t remaining = time * 1000 / timescale;
    +
    23 
    +
    24  const int ms = remaining % 1000;
    +
    25  remaining /= 1000;
    +
    26  const int sec = remaining % 60;
    +
    27  remaining /= 60;
    +
    28  const int min = remaining % 60;
    +
    29  remaining /= 60;
    +
    30  const int hr = remaining;
    +
    31 
    +
    32  return base::StringPrintf("%02d:%02d:%02d.%02d", hr, min, sec, ms);
    +
    33 }
    +
    34 
    +
    35 std::string ToTtmlSize(const TextNumber& x, const TextNumber& y) {
    +
    36  const char* kSuffixMap[] = {"px", "em", "%"};
    +
    37  return base::StringPrintf("%.0f%s %.0f%s", x.value,
    +
    38  kSuffixMap[static_cast<int>(x.type)], y.value,
    +
    39  kSuffixMap[static_cast<int>(y.type)]);
    +
    40 }
    +
    41 
    +
    42 } // namespace
    +
    43 
    +
    44 const char* TtmlGenerator::kTtNamespace = "http://www.w3.org/ns/ttml";
    +
    45 
    +
    46 TtmlGenerator::TtmlGenerator() {}
    +
    47 
    +
    48 TtmlGenerator::~TtmlGenerator() {}
    +
    49 
    +
    50 void TtmlGenerator::Initialize(const std::map<std::string, TextRegion>& regions,
    +
    51  const std::string& language,
    +
    52  uint32_t time_scale) {
    +
    53  regions_ = regions;
    +
    54  language_ = language;
    +
    55  time_scale_ = time_scale;
    +
    56 }
    +
    57 
    +
    58 void TtmlGenerator::AddSample(const TextSample& sample) {
    +
    59  samples_.emplace_back(sample);
    +
    60 }
    +
    61 
    +
    62 void TtmlGenerator::Reset() {
    +
    63  samples_.clear();
    +
    64 }
    +
    65 
    +
    66 bool TtmlGenerator::Dump(std::string* result) const {
    +
    67  xml::XmlNode root("tt");
    +
    68  RCHECK(root.SetStringAttribute("xmlns", kTtNamespace));
    +
    69  RCHECK(root.SetStringAttribute("xmlns:tts",
    +
    70  "http://www.w3.org/ns/ttml#styling"));
    +
    71 
    +
    72  bool did_log = false;
    +
    73  xml::XmlNode head("head");
    +
    74  RCHECK(root.SetStringAttribute("xml:lang", language_));
    +
    75  for (const auto& pair : regions_) {
    +
    76  if (!did_log && (pair.second.region_anchor_x.value != 0 &&
    +
    77  pair.second.region_anchor_y.value != 0)) {
    +
    78  LOG(WARNING) << "TTML doesn't support non-0 region anchor";
    +
    79  did_log = true;
    +
    80  }
    +
    81 
    +
    82  xml::XmlNode region("region");
    +
    83  const auto origin =
    +
    84  ToTtmlSize(pair.second.window_anchor_x, pair.second.window_anchor_y);
    +
    85  const auto extent = ToTtmlSize(pair.second.width, pair.second.height);
    +
    86  RCHECK(region.SetStringAttribute("xml:id", pair.first));
    +
    87  RCHECK(region.SetStringAttribute("tts:origin", origin));
    +
    88  RCHECK(region.SetStringAttribute("tts:extent", extent));
    +
    89  RCHECK(head.AddChild(std::move(region)));
    +
    90  }
    +
    91  RCHECK(root.AddChild(std::move(head)));
    +
    92 
    +
    93  size_t image_count = 0;
    +
    94  xml::XmlNode metadata("metadata");
    +
    95  xml::XmlNode body("body");
    +
    96  xml::XmlNode div("div");
    +
    97  for (const auto& sample : samples_) {
    +
    98  RCHECK(AddSampleToXml(sample, &div, &metadata, &image_count));
    +
    99  }
    +
    100  RCHECK(body.AddChild(std::move(div)));
    +
    101  if (image_count > 0) {
    +
    102  RCHECK(root.SetStringAttribute(
    +
    103  "xmlns:smpte", "http://www.smpte-ra.org/schemas/2052-1/2010/smpte-tt"));
    +
    104  RCHECK(root.AddChild(std::move(metadata)));
    +
    105  }
    +
    106  RCHECK(root.AddChild(std::move(body)));
    +
    107 
    +
    108  *result = root.ToString(/* comment= */ "");
    +
    109  return true;
    +
    110 }
    +
    111 
    +
    112 bool TtmlGenerator::AddSampleToXml(const TextSample& sample,
    +
    113  xml::XmlNode* body,
    +
    114  xml::XmlNode* metadata,
    +
    115  size_t* image_count) const {
    +
    116  xml::XmlNode p("p");
    +
    117  RCHECK(p.SetStringAttribute("xml:space", "preserve"));
    +
    118  RCHECK(p.SetStringAttribute("begin",
    +
    119  ToTtmlTime(sample.start_time(), time_scale_)));
    +
    120  RCHECK(
    +
    121  p.SetStringAttribute("end", ToTtmlTime(sample.EndTime(), time_scale_)));
    +
    122  RCHECK(ConvertFragmentToXml(sample.body(), &p, metadata, image_count));
    +
    123  if (!sample.id().empty())
    +
    124  RCHECK(p.SetStringAttribute("xml:id", sample.id()));
    +
    125 
    +
    126  const auto& settings = sample.settings();
    +
    127  if (settings.line || settings.position || settings.width || settings.height) {
    +
    128  // TTML positioning needs to be from a region.
    +
    129  if (!settings.region.empty()) {
    +
    130  LOG(WARNING)
    +
    131  << "Using both text regions and positioning isn't supported in TTML";
    +
    132  }
    +
    133 
    +
    134  const auto origin = ToTtmlSize(
    +
    135  settings.position.value_or(TextNumber(0, TextUnitType::kPixels)),
    +
    136  settings.line.value_or(TextNumber(0, TextUnitType::kPixels)));
    +
    137  const auto extent = ToTtmlSize(
    +
    138  settings.width.value_or(TextNumber(100, TextUnitType::kPercent)),
    +
    139  settings.height.value_or(TextNumber(100, TextUnitType::kPercent)));
    +
    140 
    +
    141  const std::string id = kRegionIdPrefix + std::to_string(region_id_++);
    +
    142  xml::XmlNode region("region");
    +
    143  RCHECK(region.SetStringAttribute("xml:id", id));
    +
    144  RCHECK(region.SetStringAttribute("tts:origin", origin));
    +
    145  RCHECK(region.SetStringAttribute("tts:extent", extent));
    +
    146  RCHECK(p.SetStringAttribute("region", id));
    +
    147  RCHECK(body->AddChild(std::move(region)));
    +
    148  } else if (!settings.region.empty()) {
    +
    149  RCHECK(p.SetStringAttribute("region", settings.region));
    +
    150  }
    +
    151 
    +
    152  if (settings.writing_direction != WritingDirection::kHorizontal) {
    +
    153  const char* dir =
    +
    154  settings.writing_direction == WritingDirection::kVerticalGrowingLeft
    +
    155  ? "tbrl"
    +
    156  : "tblr";
    +
    157  RCHECK(p.SetStringAttribute("tts:writingMode", dir));
    +
    158  }
    +
    159  if (settings.text_alignment != TextAlignment::kStart) {
    +
    160  switch (settings.text_alignment) {
    +
    161  case TextAlignment::kStart: // To avoid compiler warning.
    +
    162  case TextAlignment::kCenter:
    +
    163  RCHECK(p.SetStringAttribute("tts:textAlign", "center"));
    +
    164  break;
    +
    165  case TextAlignment::kEnd:
    +
    166  RCHECK(p.SetStringAttribute("tts:textAlign", "end"));
    +
    167  break;
    +
    168  case TextAlignment::kLeft:
    +
    169  RCHECK(p.SetStringAttribute("tts:textAlign", "left"));
    +
    170  break;
    +
    171  case TextAlignment::kRight:
    +
    172  RCHECK(p.SetStringAttribute("tts:textAlign", "right"));
    +
    173  break;
    +
    174  }
    +
    175  }
    +
    176 
    +
    177  RCHECK(body->AddChild(std::move(p)));
    +
    178  return true;
    +
    179 }
    +
    180 
    +
    181 bool TtmlGenerator::ConvertFragmentToXml(const TextFragment& body,
    +
    182  xml::XmlNode* parent,
    +
    183  xml::XmlNode* metadata,
    +
    184  size_t* image_count) const {
    +
    185  if (body.newline) {
    +
    186  xml::XmlNode br("br");
    +
    187  return parent->AddChild(std::move(br));
    +
    188  }
    +
    189 
    +
    190  // If we have new styles, add a new <span>.
    +
    191  xml::XmlNode span("span");
    +
    192  xml::XmlNode* node = parent;
    +
    193  if (body.style.bold || body.style.italic || body.style.underline) {
    +
    194  node = &span;
    +
    195  if (body.style.bold) {
    +
    196  RCHECK(span.SetStringAttribute("tts:fontWeight",
    +
    197  *body.style.bold ? "bold" : "normal"));
    +
    198  }
    +
    199  if (body.style.italic) {
    +
    200  RCHECK(span.SetStringAttribute("tts:fontStyle",
    +
    201  *body.style.italic ? "italic" : "normal"));
    +
    202  }
    +
    203  if (body.style.underline) {
    +
    204  RCHECK(span.SetStringAttribute(
    +
    205  "tts:textDecoration",
    +
    206  *body.style.underline ? "underline" : "noUnderline"));
    +
    207  }
    +
    208  }
    +
    209 
    +
    210  if (!body.body.empty()) {
    +
    211  node->AddContent(body.body);
    +
    212  } else if (!body.image.empty()) {
    +
    213  std::string image_data(body.image.begin(), body.image.end());
    +
    214  std::string base64_data;
    +
    215  base::Base64Encode(image_data, &base64_data);
    +
    216  std::string id = "img_" + std::to_string(++*image_count);
    +
    217 
    +
    218  xml::XmlNode image_xml("smpte:image");
    +
    219  RCHECK(image_xml.SetStringAttribute("imageType", "PNG"));
    +
    220  RCHECK(image_xml.SetStringAttribute("encoding", "Base64"));
    +
    221  RCHECK(image_xml.SetStringAttribute("xml:id", id));
    +
    222  image_xml.SetContent(base64_data);
    +
    223  RCHECK(metadata->AddChild(std::move(image_xml)));
    +
    224 
    +
    225  RCHECK(node->SetStringAttribute("smpte:backgroundImage", "#" + id));
    +
    226  } else {
    +
    227  for (const auto& frag : body.sub_fragments) {
    +
    228  if (!ConvertFragmentToXml(frag, node, metadata, image_count))
    +
    229  return false;
    +
    230  }
    +
    231  }
    +
    232 
    +
    233  if (body.style.bold || body.style.italic || body.style.underline)
    +
    234  RCHECK(parent->AddChild(std::move(span)));
    +
    235  return true;
    +
    236 }
    +
    237 
    +
    238 } // namespace ttml
    +
    239 } // namespace media
    +
    240 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/db/d1b/classshaka_1_1MemoryFile-members.html b/docs/db/d1b/classshaka_1_1MemoryFile-members.html index 7b3780a8af..6375486864 100644 --- a/docs/db/d1b/classshaka_1_1MemoryFile-members.html +++ b/docs/db/d1b/classshaka_1_1MemoryFile-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/db/d1f/classshaka_1_1media_1_1TextSample.html b/docs/db/d1f/classshaka_1_1media_1_1TextSample.html index 2521248872..bce21b0c7a 100644 --- a/docs/db/d1f/classshaka_1_1media_1_1TextSample.html +++ b/docs/db/d1f/classshaka_1_1media_1_1TextSample.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::TextSample Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

    Public Member Functions

    +TextSample (const std::string &id, int64_t start_time, int64_t end_time, const TextSettings &settings, const TextFragment &body) +  const std::string & id () const   @@ -81,31 +87,25 @@ int64_t start_time () int64_t duration () const   - -const std::string & settings () const -  - -const std::string & payload () const -  + +const TextSettingssettings () const +  + +const TextFragmentbody () const +  int64_t EndTime () const   - -void set_id (const std::string &id) -  - -void SetTime (int64_t start_time, int64_t end_time) -  - -void AppendStyle (const std::string &style) -  - -void AppendPayload (const std::string &payload) -  + +int32_t sub_stream_index () const +  + +void set_sub_stream_index (int32_t idx) + 

    Detailed Description

    -

    Definition at line 17 of file text_sample.h.

    +

    Definition at line 115 of file text_sample.h.


    The documentation for this class was generated from the following files:
    diff --git a/docs/db/d21/structshaka_1_1media_1_1mp4_1_1SubtitleMediaHeader.html b/docs/db/d21/structshaka_1_1media_1_1mp4_1_1SubtitleMediaHeader.html index bf8c23b0d7..20482fab07 100644 --- a/docs/db/d21/structshaka_1_1media_1_1mp4_1_1SubtitleMediaHeader.html +++ b/docs/db/d21/structshaka_1_1media_1_1mp4_1_1SubtitleMediaHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SubtitleMediaHeader Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -114,7 +117,7 @@ uint32_t 

    Detailed Description

    -

    Definition at line 593 of file box_definitions.h.

    +

    Definition at line 610 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -142,7 +145,7 @@ uint32_t Implements shaka::media::mp4::Box.

    -

    Definition at line 2051 of file box_definitions.cc.

    +

    Definition at line 2126 of file box_definitions.cc.

    @@ -153,9 +156,7 @@ uint32_t  diff --git a/docs/db/d2c/classshaka_1_1media_1_1mp2t_1_1VideoProgramMapTableWriter-members.html b/docs/db/d2c/classshaka_1_1media_1_1mp2t_1_1VideoProgramMapTableWriter-members.html index 5c3fc513d2..121d615d1f 100644 --- a/docs/db/d2c/classshaka_1_1media_1_1mp2t_1_1VideoProgramMapTableWriter-members.html +++ b/docs/db/d2c/classshaka_1_1media_1_1mp2t_1_1VideoProgramMapTableWriter-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    flags = 0 flags = 0 flags = 0
    - + +/* @license-end */
    diff --git a/docs/db/d30/classshaka_1_1media_1_1mp4_1_1MP4Muxer.html b/docs/db/d30/classshaka_1_1media_1_1mp4_1_1MP4Muxer.html index b681e5f665..633ae8b022 100644 --- a/docs/db/d30/classshaka_1_1media_1_1mp4_1_1MP4Muxer.html +++ b/docs/db/d30/classshaka_1_1media_1_1mp4_1_1MP4Muxer.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MP4Muxer Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::Muxer shaka::media::MediaHandler - -
    + + - + - - + + @@ -209,9 +212,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/db/d30/classshaka_1_1media_1_1ttml_1_1TtmlMuxer.html b/docs/db/d30/classshaka_1_1media_1_1ttml_1_1TtmlMuxer.html new file mode 100644 index 0000000000..8d99b4d487 --- /dev/null +++ b/docs/db/d30/classshaka_1_1media_1_1ttml_1_1TtmlMuxer.html @@ -0,0 +1,219 @@ + + + + + + + +Shaka Packager SDK: shaka::media::ttml::TtmlMuxer Class Reference + + + + + + + + + +
    +
    +

    Public Member Functions

     MP4Muxer (const MuxerOptions &options)
     Create a MP4Muxer object from MuxerOptions.
     Create a MP4Muxer object from MuxerOptions.
     
    - Public Member Functions inherited from shaka::media::Muxer
    @@ -122,9 +125,9 @@ bool 

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::Muxer
    const MuxerOptionsoptions () const
    + + + + + +
    +
    Shaka Packager SDK +
    +
    + + + + + + + + + +
    +
    + + +
    + +
    + + + +
    + +
    +
    shaka::media::ttml::TtmlMuxer Class Reference
    +
    +
    +
    +Inheritance diagram for shaka::media::ttml::TtmlMuxer:
    +
    +
    + + +shaka::media::TextMuxer +shaka::media::Muxer +shaka::media::MediaHandler + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Public Member Functions

    TtmlMuxer (const MuxerOptions &options)
     
    - Public Member Functions inherited from shaka::media::TextMuxer
    TextMuxer (const MuxerOptions &options)
     
    - Public Member Functions inherited from shaka::media::Muxer
    Muxer (const MuxerOptions &options)
     
    void Cancel ()
     
    void SetMuxerListener (std::unique_ptr< MuxerListener > muxer_listener)
     
    void SetProgressListener (std::unique_ptr< ProgressListener > progress_listener)
     
    +const std::vector< std::shared_ptr< const StreamInfo > > & streams () const
     
    void set_clock (base::Clock *clock)
     
    - Public Member Functions inherited from shaka::media::MediaHandler
    +Status SetHandler (size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
     Connect downstream handler at the specified output stream index.
     
    +Status AddHandler (std::shared_ptr< MediaHandler > handler)
     Connect downstream handler to the next available output stream index.
     
    Status Initialize ()
     
    +bool IsConnected ()
     Validate if the handler is connected to its upstream handler.
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::Muxer
    +const MuxerOptionsoptions () const
     
    +MuxerListenermuxer_listener ()
     
    +ProgressListenerprogress_listener ()
     
    +base::Clock * clock ()
     
    Status InitializeInternal () override
     
    Status Process (std::unique_ptr< StreamData > stream_data) override
     
    +Status OnFlushRequest (size_t input_stream_index) override
     Event handler for flush request at the specific input stream index.
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    +virtual bool ValidateOutputStreamIndex (size_t stream_index) const
     Validate if the stream at the specified index actually exists.
     
    Status Dispatch (std::unique_ptr< StreamData > stream_data) const
     
    +Status DispatchStreamInfo (size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
     Dispatch the stream info to downstream handlers.
     
    +Status DispatchMediaSample (size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
     Dispatch the media sample to downstream handlers.
     
    +Status DispatchTextSample (size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
     Dispatch the text sample to downstream handlers.
     
    +Status DispatchSegmentInfo (size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) const
     Dispatch the segment info to downstream handlers.
     
    +Status DispatchScte35Event (size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) const
     Dispatch the scte35 event to downstream handlers.
     
    +Status DispatchCueEvent (size_t stream_index, std::shared_ptr< const CueEvent > cue_event) const
     Dispatch the cue event to downstream handlers.
     
    +Status FlushDownstream (size_t output_stream_index)
     Flush the downstream connected at the specified output stream index.
     
    +Status FlushAllDownstreams ()
     Flush all connected downstream handlers.
     
    +bool initialized ()
     
    +size_t num_input_streams () const
     
    +size_t next_output_stream_index () const
     
    +const std::map< size_t, std::pair< std::shared_ptr< MediaHandler >, size_t > > & output_handlers ()
     
    +

    Detailed Description

    +
    +

    Definition at line 17 of file ttml_muxer.h.

    +

    The documentation for this class was generated from the following files: +
    + + + + diff --git a/docs/db/d30/classshaka_1_1media_1_1ttml_1_1TtmlMuxer.png b/docs/db/d30/classshaka_1_1media_1_1ttml_1_1TtmlMuxer.png new file mode 100644 index 0000000000000000000000000000000000000000..9604abc7169aa31892ed8e78995535703cebb74c GIT binary patch literal 1336 zcmeAS@N?(olHy`uVBq!ia0vp^Yk>Fw2Q!ddceCO&kdg@S332`Z|38rV;?396{zDUh zEHFNB-~emq9eE&^qa?^Lm;tB=1g@S6F=Aj~IqvD=7*fIbcJA#-tF3rk#NV#^^Iu(F z?T4E3Cgb#c+Z|rPUm6zbPE&ojC&){4cZZT^wML?Or(jefzvtr(%AQ4~x5Cn; z??395zCQIgm->VKEmKqa7B8yl_#VFD{Q>vh`YRW!FPUZ(MlGrO{^$KowHxe@8*(4F zH@x52x|hekfA-d!Y~NC6EZSN8Z07vlV7q6_ubH1pPGFDVz8q{Ce<#jzmDx?1h-{nB z-#({v?O#{C;_b*BC#Ryq0Tt*>C^Lo68&SZ#j4(TRtM_{o}cpEsuZdy?1)gU4{BQRm}j9hrA*@ zy8;e*1-1Cy2=cn=!oXO?_-4`Eg!uKn8Rbp3k>3~I&);H}vbnV65 zEpc0xi{Cy_{QQjZ`|r08sk{t~Kft$PUR(6i>(~9%v!fHEpPsQ+IeB?|?gekFg!Kox zqIH)=uQ}_PHuvlG4SDT$nTJg6pkD7hBV>vfrt`*a|Z~vs!pYm@|-nI5t%oWprC7ZU+PmI1QbK_q|-PR?A zHCfGZmv$cIDLtL8|1qOkI%luBX{hqn4QJIoyXEW*)Z@3S&OWoQwaoZ+Y14H!|M{=l z=f%zp=UUF2bKWY~VBg%Q!ZYOm#!B}{)FycDy_;}L=i1!`8-2f)moa;8IyFBUn#hF0 zCIOSoB$0)}+olAW2|6^yG3?Gzzi~ZV`PSS7|7*1w+ndhbWl(SmitCPQ$fB&l-aX^ND!`q_Py~nF3e7(sMt@umpRjBC}hv^%CS!Y%U@BjN*>hrwcGWYLXx7cK9 z`?@E4%B~%%n|t>zPh3;scUCIH%JycCcS(fBv5kkeS=~N#=hg!8EWQ4Pd6BzymPP+F z&r#pH!SspjwX@fEneiPnoSO9ZEc3L-pILq%6b>hKdY5FzOnru^QM;cnMa~T&jX7&22WQ% Jmvv4FO#oV;a18(e literal 0 HcmV?d00001 diff --git a/docs/db/d31/h26x__byte__to__unit__stream__converter_8h_source.html b/docs/db/d31/h26x__byte__to__unit__stream__converter_8h_source.html index cdd5408c48..d83659dde8 100644 --- a/docs/db/d31/h26x__byte__to__unit__stream__converter_8h_source.html +++ b/docs/db/d31/h26x__byte__to__unit__stream__converter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h26x_byte_to_unit_stream_converter.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    h26x_byte_to_unit_stream_converter.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_H26X_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    8 #define PACKAGER_MEDIA_CODECS_H26X_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <vector>
    13 
    14 #include "packager/media/base/video_stream_info.h"
    15 #include "packager/media/codecs/nalu_reader.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    20 class BufferWriter;
    21 
    24  public:
    25  static constexpr size_t kUnitStreamNaluLengthSize = 4;
    26 
    29  explicit H26xByteToUnitStreamConverter(Nalu::CodecType type);
    30 
    33  H26xByteToUnitStreamConverter(Nalu::CodecType type,
    34  H26xStreamFormat stream_format);
    35 
    37 
    46  bool ConvertByteStreamToNalUnitStream(const uint8_t* input_frame,
    47  size_t input_frame_size,
    48  std::vector<uint8_t>* output_frame);
    49 
    56  virtual bool GetDecoderConfigurationRecord(
    57  std::vector<uint8_t>* decoder_config) const = 0;
    58 
    59  H26xStreamFormat stream_format() const { return stream_format_; }
    60 
    61  protected:
    62  bool strip_parameter_set_nalus() const {
    63  return stream_format_ ==
    64  H26xStreamFormat::kNalUnitStreamWithoutParameterSetNalus;
    65  }
    66 
    67  // Warn if (nalu_ptr, nalu_size) does not match with |vector|.
    68  void WarnIfNotMatch(int nalu_type,
    69  const uint8_t* nalu_ptr,
    70  size_t nalu_size,
    71  const std::vector<uint8_t>& vector);
    72 
    73  private:
    74  // Process the given Nalu. If this returns true, it was handled and should
    75  // not be copied to the buffer.
    76  virtual bool ProcessNalu(const Nalu& nalu) = 0;
    77 
    78  Nalu::CodecType type_;
    79  H26xStreamFormat stream_format_;
    80 
    81  DISALLOW_COPY_AND_ASSIGN(H26xByteToUnitStreamConverter);
    82 };
    83 
    84 } // namespace media
    85 } // namespace shaka
    86 
    87 #endif // PACKAGER_MEDIA_CODECS_H26x_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    bool ConvertByteStreamToNalUnitStream(const uint8_t *input_frame, size_t input_frame_size, std::vector< uint8_t > *output_frame)
    -
    All the methods that are virtual are virtual for mocking.
    -
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    - - -
    virtual bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const =0
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_H26X_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_H26X_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/media/base/video_stream_info.h"
    +
    15 #include "packager/media/codecs/nalu_reader.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    +
    20 class BufferWriter;
    +
    21 
    + +
    24  public:
    +
    25  static constexpr size_t kUnitStreamNaluLengthSize = 4;
    +
    26 
    +
    29  explicit H26xByteToUnitStreamConverter(Nalu::CodecType type);
    +
    30 
    +
    33  H26xByteToUnitStreamConverter(Nalu::CodecType type,
    +
    34  H26xStreamFormat stream_format);
    +
    35 
    + +
    37 
    +
    46  bool ConvertByteStreamToNalUnitStream(const uint8_t* input_frame,
    +
    47  size_t input_frame_size,
    +
    48  std::vector<uint8_t>* output_frame);
    +
    49 
    + +
    57  std::vector<uint8_t>* decoder_config) const = 0;
    +
    58 
    +
    59  H26xStreamFormat stream_format() const { return stream_format_; }
    +
    60 
    +
    61  protected:
    +
    62  bool strip_parameter_set_nalus() const {
    +
    63  return stream_format_ ==
    +
    64  H26xStreamFormat::kNalUnitStreamWithoutParameterSetNalus;
    +
    65  }
    +
    66 
    +
    67  // Warn if (nalu_ptr, nalu_size) does not match with |vector|.
    +
    68  void WarnIfNotMatch(int nalu_type,
    +
    69  const uint8_t* nalu_ptr,
    +
    70  size_t nalu_size,
    +
    71  const std::vector<uint8_t>& vector);
    +
    72 
    +
    73  private:
    +
    74  // Process the given Nalu. If this returns true, it was handled and should
    +
    75  // not be copied to the buffer.
    +
    76  virtual bool ProcessNalu(const Nalu& nalu) = 0;
    +
    77 
    +
    78  Nalu::CodecType type_;
    +
    79  H26xStreamFormat stream_format_;
    +
    80 
    +
    81  DISALLOW_COPY_AND_ASSIGN(H26xByteToUnitStreamConverter);
    +
    82 };
    +
    83 
    +
    84 } // namespace media
    +
    85 } // namespace shaka
    +
    86 
    +
    87 #endif // PACKAGER_MEDIA_CODECS_H26x_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    +
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    +
    virtual bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const =0
    +
    bool ConvertByteStreamToNalUnitStream(const uint8_t *input_frame, size_t input_frame_size, std::vector< uint8_t > *output_frame)
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/d31/track__run__iterator_8cc_source.html b/docs/db/d31/track__run__iterator_8cc_source.html index 89cc547836..321b681d0c 100644 --- a/docs/db/d31/track__run__iterator_8cc_source.html +++ b/docs/db/d31/track__run__iterator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/track_run_iterator.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    track_run_iterator.cc
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/mp4/track_run_iterator.h"
    6 
    7 #include <gflags/gflags.h>
    8 
    9 DEFINE_bool(mp4_reset_initial_composition_offset_to_zero,
    10  true,
    11  "MP4 only. If it is true, reset the initial composition offset to "
    12  "zero, i.e. by assuming that there is a missing EditList.");
    13 
    14 #include <algorithm>
    15 #include <limits>
    16 
    17 #include "packager/media/base/buffer_reader.h"
    18 #include "packager/media/base/fourccs.h"
    19 #include "packager/media/base/rcheck.h"
    20 #include "packager/media/formats/mp4/chunk_info_iterator.h"
    21 #include "packager/media/formats/mp4/composition_offset_iterator.h"
    22 #include "packager/media/formats/mp4/decoding_time_iterator.h"
    23 #include "packager/media/formats/mp4/sync_sample_iterator.h"
    24 
    25 namespace {
    26 const int64_t kInvalidOffset = std::numeric_limits<int64_t>::max();
    27 
    28 int64_t Rescale(int64_t time_in_old_scale,
    29  uint32_t old_scale,
    30  uint32_t new_scale) {
    31  return (static_cast<double>(time_in_old_scale) / old_scale) * new_scale;
    32 }
    33 
    34 } // namespace
    35 
    36 namespace shaka {
    37 namespace media {
    38 namespace mp4 {
    39 
    40 struct SampleInfo {
    41  int64_t size;
    42  int64_t duration;
    43  int64_t cts_offset;
    44  bool is_keyframe;
    45 };
    46 
    47 struct TrackRunInfo {
    48  uint32_t track_id;
    49  std::vector<SampleInfo> samples;
    50  int64_t timescale;
    51  int64_t start_dts;
    52  int64_t sample_start_offset;
    53 
    54  TrackType track_type;
    55  const AudioSampleEntry* audio_description;
    56  const VideoSampleEntry* video_description;
    57 
    58  // Stores sample encryption entries, which is populated from 'senc' box if it
    59  // is available, otherwise will try to load from cenc auxiliary information.
    60  std::vector<SampleEncryptionEntry> sample_encryption_entries;
    61 
    62  // These variables are useful to load |sample_encryption_entries| from cenc
    63  // auxiliary information when 'senc' box is not available.
    64  int64_t aux_info_start_offset; // Only valid if aux_info_total_size > 0.
    65  int aux_info_default_size;
    66  std::vector<uint8_t> aux_info_sizes; // Populated if default_size == 0.
    67  int aux_info_total_size;
    68 
    69  TrackRunInfo();
    70  ~TrackRunInfo();
    71 };
    72 
    73 TrackRunInfo::TrackRunInfo()
    74  : track_id(0),
    75  timescale(-1),
    76  start_dts(-1),
    77  sample_start_offset(-1),
    78  track_type(kInvalid),
    79  audio_description(NULL),
    80  video_description(NULL),
    81  aux_info_start_offset(-1),
    82  aux_info_default_size(0),
    83  aux_info_total_size(0) {}
    84 TrackRunInfo::~TrackRunInfo() {}
    85 
    87  : moov_(moov), sample_dts_(0), sample_offset_(0) {
    88  CHECK(moov);
    89 }
    90 
    91 TrackRunIterator::~TrackRunIterator() {}
    92 
    93 static void PopulateSampleInfo(const TrackExtends& trex,
    94  const TrackFragmentHeader& tfhd,
    95  const TrackFragmentRun& trun,
    96  const size_t i,
    97  SampleInfo* sample_info) {
    98  if (i < trun.sample_sizes.size()) {
    99  sample_info->size = trun.sample_sizes[i];
    100  } else if (tfhd.default_sample_size > 0) {
    101  sample_info->size = tfhd.default_sample_size;
    102  } else {
    103  sample_info->size = trex.default_sample_size;
    104  }
    105 
    106  if (i < trun.sample_durations.size()) {
    107  sample_info->duration = trun.sample_durations[i];
    108  } else if (tfhd.default_sample_duration > 0) {
    109  sample_info->duration = tfhd.default_sample_duration;
    110  } else {
    111  sample_info->duration = trex.default_sample_duration;
    112  }
    113 
    114  if (i < trun.sample_composition_time_offsets.size()) {
    115  sample_info->cts_offset = trun.sample_composition_time_offsets[i];
    116  } else {
    117  sample_info->cts_offset = 0;
    118  }
    119 
    120  uint32_t flags;
    121  if (i < trun.sample_flags.size()) {
    122  flags = trun.sample_flags[i];
    123  } else if (tfhd.flags & TrackFragmentHeader::kDefaultSampleFlagsPresentMask) {
    124  flags = tfhd.default_sample_flags;
    125  } else {
    126  flags = trex.default_sample_flags;
    127  }
    128  sample_info->is_keyframe = !(flags & TrackFragmentHeader::kNonKeySampleMask);
    129 }
    130 
    131 // In well-structured encrypted media, each track run will be immediately
    132 // preceded by its auxiliary information; this is the only optimal storage
    133 // pattern in terms of minimum number of bytes from a serial stream needed to
    134 // begin playback. It also allows us to optimize caching on memory-constrained
    135 // architectures, because we can cache the relatively small auxiliary
    136 // information for an entire run and then discard data from the input stream,
    137 // instead of retaining the entire 'mdat' box.
    138 //
    139 // We optimize for this situation (with no loss of generality) by sorting track
    140 // runs during iteration in order of their first data offset (either sample data
    141 // or auxiliary data).
    142 class CompareMinTrackRunDataOffset {
    143  public:
    144  bool operator()(const TrackRunInfo& a, const TrackRunInfo& b) {
    145  int64_t a_aux = a.aux_info_total_size ? a.aux_info_start_offset : kInvalidOffset;
    146  int64_t b_aux = b.aux_info_total_size ? b.aux_info_start_offset : kInvalidOffset;
    147 
    148  int64_t a_lesser = std::min(a_aux, a.sample_start_offset);
    149  int64_t a_greater = std::max(a_aux, a.sample_start_offset);
    150  int64_t b_lesser = std::min(b_aux, b.sample_start_offset);
    151  int64_t b_greater = std::max(b_aux, b.sample_start_offset);
    152 
    153  if (a_lesser == b_lesser)
    154  return a_greater < b_greater;
    155  return a_lesser < b_lesser;
    156  }
    157 };
    158 
    160  runs_.clear();
    161 
    162  for (std::vector<Track>::const_iterator trak = moov_->tracks.begin();
    163  trak != moov_->tracks.end(); ++trak) {
    164  const SampleDescription& stsd =
    165  trak->media.information.sample_table.description;
    166  if (stsd.type != kAudio && stsd.type != kVideo) {
    167  DVLOG(1) << "Skipping unhandled track type";
    168  continue;
    169  }
    170 
    171  DecodingTimeIterator decoding_time(
    172  trak->media.information.sample_table.decoding_time_to_sample);
    173  CompositionOffsetIterator composition_offset(
    174  trak->media.information.sample_table.composition_time_to_sample);
    175  bool has_composition_offset = composition_offset.IsValid();
    176  ChunkInfoIterator chunk_info(
    177  trak->media.information.sample_table.sample_to_chunk);
    178  SyncSampleIterator sync_sample(
    179  trak->media.information.sample_table.sync_sample);
    180  // Skip processing saiz and saio boxes for non-fragmented mp4 as we
    181  // don't support encrypted non-fragmented mp4.
    182 
    183  const SampleSize& sample_size =
    184  trak->media.information.sample_table.sample_size;
    185  const std::vector<uint64_t>& chunk_offset_vector =
    186  trak->media.information.sample_table.chunk_large_offset.offsets;
    187 
    188  // dts is directly adjusted, which then propagates to pts as pts is encoded
    189  // as difference (composition offset) to dts in mp4.
    190  int64_t run_start_dts = GetTimestampAdjustment(*moov_, *trak, nullptr);
    191 
    192  uint32_t num_samples = sample_size.sample_count;
    193  uint32_t num_chunks = static_cast<uint32_t>(chunk_offset_vector.size());
    194 
    195  // Check that total number of samples match.
    196  DCHECK_EQ(num_samples, decoding_time.NumSamples());
    197  if (has_composition_offset) {
    198  DCHECK_EQ(num_samples, composition_offset.NumSamples());
    199  }
    200  if (num_chunks > 0) {
    201  DCHECK_EQ(num_samples, chunk_info.NumSamples(1, num_chunks));
    202  }
    203  DCHECK_GE(num_chunks, chunk_info.LastFirstChunk());
    204 
    205  if (num_samples > 0) {
    206  // Verify relevant tables are not empty.
    207  RCHECK(decoding_time.IsValid());
    208  RCHECK(chunk_info.IsValid());
    209  }
    210 
    211  uint32_t sample_index = 0;
    212  for (uint32_t chunk_index = 0; chunk_index < num_chunks; ++chunk_index) {
    213  RCHECK(chunk_info.current_chunk() == chunk_index + 1);
    214 
    215  TrackRunInfo tri;
    216  tri.track_id = trak->header.track_id;
    217  tri.timescale = trak->media.header.timescale;
    218  tri.start_dts = run_start_dts;
    219  tri.sample_start_offset = chunk_offset_vector[chunk_index];
    220 
    221  uint32_t desc_idx = chunk_info.sample_description_index();
    222  RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file.
    223  desc_idx -= 1;
    224 
    225  tri.track_type = stsd.type;
    226  if (tri.track_type == kAudio) {
    227  RCHECK(!stsd.audio_entries.empty());
    228  if (desc_idx > stsd.audio_entries.size())
    229  desc_idx = 0;
    230  tri.audio_description = &stsd.audio_entries[desc_idx];
    231  // We don't support encrypted non-fragmented mp4 for now.
    232  RCHECK(tri.audio_description->sinf.info.track_encryption
    233  .default_is_protected == 0);
    234  } else if (tri.track_type == kVideo) {
    235  RCHECK(!stsd.video_entries.empty());
    236  if (desc_idx > stsd.video_entries.size())
    237  desc_idx = 0;
    238  tri.video_description = &stsd.video_entries[desc_idx];
    239  // We don't support encrypted non-fragmented mp4 for now.
    240  RCHECK(tri.video_description->sinf.info.track_encryption
    241  .default_is_protected == 0);
    242  }
    243 
    244  uint32_t samples_per_chunk = chunk_info.samples_per_chunk();
    245  tri.samples.resize(samples_per_chunk);
    246  for (uint32_t k = 0; k < samples_per_chunk; ++k) {
    247  SampleInfo& sample = tri.samples[k];
    248  sample.size = sample_size.sample_size != 0
    249  ? sample_size.sample_size
    250  : sample_size.sizes[sample_index];
    251  sample.duration = decoding_time.sample_delta();
    252  sample.cts_offset =
    253  has_composition_offset ? composition_offset.sample_offset() : 0;
    254  sample.is_keyframe = sync_sample.IsSyncSample();
    255 
    256  run_start_dts += sample.duration;
    257 
    258  // Advance to next sample. Should success except for last sample.
    259  ++sample_index;
    260  RCHECK(chunk_info.AdvanceSample() && sync_sample.AdvanceSample());
    261  if (sample_index == num_samples) {
    262  // We should hit end of tables for decoding time and composition
    263  // offset.
    264  RCHECK(!decoding_time.AdvanceSample());
    265  if (has_composition_offset)
    266  RCHECK(!composition_offset.AdvanceSample());
    267  } else {
    268  RCHECK(decoding_time.AdvanceSample());
    269  if (has_composition_offset)
    270  RCHECK(composition_offset.AdvanceSample());
    271  }
    272  }
    273 
    274  runs_.push_back(tri);
    275  }
    276  }
    277 
    278  std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset());
    279  run_itr_ = runs_.begin();
    280  ResetRun();
    281  return true;
    282 }
    283 
    285  runs_.clear();
    286 
    287  next_fragment_start_dts_.resize(moof.tracks.size(), 0);
    288  for (size_t i = 0; i < moof.tracks.size(); i++) {
    289  const TrackFragment& traf = moof.tracks[i];
    290 
    291  const Track* trak = NULL;
    292  for (size_t t = 0; t < moov_->tracks.size(); t++) {
    293  if (moov_->tracks[t].header.track_id == traf.header.track_id)
    294  trak = &moov_->tracks[t];
    295  }
    296  RCHECK(trak);
    297 
    298  const TrackExtends* trex = NULL;
    299  for (size_t t = 0; t < moov_->extends.tracks.size(); t++) {
    300  if (moov_->extends.tracks[t].track_id == traf.header.track_id)
    301  trex = &moov_->extends.tracks[t];
    302  }
    303  RCHECK(trex);
    304 
    305  const SampleDescription& stsd =
    306  trak->media.information.sample_table.description;
    307  if (stsd.type != kAudio && stsd.type != kVideo) {
    308  DVLOG(1) << "Skipping unhandled track type";
    309  continue;
    310  }
    311  size_t desc_idx = traf.header.sample_description_index;
    312  if (!desc_idx)
    313  desc_idx = trex->default_sample_description_index;
    314  RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file
    315  desc_idx -= 1;
    316 
    317  const AudioSampleEntry* audio_sample_entry = NULL;
    318  const VideoSampleEntry* video_sample_entry = NULL;
    319  switch (stsd.type) {
    320  case kAudio:
    321  RCHECK(!stsd.audio_entries.empty());
    322  if (desc_idx > stsd.audio_entries.size())
    323  desc_idx = 0;
    324  audio_sample_entry = &stsd.audio_entries[desc_idx];
    325  break;
    326  case kVideo:
    327  RCHECK(!stsd.video_entries.empty());
    328  if (desc_idx > stsd.video_entries.size())
    329  desc_idx = 0;
    330  video_sample_entry = &stsd.video_entries[desc_idx];
    331  break;
    332  default:
    333  NOTREACHED();
    334  break;
    335  }
    336 
    337  // SampleEncryptionEntries should not have been parsed, without having
    338  // iv_size. Parse the box now.
    339  DCHECK(traf.sample_encryption.sample_encryption_entries.empty());
    340  std::vector<SampleEncryptionEntry> sample_encryption_entries;
    341  if (!traf.sample_encryption.sample_encryption_data.empty()) {
    342  RCHECK(audio_sample_entry || video_sample_entry);
    343  const uint8_t default_per_sample_iv_size =
    344  audio_sample_entry
    345  ? audio_sample_entry->sinf.info.track_encryption
    346  .default_per_sample_iv_size
    347  : video_sample_entry->sinf.info.track_encryption
    348  .default_per_sample_iv_size;
    349  RCHECK(traf.sample_encryption.ParseFromSampleEncryptionData(
    350  default_per_sample_iv_size, &sample_encryption_entries));
    351  }
    352 
    353  int64_t run_start_dts = traf.decode_time_absent
    354  ? next_fragment_start_dts_[i]
    355  : traf.decode_time.decode_time;
    356 
    357  // dts is directly adjusted, which then propagates to pts as pts is encoded
    358  // as difference (composition offset) to dts in mp4.
    359  run_start_dts += GetTimestampAdjustment(*moov_, *trak, &traf);
    360 
    361  int sample_count_sum = 0;
    362 
    363  for (size_t j = 0; j < traf.runs.size(); j++) {
    364  const TrackFragmentRun& trun = traf.runs[j];
    365  TrackRunInfo tri;
    366  tri.track_id = traf.header.track_id;
    367  tri.timescale = trak->media.header.timescale;
    368  tri.start_dts = run_start_dts;
    369  tri.sample_start_offset = trun.data_offset;
    370 
    371  tri.track_type = stsd.type;
    372  tri.audio_description = audio_sample_entry;
    373  tri.video_description = video_sample_entry;
    374 
    375  tri.aux_info_start_offset = -1;
    376  tri.aux_info_total_size = 0;
    377  // Populate sample encryption entries from SampleEncryption 'senc' box if
    378  // it is available; otherwise initialize aux_info variables, which will
    379  // be used to populate sample encryption entries later in CacheAuxInfo.
    380  if (!sample_encryption_entries.empty()) {
    381  RCHECK(sample_encryption_entries.size() >=
    382  sample_count_sum + trun.sample_count);
    383  for (size_t k = 0; k < trun.sample_count; ++k) {
    384  tri.sample_encryption_entries.push_back(
    385  sample_encryption_entries[sample_count_sum + k]);
    386  }
    387  } else if (traf.auxiliary_offset.offsets.size() > j) {
    388  // Collect information from the auxiliary_offset entry with the same
    389  // index in the 'saiz' container as the current run's index in the
    390  // 'trun' container, if it is present.
    391  tri.aux_info_start_offset = traf.auxiliary_offset.offsets[j];
    392  // There should be an auxiliary info entry corresponding to each sample
    393  // in the auxiliary offset entry's corresponding track run.
    394  RCHECK(traf.auxiliary_size.sample_count >=
    395  sample_count_sum + trun.sample_count);
    396  tri.aux_info_default_size =
    397  traf.auxiliary_size.default_sample_info_size;
    398  if (tri.aux_info_default_size == 0) {
    399  const std::vector<uint8_t>& sizes =
    400  traf.auxiliary_size.sample_info_sizes;
    401  tri.aux_info_sizes.insert(
    402  tri.aux_info_sizes.begin(),
    403  sizes.begin() + sample_count_sum,
    404  sizes.begin() + sample_count_sum + trun.sample_count);
    405  }
    406 
    407  // If the default info size is positive, find the total size of the aux
    408  // info block from it, otherwise sum over the individual sizes of each
    409  // aux info entry in the aux_offset entry.
    410  if (tri.aux_info_default_size) {
    411  tri.aux_info_total_size =
    412  tri.aux_info_default_size * trun.sample_count;
    413  } else {
    414  tri.aux_info_total_size = 0;
    415  for (size_t k = 0; k < trun.sample_count; k++) {
    416  tri.aux_info_total_size += tri.aux_info_sizes[k];
    417  }
    418  }
    419  }
    420 
    421  tri.samples.resize(trun.sample_count);
    422  for (size_t k = 0; k < trun.sample_count; k++) {
    423  PopulateSampleInfo(*trex, traf.header, trun, k, &tri.samples[k]);
    424  run_start_dts += tri.samples[k].duration;
    425  }
    426  runs_.push_back(tri);
    427  sample_count_sum += trun.sample_count;
    428  }
    429  next_fragment_start_dts_[i] = run_start_dts;
    430  }
    431 
    432  std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset());
    433  run_itr_ = runs_.begin();
    434  ResetRun();
    435  return true;
    436 }
    437 
    439  ++run_itr_;
    440  ResetRun();
    441 }
    442 
    443 void TrackRunIterator::ResetRun() {
    444  if (!IsRunValid())
    445  return;
    446  sample_dts_ = run_itr_->start_dts;
    447  sample_offset_ = run_itr_->sample_start_offset;
    448  sample_itr_ = run_itr_->samples.begin();
    449 }
    450 
    452  DCHECK(IsSampleValid());
    453  sample_dts_ += sample_itr_->duration;
    454  sample_offset_ += sample_itr_->size;
    455  ++sample_itr_;
    456 }
    457 
    458 // This implementation only indicates a need for caching if CENC auxiliary
    459 // info is available in the stream.
    461  DCHECK(IsRunValid());
    462  return is_encrypted() && aux_info_size() > 0 &&
    463  run_itr_->sample_encryption_entries.size() == 0;
    464 }
    465 
    466 // This implementation currently only caches CENC auxiliary info.
    467 bool TrackRunIterator::CacheAuxInfo(const uint8_t* buf, int buf_size) {
    468  RCHECK(AuxInfoNeedsToBeCached() && buf_size >= aux_info_size());
    469 
    470  std::vector<SampleEncryptionEntry>& sample_encryption_entries =
    471  runs_[run_itr_ - runs_.begin()].sample_encryption_entries;
    472  sample_encryption_entries.resize(run_itr_->samples.size());
    473  int64_t pos = 0;
    474  for (size_t i = 0; i < run_itr_->samples.size(); i++) {
    475  int info_size = run_itr_->aux_info_default_size;
    476  if (!info_size)
    477  info_size = run_itr_->aux_info_sizes[i];
    478 
    479  BufferReader reader(buf + pos, info_size);
    480  const bool has_subsamples =
    481  info_size > track_encryption().default_per_sample_iv_size;
    482  RCHECK(sample_encryption_entries[i].ParseFromBuffer(
    483  track_encryption().default_per_sample_iv_size, has_subsamples,
    484  &reader));
    485  pos += info_size;
    486  }
    487 
    488  return true;
    489 }
    490 
    491 bool TrackRunIterator::IsRunValid() const { return run_itr_ != runs_.end(); }
    492 
    494  return IsRunValid() && (sample_itr_ != run_itr_->samples.end());
    495 }
    496 
    497 // Because tracks are in sorted order and auxiliary information is cached when
    498 // returning samples, it is guaranteed that no data will be required before the
    499 // lesser of the minimum data offset of this track and the next in sequence.
    500 // (The stronger condition - that no data is required before the minimum data
    501 // offset of this track alone - is not guaranteed, because the BMFF spec does
    502 // not have any inter-run ordering restrictions.)
    504  int64_t offset = kInvalidOffset;
    505 
    506  if (IsSampleValid()) {
    507  offset = std::min(offset, sample_offset_);
    509  offset = std::min(offset, aux_info_offset());
    510  }
    511  if (run_itr_ != runs_.end()) {
    512  std::vector<TrackRunInfo>::const_iterator next_run = run_itr_ + 1;
    513  if (next_run != runs_.end()) {
    514  offset = std::min(offset, next_run->sample_start_offset);
    515  if (next_run->aux_info_total_size)
    516  offset = std::min(offset, next_run->aux_info_start_offset);
    517  }
    518  }
    519  if (offset == kInvalidOffset)
    520  return runs_.empty() ? 0 : runs_[0].sample_start_offset;
    521  return offset;
    522 }
    523 
    524 uint32_t TrackRunIterator::track_id() const {
    525  DCHECK(IsRunValid());
    526  return run_itr_->track_id;
    527 }
    528 
    529 bool TrackRunIterator::is_encrypted() const {
    530  DCHECK(IsRunValid());
    531  return track_encryption().default_is_protected == 1;
    532 }
    533 
    534 int64_t TrackRunIterator::aux_info_offset() const {
    535  return run_itr_->aux_info_start_offset;
    536 }
    537 
    538 int TrackRunIterator::aux_info_size() const {
    539  return run_itr_->aux_info_total_size;
    540 }
    541 
    542 bool TrackRunIterator::is_audio() const {
    543  DCHECK(IsRunValid());
    544  return run_itr_->track_type == kAudio;
    545 }
    546 
    547 bool TrackRunIterator::is_video() const {
    548  DCHECK(IsRunValid());
    549  return run_itr_->track_type == kVideo;
    550 }
    551 
    553  DCHECK(is_audio());
    554  DCHECK(run_itr_->audio_description);
    555  return *run_itr_->audio_description;
    556 }
    557 
    559  DCHECK(is_video());
    560  DCHECK(run_itr_->video_description);
    561  return *run_itr_->video_description;
    562 }
    563 
    564 int64_t TrackRunIterator::sample_offset() const {
    565  DCHECK(IsSampleValid());
    566  return sample_offset_;
    567 }
    568 
    569 int TrackRunIterator::sample_size() const {
    570  DCHECK(IsSampleValid());
    571  return sample_itr_->size;
    572 }
    573 
    574 int64_t TrackRunIterator::dts() const {
    575  DCHECK(IsSampleValid());
    576  return sample_dts_;
    577 }
    578 
    579 int64_t TrackRunIterator::cts() const {
    580  DCHECK(IsSampleValid());
    581  return sample_dts_ + sample_itr_->cts_offset;
    582 }
    583 
    584 int64_t TrackRunIterator::duration() const {
    585  DCHECK(IsSampleValid());
    586  return sample_itr_->duration;
    587 }
    588 
    589 bool TrackRunIterator::is_keyframe() const {
    590  DCHECK(IsSampleValid());
    591  return sample_itr_->is_keyframe;
    592 }
    593 
    594 const TrackEncryption& TrackRunIterator::track_encryption() const {
    595  if (is_audio())
    596  return audio_description().sinf.info.track_encryption;
    597  DCHECK(is_video());
    598  return video_description().sinf.info.track_encryption;
    599 }
    600 
    601 std::unique_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() {
    602  std::vector<uint8_t> iv;
    603  std::vector<SubsampleEntry> subsamples;
    604 
    605  size_t sample_idx = sample_itr_ - run_itr_->samples.begin();
    606  if (sample_idx < run_itr_->sample_encryption_entries.size()) {
    607  const SampleEncryptionEntry& sample_encryption_entry =
    608  run_itr_->sample_encryption_entries[sample_idx];
    609  DCHECK(is_encrypted());
    610  DCHECK(!AuxInfoNeedsToBeCached());
    611 
    612  const size_t total_size_of_subsamples =
    613  sample_encryption_entry.GetTotalSizeOfSubsamples();
    614  if (total_size_of_subsamples != 0 &&
    615  total_size_of_subsamples != static_cast<size_t>(sample_size())) {
    616  LOG(ERROR) << "Incorrect CENC subsample size.";
    617  return std::unique_ptr<DecryptConfig>();
    618  }
    619 
    620  iv = sample_encryption_entry.initialization_vector;
    621  subsamples = sample_encryption_entry.subsamples;
    622  }
    623 
    624  FourCC protection_scheme = is_audio() ? audio_description().sinf.type.type
    625  : video_description().sinf.type.type;
    626  if (iv.empty()) {
    627  if (protection_scheme != FOURCC_cbcs) {
    628  LOG(WARNING)
    629  << "Constant IV should only be used with 'cbcs' protection scheme.";
    630  }
    631  iv = track_encryption().default_constant_iv;
    632  if (iv.empty()) {
    633  LOG(ERROR) << "IV cannot be empty.";
    634  return std::unique_ptr<DecryptConfig>();
    635  }
    636  }
    637  return std::unique_ptr<DecryptConfig>(new DecryptConfig(
    638  track_encryption().default_kid, iv, subsamples, protection_scheme,
    639  track_encryption().default_crypt_byte_block,
    640  track_encryption().default_skip_byte_block));
    641 }
    642 
    643 int64_t TrackRunIterator::GetTimestampAdjustment(const Movie& movie,
    644  const Track& track,
    645  const TrackFragment* traf) {
    646  const uint32_t track_id = track.header.track_id;
    647  const auto iter = timestamp_adjustment_map_.find(track_id);
    648  if (iter != timestamp_adjustment_map_.end())
    649  return iter->second;
    650 
    651  int64_t timestamp_adjustment = 0;
    652  const std::vector<EditListEntry>& edits = track.edit.list.edits;
    653  if (!edits.empty()) {
    654  // ISO/IEC 14496-12:2015 8.6.6 Edit List Box.
    655  for (const EditListEntry& edit : edits) {
    656  if (edit.media_rate_integer != 1) {
    657  LOG(INFO) << "dwell EditListEntry is ignored.";
    658  continue;
    659  }
    660 
    661  if (edit.media_time < 0) {
    662  // This is an empty edit. |segment_duration| is in movie's timescale
    663  // instead of track's timescale.
    664  const int64_t scaled_time =
    665  Rescale(edit.segment_duration, movie.header.timescale,
    666  track.media.header.timescale);
    667  timestamp_adjustment += scaled_time;
    668  } else {
    669  timestamp_adjustment -= edit.media_time;
    670  }
    671  }
    672  }
    673 
    674  if (timestamp_adjustment == 0) {
    675  int64_t composition_offset = 0;
    676  if (traf && !traf->runs.empty()) {
    677  const auto& cts_offsets =
    678  traf->runs.front().sample_composition_time_offsets;
    679  if (!cts_offsets.empty())
    680  composition_offset = cts_offsets.front();
    681  } else {
    682  CompositionOffsetIterator composition_offset_iter(
    683  track.media.information.sample_table.composition_time_to_sample);
    684  if (!composition_offset_iter.IsValid()) {
    685  // This is the init (sub)segment of a fragmented mp4, which does not
    686  // contain any samples. Exit with 0 adjustment and without storing
    687  // |timestamp_adjustment|. This function will be called again later
    688  // with track fragment |traf|. |timestamp_adjustment| will be computed
    689  // and stored then.
    690  return 0;
    691  }
    692  composition_offset = composition_offset_iter.sample_offset();
    693  }
    694 
    695  int64_t decode_time = 0;
    696  if (traf)
    697  decode_time = traf->decode_time.decode_time;
    698  if (composition_offset != 0 && decode_time == 0) {
    699  LOG(WARNING) << "Seeing non-zero composition offset "
    700  << composition_offset
    701  << ". An EditList is probably missing.";
    702  if (FLAGS_mp4_reset_initial_composition_offset_to_zero) {
    703  LOG(WARNING)
    704  << "Adjusting timestamps by " << -composition_offset
    705  << ". Please file a bug to "
    706  "https://github.com/google/shaka-packager/issues if you "
    707  "do not think it is right or if you are seeing any problems.";
    708  timestamp_adjustment = -composition_offset;
    709  }
    710  }
    711  }
    712 
    713  timestamp_adjustment_map_.insert(
    714  std::make_pair(track_id, timestamp_adjustment));
    715  return timestamp_adjustment;
    716 }
    717 
    718 } // namespace mp4
    719 } // namespace media
    720 } // namespace shaka
    - - - - - - - - - - - - - - - - -
    All the methods that are virtual are virtual for mocking.
    -
    const VideoSampleEntry & video_description() const
    Only valid if is_video() is true.
    - - -
    bool ParseFromSampleEncryptionData(uint8_t iv_size, std::vector< SampleEncryptionEntry > *sample_encryption_entries) const
    - - - - - - - - -
    std::vector< uint8_t > sample_encryption_data
    - - - -
    std::unique_ptr< DecryptConfig > GetDecryptConfig()
    - - - - - - - - - - -
    uint32_t NumSamples(uint32_t start_chunk, uint32_t end_chunk) const
    - - - -
    bool CacheAuxInfo(const uint8_t *buf, int size)
    - -
    const AudioSampleEntry & audio_description() const
    Only valid if is_audio() is true.
    - +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/mp4/track_run_iterator.h"
    +
    6 
    +
    7 #include <gflags/gflags.h>
    +
    8 
    +
    9 DEFINE_bool(mp4_reset_initial_composition_offset_to_zero,
    +
    10  true,
    +
    11  "MP4 only. If it is true, reset the initial composition offset to "
    +
    12  "zero, i.e. by assuming that there is a missing EditList.");
    +
    13 
    +
    14 #include <algorithm>
    +
    15 #include <limits>
    +
    16 
    +
    17 #include "packager/media/base/buffer_reader.h"
    +
    18 #include "packager/media/base/fourccs.h"
    +
    19 #include "packager/media/base/rcheck.h"
    +
    20 #include "packager/media/formats/mp4/chunk_info_iterator.h"
    +
    21 #include "packager/media/formats/mp4/composition_offset_iterator.h"
    +
    22 #include "packager/media/formats/mp4/decoding_time_iterator.h"
    +
    23 #include "packager/media/formats/mp4/sync_sample_iterator.h"
    +
    24 
    +
    25 namespace {
    +
    26 const int64_t kInvalidOffset = std::numeric_limits<int64_t>::max();
    +
    27 
    +
    28 int64_t Rescale(int64_t time_in_old_scale,
    +
    29  uint32_t old_scale,
    +
    30  uint32_t new_scale) {
    +
    31  return (static_cast<double>(time_in_old_scale) / old_scale) * new_scale;
    +
    32 }
    +
    33 
    +
    34 } // namespace
    +
    35 
    +
    36 namespace shaka {
    +
    37 namespace media {
    +
    38 namespace mp4 {
    +
    39 
    +
    40 struct SampleInfo {
    +
    41  int64_t size;
    +
    42  int64_t duration;
    +
    43  int64_t cts_offset;
    +
    44  bool is_keyframe;
    +
    45 };
    +
    46 
    +
    47 struct TrackRunInfo {
    +
    48  uint32_t track_id;
    +
    49  std::vector<SampleInfo> samples;
    +
    50  int64_t timescale;
    +
    51  int64_t start_dts;
    +
    52  int64_t sample_start_offset;
    +
    53 
    +
    54  TrackType track_type;
    +
    55  const AudioSampleEntry* audio_description;
    +
    56  const VideoSampleEntry* video_description;
    +
    57 
    +
    58  // Stores sample encryption entries, which is populated from 'senc' box if it
    +
    59  // is available, otherwise will try to load from cenc auxiliary information.
    +
    60  std::vector<SampleEncryptionEntry> sample_encryption_entries;
    +
    61 
    +
    62  // These variables are useful to load |sample_encryption_entries| from cenc
    +
    63  // auxiliary information when 'senc' box is not available.
    +
    64  int64_t aux_info_start_offset; // Only valid if aux_info_total_size > 0.
    +
    65  int aux_info_default_size;
    +
    66  std::vector<uint8_t> aux_info_sizes; // Populated if default_size == 0.
    +
    67  int aux_info_total_size;
    +
    68 
    +
    69  TrackRunInfo();
    +
    70  ~TrackRunInfo();
    +
    71 };
    +
    72 
    +
    73 TrackRunInfo::TrackRunInfo()
    +
    74  : track_id(0),
    +
    75  timescale(-1),
    +
    76  start_dts(-1),
    +
    77  sample_start_offset(-1),
    +
    78  track_type(kInvalid),
    +
    79  audio_description(NULL),
    +
    80  video_description(NULL),
    +
    81  aux_info_start_offset(-1),
    +
    82  aux_info_default_size(0),
    +
    83  aux_info_total_size(0) {}
    +
    84 TrackRunInfo::~TrackRunInfo() {}
    +
    85 
    +
    86 TrackRunIterator::TrackRunIterator(const Movie* moov)
    +
    87  : moov_(moov), sample_dts_(0), sample_offset_(0) {
    +
    88  CHECK(moov);
    +
    89 }
    +
    90 
    +
    91 TrackRunIterator::~TrackRunIterator() {}
    +
    92 
    +
    93 static void PopulateSampleInfo(const TrackExtends& trex,
    +
    94  const TrackFragmentHeader& tfhd,
    +
    95  const TrackFragmentRun& trun,
    +
    96  const size_t i,
    +
    97  SampleInfo* sample_info) {
    +
    98  if (i < trun.sample_sizes.size()) {
    +
    99  sample_info->size = trun.sample_sizes[i];
    +
    100  } else if (tfhd.default_sample_size > 0) {
    +
    101  sample_info->size = tfhd.default_sample_size;
    +
    102  } else {
    +
    103  sample_info->size = trex.default_sample_size;
    +
    104  }
    +
    105 
    +
    106  if (i < trun.sample_durations.size()) {
    +
    107  sample_info->duration = trun.sample_durations[i];
    +
    108  } else if (tfhd.default_sample_duration > 0) {
    +
    109  sample_info->duration = tfhd.default_sample_duration;
    +
    110  } else {
    +
    111  sample_info->duration = trex.default_sample_duration;
    +
    112  }
    +
    113 
    +
    114  if (i < trun.sample_composition_time_offsets.size()) {
    +
    115  sample_info->cts_offset = trun.sample_composition_time_offsets[i];
    +
    116  } else {
    +
    117  sample_info->cts_offset = 0;
    +
    118  }
    +
    119 
    +
    120  uint32_t flags;
    +
    121  if (i < trun.sample_flags.size()) {
    +
    122  flags = trun.sample_flags[i];
    +
    123  } else if (tfhd.flags & TrackFragmentHeader::kDefaultSampleFlagsPresentMask) {
    +
    124  flags = tfhd.default_sample_flags;
    +
    125  } else {
    +
    126  flags = trex.default_sample_flags;
    +
    127  }
    +
    128  sample_info->is_keyframe = !(flags & TrackFragmentHeader::kNonKeySampleMask);
    +
    129 }
    +
    130 
    +
    131 // In well-structured encrypted media, each track run will be immediately
    +
    132 // preceded by its auxiliary information; this is the only optimal storage
    +
    133 // pattern in terms of minimum number of bytes from a serial stream needed to
    +
    134 // begin playback. It also allows us to optimize caching on memory-constrained
    +
    135 // architectures, because we can cache the relatively small auxiliary
    +
    136 // information for an entire run and then discard data from the input stream,
    +
    137 // instead of retaining the entire 'mdat' box.
    +
    138 //
    +
    139 // We optimize for this situation (with no loss of generality) by sorting track
    +
    140 // runs during iteration in order of their first data offset (either sample data
    +
    141 // or auxiliary data).
    +
    142 class CompareMinTrackRunDataOffset {
    +
    143  public:
    +
    144  bool operator()(const TrackRunInfo& a, const TrackRunInfo& b) {
    +
    145  int64_t a_aux = a.aux_info_total_size ? a.aux_info_start_offset : kInvalidOffset;
    +
    146  int64_t b_aux = b.aux_info_total_size ? b.aux_info_start_offset : kInvalidOffset;
    +
    147 
    +
    148  int64_t a_lesser = std::min(a_aux, a.sample_start_offset);
    +
    149  int64_t a_greater = std::max(a_aux, a.sample_start_offset);
    +
    150  int64_t b_lesser = std::min(b_aux, b.sample_start_offset);
    +
    151  int64_t b_greater = std::max(b_aux, b.sample_start_offset);
    +
    152 
    +
    153  if (a_lesser == b_lesser)
    +
    154  return a_greater < b_greater;
    +
    155  return a_lesser < b_lesser;
    +
    156  }
    +
    157 };
    +
    158 
    + +
    160  runs_.clear();
    +
    161 
    +
    162  for (std::vector<Track>::const_iterator trak = moov_->tracks.begin();
    +
    163  trak != moov_->tracks.end(); ++trak) {
    +
    164  const SampleDescription& stsd =
    +
    165  trak->media.information.sample_table.description;
    +
    166  if (stsd.type != kAudio && stsd.type != kVideo) {
    +
    167  DVLOG(1) << "Skipping unhandled track type";
    +
    168  continue;
    +
    169  }
    +
    170 
    +
    171  DecodingTimeIterator decoding_time(
    +
    172  trak->media.information.sample_table.decoding_time_to_sample);
    +
    173  CompositionOffsetIterator composition_offset(
    +
    174  trak->media.information.sample_table.composition_time_to_sample);
    +
    175  bool has_composition_offset = composition_offset.IsValid();
    +
    176  ChunkInfoIterator chunk_info(
    +
    177  trak->media.information.sample_table.sample_to_chunk);
    +
    178  SyncSampleIterator sync_sample(
    +
    179  trak->media.information.sample_table.sync_sample);
    +
    180  // Skip processing saiz and saio boxes for non-fragmented mp4 as we
    +
    181  // don't support encrypted non-fragmented mp4.
    +
    182 
    +
    183  const SampleSize& sample_size =
    +
    184  trak->media.information.sample_table.sample_size;
    +
    185  const std::vector<uint64_t>& chunk_offset_vector =
    +
    186  trak->media.information.sample_table.chunk_large_offset.offsets;
    +
    187 
    +
    188  // dts is directly adjusted, which then propagates to pts as pts is encoded
    +
    189  // as difference (composition offset) to dts in mp4.
    +
    190  int64_t run_start_dts = GetTimestampAdjustment(*moov_, *trak, nullptr);
    +
    191 
    +
    192  uint32_t num_samples = sample_size.sample_count;
    +
    193  uint32_t num_chunks = static_cast<uint32_t>(chunk_offset_vector.size());
    +
    194 
    +
    195  // Check that total number of samples match.
    +
    196  DCHECK_EQ(num_samples, decoding_time.NumSamples());
    +
    197  if (has_composition_offset) {
    +
    198  DCHECK_EQ(num_samples, composition_offset.NumSamples());
    +
    199  }
    +
    200  if (num_chunks > 0) {
    +
    201  DCHECK_EQ(num_samples, chunk_info.NumSamples(1, num_chunks));
    +
    202  }
    +
    203  DCHECK_GE(num_chunks, chunk_info.LastFirstChunk());
    +
    204 
    +
    205  if (num_samples > 0) {
    +
    206  // Verify relevant tables are not empty.
    +
    207  RCHECK(decoding_time.IsValid());
    +
    208  RCHECK(chunk_info.IsValid());
    +
    209  }
    +
    210 
    +
    211  uint32_t sample_index = 0;
    +
    212  for (uint32_t chunk_index = 0; chunk_index < num_chunks; ++chunk_index) {
    +
    213  RCHECK(chunk_info.current_chunk() == chunk_index + 1);
    +
    214 
    +
    215  TrackRunInfo tri;
    +
    216  tri.track_id = trak->header.track_id;
    +
    217  tri.timescale = trak->media.header.timescale;
    +
    218  tri.start_dts = run_start_dts;
    +
    219  tri.sample_start_offset = chunk_offset_vector[chunk_index];
    +
    220 
    +
    221  uint32_t desc_idx = chunk_info.sample_description_index();
    +
    222  RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file.
    +
    223  desc_idx -= 1;
    +
    224 
    +
    225  tri.track_type = stsd.type;
    +
    226  if (tri.track_type == kAudio) {
    +
    227  RCHECK(!stsd.audio_entries.empty());
    +
    228  if (desc_idx > stsd.audio_entries.size())
    +
    229  desc_idx = 0;
    +
    230  tri.audio_description = &stsd.audio_entries[desc_idx];
    +
    231  // We don't support encrypted non-fragmented mp4 for now.
    +
    232  RCHECK(tri.audio_description->sinf.info.track_encryption
    +
    233  .default_is_protected == 0);
    +
    234  } else if (tri.track_type == kVideo) {
    +
    235  RCHECK(!stsd.video_entries.empty());
    +
    236  if (desc_idx > stsd.video_entries.size())
    +
    237  desc_idx = 0;
    +
    238  tri.video_description = &stsd.video_entries[desc_idx];
    +
    239  // We don't support encrypted non-fragmented mp4 for now.
    +
    240  RCHECK(tri.video_description->sinf.info.track_encryption
    +
    241  .default_is_protected == 0);
    +
    242  }
    +
    243 
    +
    244  uint32_t samples_per_chunk = chunk_info.samples_per_chunk();
    +
    245  tri.samples.resize(samples_per_chunk);
    +
    246  for (uint32_t k = 0; k < samples_per_chunk; ++k) {
    +
    247  SampleInfo& sample = tri.samples[k];
    +
    248  sample.size = sample_size.sample_size != 0
    +
    249  ? sample_size.sample_size
    +
    250  : sample_size.sizes[sample_index];
    +
    251  sample.duration = decoding_time.sample_delta();
    +
    252  sample.cts_offset =
    +
    253  has_composition_offset ? composition_offset.sample_offset() : 0;
    +
    254  sample.is_keyframe = sync_sample.IsSyncSample();
    +
    255 
    +
    256  run_start_dts += sample.duration;
    +
    257 
    +
    258  // Advance to next sample. Should success except for last sample.
    +
    259  ++sample_index;
    +
    260  RCHECK(chunk_info.AdvanceSample() && sync_sample.AdvanceSample());
    +
    261  if (sample_index == num_samples) {
    +
    262  // We should hit end of tables for decoding time and composition
    +
    263  // offset.
    +
    264  RCHECK(!decoding_time.AdvanceSample());
    +
    265  if (has_composition_offset)
    +
    266  RCHECK(!composition_offset.AdvanceSample());
    +
    267  } else {
    +
    268  RCHECK(decoding_time.AdvanceSample());
    +
    269  if (has_composition_offset)
    +
    270  RCHECK(composition_offset.AdvanceSample());
    +
    271  }
    +
    272  }
    +
    273 
    +
    274  runs_.push_back(tri);
    +
    275  }
    +
    276  }
    +
    277 
    +
    278  std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset());
    +
    279  run_itr_ = runs_.begin();
    +
    280  ResetRun();
    +
    281  return true;
    +
    282 }
    +
    283 
    + +
    285  runs_.clear();
    +
    286 
    +
    287  next_fragment_start_dts_.resize(moof.tracks.size(), 0);
    +
    288  for (size_t i = 0; i < moof.tracks.size(); i++) {
    +
    289  const TrackFragment& traf = moof.tracks[i];
    +
    290 
    +
    291  const Track* trak = NULL;
    +
    292  for (size_t t = 0; t < moov_->tracks.size(); t++) {
    +
    293  if (moov_->tracks[t].header.track_id == traf.header.track_id)
    +
    294  trak = &moov_->tracks[t];
    +
    295  }
    +
    296  RCHECK(trak);
    +
    297 
    +
    298  const TrackExtends* trex = NULL;
    +
    299  for (size_t t = 0; t < moov_->extends.tracks.size(); t++) {
    +
    300  if (moov_->extends.tracks[t].track_id == traf.header.track_id)
    +
    301  trex = &moov_->extends.tracks[t];
    +
    302  }
    +
    303  RCHECK(trex);
    +
    304 
    +
    305  const SampleDescription& stsd =
    +
    306  trak->media.information.sample_table.description;
    +
    307  if (stsd.type != kAudio && stsd.type != kVideo) {
    +
    308  DVLOG(1) << "Skipping unhandled track type";
    +
    309  continue;
    +
    310  }
    +
    311  size_t desc_idx = traf.header.sample_description_index;
    +
    312  if (!desc_idx)
    +
    313  desc_idx = trex->default_sample_description_index;
    +
    314  RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file
    +
    315  desc_idx -= 1;
    +
    316 
    +
    317  const AudioSampleEntry* audio_sample_entry = NULL;
    +
    318  const VideoSampleEntry* video_sample_entry = NULL;
    +
    319  switch (stsd.type) {
    +
    320  case kAudio:
    +
    321  RCHECK(!stsd.audio_entries.empty());
    +
    322  if (desc_idx > stsd.audio_entries.size())
    +
    323  desc_idx = 0;
    +
    324  audio_sample_entry = &stsd.audio_entries[desc_idx];
    +
    325  break;
    +
    326  case kVideo:
    +
    327  RCHECK(!stsd.video_entries.empty());
    +
    328  if (desc_idx > stsd.video_entries.size())
    +
    329  desc_idx = 0;
    +
    330  video_sample_entry = &stsd.video_entries[desc_idx];
    +
    331  break;
    +
    332  default:
    +
    333  NOTREACHED();
    +
    334  break;
    +
    335  }
    +
    336 
    +
    337  // SampleEncryptionEntries should not have been parsed, without having
    +
    338  // iv_size. Parse the box now.
    +
    339  DCHECK(traf.sample_encryption.sample_encryption_entries.empty());
    +
    340  std::vector<SampleEncryptionEntry> sample_encryption_entries;
    +
    341  if (!traf.sample_encryption.sample_encryption_data.empty()) {
    +
    342  RCHECK(audio_sample_entry || video_sample_entry);
    +
    343  const uint8_t default_per_sample_iv_size =
    +
    344  audio_sample_entry
    +
    345  ? audio_sample_entry->sinf.info.track_encryption
    +
    346  .default_per_sample_iv_size
    +
    347  : video_sample_entry->sinf.info.track_encryption
    +
    348  .default_per_sample_iv_size;
    +
    349  RCHECK(traf.sample_encryption.ParseFromSampleEncryptionData(
    +
    350  default_per_sample_iv_size, &sample_encryption_entries));
    +
    351  }
    +
    352 
    +
    353  int64_t run_start_dts = traf.decode_time_absent
    +
    354  ? next_fragment_start_dts_[i]
    +
    355  : traf.decode_time.decode_time;
    +
    356 
    +
    357  // dts is directly adjusted, which then propagates to pts as pts is encoded
    +
    358  // as difference (composition offset) to dts in mp4.
    +
    359  run_start_dts += GetTimestampAdjustment(*moov_, *trak, &traf);
    +
    360 
    +
    361  int sample_count_sum = 0;
    +
    362 
    +
    363  for (size_t j = 0; j < traf.runs.size(); j++) {
    +
    364  const TrackFragmentRun& trun = traf.runs[j];
    +
    365  TrackRunInfo tri;
    +
    366  tri.track_id = traf.header.track_id;
    +
    367  tri.timescale = trak->media.header.timescale;
    +
    368  tri.start_dts = run_start_dts;
    +
    369  tri.sample_start_offset = trun.data_offset;
    +
    370 
    +
    371  tri.track_type = stsd.type;
    +
    372  tri.audio_description = audio_sample_entry;
    +
    373  tri.video_description = video_sample_entry;
    +
    374 
    +
    375  tri.aux_info_start_offset = -1;
    +
    376  tri.aux_info_total_size = 0;
    +
    377  // Populate sample encryption entries from SampleEncryption 'senc' box if
    +
    378  // it is available; otherwise initialize aux_info variables, which will
    +
    379  // be used to populate sample encryption entries later in CacheAuxInfo.
    +
    380  if (!sample_encryption_entries.empty()) {
    +
    381  RCHECK(sample_encryption_entries.size() >=
    +
    382  sample_count_sum + trun.sample_count);
    +
    383  for (size_t k = 0; k < trun.sample_count; ++k) {
    +
    384  tri.sample_encryption_entries.push_back(
    +
    385  sample_encryption_entries[sample_count_sum + k]);
    +
    386  }
    +
    387  } else if (traf.auxiliary_offset.offsets.size() > j) {
    +
    388  // Collect information from the auxiliary_offset entry with the same
    +
    389  // index in the 'saiz' container as the current run's index in the
    +
    390  // 'trun' container, if it is present.
    +
    391  tri.aux_info_start_offset = traf.auxiliary_offset.offsets[j];
    +
    392  // There should be an auxiliary info entry corresponding to each sample
    +
    393  // in the auxiliary offset entry's corresponding track run.
    +
    394  RCHECK(traf.auxiliary_size.sample_count >=
    +
    395  sample_count_sum + trun.sample_count);
    +
    396  tri.aux_info_default_size =
    +
    397  traf.auxiliary_size.default_sample_info_size;
    +
    398  if (tri.aux_info_default_size == 0) {
    +
    399  const std::vector<uint8_t>& sizes =
    +
    400  traf.auxiliary_size.sample_info_sizes;
    +
    401  tri.aux_info_sizes.insert(
    +
    402  tri.aux_info_sizes.begin(),
    +
    403  sizes.begin() + sample_count_sum,
    +
    404  sizes.begin() + sample_count_sum + trun.sample_count);
    +
    405  }
    +
    406 
    +
    407  // If the default info size is positive, find the total size of the aux
    +
    408  // info block from it, otherwise sum over the individual sizes of each
    +
    409  // aux info entry in the aux_offset entry.
    +
    410  if (tri.aux_info_default_size) {
    +
    411  tri.aux_info_total_size =
    +
    412  tri.aux_info_default_size * trun.sample_count;
    +
    413  } else {
    +
    414  tri.aux_info_total_size = 0;
    +
    415  for (size_t k = 0; k < trun.sample_count; k++) {
    +
    416  tri.aux_info_total_size += tri.aux_info_sizes[k];
    +
    417  }
    +
    418  }
    +
    419  }
    +
    420 
    +
    421  tri.samples.resize(trun.sample_count);
    +
    422  for (size_t k = 0; k < trun.sample_count; k++) {
    +
    423  PopulateSampleInfo(*trex, traf.header, trun, k, &tri.samples[k]);
    +
    424  run_start_dts += tri.samples[k].duration;
    +
    425  }
    +
    426  runs_.push_back(tri);
    +
    427  sample_count_sum += trun.sample_count;
    +
    428  }
    +
    429  next_fragment_start_dts_[i] = run_start_dts;
    +
    430  }
    +
    431 
    +
    432  std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset());
    +
    433  run_itr_ = runs_.begin();
    +
    434  ResetRun();
    +
    435  return true;
    +
    436 }
    +
    437 
    + +
    439  ++run_itr_;
    +
    440  ResetRun();
    +
    441 }
    +
    442 
    +
    443 void TrackRunIterator::ResetRun() {
    +
    444  if (!IsRunValid())
    +
    445  return;
    +
    446  sample_dts_ = run_itr_->start_dts;
    +
    447  sample_offset_ = run_itr_->sample_start_offset;
    +
    448  sample_itr_ = run_itr_->samples.begin();
    +
    449 }
    +
    450 
    + +
    452  DCHECK(IsSampleValid());
    +
    453  sample_dts_ += sample_itr_->duration;
    +
    454  sample_offset_ += sample_itr_->size;
    +
    455  ++sample_itr_;
    +
    456 }
    +
    457 
    +
    458 // This implementation only indicates a need for caching if CENC auxiliary
    +
    459 // info is available in the stream.
    + +
    461  DCHECK(IsRunValid());
    +
    462  return is_encrypted() && aux_info_size() > 0 &&
    +
    463  run_itr_->sample_encryption_entries.size() == 0;
    +
    464 }
    +
    465 
    +
    466 // This implementation currently only caches CENC auxiliary info.
    +
    467 bool TrackRunIterator::CacheAuxInfo(const uint8_t* buf, int buf_size) {
    +
    468  RCHECK(AuxInfoNeedsToBeCached() && buf_size >= aux_info_size());
    +
    469 
    +
    470  std::vector<SampleEncryptionEntry>& sample_encryption_entries =
    +
    471  runs_[run_itr_ - runs_.begin()].sample_encryption_entries;
    +
    472  sample_encryption_entries.resize(run_itr_->samples.size());
    +
    473  int64_t pos = 0;
    +
    474  for (size_t i = 0; i < run_itr_->samples.size(); i++) {
    +
    475  int info_size = run_itr_->aux_info_default_size;
    +
    476  if (!info_size)
    +
    477  info_size = run_itr_->aux_info_sizes[i];
    +
    478 
    +
    479  BufferReader reader(buf + pos, info_size);
    +
    480  const bool has_subsamples =
    +
    481  info_size > track_encryption().default_per_sample_iv_size;
    +
    482  RCHECK(sample_encryption_entries[i].ParseFromBuffer(
    +
    483  track_encryption().default_per_sample_iv_size, has_subsamples,
    +
    484  &reader));
    +
    485  pos += info_size;
    +
    486  }
    +
    487 
    +
    488  return true;
    +
    489 }
    +
    490 
    +
    491 bool TrackRunIterator::IsRunValid() const { return run_itr_ != runs_.end(); }
    +
    492 
    + +
    494  return IsRunValid() && (sample_itr_ != run_itr_->samples.end());
    +
    495 }
    +
    496 
    +
    497 // Because tracks are in sorted order and auxiliary information is cached when
    +
    498 // returning samples, it is guaranteed that no data will be required before the
    +
    499 // lesser of the minimum data offset of this track and the next in sequence.
    +
    500 // (The stronger condition - that no data is required before the minimum data
    +
    501 // offset of this track alone - is not guaranteed, because the BMFF spec does
    +
    502 // not have any inter-run ordering restrictions.)
    + +
    504  int64_t offset = kInvalidOffset;
    +
    505 
    +
    506  if (IsSampleValid()) {
    +
    507  offset = std::min(offset, sample_offset_);
    + +
    509  offset = std::min(offset, aux_info_offset());
    +
    510  }
    +
    511  if (run_itr_ != runs_.end()) {
    +
    512  std::vector<TrackRunInfo>::const_iterator next_run = run_itr_ + 1;
    +
    513  if (next_run != runs_.end()) {
    +
    514  offset = std::min(offset, next_run->sample_start_offset);
    +
    515  if (next_run->aux_info_total_size)
    +
    516  offset = std::min(offset, next_run->aux_info_start_offset);
    +
    517  }
    +
    518  }
    +
    519  if (offset == kInvalidOffset)
    +
    520  return runs_.empty() ? 0 : runs_[0].sample_start_offset;
    +
    521  return offset;
    +
    522 }
    +
    523 
    +
    524 uint32_t TrackRunIterator::track_id() const {
    +
    525  DCHECK(IsRunValid());
    +
    526  return run_itr_->track_id;
    +
    527 }
    +
    528 
    +
    529 bool TrackRunIterator::is_encrypted() const {
    +
    530  DCHECK(IsRunValid());
    +
    531  return track_encryption().default_is_protected == 1;
    +
    532 }
    +
    533 
    +
    534 int64_t TrackRunIterator::aux_info_offset() const {
    +
    535  return run_itr_->aux_info_start_offset;
    +
    536 }
    +
    537 
    +
    538 int TrackRunIterator::aux_info_size() const {
    +
    539  return run_itr_->aux_info_total_size;
    +
    540 }
    +
    541 
    +
    542 bool TrackRunIterator::is_audio() const {
    +
    543  DCHECK(IsRunValid());
    +
    544  return run_itr_->track_type == kAudio;
    +
    545 }
    +
    546 
    +
    547 bool TrackRunIterator::is_video() const {
    +
    548  DCHECK(IsRunValid());
    +
    549  return run_itr_->track_type == kVideo;
    +
    550 }
    +
    551 
    + +
    553  DCHECK(is_audio());
    +
    554  DCHECK(run_itr_->audio_description);
    +
    555  return *run_itr_->audio_description;
    +
    556 }
    +
    557 
    + +
    559  DCHECK(is_video());
    +
    560  DCHECK(run_itr_->video_description);
    +
    561  return *run_itr_->video_description;
    +
    562 }
    +
    563 
    +
    564 int64_t TrackRunIterator::sample_offset() const {
    +
    565  DCHECK(IsSampleValid());
    +
    566  return sample_offset_;
    +
    567 }
    +
    568 
    +
    569 int TrackRunIterator::sample_size() const {
    +
    570  DCHECK(IsSampleValid());
    +
    571  return sample_itr_->size;
    +
    572 }
    +
    573 
    +
    574 int64_t TrackRunIterator::dts() const {
    +
    575  DCHECK(IsSampleValid());
    +
    576  return sample_dts_;
    +
    577 }
    +
    578 
    +
    579 int64_t TrackRunIterator::cts() const {
    +
    580  DCHECK(IsSampleValid());
    +
    581  return sample_dts_ + sample_itr_->cts_offset;
    +
    582 }
    +
    583 
    +
    584 int64_t TrackRunIterator::duration() const {
    +
    585  DCHECK(IsSampleValid());
    +
    586  return sample_itr_->duration;
    +
    587 }
    +
    588 
    +
    589 bool TrackRunIterator::is_keyframe() const {
    +
    590  DCHECK(IsSampleValid());
    +
    591  return sample_itr_->is_keyframe;
    +
    592 }
    +
    593 
    +
    594 const TrackEncryption& TrackRunIterator::track_encryption() const {
    +
    595  if (is_audio())
    +
    596  return audio_description().sinf.info.track_encryption;
    +
    597  DCHECK(is_video());
    +
    598  return video_description().sinf.info.track_encryption;
    +
    599 }
    +
    600 
    +
    601 std::unique_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() {
    +
    602  std::vector<uint8_t> iv;
    +
    603  std::vector<SubsampleEntry> subsamples;
    +
    604 
    +
    605  size_t sample_idx = sample_itr_ - run_itr_->samples.begin();
    +
    606  if (sample_idx < run_itr_->sample_encryption_entries.size()) {
    +
    607  const SampleEncryptionEntry& sample_encryption_entry =
    +
    608  run_itr_->sample_encryption_entries[sample_idx];
    +
    609  DCHECK(is_encrypted());
    +
    610  DCHECK(!AuxInfoNeedsToBeCached());
    +
    611 
    +
    612  const size_t total_size_of_subsamples =
    +
    613  sample_encryption_entry.GetTotalSizeOfSubsamples();
    +
    614  if (total_size_of_subsamples != 0 &&
    +
    615  total_size_of_subsamples != static_cast<size_t>(sample_size())) {
    +
    616  LOG(ERROR) << "Incorrect CENC subsample size.";
    +
    617  return std::unique_ptr<DecryptConfig>();
    +
    618  }
    +
    619 
    +
    620  iv = sample_encryption_entry.initialization_vector;
    +
    621  subsamples = sample_encryption_entry.subsamples;
    +
    622  }
    +
    623 
    +
    624  FourCC protection_scheme = is_audio() ? audio_description().sinf.type.type
    +
    625  : video_description().sinf.type.type;
    +
    626  if (iv.empty()) {
    +
    627  if (protection_scheme != FOURCC_cbcs) {
    +
    628  LOG(WARNING)
    +
    629  << "Constant IV should only be used with 'cbcs' protection scheme.";
    +
    630  }
    +
    631  iv = track_encryption().default_constant_iv;
    +
    632  if (iv.empty()) {
    +
    633  LOG(ERROR) << "IV cannot be empty.";
    +
    634  return std::unique_ptr<DecryptConfig>();
    +
    635  }
    +
    636  }
    +
    637  return std::unique_ptr<DecryptConfig>(new DecryptConfig(
    +
    638  track_encryption().default_kid, iv, subsamples, protection_scheme,
    +
    639  track_encryption().default_crypt_byte_block,
    +
    640  track_encryption().default_skip_byte_block));
    +
    641 }
    +
    642 
    +
    643 int64_t TrackRunIterator::GetTimestampAdjustment(const Movie& movie,
    +
    644  const Track& track,
    +
    645  const TrackFragment* traf) {
    +
    646  const uint32_t track_id = track.header.track_id;
    +
    647  const auto iter = timestamp_adjustment_map_.find(track_id);
    +
    648  if (iter != timestamp_adjustment_map_.end())
    +
    649  return iter->second;
    +
    650 
    +
    651  int64_t timestamp_adjustment = 0;
    +
    652  const std::vector<EditListEntry>& edits = track.edit.list.edits;
    +
    653  if (!edits.empty()) {
    +
    654  // ISO/IEC 14496-12:2015 8.6.6 Edit List Box.
    +
    655  for (const EditListEntry& edit : edits) {
    +
    656  if (edit.media_rate_integer != 1) {
    +
    657  LOG(INFO) << "dwell EditListEntry is ignored.";
    +
    658  continue;
    +
    659  }
    +
    660 
    +
    661  if (edit.media_time < 0) {
    +
    662  // This is an empty edit. |segment_duration| is in movie's timescale
    +
    663  // instead of track's timescale.
    +
    664  const int64_t scaled_time =
    +
    665  Rescale(edit.segment_duration, movie.header.timescale,
    +
    666  track.media.header.timescale);
    +
    667  timestamp_adjustment += scaled_time;
    +
    668  } else {
    +
    669  timestamp_adjustment -= edit.media_time;
    +
    670  }
    +
    671  }
    +
    672  }
    +
    673 
    +
    674  if (timestamp_adjustment == 0) {
    +
    675  int64_t composition_offset = 0;
    +
    676  if (traf && !traf->runs.empty()) {
    +
    677  const auto& cts_offsets =
    +
    678  traf->runs.front().sample_composition_time_offsets;
    +
    679  if (!cts_offsets.empty())
    +
    680  composition_offset = cts_offsets.front();
    +
    681  } else {
    +
    682  CompositionOffsetIterator composition_offset_iter(
    +
    683  track.media.information.sample_table.composition_time_to_sample);
    +
    684  if (!composition_offset_iter.IsValid()) {
    +
    685  // This is the init (sub)segment of a fragmented mp4, which does not
    +
    686  // contain any samples. Exit with 0 adjustment and without storing
    +
    687  // |timestamp_adjustment|. This function will be called again later
    +
    688  // with track fragment |traf|. |timestamp_adjustment| will be computed
    +
    689  // and stored then.
    +
    690  return 0;
    +
    691  }
    +
    692  composition_offset = composition_offset_iter.sample_offset();
    +
    693  }
    +
    694 
    +
    695  int64_t decode_time = 0;
    +
    696  if (traf)
    +
    697  decode_time = traf->decode_time.decode_time;
    +
    698  if (composition_offset != 0 && decode_time == 0) {
    +
    699  LOG(WARNING) << "Seeing non-zero composition offset "
    +
    700  << composition_offset
    +
    701  << ". An EditList is probably missing.";
    +
    702  if (FLAGS_mp4_reset_initial_composition_offset_to_zero) {
    +
    703  LOG(WARNING)
    +
    704  << "Adjusting timestamps by " << -composition_offset
    +
    705  << ". Please file a bug to "
    +
    706  "https://github.com/google/shaka-packager/issues if you "
    +
    707  "do not think it is right or if you are seeing any problems.";
    +
    708  timestamp_adjustment = -composition_offset;
    +
    709  }
    +
    710  }
    +
    711  }
    +
    712 
    +
    713  timestamp_adjustment_map_.insert(
    +
    714  std::make_pair(track_id, timestamp_adjustment));
    +
    715  return timestamp_adjustment;
    +
    716 }
    +
    717 
    +
    718 } // namespace mp4
    +
    719 } // namespace media
    +
    720 } // namespace shaka
    + + + + + + + + +
    uint32_t NumSamples(uint32_t start_chunk, uint32_t end_chunk) const
    + + + + + + + + + + + + + + + +
    const VideoSampleEntry & video_description() const
    Only valid if is_video() is true.
    + + + +
    const AudioSampleEntry & audio_description() const
    Only valid if is_audio() is true.
    +
    bool CacheAuxInfo(const uint8_t *buf, int size)
    + + + +
    std::unique_ptr< DecryptConfig > GetDecryptConfig()
    +
    All the methods that are virtual are virtual for mocking.
    + + + + + + + +
    bool ParseFromSampleEncryptionData(uint8_t iv_size, std::vector< SampleEncryptionEntry > *sample_encryption_entries) const
    +
    std::vector< uint8_t > sample_encryption_data
    + + + + + +
    diff --git a/docs/db/d32/classshaka_1_1media_1_1mp2t_1_1EsParserDvb-members.html b/docs/db/d32/classshaka_1_1media_1_1mp2t_1_1EsParserDvb-members.html new file mode 100644 index 0000000000..2ff24b74d6 --- /dev/null +++ b/docs/db/d32/classshaka_1_1media_1_1mp2t_1_1EsParserDvb-members.html @@ -0,0 +1,92 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::mp2t::EsParserDvb Member List
    +
    +
    + +

    This is the complete list of members for shaka::media::mp2t::EsParserDvb, including all inherited members.

    + + + + + + + + + + + + +
    EmitSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    EmitTextSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    EsParserDvb(uint32_t pid, const NewStreamInfoCB &new_stream_info_cb, const EmitTextSampleCB &emit_sample_cb, const uint8_t *descriptor, size_t descriptor_length) (defined in shaka::media::mp2t::EsParserDvb)shaka::media::mp2t::EsParserDvb
    Flush() override (defined in shaka::media::mp2t::EsParserDvb)shaka::media::mp2t::EsParserDvbvirtual
    NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserDvb)shaka::media::mp2t::EsParserDvbvirtual
    pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    Reset() override (defined in shaka::media::mp2t::EsParserDvb)shaka::media::mp2t::EsParserDvbvirtual
    ~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
    ~EsParserDvb() override (defined in shaka::media::mp2t::EsParserDvb)shaka::media::mp2t::EsParserDvb
    + + + + diff --git a/docs/db/d38/classshaka_1_1media_1_1mp2t_1_1PesPacketGenerator-members.html b/docs/db/d38/classshaka_1_1media_1_1mp2t_1_1PesPacketGenerator-members.html index a3278b8dc1..f2d826e090 100644 --- a/docs/db/d38/classshaka_1_1media_1_1mp2t_1_1PesPacketGenerator-members.html +++ b/docs/db/d38/classshaka_1_1media_1_1mp2t_1_1PesPacketGenerator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/d3b/classshaka_1_1media_1_1VideoSliceHeaderParser-members.html b/docs/db/d3b/classshaka_1_1media_1_1VideoSliceHeaderParser-members.html index 3cce2ae6e4..f7e4212ae5 100644 --- a/docs/db/d3b/classshaka_1_1media_1_1VideoSliceHeaderParser-members.html +++ b/docs/db/d3b/classshaka_1_1media_1_1VideoSliceHeaderParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/db/d45/mpd__notify__muxer__listener_8h_source.html b/docs/db/d45/mpd__notify__muxer__listener_8h_source.html index efb258d725..bcd063a868 100644 --- a/docs/db/d45/mpd__notify__muxer__listener_8h_source.html +++ b/docs/db/d45/mpd__notify__muxer__listener_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/mpd_notify_muxer_listener.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    mpd_notify_muxer_listener.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Implementation of MuxerListener that deals with MpdNotifier.
    8 
    9 #ifndef PACKAGER_MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_
    10 #define PACKAGER_MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_
    11 
    12 #include <memory>
    13 #include <vector>
    14 
    15 #include "packager/base/optional.h"
    16 #include "packager/media/base/muxer_options.h"
    17 #include "packager/media/event/event_info.h"
    18 #include "packager/media/event/muxer_listener.h"
    19 
    20 namespace shaka {
    21 
    22 class MediaInfo;
    23 class MpdNotifier;
    24 
    25 namespace media {
    26 
    28  public:
    31  explicit MpdNotifyMuxerListener(MpdNotifier* mpd_notifier);
    32  ~MpdNotifyMuxerListener() override;
    33 
    36  void OnEncryptionInfoReady(bool is_initial_encryption_info,
    37  FourCC protection_scheme,
    38  const std::vector<uint8_t>& key_id,
    39  const std::vector<uint8_t>& iv,
    40  const std::vector<ProtectionSystemSpecificInfo>&
    41  key_system_info) override;
    42  void OnEncryptionStart() override;
    43  void OnMediaStart(const MuxerOptions& muxer_options,
    44  const StreamInfo& stream_info,
    45  uint32_t time_scale,
    46  ContainerType container_type) override;
    47  void OnSampleDurationReady(uint32_t sample_duration) override;
    48  void OnMediaEnd(const MediaRanges& media_ranges,
    49  float duration_seconds) override;
    50  void OnNewSegment(const std::string& file_name,
    51  int64_t start_time,
    52  int64_t duration,
    53  uint64_t segment_file_size) override;
    54  void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size);
    55  void OnCueEvent(int64_t timestamp, const std::string& cue_data) override;
    57 
    58  void set_accessibilities(const std::vector<std::string>& accessiblities) {
    59  accessibilities_ = accessiblities;
    60  }
    61 
    62  void set_roles(const std::vector<std::string>& roles) { roles_ = roles; }
    63 
    64  private:
    66  MpdNotifyMuxerListener& operator=(const MpdNotifyMuxerListener&) = delete;
    67 
    68  bool NotifyNewContainer();
    69 
    70  MpdNotifier* const mpd_notifier_ = nullptr;
    71  base::Optional<uint32_t> notification_id_;
    72  std::unique_ptr<MediaInfo> media_info_;
    73 
    74  std::vector<std::string> accessibilities_;
    75  std::vector<std::string> roles_;
    76 
    77  bool is_encrypted_ = false;
    78  // Storage for values passed to OnEncryptionInfoReady().
    79  FourCC protection_scheme_ = FOURCC_NULL;
    80  std::vector<uint8_t> default_key_id_;
    81  std::vector<ProtectionSystemSpecificInfo> key_system_info_;
    82 
    83  // Saves all the Subsegment and CueEvent information for VOD. This should be
    84  // used to call NotifyNewSegment() and NotifyCueEvent after
    85  // NotifyNewContainer() is called (in OnMediaEnd). This is not used for live
    86  // because NotifyNewSegment() is called immediately in OnNewSegment(), and
    87  // NotifyCueEvent is called immediately in OnCueEvent.
    88  std::vector<EventInfo> event_info_;
    89 };
    90 
    91 } // namespace media
    92 } // namespace shaka
    93 
    94 #endif // PACKAGER_MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    - -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    -
    void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
    -
    void OnSampleDurationReady(uint32_t sample_duration) override
    - -
    void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
    -
    MpdNotifyMuxerListener(MpdNotifier *mpd_notifier)
    - - -
    void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
    -
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    - -
    void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Implementation of MuxerListener that deals with MpdNotifier.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_
    +
    10 #define PACKAGER_MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_
    +
    11 
    +
    12 #include <memory>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/base/optional.h"
    +
    16 #include "packager/media/base/muxer_options.h"
    +
    17 #include "packager/media/event/event_info.h"
    +
    18 #include "packager/media/event/muxer_listener.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 
    +
    22 class MediaInfo;
    +
    23 class MpdNotifier;
    +
    24 
    +
    25 namespace media {
    +
    26 
    + +
    28  public:
    +
    31  explicit MpdNotifyMuxerListener(MpdNotifier* mpd_notifier);
    +
    32  ~MpdNotifyMuxerListener() override;
    +
    33 
    +
    36  void OnEncryptionInfoReady(bool is_initial_encryption_info,
    +
    37  FourCC protection_scheme,
    +
    38  const std::vector<uint8_t>& key_id,
    +
    39  const std::vector<uint8_t>& iv,
    +
    40  const std::vector<ProtectionSystemSpecificInfo>&
    +
    41  key_system_info) override;
    +
    42  void OnEncryptionStart() override;
    +
    43  void OnMediaStart(const MuxerOptions& muxer_options,
    +
    44  const StreamInfo& stream_info,
    +
    45  uint32_t time_scale,
    +
    46  ContainerType container_type) override;
    +
    47  void OnSampleDurationReady(uint32_t sample_duration) override;
    +
    48  void OnMediaEnd(const MediaRanges& media_ranges,
    +
    49  float duration_seconds) override;
    +
    50  void OnNewSegment(const std::string& file_name,
    +
    51  int64_t start_time,
    +
    52  int64_t duration,
    +
    53  uint64_t segment_file_size) override;
    +
    54  void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size);
    +
    55  void OnCueEvent(int64_t timestamp, const std::string& cue_data) override;
    +
    57 
    +
    58  void set_accessibilities(const std::vector<std::string>& accessiblities) {
    +
    59  accessibilities_ = accessiblities;
    +
    60  }
    +
    61 
    +
    62  void set_roles(const std::vector<std::string>& roles) { roles_ = roles; }
    +
    63 
    +
    64  private:
    + +
    66  MpdNotifyMuxerListener& operator=(const MpdNotifyMuxerListener&) = delete;
    +
    67 
    +
    68  bool NotifyNewContainer();
    +
    69 
    +
    70  MpdNotifier* const mpd_notifier_ = nullptr;
    +
    71  base::Optional<uint32_t> notification_id_;
    +
    72  std::unique_ptr<MediaInfo> media_info_;
    +
    73 
    +
    74  std::vector<std::string> accessibilities_;
    +
    75  std::vector<std::string> roles_;
    +
    76 
    +
    77  bool is_encrypted_ = false;
    +
    78  // Storage for values passed to OnEncryptionInfoReady().
    +
    79  FourCC protection_scheme_ = FOURCC_NULL;
    +
    80  std::vector<uint8_t> default_key_id_;
    +
    81  std::vector<ProtectionSystemSpecificInfo> key_system_info_;
    +
    82 
    +
    83  // Saves all the Subsegment and CueEvent information for VOD. This should be
    +
    84  // used to call NotifyNewSegment() and NotifyCueEvent after
    +
    85  // NotifyNewContainer() is called (in OnMediaEnd). This is not used for live
    +
    86  // because NotifyNewSegment() is called immediately in OnNewSegment(), and
    +
    87  // NotifyCueEvent is called immediately in OnCueEvent.
    +
    88  std::vector<EventInfo> event_info_;
    +
    89 };
    +
    90 
    +
    91 } // namespace media
    +
    92 } // namespace shaka
    +
    93 
    +
    94 #endif // PACKAGER_MEDIA_EVENT_MPD_NOTIFY_MUXER_LISTENER_H_
    + + +
    void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
    +
    void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
    +
    void OnSampleDurationReady(uint32_t sample_duration) override
    + +
    void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
    +
    MpdNotifyMuxerListener(MpdNotifier *mpd_notifier)
    +
    void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
    +
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    +
    void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    + +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/db/d49/structshaka_1_1media_1_1EventInfo.html b/docs/db/d49/structshaka_1_1media_1_1EventInfo.html index 6fe64a806c..b992cee27f 100644 --- a/docs/db/d49/structshaka_1_1media_1_1EventInfo.html +++ b/docs/db/d49/structshaka_1_1media_1_1EventInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::EventInfo Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/d4b/classshaka_1_1MockAdaptationSet.html b/docs/db/d4b/classshaka_1_1MockAdaptationSet.html index a45b196230..fa3c794f0b 100644 --- a/docs/db/d4b/classshaka_1_1MockAdaptationSet.html +++ b/docs/db/d4b/classshaka_1_1MockAdaptationSet.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MockAdaptationSet Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::AdaptationSet - -
    + + @@ -118,8 +121,8 @@ Public Member Functions - - + + @@ -142,20 +145,24 @@ const std::list< + + + +

    Public Member Functions

     
    virtual void AddRole (Role role)
     
    xml::scoped_xml_ptr< xmlNode > GetXml ()
     
    base::Optional< xml::XmlNodeGetXml ()
     
    virtual void ForceSetSegmentAlignment (bool segment_alignment)
     
    virtual void AddAdaptationSetSwitching (const AdaptationSet *adaptation_set)
     
    bool IsVideo () const
     
    const std::string & codec () const
     
    void set_codec (const std::string &codec)
     
    @@ -173,9 +180,7 @@ Additional Inherited Members diff --git a/docs/db/d4e/classshaka_1_1media_1_1mp4_1_1CompositionOffsetIterator.html b/docs/db/d4e/classshaka_1_1media_1_1mp4_1_1CompositionOffsetIterator.html index a57772f5ab..09caba3ed6 100644 --- a/docs/db/d4e/classshaka_1_1media_1_1mp4_1_1CompositionOffsetIterator.html +++ b/docs/db/d4e/classshaka_1_1media_1_1mp4_1_1CompositionOffsetIterator.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::mp4::CompositionOffsetIterator Class Reference @@ -29,18 +29,21 @@

    Additional Inherited Members

    - Public Types inherited from shaka::AdaptationSet
    enum  Role {
    -  kRoleUnknown, -kRoleCaption, -kRoleSubtitle, -kRoleMain, -
    -  kRoleAlternate, -kRoleSupplementary, -kRoleCommentary, -kRoleDub +  kRoleUnknown +, kRoleCaption +, kRoleSubtitle +, kRoleMain +,
    +  kRoleAlternate +, kRoleSupplementary +, kRoleCommentary +, kRoleDub
    }
     
    - + +/* @license-end */
    diff --git a/docs/db/d51/mp2t__media__parser_8h_source.html b/docs/db/d51/mp2t__media__parser_8h_source.html index 1f2010a615..4b9c1a1583 100644 --- a/docs/db/d51/mp2t__media__parser_8h_source.html +++ b/docs/db/d51/mp2t__media__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/mp2t_media_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    mp2t_media_parser.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_MP2T_MEDIA_PARSER_H_
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_MP2T_MEDIA_PARSER_H_
    7 
    8 #include <deque>
    9 #include <map>
    10 #include <memory>
    11 
    12 #include "packager/media/base/byte_queue.h"
    13 #include "packager/media/base/media_parser.h"
    14 #include "packager/media/base/stream_info.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 class MediaSample;
    20 
    21 namespace mp2t {
    22 
    23 class PidState;
    24 class TsPacket;
    25 class TsSection;
    26 
    27 typedef std::deque<std::shared_ptr<MediaSample>> SampleQueue;
    28 
    29 class Mp2tMediaParser : public MediaParser {
    30  public:
    32  ~Mp2tMediaParser() override;
    33 
    36  void Init(const InitCB& init_cb,
    37  const NewSampleCB& new_sample_cb,
    38  KeySource* decryption_key_source) override;
    39  bool Flush() override WARN_UNUSED_RESULT;
    40  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
    42 
    43  private:
    44  typedef std::map<int, std::unique_ptr<PidState>> PidMap;
    45 
    46  // Callback invoked to register a Program Map Table.
    47  // Note: Does nothing if the PID is already registered.
    48  void RegisterPmt(int program_number, int pmt_pid);
    49 
    50  // Callback invoked to register a PES pid.
    51  // Possible values for |media_type| are defined in:
    52  // ISO-13818.1 / ITU H.222 Table 2.34 "Media type assignments".
    53  // |pes_pid| is part of the Program Map Table refered by |pmt_pid|.
    54  void RegisterPes(int pmt_pid, int pes_pid, int media_type);
    55 
    56  // Callback invoked each time the audio/video decoder configuration is
    57  // changed.
    58  void OnNewStreamInfo(const std::shared_ptr<StreamInfo>& new_stream_info);
    59 
    60  // Callback invoked by the ES media parser
    61  // to emit a new audio/video access unit.
    62  void OnEmitSample(uint32_t pes_pid,
    63  const std::shared_ptr<MediaSample>& new_sample);
    64 
    65  // Invoke the initialization callback if needed.
    66  bool FinishInitializationIfNeeded();
    67 
    68  bool EmitRemainingSamples();
    69 
    72  void set_sbr_in_mime_type(bool sbr_in_mimetype) {
    73  sbr_in_mimetype_ = sbr_in_mimetype; }
    74 
    75  // List of callbacks.
    76  InitCB init_cb_;
    77  NewSampleCB new_sample_cb_;
    78 
    79  bool sbr_in_mimetype_;
    80 
    81  // Bytes of the TS media.
    82  ByteQueue ts_byte_queue_;
    83 
    84  // List of PIDs and their states.
    85  PidMap pids_;
    86 
    87  // Whether |init_cb_| has been invoked.
    88  bool is_initialized_;
    89 
    90  // A map used to track unsupported stream types and make sure the error is
    91  // only logged once.
    92  std::map<uint8_t, bool> stream_type_logged_once_;
    93 
    94  DISALLOW_COPY_AND_ASSIGN(Mp2tMediaParser);
    95 };
    96 
    97 } // namespace mp2t
    98 } // namespace media
    99 } // namespace shaka
    100 
    101 #endif
    -
    void Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
    -
    All the methods that are virtual are virtual for mocking.
    - -
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:34
    -
    bool Flush() override WARN_UNUSED_RESULT
    -
    base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
    Definition: media_parser.h:43
    - -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_MP2T_MEDIA_PARSER_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_MP2T_MEDIA_PARSER_H_
    +
    7 
    +
    8 #include <bitset>
    +
    9 #include <deque>
    +
    10 #include <map>
    +
    11 #include <memory>
    +
    12 
    +
    13 #include "packager/media/base/byte_queue.h"
    +
    14 #include "packager/media/base/media_parser.h"
    +
    15 #include "packager/media/base/stream_info.h"
    +
    16 #include "packager/media/formats/mp2t/ts_stream_type.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    +
    21 class MediaSample;
    +
    22 
    +
    23 namespace mp2t {
    +
    24 
    +
    25 class PidState;
    +
    26 class TsPacket;
    +
    27 class TsSection;
    +
    28 
    +
    29 class Mp2tMediaParser : public MediaParser {
    +
    30  public:
    + +
    32  ~Mp2tMediaParser() override;
    +
    33 
    +
    36  void Init(const InitCB& init_cb,
    +
    37  const NewMediaSampleCB& new_media_sample_cb,
    +
    38  const NewTextSampleCB& new_text_sample_cb,
    +
    39  KeySource* decryption_key_source) override;
    +
    40  bool Flush() override WARN_UNUSED_RESULT;
    +
    41  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
    +
    43 
    +
    44  private:
    +
    45  // Callback invoked to register a Program Map Table.
    +
    46  // Note: Does nothing if the PID is already registered.
    +
    47  void RegisterPmt(int program_number, int pmt_pid);
    +
    48 
    +
    49  // Callback invoked to register a PES pid.
    +
    50  // Possible values for |media_type| are defined in:
    +
    51  // ISO-13818.1 / ITU H.222 Table 2.34 "Media type assignments".
    +
    52  // |pes_pid| is part of the Program Map Table refered by |pmt_pid|.
    +
    53  void RegisterPes(int pmt_pid,
    +
    54  int pes_pid,
    +
    55  TsStreamType media_type,
    +
    56  const uint8_t* descriptor,
    +
    57  size_t descriptor_length);
    +
    58 
    +
    59  // Callback invoked each time the audio/video decoder configuration is
    +
    60  // changed.
    +
    61  void OnNewStreamInfo(uint32_t pes_pid,
    +
    62  std::shared_ptr<StreamInfo> new_stream_info);
    +
    63 
    +
    64  // Callback invoked by the ES media parser
    +
    65  // to emit a new audio/video access unit.
    +
    66  void OnEmitMediaSample(uint32_t pes_pid,
    +
    67  std::shared_ptr<MediaSample> new_sample);
    +
    68  void OnEmitTextSample(uint32_t pes_pid,
    +
    69  std::shared_ptr<TextSample> new_sample);
    +
    70 
    +
    71  // Invoke the initialization callback if needed.
    +
    72  bool FinishInitializationIfNeeded();
    +
    73 
    +
    74  bool EmitRemainingSamples();
    +
    75 
    +
    78  void set_sbr_in_mime_type(bool sbr_in_mimetype) {
    +
    79  sbr_in_mimetype_ = sbr_in_mimetype;
    +
    80  }
    +
    81 
    +
    82  // List of callbacks.
    +
    83  InitCB init_cb_;
    +
    84  NewMediaSampleCB new_media_sample_cb_;
    +
    85  NewTextSampleCB new_text_sample_cb_;
    +
    86 
    +
    87  bool sbr_in_mimetype_;
    +
    88 
    +
    89  // Bytes of the TS media.
    +
    90  ByteQueue ts_byte_queue_;
    +
    91 
    +
    92  // Map of PIDs and their states. Use an ordered map so manifest generation
    +
    93  // has a deterministic order.
    +
    94  std::map<int, std::unique_ptr<PidState>> pids_;
    +
    95 
    +
    96  // Whether |init_cb_| has been invoked.
    +
    97  bool is_initialized_;
    +
    98 
    +
    99  // A map used to track unsupported stream types and make sure the error is
    +
    100  // only logged once.
    +
    101  std::bitset<256> stream_type_logged_once_;
    +
    102 
    +
    103  DISALLOW_COPY_AND_ASSIGN(Mp2tMediaParser);
    +
    104 };
    +
    105 
    +
    106 } // namespace mp2t
    +
    107 } // namespace media
    +
    108 } // namespace shaka
    +
    109 
    +
    110 #endif
    + +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    + +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
    Definition: media_parser.h:53
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    + +
    void Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
    +
    bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    +
    bool Flush() override WARN_UNUSED_RESULT
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/d51/two__pass__single__segment__segmenter_8h_source.html b/docs/db/d51/two__pass__single__segment__segmenter_8h_source.html index 41aa79f7a0..3936e342f7 100644 --- a/docs/db/d51/two__pass__single__segment__segmenter_8h_source.html +++ b/docs/db/d51/two__pass__single__segment__segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/two_pass_single_segment_segmenter.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    two_pass_single_segment_segmenter.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_TWO_PASS_SINGLE_SEGMENT_SEGMENTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_TWO_PASS_SINGLE_SEGMENT_SEGMENTER_H_
    9 
    10 #include <memory>
    11 #include <string>
    12 
    13 #include "packager/media/formats/webm/mkv_writer.h"
    14 #include "packager/media/formats/webm/single_segment_segmenter.h"
    15 #include "packager/status.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    20 struct MuxerOptions;
    21 
    22 namespace webm {
    23 
    27  public:
    28  explicit TwoPassSingleSegmentSegmenter(const MuxerOptions& options);
    30 
    31  // Segmenter implementation overrides.
    32  Status DoInitialize() override;
    33  Status DoFinalize() override;
    34 
    35  private:
    40  bool CopyFileWithClusterRewrite(File* source,
    41  MkvWriter* dest,
    42  uint64_t last_size);
    43 
    44  std::string temp_file_name_;
    45 
    46  DISALLOW_COPY_AND_ASSIGN(TwoPassSingleSegmentSegmenter);
    47 };
    48 
    49 } // namespace webm
    50 } // namespace media
    51 } // namespace shaka
    52 
    53 #endif // PACKAGER_MEDIA_FORMATS_WEBM_TWO_PASS_SINGLE_SEGMENT_SEGMENTER_H_
    -
    Define an abstract file interface.
    Definition: file.h:26
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    An implementation of IMkvWriter using our File type.
    Definition: mkv_writer.h:21
    - +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_TWO_PASS_SINGLE_SEGMENT_SEGMENTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_TWO_PASS_SINGLE_SEGMENT_SEGMENTER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <string>
    +
    12 
    +
    13 #include "packager/media/formats/webm/mkv_writer.h"
    +
    14 #include "packager/media/formats/webm/single_segment_segmenter.h"
    +
    15 #include "packager/status.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    +
    20 struct MuxerOptions;
    +
    21 
    +
    22 namespace webm {
    +
    23 
    + +
    27  public:
    +
    28  explicit TwoPassSingleSegmentSegmenter(const MuxerOptions& options);
    + +
    30 
    +
    31  // Segmenter implementation overrides.
    +
    32  Status DoInitialize() override;
    +
    33  Status DoFinalize() override;
    +
    34 
    +
    35  private:
    +
    40  bool CopyFileWithClusterRewrite(File* source,
    +
    41  MkvWriter* dest,
    +
    42  uint64_t last_size);
    +
    43 
    +
    44  std::string temp_file_name_;
    +
    45 
    +
    46  DISALLOW_COPY_AND_ASSIGN(TwoPassSingleSegmentSegmenter);
    +
    47 };
    +
    48 
    +
    49 } // namespace webm
    +
    50 } // namespace media
    +
    51 } // namespace shaka
    +
    52 
    +
    53 #endif // PACKAGER_MEDIA_FORMATS_WEBM_TWO_PASS_SINGLE_SEGMENT_SEGMENTER_H_
    +
    Define an abstract file interface.
    Definition: file.h:27
    + +
    An implementation of IMkvWriter using our File type.
    Definition: mkv_writer.h:21
    + + +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/db/d59/media__handler__test__base_8h_source.html b/docs/db/d59/media__handler__test__base_8h_source.html index ffd63c87c3..865d5617b4 100644 --- a/docs/db/d59/media__handler__test__base_8h_source.html +++ b/docs/db/d59/media__handler__test__base_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/media_handler_test_base.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    media_handler_test_base.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
    8 #define PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
    9 
    10 #include <gmock/gmock.h>
    11 #include <gtest/gtest.h>
    12 
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/media/base/media_handler.h"
    15 #include "packager/media/base/video_stream_info.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    20 std::string BoolToString(bool value);
    21 std::string ToPrettyString(const std::string& str);
    22 
    23 bool TryMatchStreamDataType(const StreamDataType& actual,
    24  const StreamDataType& expected,
    25  ::testing::MatchResultListener* listener);
    26 
    27 bool TryMatchStreamType(const StreamType& actual,
    28  const StreamType& expected,
    29  ::testing::MatchResultListener* listener);
    30 
    31 template <typename T, typename M>
    32 bool TryMatch(const T& value,
    33  const M& matcher,
    34  ::testing::MatchResultListener* listener,
    35  const char* value_name) {
    36  if (!ExplainMatchResult(matcher, value, listener)) {
    37  // Need a space at the start of the string in the case that
    38  // it gets combined with another string.
    39  *listener << " Mismatch on " << value_name;
    40  return false;
    41  }
    42 
    43  return true;
    44 }
    45 
    46 MATCHER_P4(IsStreamInfo, stream_index, time_scale, encrypted, language, "") {
    47  if (!TryMatchStreamDataType(arg->stream_data_type,
    48  StreamDataType::kStreamInfo, result_listener)) {
    49  return false;
    50  }
    51 
    52  const std::string is_encrypted_string =
    53  BoolToString(arg->stream_info->is_encrypted());
    54 
    55  *result_listener << "which is (" << arg->stream_index << ", "
    56  << arg->stream_info->time_scale() << ", "
    57  << is_encrypted_string << ", "
    58  << arg->stream_info->language() << ")";
    59 
    60  return TryMatch(arg->stream_index, stream_index, result_listener,
    61  "stream_index") &&
    62  TryMatch(arg->stream_info->time_scale(), time_scale, result_listener,
    63  "time_scale") &&
    64  TryMatch(arg->stream_info->is_encrypted(), encrypted, result_listener,
    65  "is_encrypted") &&
    66  TryMatch(arg->stream_info->language(), language, result_listener,
    67  "language");
    68 }
    69 
    70 MATCHER_P3(IsVideoStream, stream_index, trick_play_factor, playback_rate, "") {
    71  if (!TryMatchStreamDataType(arg->stream_data_type,
    72  StreamDataType::kStreamInfo, result_listener)) {
    73  return false;
    74  }
    75 
    76  if (!TryMatchStreamType(arg->stream_info->stream_type(), kStreamVideo,
    77  result_listener)) {
    78  return false;
    79  }
    80 
    81  const VideoStreamInfo* info =
    82  static_cast<const VideoStreamInfo*>(arg->stream_info.get());
    83 
    84  *result_listener << "which is (" << arg->stream_index << ", "
    85  << info->trick_play_factor() << ", " << info->playback_rate()
    86  << ")";
    87 
    88  return TryMatch(arg->stream_index, stream_index, result_listener,
    89  "stream_index") &&
    90  TryMatch(info->trick_play_factor(), trick_play_factor, result_listener,
    91  "trick_play_factor") &&
    92  TryMatch(info->playback_rate(), playback_rate, result_listener,
    93  "playback_rate");
    94 }
    95 
    96 MATCHER_P5(IsSegmentInfo,
    97  stream_index,
    98  start_timestamp,
    99  duration,
    100  subsegment,
    101  encrypted,
    102  "") {
    103  if (!TryMatchStreamDataType(arg->stream_data_type,
    104  StreamDataType::kSegmentInfo, result_listener)) {
    105  return false;
    106  }
    107 
    108  const std::string is_subsegment_string =
    109  BoolToString(arg->segment_info->is_subsegment);
    110  const std::string is_encrypted_string =
    111  BoolToString(arg->segment_info->is_encrypted);
    112 
    113  *result_listener << "which is (" << arg->stream_index << ", "
    114  << arg->segment_info->start_timestamp << ", "
    115  << arg->segment_info->duration << ", "
    116  << is_subsegment_string << ", " << is_encrypted_string
    117  << ")";
    118 
    119  return TryMatch(arg->stream_index, stream_index, result_listener,
    120  "stream_index") &&
    121  TryMatch(arg->segment_info->start_timestamp, start_timestamp,
    122  result_listener, "start_timestamp") &&
    123  TryMatch(arg->segment_info->duration, duration, result_listener,
    124  "duration") &&
    125  TryMatch(arg->segment_info->is_subsegment, subsegment, result_listener,
    126  "is_subsegment") &&
    127  TryMatch(arg->segment_info->is_encrypted, encrypted, result_listener,
    128  "is_encrypted");
    129 }
    130 
    131 MATCHER_P6(MatchEncryptionConfig,
    132  protection_scheme,
    133  crypt_byte_block,
    134  skip_byte_block,
    135  per_sample_iv_size,
    136  constant_iv,
    137  key_id,
    138  "") {
    139  const std::string constant_iv_hex =
    140  base::HexEncode(arg.constant_iv.data(), arg.constant_iv.size());
    141  const std::string key_id_hex =
    142  base::HexEncode(arg.key_id.data(), arg.key_id.size());
    143  const std::string protection_scheme_as_string =
    144  FourCCToString(arg.protection_scheme);
    145  // Convert to integers so that they will print as a number and not a uint8_t
    146  // (char).
    147  const int crypt_byte_as_int = static_cast<int>(arg.crypt_byte_block);
    148  const int skip_byte_as_int = static_cast<int>(arg.skip_byte_block);
    149 
    150  *result_listener << "which is (" << protection_scheme_as_string << ", "
    151  << crypt_byte_as_int << ", " << skip_byte_as_int << ", "
    152  << arg.per_sample_iv_size << ", " << constant_iv_hex << ", "
    153  << key_id_hex << ")";
    154 
    155  return TryMatch(arg.protection_scheme, protection_scheme, result_listener,
    156  "protection_scheme") &&
    157  TryMatch(arg.crypt_byte_block, crypt_byte_block, result_listener,
    158  "crypt_byte_block") &&
    159  TryMatch(arg.skip_byte_block, skip_byte_block, result_listener,
    160  "skip_byte_block") &&
    161  TryMatch(arg.per_sample_iv_size, per_sample_iv_size, result_listener,
    162  "per_sample_iv_size") &&
    163  TryMatch(arg.constant_iv, constant_iv, result_listener,
    164  "constant_iv") &&
    165  TryMatch(arg.key_id, key_id, result_listener, "key_id");
    166 }
    167 
    168 MATCHER_P5(IsMediaSample,
    169  stream_index,
    170  timestamp,
    171  duration,
    172  encrypted,
    173  keyframe,
    174  "") {
    175  if (!TryMatchStreamDataType(arg->stream_data_type,
    176  StreamDataType::kMediaSample, result_listener)) {
    177  return false;
    178  }
    179 
    180  const std::string is_encrypted_string =
    181  BoolToString(arg->media_sample->is_encrypted());
    182  const std::string is_key_frame_string =
    183  BoolToString(arg->media_sample->is_key_frame());
    184 
    185  *result_listener << "which is (" << arg->stream_index << ", "
    186  << arg->media_sample->dts() << ", "
    187  << arg->media_sample->duration() << ", "
    188  << is_encrypted_string << ", " << is_key_frame_string << ")";
    189 
    190  return TryMatch(arg->stream_index, stream_index, result_listener,
    191  "stream_index") &&
    192  TryMatch(arg->media_sample->dts(), timestamp, result_listener,
    193  "dts") &&
    194  TryMatch(arg->media_sample->duration(), duration, result_listener,
    195  "duration") &&
    196  TryMatch(arg->media_sample->is_encrypted(), encrypted, result_listener,
    197  "is_encrypted") &&
    198  TryMatch(arg->media_sample->is_key_frame(), keyframe, result_listener,
    199  "is_key_frame");
    200 }
    201 
    202 MATCHER_P6(IsTextSample,
    203  stream_index,
    204  id,
    205  start_time,
    206  end_time,
    207  settings,
    208  payload,
    209  "") {
    210  if (!TryMatchStreamDataType(arg->stream_data_type,
    211  StreamDataType::kTextSample, result_listener)) {
    212  return false;
    213  }
    214 
    215  *result_listener << "which is (" << arg->stream_index << ", "
    216  << ToPrettyString(arg->text_sample->id()) << ", "
    217  << arg->text_sample->start_time() << ", "
    218  << arg->text_sample->EndTime() << ", "
    219  << ToPrettyString(arg->text_sample->settings()) << ", "
    220  << ToPrettyString(arg->text_sample->payload()) << ")";
    221 
    222  return TryMatch(arg->stream_index, stream_index, result_listener,
    223  "stream_index") &&
    224  TryMatch(arg->text_sample->id(), id, result_listener, "id") &&
    225  TryMatch(arg->text_sample->start_time(), start_time, result_listener,
    226  "start_time") &&
    227  TryMatch(arg->text_sample->EndTime(), end_time, result_listener,
    228  "EndTime") &&
    229  TryMatch(arg->text_sample->settings(), settings, result_listener,
    230  "settings") &&
    231  TryMatch(arg->text_sample->payload(), payload, result_listener,
    232  "payload");
    233 }
    234 
    235 MATCHER_P2(IsCueEvent, stream_index, time_in_seconds, "") {
    236  if (!TryMatchStreamDataType(arg->stream_data_type, StreamDataType::kCueEvent,
    237  result_listener)) {
    238  return false;
    239  }
    240 
    241  *result_listener << "which is (" << arg->stream_index << ", "
    242  << arg->cue_event->time_in_seconds << ")";
    243 
    244  return TryMatch(arg->stream_index, stream_index, result_listener,
    245  "stream_index") &&
    246  TryMatch(arg->cue_event->time_in_seconds, time_in_seconds,
    247  result_listener, "time_in_seconds");
    248 }
    249 
    251  public:
    255 
    256  private:
    257  bool ValidateOutputStreamIndex(size_t index) const override;
    258  Status InitializeInternal() override;
    259  Status Process(std::unique_ptr<StreamData> stream_data) override;
    260 };
    261 
    263  public:
    264  MOCK_METHOD1(OnProcess, void(const StreamData*));
    265  MOCK_METHOD1(OnFlush, void(size_t index));
    266 
    267  private:
    268  Status InitializeInternal() override;
    269  Status Process(std::unique_ptr<StreamData> stream_data) override;
    270  Status OnFlushRequest(size_t index) override;
    271 };
    272 
    274  public:
    275  const std::vector<std::unique_ptr<StreamData>>& Cache() const {
    276  return stream_data_vector_;
    277  }
    278 
    279  // TODO(vaage) : Remove the use of clear in our tests as it can make flow
    280  // of the test harder to understand.
    281  void Clear() { stream_data_vector_.clear(); }
    282 
    283  private:
    284  Status InitializeInternal() override;
    285  Status Process(std::unique_ptr<StreamData> stream_data) override;
    286  Status OnFlushRequest(size_t input_stream_index) override;
    287  bool ValidateOutputStreamIndex(size_t stream_index) const override;
    288 
    289  std::vector<std::unique_ptr<StreamData>> stream_data_vector_;
    290 };
    291 
    292 class MediaHandlerTestBase : public ::testing::Test {
    293  public:
    294  MediaHandlerTestBase() = default;
    295 
    296  protected:
    297  bool IsVideoCodec(Codec codec) const;
    298 
    299  std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale) const;
    300 
    301  std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
    302  uint32_t width,
    303  uint64_t height) const;
    304 
    305  std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
    306  Codec codec) const;
    307 
    308  std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
    309  Codec codec,
    310  uint32_t width,
    311  uint64_t height) const;
    312 
    313  std::unique_ptr<StreamInfo> GetAudioStreamInfo(uint32_t time_scale) const;
    314 
    315  std::unique_ptr<StreamInfo> GetAudioStreamInfo(uint32_t time_scale,
    316  Codec codec) const;
    317 
    318  std::shared_ptr<MediaSample> GetMediaSample(int64_t timestamp,
    319  int64_t duration,
    320  bool is_keyframe) const;
    321 
    322  std::shared_ptr<MediaSample> GetMediaSample(int64_t timestamp,
    323  int64_t duration,
    324  bool is_keyframe,
    325  const uint8_t* data,
    326  size_t data_length) const;
    327 
    328  std::unique_ptr<SegmentInfo> GetSegmentInfo(int64_t start_timestamp,
    329  int64_t duration,
    330  bool is_subsegment) const;
    331 
    332  std::unique_ptr<StreamInfo> GetTextStreamInfo(uint32_t timescale) const;
    333 
    334  std::unique_ptr<TextSample> GetTextSample(const std::string& id,
    335  int64_t start,
    336  int64_t end,
    337  const std::string& payload) const;
    338 
    339  std::unique_ptr<CueEvent> GetCueEvent(double time_in_seconds) const;
    340 
    341  // Connect and initialize all handlers.
    342  Status SetUpAndInitializeGraph(std::shared_ptr<MediaHandler> handler,
    343  size_t input_count,
    344  size_t output_count);
    345 
    346  // Get the input handler at |index|. The values of |index| will match the
    347  // call to |AddInput|.
    348  FakeInputMediaHandler* Input(size_t index);
    349 
    350  // Get the output handler at |index|. The values of |index| will match the
    351  // call to |AddOutput|.
    352  MockOutputMediaHandler* Output(size_t index);
    353 
    354  private:
    356  MediaHandlerTestBase& operator=(const MediaHandlerTestBase&) = delete;
    357 
    358  std::shared_ptr<MediaHandler> handler_;
    359 
    360  std::vector<std::shared_ptr<FakeInputMediaHandler>> inputs_;
    361  std::vector<std::shared_ptr<MockOutputMediaHandler>> outputs_;
    362 };
    363 
    365  public:
    367 
    368  protected:
    370  void SetUpGraph(size_t num_inputs,
    371  size_t num_outputs,
    372  std::shared_ptr<MediaHandler> handler);
    373 
    375  const std::vector<std::unique_ptr<StreamData>>& GetOutputStreamDataVector()
    376  const;
    377 
    379  void ClearOutputStreamDataVector();
    380 
    382  std::shared_ptr<MediaHandler> some_handler() { return some_handler_; }
    383 
    385  std::shared_ptr<CachingMediaHandler> next_handler() { return next_handler_; }
    386 
    387  private:
    390  delete;
    391 
    392  // Downstream handler used in testing graph.
    393  std::shared_ptr<CachingMediaHandler> next_handler_;
    394  // Some random handler which can be used for testing.
    395  std::shared_ptr<MediaHandler> some_handler_;
    396 };
    397 
    398 } // namespace media
    399 } // namespace shaka
    400 
    401 #endif // PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
    -
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    - - - -
    virtual Status OnFlushRequest(size_t input_stream_index)
    Event handler for flush request at the specific input stream index.
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    Status FlushAllDownstreams()
    Flush all connected downstream handlers.
    -
    Status FlushDownstream(size_t output_stream_index)
    Flush the downstream connected at the specified output stream index.
    - - -
    std::shared_ptr< CachingMediaHandler > next_handler()
    -
    std::shared_ptr< MediaHandler > some_handler()
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
    +
    8 #define PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
    +
    9 
    +
    10 #include <gmock/gmock.h>
    +
    11 #include <gtest/gtest.h>
    +
    12 
    +
    13 #include "packager/base/strings/string_number_conversions.h"
    +
    14 #include "packager/media/base/media_handler.h"
    +
    15 #include "packager/media/base/video_stream_info.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    +
    20 std::string BoolToString(bool value);
    +
    21 std::string ToPrettyString(const std::string& str);
    +
    22 
    +
    23 bool TryMatchStreamDataType(const StreamDataType& actual,
    +
    24  const StreamDataType& expected,
    +
    25  ::testing::MatchResultListener* listener);
    +
    26 
    +
    27 bool TryMatchStreamType(const StreamType& actual,
    +
    28  const StreamType& expected,
    +
    29  ::testing::MatchResultListener* listener);
    +
    30 
    +
    31 template <typename T, typename M>
    +
    32 bool TryMatch(const T& value,
    +
    33  const M& matcher,
    +
    34  ::testing::MatchResultListener* listener,
    +
    35  const char* value_name) {
    +
    36  if (!ExplainMatchResult(matcher, value, listener)) {
    +
    37  // Need a space at the start of the string in the case that
    +
    38  // it gets combined with another string.
    +
    39  *listener << " Mismatch on " << value_name;
    +
    40  return false;
    +
    41  }
    +
    42 
    +
    43  return true;
    +
    44 }
    +
    45 
    +
    46 MATCHER_P(IsPsshInfoWithSystemId,
    +
    47  system_id,
    +
    48  std::string(negation ? "doesn't " : "") + " have system ID " +
    +
    49  testing::PrintToString(system_id)) {
    +
    50  *result_listener << "which is (" << testing::PrintToString(arg.system_id)
    +
    51  << ")";
    +
    52  return arg.system_id == system_id;
    +
    53 }
    +
    54 
    +
    55 MATCHER_P4(IsStreamInfo, stream_index, time_scale, encrypted, language, "") {
    +
    56  if (!TryMatchStreamDataType(arg->stream_data_type,
    +
    57  StreamDataType::kStreamInfo, result_listener)) {
    +
    58  return false;
    +
    59  }
    +
    60 
    +
    61  const std::string is_encrypted_string =
    +
    62  BoolToString(arg->stream_info->is_encrypted());
    +
    63 
    +
    64  *result_listener << "which is (" << arg->stream_index << ", "
    +
    65  << arg->stream_info->time_scale() << ", "
    +
    66  << is_encrypted_string << ", "
    +
    67  << arg->stream_info->language() << ")";
    +
    68 
    +
    69  return TryMatch(arg->stream_index, stream_index, result_listener,
    +
    70  "stream_index") &&
    +
    71  TryMatch(arg->stream_info->time_scale(), time_scale, result_listener,
    +
    72  "time_scale") &&
    +
    73  TryMatch(arg->stream_info->is_encrypted(), encrypted, result_listener,
    +
    74  "is_encrypted") &&
    +
    75  TryMatch(arg->stream_info->language(), language, result_listener,
    +
    76  "language");
    +
    77 }
    +
    78 
    +
    79 MATCHER_P3(IsVideoStream, stream_index, trick_play_factor, playback_rate, "") {
    +
    80  if (!TryMatchStreamDataType(arg->stream_data_type,
    +
    81  StreamDataType::kStreamInfo, result_listener)) {
    +
    82  return false;
    +
    83  }
    +
    84 
    +
    85  if (!TryMatchStreamType(arg->stream_info->stream_type(), kStreamVideo,
    +
    86  result_listener)) {
    +
    87  return false;
    +
    88  }
    +
    89 
    +
    90  const VideoStreamInfo* info =
    +
    91  static_cast<const VideoStreamInfo*>(arg->stream_info.get());
    +
    92 
    +
    93  *result_listener << "which is (" << arg->stream_index << ", "
    +
    94  << info->trick_play_factor() << ", " << info->playback_rate()
    +
    95  << ")";
    +
    96 
    +
    97  return TryMatch(arg->stream_index, stream_index, result_listener,
    +
    98  "stream_index") &&
    +
    99  TryMatch(info->trick_play_factor(), trick_play_factor, result_listener,
    +
    100  "trick_play_factor") &&
    +
    101  TryMatch(info->playback_rate(), playback_rate, result_listener,
    +
    102  "playback_rate");
    +
    103 }
    +
    104 
    +
    105 MATCHER_P5(IsSegmentInfo,
    +
    106  stream_index,
    +
    107  start_timestamp,
    +
    108  duration,
    +
    109  subsegment,
    +
    110  encrypted,
    +
    111  "") {
    +
    112  if (!TryMatchStreamDataType(arg->stream_data_type,
    +
    113  StreamDataType::kSegmentInfo, result_listener)) {
    +
    114  return false;
    +
    115  }
    +
    116 
    +
    117  const std::string is_subsegment_string =
    +
    118  BoolToString(arg->segment_info->is_subsegment);
    +
    119  const std::string is_encrypted_string =
    +
    120  BoolToString(arg->segment_info->is_encrypted);
    +
    121 
    +
    122  *result_listener << "which is (" << arg->stream_index << ", "
    +
    123  << arg->segment_info->start_timestamp << ", "
    +
    124  << arg->segment_info->duration << ", "
    +
    125  << is_subsegment_string << ", " << is_encrypted_string
    +
    126  << ")";
    +
    127 
    +
    128  return TryMatch(arg->stream_index, stream_index, result_listener,
    +
    129  "stream_index") &&
    +
    130  TryMatch(arg->segment_info->start_timestamp, start_timestamp,
    +
    131  result_listener, "start_timestamp") &&
    +
    132  TryMatch(arg->segment_info->duration, duration, result_listener,
    +
    133  "duration") &&
    +
    134  TryMatch(arg->segment_info->is_subsegment, subsegment, result_listener,
    +
    135  "is_subsegment") &&
    +
    136  TryMatch(arg->segment_info->is_encrypted, encrypted, result_listener,
    +
    137  "is_encrypted");
    +
    138 }
    +
    139 
    +
    140 MATCHER_P6(MatchEncryptionConfig,
    +
    141  protection_scheme,
    +
    142  crypt_byte_block,
    +
    143  skip_byte_block,
    +
    144  per_sample_iv_size,
    +
    145  constant_iv,
    +
    146  key_id,
    +
    147  "") {
    +
    148  const std::string constant_iv_hex =
    +
    149  base::HexEncode(arg.constant_iv.data(), arg.constant_iv.size());
    +
    150  const std::string key_id_hex =
    +
    151  base::HexEncode(arg.key_id.data(), arg.key_id.size());
    +
    152  const std::string protection_scheme_as_string =
    +
    153  FourCCToString(arg.protection_scheme);
    +
    154  // Convert to integers so that they will print as a number and not a uint8_t
    +
    155  // (char).
    +
    156  const int crypt_byte_as_int = static_cast<int>(arg.crypt_byte_block);
    +
    157  const int skip_byte_as_int = static_cast<int>(arg.skip_byte_block);
    +
    158 
    +
    159  *result_listener << "which is (" << protection_scheme_as_string << ", "
    +
    160  << crypt_byte_as_int << ", " << skip_byte_as_int << ", "
    +
    161  << arg.per_sample_iv_size << ", " << constant_iv_hex << ", "
    +
    162  << key_id_hex << ")";
    +
    163 
    +
    164  return TryMatch(arg.protection_scheme, protection_scheme, result_listener,
    +
    165  "protection_scheme") &&
    +
    166  TryMatch(arg.crypt_byte_block, crypt_byte_block, result_listener,
    +
    167  "crypt_byte_block") &&
    +
    168  TryMatch(arg.skip_byte_block, skip_byte_block, result_listener,
    +
    169  "skip_byte_block") &&
    +
    170  TryMatch(arg.per_sample_iv_size, per_sample_iv_size, result_listener,
    +
    171  "per_sample_iv_size") &&
    +
    172  TryMatch(arg.constant_iv, constant_iv, result_listener,
    +
    173  "constant_iv") &&
    +
    174  TryMatch(arg.key_id, key_id, result_listener, "key_id");
    +
    175 }
    +
    176 
    +
    177 MATCHER_P5(IsMediaSample,
    +
    178  stream_index,
    +
    179  timestamp,
    +
    180  duration,
    +
    181  encrypted,
    +
    182  keyframe,
    +
    183  "") {
    +
    184  if (!TryMatchStreamDataType(arg->stream_data_type,
    +
    185  StreamDataType::kMediaSample, result_listener)) {
    +
    186  return false;
    +
    187  }
    +
    188 
    +
    189  const std::string is_encrypted_string =
    +
    190  BoolToString(arg->media_sample->is_encrypted());
    +
    191  const std::string is_key_frame_string =
    +
    192  BoolToString(arg->media_sample->is_key_frame());
    +
    193 
    +
    194  *result_listener << "which is (" << arg->stream_index << ", "
    +
    195  << arg->media_sample->dts() << ", "
    +
    196  << arg->media_sample->duration() << ", "
    +
    197  << is_encrypted_string << ", " << is_key_frame_string << ")";
    +
    198 
    +
    199  return TryMatch(arg->stream_index, stream_index, result_listener,
    +
    200  "stream_index") &&
    +
    201  TryMatch(arg->media_sample->dts(), timestamp, result_listener,
    +
    202  "dts") &&
    +
    203  TryMatch(arg->media_sample->duration(), duration, result_listener,
    +
    204  "duration") &&
    +
    205  TryMatch(arg->media_sample->is_encrypted(), encrypted, result_listener,
    +
    206  "is_encrypted") &&
    +
    207  TryMatch(arg->media_sample->is_key_frame(), keyframe, result_listener,
    +
    208  "is_key_frame");
    +
    209 }
    +
    210 
    +
    211 MATCHER_P4(IsTextSample, stream_index, id, start_time, end_time, "") {
    +
    212  if (!TryMatchStreamDataType(arg->stream_data_type,
    +
    213  StreamDataType::kTextSample, result_listener)) {
    +
    214  return false;
    +
    215  }
    +
    216 
    +
    217  *result_listener << "which is (" << arg->stream_index << ", "
    +
    218  << ToPrettyString(arg->text_sample->id()) << ", "
    +
    219  << arg->text_sample->start_time() << ", "
    +
    220  << arg->text_sample->EndTime() << ")";
    +
    221 
    +
    222  return TryMatch(arg->stream_index, stream_index, result_listener,
    +
    223  "stream_index") &&
    +
    224  TryMatch(arg->text_sample->id(), id, result_listener, "id") &&
    +
    225  TryMatch(arg->text_sample->start_time(), start_time, result_listener,
    +
    226  "start_time") &&
    +
    227  TryMatch(arg->text_sample->EndTime(), end_time, result_listener,
    +
    228  "EndTime");
    +
    229 }
    +
    230 
    +
    231 MATCHER_P2(IsCueEvent, stream_index, time_in_seconds, "") {
    +
    232  if (!TryMatchStreamDataType(arg->stream_data_type, StreamDataType::kCueEvent,
    +
    233  result_listener)) {
    +
    234  return false;
    +
    235  }
    +
    236 
    +
    237  *result_listener << "which is (" << arg->stream_index << ", "
    +
    238  << arg->cue_event->time_in_seconds << ")";
    +
    239 
    +
    240  return TryMatch(arg->stream_index, stream_index, result_listener,
    +
    241  "stream_index") &&
    +
    242  TryMatch(arg->cue_event->time_in_seconds, time_in_seconds,
    +
    243  result_listener, "time_in_seconds");
    +
    244 }
    +
    245 
    + +
    247  public:
    + + + +
    251 
    +
    252  private:
    +
    253  bool ValidateOutputStreamIndex(size_t index) const override;
    +
    254  Status InitializeInternal() override;
    +
    255  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    256 };
    +
    257 
    + +
    259  public:
    +
    260  MOCK_METHOD1(OnProcess, void(const StreamData*));
    +
    261  MOCK_METHOD1(OnFlush, void(size_t index));
    +
    262 
    +
    263  private:
    +
    264  Status InitializeInternal() override;
    +
    265  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    266  Status OnFlushRequest(size_t index) override;
    +
    267 };
    +
    268 
    + +
    270  public:
    +
    271  const std::vector<std::unique_ptr<StreamData>>& Cache() const {
    +
    272  return stream_data_vector_;
    +
    273  }
    +
    274 
    +
    275  // TODO(vaage) : Remove the use of clear in our tests as it can make flow
    +
    276  // of the test harder to understand.
    +
    277  void Clear() { stream_data_vector_.clear(); }
    +
    278 
    +
    279  private:
    +
    280  Status InitializeInternal() override;
    +
    281  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    282  Status OnFlushRequest(size_t input_stream_index) override;
    +
    283  bool ValidateOutputStreamIndex(size_t stream_index) const override;
    +
    284 
    +
    285  std::vector<std::unique_ptr<StreamData>> stream_data_vector_;
    +
    286 };
    +
    287 
    +
    288 class MediaHandlerTestBase : public ::testing::Test {
    +
    289  public:
    +
    290  MediaHandlerTestBase() = default;
    +
    291 
    +
    292  protected:
    +
    293  bool IsVideoCodec(Codec codec) const;
    +
    294 
    +
    295  std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale) const;
    +
    296 
    +
    297  std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
    +
    298  uint32_t width,
    +
    299  uint64_t height) const;
    +
    300 
    +
    301  std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
    +
    302  Codec codec) const;
    +
    303 
    +
    304  std::unique_ptr<StreamInfo> GetVideoStreamInfo(uint32_t time_scale,
    +
    305  Codec codec,
    +
    306  uint32_t width,
    +
    307  uint64_t height) const;
    +
    308 
    +
    309  std::unique_ptr<StreamInfo> GetAudioStreamInfo(uint32_t time_scale) const;
    +
    310 
    +
    311  std::unique_ptr<StreamInfo> GetAudioStreamInfo(uint32_t time_scale,
    +
    312  Codec codec) const;
    +
    313 
    +
    314  std::shared_ptr<MediaSample> GetMediaSample(int64_t timestamp,
    +
    315  int64_t duration,
    +
    316  bool is_keyframe) const;
    +
    317 
    +
    318  std::shared_ptr<MediaSample> GetMediaSample(int64_t timestamp,
    +
    319  int64_t duration,
    +
    320  bool is_keyframe,
    +
    321  const uint8_t* data,
    +
    322  size_t data_length) const;
    +
    323 
    +
    324  std::unique_ptr<SegmentInfo> GetSegmentInfo(int64_t start_timestamp,
    +
    325  int64_t duration,
    +
    326  bool is_subsegment) const;
    +
    327 
    +
    328  std::unique_ptr<StreamInfo> GetTextStreamInfo(uint32_t timescale) const;
    +
    329 
    +
    330  std::unique_ptr<TextSample> GetTextSample(const std::string& id,
    +
    331  int64_t start,
    +
    332  int64_t end,
    +
    333  const std::string& payload) const;
    +
    334 
    +
    335  std::unique_ptr<CueEvent> GetCueEvent(double time_in_seconds) const;
    +
    336 
    +
    337  // Connect and initialize all handlers.
    +
    338  Status SetUpAndInitializeGraph(std::shared_ptr<MediaHandler> handler,
    +
    339  size_t input_count,
    +
    340  size_t output_count);
    +
    341 
    +
    342  // Get the input handler at |index|. The values of |index| will match the
    +
    343  // call to |AddInput|.
    +
    344  FakeInputMediaHandler* Input(size_t index);
    +
    345 
    +
    346  // Get the output handler at |index|. The values of |index| will match the
    +
    347  // call to |AddOutput|.
    +
    348  MockOutputMediaHandler* Output(size_t index);
    +
    349 
    +
    350  private:
    + +
    352  MediaHandlerTestBase& operator=(const MediaHandlerTestBase&) = delete;
    +
    353 
    +
    354  std::shared_ptr<MediaHandler> handler_;
    +
    355 
    +
    356  std::vector<std::shared_ptr<FakeInputMediaHandler>> inputs_;
    +
    357  std::vector<std::shared_ptr<MockOutputMediaHandler>> outputs_;
    +
    358 };
    +
    359 
    + +
    361  public:
    + +
    363 
    +
    364  protected:
    +
    366  void SetUpGraph(size_t num_inputs,
    +
    367  size_t num_outputs,
    +
    368  std::shared_ptr<MediaHandler> handler);
    +
    369 
    +
    371  const std::vector<std::unique_ptr<StreamData>>& GetOutputStreamDataVector()
    +
    372  const;
    +
    373 
    + +
    376 
    +
    378  std::shared_ptr<MediaHandler> some_handler() { return some_handler_; }
    +
    379 
    +
    381  std::shared_ptr<CachingMediaHandler> next_handler() { return next_handler_; }
    +
    382 
    +
    383  private:
    + + +
    386  delete;
    +
    387 
    +
    388  // Downstream handler used in testing graph.
    +
    389  std::shared_ptr<CachingMediaHandler> next_handler_;
    +
    390  // Some random handler which can be used for testing.
    +
    391  std::shared_ptr<MediaHandler> some_handler_;
    +
    392 };
    +
    393 
    +
    394 } // namespace media
    +
    395 } // namespace shaka
    +
    396 
    +
    397 #endif // PACKAGER_MEDIA_BASE_MEDIA_HANDLER_TEST_BASE_H_
    + + + + +
    std::shared_ptr< MediaHandler > some_handler()
    +
    void ClearOutputStreamDataVector()
    Clear the output stream data vector.
    +
    const std::vector< std::unique_ptr< StreamData > > & GetOutputStreamDataVector() const
    +
    std::shared_ptr< CachingMediaHandler > next_handler()
    +
    void SetUpGraph(size_t num_inputs, size_t num_outputs, std::shared_ptr< MediaHandler > handler)
    Setup a graph using |handler| with |num_inputs| and |num_outputs|.
    + + +
    Status FlushAllDownstreams()
    Flush all connected downstream handlers.
    +
    Status FlushDownstream(size_t output_stream_index)
    Flush the downstream connected at the specified output stream index.
    +
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    + +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/db/d5a/classshaka_1_1media_1_1CcStreamFilter.html b/docs/db/d5a/classshaka_1_1media_1_1CcStreamFilter.html new file mode 100644 index 0000000000..d80af75eba --- /dev/null +++ b/docs/db/d5a/classshaka_1_1media_1_1CcStreamFilter.html @@ -0,0 +1,254 @@ + + + + + + + +Shaka Packager SDK: shaka::media::CcStreamFilter Class Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::CcStreamFilter Class Reference
    +
    +
    + +

    #include <cc_stream_filter.h>

    +
    +Inheritance diagram for shaka::media::CcStreamFilter:
    +
    +
    + + +shaka::media::MediaHandler + +
    + + + + + + + + + + + + + + + + +

    +Public Member Functions

    CcStreamFilter (const std::string &language, uint16_t cc_index)
     
    - Public Member Functions inherited from shaka::media::MediaHandler
    +Status SetHandler (size_t output_stream_index, std::shared_ptr< MediaHandler > handler)
     Connect downstream handler at the specified output stream index.
     
    +Status AddHandler (std::shared_ptr< MediaHandler > handler)
     Connect downstream handler to the next available output stream index.
     
    Status Initialize ()
     
    +bool IsConnected ()
     Validate if the handler is connected to its upstream handler.
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Protected Member Functions

    Status InitializeInternal () override
     
    Status Process (std::unique_ptr< StreamData > stream_data) override
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    +virtual Status OnFlushRequest (size_t input_stream_index)
     Event handler for flush request at the specific input stream index.
     
    +virtual bool ValidateOutputStreamIndex (size_t stream_index) const
     Validate if the stream at the specified index actually exists.
     
    Status Dispatch (std::unique_ptr< StreamData > stream_data) const
     
    +Status DispatchStreamInfo (size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) const
     Dispatch the stream info to downstream handlers.
     
    +Status DispatchMediaSample (size_t stream_index, std::shared_ptr< const MediaSample > media_sample) const
     Dispatch the media sample to downstream handlers.
     
    +Status DispatchTextSample (size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
     Dispatch the text sample to downstream handlers.
     
    +Status DispatchSegmentInfo (size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) const
     Dispatch the segment info to downstream handlers.
     
    +Status DispatchScte35Event (size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) const
     Dispatch the scte35 event to downstream handlers.
     
    +Status DispatchCueEvent (size_t stream_index, std::shared_ptr< const CueEvent > cue_event) const
     Dispatch the cue event to downstream handlers.
     
    +Status FlushDownstream (size_t output_stream_index)
     Flush the downstream connected at the specified output stream index.
     
    +Status FlushAllDownstreams ()
     Flush all connected downstream handlers.
     
    +bool initialized ()
     
    +size_t num_input_streams () const
     
    +size_t next_output_stream_index () const
     
    +const std::map< size_t, std::pair< std::shared_ptr< MediaHandler >, size_t > > & output_handlers ()
     
    + + + + +

    +Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    +

    Detailed Description

    +

    A media handler that filters out text samples based on the cc_index field. Some text formats allow multiple "channels" per stream, so this filters out only one of them.

    + +

    Definition at line 22 of file cc_stream_filter.h.

    +

    Member Function Documentation

    + +

    ◆ InitializeInternal()

    + +
    +
    + + + + + +
    + + + + + + + +
    Status shaka::media::CcStreamFilter::InitializeInternal ()
    +
    +overrideprotectedvirtual
    +
    +

    Internal implementation of initialize. Note that it should only initialize the MediaHandler itself. Downstream handlers are handled in Initialize().

    + +

    Implements shaka::media::MediaHandler.

    + +

    Definition at line 18 of file cc_stream_filter.cc.

    + +
    +
    + +

    ◆ Process()

    + +
    +
    + + + + + +
    + + + + + + + + +
    Status shaka::media::CcStreamFilter::Process (std::unique_ptr< StreamDatastream_data)
    +
    +overrideprotectedvirtual
    +
    +

    Process the incoming stream data. Note that (1) stream_data.stream_index should be the input stream index; (2) The implementation needs to call DispatchXxx to dispatch the processed stream data to the downstream handlers after finishing processing if needed.

    + +

    Implements shaka::media::MediaHandler.

    + +

    Definition at line 22 of file cc_stream_filter.cc.

    + +
    +
    +
    The documentation for this class was generated from the following files: +
    + + + + diff --git a/docs/db/d5a/classshaka_1_1media_1_1CcStreamFilter.png b/docs/db/d5a/classshaka_1_1media_1_1CcStreamFilter.png new file mode 100644 index 0000000000000000000000000000000000000000..e781c98ce060fb27fba2458115d3c9ab2e680769 GIT binary patch literal 725 zcmeAS@N?(olHy`uVBq!ia0vp^>wq|bgBeI}_u97=NJ#|vgt-3y{~ySF@#br3|Dg#$ z78oBmaDcV*jy#adQ4-`A%m7pb0#{Fk7%?y~rFgnHhEy=VoqMtGwE>4qf9I9||DViO zE9055W%sVr&MK>XqGuV}9lTMSdVAYj%OqjJ$}X;O7ZvYTZKX*|S+{qd*ps88B$Tzi z@_EPfn$PW@qb*z~e8?|!Jrc9_aLtMD^LMzvx|W_{Yt=UQ;0cqWukqi%pIBCq-y>Xp z#GJGL#^ZU@wkOVLFKn96HdS9{v3s4_s;(EiuPvW;;*sB$i7$*^>7QOw{C0}&fvv~( zmc5@IS@-|SEcLv$Y+1E;XR=P!MERVLxShT@vrS;TdQahD_n3JXLavv0ZLT%bJ1Y=+ z{oS#x<;{lQcOvj;**OeFZ|cy>ar6`OI*Rbm3zX{L#!u)9x|n%NWc4-wRY?C4z>>>FqM4QH~s(MS$6xC&9;w1 zbti9>*PoY|@t;Hdz>6Qb_aq*g-_bV>*zxz}`B^brE$l+(^6lTW=kG#a(VSy@OWvDX zpZ8c8>0kW)YqWUY`u{O)6D!#6E?_upxXd8D$?)#e>&YcStebhvcWC{ddMy03dXW6N zZPO$({PdFZW2HV9rIw#9(0y~{>h5Fd+iX8`UJqSed~@#BuFAySFOHz>XJdY#p$l<%|{rIUs~08_Ot7bgErsy{@yB?mb?ByTBjddalsAdCHnj9 w!)vnkzdwF5p#BiUPUIl5&dXkF>-L|a$x~&^cj + - + Shaka Packager SDK: shaka::media::VP9Parser Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::VPxParser - -
    + + @@ -216,9 +219,7 @@ Additional Inherited Members diff --git a/docs/db/d60/mpd__options_8h_source.html b/docs/db/d60/mpd__options_8h_source.html index cdb9dd4b7e..30fbe242e2 100644 --- a/docs/db/d60/mpd__options_8h_source.html +++ b/docs/db/d60/mpd__options_8h_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/mpd/base/mpd_options.h Source File @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    mpd_options.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef MPD_BASE_MPD_OPTIONS_H_
    8 #define MPD_BASE_MPD_OPTIONS_H_
    9 
    10 #include <string>
    11 
    12 #include "packager/mpd/public/mpd_params.h"
    13 
    14 namespace shaka {
    15 
    16 enum class DashProfile {
    17  kUnknown,
    18  kOnDemand,
    19  kLive,
    20 };
    21 
    22 enum class MpdType { kStatic, kDynamic };
    23 
    25 struct MpdOptions {
    26  DashProfile dash_profile = DashProfile::kOnDemand;
    27  MpdType mpd_type = MpdType::kStatic;
    28  MpdParams mpd_params;
    29 };
    30 
    31 } // namespace shaka
    32 
    33 #endif // MPD_BASE_MPD_OPTIONS_H_
    DASH MPD related parameters.
    Definition: mpd_params.h:16
    -
    All the methods that are virtual are virtual for mocking.
    -
    Defines Mpd Options.
    Definition: mpd_options.h:25
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef MPD_BASE_MPD_OPTIONS_H_
    +
    8 #define MPD_BASE_MPD_OPTIONS_H_
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 #include "packager/mpd/public/mpd_params.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 
    +
    16 enum class DashProfile {
    +
    17  kUnknown,
    +
    18  kOnDemand,
    +
    19  kLive,
    +
    20 };
    +
    21 
    +
    22 enum class MpdType { kStatic, kDynamic };
    +
    23 
    +
    25 struct MpdOptions {
    +
    26  DashProfile dash_profile = DashProfile::kOnDemand;
    +
    27  MpdType mpd_type = MpdType::kStatic;
    +
    28  MpdParams mpd_params;
    +
    29 };
    +
    30 
    +
    31 } // namespace shaka
    +
    32 
    +
    33 #endif // MPD_BASE_MPD_OPTIONS_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    Defines Mpd Options.
    Definition: mpd_options.h:25
    +
    DASH MPD related parameters.
    Definition: mpd_params.h:16
    diff --git a/docs/db/d66/structshaka_1_1media_1_1mp4_1_1SegmentType-members.html b/docs/db/d66/structshaka_1_1media_1_1mp4_1_1SegmentType-members.html index 0fb9935dde..cf51b2efcb 100644 --- a/docs/db/d66/structshaka_1_1media_1_1mp4_1_1SegmentType-members.html +++ b/docs/db/d66/structshaka_1_1media_1_1mp4_1_1SegmentType-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/d66/udp__file_8cc_source.html b/docs/db/d66/udp__file_8cc_source.html index e43787595e..250c2af93d 100644 --- a/docs/db/d66/udp__file_8cc_source.html +++ b/docs/db/d66/udp__file_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/udp_file.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    udp_file.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/file/udp_file.h"
    8 
    9 #if defined(OS_WIN)
    10 
    11 #include <windows.h>
    12 #include <ws2tcpip.h>
    13 #define close closesocket
    14 #define EINTR_CODE WSAEINTR
    15 
    16 #else
    17 
    18 #include <arpa/inet.h>
    19 #include <errno.h>
    20 #include <strings.h>
    21 #include <sys/socket.h>
    22 #include <sys/time.h>
    23 #include <unistd.h>
    24 #define INVALID_SOCKET -1
    25 #define EINTR_CODE EINTR
    26 
    27 // IP_MULTICAST_ALL has been supported since kernel version 2.6.31 but we may be
    28 // building on a machine that is older than that.
    29 #ifndef IP_MULTICAST_ALL
    30 #define IP_MULTICAST_ALL 49
    31 #endif
    32 
    33 #endif // defined(OS_WIN)
    34 
    35 #include <limits>
    36 
    37 #include "packager/base/logging.h"
    38 #include "packager/file/udp_options.h"
    39 
    40 namespace shaka {
    41 
    42 namespace {
    43 
    44 bool IsIpv4MulticastAddress(const struct in_addr& addr) {
    45  return (ntohl(addr.s_addr) & 0xf0000000) == 0xe0000000;
    46 }
    47 
    48 int GetSocketErrorCode() {
    49 #if defined(OS_WIN)
    50  return WSAGetLastError();
    51 #else
    52  return errno;
    53 #endif
    54 }
    55 
    56 } // anonymous namespace
    57 
    58 UdpFile::UdpFile(const char* file_name)
    59  : File(file_name), socket_(INVALID_SOCKET) {}
    60 
    61 UdpFile::~UdpFile() {}
    62 
    64  if (socket_ != INVALID_SOCKET) {
    65  close(socket_);
    66  socket_ = INVALID_SOCKET;
    67  }
    68  delete this;
    69 #if defined(OS_WIN)
    70  if (wsa_started_)
    71  WSACleanup();
    72 #endif
    73  return true;
    74 }
    75 
    76 int64_t UdpFile::Read(void* buffer, uint64_t length) {
    77  DCHECK(buffer);
    78  DCHECK_GE(length, 65535u)
    79  << "Buffer may be too small to read entire datagram.";
    80 
    81  if (socket_ == INVALID_SOCKET)
    82  return -1;
    83 
    84  int64_t result;
    85  do {
    86  result =
    87  recvfrom(socket_, reinterpret_cast<char*>(buffer), length, 0, NULL, 0);
    88  } while (result == -1 && GetSocketErrorCode() == EINTR_CODE);
    89 
    90  return result;
    91 }
    92 
    93 int64_t UdpFile::Write(const void* buffer, uint64_t length) {
    94  NOTIMPLEMENTED();
    95  return -1;
    96 }
    97 
    98 int64_t UdpFile::Size() {
    99  if (socket_ == INVALID_SOCKET)
    100  return -1;
    101 
    102  return std::numeric_limits<int64_t>::max();
    103 }
    104 
    106  NOTIMPLEMENTED();
    107  return false;
    108 }
    109 
    110 bool UdpFile::Seek(uint64_t position) {
    111  NOTIMPLEMENTED();
    112  return false;
    113 }
    114 
    115 bool UdpFile::Tell(uint64_t* position) {
    116  NOTIMPLEMENTED();
    117  return false;
    118 }
    119 
    120 class ScopedSocket {
    121  public:
    122  explicit ScopedSocket(SOCKET sock_fd) : sock_fd_(sock_fd) {}
    123 
    124  ~ScopedSocket() {
    125  if (sock_fd_ != INVALID_SOCKET)
    126  close(sock_fd_);
    127  }
    128 
    129  SOCKET get() { return sock_fd_; }
    130 
    131  SOCKET release() {
    132  SOCKET socket = sock_fd_;
    133  sock_fd_ = INVALID_SOCKET;
    134  return socket;
    135  }
    136 
    137  private:
    138  SOCKET sock_fd_;
    139 
    140  DISALLOW_COPY_AND_ASSIGN(ScopedSocket);
    141 };
    142 
    144 #if defined(OS_WIN)
    145  WSADATA wsa_data;
    146  int wsa_error = WSAStartup(MAKEWORD(2, 2), &wsa_data);
    147  if (wsa_error != 0) {
    148  LOG(ERROR) << "Winsock start up failed with error " << wsa_error;
    149  return false;
    150  }
    151  wsa_started_ = true;
    152 #endif // defined(OS_WIN)
    153 
    154  DCHECK_EQ(INVALID_SOCKET, socket_);
    155 
    156  std::unique_ptr<UdpOptions> options =
    158  if (!options)
    159  return false;
    160 
    161  ScopedSocket new_socket(socket(AF_INET, SOCK_DGRAM, 0));
    162  if (new_socket.get() == INVALID_SOCKET) {
    163  LOG(ERROR) << "Could not allocate socket, error = " << GetSocketErrorCode();
    164  return false;
    165  }
    166 
    167  struct in_addr local_in_addr = {0};
    168  if (inet_pton(AF_INET, options->address().c_str(), &local_in_addr) != 1) {
    169  LOG(ERROR) << "Malformed IPv4 address " << options->address();
    170  return false;
    171  }
    172 
    173  struct sockaddr_in local_sock_addr = {0};
    174  // TODO(kqyang): Support IPv6.
    175  local_sock_addr.sin_family = AF_INET;
    176  local_sock_addr.sin_port = htons(options->port());
    177  const bool is_multicast = IsIpv4MulticastAddress(local_in_addr);
    178  if (is_multicast) {
    179  local_sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    180  } else {
    181  local_sock_addr.sin_addr = local_in_addr;
    182  }
    183 
    184  if (options->reuse()) {
    185  const int optval = 1;
    186  if (setsockopt(new_socket.get(), SOL_SOCKET, SO_REUSEADDR,
    187  reinterpret_cast<const char*>(&optval),
    188  sizeof(optval)) < 0) {
    189  LOG(ERROR) << "Could not apply the SO_REUSEADDR property to the UDP "
    190  "socket, error = "
    191  << GetSocketErrorCode();
    192  return false;
    193  }
    194  }
    195 
    196  if (bind(new_socket.get(),
    197  reinterpret_cast<struct sockaddr*>(&local_sock_addr),
    198  sizeof(local_sock_addr)) < 0) {
    199  LOG(ERROR) << "Could not bind UDP socket, error = " << GetSocketErrorCode();
    200  return false;
    201  }
    202 
    203  if (is_multicast) {
    204  if (options->is_source_specific_multicast()) {
    205  struct ip_mreq_source source_multicast_group;
    206 
    207  source_multicast_group.imr_multiaddr = local_in_addr;
    208  if (inet_pton(AF_INET,
    209  options->interface_address().c_str(),
    210  &source_multicast_group.imr_interface) != 1) {
    211  LOG(ERROR) << "Malformed IPv4 interface address "
    212  << options->interface_address();
    213  return false;
    214  }
    215  if (inet_pton(AF_INET,
    216  options->source_address().c_str(),
    217  &source_multicast_group.imr_sourceaddr) != 1) {
    218  LOG(ERROR) << "Malformed IPv4 source specific multicast address "
    219  << options->source_address();
    220  return false;
    221  }
    222 
    223  if (setsockopt(new_socket.get(),
    224  IPPROTO_IP,
    225  IP_ADD_SOURCE_MEMBERSHIP,
    226  reinterpret_cast<const char*>(&source_multicast_group),
    227  sizeof(source_multicast_group)) < 0) {
    228  LOG(ERROR) << "Failed to join multicast group, error = "
    229  << GetSocketErrorCode();
    230  return false;
    231  }
    232  } else {
    233  // this is a v2 join without a specific source.
    234  struct ip_mreq multicast_group;
    235 
    236  multicast_group.imr_multiaddr = local_in_addr;
    237 
    238  if (inet_pton(AF_INET, options->interface_address().c_str(),
    239  &multicast_group.imr_interface) != 1) {
    240  LOG(ERROR) << "Malformed IPv4 interface address "
    241  << options->interface_address();
    242  return false;
    243  }
    244 
    245  if (setsockopt(new_socket.get(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
    246  reinterpret_cast<const char*>(&multicast_group),
    247  sizeof(multicast_group)) < 0) {
    248  LOG(ERROR) << "Failed to join multicast group, error = "
    249  << GetSocketErrorCode();
    250  return false;
    251  }
    252  }
    253 
    254 #if defined(__linux__)
    255  // Disable IP_MULTICAST_ALL to avoid interference caused when two sockets
    256  // are bound to the same port but joined to different multicast groups.
    257  const int optval_zero = 0;
    258  if (setsockopt(new_socket.get(), IPPROTO_IP, IP_MULTICAST_ALL,
    259  reinterpret_cast<const char*>(&optval_zero),
    260  sizeof(optval_zero)) < 0 &&
    261  GetSocketErrorCode() != ENOPROTOOPT) {
    262  LOG(ERROR) << "Failed to disable IP_MULTICAST_ALL option, error = "
    263  << GetSocketErrorCode();
    264  return false;
    265  }
    266 #endif // #if defined(__linux__)
    267  }
    268 
    269  // Set timeout if needed.
    270  if (options->timeout_us() != 0) {
    271  struct timeval tv;
    272  tv.tv_sec = options->timeout_us() / 1000000;
    273  tv.tv_usec = options->timeout_us() % 1000000;
    274  if (setsockopt(new_socket.get(), SOL_SOCKET, SO_RCVTIMEO,
    275  reinterpret_cast<const char*>(&tv), sizeof(tv)) < 0) {
    276  LOG(ERROR) << "Failed to set socket timeout, error = "
    277  << GetSocketErrorCode();
    278  return false;
    279  }
    280  }
    281 
    282  if (options->buffer_size() > 0) {
    283  const int receive_buffer_size = options->buffer_size();
    284  if (setsockopt(new_socket.get(), SOL_SOCKET, SO_RCVBUF,
    285  reinterpret_cast<const char*>(&receive_buffer_size),
    286  sizeof(receive_buffer_size)) < 0) {
    287  LOG(ERROR) << "Failed to set the maximum receive buffer size, error = "
    288  << GetSocketErrorCode();
    289  return false;
    290  }
    291  }
    292 
    293  socket_ = new_socket.release();
    294  return true;
    295 }
    296 
    297 } // namespace shaka
    int64_t Read(void *buffer, uint64_t length) override
    Definition: udp_file.cc:76
    -
    bool Tell(uint64_t *position) override
    Definition: udp_file.cc:115
    -
    bool Seek(uint64_t position) override
    Definition: udp_file.cc:110
    -
    UdpFile(const char *address_and_port)
    Definition: udp_file.cc:58
    -
    static std::unique_ptr< UdpOptions > ParseFromString(base::StringPiece udp_url)
    Definition: udp_options.cc:75
    -
    Define an abstract file interface.
    Definition: file.h:26
    -
    int64_t Write(const void *buffer, uint64_t length) override
    Definition: udp_file.cc:93
    -
    const std::string & file_name() const
    Definition: file.h:94
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool Close() override
    Definition: udp_file.cc:63
    -
    bool Open() override
    Internal open. Should not be used directly.
    Definition: udp_file.cc:143
    -
    int64_t Size() override
    Definition: udp_file.cc:98
    -
    bool Flush() override
    Definition: udp_file.cc:105
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/file/udp_file.h"
    +
    8 
    +
    9 #if defined(OS_WIN)
    +
    10 
    +
    11 #include <windows.h>
    +
    12 #include <ws2tcpip.h>
    +
    13 #define close closesocket
    +
    14 #define EINTR_CODE WSAEINTR
    +
    15 
    +
    16 #else
    +
    17 
    +
    18 #include <arpa/inet.h>
    +
    19 #include <errno.h>
    +
    20 #include <strings.h>
    +
    21 #include <sys/socket.h>
    +
    22 #include <sys/time.h>
    +
    23 #include <unistd.h>
    +
    24 #define INVALID_SOCKET -1
    +
    25 #define EINTR_CODE EINTR
    +
    26 
    +
    27 // IP_MULTICAST_ALL has been supported since kernel version 2.6.31 but we may be
    +
    28 // building on a machine that is older than that.
    +
    29 #ifndef IP_MULTICAST_ALL
    +
    30 #define IP_MULTICAST_ALL 49
    +
    31 #endif
    +
    32 
    +
    33 #endif // defined(OS_WIN)
    +
    34 
    +
    35 #include <limits>
    +
    36 
    +
    37 #include "packager/base/logging.h"
    +
    38 #include "packager/file/udp_options.h"
    +
    39 
    +
    40 namespace shaka {
    +
    41 
    +
    42 namespace {
    +
    43 
    +
    44 bool IsIpv4MulticastAddress(const struct in_addr& addr) {
    +
    45  return (ntohl(addr.s_addr) & 0xf0000000) == 0xe0000000;
    +
    46 }
    +
    47 
    +
    48 int GetSocketErrorCode() {
    +
    49 #if defined(OS_WIN)
    +
    50  return WSAGetLastError();
    +
    51 #else
    +
    52  return errno;
    +
    53 #endif
    +
    54 }
    +
    55 
    +
    56 } // anonymous namespace
    +
    57 
    +
    58 UdpFile::UdpFile(const char* file_name)
    +
    59  : File(file_name), socket_(INVALID_SOCKET) {}
    +
    60 
    +
    61 UdpFile::~UdpFile() {}
    +
    62 
    + +
    64  if (socket_ != INVALID_SOCKET) {
    +
    65  close(socket_);
    +
    66  socket_ = INVALID_SOCKET;
    +
    67  }
    +
    68  delete this;
    +
    69 #if defined(OS_WIN)
    +
    70  if (wsa_started_)
    +
    71  WSACleanup();
    +
    72 #endif
    +
    73  return true;
    +
    74 }
    +
    75 
    +
    76 int64_t UdpFile::Read(void* buffer, uint64_t length) {
    +
    77  DCHECK(buffer);
    +
    78  DCHECK_GE(length, 65535u)
    +
    79  << "Buffer may be too small to read entire datagram.";
    +
    80 
    +
    81  if (socket_ == INVALID_SOCKET)
    +
    82  return -1;
    +
    83 
    +
    84  int64_t result;
    +
    85  do {
    +
    86  result =
    +
    87  recvfrom(socket_, reinterpret_cast<char*>(buffer), length, 0, NULL, 0);
    +
    88  } while (result == -1 && GetSocketErrorCode() == EINTR_CODE);
    +
    89 
    +
    90  return result;
    +
    91 }
    +
    92 
    +
    93 int64_t UdpFile::Write(const void* buffer, uint64_t length) {
    +
    94  NOTIMPLEMENTED();
    +
    95  return -1;
    +
    96 }
    +
    97 
    +
    98 int64_t UdpFile::Size() {
    +
    99  if (socket_ == INVALID_SOCKET)
    +
    100  return -1;
    +
    101 
    +
    102  return std::numeric_limits<int64_t>::max();
    +
    103 }
    +
    104 
    + +
    106  NOTIMPLEMENTED();
    +
    107  return false;
    +
    108 }
    +
    109 
    +
    110 bool UdpFile::Seek(uint64_t position) {
    +
    111  NOTIMPLEMENTED();
    +
    112  return false;
    +
    113 }
    +
    114 
    +
    115 bool UdpFile::Tell(uint64_t* position) {
    +
    116  NOTIMPLEMENTED();
    +
    117  return false;
    +
    118 }
    +
    119 
    +
    120 class ScopedSocket {
    +
    121  public:
    +
    122  explicit ScopedSocket(SOCKET sock_fd) : sock_fd_(sock_fd) {}
    +
    123 
    +
    124  ~ScopedSocket() {
    +
    125  if (sock_fd_ != INVALID_SOCKET)
    +
    126  close(sock_fd_);
    +
    127  }
    +
    128 
    +
    129  SOCKET get() { return sock_fd_; }
    +
    130 
    +
    131  SOCKET release() {
    +
    132  SOCKET socket = sock_fd_;
    +
    133  sock_fd_ = INVALID_SOCKET;
    +
    134  return socket;
    +
    135  }
    +
    136 
    +
    137  private:
    +
    138  SOCKET sock_fd_;
    +
    139 
    +
    140  DISALLOW_COPY_AND_ASSIGN(ScopedSocket);
    +
    141 };
    +
    142 
    + +
    144 #if defined(OS_WIN)
    +
    145  WSADATA wsa_data;
    +
    146  int wsa_error = WSAStartup(MAKEWORD(2, 2), &wsa_data);
    +
    147  if (wsa_error != 0) {
    +
    148  LOG(ERROR) << "Winsock start up failed with error " << wsa_error;
    +
    149  return false;
    +
    150  }
    +
    151  wsa_started_ = true;
    +
    152 #endif // defined(OS_WIN)
    +
    153 
    +
    154  DCHECK_EQ(INVALID_SOCKET, socket_);
    +
    155 
    +
    156  std::unique_ptr<UdpOptions> options =
    + +
    158  if (!options)
    +
    159  return false;
    +
    160 
    +
    161  ScopedSocket new_socket(socket(AF_INET, SOCK_DGRAM, 0));
    +
    162  if (new_socket.get() == INVALID_SOCKET) {
    +
    163  LOG(ERROR) << "Could not allocate socket, error = " << GetSocketErrorCode();
    +
    164  return false;
    +
    165  }
    +
    166 
    +
    167  struct in_addr local_in_addr = {0};
    +
    168  if (inet_pton(AF_INET, options->address().c_str(), &local_in_addr) != 1) {
    +
    169  LOG(ERROR) << "Malformed IPv4 address " << options->address();
    +
    170  return false;
    +
    171  }
    +
    172 
    +
    173  struct sockaddr_in local_sock_addr = {0};
    +
    174  // TODO(kqyang): Support IPv6.
    +
    175  local_sock_addr.sin_family = AF_INET;
    +
    176  local_sock_addr.sin_port = htons(options->port());
    +
    177  const bool is_multicast = IsIpv4MulticastAddress(local_in_addr);
    +
    178  if (is_multicast) {
    +
    179  local_sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    +
    180  } else {
    +
    181  local_sock_addr.sin_addr = local_in_addr;
    +
    182  }
    +
    183 
    +
    184  if (options->reuse()) {
    +
    185  const int optval = 1;
    +
    186  if (setsockopt(new_socket.get(), SOL_SOCKET, SO_REUSEADDR,
    +
    187  reinterpret_cast<const char*>(&optval),
    +
    188  sizeof(optval)) < 0) {
    +
    189  LOG(ERROR) << "Could not apply the SO_REUSEADDR property to the UDP "
    +
    190  "socket, error = "
    +
    191  << GetSocketErrorCode();
    +
    192  return false;
    +
    193  }
    +
    194  }
    +
    195 
    +
    196  if (bind(new_socket.get(),
    +
    197  reinterpret_cast<struct sockaddr*>(&local_sock_addr),
    +
    198  sizeof(local_sock_addr)) < 0) {
    +
    199  LOG(ERROR) << "Could not bind UDP socket, error = " << GetSocketErrorCode();
    +
    200  return false;
    +
    201  }
    +
    202 
    +
    203  if (is_multicast) {
    +
    204  if (options->is_source_specific_multicast()) {
    +
    205  struct ip_mreq_source source_multicast_group;
    +
    206 
    +
    207  source_multicast_group.imr_multiaddr = local_in_addr;
    +
    208  if (inet_pton(AF_INET,
    +
    209  options->interface_address().c_str(),
    +
    210  &source_multicast_group.imr_interface) != 1) {
    +
    211  LOG(ERROR) << "Malformed IPv4 interface address "
    +
    212  << options->interface_address();
    +
    213  return false;
    +
    214  }
    +
    215  if (inet_pton(AF_INET,
    +
    216  options->source_address().c_str(),
    +
    217  &source_multicast_group.imr_sourceaddr) != 1) {
    +
    218  LOG(ERROR) << "Malformed IPv4 source specific multicast address "
    +
    219  << options->source_address();
    +
    220  return false;
    +
    221  }
    +
    222 
    +
    223  if (setsockopt(new_socket.get(),
    +
    224  IPPROTO_IP,
    +
    225  IP_ADD_SOURCE_MEMBERSHIP,
    +
    226  reinterpret_cast<const char*>(&source_multicast_group),
    +
    227  sizeof(source_multicast_group)) < 0) {
    +
    228  LOG(ERROR) << "Failed to join multicast group, error = "
    +
    229  << GetSocketErrorCode();
    +
    230  return false;
    +
    231  }
    +
    232  } else {
    +
    233  // this is a v2 join without a specific source.
    +
    234  struct ip_mreq multicast_group;
    +
    235 
    +
    236  multicast_group.imr_multiaddr = local_in_addr;
    +
    237 
    +
    238  if (inet_pton(AF_INET, options->interface_address().c_str(),
    +
    239  &multicast_group.imr_interface) != 1) {
    +
    240  LOG(ERROR) << "Malformed IPv4 interface address "
    +
    241  << options->interface_address();
    +
    242  return false;
    +
    243  }
    +
    244 
    +
    245  if (setsockopt(new_socket.get(), IPPROTO_IP, IP_ADD_MEMBERSHIP,
    +
    246  reinterpret_cast<const char*>(&multicast_group),
    +
    247  sizeof(multicast_group)) < 0) {
    +
    248  LOG(ERROR) << "Failed to join multicast group, error = "
    +
    249  << GetSocketErrorCode();
    +
    250  return false;
    +
    251  }
    +
    252  }
    +
    253 
    +
    254 #if defined(__linux__)
    +
    255  // Disable IP_MULTICAST_ALL to avoid interference caused when two sockets
    +
    256  // are bound to the same port but joined to different multicast groups.
    +
    257  const int optval_zero = 0;
    +
    258  if (setsockopt(new_socket.get(), IPPROTO_IP, IP_MULTICAST_ALL,
    +
    259  reinterpret_cast<const char*>(&optval_zero),
    +
    260  sizeof(optval_zero)) < 0 &&
    +
    261  GetSocketErrorCode() != ENOPROTOOPT) {
    +
    262  LOG(ERROR) << "Failed to disable IP_MULTICAST_ALL option, error = "
    +
    263  << GetSocketErrorCode();
    +
    264  return false;
    +
    265  }
    +
    266 #endif // #if defined(__linux__)
    +
    267  }
    +
    268 
    +
    269  // Set timeout if needed.
    +
    270  if (options->timeout_us() != 0) {
    +
    271  struct timeval tv;
    +
    272  tv.tv_sec = options->timeout_us() / 1000000;
    +
    273  tv.tv_usec = options->timeout_us() % 1000000;
    +
    274  if (setsockopt(new_socket.get(), SOL_SOCKET, SO_RCVTIMEO,
    +
    275  reinterpret_cast<const char*>(&tv), sizeof(tv)) < 0) {
    +
    276  LOG(ERROR) << "Failed to set socket timeout, error = "
    +
    277  << GetSocketErrorCode();
    +
    278  return false;
    +
    279  }
    +
    280  }
    +
    281 
    +
    282  if (options->buffer_size() > 0) {
    +
    283  const int receive_buffer_size = options->buffer_size();
    +
    284  if (setsockopt(new_socket.get(), SOL_SOCKET, SO_RCVBUF,
    +
    285  reinterpret_cast<const char*>(&receive_buffer_size),
    +
    286  sizeof(receive_buffer_size)) < 0) {
    +
    287  LOG(ERROR) << "Failed to set the maximum receive buffer size, error = "
    +
    288  << GetSocketErrorCode();
    +
    289  return false;
    +
    290  }
    +
    291  }
    +
    292 
    +
    293  socket_ = new_socket.release();
    +
    294  return true;
    +
    295 }
    +
    296 
    +
    297 } // namespace shaka
    +
    Define an abstract file interface.
    Definition: file.h:27
    +
    const std::string & file_name() const
    Definition: file.h:95
    +
    int64_t Size() override
    Definition: udp_file.cc:98
    +
    bool Seek(uint64_t position) override
    Definition: udp_file.cc:110
    +
    int64_t Write(const void *buffer, uint64_t length) override
    Definition: udp_file.cc:93
    +
    bool Tell(uint64_t *position) override
    Definition: udp_file.cc:115
    +
    bool Flush() override
    Definition: udp_file.cc:105
    +
    bool Close() override
    Definition: udp_file.cc:63
    +
    int64_t Read(void *buffer, uint64_t length) override
    Definition: udp_file.cc:76
    +
    bool Open() override
    Internal open. Should not be used directly.
    Definition: udp_file.cc:143
    +
    UdpFile(const char *address_and_port)
    Definition: udp_file.cc:58
    +
    static std::unique_ptr< UdpOptions > ParseFromString(base::StringPiece udp_url)
    Definition: udp_options.cc:75
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/d6b/structshaka_1_1MpdParams-members.html b/docs/db/d6b/structshaka_1_1MpdParams-members.html index 14842c293a..683feb28cf 100644 --- a/docs/db/d6b/structshaka_1_1MpdParams-members.html +++ b/docs/db/d6b/structshaka_1_1MpdParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */ diff --git a/docs/db/d71/http__key__fetcher_8h_source.html b/docs/db/d71/http__key__fetcher_8h_source.html index d3f2d6cf3b..3f55b3b670 100644 --- a/docs/db/d71/http__key__fetcher_8h_source.html +++ b/docs/db/d71/http__key__fetcher_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/http_key_fetcher.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    http_key_fetcher.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    10 
    11 #ifndef PACKAGER_MEDIA_BASE_HTTP_KEY_FETCHER_H_
    12 #define PACKAGER_MEDIA_BASE_HTTP_KEY_FETCHER_H_
    13 
    14 #include "packager/base/compiler_specific.h"
    15 #include "packager/media/base/key_fetcher.h"
    16 #include "packager/status.h"
    17 
    18 namespace shaka {
    19 namespace media {
    20 
    26 class HttpKeyFetcher : public KeyFetcher {
    27  public:
    32  HttpKeyFetcher(uint32_t timeout_in_seconds);
    33  ~HttpKeyFetcher() override;
    34 
    36  Status FetchKeys(const std::string& url,
    37  const std::string& request,
    38  std::string* response) override;
    39 
    45  virtual Status Get(const std::string& url, std::string* response);
    46 
    52  virtual Status Post(const std::string& url,
    53  const std::string& data,
    54  std::string* response);
    55 
    61  void SetClientCertInfo(const std::string& cert_file,
    62  const std::string& private_key_file,
    63  const std::string& private_key_password) {
    64  client_cert_file_ = cert_file;
    65  client_cert_private_key_file_ = private_key_file;
    66  client_cert_private_key_password_ = private_key_password;
    67  }
    70  void SetCaFile(const std::string& ca_file) {
    71  ca_file_ = ca_file;
    72  }
    73 
    74  private:
    75  enum HttpMethod {
    76  GET,
    77  POST,
    78  PUT
    79  };
    80 
    81  // Internal implementation of HTTP functions, e.g. Get and Post.
    82  Status FetchInternal(HttpMethod method, const std::string& url,
    83  const std::string& data, std::string* response);
    84 
    85  const uint32_t timeout_in_seconds_;
    86  std::string ca_file_;
    87  std::string client_cert_file_;
    88  std::string client_cert_private_key_file_;
    89  std::string client_cert_private_key_password_;
    90 
    91  DISALLOW_COPY_AND_ASSIGN(HttpKeyFetcher);
    92 };
    93 
    94 } // namespace media
    95 } // namespace shaka
    96 
    97 #endif // PACKAGER_MEDIA_BASE_HTTP_KEY_FETCHER_H_
    -
    void SetCaFile(const std::string &ca_file)
    -
    All the methods that are virtual are virtual for mocking.
    - -
    virtual Status Get(const std::string &url, std::string *response)
    -
    Base class for fetching keys from the license service.
    Definition: key_fetcher.h:17
    -
    void SetClientCertInfo(const std::string &cert_file, const std::string &private_key_file, const std::string &private_key_password)
    -
    Status FetchKeys(const std::string &url, const std::string &request, std::string *response) override
    -
    HttpKeyFetcher()
    Creates a fetcher with no timeout.
    -
    virtual Status Post(const std::string &url, const std::string &data, std::string *response)
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_HTTP_KEY_FETCHER_H_
    +
    8 #define PACKAGER_MEDIA_BASE_HTTP_KEY_FETCHER_H_
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 #include "packager/base/compiler_specific.h"
    +
    13 #include "packager/file/http_file.h"
    +
    14 #include "packager/media/base/key_fetcher.h"
    +
    15 #include "packager/status.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    +
    25 class HttpKeyFetcher : public KeyFetcher {
    +
    26  public:
    + +
    31  HttpKeyFetcher(uint32_t timeout_in_seconds);
    +
    32  ~HttpKeyFetcher() override;
    +
    33 
    +
    35  Status FetchKeys(const std::string& url,
    +
    36  const std::string& request,
    +
    37  std::string* response) override;
    +
    38 
    +
    44  virtual Status Get(const std::string& url, std::string* response);
    +
    45 
    +
    51  virtual Status Post(const std::string& url,
    +
    52  const std::string& data,
    +
    53  std::string* response);
    +
    54 
    +
    55  private:
    +
    56  Status FetchInternal(HttpMethod method, const std::string& url,
    +
    57  const std::string& data, std::string* response);
    +
    58 
    +
    59  const uint32_t timeout_in_seconds_;
    +
    60 
    +
    61  DISALLOW_COPY_AND_ASSIGN(HttpKeyFetcher);
    +
    62 };
    +
    63 
    +
    64 } // namespace media
    +
    65 } // namespace shaka
    +
    66 
    +
    67 #endif // PACKAGER_MEDIA_BASE_HTTP_KEY_FETCHER_H_
    + + +
    HttpKeyFetcher()
    Creates a fetcher with no timeout.
    +
    virtual Status Post(const std::string &url, const std::string &data, std::string *response)
    +
    virtual Status Get(const std::string &url, std::string *response)
    +
    Status FetchKeys(const std::string &url, const std::string &request, std::string *response) override
    +
    Base class for fetching keys from the license service.
    Definition: key_fetcher.h:17
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/d74/classshaka_1_1media_1_1HEVCDecoderConfigurationRecord-members.html b/docs/db/d74/classshaka_1_1media_1_1HEVCDecoderConfigurationRecord-members.html index f38c188358..745194fbec 100644 --- a/docs/db/d74/classshaka_1_1media_1_1HEVCDecoderConfigurationRecord-members.html +++ b/docs/db/d74/classshaka_1_1media_1_1HEVCDecoderConfigurationRecord-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/d75/classshaka_1_1media_1_1webm_1_1TwoPassSingleSegmentSegmenter-members.html b/docs/db/d75/classshaka_1_1media_1_1webm_1_1TwoPassSingleSegmentSegmenter-members.html index e1a91a597c..b085519dc0 100644 --- a/docs/db/d75/classshaka_1_1media_1_1webm_1_1TwoPassSingleSegmentSegmenter-members.html +++ b/docs/db/d75/classshaka_1_1media_1_1webm_1_1TwoPassSingleSegmentSegmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/db/d78/classshaka_1_1media_1_1mp2t_1_1ContinuityCounter-members.html b/docs/db/d78/classshaka_1_1media_1_1mp2t_1_1ContinuityCounter-members.html index 11b1c08183..129fef03df 100644 --- a/docs/db/d78/classshaka_1_1media_1_1mp2t_1_1ContinuityCounter-members.html +++ b/docs/db/d78/classshaka_1_1media_1_1mp2t_1_1ContinuityCounter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/db/d79/chunking__params_8h_source.html b/docs/db/d79/chunking__params_8h_source.html index 3e80a67560..31bd13c986 100644 --- a/docs/db/d79/chunking__params_8h_source.html +++ b/docs/db/d79/chunking__params_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/public/chunking_params.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    chunking_params.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_PUBLIC_CHUNKING_PARAMS_H_
    8 #define PACKAGER_MEDIA_PUBLIC_CHUNKING_PARAMS_H_
    9 
    10 namespace shaka {
    11 
    19 
    22  bool segment_sap_aligned = true;
    28 };
    29 
    30 } // namespace shaka
    31 
    32 #endif // PACKAGER_MEDIA_PUBLIC_CHUNKING_PARAMS_H_
    All the methods that are virtual are virtual for mocking.
    - -
    Chunking (segmentation) related parameters.
    - -
    double segment_duration_in_seconds
    Segment duration in seconds.
    -
    double subsegment_duration_in_seconds
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_PUBLIC_CHUNKING_PARAMS_H_
    +
    8 #define PACKAGER_MEDIA_PUBLIC_CHUNKING_PARAMS_H_
    +
    9 
    +
    10 namespace shaka {
    +
    11 
    + + + +
    19 
    +
    22  bool segment_sap_aligned = true;
    + +
    28 };
    +
    29 
    +
    30 } // namespace shaka
    +
    31 
    +
    32 #endif // PACKAGER_MEDIA_PUBLIC_CHUNKING_PARAMS_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    Chunking (segmentation) related parameters.
    +
    double segment_duration_in_seconds
    Segment duration in seconds.
    + +
    double subsegment_duration_in_seconds
    +
    diff --git a/docs/db/d7e/muxer__options_8cc_source.html b/docs/db/d7e/muxer__options_8cc_source.html index 668d23e06d..5ae2ef4f24 100644 --- a/docs/db/d7e/muxer__options_8cc_source.html +++ b/docs/db/d7e/muxer__options_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/muxer_options.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    muxer_options.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/muxer_options.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 
    12 MuxerOptions::MuxerOptions() = default;
    13 MuxerOptions::~MuxerOptions() = default;
    14 
    15 } // namespace media
    16 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/muxer_options.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 
    +
    12 MuxerOptions::MuxerOptions() = default;
    +
    13 MuxerOptions::~MuxerOptions() = default;
    +
    14 
    +
    15 } // namespace media
    +
    16 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/d84/classshaka_1_1media_1_1AACAudioSpecificConfig-members.html b/docs/db/d84/classshaka_1_1media_1_1AACAudioSpecificConfig-members.html index 6d889f7ac6..ec505b7559 100644 --- a/docs/db/d84/classshaka_1_1media_1_1AACAudioSpecificConfig-members.html +++ b/docs/db/d84/classshaka_1_1media_1_1AACAudioSpecificConfig-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/d86/classshaka_1_1media_1_1NaluReader.html b/docs/db/d86/classshaka_1_1media_1_1NaluReader.html index 382695b4ac..f064fb3f5c 100644 --- a/docs/db/d86/classshaka_1_1media_1_1NaluReader.html +++ b/docs/db/d86/classshaka_1_1media_1_1NaluReader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::NaluReader Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

    Public Types

    -enum  Result { kOk, -kInvalidStream, -kEOStream +enum  Result { kOk +, kInvalidStream +, kEOStream }   @@ -333,9 +336,7 @@ static bool 
    FindStartCode< diff --git a/docs/db/d8f/mp4__muxer_8h_source.html b/docs/db/d8f/mp4__muxer_8h_source.html index f3aac6a5cd..9010d1d5d2 100644 --- a/docs/db/d8f/mp4__muxer_8h_source.html +++ b/docs/db/d8f/mp4__muxer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/mp4_muxer.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mp4_muxer.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_MP4_MUXER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_MP4_MUXER_H_
    9 
    10 #include <vector>
    11 
    12 #include "packager/base/optional.h"
    13 #include "packager/media/base/muxer.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    18 class AudioStreamInfo;
    19 class StreamInfo;
    20 class TextStreamInfo;
    21 class VideoStreamInfo;
    22 
    23 namespace mp4 {
    24 
    25 class Segmenter;
    26 
    27 struct ProtectionSchemeInfo;
    28 struct Track;
    29 
    32 class MP4Muxer : public Muxer {
    33  public:
    35  explicit MP4Muxer(const MuxerOptions& options);
    36  ~MP4Muxer() override;
    37 
    38  private:
    39  // Muxer implementation overrides.
    40  Status InitializeMuxer() override;
    41  Status Finalize() override;
    42  Status AddSample(size_t stream_id, const MediaSample& sample) override;
    43  Status FinalizeSegment(size_t stream_id,
    44  const SegmentInfo& segment_info) override;
    45 
    46  Status DelayInitializeMuxer();
    47  Status UpdateEditListOffsetFromSample(const MediaSample& sample);
    48 
    49  // Generate Audio/Video Track box.
    50  void InitializeTrak(const StreamInfo* info, Track* trak);
    51  bool GenerateAudioTrak(const AudioStreamInfo* audio_info,
    52  Track* trak,
    53  uint32_t track_id);
    54  bool GenerateVideoTrak(const VideoStreamInfo* video_info,
    55  Track* trak,
    56  uint32_t track_id);
    57  bool GenerateTextTrak(const TextStreamInfo* video_info,
    58  Track* trak,
    59  uint32_t track_id);
    60 
    61  // Gets |start| and |end| initialization range. Returns true if there is an
    62  // init range and sets start-end byte-range-spec specified in RFC2616.
    63  base::Optional<Range> GetInitRangeStartAndEnd();
    64 
    65  // Gets |start| and |end| index range. Returns true if there is an index range
    66  // and sets start-end byte-range-spec specified in RFC2616.
    67  base::Optional<Range> GetIndexRangeStartAndEnd();
    68 
    69  // Fire events if there are no errors and Muxer::muxer_listener() is not NULL.
    70  void FireOnMediaStartEvent();
    71  void FireOnMediaEndEvent();
    72 
    73  // Get time in seconds since midnight, Jan. 1, 1904, in UTC Time.
    74  uint64_t IsoTimeNow();
    75 
    76  // Assumes single stream (multiplexed a/v not supported yet).
    77  bool to_be_initialized_ = true;
    78  base::Optional<int64_t> edit_list_offset_;
    79 
    80  std::unique_ptr<Segmenter> segmenter_;
    81 
    82  DISALLOW_COPY_AND_ASSIGN(MP4Muxer);
    83 };
    84 
    85 } // namespace mp4
    86 } // namespace media
    87 } // namespace shaka
    88 
    89 #endif // PACKAGER_MEDIA_FORMATS_MP4_MP4_MUXER_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    - -
    MP4Muxer(const MuxerOptions &options)
    Create a MP4Muxer object from MuxerOptions.
    Definition: mp4_muxer.cc:151
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - - -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - - - -
    Holds video stream information.
    -
    Holds audio stream information.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_MP4_MUXER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_MP4_MUXER_H_
    +
    9 
    +
    10 #include <vector>
    +
    11 
    +
    12 #include "packager/base/optional.h"
    +
    13 #include "packager/media/base/muxer.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    18 class AudioStreamInfo;
    +
    19 class StreamInfo;
    +
    20 class TextStreamInfo;
    +
    21 class VideoStreamInfo;
    +
    22 
    +
    23 namespace mp4 {
    +
    24 
    +
    25 class Segmenter;
    +
    26 
    +
    27 struct ProtectionSchemeInfo;
    +
    28 struct Track;
    +
    29 
    +
    32 class MP4Muxer : public Muxer {
    +
    33  public:
    +
    35  explicit MP4Muxer(const MuxerOptions& options);
    +
    36  ~MP4Muxer() override;
    +
    37 
    +
    38  private:
    +
    39  // Muxer implementation overrides.
    +
    40  Status InitializeMuxer() override;
    +
    41  Status Finalize() override;
    +
    42  Status AddMediaSample(size_t stream_id, const MediaSample& sample) override;
    +
    43  Status FinalizeSegment(size_t stream_id,
    +
    44  const SegmentInfo& segment_info) override;
    +
    45 
    +
    46  Status DelayInitializeMuxer();
    +
    47  Status UpdateEditListOffsetFromSample(const MediaSample& sample);
    +
    48 
    +
    49  // Generate Audio/Video Track box.
    +
    50  void InitializeTrak(const StreamInfo* info, Track* trak);
    +
    51  bool GenerateAudioTrak(const AudioStreamInfo* audio_info, Track* trak);
    +
    52  bool GenerateVideoTrak(const VideoStreamInfo* video_info, Track* trak);
    +
    53  bool GenerateTextTrak(const TextStreamInfo* video_info, Track* trak);
    +
    54 
    +
    55  // Gets |start| and |end| initialization range. Returns true if there is an
    +
    56  // init range and sets start-end byte-range-spec specified in RFC2616.
    +
    57  base::Optional<Range> GetInitRangeStartAndEnd();
    +
    58 
    +
    59  // Gets |start| and |end| index range. Returns true if there is an index range
    +
    60  // and sets start-end byte-range-spec specified in RFC2616.
    +
    61  base::Optional<Range> GetIndexRangeStartAndEnd();
    +
    62 
    +
    63  // Fire events if there are no errors and Muxer::muxer_listener() is not NULL.
    +
    64  void FireOnMediaStartEvent();
    +
    65  void FireOnMediaEndEvent();
    +
    66 
    +
    67  // Get time in seconds since midnight, Jan. 1, 1904, in UTC Time.
    +
    68  uint64_t IsoTimeNow();
    +
    69 
    +
    70  // Assumes single stream (multiplexed a/v not supported yet).
    +
    71  bool to_be_initialized_ = true;
    +
    72  base::Optional<int64_t> edit_list_offset_;
    +
    73 
    +
    74  std::unique_ptr<Segmenter> segmenter_;
    +
    75 
    +
    76  DISALLOW_COPY_AND_ASSIGN(MP4Muxer);
    +
    77 };
    +
    78 
    +
    79 } // namespace mp4
    +
    80 } // namespace media
    +
    81 } // namespace shaka
    +
    82 
    +
    83 #endif // PACKAGER_MEDIA_FORMATS_MP4_MP4_MUXER_H_
    + +
    Holds audio stream information.
    +
    Class to hold a media sample.
    Definition: media_sample.h:22
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    + +
    Holds video stream information.
    + +
    MP4Muxer(const MuxerOptions &options)
    Create a MP4Muxer object from MuxerOptions.
    Definition: mp4_muxer.cc:155
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    + +
    diff --git a/docs/db/d94/classshaka_1_1media_1_1ClusterBuilder.html b/docs/db/d94/classshaka_1_1media_1_1ClusterBuilder.html index d5cc027a7f..ac1b021dcb 100644 --- a/docs/db/d94/classshaka_1_1media_1_1ClusterBuilder.html +++ b/docs/db/d94/classshaka_1_1media_1_1ClusterBuilder.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ClusterBuilder Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/d95/classshaka_1_1media_1_1mp4_1_1Fragmenter.html b/docs/db/d95/classshaka_1_1media_1_1mp4_1_1Fragmenter.html index a4bc26f882..8834af0e13 100644 --- a/docs/db/d95/classshaka_1_1media_1_1mp4_1_1Fragmenter.html +++ b/docs/db/d95/classshaka_1_1media_1_1mp4_1_1Fragmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Fragmenter Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/d95/structshaka_1_1media_1_1mp4_1_1ChunkLargeOffset.html b/docs/db/d95/structshaka_1_1media_1_1mp4_1_1ChunkLargeOffset.html index 69c5010057..538f9d0fc7 100644 --- a/docs/db/d95/structshaka_1_1media_1_1mp4_1_1ChunkLargeOffset.html +++ b/docs/db/d95/structshaka_1_1media_1_1mp4_1_1ChunkLargeOffset.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::ChunkLargeOffset Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box shaka::media::mp4::ChunkOffset - -
    + + @@ -122,7 +125,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 478 of file box_definitions.h.

    +

    Definition at line 491 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -152,7 +155,7 @@ Additional Inherited Members

    Reimplemented in shaka::media::mp4::ChunkOffset.

    -

    Definition at line 897 of file box_definitions.cc.

    +

    Definition at line 910 of file box_definitions.cc.

    @@ -163,9 +166,7 @@ Additional Inherited Members diff --git a/docs/db/d96/wvm__media__parser_8h_source.html b/docs/db/d96/wvm__media__parser_8h_source.html index ed7e10851e..ba449aa835 100644 --- a/docs/db/d96/wvm__media__parser_8h_source.html +++ b/docs/db/d96/wvm__media__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/wvm/wvm_media_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    wvm_media_parser.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 // Media parser for a Widevine Media Format (WVM) file.
    5 
    6 #ifndef PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
    7 #define PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
    8 
    9 #include <deque>
    10 #include <map>
    11 #include <memory>
    12 #include <string>
    13 #include <vector>
    14 
    15 #include "packager/base/compiler_specific.h"
    16 #include "packager/media/base/media_parser.h"
    17 #include "packager/media/base/network_util.h"
    18 #include "packager/media/codecs/h264_byte_to_unit_stream_converter.h"
    19 
    20 namespace shaka {
    21 namespace media {
    22 
    23 class AesCbcDecryptor;
    24 class KeySource;
    25 struct EncryptionKey;
    26 
    27 namespace wvm {
    28 
    30  public:
    33  uint32_t demux_stream_id;
    34  uint32_t parsed_audio_or_video_stream_id;
    35  std::shared_ptr<MediaSample> media_sample;
    36 };
    37 
    39  public:
    41  ~PrevSampleData();
    42  void Reset();
    43  std::shared_ptr<MediaSample> audio_sample;
    44  std::shared_ptr<MediaSample> video_sample;
    45  uint32_t audio_stream_id;
    46  uint32_t video_stream_id;
    47  int64_t audio_sample_duration;
    48  int64_t video_sample_duration;
    49 };
    50 
    51 class WvmMediaParser : public MediaParser {
    52  public:
    54  ~WvmMediaParser() override;
    55 
    58  void Init(const InitCB& init_cb,
    59  const NewSampleCB& new_sample_cb,
    60  KeySource* decryption_key_source) override;
    61  bool Flush() override WARN_UNUSED_RESULT;
    62  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
    64 
    65  private:
    66  enum Tag {
    67  CypherVersion = 0,
    68  TrackOffset = 1,
    69  TrackSize = 2,
    70  TrackDuration = 3,
    71  TrackBitRate = 4,
    72  TrackTrickPlayFactor = 5,
    73  TrackAdaptationInterval = 6,
    74  TrackFlags = 7,
    75  VideoType = 8,
    76  VideoProfile = 9,
    77  VideoLevel = 10,
    78  VideoWidth = 11,
    79  VideoHeight = 12,
    80  VideoTicksPerFrame = 13,
    81  VideoBitRate = 14,
    82  AudioType = 15,
    83  AudioProfile = 16,
    84  AudioNumChannels = 17,
    85  AudioSampleFrequency = 18,
    86  AudioBitRate = 19,
    87  TrackVersion = 20,
    88  Title = 21,
    89  Copyright = 22,
    90  ChapterIndex = 23,
    91  TimeIndex = 24,
    92  Thumbnail = 25,
    93  ObjectSeqNum = 26,
    94  ThumbnailOffset = 27,
    95  ThumbnailSize = 28,
    96  NumEntries = 29,
    97  Chapters = 30,
    98  VideoPixelWidth = 31,
    99  VideoPixelHeight = 32,
    100  FileSize = 33,
    101  SparseDownloadUrl = 34,
    102  SparseDownloadRangeTranslations = 35,
    103  SparseDownloadMap = 36,
    104  AudioSampleSize = 37,
    105  Audio_EsDescriptor = 38,
    106  Video_AVCDecoderConfigurationRecord = 39,
    107  Audio_EC3SpecificData = 40,
    108  AudioIdentifier = 41,
    109  VideoStreamId = 42,
    110  VideoStreamType = 43,
    111  AudioStreamId = 44,
    112  AudioStreamType = 45,
    113  Audio_DtsSpecificData = 46,
    114  Audio_AC3SpecificData = 47,
    115  Unset = 48
    116  };
    117 
    118  enum State {
    119  StartCode1 = 0,
    120  StartCode2,
    121  StartCode3,
    122  StartCode4,
    123  PackHeader1,
    124  PackHeader2,
    125  PackHeader3,
    126  PackHeader4,
    127  PackHeader5,
    128  PackHeader6,
    129  PackHeader7,
    130  PackHeader8,
    131  PackHeader9,
    132  PackHeader10,
    133  PackHeaderStuffingSkip,
    134  SystemHeader1,
    135  SystemHeader2,
    136  SystemHeaderSkip,
    137  PesStreamId,
    138  PesPacketLength1,
    139  PesPacketLength2,
    140  PesExtension1,
    141  PesExtension2,
    142  PesExtension3,
    143  Pts1,
    144  Pts2,
    145  Pts3,
    146  Pts4,
    147  Pts5,
    148  Dts1,
    149  Dts2,
    150  Dts3,
    151  Dts4,
    152  Dts5,
    153  PesHeaderData,
    154  PesPayload,
    155  EsPayload,
    156  PsmPayload,
    157  EcmPayload,
    158  IndexPayload,
    159  Padding,
    160  ProgramEnd
    161  };
    162 
    163  bool ProcessEcm();
    164 
    165  // Index denotes 'search index' in the WVM content.
    166  bool ParseIndexEntry();
    167 
    168  bool DemuxNextPes(bool is_program_end);
    169 
    170  void StartMediaSampleDemux();
    171 
    172  template <typename T>
    173  Tag GetTag(const uint8_t& tag,
    174  const uint32_t& length,
    175  const uint8_t* start_index,
    176  T* value) {
    177  if (length == sizeof(uint8_t)) {
    178  *value = (uint8_t)(*start_index);
    179  } else if (length == sizeof(int8_t)) {
    180  *value = (int8_t)(*start_index);
    181  } else if (length == sizeof(uint16_t)) {
    182  *value = (uint16_t)(ntohsFromBuffer(start_index));
    183  } else if (length == sizeof(int16_t)) {
    184  *value = (int16_t)(ntohsFromBuffer(start_index));
    185  } else if (length == sizeof(uint32_t)) {
    186  *value = (uint32_t)(ntohlFromBuffer(start_index));
    187  } else if (length == sizeof(int32_t)) {
    188  *value = (int32_t)(ntohlFromBuffer(start_index));
    189  } else if (length == sizeof(uint64_t)) {
    190  *value = (uint64_t)(ntohllFromBuffer(start_index));
    191  } else if (length == sizeof(int64_t)) {
    192  *value = (int64_t)(ntohllFromBuffer(start_index));
    193  } else {
    194  *value = 0;
    195  }
    196  return Tag(tag);
    197  }
    198 
    199  // |must_process_encrypted| setting determines if Output() should attempt
    200  // to ouput media sample as encrypted.
    201  bool Output(bool must_process_encrypted);
    202 
    203  bool GetAssetKey(const uint8_t* asset_id, EncryptionKey* encryption_key);
    204 
    205  // Callback invoked by the ES media parser
    206  // to emit a new audio/video access unit.
    207  bool EmitSample(uint32_t parsed_audio_or_video_stream_id,
    208  uint32_t stream_id,
    209  const std::shared_ptr<MediaSample>& new_sample,
    210  bool isLastSample);
    211 
    212  bool EmitPendingSamples();
    213 
    214  bool EmitLastSample(uint32_t stream_id,
    215  const std::shared_ptr<MediaSample>& new_sample);
    216 
    217  // List of callbacks.t
    218  InitCB init_cb_;
    219  NewSampleCB new_sample_cb_;
    220 
    221  // Whether |init_cb_| has been invoked.
    222  bool is_initialized_;
    223  // Internal content parsing state.
    224  State parse_state_;
    225 
    226  uint32_t skip_bytes_;
    227  bool metadata_is_complete_;
    228  uint8_t current_program_id_;
    229  uint32_t pes_stream_id_;
    230  uint32_t prev_pes_stream_id_;
    231  size_t pes_packet_bytes_;
    232  uint8_t pes_flags_1_;
    233  uint8_t pes_flags_2_;
    234  uint8_t prev_pes_flags_1_;
    235  size_t pes_header_data_bytes_;
    236  uint64_t timestamp_;
    237  uint64_t pts_;
    238  uint64_t dts_;
    239  uint8_t index_program_id_;
    240  std::shared_ptr<MediaSample> media_sample_;
    241  size_t crypto_unit_start_pos_;
    242  PrevSampleData prev_media_sample_data_;
    243  H264ByteToUnitStreamConverter byte_to_unit_stream_converter_;
    244 
    245  std::vector<uint8_t, std::allocator<uint8_t>> ecm_;
    246  std::vector<uint8_t> psm_data_;
    247  std::vector<uint8_t> index_data_;
    248  std::map<std::string, uint32_t> program_demux_stream_map_;
    249  int stream_id_count_;
    250  std::vector<std::shared_ptr<StreamInfo>> stream_infos_;
    251  std::deque<DemuxStreamIdMediaSample> media_sample_queue_;
    252  std::vector<uint8_t> sample_data_;
    253  KeySource* decryption_key_source_;
    254  std::unique_ptr<AesCbcDecryptor> content_decryptor_;
    255 
    256  DISALLOW_COPY_AND_ASSIGN(WvmMediaParser);
    257 };
    258 
    259 } // namespace wvm
    260 } // namespace media
    261 } // namespace shaka
    262 
    263 #endif // PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
    - - - -
    All the methods that are virtual are virtual for mocking.
    - -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 // Media parser for a Widevine Media Format (WVM) file.
    +
    5 
    +
    6 #ifndef PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
    +
    7 #define PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
    +
    8 
    +
    9 #include <deque>
    +
    10 #include <map>
    +
    11 #include <memory>
    +
    12 #include <string>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/base/compiler_specific.h"
    +
    16 #include "packager/media/base/media_parser.h"
    +
    17 #include "packager/media/base/network_util.h"
    +
    18 #include "packager/media/codecs/h264_byte_to_unit_stream_converter.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 namespace media {
    +
    22 
    +
    23 class AesCbcDecryptor;
    +
    24 class KeySource;
    +
    25 struct EncryptionKey;
    +
    26 
    +
    27 namespace wvm {
    +
    28 
    + +
    30  public:
    + + +
    33  uint32_t demux_stream_id;
    +
    34  uint32_t parsed_audio_or_video_stream_id;
    +
    35  std::shared_ptr<MediaSample> media_sample;
    +
    36 };
    +
    37 
    + +
    39  public:
    + +
    41  ~PrevSampleData();
    +
    42  void Reset();
    +
    43  std::shared_ptr<MediaSample> audio_sample;
    +
    44  std::shared_ptr<MediaSample> video_sample;
    +
    45  uint32_t audio_stream_id;
    +
    46  uint32_t video_stream_id;
    +
    47  int64_t audio_sample_duration;
    +
    48  int64_t video_sample_duration;
    +
    49 };
    +
    50 
    +
    51 class WvmMediaParser : public MediaParser {
    +
    52  public:
    + +
    54  ~WvmMediaParser() override;
    +
    55 
    +
    58  void Init(const InitCB& init_cb,
    +
    59  const NewMediaSampleCB& new_media_sample_cb,
    +
    60  const NewTextSampleCB& new_text_sample_cb,
    +
    61  KeySource* decryption_key_source) override;
    +
    62  bool Flush() override WARN_UNUSED_RESULT;
    +
    63  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
    +
    65 
    +
    66  private:
    +
    67  enum Tag {
    +
    68  CypherVersion = 0,
    +
    69  TrackOffset = 1,
    +
    70  TrackSize = 2,
    +
    71  TrackDuration = 3,
    +
    72  TrackBitRate = 4,
    +
    73  TrackTrickPlayFactor = 5,
    +
    74  TrackAdaptationInterval = 6,
    +
    75  TrackFlags = 7,
    +
    76  VideoType = 8,
    +
    77  VideoProfile = 9,
    +
    78  VideoLevel = 10,
    +
    79  VideoWidth = 11,
    +
    80  VideoHeight = 12,
    +
    81  VideoTicksPerFrame = 13,
    +
    82  VideoBitRate = 14,
    +
    83  AudioType = 15,
    +
    84  AudioProfile = 16,
    +
    85  AudioNumChannels = 17,
    +
    86  AudioSampleFrequency = 18,
    +
    87  AudioBitRate = 19,
    +
    88  TrackVersion = 20,
    +
    89  Title = 21,
    +
    90  Copyright = 22,
    +
    91  ChapterIndex = 23,
    +
    92  TimeIndex = 24,
    +
    93  Thumbnail = 25,
    +
    94  ObjectSeqNum = 26,
    +
    95  ThumbnailOffset = 27,
    +
    96  ThumbnailSize = 28,
    +
    97  NumEntries = 29,
    +
    98  Chapters = 30,
    +
    99  VideoPixelWidth = 31,
    +
    100  VideoPixelHeight = 32,
    +
    101  FileSize = 33,
    +
    102  SparseDownloadUrl = 34,
    +
    103  SparseDownloadRangeTranslations = 35,
    +
    104  SparseDownloadMap = 36,
    +
    105  AudioSampleSize = 37,
    +
    106  Audio_EsDescriptor = 38,
    +
    107  Video_AVCDecoderConfigurationRecord = 39,
    +
    108  Audio_EC3SpecificData = 40,
    +
    109  AudioIdentifier = 41,
    +
    110  VideoStreamId = 42,
    +
    111  VideoStreamType = 43,
    +
    112  AudioStreamId = 44,
    +
    113  AudioStreamType = 45,
    +
    114  Audio_DtsSpecificData = 46,
    +
    115  Audio_AC3SpecificData = 47,
    +
    116  Unset = 48
    +
    117  };
    +
    118 
    +
    119  enum State {
    +
    120  StartCode1 = 0,
    +
    121  StartCode2,
    +
    122  StartCode3,
    +
    123  StartCode4,
    +
    124  PackHeader1,
    +
    125  PackHeader2,
    +
    126  PackHeader3,
    +
    127  PackHeader4,
    +
    128  PackHeader5,
    +
    129  PackHeader6,
    +
    130  PackHeader7,
    +
    131  PackHeader8,
    +
    132  PackHeader9,
    +
    133  PackHeader10,
    +
    134  PackHeaderStuffingSkip,
    +
    135  SystemHeader1,
    +
    136  SystemHeader2,
    +
    137  SystemHeaderSkip,
    +
    138  PesStreamId,
    +
    139  PesPacketLength1,
    +
    140  PesPacketLength2,
    +
    141  PesExtension1,
    +
    142  PesExtension2,
    +
    143  PesExtension3,
    +
    144  Pts1,
    +
    145  Pts2,
    +
    146  Pts3,
    +
    147  Pts4,
    +
    148  Pts5,
    +
    149  Dts1,
    +
    150  Dts2,
    +
    151  Dts3,
    +
    152  Dts4,
    +
    153  Dts5,
    +
    154  PesHeaderData,
    +
    155  PesPayload,
    +
    156  EsPayload,
    +
    157  PsmPayload,
    +
    158  EcmPayload,
    +
    159  IndexPayload,
    +
    160  Padding,
    +
    161  ProgramEnd
    +
    162  };
    +
    163 
    +
    164  bool ProcessEcm();
    +
    165 
    +
    166  // Index denotes 'search index' in the WVM content.
    +
    167  bool ParseIndexEntry();
    +
    168 
    +
    169  bool DemuxNextPes(bool is_program_end);
    +
    170 
    +
    171  void StartMediaSampleDemux();
    +
    172 
    +
    173  template <typename T>
    +
    174  Tag GetTag(const uint8_t& tag,
    +
    175  const uint32_t& length,
    +
    176  const uint8_t* start_index,
    +
    177  T* value) {
    +
    178  if (length == sizeof(uint8_t)) {
    +
    179  *value = (uint8_t)(*start_index);
    +
    180  } else if (length == sizeof(int8_t)) {
    +
    181  *value = (int8_t)(*start_index);
    +
    182  } else if (length == sizeof(uint16_t)) {
    +
    183  *value = (uint16_t)(ntohsFromBuffer(start_index));
    +
    184  } else if (length == sizeof(int16_t)) {
    +
    185  *value = (int16_t)(ntohsFromBuffer(start_index));
    +
    186  } else if (length == sizeof(uint32_t)) {
    +
    187  *value = (uint32_t)(ntohlFromBuffer(start_index));
    +
    188  } else if (length == sizeof(int32_t)) {
    +
    189  *value = (int32_t)(ntohlFromBuffer(start_index));
    +
    190  } else if (length == sizeof(uint64_t)) {
    +
    191  *value = (uint64_t)(ntohllFromBuffer(start_index));
    +
    192  } else if (length == sizeof(int64_t)) {
    +
    193  *value = (int64_t)(ntohllFromBuffer(start_index));
    +
    194  } else {
    +
    195  *value = 0;
    +
    196  }
    +
    197  return Tag(tag);
    +
    198  }
    +
    199 
    +
    200  // |must_process_encrypted| setting determines if Output() should attempt
    +
    201  // to ouput media sample as encrypted.
    +
    202  bool Output(bool must_process_encrypted);
    +
    203 
    +
    204  bool GetAssetKey(const uint8_t* asset_id, EncryptionKey* encryption_key);
    +
    205 
    +
    206  // Callback invoked by the ES media parser
    +
    207  // to emit a new audio/video access unit.
    +
    208  bool EmitSample(uint32_t parsed_audio_or_video_stream_id,
    +
    209  uint32_t stream_id,
    +
    210  const std::shared_ptr<MediaSample>& new_sample,
    +
    211  bool isLastSample);
    +
    212 
    +
    213  bool EmitPendingSamples();
    +
    214 
    +
    215  bool EmitLastSample(uint32_t stream_id,
    +
    216  const std::shared_ptr<MediaSample>& new_sample);
    +
    217 
    +
    218  // List of callbacks.t
    +
    219  InitCB init_cb_;
    +
    220  NewMediaSampleCB new_sample_cb_;
    +
    221 
    +
    222  // Whether |init_cb_| has been invoked.
    +
    223  bool is_initialized_;
    +
    224  // Internal content parsing state.
    +
    225  State parse_state_;
    +
    226 
    +
    227  uint32_t skip_bytes_;
    +
    228  bool metadata_is_complete_;
    +
    229  uint8_t current_program_id_;
    +
    230  uint32_t pes_stream_id_;
    +
    231  uint32_t prev_pes_stream_id_;
    +
    232  size_t pes_packet_bytes_;
    +
    233  uint8_t pes_flags_1_;
    +
    234  uint8_t pes_flags_2_;
    +
    235  uint8_t prev_pes_flags_1_;
    +
    236  size_t pes_header_data_bytes_;
    +
    237  uint64_t timestamp_;
    +
    238  uint64_t pts_;
    +
    239  uint64_t dts_;
    +
    240  uint8_t index_program_id_;
    +
    241  std::shared_ptr<MediaSample> media_sample_;
    +
    242  size_t crypto_unit_start_pos_;
    +
    243  PrevSampleData prev_media_sample_data_;
    +
    244  H264ByteToUnitStreamConverter byte_to_unit_stream_converter_;
    +
    245 
    +
    246  std::vector<uint8_t, std::allocator<uint8_t>> ecm_;
    +
    247  std::vector<uint8_t> psm_data_;
    +
    248  std::vector<uint8_t> index_data_;
    +
    249  std::map<std::string, uint32_t> program_demux_stream_map_;
    +
    250  int stream_id_count_;
    +
    251  std::vector<std::shared_ptr<StreamInfo>> stream_infos_;
    +
    252  std::deque<DemuxStreamIdMediaSample> media_sample_queue_;
    +
    253  std::vector<uint8_t> sample_data_;
    +
    254  KeySource* decryption_key_source_;
    +
    255  std::unique_ptr<AesCbcDecryptor> content_decryptor_;
    +
    256 
    +
    257  DISALLOW_COPY_AND_ASSIGN(WvmMediaParser);
    +
    258 };
    +
    259 
    +
    260 } // namespace wvm
    +
    261 } // namespace media
    +
    262 } // namespace shaka
    +
    263 
    +
    264 #endif // PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
    + +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    + +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
    Definition: media_parser.h:53
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    + +
    void Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
    +
    bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    +
    bool Flush() override WARN_UNUSED_RESULT
    +
    All the methods that are virtual are virtual for mocking.
    + + +
    diff --git a/docs/db/da6/memory__file_8h_source.html b/docs/db/da6/memory__file_8h_source.html index 884ede9093..e1878876bb 100644 --- a/docs/db/da6/memory__file_8h_source.html +++ b/docs/db/da6/memory__file_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/memory_file.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    memory_file.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef MEDIA_FILE_MEDIA_FILE_H_
    8 #define MEDIA_FILE_MEDIA_FILE_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <string>
    13 #include <vector>
    14 
    15 #include "packager/file/file.h"
    16 
    17 namespace shaka {
    18 
    21 class MemoryFile : public File {
    22  public:
    23  MemoryFile(const std::string& file_name, const std::string& mode);
    24 
    27  bool Close() override;
    28  int64_t Read(void* buffer, uint64_t length) override;
    29  int64_t Write(const void* buffer, uint64_t length) override;
    30  int64_t Size() override;
    31  bool Flush() override;
    32  bool Seek(uint64_t position) override;
    33  bool Tell(uint64_t* position) override;
    35 
    39  static void DeleteAll();
    42  static void Delete(const std::string& file_name);
    43 
    44  protected:
    45  ~MemoryFile() override;
    46  bool Open() override;
    47 
    48  private:
    49  std::string mode_;
    50  std::vector<uint8_t>* file_;
    51  uint64_t position_;
    52 
    53  DISALLOW_COPY_AND_ASSIGN(MemoryFile);
    54 };
    55 
    56 } // namespace shaka
    57 
    58 #endif // MEDIA_FILE_MEDIA_FILE_H_
    static void Delete(const std::string &file_name)
    Definition: memory_file.cc:190
    -
    static void DeleteAll()
    Definition: memory_file.cc:186
    -
    bool Open() override
    Internal open. Should not be used directly.
    Definition: memory_file.cc:177
    -
    bool Close() override
    Definition: memory_file.cc:118
    -
    Define an abstract file interface.
    Definition: file.h:26
    -
    bool Seek(uint64_t position) override
    Definition: memory_file.cc:164
    -
    const std::string & file_name() const
    Definition: file.h:94
    -
    All the methods that are virtual are virtual for mocking.
    -
    int64_t Write(const void *buffer, uint64_t length) override
    Definition: memory_file.cc:137
    - -
    int64_t Size() override
    Definition: memory_file.cc:155
    -
    bool Tell(uint64_t *position) override
    Definition: memory_file.cc:172
    -
    bool Flush() override
    Definition: memory_file.cc:160
    -
    int64_t Read(void *buffer, uint64_t length) override
    Definition: memory_file.cc:125
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef MEDIA_FILE_MEDIA_FILE_H_
    +
    8 #define MEDIA_FILE_MEDIA_FILE_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <string>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/file/file.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 
    +
    21 class MemoryFile : public File {
    +
    22  public:
    +
    23  MemoryFile(const std::string& file_name, const std::string& mode);
    +
    24 
    +
    27  bool Close() override;
    +
    28  int64_t Read(void* buffer, uint64_t length) override;
    +
    29  int64_t Write(const void* buffer, uint64_t length) override;
    +
    30  int64_t Size() override;
    +
    31  bool Flush() override;
    +
    32  bool Seek(uint64_t position) override;
    +
    33  bool Tell(uint64_t* position) override;
    +
    35 
    +
    39  static void DeleteAll();
    +
    42  static void Delete(const std::string& file_name);
    +
    43 
    +
    44  protected:
    +
    45  ~MemoryFile() override;
    +
    46  bool Open() override;
    +
    47 
    +
    48  private:
    +
    49  std::string mode_;
    +
    50  std::vector<uint8_t>* file_;
    +
    51  uint64_t position_;
    +
    52 
    +
    53  DISALLOW_COPY_AND_ASSIGN(MemoryFile);
    +
    54 };
    +
    55 
    +
    56 } // namespace shaka
    +
    57 
    +
    58 #endif // MEDIA_FILE_MEDIA_FILE_H_
    +
    Define an abstract file interface.
    Definition: file.h:27
    +
    const std::string & file_name() const
    Definition: file.h:95
    + +
    bool Seek(uint64_t position) override
    Definition: memory_file.cc:164
    +
    int64_t Size() override
    Definition: memory_file.cc:155
    +
    static void Delete(const std::string &file_name)
    Definition: memory_file.cc:190
    +
    bool Close() override
    Definition: memory_file.cc:118
    +
    bool Tell(uint64_t *position) override
    Definition: memory_file.cc:172
    +
    int64_t Write(const void *buffer, uint64_t length) override
    Definition: memory_file.cc:137
    +
    static void DeleteAll()
    Definition: memory_file.cc:186
    +
    bool Open() override
    Internal open. Should not be used directly.
    Definition: memory_file.cc:177
    +
    int64_t Read(void *buffer, uint64_t length) override
    Definition: memory_file.cc:125
    +
    bool Flush() override
    Definition: memory_file.cc:160
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/dab/classshaka_1_1media_1_1TextStreamInfo.html b/docs/db/dab/classshaka_1_1media_1_1TextStreamInfo.html index afbe34204d..fddc58d82c 100644 --- a/docs/db/dab/classshaka_1_1media_1_1TextStreamInfo.html +++ b/docs/db/dab/classshaka_1_1media_1_1TextStreamInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::TextStreamInfo Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::media::StreamInfo - -
    +shaka::media::StreamInfo + + @@ -85,6 +88,8 @@ Public Member Functions + + + + + + + + + + + + + + - - @@ -159,7 +180,7 @@ void 

    Public Member Functions

     
    bool IsValidConfig () const override
     
    std::string ToString () const override
     
    std::unique_ptr< StreamInfoClone () const override
     
    @@ -93,12 +98,28 @@ uint16_t width () cons
    uint16_t height () const
     
    +const std::map< std::string, TextRegion > & regions () const
     
    +void AddRegion (const std::string &id, const TextRegion &region)
     
    +const std::string & css_styles () const
     
    +void set_css_styles (const std::string &styles)
     
    +void AddSubStream (uint16_t index, TextSubStreamInfo info)
     
    +const std::map< uint16_t, TextSubStreamInfo > & sub_streams () const
     
    - Public Member Functions inherited from shaka::media::StreamInfo
     StreamInfo (StreamType stream_type, int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const uint8_t *codec_config, size_t codec_config_size, const std::string &language, bool is_encrypted)
     
    virtual std::string ToString () const
     
    StreamType stream_type () const
     
    set_encryption_config

    Detailed Description

    -

    Definition at line 17 of file text_stream_info.h.

    +

    Definition at line 49 of file text_stream_info.h.

    Constructor & Destructor Documentation

    ◆ TextStreamInfo()

    @@ -243,7 +264,7 @@ void set_encryption_config -

    Definition at line 12 of file text_stream_info.cc.

    +

    Definition at line 14 of file text_stream_info.cc.

    @@ -274,7 +295,7 @@ void set_encryption_config

    Implements shaka::media::StreamInfo.

    -

    Definition at line 31 of file text_stream_info.cc.

    +

    Definition at line 45 of file text_stream_info.cc.

    @@ -304,7 +325,37 @@ void set_encryption_config

    Implements shaka::media::StreamInfo.

    -

    Definition at line 27 of file text_stream_info.cc.

    +

    Definition at line 29 of file text_stream_info.cc.

    + + + + +

    ◆ ToString()

    + +
    +
    + + + + + +
    + + + + + + + +
    std::string shaka::media::TextStreamInfo::ToString () const
    +
    +overridevirtual
    +
    +
    Returns
    A human-readable string describing the stream info.
    + +

    Reimplemented from shaka::media::StreamInfo.

    + +

    Definition at line 33 of file text_stream_info.cc.

    @@ -315,9 +366,7 @@ void set_encryption_config diff --git a/docs/db/dab/cue__alignment__handler_8cc_source.html b/docs/db/dab/cue__alignment__handler_8cc_source.html index 728ff0b10d..e84e7456b5 100644 --- a/docs/db/dab/cue__alignment__handler_8cc_source.html +++ b/docs/db/dab/cue__alignment__handler_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking/cue_alignment_handler.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    cue_alignment_handler.cc
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/chunking/cue_alignment_handler.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/status_macros.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace {
    16 // The max number of samples that are allowed to be buffered before we shutdown
    17 // because there is likely a problem with the content or how the pipeline was
    18 // configured. This is about 20 seconds of buffer for audio with 48kHz.
    19 const size_t kMaxBufferSize = 1000;
    20 
    21 int64_t GetScaledTime(const StreamInfo& info, const StreamData& data) {
    22  DCHECK(data.text_sample || data.media_sample);
    23 
    24  if (data.text_sample) {
    25  return data.text_sample->start_time();
    26  }
    27 
    28  if (info.stream_type() == kStreamText) {
    29  // This class does not support splitting MediaSample at cue points, which is
    30  // required for text stream. This class expects MediaSample to be converted
    31  // to TextSample before passing to this class.
    32  NOTREACHED()
    33  << "A text streams should use text samples, not media samples.";
    34  }
    35 
    36  if (info.stream_type() == kStreamAudio) {
    37  // Return the mid-point for audio because if the portion of the sample
    38  // after the cue point is bigger than the portion of the sample before
    39  // the cue point, the sample is placed after the cue.
    40  return data.media_sample->pts() + data.media_sample->duration() / 2;
    41  }
    42 
    43  DCHECK_EQ(info.stream_type(), kStreamVideo);
    44  return data.media_sample->pts();
    45 }
    46 
    47 double TimeInSeconds(const StreamInfo& info, const StreamData& data) {
    48  const int64_t scaled_time = GetScaledTime(info, data);
    49  const uint32_t time_scale = info.time_scale();
    50 
    51  return static_cast<double>(scaled_time) / time_scale;
    52 }
    53 
    54 double TextEndTimeInSeconds(const StreamInfo& info, const StreamData& data) {
    55  DCHECK(data.text_sample);
    56 
    57  const int64_t scaled_time = data.text_sample->EndTime();
    58  const uint32_t time_scale = info.time_scale();
    59 
    60  return static_cast<double>(scaled_time) / time_scale;
    61 }
    62 
    63 Status GetNextCue(double hint,
    64  SyncPointQueue* sync_points,
    65  std::shared_ptr<const CueEvent>* out_cue) {
    66  DCHECK(sync_points);
    67  DCHECK(out_cue);
    68 
    69  *out_cue = sync_points->GetNext(hint);
    70 
    71  // |*out_cue| will only be null if the job was cancelled.
    72  return *out_cue ? Status::OK
    73  : Status(error::CANCELLED, "SyncPointQueue is cancelled.");
    74 }
    75 } // namespace
    76 
    77 CueAlignmentHandler::CueAlignmentHandler(SyncPointQueue* sync_points)
    78  : sync_points_(sync_points) {}
    79 
    80 Status CueAlignmentHandler::InitializeInternal() {
    81  sync_points_->AddThread();
    82  stream_states_.resize(num_input_streams());
    83 
    84  // Get the first hint for the stream. Use a negative hint so that if there is
    85  // suppose to be a sync point at zero, we will still respect it.
    86  hint_ = sync_points_->GetHint(-1);
    87 
    88  return Status::OK;
    89 }
    90 
    91 Status CueAlignmentHandler::Process(std::unique_ptr<StreamData> data) {
    92  switch (data->stream_data_type) {
    93  case StreamDataType::kStreamInfo:
    94  return OnStreamInfo(std::move(data));
    95  case StreamDataType::kTextSample:
    96  case StreamDataType::kMediaSample:
    97  return OnSample(std::move(data));
    98  default:
    99  VLOG(3) << "Dropping unsupported data type "
    100  << static_cast<int>(data->stream_data_type);
    101  return Status::OK;
    102  }
    103 }
    104 
    105 Status CueAlignmentHandler::OnFlushRequest(size_t stream_index) {
    106  stream_states_[stream_index].to_be_flushed = true;
    107 
    108  // We need to wait for all stream to flush before we can flush each stream.
    109  // This allows cached buffers to be cleared and cues to be properly
    110  // synchronized and set on all streams.
    111  for (const StreamState& stream_state : stream_states_) {
    112  if (!stream_state.to_be_flushed) {
    113  return Status::OK;
    114  }
    115  }
    116 
    117  // Do a once over all the streams to ensure that their states are as we expect
    118  // them. Video and non-video streams have different allowances here. Video
    119  // should absolutely have no cues or samples where as non-video streams may
    120  // have cues or samples.
    121  for (StreamState& stream : stream_states_) {
    122  DCHECK(stream.to_be_flushed);
    123 
    124  if (stream.info->stream_type() == kStreamVideo) {
    125  DCHECK_EQ(stream.samples.size(), 0u)
    126  << "Video streams should not store samples";
    127  DCHECK_EQ(stream.cues.size(), 0u)
    128  << "Video streams should not store cues";
    129  }
    130  }
    131 
    132  // It is possible that we did not get all the cues. |hint_| will get updated
    133  // when we call |UseNextSyncPoint|.
    134  while (sync_points_->HasMore(hint_)) {
    135  std::shared_ptr<const CueEvent> next_cue;
    136  RETURN_IF_ERROR(GetNextCue(hint_, sync_points_, &next_cue));
    137  RETURN_IF_ERROR(UseNewSyncPoint(std::move(next_cue)));
    138  }
    139 
    140  // Now that there are new cues, it may be possible to dispatch some of the
    141  // samples that may be left waiting.
    142  for (StreamState& stream : stream_states_) {
    143  RETURN_IF_ERROR(RunThroughSamples(&stream));
    144  DCHECK_EQ(stream.samples.size(), 0u);
    145 
    146  // Ignore extra cues at the end, except for text, as they will result in
    147  // empty DASH Representations, which is not spec compliant.
    148  // For text, if the cue is before the max end time, it will still be
    149  // dispatched as the text samples intercepted by the cue can be split into
    150  // two at the cue point.
    151  for (auto& cue : stream.cues) {
    152  // |max_text_sample_end_time_seconds| is always 0 for non-text samples.
    153  if (cue->cue_event->time_in_seconds <
    154  stream.max_text_sample_end_time_seconds) {
    155  RETURN_IF_ERROR(Dispatch(std::move(cue)));
    156  } else {
    157  VLOG(1) << "Ignore extra cue in stream " << cue->stream_index
    158  << " with time " << cue->cue_event->time_in_seconds
    159  << "s in the end.";
    160  }
    161  }
    162  stream.cues.clear();
    163  }
    164 
    165  return FlushAllDownstreams();
    166 }
    167 
    168 Status CueAlignmentHandler::OnStreamInfo(std::unique_ptr<StreamData> data) {
    169  StreamState& stream_state = stream_states_[data->stream_index];
    170  // Keep a copy of the stream info so that we can check type and check
    171  // timescale.
    172  stream_state.info = data->stream_info;
    173 
    174  return Dispatch(std::move(data));
    175 }
    176 
    177 Status CueAlignmentHandler::OnVideoSample(std::unique_ptr<StreamData> sample) {
    178  DCHECK(sample);
    179  DCHECK(sample->media_sample);
    180 
    181  const size_t stream_index = sample->stream_index;
    182  StreamState& stream = stream_states_[stream_index];
    183 
    184  const double sample_time = TimeInSeconds(*stream.info, *sample);
    185  const bool is_key_frame = sample->media_sample->is_key_frame();
    186 
    187  if (is_key_frame && sample_time >= hint_) {
    188  auto next_sync = sync_points_->PromoteAt(sample_time);
    189 
    190  if (!next_sync) {
    191  LOG(ERROR) << "Failed to promote sync point at " << sample_time
    192  << ". This happens only if video streams are not GOP-aligned.";
    193  return Status(error::INVALID_ARGUMENT,
    194  "Streams are not properly GOP-aligned.");
    195  }
    196 
    197  RETURN_IF_ERROR(UseNewSyncPoint(std::move(next_sync)));
    198  DCHECK_EQ(stream.cues.size(), 1u);
    199  RETURN_IF_ERROR(Dispatch(std::move(stream.cues.front())));
    200  stream.cues.pop_front();
    201  }
    202 
    203  return Dispatch(std::move(sample));
    204 }
    205 
    206 Status CueAlignmentHandler::OnNonVideoSample(
    207  std::unique_ptr<StreamData> sample) {
    208  DCHECK(sample);
    209  DCHECK(sample->media_sample || sample->text_sample);
    210 
    211  const size_t stream_index = sample->stream_index;
    212  StreamState& stream_state = stream_states_[stream_index];
    213 
    214  // Accept the sample. This will output it if it comes before the hint point or
    215  // will cache it if it comes after the hint point.
    216  RETURN_IF_ERROR(AcceptSample(std::move(sample), &stream_state));
    217 
    218  // If all the streams are waiting on a hint, it means that none has next sync
    219  // point determined. It also means that there are no video streams and we need
    220  // to wait for all streams to converge on a hint so that we can get the next
    221  // sync point.
    222  if (EveryoneWaitingAtHint()) {
    223  std::shared_ptr<const CueEvent> next_sync;
    224  RETURN_IF_ERROR(GetNextCue(hint_, sync_points_, &next_sync));
    225  RETURN_IF_ERROR(UseNewSyncPoint(next_sync));
    226  }
    227 
    228  return Status::OK;
    229 }
    230 
    231 Status CueAlignmentHandler::OnSample(std::unique_ptr<StreamData> sample) {
    232  // There are two modes:
    233  // 1. There is a video input.
    234  // 2. There are no video inputs.
    235  //
    236  // When there is a video input, we rely on the video input get the next sync
    237  // point and release all the samples.
    238  //
    239  // When there are no video inputs, we rely on the sync point queue to block
    240  // us until there is a sync point.
    241 
    242  const size_t stream_index = sample->stream_index;
    243 
    244  if (sample->text_sample) {
    245  StreamState& stream = stream_states_[stream_index];
    246  stream.max_text_sample_end_time_seconds =
    247  std::max(stream.max_text_sample_end_time_seconds,
    248  TextEndTimeInSeconds(*stream.info, *sample));
    249  }
    250 
    251  const StreamType stream_type =
    252  stream_states_[stream_index].info->stream_type();
    253  const bool is_video = stream_type == kStreamVideo;
    254 
    255  return is_video ? OnVideoSample(std::move(sample))
    256  : OnNonVideoSample(std::move(sample));
    257 }
    258 
    259 Status CueAlignmentHandler::UseNewSyncPoint(
    260  std::shared_ptr<const CueEvent> new_sync) {
    261  hint_ = sync_points_->GetHint(new_sync->time_in_seconds);
    262  DCHECK_GT(hint_, new_sync->time_in_seconds);
    263 
    264  for (size_t stream_index = 0; stream_index < stream_states_.size();
    265  stream_index++) {
    266  StreamState& stream = stream_states_[stream_index];
    267  stream.cues.push_back(StreamData::FromCueEvent(stream_index, new_sync));
    268 
    269  RETURN_IF_ERROR(RunThroughSamples(&stream));
    270  }
    271 
    272  return Status::OK;
    273 }
    274 
    275 bool CueAlignmentHandler::EveryoneWaitingAtHint() const {
    276  for (const StreamState& stream_state : stream_states_) {
    277  if (stream_state.samples.empty()) {
    278  return false;
    279  }
    280  }
    281  return true;
    282 }
    283 
    284 Status CueAlignmentHandler::AcceptSample(std::unique_ptr<StreamData> sample,
    285  StreamState* stream) {
    286  DCHECK(sample);
    287  DCHECK(sample->media_sample || sample->text_sample);
    288  DCHECK(stream);
    289 
    290  // Need to cache the stream index as we will lose the pointer when we add
    291  // the sample to the queue.
    292  const size_t stream_index = sample->stream_index;
    293 
    294  stream->samples.push_back(std::move(sample));
    295 
    296  if (stream->samples.size() > kMaxBufferSize) {
    297  LOG(ERROR) << "Stream " << stream_index << " has buffered "
    298  << stream->samples.size() << " when the max is "
    299  << kMaxBufferSize;
    300  return Status(error::INVALID_ARGUMENT,
    301  "Streams are not properly multiplexed.");
    302  }
    303 
    304  return RunThroughSamples(stream);
    305 }
    306 
    307 Status CueAlignmentHandler::RunThroughSamples(StreamState* stream) {
    308  // Step through all our samples until we find where we can insert the cue.
    309  // Think of this as a merge sort.
    310  while (stream->cues.size() && stream->samples.size()) {
    311  const double cue_time = stream->cues.front()->cue_event->time_in_seconds;
    312  const double sample_time =
    313  TimeInSeconds(*stream->info, *stream->samples.front());
    314 
    315  if (sample_time < cue_time) {
    316  RETURN_IF_ERROR(Dispatch(std::move(stream->samples.front())));
    317  stream->samples.pop_front();
    318  } else {
    319  RETURN_IF_ERROR(Dispatch(std::move(stream->cues.front())));
    320  stream->cues.pop_front();
    321  }
    322  }
    323 
    324  // If we still have samples, then it means that we sent out the cue and can
    325  // now work up to the hint. So now send all samples that come before the hint
    326  // downstream.
    327  while (stream->samples.size() &&
    328  TimeInSeconds(*stream->info, *stream->samples.front()) < hint_) {
    329  RETURN_IF_ERROR(Dispatch(std::move(stream->samples.front())));
    330  stream->samples.pop_front();
    331  }
    332 
    333  return Status::OK;
    334 }
    335 } // namespace media
    336 } // namespace shaka
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    -
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    -
    Status FlushAllDownstreams()
    Flush all connected downstream handlers.
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/chunking/cue_alignment_handler.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/status_macros.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace {
    +
    16 // The max number of samples that are allowed to be buffered before we shutdown
    +
    17 // because there is likely a problem with the content or how the pipeline was
    +
    18 // configured. This is about 20 seconds of buffer for audio with 48kHz.
    +
    19 const size_t kMaxBufferSize = 1000;
    +
    20 
    +
    21 int64_t GetScaledTime(const StreamInfo& info, const StreamData& data) {
    +
    22  DCHECK(data.text_sample || data.media_sample);
    +
    23 
    +
    24  if (data.text_sample) {
    +
    25  return data.text_sample->start_time();
    +
    26  }
    +
    27 
    +
    28  if (info.stream_type() == kStreamText) {
    +
    29  // This class does not support splitting MediaSample at cue points, which is
    +
    30  // required for text stream. This class expects MediaSample to be converted
    +
    31  // to TextSample before passing to this class.
    +
    32  NOTREACHED()
    +
    33  << "A text streams should use text samples, not media samples.";
    +
    34  }
    +
    35 
    +
    36  if (info.stream_type() == kStreamAudio) {
    +
    37  // Return the mid-point for audio because if the portion of the sample
    +
    38  // after the cue point is bigger than the portion of the sample before
    +
    39  // the cue point, the sample is placed after the cue.
    +
    40  return data.media_sample->pts() + data.media_sample->duration() / 2;
    +
    41  }
    +
    42 
    +
    43  DCHECK_EQ(info.stream_type(), kStreamVideo);
    +
    44  return data.media_sample->pts();
    +
    45 }
    +
    46 
    +
    47 double TimeInSeconds(const StreamInfo& info, const StreamData& data) {
    +
    48  const int64_t scaled_time = GetScaledTime(info, data);
    +
    49  const uint32_t time_scale = info.time_scale();
    +
    50 
    +
    51  return static_cast<double>(scaled_time) / time_scale;
    +
    52 }
    +
    53 
    +
    54 double TextEndTimeInSeconds(const StreamInfo& info, const StreamData& data) {
    +
    55  DCHECK(data.text_sample);
    +
    56 
    +
    57  const int64_t scaled_time = data.text_sample->EndTime();
    +
    58  const uint32_t time_scale = info.time_scale();
    +
    59 
    +
    60  return static_cast<double>(scaled_time) / time_scale;
    +
    61 }
    +
    62 
    +
    63 Status GetNextCue(double hint,
    +
    64  SyncPointQueue* sync_points,
    +
    65  std::shared_ptr<const CueEvent>* out_cue) {
    +
    66  DCHECK(sync_points);
    +
    67  DCHECK(out_cue);
    +
    68 
    +
    69  *out_cue = sync_points->GetNext(hint);
    +
    70 
    +
    71  // |*out_cue| will only be null if the job was cancelled.
    +
    72  return *out_cue ? Status::OK
    +
    73  : Status(error::CANCELLED, "SyncPointQueue is cancelled.");
    +
    74 }
    +
    75 } // namespace
    +
    76 
    +
    77 CueAlignmentHandler::CueAlignmentHandler(SyncPointQueue* sync_points)
    +
    78  : sync_points_(sync_points) {}
    +
    79 
    +
    80 Status CueAlignmentHandler::InitializeInternal() {
    +
    81  sync_points_->AddThread();
    +
    82  stream_states_.resize(num_input_streams());
    +
    83 
    +
    84  // Get the first hint for the stream. Use a negative hint so that if there is
    +
    85  // suppose to be a sync point at zero, we will still respect it.
    +
    86  hint_ = sync_points_->GetHint(-1);
    +
    87 
    +
    88  return Status::OK;
    +
    89 }
    +
    90 
    +
    91 Status CueAlignmentHandler::Process(std::unique_ptr<StreamData> data) {
    +
    92  switch (data->stream_data_type) {
    +
    93  case StreamDataType::kStreamInfo:
    +
    94  return OnStreamInfo(std::move(data));
    +
    95  case StreamDataType::kTextSample:
    +
    96  case StreamDataType::kMediaSample:
    +
    97  return OnSample(std::move(data));
    +
    98  default:
    +
    99  VLOG(3) << "Dropping unsupported data type "
    +
    100  << static_cast<int>(data->stream_data_type);
    +
    101  return Status::OK;
    +
    102  }
    +
    103 }
    +
    104 
    +
    105 Status CueAlignmentHandler::OnFlushRequest(size_t stream_index) {
    +
    106  stream_states_[stream_index].to_be_flushed = true;
    +
    107 
    +
    108  // We need to wait for all stream to flush before we can flush each stream.
    +
    109  // This allows cached buffers to be cleared and cues to be properly
    +
    110  // synchronized and set on all streams.
    +
    111  for (const StreamState& stream_state : stream_states_) {
    +
    112  if (!stream_state.to_be_flushed) {
    +
    113  return Status::OK;
    +
    114  }
    +
    115  }
    +
    116 
    +
    117  // Do a once over all the streams to ensure that their states are as we expect
    +
    118  // them. Video and non-video streams have different allowances here. Video
    +
    119  // should absolutely have no cues or samples where as non-video streams may
    +
    120  // have cues or samples.
    +
    121  for (StreamState& stream : stream_states_) {
    +
    122  DCHECK(stream.to_be_flushed);
    +
    123 
    +
    124  if (stream.info->stream_type() == kStreamVideo) {
    +
    125  DCHECK_EQ(stream.samples.size(), 0u)
    +
    126  << "Video streams should not store samples";
    +
    127  DCHECK_EQ(stream.cues.size(), 0u)
    +
    128  << "Video streams should not store cues";
    +
    129  }
    +
    130  }
    +
    131 
    +
    132  // It is possible that we did not get all the cues. |hint_| will get updated
    +
    133  // when we call |UseNextSyncPoint|.
    +
    134  while (sync_points_->HasMore(hint_)) {
    +
    135  std::shared_ptr<const CueEvent> next_cue;
    +
    136  RETURN_IF_ERROR(GetNextCue(hint_, sync_points_, &next_cue));
    +
    137  RETURN_IF_ERROR(UseNewSyncPoint(std::move(next_cue)));
    +
    138  }
    +
    139 
    +
    140  // Now that there are new cues, it may be possible to dispatch some of the
    +
    141  // samples that may be left waiting.
    +
    142  for (StreamState& stream : stream_states_) {
    +
    143  RETURN_IF_ERROR(RunThroughSamples(&stream));
    +
    144  DCHECK_EQ(stream.samples.size(), 0u);
    +
    145 
    +
    146  // Ignore extra cues at the end, except for text, as they will result in
    +
    147  // empty DASH Representations, which is not spec compliant.
    +
    148  // For text, if the cue is before the max end time, it will still be
    +
    149  // dispatched as the text samples intercepted by the cue can be split into
    +
    150  // two at the cue point.
    +
    151  for (auto& cue : stream.cues) {
    +
    152  // |max_text_sample_end_time_seconds| is always 0 for non-text samples.
    +
    153  if (cue->cue_event->time_in_seconds <
    +
    154  stream.max_text_sample_end_time_seconds) {
    +
    155  RETURN_IF_ERROR(Dispatch(std::move(cue)));
    +
    156  } else {
    +
    157  VLOG(1) << "Ignore extra cue in stream " << cue->stream_index
    +
    158  << " with time " << cue->cue_event->time_in_seconds
    +
    159  << "s in the end.";
    +
    160  }
    +
    161  }
    +
    162  stream.cues.clear();
    +
    163  }
    +
    164 
    +
    165  return FlushAllDownstreams();
    +
    166 }
    +
    167 
    +
    168 Status CueAlignmentHandler::OnStreamInfo(std::unique_ptr<StreamData> data) {
    +
    169  StreamState& stream_state = stream_states_[data->stream_index];
    +
    170  // Keep a copy of the stream info so that we can check type and check
    +
    171  // timescale.
    +
    172  stream_state.info = data->stream_info;
    +
    173 
    +
    174  return Dispatch(std::move(data));
    +
    175 }
    +
    176 
    +
    177 Status CueAlignmentHandler::OnVideoSample(std::unique_ptr<StreamData> sample) {
    +
    178  DCHECK(sample);
    +
    179  DCHECK(sample->media_sample);
    +
    180 
    +
    181  const size_t stream_index = sample->stream_index;
    +
    182  StreamState& stream = stream_states_[stream_index];
    +
    183 
    +
    184  const double sample_time = TimeInSeconds(*stream.info, *sample);
    +
    185  const bool is_key_frame = sample->media_sample->is_key_frame();
    +
    186 
    +
    187  if (is_key_frame && sample_time >= hint_) {
    +
    188  auto next_sync = sync_points_->PromoteAt(sample_time);
    +
    189 
    +
    190  if (!next_sync) {
    +
    191  LOG(ERROR) << "Failed to promote sync point at " << sample_time
    +
    192  << ". This happens only if video streams are not GOP-aligned.";
    +
    193  return Status(error::INVALID_ARGUMENT,
    +
    194  "Streams are not properly GOP-aligned.");
    +
    195  }
    +
    196 
    +
    197  RETURN_IF_ERROR(UseNewSyncPoint(std::move(next_sync)));
    +
    198  DCHECK_EQ(stream.cues.size(), 1u);
    +
    199  RETURN_IF_ERROR(Dispatch(std::move(stream.cues.front())));
    +
    200  stream.cues.pop_front();
    +
    201  }
    +
    202 
    +
    203  return Dispatch(std::move(sample));
    +
    204 }
    +
    205 
    +
    206 Status CueAlignmentHandler::OnNonVideoSample(
    +
    207  std::unique_ptr<StreamData> sample) {
    +
    208  DCHECK(sample);
    +
    209  DCHECK(sample->media_sample || sample->text_sample);
    +
    210 
    +
    211  const size_t stream_index = sample->stream_index;
    +
    212  StreamState& stream_state = stream_states_[stream_index];
    +
    213 
    +
    214  // Accept the sample. This will output it if it comes before the hint point or
    +
    215  // will cache it if it comes after the hint point.
    +
    216  RETURN_IF_ERROR(AcceptSample(std::move(sample), &stream_state));
    +
    217 
    +
    218  // If all the streams are waiting on a hint, it means that none has next sync
    +
    219  // point determined. It also means that there are no video streams and we need
    +
    220  // to wait for all streams to converge on a hint so that we can get the next
    +
    221  // sync point.
    +
    222  if (EveryoneWaitingAtHint()) {
    +
    223  std::shared_ptr<const CueEvent> next_sync;
    +
    224  RETURN_IF_ERROR(GetNextCue(hint_, sync_points_, &next_sync));
    +
    225  RETURN_IF_ERROR(UseNewSyncPoint(next_sync));
    +
    226  }
    +
    227 
    +
    228  return Status::OK;
    +
    229 }
    +
    230 
    +
    231 Status CueAlignmentHandler::OnSample(std::unique_ptr<StreamData> sample) {
    +
    232  // There are two modes:
    +
    233  // 1. There is a video input.
    +
    234  // 2. There are no video inputs.
    +
    235  //
    +
    236  // When there is a video input, we rely on the video input get the next sync
    +
    237  // point and release all the samples.
    +
    238  //
    +
    239  // When there are no video inputs, we rely on the sync point queue to block
    +
    240  // us until there is a sync point.
    +
    241 
    +
    242  const size_t stream_index = sample->stream_index;
    +
    243 
    +
    244  if (sample->text_sample) {
    +
    245  StreamState& stream = stream_states_[stream_index];
    +
    246  stream.max_text_sample_end_time_seconds =
    +
    247  std::max(stream.max_text_sample_end_time_seconds,
    +
    248  TextEndTimeInSeconds(*stream.info, *sample));
    +
    249  }
    +
    250 
    +
    251  const StreamType stream_type =
    +
    252  stream_states_[stream_index].info->stream_type();
    +
    253  const bool is_video = stream_type == kStreamVideo;
    +
    254 
    +
    255  return is_video ? OnVideoSample(std::move(sample))
    +
    256  : OnNonVideoSample(std::move(sample));
    +
    257 }
    +
    258 
    +
    259 Status CueAlignmentHandler::UseNewSyncPoint(
    +
    260  std::shared_ptr<const CueEvent> new_sync) {
    +
    261  hint_ = sync_points_->GetHint(new_sync->time_in_seconds);
    +
    262  DCHECK_GT(hint_, new_sync->time_in_seconds);
    +
    263 
    +
    264  for (size_t stream_index = 0; stream_index < stream_states_.size();
    +
    265  stream_index++) {
    +
    266  StreamState& stream = stream_states_[stream_index];
    +
    267  stream.cues.push_back(StreamData::FromCueEvent(stream_index, new_sync));
    +
    268 
    +
    269  RETURN_IF_ERROR(RunThroughSamples(&stream));
    +
    270  }
    +
    271 
    +
    272  return Status::OK;
    +
    273 }
    +
    274 
    +
    275 bool CueAlignmentHandler::EveryoneWaitingAtHint() const {
    +
    276  for (const StreamState& stream_state : stream_states_) {
    +
    277  if (stream_state.samples.empty()) {
    +
    278  return false;
    +
    279  }
    +
    280  }
    +
    281  return true;
    +
    282 }
    +
    283 
    +
    284 Status CueAlignmentHandler::AcceptSample(std::unique_ptr<StreamData> sample,
    +
    285  StreamState* stream) {
    +
    286  DCHECK(sample);
    +
    287  DCHECK(sample->media_sample || sample->text_sample);
    +
    288  DCHECK(stream);
    +
    289 
    +
    290  // Need to cache the stream index as we will lose the pointer when we add
    +
    291  // the sample to the queue.
    +
    292  const size_t stream_index = sample->stream_index;
    +
    293 
    +
    294  stream->samples.push_back(std::move(sample));
    +
    295 
    +
    296  if (stream->samples.size() > kMaxBufferSize) {
    +
    297  LOG(ERROR) << "Stream " << stream_index << " has buffered "
    +
    298  << stream->samples.size() << " when the max is "
    +
    299  << kMaxBufferSize;
    +
    300  return Status(error::INVALID_ARGUMENT,
    +
    301  "Streams are not properly multiplexed.");
    +
    302  }
    +
    303 
    +
    304  return RunThroughSamples(stream);
    +
    305 }
    +
    306 
    +
    307 Status CueAlignmentHandler::RunThroughSamples(StreamState* stream) {
    +
    308  // Step through all our samples until we find where we can insert the cue.
    +
    309  // Think of this as a merge sort.
    +
    310  while (stream->cues.size() && stream->samples.size()) {
    +
    311  const double cue_time = stream->cues.front()->cue_event->time_in_seconds;
    +
    312  const double sample_time =
    +
    313  TimeInSeconds(*stream->info, *stream->samples.front());
    +
    314 
    +
    315  if (sample_time < cue_time) {
    +
    316  RETURN_IF_ERROR(Dispatch(std::move(stream->samples.front())));
    +
    317  stream->samples.pop_front();
    +
    318  } else {
    +
    319  RETURN_IF_ERROR(Dispatch(std::move(stream->cues.front())));
    +
    320  stream->cues.pop_front();
    +
    321  }
    +
    322  }
    +
    323 
    +
    324  // If we still have samples, then it means that we sent out the cue and can
    +
    325  // now work up to the hint. So now send all samples that come before the hint
    +
    326  // downstream.
    +
    327  while (stream->samples.size() &&
    +
    328  TimeInSeconds(*stream->info, *stream->samples.front()) < hint_) {
    +
    329  RETURN_IF_ERROR(Dispatch(std::move(stream->samples.front())));
    +
    330  stream->samples.pop_front();
    +
    331  }
    +
    332 
    +
    333  return Status::OK;
    +
    334 }
    +
    335 } // namespace media
    +
    336 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/dae/classshaka_1_1media_1_1WebMInfoParser.html b/docs/db/dae/classshaka_1_1media_1_1WebMInfoParser.html index 1c468e5910..e4f1c5eb0a 100644 --- a/docs/db/dae/classshaka_1_1media_1_1WebMInfoParser.html +++ b/docs/db/dae/classshaka_1_1media_1_1WebMInfoParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMInfoParser Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::WebMParserClient - -
    + + @@ -152,9 +155,7 @@ The number of bytes parsed on success. diff --git a/docs/db/dae/structshaka_1_1media_1_1mp4_1_1SoundMediaHeader-members.html b/docs/db/dae/structshaka_1_1media_1_1mp4_1_1SoundMediaHeader-members.html index cba45d10cb..62448caec0 100644 --- a/docs/db/dae/structshaka_1_1media_1_1mp4_1_1SoundMediaHeader-members.html +++ b/docs/db/dae/structshaka_1_1media_1_1mp4_1_1SoundMediaHeader-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    diff --git a/docs/db/db1/structshaka_1_1media_1_1mp4_1_1CencSampleEncryptionInfoEntry-members.html b/docs/db/db1/structshaka_1_1media_1_1mp4_1_1CencSampleEncryptionInfoEntry-members.html index 437ac36f7b..4702b92eaf 100644 --- a/docs/db/db1/structshaka_1_1media_1_1mp4_1_1CencSampleEncryptionInfoEntry-members.html +++ b/docs/db/db1/structshaka_1_1media_1_1mp4_1_1CencSampleEncryptionInfoEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/db/db6/structshaka_1_1media_1_1TextSettings-members.html b/docs/db/db6/structshaka_1_1media_1_1TextSettings-members.html new file mode 100644 index 0000000000..edffb10370 --- /dev/null +++ b/docs/db/db6/structshaka_1_1media_1_1TextSettings-members.html @@ -0,0 +1,88 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::TextSettings Member List
    +
    + + + + + diff --git a/docs/db/db8/ac4__audio__util_8cc_source.html b/docs/db/db8/ac4__audio__util_8cc_source.html new file mode 100644 index 0000000000..ab6f94e473 --- /dev/null +++ b/docs/db/db8/ac4__audio__util_8cc_source.html @@ -0,0 +1,607 @@ + + + + + + + +Shaka Packager SDK: packager/media/codecs/ac4_audio_util.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    ac4_audio_util.cc
    +
    +
    +
    1 // Copyright 2020 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/ac4_audio_util.h"
    +
    8 
    +
    9 #include "packager/base/macros.h"
    +
    10 #include "packager/base/strings/string_number_conversions.h"
    +
    11 #include "packager/media/base/bit_reader.h"
    +
    12 #include "packager/media/base/rcheck.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 namespace {
    +
    18 
    +
    19 // Speaker group index
    +
    20 // Bit, Location
    +
    21 // 0(LSB), Left/Right pair
    +
    22 // 1, Centre
    +
    23 // 2, Left surround/Right surround pair
    +
    24 // 3, Left back/Right back pair
    +
    25 // 4, Top front left/Top front right pair
    +
    26 // 5, Top back left/Top back right pair
    +
    27 // 6, LFE
    +
    28 // 7, Top left/Top right pair
    +
    29 // 8, Top side left/Top side right pair
    +
    30 // 9, Top front centre
    +
    31 // 10, Top back centre
    +
    32 // 11, Top centre
    +
    33 // 12, LFE2
    +
    34 // 13, Bottom front left/Bottom front right pair
    +
    35 // 14, Bottom front centre
    +
    36 // 15, Back centre
    +
    37 // 16, Left screen/Right screen pair
    +
    38 // 17, Left wide/Right wide pair
    +
    39 // 18, Vertical height left/Vertical height right pair
    +
    40 enum kAC4AudioChannelGroupIndex {
    +
    41  kLRPair = 0x1,
    +
    42  kCentre = 0x2,
    +
    43  kLsRsPair = 0x4,
    +
    44  kLbRbPair = 0x8,
    +
    45  kTflTfrPair = 0x10,
    +
    46  kTblTbrPair = 0x20,
    +
    47  kLFE = 0x40,
    +
    48  kTlTrPair = 0x80,
    +
    49  kTslTsrPair = 0x100,
    +
    50  kTopfrontCentre = 0x200,
    +
    51  kTopbackCentre = 0x400,
    +
    52  kTopCentre = 0x800,
    +
    53  kLFE2 = 0x1000,
    +
    54  kBflBfrPair = 0x2000,
    +
    55  kBottomFrontCentre = 0x4000,
    +
    56  kBackCentre = 0x8000,
    +
    57  kLscrRscrPair = 0x10000,
    +
    58  kLwRw = 0x20000,
    +
    59  kVhlVhrPair = 0x40000,
    +
    60 };
    +
    61 
    +
    62 // Mapping of channel configurations to the MPEG audio value based on ETSI TS
    +
    63 // 103 192-2 V1.2.1 Digital Audio Compression (AC-4) Standard;
    +
    64 // Part 2: Immersive and personalized Table G.1
    +
    65 uint32_t AC4ChannelMasktoMPEGValue(uint32_t channel_mask) {
    +
    66  uint32_t ret = 0;
    +
    67 
    +
    68  switch (channel_mask) {
    +
    69  case kCentre:
    +
    70  ret = 1;
    +
    71  break;
    +
    72  case kLRPair:
    +
    73  ret = 2;
    +
    74  break;
    +
    75  case kCentre | kLRPair:
    +
    76  ret = 3;
    +
    77  break;
    +
    78  case kCentre | kLRPair | kBackCentre:
    +
    79  ret = 4;
    +
    80  break;
    +
    81  case kCentre | kLRPair | kLsRsPair:
    +
    82  ret = 5;
    +
    83  break;
    +
    84  case kCentre | kLRPair | kLsRsPair | kLFE:
    +
    85  ret = 6;
    +
    86  break;
    +
    87  case kCentre | kLRPair | kLsRsPair | kLFE | kLwRw:
    +
    88  ret = 7;
    +
    89  break;
    +
    90  case kBackCentre | kLRPair:
    +
    91  ret = 9;
    +
    92  break;
    +
    93  case kLRPair | kLsRsPair:
    +
    94  ret = 10;
    +
    95  break;
    +
    96  case kCentre | kLRPair | kLsRsPair | kLFE | kBackCentre:
    +
    97  ret = 11;
    +
    98  break;
    +
    99  case kCentre | kLRPair | kLsRsPair | kLbRbPair | kLFE:
    +
    100  ret = 12;
    +
    101  break;
    +
    102  case kLwRw | kBackCentre | kBottomFrontCentre | kBflBfrPair | kLFE2 |
    +
    103  kTopCentre | kTopbackCentre | kTopfrontCentre | kTslTsrPair | kLFE |
    +
    104  kTblTbrPair | kTflTfrPair | kLbRbPair | kLsRsPair | kCentre | kLRPair:
    +
    105  case kVhlVhrPair | kLwRw | kBackCentre | kBottomFrontCentre | kBflBfrPair|
    +
    106  kLFE2 | kTopCentre | kTopbackCentre | kTopfrontCentre | kTslTsrPair |
    +
    107  kLFE | kTblTbrPair | kLbRbPair | kLsRsPair | kCentre | kLRPair:
    +
    108  ret = 13;
    +
    109  break;
    +
    110  case kLFE | kTflTfrPair | kLsRsPair | kCentre | kLRPair:
    +
    111  case kVhlVhrPair | kLFE | kCentre | kLRPair | kLsRsPair:
    +
    112  ret = 14;
    +
    113  break;
    +
    114  case kLFE2 | kTopbackCentre | kLFE | kTflTfrPair | kCentre | kLRPair |
    +
    115  kLsRsPair | kLbRbPair:
    +
    116  case kVhlVhrPair | kLFE2 | kTopbackCentre | kLFE | kCentre | kLRPair |
    +
    117  kLsRsPair | kLbRbPair:
    +
    118  ret = 15;
    +
    119  break;
    +
    120  case kLFE | kTblTbrPair | kTflTfrPair | kLsRsPair | kCentre | kLRPair:
    +
    121  case kVhlVhrPair | kLFE | kTblTbrPair | kLsRsPair | kCentre | kLRPair:
    +
    122  ret = 16;
    +
    123  break;
    +
    124  case kTopCentre | kTopfrontCentre | kLFE | kTblTbrPair | kTflTfrPair |
    +
    125  kLsRsPair | kCentre | kLRPair:
    +
    126  case kVhlVhrPair | kTopCentre | kTopfrontCentre | kLFE | kTblTbrPair |
    +
    127  kLsRsPair | kCentre | kLRPair:
    +
    128  ret = 17;
    +
    129  break;
    +
    130  case kTopCentre | kTopfrontCentre | kLFE | kTblTbrPair | kTflTfrPair |
    +
    131  kCentre | kLRPair | kLsRsPair | kLbRbPair:
    +
    132  case kVhlVhrPair | kTopCentre | kTopfrontCentre | kLFE | kTblTbrPair |
    +
    133  kCentre | kLRPair | kLsRsPair | kLbRbPair:
    +
    134  ret = 18;
    +
    135  break;
    +
    136  case kLFE | kTblTbrPair | kTflTfrPair | kCentre | kLRPair | kLsRsPair |
    +
    137  kLbRbPair:
    +
    138  case kVhlVhrPair | kLFE | kTblTbrPair | kCentre | kLRPair | kLsRsPair |
    +
    139  kLbRbPair:
    +
    140  ret = 19;
    +
    141  break;
    +
    142  case kLscrRscrPair | kLFE | kTblTbrPair | kTflTfrPair | kCentre | kLRPair |
    +
    143  kLsRsPair | kLbRbPair:
    +
    144  case kVhlVhrPair | kLscrRscrPair | kLFE | kTblTbrPair | kCentre | kLRPair |
    +
    145  kLsRsPair | kLbRbPair:
    +
    146  ret = 20;
    +
    147  break;
    +
    148  default:
    +
    149  ret = 0xFFFFFFFF;
    +
    150  }
    +
    151  return ret;
    +
    152 }
    +
    153 
    +
    154 // Parse AC-4 substream group based on ETSI TS 103 192-2 V1.2.1 Digital Audio
    +
    155 // Compression (AC-4) Standard; Part 2: Immersive and personalized E.11.
    +
    156 bool ParseAC4SubStreamGroupDsi(BitReader& bit_reader) {
    +
    157  bool b_substream_present;
    +
    158  RCHECK(bit_reader.ReadBits(1, &b_substream_present));
    +
    159  bool b_hsf_ext;
    +
    160  RCHECK(bit_reader.ReadBits(1, &b_hsf_ext));
    +
    161  bool b_channel_coded;
    +
    162  RCHECK(bit_reader.ReadBits(1, &b_channel_coded));
    +
    163  uint8_t n_substreams;
    +
    164  RCHECK(bit_reader.ReadBits(8, &n_substreams));
    +
    165  for (uint8_t i = 0; i < n_substreams; i++) {
    +
    166  RCHECK(bit_reader.SkipBits(2));
    +
    167  bool b_substream_bitrate_indicator;
    +
    168  RCHECK(bit_reader.ReadBits(1, &b_substream_bitrate_indicator));
    +
    169  if (b_substream_bitrate_indicator) {
    +
    170  RCHECK(bit_reader.SkipBits(5));
    +
    171  }
    +
    172  if (b_channel_coded) {
    +
    173  RCHECK(bit_reader.SkipBits(24));
    +
    174  } else {
    +
    175  bool b_ajoc;
    +
    176  RCHECK(bit_reader.ReadBits(1, &b_ajoc));
    +
    177  if (b_ajoc) {
    +
    178  bool b_static_dmx;
    +
    179  RCHECK(bit_reader.ReadBits(1, &b_static_dmx));
    +
    180  if (!b_static_dmx) {
    +
    181  RCHECK(bit_reader.SkipBits(4));
    +
    182  }
    +
    183  RCHECK(bit_reader.SkipBits(6));
    +
    184  }
    +
    185  RCHECK(bit_reader.SkipBits(4));
    +
    186  }
    +
    187  }
    +
    188  bool b_content_type;
    +
    189  RCHECK(bit_reader.ReadBits(1, &b_content_type));
    +
    190  if (b_content_type) {
    +
    191  RCHECK(bit_reader.SkipBits(3));
    +
    192  bool b_language_indicator;
    +
    193  RCHECK(bit_reader.ReadBits(1, &b_language_indicator));
    +
    194  if (b_language_indicator) {
    +
    195  uint8_t n_language_tag_bytes;
    +
    196  RCHECK(bit_reader.ReadBits(6, &n_language_tag_bytes));
    +
    197  RCHECK(bit_reader.SkipBits(n_language_tag_bytes * 8));
    +
    198  }
    +
    199  }
    +
    200  return true;
    +
    201 }
    +
    202 
    +
    203 // Parse AC-4 Presentation V1 based on ETSI TS 103 192-2 V1.2.1 Digital Audio
    +
    204 // Compression (AC-4) Standard;Part 2: Immersive and personalized E.10.
    +
    205 bool ParseAC4PresentationV1Dsi(BitReader& bit_reader,
    +
    206  uint32_t pres_bytes,
    +
    207  uint8_t* mdcompat,
    +
    208  uint32_t* presentation_channel_mask_v1,
    +
    209  bool* dolby_cbi_indicator,
    +
    210  uint8_t* dolby_atmos_indicator) {
    +
    211  bool ret = true;
    +
    212  // Record the initial offset.
    +
    213  const size_t presentation_start = bit_reader.bit_position();
    +
    214  uint8_t presentation_config_v1;
    +
    215  RCHECK(bit_reader.ReadBits(5, &presentation_config_v1));
    +
    216  uint8_t b_add_emdf_substreams;
    +
    217  // set default value (stereo content) for output parameters.
    +
    218  *mdcompat = 0;
    +
    219  *presentation_channel_mask_v1 = 2;
    +
    220  *dolby_cbi_indicator = false;
    +
    221  *dolby_atmos_indicator = 0;
    +
    222  if (presentation_config_v1 == 0x06) {
    +
    223  b_add_emdf_substreams = 1;
    +
    224  } else {
    +
    225  RCHECK(bit_reader.ReadBits(3, mdcompat));
    +
    226  bool b_presentation_id;
    +
    227  RCHECK(bit_reader.ReadBits(1, &b_presentation_id));
    +
    228  if (b_presentation_id) {
    +
    229  RCHECK(bit_reader.SkipBits(5));
    +
    230  }
    +
    231  RCHECK(bit_reader.SkipBits(19));
    +
    232  bool b_presentation_channel_coded;
    +
    233  RCHECK(bit_reader.ReadBits(1, &b_presentation_channel_coded));
    +
    234  *presentation_channel_mask_v1 = 0;
    +
    235  if (b_presentation_channel_coded) {
    +
    236  uint8_t dsi_presentation_ch_mode;
    +
    237  RCHECK(bit_reader.ReadBits(5, &dsi_presentation_ch_mode));
    +
    238  if (dsi_presentation_ch_mode >= 11 && dsi_presentation_ch_mode <= 14) {
    +
    239  RCHECK(bit_reader.SkipBits(1));
    +
    240  uint8_t pres_top_channel_pairs;
    +
    241  RCHECK(bit_reader.ReadBits(2, &pres_top_channel_pairs));
    +
    242  if (pres_top_channel_pairs) {
    +
    243  *dolby_cbi_indicator = true;
    +
    244  }
    +
    245  } else if (dsi_presentation_ch_mode == 15) {
    +
    246  *dolby_cbi_indicator = true;
    +
    247  }
    +
    248  RCHECK(bit_reader.ReadBits(24, presentation_channel_mask_v1));
    +
    249  }
    +
    250  bool b_presentation_core_differs;
    +
    251  RCHECK(bit_reader.ReadBits(1, &b_presentation_core_differs));
    +
    252  if (b_presentation_core_differs) {
    +
    253  bool b_presentation_core_channel_coded;
    +
    254  RCHECK(bit_reader.ReadBits(1, &b_presentation_core_channel_coded));
    +
    255  if (b_presentation_core_channel_coded) {
    +
    256  RCHECK(bit_reader.SkipBits(2));
    +
    257  }
    +
    258  }
    +
    259  bool b_presentation_filter;
    +
    260  RCHECK(bit_reader.ReadBits(1, &b_presentation_filter));
    +
    261  if (b_presentation_filter) {
    +
    262  RCHECK(bit_reader.SkipBits(1));
    +
    263  uint8_t n_filter_bytes;
    +
    264  RCHECK(bit_reader.ReadBits(8, &n_filter_bytes));
    +
    265  RCHECK(bit_reader.SkipBits(n_filter_bytes * 8));
    +
    266  }
    +
    267  if (presentation_config_v1 == 0x1f) {
    +
    268  ret &= ParseAC4SubStreamGroupDsi(bit_reader);
    +
    269  } else {
    +
    270  RCHECK(bit_reader.SkipBits(1));
    +
    271  if (presentation_config_v1 == 0 ||
    +
    272  presentation_config_v1 == 1 ||
    +
    273  presentation_config_v1 == 2) {
    +
    274  ret &= ParseAC4SubStreamGroupDsi(bit_reader);
    +
    275  ret &= ParseAC4SubStreamGroupDsi(bit_reader);
    +
    276  }
    +
    277  if (presentation_config_v1 == 3 || presentation_config_v1 == 4) {
    +
    278  ret &= ParseAC4SubStreamGroupDsi(bit_reader);
    +
    279  ret &= ParseAC4SubStreamGroupDsi(bit_reader);
    +
    280  ret &= ParseAC4SubStreamGroupDsi(bit_reader);
    +
    281  }
    +
    282  if (presentation_config_v1 == 5) {
    +
    283  uint8_t n_substream_groups_minus2;
    +
    284  RCHECK(bit_reader.ReadBits(3, &n_substream_groups_minus2));
    +
    285  for (uint8_t sg = 0; sg < n_substream_groups_minus2 + 2; sg++) {
    +
    286  ret &= ParseAC4SubStreamGroupDsi(bit_reader);
    +
    287  }
    +
    288  }
    +
    289  if (presentation_config_v1 > 5) {
    +
    290  uint8_t n_skip_bytes;
    +
    291  RCHECK(bit_reader.ReadBits(7, &n_skip_bytes));
    +
    292  RCHECK(bit_reader.SkipBits(n_skip_bytes * 8));
    +
    293  }
    +
    294  }
    +
    295  RCHECK(bit_reader.SkipBits(1));
    +
    296  RCHECK(bit_reader.ReadBits(1, &b_add_emdf_substreams));
    +
    297  }
    +
    298  if (b_add_emdf_substreams) {
    +
    299  uint8_t n_add_emdf_substreams;
    +
    300  RCHECK(bit_reader.ReadBits(7, &n_add_emdf_substreams));
    +
    301  RCHECK(bit_reader.SkipBits(n_add_emdf_substreams * 15));
    +
    302  }
    +
    303  bool b_presentation_bitrate_info;
    +
    304  RCHECK(bit_reader.ReadBits(1, &b_presentation_bitrate_info));
    +
    305  if (b_presentation_bitrate_info) {
    +
    306  // Skip bit rate information based on ETSI TS 103 190-2 v1.2.1 E.7.1
    +
    307  RCHECK(bit_reader.SkipBits(66));
    +
    308  }
    +
    309  bool b_alternative;
    +
    310  RCHECK(bit_reader.ReadBits(1, &b_alternative));
    +
    311  if (b_alternative) {
    +
    312  bit_reader.SkipToNextByte();
    +
    313  // Parse alternative information based on ETSI TS 103 190-2 v1.2.1 E.12
    +
    314  uint16_t name_len;
    +
    315  RCHECK(bit_reader.ReadBits(16, &name_len));
    +
    316  RCHECK(bit_reader.SkipBits(name_len * 8));
    +
    317  uint8_t n_targets;
    +
    318  RCHECK(bit_reader.ReadBits(5, &n_targets));
    +
    319  RCHECK(bit_reader.SkipBits(n_targets * 11));
    +
    320  }
    +
    321  bit_reader.SkipToNextByte();
    +
    322  if ((bit_reader.bit_position() - presentation_start) <=
    +
    323  (pres_bytes - 1) * 8) {
    +
    324  RCHECK(bit_reader.SkipBits(1));
    +
    325  RCHECK(bit_reader.ReadBits(1, dolby_atmos_indicator));
    +
    326  RCHECK(bit_reader.SkipBits(4));
    +
    327  bool b_extended_presentation_group_index;
    +
    328  RCHECK(bit_reader.ReadBits(1, &b_extended_presentation_group_index));
    +
    329  if (b_extended_presentation_group_index) {
    +
    330  RCHECK(bit_reader.SkipBits(9));
    +
    331  } else {
    +
    332  RCHECK(bit_reader.SkipBits(1));
    +
    333  }
    +
    334  }
    +
    335  return ret;
    +
    336 }
    +
    337 
    +
    338 bool ExtractAc4Data(const std::vector<uint8_t>& ac4_data,
    +
    339  uint8_t* bitstream_version,
    +
    340  uint8_t* presentation_version,
    +
    341  uint8_t* mdcompat,
    +
    342  uint32_t* presentation_channel_mask_v1,
    +
    343  bool* dolby_ims_indicator,
    +
    344  bool* dolby_cbi_indicator) {
    +
    345  BitReader bit_reader(ac4_data.data(), ac4_data.size());
    +
    346 
    +
    347  uint16_t n_presentation;
    +
    348  RCHECK(bit_reader.SkipBits(3) && bit_reader.ReadBits(7, bitstream_version));
    +
    349  RCHECK(bit_reader.SkipBits(5) && bit_reader.ReadBits(9, &n_presentation));
    +
    350 
    +
    351  if (*bitstream_version == 2) {
    +
    352  uint8_t b_program_id = 0;
    +
    353  RCHECK(bit_reader.ReadBits(1, &b_program_id));
    +
    354  if (b_program_id) {
    +
    355  RCHECK(bit_reader.SkipBits(16));
    +
    356  uint8_t b_uuid = 0;
    +
    357  RCHECK(bit_reader.ReadBits(1, &b_uuid));
    +
    358  if (b_uuid) {
    +
    359  RCHECK(bit_reader.SkipBits(16 * 8));
    +
    360  }
    +
    361  }
    +
    362  } else if (*bitstream_version == 0 || *bitstream_version == 1) {
    +
    363  LOG(WARNING) << "Bitstream version 0 or 1 is not supported";
    +
    364  return false;
    +
    365  } else {
    +
    366  LOG(WARNING) << "Invalid Bitstream version";
    +
    367  return false;
    +
    368  }
    +
    369 
    +
    370  RCHECK(bit_reader.SkipBits(66));
    +
    371  bit_reader.SkipToNextByte();
    +
    372 
    +
    373  // AC4 stream containing the single presentation is valid for OTT only.
    +
    374  // IMS has two presentations, and the 2nd is legacy (duplicated) presentation.
    +
    375  // So it can be considered as AC4 stream with single presentation. And IMS
    +
    376  // presentation must be prior to legacy presentation.
    +
    377  // In other word, only the 1st presentation in AC4 stream need to be parsed.
    +
    378  const uint8_t ott_n_presentation = 1;
    +
    379  for (uint8_t i = 0; i < ott_n_presentation; i++) {
    +
    380  RCHECK(bit_reader.ReadBits(8, presentation_version));
    +
    381  // *presentation_version == 2 means IMS presentation.
    +
    382  if ((*presentation_version == 2 && n_presentation > 2) ||
    +
    383  (*presentation_version == 1 && n_presentation > 1) ) {
    +
    384  LOG(WARNING) << "Seeing multiple presentations, only single presentation "
    +
    385  << "(including IMS presentation) is supported";
    +
    386  return false;
    +
    387  }
    +
    388  uint32_t pres_bytes;
    +
    389  RCHECK(bit_reader.ReadBits(8, &pres_bytes));
    +
    390  if (pres_bytes == 255) {
    +
    391  uint32_t add_pres_bytes;
    +
    392  RCHECK(bit_reader.ReadBits(16, &add_pres_bytes));
    +
    393  pres_bytes += add_pres_bytes;
    +
    394  }
    +
    395 
    +
    396  size_t presentation_bits = 0;
    +
    397  *dolby_ims_indicator = false;
    +
    398  if (*presentation_version == 0) {
    +
    399  LOG(WARNING) << "Presentation version 0 is not supported";
    +
    400  return false;
    +
    401  } else {
    +
    402  if (*presentation_version == 1 || *presentation_version == 2) {
    +
    403  if (*presentation_version == 2) {
    +
    404  *dolby_ims_indicator = true;
    +
    405  }
    +
    406  const size_t presentation_start = bit_reader.bit_position();
    +
    407  // dolby_atmos_indicator is extended in Dolby internal specs.
    +
    408  // It indicates whether the source content before encoding is Atmos.
    +
    409  // No final decision about how to use it in OTT.
    +
    410  // Parse it for the future usage.
    +
    411  uint8_t dolby_atmos_indicator;
    +
    412  if (!ParseAC4PresentationV1Dsi(bit_reader, pres_bytes, mdcompat,
    +
    413  presentation_channel_mask_v1,
    +
    414  dolby_cbi_indicator,
    +
    415  &dolby_atmos_indicator)) {
    +
    416  return false;
    +
    417  }
    +
    418  const size_t presentation_end = bit_reader.bit_position();
    +
    419  presentation_bits = presentation_end - presentation_start;
    +
    420  } else {
    +
    421  LOG(WARNING) << "Invalid Presentation version";
    +
    422  return false;
    +
    423  }
    +
    424  }
    +
    425  size_t skip_bits = pres_bytes * 8 - presentation_bits;
    +
    426  RCHECK(bit_reader.SkipBits(skip_bits));
    +
    427  }
    +
    428  return true;
    +
    429 }
    +
    430 } // namespace
    +
    431 
    +
    432 bool CalculateAC4ChannelMask(const std::vector<uint8_t>& ac4_data,
    +
    433  uint32_t* ac4_channel_mask) {
    +
    434  uint8_t bitstream_version;
    +
    435  uint8_t presentation_version;
    +
    436  uint8_t mdcompat;
    +
    437  uint32_t pre_channel_mask;
    +
    438  bool dolby_ims_indicator;
    +
    439  bool dolby_cbi_indicator;
    +
    440 
    +
    441  if (!ExtractAc4Data(ac4_data, &bitstream_version, &presentation_version,
    +
    442  &mdcompat, &pre_channel_mask, &dolby_ims_indicator,
    +
    443  &dolby_cbi_indicator)) {
    +
    444  LOG(WARNING) << "Seeing invalid AC4 data: "
    +
    445  << base::HexEncode(ac4_data.data(), ac4_data.size());
    +
    446  return false;
    +
    447  }
    +
    448 
    +
    449  if (pre_channel_mask) {
    +
    450  *ac4_channel_mask = pre_channel_mask;
    +
    451  } else {
    +
    452  *ac4_channel_mask = 0x800000;
    +
    453  }
    +
    454  return true;
    +
    455 }
    +
    456 
    +
    457 bool CalculateAC4ChannelMPEGValue(const std::vector<uint8_t>& ac4_data,
    +
    458  uint32_t* ac4_channel_mpeg_value) {
    +
    459  uint8_t bitstream_version;
    +
    460  uint8_t presentation_version;
    +
    461  uint8_t mdcompat;
    +
    462  uint32_t pre_channel_mask;
    +
    463  bool dolby_ims_indicator;
    +
    464  bool dolby_cbi_indicator;
    +
    465 
    +
    466  if (!ExtractAc4Data(ac4_data, &bitstream_version, &presentation_version,
    +
    467  &mdcompat, &pre_channel_mask, &dolby_ims_indicator,
    +
    468  &dolby_cbi_indicator)) {
    +
    469  LOG(WARNING) << "Seeing invalid AC4 data: "
    +
    470  << base::HexEncode(ac4_data.data(), ac4_data.size());
    +
    471  return false;
    +
    472  }
    +
    473 
    +
    474  *ac4_channel_mpeg_value = AC4ChannelMasktoMPEGValue(pre_channel_mask);
    +
    475  return true;
    +
    476 }
    +
    477 
    +
    478 bool GetAc4CodecInfo(const std::vector<uint8_t>& ac4_data,
    +
    479  uint8_t* ac4_codec_info) {
    +
    480  uint8_t bitstream_version;
    +
    481  uint8_t presentation_version;
    +
    482  uint8_t mdcompat;
    +
    483  uint32_t pre_channel_mask;
    +
    484  bool dolby_ims_indicator;
    +
    485  bool dolby_cbi_indicator;
    +
    486 
    +
    487  if (!ExtractAc4Data(ac4_data, &bitstream_version, &presentation_version,
    +
    488  &mdcompat, &pre_channel_mask, &dolby_ims_indicator,
    +
    489  &dolby_cbi_indicator)) {
    +
    490  LOG(WARNING) << "Seeing invalid AC4 data: "
    +
    491  << base::HexEncode(ac4_data.data(), ac4_data.size());
    +
    492  return false;
    +
    493  }
    +
    494 
    +
    495  // The valid value of bitstream_version (8 bits) is 2, the valid value of
    +
    496  // presentation_version (8 bits) is 1 or 2, and mdcompat is 3 bits.
    +
    497  // So uint8_t is fine now. If Dolby extends the value of bitstream_version and
    +
    498  // presentation_version in future, maybe need change the type from uint8_t to
    +
    499  // uint16_t or uint32_t to accommodate the valid values.
    +
    500  // If that, AudioStreamInfo::GetCodecString need to be changed accordingly.
    +
    501  // bitstream_version (3bits) + presentation_version (2bits) + mdcompat (3bits)
    +
    502  *ac4_codec_info = ((bitstream_version << 5) |
    +
    503  ((presentation_version << 3) & 0x1F) |
    +
    504  (mdcompat & 0x7));
    +
    505  return true;
    +
    506 }
    +
    507 
    +
    508 bool GetAc4ImmersiveInfo(const std::vector<uint8_t>& ac4_data,
    +
    509  bool* ac4_ims_flag,
    +
    510  bool* ac4_cbi_flag) {
    +
    511  uint8_t bitstream_version;
    +
    512  uint8_t presentation_version;
    +
    513  uint8_t mdcompat;
    +
    514  uint32_t pre_channel_mask;
    +
    515 
    +
    516  if (!ExtractAc4Data(ac4_data, &bitstream_version, &presentation_version,
    +
    517  &mdcompat, &pre_channel_mask, ac4_ims_flag,
    +
    518  ac4_cbi_flag)) {
    +
    519  LOG(WARNING) << "Seeing invalid AC4 data: "
    +
    520  << base::HexEncode(ac4_data.data(), ac4_data.size());
    +
    521  return false;
    +
    522  }
    +
    523 
    +
    524  return true;
    +
    525 }
    +
    526 
    +
    527 } // namespace media
    +
    528 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/db/db8/structshaka_1_1media_1_1OnMediaEndParameters.html b/docs/db/db8/structshaka_1_1media_1_1OnMediaEndParameters.html index 6ea0204402..dde2ba5607 100644 --- a/docs/db/db8/structshaka_1_1media_1_1OnMediaEndParameters.html +++ b/docs/db/db8/structshaka_1_1media_1_1OnMediaEndParameters.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::OnMediaEndParameters Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    duration_seconds
    diff --git a/docs/db/db8/structshaka_1_1media_1_1mp4_1_1TrackEncryption.html b/docs/db/db8/structshaka_1_1media_1_1mp4_1_1TrackEncryption.html index 5c6ef3ef24..5d2c6925bb 100644 --- a/docs/db/db8/structshaka_1_1media_1_1mp4_1_1TrackEncryption.html +++ b/docs/db/db8/structshaka_1_1media_1_1mp4_1_1TrackEncryption.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TrackEncryption Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -136,7 +139,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 143 of file box_definitions.h.

    +

    Definition at line 144 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -164,7 +167,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 420 of file box_definitions.cc.

    +

    Definition at line 432 of file box_definitions.cc.

    @@ -175,9 +178,7 @@ Additional Inherited Members diff --git a/docs/db/db9/text__chunker_8cc_source.html b/docs/db/db9/text__chunker_8cc_source.html index b387945e39..692bcfd3a3 100644 --- a/docs/db/db9/text__chunker_8cc_source.html +++ b/docs/db/db9/text__chunker_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking/text_chunker.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    text_chunker.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/chunking/text_chunker.h"
    8 
    9 #include "packager/status_macros.h"
    10 
    11 namespace shaka {
    12 namespace media {
    13 namespace {
    14 const size_t kStreamIndex = 0;
    15 } // namespace
    16 
    17 TextChunker::TextChunker(double segment_duration_in_seconds)
    18  : segment_duration_in_seconds_(segment_duration_in_seconds){};
    19 
    20 Status TextChunker::Process(std::unique_ptr<StreamData> data) {
    21  switch (data->stream_data_type) {
    22  case StreamDataType::kStreamInfo:
    23  return OnStreamInfo(std::move(data->stream_info));
    24  case StreamDataType::kTextSample:
    25  return OnTextSample(data->text_sample);
    26  case StreamDataType::kCueEvent:
    27  return OnCueEvent(data->cue_event);
    28  default:
    29  return Status(error::INTERNAL_ERROR,
    30  "Invalid stream data type for this handler");
    31  }
    32 }
    33 
    34 Status TextChunker::OnFlushRequest(size_t input_stream_index) {
    35  // Keep outputting segments until all the samples leave the system. Calling
    36  // |DispatchSegment| will remove samples over time.
    37  while (samples_in_current_segment_.size()) {
    38  RETURN_IF_ERROR(DispatchSegment(segment_duration_));
    39  }
    40 
    41  return FlushAllDownstreams();
    42 }
    43 
    44 Status TextChunker::OnStreamInfo(std::shared_ptr<const StreamInfo> info) {
    45  time_scale_ = info->time_scale();
    46  segment_duration_ = ScaleTime(segment_duration_in_seconds_);
    47 
    48  return DispatchStreamInfo(kStreamIndex, std::move(info));
    49 }
    50 
    51 Status TextChunker::OnCueEvent(std::shared_ptr<const CueEvent> event) {
    52  // We are going to end the current segment prematurely using the cue event's
    53  // time as the new segment end.
    54 
    55  // Because the cue should have been inserted into the stream such that no
    56  // later sample could start before it does, we know that there should
    57  // be no later samples starting before the cue event.
    58 
    59  // Convert the event's time to be scaled to the time of each sample.
    60  const int64_t event_time = ScaleTime(event->time_in_seconds);
    61 
    62  // Output all full segments before the segment that the cue event interupts.
    63  while (segment_start_ + segment_duration_ < event_time) {
    64  RETURN_IF_ERROR(DispatchSegment(segment_duration_));
    65  }
    66 
    67  const int64_t shorten_duration = event_time - segment_start_;
    68 
    69  RETURN_IF_ERROR(DispatchSegment(shorten_duration));
    70  return DispatchCueEvent(kStreamIndex, std::move(event));
    71 }
    72 
    73 Status TextChunker::OnTextSample(std::shared_ptr<const TextSample> sample) {
    74  // Output all segments that come before our new sample.
    75  const int64_t sample_start = sample->start_time();
    76 
    77  // If we have not seen a sample yet, base all segments off the first sample's
    78  // start time.
    79  if (segment_start_ < 0) {
    80  // Force the first segment to start at the segment that would have started
    81  // before the sample. This should allow segments from different streams to
    82  // align.
    83  segment_start_ = (sample_start / segment_duration_) * segment_duration_;
    84  }
    85 
    86  // We need to write all the segments that would have ended before the new
    87  // sample started.
    88  while (sample_start >= segment_start_ + segment_duration_) {
    89  // |DispatchSegment| will advance |segment_start_|.
    90  RETURN_IF_ERROR(DispatchSegment(segment_duration_));
    91  }
    92 
    93  samples_in_current_segment_.push_back(std::move(sample));
    94 
    95  return Status::OK;
    96 }
    97 
    98 Status TextChunker::DispatchSegment(int64_t duration) {
    99  DCHECK_GT(duration, 0) << "Segment duration should always be positive";
    100 
    101  // Output all the samples that are part of the segment.
    102  for (const auto& sample : samples_in_current_segment_) {
    103  RETURN_IF_ERROR(DispatchTextSample(kStreamIndex, sample));
    104  }
    105 
    106  // Output the segment info.
    107  std::shared_ptr<SegmentInfo> info = std::make_shared<SegmentInfo>();
    108  info->start_timestamp = segment_start_;
    109  info->duration = duration;
    110  RETURN_IF_ERROR(DispatchSegmentInfo(kStreamIndex, std::move(info)));
    111 
    112  // Move onto the next segment.
    113  const int64_t new_segment_start = segment_start_ + duration;
    114  segment_start_ = new_segment_start;
    115 
    116  // Remove all samples that end before the (new) current segment started.
    117  samples_in_current_segment_.remove_if(
    118  [new_segment_start](const std::shared_ptr<const TextSample>& sample) {
    119  // For the sample to even be in this list, it should have started
    120  // before the (new) current segment.
    121  DCHECK_LT(sample->start_time(), new_segment_start);
    122  return sample->EndTime() <= new_segment_start;
    123  });
    124 
    125  return Status::OK;
    126 }
    127 
    128 int64_t TextChunker::ScaleTime(double seconds) const {
    129  DCHECK_GT(time_scale_, 0) << "Need positive time scale to scale time.";
    130  return static_cast<int64_t>(seconds * time_scale_);
    131 }
    132 } // namespace media
    133 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/chunking/text_chunker.h"
    +
    8 
    +
    9 #include "packager/status_macros.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 namespace media {
    +
    13 namespace {
    +
    14 const size_t kStreamIndex = 0;
    +
    15 } // namespace
    +
    16 
    +
    17 TextChunker::TextChunker(double segment_duration_in_seconds)
    +
    18  : segment_duration_in_seconds_(segment_duration_in_seconds){};
    +
    19 
    +
    20 Status TextChunker::Process(std::unique_ptr<StreamData> data) {
    +
    21  switch (data->stream_data_type) {
    +
    22  case StreamDataType::kStreamInfo:
    +
    23  return OnStreamInfo(std::move(data->stream_info));
    +
    24  case StreamDataType::kTextSample:
    +
    25  return OnTextSample(data->text_sample);
    +
    26  case StreamDataType::kCueEvent:
    +
    27  return OnCueEvent(data->cue_event);
    +
    28  default:
    +
    29  return Status(error::INTERNAL_ERROR,
    +
    30  "Invalid stream data type for this handler");
    +
    31  }
    +
    32 }
    +
    33 
    +
    34 Status TextChunker::OnFlushRequest(size_t input_stream_index) {
    +
    35  // Keep outputting segments until all the samples leave the system. Calling
    +
    36  // |DispatchSegment| will remove samples over time.
    +
    37  while (samples_in_current_segment_.size()) {
    +
    38  RETURN_IF_ERROR(DispatchSegment(segment_duration_));
    +
    39  }
    +
    40 
    +
    41  return FlushAllDownstreams();
    +
    42 }
    +
    43 
    +
    44 Status TextChunker::OnStreamInfo(std::shared_ptr<const StreamInfo> info) {
    +
    45  time_scale_ = info->time_scale();
    +
    46  segment_duration_ = ScaleTime(segment_duration_in_seconds_);
    +
    47 
    +
    48  return DispatchStreamInfo(kStreamIndex, std::move(info));
    +
    49 }
    +
    50 
    +
    51 Status TextChunker::OnCueEvent(std::shared_ptr<const CueEvent> event) {
    +
    52  // We are going to end the current segment prematurely using the cue event's
    +
    53  // time as the new segment end.
    +
    54 
    +
    55  // Because the cue should have been inserted into the stream such that no
    +
    56  // later sample could start before it does, we know that there should
    +
    57  // be no later samples starting before the cue event.
    +
    58 
    +
    59  // Convert the event's time to be scaled to the time of each sample.
    +
    60  const int64_t event_time = ScaleTime(event->time_in_seconds);
    +
    61 
    +
    62  // Output all full segments before the segment that the cue event interupts.
    +
    63  while (segment_start_ + segment_duration_ < event_time) {
    +
    64  RETURN_IF_ERROR(DispatchSegment(segment_duration_));
    +
    65  }
    +
    66 
    +
    67  const int64_t shorten_duration = event_time - segment_start_;
    +
    68 
    +
    69  RETURN_IF_ERROR(DispatchSegment(shorten_duration));
    +
    70  return DispatchCueEvent(kStreamIndex, std::move(event));
    +
    71 }
    +
    72 
    +
    73 Status TextChunker::OnTextSample(std::shared_ptr<const TextSample> sample) {
    +
    74  // Output all segments that come before our new sample.
    +
    75  const int64_t sample_start = sample->start_time();
    +
    76 
    +
    77  // If we have not seen a sample yet, base all segments off the first sample's
    +
    78  // start time.
    +
    79  if (segment_start_ < 0) {
    +
    80  // Force the first segment to start at the segment that would have started
    +
    81  // before the sample. This should allow segments from different streams to
    +
    82  // align.
    +
    83  segment_start_ = (sample_start / segment_duration_) * segment_duration_;
    +
    84  }
    +
    85 
    +
    86  // We need to write all the segments that would have ended before the new
    +
    87  // sample started.
    +
    88  while (sample_start >= segment_start_ + segment_duration_) {
    +
    89  // |DispatchSegment| will advance |segment_start_|.
    +
    90  RETURN_IF_ERROR(DispatchSegment(segment_duration_));
    +
    91  }
    +
    92 
    +
    93  samples_in_current_segment_.push_back(std::move(sample));
    +
    94 
    +
    95  return Status::OK;
    +
    96 }
    +
    97 
    +
    98 Status TextChunker::DispatchSegment(int64_t duration) {
    +
    99  DCHECK_GT(duration, 0) << "Segment duration should always be positive";
    +
    100 
    +
    101  // Output all the samples that are part of the segment.
    +
    102  for (const auto& sample : samples_in_current_segment_) {
    +
    103  RETURN_IF_ERROR(DispatchTextSample(kStreamIndex, sample));
    +
    104  }
    +
    105 
    +
    106  // Output the segment info.
    +
    107  std::shared_ptr<SegmentInfo> info = std::make_shared<SegmentInfo>();
    +
    108  info->start_timestamp = segment_start_;
    +
    109  info->duration = duration;
    +
    110  RETURN_IF_ERROR(DispatchSegmentInfo(kStreamIndex, std::move(info)));
    +
    111 
    +
    112  // Move onto the next segment.
    +
    113  const int64_t new_segment_start = segment_start_ + duration;
    +
    114  segment_start_ = new_segment_start;
    +
    115 
    +
    116  // Remove all samples that end before the (new) current segment started.
    +
    117  samples_in_current_segment_.remove_if(
    +
    118  [new_segment_start](const std::shared_ptr<const TextSample>& sample) {
    +
    119  // For the sample to even be in this list, it should have started
    +
    120  // before the (new) current segment.
    +
    121  DCHECK_LT(sample->start_time(), new_segment_start);
    +
    122  return sample->EndTime() <= new_segment_start;
    +
    123  });
    +
    124 
    +
    125  return Status::OK;
    +
    126 }
    +
    127 
    +
    128 int64_t TextChunker::ScaleTime(double seconds) const {
    +
    129  DCHECK_GT(time_scale_, 0) << "Need positive time scale to scale time.";
    +
    130  return static_cast<int64_t>(seconds * time_scale_);
    +
    131 }
    +
    132 } // namespace media
    +
    133 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/dc7/classshaka_1_1media_1_1AV1Parser.html b/docs/db/dc7/classshaka_1_1media_1_1AV1Parser.html index 66401027da..f1b803eabf 100644 --- a/docs/db/dc7/classshaka_1_1media_1_1AV1Parser.html +++ b/docs/db/dc7/classshaka_1_1media_1_1AV1Parser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AV1Parser Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/dcb/classshaka_1_1media_1_1VPxParser.html b/docs/db/dcb/classshaka_1_1media_1_1VPxParser.html index d8d0d52331..a364af4792 100644 --- a/docs/db/dcb/classshaka_1_1media_1_1VPxParser.html +++ b/docs/db/dcb/classshaka_1_1media_1_1VPxParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::VPxParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::VP8Parser -shaka::media::VP9Parser - -
    +shaka::media::VP9Parser + + @@ -174,7 +177,7 @@ Protected Member Functions
    Returns
    true on success, false otherwise.
    -

    Implemented in shaka::media::VP8Parser, and shaka::media::VP9Parser.

    +

    Implemented in shaka::media::VP9Parser, and shaka::media::VP8Parser.

    @@ -184,9 +187,7 @@ Protected Member Functions diff --git a/docs/db/dcd/classshaka_1_1MpdWriter.html b/docs/db/dcd/classshaka_1_1MpdWriter.html index a8061ff3a8..b314485449 100644 --- a/docs/db/dcd/classshaka_1_1MpdWriter.html +++ b/docs/db/dcd/classshaka_1_1MpdWriter.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::MpdWriter Class Reference @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    MpdWriterTest diff --git a/docs/db/dcd/structshaka_1_1media_1_1mp4_1_1DTSSpecific-members.html b/docs/db/dcd/structshaka_1_1media_1_1mp4_1_1DTSSpecific-members.html index 7b62255c80..7d2b3afabe 100644 --- a/docs/db/dcd/structshaka_1_1media_1_1mp4_1_1DTSSpecific-members.html +++ b/docs/db/dcd/structshaka_1_1media_1_1mp4_1_1DTSSpecific-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/dd0/classshaka_1_1Packager.html b/docs/db/dd0/classshaka_1_1Packager.html index 7de1aa3158..3af099eaed 100644 --- a/docs/db/dd0/classshaka_1_1Packager.html +++ b/docs/db/dd0/classshaka_1_1Packager.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::Packager Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

    Detailed Description

    -

    Definition at line 133 of file packager.h.

    +

    Definition at line 145 of file packager.h.

    Member Function Documentation

    ◆ DefaultStreamLabelFunction()

    @@ -149,7 +152,7 @@ Static Public Member Functions
    Returns
    the stream label associated with stream_info. Can be "AUDIO", "SD", "HD", "UHD1" or "UHD2".
    -

    Definition at line 1033 of file packager.cc.

    +

    Definition at line 982 of file packager.cc.

    @@ -177,7 +180,7 @@ Static Public Member Functions
    Returns
    The version of the library.
    -

    Definition at line 1029 of file packager.cc.

    +

    Definition at line 978 of file packager.cc.

    @@ -215,7 +218,7 @@ Static Public Member Functions
    Returns
    OK on success, an appropriate error code on failure.
    -

    Definition at line 869 of file packager.cc.

    +

    Definition at line 811 of file packager.cc.

    @@ -235,7 +238,7 @@ Static Public Member Functions

    Run the pipeline to completion (or failed / been cancelled). Note that it blocks until completion.

    Returns
    OK on success, an appropriate error code on failure.
    -

    Definition at line 1004 of file packager.cc.

    +

    Definition at line 953 of file packager.cc.

    @@ -246,9 +249,7 @@ Static Public Member Functions diff --git a/docs/db/dd0/classshaka_1_1media_1_1RawKeySource.html b/docs/db/dd0/classshaka_1_1media_1_1RawKeySource.html index 5f57fea6d0..7aaaf82e61 100644 --- a/docs/db/dd0/classshaka_1_1media_1_1RawKeySource.html +++ b/docs/db/dd0/classshaka_1_1media_1_1RawKeySource.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::RawKeySource Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::media::KeySource - -
    +shaka::media::KeySource + + @@ -95,29 +98,19 @@ Public Member Functions - - -

    Public Member Functions

     
    Status GetCryptoPeriodKey (uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
     
    - Public Member Functions inherited from shaka::media::KeySource
    KeySource (int protection_systems_flags, FourCC protection_scheme)
     
    - - -

    Static Public Member Functions

    static std::unique_ptr< RawKeySourceCreate (const RawKeyParams &raw_key, int protection_system_flags, FourCC protection_scheme)
     
    - - - - + +

    -Additional Inherited Members

    - Protected Member Functions inherited from shaka::media::KeySource
    Status UpdateProtectionSystemInfo (EncryptionKeyMap *encryption_key_map)
     
    static std::unique_ptr< RawKeySourceCreate (const RawKeyParams &raw_key)
     

    Detailed Description

    A key source that uses raw keys for encryption.

    Definition at line 21 of file raw_key_source.h.

    Member Function Documentation

    - -

    ◆ Create()

    + +

    ◆ Create()

    @@ -129,24 +122,8 @@ Additional Inherited Members std::unique_ptr< RawKeySource > shaka::media::RawKeySource::Create ( const RawKeyParams &  - raw_key, - - - + raw_key) - int  - protection_system_flags, - - - - - FourCC  - protection_scheme  - - - - ) - @@ -155,16 +132,14 @@ Additional Inherited Members
    -

    Creates a new RawKeySource from the given data. Returns null if the parameter is malformed.

    Parameters
    +

    Creates a new RawKeySource from the given data. Returns null if the parameter is malformed.

    Parameters
    - -
    raw_keycontains parameters to setup the key source.
    protection_systems_flagsis the flags indicating which PSSH should be included.
    protection_schemeis the Protection Scheme to be used for encryption. It needs to be signalled in Widevine PSSH. This argument can be ignored if Widevine PSSH is not generated.
    -

    Definition at line 99 of file raw_key_source.cc.

    +

    Definition at line 85 of file raw_key_source.cc.

    @@ -381,9 +356,7 @@ Additional Inherited Members diff --git a/docs/db/dd0/classshaka_1_1media_1_1VodMediaInfoDumpMuxerListener.html b/docs/db/dd0/classshaka_1_1media_1_1VodMediaInfoDumpMuxerListener.html index bde0c726cf..e2decc9468 100644 --- a/docs/db/dd0/classshaka_1_1media_1_1VodMediaInfoDumpMuxerListener.html +++ b/docs/db/dd0/classshaka_1_1media_1_1VodMediaInfoDumpMuxerListener.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::VodMediaInfoDumpMuxerListener Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MuxerListener - -
    + + @@ -112,13 +115,13 @@ Static Public Member Functions Additional Inherited Members @@ -417,7 +420,7 @@ Additional Inherited Members

    Public Member Functions

    - Public Types inherited from shaka::media::MuxerListener
    enum  ContainerType {
    -  kContainerUnknown = 0, -kContainerMp4, -kContainerMpeg2ts, -kContainerWebM, -
    -  kContainerText, -kContainerPackedAudio +  kContainerUnknown = 0 +, kContainerMp4 +, kContainerMpeg2ts +, kContainerWebM +,
    +  kContainerText +, kContainerPackedAudio
    }
     
    -

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    +

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    @@ -583,9 +586,7 @@ Additional Inherited Members diff --git a/docs/db/dd0/ttml__generator_8h_source.html b/docs/db/dd0/ttml__generator_8h_source.html new file mode 100644 index 0000000000..c0f33f10aa --- /dev/null +++ b/docs/db/dd0/ttml__generator_8h_source.html @@ -0,0 +1,142 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/ttml/ttml_generator.h Source File + + + + + + + + + +
    +
    +
    muxer_optionsis the options for Muxer.
    stream_infois the information of this media.
    + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + + +
    +
    +
    ttml_generator.h
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_TTML_TTML_GENERATOR_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_TTML_TTML_GENERATOR_H_
    +
    9 
    +
    10 #include <list>
    +
    11 #include <map>
    +
    12 #include <string>
    +
    13 
    +
    14 #include "packager/media/base/text_sample.h"
    +
    15 #include "packager/media/base/text_stream_info.h"
    +
    16 #include "packager/mpd/base/xml/xml_node.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 namespace ttml {
    +
    21 
    + +
    23  public:
    +
    24  explicit TtmlGenerator();
    +
    25  ~TtmlGenerator();
    +
    26 
    +
    27  static const char* kTtNamespace;
    +
    28 
    +
    29  void Initialize(const std::map<std::string, TextRegion>& regions,
    +
    30  const std::string& language,
    +
    31  uint32_t time_scale);
    +
    32  void AddSample(const TextSample& sample);
    +
    33  void Reset();
    +
    34 
    +
    35  bool Dump(std::string* result) const;
    +
    36 
    +
    37  private:
    +
    38  bool AddSampleToXml(const TextSample& sample,
    +
    39  xml::XmlNode* body,
    +
    40  xml::XmlNode* metadata,
    +
    41  size_t* image_count) const;
    +
    42  bool ConvertFragmentToXml(const TextFragment& fragment,
    +
    43  xml::XmlNode* parent,
    +
    44  xml::XmlNode* metadata,
    +
    45  size_t* image_count) const;
    +
    46 
    +
    47  std::list<TextSample> samples_;
    +
    48  std::map<std::string, TextRegion> regions_;
    +
    49  std::string language_;
    +
    50  uint32_t time_scale_;
    +
    51  // This is modified in "const" methods to create unique IDs.
    +
    52  mutable uint32_t region_id_ = 0;
    +
    53 };
    +
    54 
    +
    55 } // namespace ttml
    +
    56 } // namespace media
    +
    57 } // namespace shaka
    +
    58 
    +
    59 #endif // PACKAGER_MEDIA_FORMATS_TTML_TTML_GENERATOR_H_
    + + + +
    All the methods that are virtual are virtual for mocking.
    + +
    + + + + diff --git a/docs/db/dd2/chunk__info__iterator_8h_source.html b/docs/db/dd2/chunk__info__iterator_8h_source.html index cfae33bf4e..c0b6cc3818 100644 --- a/docs/db/dd2/chunk__info__iterator_8h_source.html +++ b/docs/db/dd2/chunk__info__iterator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/chunk_info_iterator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    chunk_info_iterator.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_CHUNK_INFO_ITERATOR_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_CHUNK_INFO_ITERATOR_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <vector>
    13 
    14 #include "packager/base/macros.h"
    15 #include "packager/media/formats/mp4/box_definitions.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 namespace mp4 {
    20 
    25  public:
    27  explicit ChunkInfoIterator(const SampleToChunk& sample_to_chunk);
    29 
    32  bool AdvanceChunk();
    33 
    36  bool AdvanceSample();
    37 
    39  bool IsValid() const;
    40 
    42  uint32_t current_chunk() const { return current_chunk_; }
    43 
    45  uint32_t samples_per_chunk() const { return iterator_->samples_per_chunk; }
    46 
    48  uint32_t sample_description_index() const {
    49  return iterator_->sample_description_index;
    50  }
    51 
    54  uint32_t NumSamples(uint32_t start_chunk, uint32_t end_chunk) const;
    55 
    57  uint32_t LastFirstChunk() const {
    58  return chunk_info_table_.empty() ? 0
    59  : chunk_info_table_.back().first_chunk;
    60  }
    61 
    62  private:
    63  uint32_t chunk_sample_index_;
    64  uint32_t current_chunk_;
    65  const std::vector<ChunkInfo>& chunk_info_table_;
    66  std::vector<ChunkInfo>::const_iterator iterator_;
    67 
    68  DISALLOW_COPY_AND_ASSIGN(ChunkInfoIterator);
    69 };
    70 
    71 } // namespace mp4
    72 } // namespace media
    73 } // namespace shaka
    74 
    75 #endif // PACKAGER_MEDIA_FORMATS_MP4_CHUNK_INFO_ITERATOR_H_
    - - - - - -
    All the methods that are virtual are virtual for mocking.
    - - - -
    uint32_t NumSamples(uint32_t start_chunk, uint32_t end_chunk) const
    -
    ChunkInfoIterator(const SampleToChunk &sample_to_chunk)
    Create ChunkInfoIterator from sample to chunk box.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_CHUNK_INFO_ITERATOR_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_CHUNK_INFO_ITERATOR_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/macros.h"
    +
    15 #include "packager/media/formats/mp4/box_definitions.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 namespace mp4 {
    +
    20 
    + +
    25  public:
    +
    27  explicit ChunkInfoIterator(const SampleToChunk& sample_to_chunk);
    + +
    29 
    +
    32  bool AdvanceChunk();
    +
    33 
    +
    36  bool AdvanceSample();
    +
    37 
    +
    39  bool IsValid() const;
    +
    40 
    +
    42  uint32_t current_chunk() const { return current_chunk_; }
    +
    43 
    +
    45  uint32_t samples_per_chunk() const { return iterator_->samples_per_chunk; }
    +
    46 
    +
    48  uint32_t sample_description_index() const {
    +
    49  return iterator_->sample_description_index;
    +
    50  }
    +
    51 
    +
    54  uint32_t NumSamples(uint32_t start_chunk, uint32_t end_chunk) const;
    +
    55 
    +
    57  uint32_t LastFirstChunk() const {
    +
    58  return chunk_info_table_.empty() ? 0
    +
    59  : chunk_info_table_.back().first_chunk;
    +
    60  }
    +
    61 
    +
    62  private:
    +
    63  uint32_t chunk_sample_index_;
    +
    64  uint32_t current_chunk_;
    +
    65  const std::vector<ChunkInfo>& chunk_info_table_;
    +
    66  std::vector<ChunkInfo>::const_iterator iterator_;
    +
    67 
    +
    68  DISALLOW_COPY_AND_ASSIGN(ChunkInfoIterator);
    +
    69 };
    +
    70 
    +
    71 } // namespace mp4
    +
    72 } // namespace media
    +
    73 } // namespace shaka
    +
    74 
    +
    75 #endif // PACKAGER_MEDIA_FORMATS_MP4_CHUNK_INFO_ITERATOR_H_
    + + + + + + + +
    uint32_t NumSamples(uint32_t start_chunk, uint32_t end_chunk) const
    + +
    ChunkInfoIterator(const SampleToChunk &sample_to_chunk)
    Create ChunkInfoIterator from sample to chunk box.
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/db/dd9/sync__sample__iterator_8h_source.html b/docs/db/dd9/sync__sample__iterator_8h_source.html index 6b78863dd5..6ed1550a84 100644 --- a/docs/db/dd9/sync__sample__iterator_8h_source.html +++ b/docs/db/dd9/sync__sample__iterator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/sync_sample_iterator.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    sync_sample_iterator.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_SYNC_SAMPLE_ITERATOR_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_SYNC_SAMPLE_ITERATOR_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <vector>
    13 
    14 #include "packager/base/macros.h"
    15 #include "packager/media/formats/mp4/box_definitions.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 namespace mp4 {
    20 
    24  public:
    26  explicit SyncSampleIterator(const SyncSample& sync_sample);
    28 
    31  bool AdvanceSample();
    32 
    34  bool IsSyncSample() const;
    35 
    37  bool IsSyncSample(uint32_t sample) const;
    38 
    39  private:
    40  uint32_t sample_number_;
    41  const std::vector<uint32_t>& sync_sample_vector_;
    42  std::vector<uint32_t>::const_iterator iterator_;
    43  bool is_empty_;
    44 
    45  DISALLOW_COPY_AND_ASSIGN(SyncSampleIterator);
    46 };
    47 
    48 } // namespace mp4
    49 } // namespace media
    50 } // namespace shaka
    51 
    52 #endif // PACKAGER_MEDIA_FORMATS_MP4_SYNC_SAMPLE_ITERATOR_H_
    -
    SyncSampleIterator(const SyncSample &sync_sample)
    Create a new SyncSampleIterator from sync sample box.
    - -
    All the methods that are virtual are virtual for mocking.
    - - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_SYNC_SAMPLE_ITERATOR_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_SYNC_SAMPLE_ITERATOR_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/macros.h"
    +
    15 #include "packager/media/formats/mp4/box_definitions.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 namespace mp4 {
    +
    20 
    + +
    24  public:
    +
    26  explicit SyncSampleIterator(const SyncSample& sync_sample);
    + +
    28 
    +
    31  bool AdvanceSample();
    +
    32 
    +
    34  bool IsSyncSample() const;
    +
    35 
    +
    37  bool IsSyncSample(uint32_t sample) const;
    +
    38 
    +
    39  private:
    +
    40  uint32_t sample_number_;
    +
    41  const std::vector<uint32_t>& sync_sample_vector_;
    +
    42  std::vector<uint32_t>::const_iterator iterator_;
    +
    43  bool is_empty_;
    +
    44 
    +
    45  DISALLOW_COPY_AND_ASSIGN(SyncSampleIterator);
    +
    46 };
    +
    47 
    +
    48 } // namespace mp4
    +
    49 } // namespace media
    +
    50 } // namespace shaka
    +
    51 
    +
    52 #endif // PACKAGER_MEDIA_FORMATS_MP4_SYNC_SAMPLE_ITERATOR_H_
    + + + +
    SyncSampleIterator(const SyncSample &sync_sample)
    Create a new SyncSampleIterator from sync sample box.
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/db/dde/h265__parser_8cc_source.html b/docs/db/dde/h265__parser_8cc_source.html index afe0fffacf..debfee36ed 100644 --- a/docs/db/dde/h265__parser_8cc_source.html +++ b/docs/db/dde/h265__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h265_parser.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    h265_parser.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/h265_parser.h"
    8 
    9 #include <math.h>
    10 #include <algorithm>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/media/base/macros.h"
    14 #include "packager/media/codecs/nalu_reader.h"
    15 
    16 #define TRUE_OR_RETURN(a) \
    17  do { \
    18  if (!(a)) { \
    19  DVLOG(1) << "Failure while processing " << #a; \
    20  return kInvalidStream; \
    21  } \
    22  } while (0)
    23 
    24 #define OK_OR_RETURN(a) \
    25  do { \
    26  Result status = (a); \
    27  if (status != kOk) \
    28  return status; \
    29  } while (false)
    30 
    31 namespace shaka {
    32 namespace media {
    33 
    34 namespace {
    35 int GetNumPicTotalCurr(const H265SliceHeader& slice_header,
    36  const H265Sps& sps) {
    37  int num_pic_total_curr = 0;
    38  const H265ReferencePictureSet& ref_pic_set =
    39  slice_header.short_term_ref_pic_set_sps_flag
    40  ? sps.st_ref_pic_sets[slice_header.short_term_ref_pic_set_idx]
    41  : slice_header.st_ref_pic_set;
    42 
    43  for (int i = 0; i < ref_pic_set.num_negative_pics; i++) {
    44  if (ref_pic_set.used_by_curr_pic_s0[i])
    45  num_pic_total_curr++;
    46  }
    47  for (int i = 0; i < ref_pic_set.num_positive_pics; i++) {
    48  if (ref_pic_set.used_by_curr_pic_s1[i])
    49  num_pic_total_curr++;
    50  }
    51 
    52  return num_pic_total_curr + slice_header.used_by_curr_pic_lt;
    53 }
    54 
    55 void GetAspectRatioInfo(const H265Sps& sps,
    56  uint32_t* pixel_width,
    57  uint32_t* pixel_height) {
    58  // The default value is 0; so if this is not in the SPS, it will correctly
    59  // assume unspecified.
    60  int aspect_ratio_idc = sps.vui_parameters.aspect_ratio_idc;
    61 
    62  // Table E.1
    63  switch (aspect_ratio_idc) {
    64  case 1: *pixel_width = 1; *pixel_height = 1; break;
    65  case 2: *pixel_width = 12; *pixel_height = 11; break;
    66  case 3: *pixel_width = 10; *pixel_height = 11; break;
    67  case 4: *pixel_width = 16; *pixel_height = 11; break;
    68  case 5: *pixel_width = 40; *pixel_height = 33; break;
    69  case 6: *pixel_width = 24; *pixel_height = 11; break;
    70  case 7: *pixel_width = 20; *pixel_height = 11; break;
    71  case 8: *pixel_width = 32; *pixel_height = 11; break;
    72  case 9: *pixel_width = 80; *pixel_height = 33; break;
    73  case 10: *pixel_width = 18; *pixel_height = 11; break;
    74  case 11: *pixel_width = 15; *pixel_height = 11; break;
    75  case 12: *pixel_width = 64; *pixel_height = 33; break;
    76  case 13: *pixel_width = 160; *pixel_height = 99; break;
    77  case 14: *pixel_width = 4; *pixel_height = 3; break;
    78  case 15: *pixel_width = 3; *pixel_height = 2; break;
    79  case 16: *pixel_width = 2; *pixel_height = 1; break;
    80 
    81  case 255:
    82  *pixel_width = sps.vui_parameters.sar_width;
    83  *pixel_height = sps.vui_parameters.sar_height;
    84  break;
    85 
    86  default:
    87  // Section E.3.1 specifies that other values should be interpreted as 0.
    88  LOG(WARNING) << "Unknown aspect_ratio_idc " << aspect_ratio_idc;
    89  FALLTHROUGH_INTENDED;
    90  case 0:
    91  // Unlike the spec, assume 1:1 if not specified.
    92  *pixel_width = 1;
    93  *pixel_height = 1;
    94  break;
    95  }
    96 }
    97 } // namespace
    98 
    99 bool ExtractResolutionFromSps(const H265Sps& sps,
    100  uint32_t* coded_width,
    101  uint32_t* coded_height,
    102  uint32_t* pixel_width,
    103  uint32_t* pixel_height) {
    104  int crop_x = 0;
    105  int crop_y = 0;
    106  if (sps.conformance_window_flag) {
    107  int sub_width_c = 0;
    108  int sub_height_c = 0;
    109 
    110  // Table 6-1
    111  switch (sps.chroma_format_idc) {
    112  case 0: // Monochrome
    113  sub_width_c = 1;
    114  sub_height_c = 1;
    115  break;
    116  case 1: // 4:2:0
    117  sub_width_c = 2;
    118  sub_height_c = 2;
    119  break;
    120  case 2: // 4:2:2
    121  sub_width_c = 2;
    122  sub_height_c = 1;
    123  break;
    124  case 3: // 4:4:4
    125  sub_width_c = 1;
    126  sub_height_c = 1;
    127  break;
    128  default:
    129  LOG(ERROR) << "Unexpected chroma_format_idc " << sps.chroma_format_idc;
    130  return false;
    131  }
    132 
    133  // Formula D-28, D-29
    134  crop_x =
    135  sub_width_c * (sps.conf_win_right_offset + sps.conf_win_left_offset);
    136  crop_y =
    137  sub_height_c * (sps.conf_win_bottom_offset + sps.conf_win_top_offset);
    138  }
    139 
    140  // Formula D-28, D-29
    141  *coded_width = sps.pic_width_in_luma_samples - crop_x;
    142  *coded_height = sps.pic_height_in_luma_samples - crop_y;
    143  GetAspectRatioInfo(sps, pixel_width, pixel_height);
    144  return true;
    145 }
    146 
    147 H265Pps::H265Pps() {}
    148 H265Pps::~H265Pps() {}
    149 
    150 H265Sps::H265Sps() {}
    151 H265Sps::~H265Sps() {}
    152 
    153 int H265Sps::GetPicSizeInCtbsY() const {
    154  int min_cb_log2_size_y = log2_min_luma_coding_block_size_minus3 + 3;
    155  int ctb_log2_size_y =
    156  min_cb_log2_size_y + log2_diff_max_min_luma_coding_block_size;
    157  int ctb_size_y = 1 << ctb_log2_size_y;
    158 
    159  // Round-up division.
    160  int pic_width_in_ctbs_y = (pic_width_in_luma_samples - 1) / ctb_size_y + 1;
    161  int pic_height_in_ctbs_y = (pic_height_in_luma_samples - 1) / ctb_size_y + 1;
    162  return pic_width_in_ctbs_y * pic_height_in_ctbs_y;
    163 }
    164 
    165 int H265Sps::GetChromaArrayType() const {
    166  if (!separate_colour_plane_flag)
    167  return chroma_format_idc;
    168  else
    169  return 0;
    170 }
    171 
    172 H265ReferencePictureListModifications::H265ReferencePictureListModifications() {
    173 }
    174 H265ReferencePictureListModifications::
    175  ~H265ReferencePictureListModifications() {}
    176 
    177 H265SliceHeader::H265SliceHeader() {}
    178 H265SliceHeader::~H265SliceHeader() {}
    179 
    180 H265Parser::H265Parser() {}
    181 H265Parser::~H265Parser() {}
    182 
    183 H265Parser::Result H265Parser::ParseSliceHeader(const Nalu& nalu,
    184  H265SliceHeader* slice_header) {
    185  DCHECK(nalu.is_video_slice());
    186  *slice_header = H265SliceHeader();
    187 
    188  // Parses whole element.
    189  H26xBitReader reader;
    190  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    191  H26xBitReader* br = &reader;
    192 
    193  TRUE_OR_RETURN(br->ReadBool(&slice_header->first_slice_segment_in_pic_flag));
    194  if (nalu.type() >= Nalu::H265_BLA_W_LP &&
    195  nalu.type() <= Nalu::H265_RSV_IRAP_VCL23) {
    196  TRUE_OR_RETURN(br->ReadBool(&slice_header->no_output_of_prior_pics_flag));
    197  }
    198 
    199  TRUE_OR_RETURN(br->ReadUE(&slice_header->pic_parameter_set_id));
    200  const H265Pps* pps = GetPps(slice_header->pic_parameter_set_id);
    201  TRUE_OR_RETURN(pps);
    202 
    203  const H265Sps* sps = GetSps(pps->seq_parameter_set_id);
    204  TRUE_OR_RETURN(sps);
    205 
    206  if (!slice_header->first_slice_segment_in_pic_flag) {
    207  if (pps->dependent_slice_segments_enabled_flag) {
    208  TRUE_OR_RETURN(br->ReadBool(&slice_header->dependent_slice_segment_flag));
    209  }
    210  const int bit_length = ceil(log2(sps->GetPicSizeInCtbsY()));
    211  TRUE_OR_RETURN(br->ReadBits(bit_length, &slice_header->segment_address));
    212  }
    213 
    214  if (!slice_header->dependent_slice_segment_flag) {
    215  TRUE_OR_RETURN(br->SkipBits(pps->num_extra_slice_header_bits));
    216  TRUE_OR_RETURN(br->ReadUE(&slice_header->slice_type));
    217  if (pps->output_flag_present_flag) {
    218  TRUE_OR_RETURN(br->ReadBool(&slice_header->pic_output_flag));
    219  }
    220  if (sps->separate_colour_plane_flag) {
    221  TRUE_OR_RETURN(br->ReadBits(2, &slice_header->colour_plane_id));
    222  }
    223 
    224  if (nalu.type() != Nalu::H265_IDR_W_RADL &&
    225  nalu.type() != Nalu::H265_IDR_N_LP) {
    226  TRUE_OR_RETURN(br->ReadBits(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
    227  &slice_header->slice_pic_order_cnt_lsb));
    228 
    229  TRUE_OR_RETURN(
    230  br->ReadBool(&slice_header->short_term_ref_pic_set_sps_flag));
    231  if (!slice_header->short_term_ref_pic_set_sps_flag) {
    232  OK_OR_RETURN(ParseReferencePictureSet(
    233  sps->num_short_term_ref_pic_sets, sps->num_short_term_ref_pic_sets,
    234  sps->st_ref_pic_sets, br, &slice_header->st_ref_pic_set));
    235  } else if (sps->num_short_term_ref_pic_sets > 1) {
    236  TRUE_OR_RETURN(
    237  br->ReadBits(ceil(log2(sps->num_short_term_ref_pic_sets)),
    238  &slice_header->short_term_ref_pic_set_idx));
    239  TRUE_OR_RETURN(slice_header->short_term_ref_pic_set_idx <
    240  sps->num_short_term_ref_pic_sets);
    241  }
    242 
    243  if (sps->long_term_ref_pic_present_flag) {
    244  if (sps->num_long_term_ref_pics > 0) {
    245  TRUE_OR_RETURN(br->ReadUE(&slice_header->num_long_term_sps));
    246  }
    247  TRUE_OR_RETURN(br->ReadUE(&slice_header->num_long_term_pics));
    248 
    249  const int pic_count =
    250  slice_header->num_long_term_sps + slice_header->num_long_term_pics;
    251  slice_header->long_term_pics_info.resize(pic_count);
    252  for (int i = 0; i < pic_count; i++) {
    253  if (i < slice_header->num_long_term_sps) {
    254  int lt_idx_sps = 0;
    255  if (sps->num_long_term_ref_pics > 1) {
    256  TRUE_OR_RETURN(br->ReadBits(
    257  ceil(log2(sps->num_long_term_ref_pics)), &lt_idx_sps));
    258  }
    259  if (sps->used_by_curr_pic_lt_flag[lt_idx_sps])
    260  slice_header->used_by_curr_pic_lt++;
    261  } else {
    262  TRUE_OR_RETURN(br->SkipBits(sps->log2_max_pic_order_cnt_lsb_minus4 +
    263  4)); // poc_lsb_lt
    264  bool used_by_curr_pic_lt_flag;
    265  TRUE_OR_RETURN(br->ReadBool(&used_by_curr_pic_lt_flag));
    266  if (used_by_curr_pic_lt_flag)
    267  slice_header->used_by_curr_pic_lt++;
    268  }
    269  TRUE_OR_RETURN(br->ReadBool(&slice_header->long_term_pics_info[i]
    270  .delta_poc_msb_present_flag));
    271  if (slice_header->long_term_pics_info[i].delta_poc_msb_present_flag) {
    272  TRUE_OR_RETURN(br->ReadUE(
    273  &slice_header->long_term_pics_info[i].delta_poc_msb_cycle_lt));
    274  }
    275  }
    276  }
    277 
    278  if (sps->temporal_mvp_enabled_flag) {
    279  TRUE_OR_RETURN(
    280  br->ReadBool(&slice_header->slice_temporal_mvp_enabled_flag));
    281  }
    282  }
    283 
    284  if (nalu.nuh_layer_id() != 0) {
    285  NOTIMPLEMENTED() << "Multi-layer streams are not supported.";
    286  return kUnsupportedStream;
    287  }
    288 
    289  if (sps->sample_adaptive_offset_enabled_flag) {
    290  TRUE_OR_RETURN(br->ReadBool(&slice_header->slice_sao_luma_flag));
    291  if (sps->GetChromaArrayType() != 0) {
    292  TRUE_OR_RETURN(br->ReadBool(&slice_header->slice_sao_chroma_flag));
    293  }
    294  }
    295 
    296  slice_header->num_ref_idx_l0_active_minus1 =
    297  pps->num_ref_idx_l0_default_active_minus1;
    298  slice_header->num_ref_idx_l1_active_minus1 =
    299  pps->num_ref_idx_l1_default_active_minus1;
    300  if (slice_header->slice_type == kPSlice ||
    301  slice_header->slice_type == kBSlice) {
    302  TRUE_OR_RETURN(
    303  br->ReadBool(&slice_header->num_ref_idx_active_override_flag));
    304  if (slice_header->num_ref_idx_active_override_flag) {
    305  TRUE_OR_RETURN(br->ReadUE(&slice_header->num_ref_idx_l0_active_minus1));
    306  if (slice_header->slice_type == kBSlice) {
    307  TRUE_OR_RETURN(
    308  br->ReadUE(&slice_header->num_ref_idx_l1_active_minus1));
    309  }
    310  }
    311 
    312  const int num_pic_total_curr = GetNumPicTotalCurr(*slice_header, *sps);
    313  if (pps->lists_modification_present_flag && num_pic_total_curr > 1) {
    314  OK_OR_RETURN(SkipReferencePictureListModification(
    315  *slice_header, *pps, num_pic_total_curr, br));
    316  }
    317 
    318  if (slice_header->slice_type == kBSlice) {
    319  TRUE_OR_RETURN(br->ReadBool(&slice_header->mvd_l1_zero_flag));
    320  }
    321  if (pps->cabac_init_present_flag) {
    322  TRUE_OR_RETURN(br->ReadBool(&slice_header->cabac_init_flag));
    323  }
    324  if (slice_header->slice_temporal_mvp_enabled_flag) {
    325  if (slice_header->slice_type == kBSlice) {
    326  TRUE_OR_RETURN(br->ReadBool(&slice_header->collocated_from_l0));
    327  }
    328  bool l0_greater_than_0 = slice_header->num_ref_idx_l0_active_minus1 > 0;
    329  bool l1_greater_than_0 = slice_header->num_ref_idx_l1_active_minus1 > 0;
    330  if (slice_header->collocated_from_l0 ? l0_greater_than_0
    331  : l1_greater_than_0) {
    332  TRUE_OR_RETURN(br->ReadUE(&slice_header->collocated_ref_idx));
    333  }
    334  }
    335 
    336  if ((pps->weighted_pred_flag && slice_header->slice_type == kPSlice) ||
    337  (pps->weighted_bipred_flag && slice_header->slice_type == kBSlice)) {
    338  OK_OR_RETURN(SkipPredictionWeightTable(
    339  slice_header->slice_type == kBSlice, *sps, *slice_header, br));
    340  }
    341  TRUE_OR_RETURN(br->ReadUE(&slice_header->five_minus_max_num_merge_cand));
    342  }
    343 
    344  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_qp_delta));
    345  if (pps->slice_chroma_qp_offsets_present_flag) {
    346  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_cb_qp_offset));
    347  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_cr_qp_offset));
    348  }
    349 
    350  if (pps->chroma_qp_offset_list_enabled_flag) {
    351  TRUE_OR_RETURN(
    352  br->ReadBool(&slice_header->cu_chroma_qp_offset_enabled_flag));
    353  }
    354  if (pps->deblocking_filter_override_enabled_flag) {
    355  TRUE_OR_RETURN(
    356  br->ReadBool(&slice_header->deblocking_filter_override_flag));
    357  }
    358  if (slice_header->deblocking_filter_override_flag) {
    359  TRUE_OR_RETURN(
    360  br->ReadBool(&slice_header->slice_deblocking_filter_disabled_flag));
    361  if (!slice_header->slice_deblocking_filter_disabled_flag) {
    362  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_beta_offset_div2));
    363  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_tc_offset_div2));
    364  }
    365  }
    366  if (pps->loop_filter_across_slices_enabled_flag &&
    367  (slice_header->slice_sao_luma_flag ||
    368  slice_header->slice_sao_chroma_flag ||
    369  !slice_header->slice_deblocking_filter_disabled_flag)) {
    370  TRUE_OR_RETURN(br->ReadBool(
    371  &slice_header->slice_loop_filter_across_slices_enabled_flag));
    372  }
    373  }
    374 
    375  if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
    376  TRUE_OR_RETURN(br->ReadUE(&slice_header->num_entry_point_offsets));
    377  if (slice_header->num_entry_point_offsets > 0) {
    378  TRUE_OR_RETURN(br->ReadUE(&slice_header->offset_len_minus1));
    379  slice_header->entry_point_offset_minus1.resize(
    380  slice_header->num_entry_point_offsets);
    381  for (int i = 0; i < slice_header->num_entry_point_offsets; i++) {
    382  TRUE_OR_RETURN(
    383  br->ReadBits(slice_header->offset_len_minus1 + 1,
    384  &slice_header->entry_point_offset_minus1[i]));
    385  }
    386  }
    387  }
    388 
    389  if (pps->slice_segment_header_extension_present_flag) {
    390  int extension_length;
    391  TRUE_OR_RETURN(br->ReadUE(&extension_length));
    392  TRUE_OR_RETURN(br->SkipBits(extension_length * 8));
    393  }
    394 
    395  OK_OR_RETURN(ByteAlignment(br));
    396 
    397  slice_header->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
    398  return kOk;
    399 }
    400 
    401 H265Parser::Result H265Parser::ParsePps(const Nalu& nalu, int* pps_id) {
    402  DCHECK_EQ(Nalu::H265_PPS, nalu.type());
    403 
    404  // Reads most of the element, not reading the extension data.
    405  H26xBitReader reader;
    406  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    407  H26xBitReader* br = &reader;
    408 
    409  *pps_id = -1;
    410  std::unique_ptr<H265Pps> pps(new H265Pps);
    411 
    412  TRUE_OR_RETURN(br->ReadUE(&pps->pic_parameter_set_id));
    413  TRUE_OR_RETURN(br->ReadUE(&pps->seq_parameter_set_id));
    414 
    415  TRUE_OR_RETURN(br->ReadBool(&pps->dependent_slice_segments_enabled_flag));
    416  TRUE_OR_RETURN(br->ReadBool(&pps->output_flag_present_flag));
    417  TRUE_OR_RETURN(br->ReadBits(3, &pps->num_extra_slice_header_bits));
    418  TRUE_OR_RETURN(br->ReadBool(&pps->sign_data_hiding_enabled_flag));
    419  TRUE_OR_RETURN(br->ReadBool(&pps->cabac_init_present_flag));
    420 
    421  TRUE_OR_RETURN(br->ReadUE(&pps->num_ref_idx_l0_default_active_minus1));
    422  TRUE_OR_RETURN(br->ReadUE(&pps->num_ref_idx_l1_default_active_minus1));
    423  TRUE_OR_RETURN(br->ReadSE(&pps->init_qp_minus26));
    424  TRUE_OR_RETURN(br->ReadBool(&pps->constrained_intra_pred_flag));
    425  TRUE_OR_RETURN(br->ReadBool(&pps->transform_skip_enabled_flag));
    426 
    427  TRUE_OR_RETURN(br->ReadBool(&pps->cu_qp_delta_enabled_flag));
    428  if (pps->cu_qp_delta_enabled_flag)
    429  TRUE_OR_RETURN(br->ReadUE(&pps->diff_cu_qp_delta_depth));
    430  TRUE_OR_RETURN(br->ReadSE(&pps->cb_qp_offset));
    431  TRUE_OR_RETURN(br->ReadSE(&pps->cr_qp_offset));
    432 
    433  TRUE_OR_RETURN(br->ReadBool(&pps->slice_chroma_qp_offsets_present_flag));
    434  TRUE_OR_RETURN(br->ReadBool(&pps->weighted_pred_flag));
    435  TRUE_OR_RETURN(br->ReadBool(&pps->weighted_bipred_flag));
    436  TRUE_OR_RETURN(br->ReadBool(&pps->transquant_bypass_enabled_flag));
    437  TRUE_OR_RETURN(br->ReadBool(&pps->tiles_enabled_flag));
    438  TRUE_OR_RETURN(br->ReadBool(&pps->entropy_coding_sync_enabled_flag));
    439 
    440  if (pps->tiles_enabled_flag) {
    441  TRUE_OR_RETURN(br->ReadUE(&pps->num_tile_columns_minus1));
    442  TRUE_OR_RETURN(br->ReadUE(&pps->num_tile_rows_minus1));
    443  TRUE_OR_RETURN(br->ReadBool(&pps->uniform_spacing_flag));
    444  if (!pps->uniform_spacing_flag) {
    445  pps->column_width_minus1.resize(pps->num_tile_columns_minus1);
    446  for (int i = 0; i < pps->num_tile_columns_minus1; i++) {
    447  TRUE_OR_RETURN(br->ReadUE(&pps->column_width_minus1[i]));
    448  }
    449  pps->row_height_minus1.resize(pps->num_tile_rows_minus1);
    450  for (int i = 0; i < pps->num_tile_rows_minus1; i++) {
    451  TRUE_OR_RETURN(br->ReadUE(&pps->row_height_minus1[i]));
    452  }
    453  }
    454  TRUE_OR_RETURN(br->ReadBool(&pps->loop_filter_across_tiles_enabled_flag));
    455  }
    456 
    457  TRUE_OR_RETURN(br->ReadBool(&pps->loop_filter_across_slices_enabled_flag));
    458  TRUE_OR_RETURN(br->ReadBool(&pps->deblocking_filter_control_present_flag));
    459  if (pps->deblocking_filter_control_present_flag) {
    460  TRUE_OR_RETURN(br->ReadBool(&pps->deblocking_filter_override_enabled_flag));
    461  TRUE_OR_RETURN(br->ReadBool(&pps->deblocking_filter_disabled_flag));
    462  if (!pps->deblocking_filter_disabled_flag) {
    463  TRUE_OR_RETURN(br->ReadSE(&pps->beta_offset_div2));
    464  TRUE_OR_RETURN(br->ReadSE(&pps->tc_offset_div2));
    465  }
    466  }
    467 
    468  TRUE_OR_RETURN(br->ReadBool(&pps->scaling_list_data_present_flag));
    469  if (pps->scaling_list_data_present_flag) {
    470  OK_OR_RETURN(SkipScalingListData(br));
    471  }
    472 
    473  TRUE_OR_RETURN(br->ReadBool(&pps->lists_modification_present_flag));
    474  TRUE_OR_RETURN(br->ReadUE(&pps->log2_parallel_merge_level_minus2));
    475 
    476  TRUE_OR_RETURN(
    477  br->ReadBool(&pps->slice_segment_header_extension_present_flag));
    478 
    479  bool pps_extension_present_flag;
    480  bool pps_range_extension_flag = false;
    481  TRUE_OR_RETURN(br->ReadBool(&pps_extension_present_flag));
    482  if (pps_extension_present_flag) {
    483  TRUE_OR_RETURN(br->ReadBool(&pps_range_extension_flag));
    484  // pps_multilayer_extension_flag, pps_3d_extension_flag, pps_extension_5bits
    485  TRUE_OR_RETURN(br->SkipBits(1 + 1 + 5));
    486  }
    487 
    488  if (pps_range_extension_flag) {
    489  if (pps->transform_skip_enabled_flag) {
    490  // log2_max_transform_skip_block_size_minus2
    491  int ignored;
    492  TRUE_OR_RETURN(br->ReadUE(&ignored));
    493  }
    494 
    495  TRUE_OR_RETURN(br->SkipBits(1)); // cross_component_prediction_enabled_flag
    496  TRUE_OR_RETURN(br->ReadBool(&pps->chroma_qp_offset_list_enabled_flag));
    497  // Incomplete
    498  }
    499 
    500  // Ignore remaining extension data.
    501 
    502  // This will replace any existing PPS instance.
    503  *pps_id = pps->pic_parameter_set_id;
    504  active_ppses_[*pps_id] = std::move(pps);
    505 
    506  return kOk;
    507 }
    508 
    509 H265Parser::Result H265Parser::ParseSps(const Nalu& nalu, int* sps_id) {
    510  DCHECK_EQ(Nalu::H265_SPS, nalu.type());
    511 
    512  // Reads most of the element, not reading the extension data.
    513  H26xBitReader reader;
    514  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    515  H26xBitReader* br = &reader;
    516 
    517  *sps_id = -1;
    518 
    519  std::unique_ptr<H265Sps> sps(new H265Sps);
    520 
    521  TRUE_OR_RETURN(br->ReadBits(4, &sps->video_parameter_set_id));
    522  TRUE_OR_RETURN(br->ReadBits(3, &sps->max_sub_layers_minus1));
    523  TRUE_OR_RETURN(br->ReadBool(&sps->temporal_id_nesting_flag));
    524 
    525  OK_OR_RETURN(
    526  ReadProfileTierLevel(true, sps->max_sub_layers_minus1, br, sps.get()));
    527 
    528  TRUE_OR_RETURN(br->ReadUE(&sps->seq_parameter_set_id));
    529  TRUE_OR_RETURN(br->ReadUE(&sps->chroma_format_idc));
    530  if (sps->chroma_format_idc == 3) {
    531  TRUE_OR_RETURN(br->ReadBool(&sps->separate_colour_plane_flag));
    532  }
    533  TRUE_OR_RETURN(br->ReadUE(&sps->pic_width_in_luma_samples));
    534  TRUE_OR_RETURN(br->ReadUE(&sps->pic_height_in_luma_samples));
    535 
    536  TRUE_OR_RETURN(br->ReadBool(&sps->conformance_window_flag));
    537  if (sps->conformance_window_flag) {
    538  TRUE_OR_RETURN(br->ReadUE(&sps->conf_win_left_offset));
    539  TRUE_OR_RETURN(br->ReadUE(&sps->conf_win_right_offset));
    540  TRUE_OR_RETURN(br->ReadUE(&sps->conf_win_top_offset));
    541  TRUE_OR_RETURN(br->ReadUE(&sps->conf_win_bottom_offset));
    542  }
    543 
    544  TRUE_OR_RETURN(br->ReadUE(&sps->bit_depth_luma_minus8));
    545  TRUE_OR_RETURN(br->ReadUE(&sps->bit_depth_chroma_minus8));
    546  TRUE_OR_RETURN(br->ReadUE(&sps->log2_max_pic_order_cnt_lsb_minus4));
    547 
    548  TRUE_OR_RETURN(br->ReadBool(&sps->sub_layer_ordering_info_present_flag));
    549  int start = sps->sub_layer_ordering_info_present_flag
    550  ? 0
    551  : sps->max_sub_layers_minus1;
    552  for (int i = start; i <= sps->max_sub_layers_minus1; i++) {
    553  TRUE_OR_RETURN(br->ReadUE(&sps->max_dec_pic_buffering_minus1[i]));
    554  TRUE_OR_RETURN(br->ReadUE(&sps->max_num_reorder_pics[i]));
    555  TRUE_OR_RETURN(br->ReadUE(&sps->max_latency_increase_plus1[i]));
    556  }
    557 
    558  TRUE_OR_RETURN(br->ReadUE(&sps->log2_min_luma_coding_block_size_minus3));
    559  TRUE_OR_RETURN(br->ReadUE(&sps->log2_diff_max_min_luma_coding_block_size));
    560  TRUE_OR_RETURN(br->ReadUE(&sps->log2_min_luma_transform_block_size_minus2));
    561  TRUE_OR_RETURN(br->ReadUE(&sps->log2_diff_max_min_luma_transform_block_size));
    562  TRUE_OR_RETURN(br->ReadUE(&sps->max_transform_hierarchy_depth_inter));
    563  TRUE_OR_RETURN(br->ReadUE(&sps->max_transform_hierarchy_depth_intra));
    564 
    565  TRUE_OR_RETURN(br->ReadBool(&sps->scaling_list_enabled_flag));
    566  if (sps->scaling_list_enabled_flag) {
    567  TRUE_OR_RETURN(br->ReadBool(&sps->scaling_list_data_present_flag));
    568  if (sps->scaling_list_data_present_flag) {
    569  OK_OR_RETURN(SkipScalingListData(br));
    570  }
    571  }
    572 
    573  TRUE_OR_RETURN(br->ReadBool(&sps->amp_enabled_flag));
    574  TRUE_OR_RETURN(br->ReadBool(&sps->sample_adaptive_offset_enabled_flag));
    575  TRUE_OR_RETURN(br->ReadBool(&sps->pcm_enabled_flag));
    576  if (sps->pcm_enabled_flag) {
    577  TRUE_OR_RETURN(br->ReadBits(4, &sps->pcm_sample_bit_depth_luma_minus1));
    578  TRUE_OR_RETURN(br->ReadBits(4, &sps->pcm_sample_bit_depth_chroma_minus1));
    579  TRUE_OR_RETURN(
    580  br->ReadUE(&sps->log2_min_pcm_luma_coding_block_size_minus3));
    581  TRUE_OR_RETURN(
    582  br->ReadUE(&sps->log2_diff_max_min_pcm_luma_coding_block_size));
    583  TRUE_OR_RETURN(br->ReadBool(&sps->pcm_loop_filter_disabled_flag));
    584  }
    585 
    586  TRUE_OR_RETURN(br->ReadUE(&sps->num_short_term_ref_pic_sets));
    587  sps->st_ref_pic_sets.resize(sps->num_short_term_ref_pic_sets);
    588  for (int i = 0; i < sps->num_short_term_ref_pic_sets; i++) {
    589  OK_OR_RETURN(ParseReferencePictureSet(sps->num_short_term_ref_pic_sets, i,
    590  sps->st_ref_pic_sets, br,
    591  &sps->st_ref_pic_sets[i]));
    592  }
    593 
    594  TRUE_OR_RETURN(br->ReadBool(&sps->long_term_ref_pic_present_flag));
    595  if (sps->long_term_ref_pic_present_flag) {
    596  TRUE_OR_RETURN(br->ReadUE(&sps->num_long_term_ref_pics));
    597  sps->lt_ref_pic_poc_lsb.resize(sps->num_long_term_ref_pics);
    598  sps->used_by_curr_pic_lt_flag.resize(sps->num_long_term_ref_pics);
    599  for (int i = 0; i < sps->num_long_term_ref_pics; i++) {
    600  TRUE_OR_RETURN(br->ReadBits(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
    601  &sps->lt_ref_pic_poc_lsb[i]));
    602  bool temp;
    603  TRUE_OR_RETURN(br->ReadBool(&temp));
    604  sps->used_by_curr_pic_lt_flag[i] = temp;
    605  }
    606  }
    607 
    608  TRUE_OR_RETURN(br->ReadBool(&sps->temporal_mvp_enabled_flag));
    609  TRUE_OR_RETURN(br->ReadBool(&sps->strong_intra_smoothing_enabled_flag));
    610 
    611  TRUE_OR_RETURN(br->ReadBool(&sps->vui_parameters_present));
    612  if (sps->vui_parameters_present) {
    613  OK_OR_RETURN(ParseVuiParameters(sps->max_sub_layers_minus1, br,
    614  &sps->vui_parameters));
    615  }
    616 
    617  // Ignore remaining extension data.
    618 
    619  // This will replace any existing SPS instance.
    620  *sps_id = sps->seq_parameter_set_id;
    621  active_spses_[*sps_id] = std::move(sps);
    622 
    623  return kOk;
    624 }
    625 
    626 const H265Pps* H265Parser::GetPps(int pps_id) {
    627  return active_ppses_[pps_id].get();
    628 }
    629 
    630 const H265Sps* H265Parser::GetSps(int sps_id) {
    631  return active_spses_[sps_id].get();
    632 }
    633 
    634 H265Parser::Result H265Parser::ParseVuiParameters(int max_num_sub_layers_minus1,
    635  H26xBitReader* br,
    636  H265VuiParameters* vui) {
    637  // Reads whole element but ignores most of it.
    638  int ignored;
    639 
    640  TRUE_OR_RETURN(br->ReadBool(&vui->aspect_ratio_info_present_flag));
    641  if (vui->aspect_ratio_info_present_flag) {
    642  TRUE_OR_RETURN(br->ReadBits(8, &vui->aspect_ratio_idc));
    643  if (vui->aspect_ratio_idc == H265VuiParameters::kExtendedSar) {
    644  TRUE_OR_RETURN(br->ReadBits(16, &vui->sar_width));
    645  TRUE_OR_RETURN(br->ReadBits(16, &vui->sar_height));
    646  }
    647  }
    648 
    649  bool overscan_info_present_flag;
    650  TRUE_OR_RETURN(br->ReadBool(&overscan_info_present_flag));
    651  if (overscan_info_present_flag) {
    652  TRUE_OR_RETURN(br->SkipBits(1)); // overscan_appropriate_flag
    653  }
    654 
    655  bool video_signal_type_present_flag;
    656  TRUE_OR_RETURN(br->ReadBool(&video_signal_type_present_flag));
    657  if (video_signal_type_present_flag) {
    658  TRUE_OR_RETURN(br->SkipBits(3)); // video_format
    659  TRUE_OR_RETURN(br->SkipBits(1)); // video_full_range_flag
    660 
    661  bool colour_description_present_flag;
    662  TRUE_OR_RETURN(br->ReadBool(&colour_description_present_flag));
    663  if (colour_description_present_flag) {
    664  TRUE_OR_RETURN(br->SkipBits(8)); // colour_primaries
    665  TRUE_OR_RETURN(br->ReadBits(8, &vui->transfer_characteristics));
    666  TRUE_OR_RETURN(br->SkipBits(8)); // matrix_coeffs
    667  }
    668  }
    669 
    670  bool chroma_loc_info_present_flag;
    671  TRUE_OR_RETURN(br->ReadBool(&chroma_loc_info_present_flag));
    672  if (chroma_loc_info_present_flag) {
    673  // chroma_sample_log_type_top_field, chroma_sample_log_type_bottom_field
    674  TRUE_OR_RETURN(br->ReadUE(&ignored));
    675  TRUE_OR_RETURN(br->ReadUE(&ignored));
    676  }
    677 
    678  // neutral_chroma_indication_flag, field_seq_flag,
    679  // frame_field_info_present_flag.
    680  TRUE_OR_RETURN(br->SkipBits(3));
    681 
    682  bool default_display_window_flag;
    683  TRUE_OR_RETURN(br->ReadBool(&default_display_window_flag));
    684  if (default_display_window_flag) {
    685  TRUE_OR_RETURN(br->ReadUE(&ignored)); // def_disp_win_left_offset
    686  TRUE_OR_RETURN(br->ReadUE(&ignored)); // def_disp_win_right_offset
    687  TRUE_OR_RETURN(br->ReadUE(&ignored)); // def_disp_win_top_offset
    688  TRUE_OR_RETURN(br->ReadUE(&ignored)); // def_disp_win_bottom_offset
    689  }
    690 
    691  bool vui_timing_info_present_flag;
    692  TRUE_OR_RETURN(br->ReadBool(&vui_timing_info_present_flag));
    693  if (vui_timing_info_present_flag) {
    694  // vui_num_units_in_tick, vui_time_scale
    695  TRUE_OR_RETURN(br->SkipBits(32 + 32));
    696 
    697  bool vui_poc_proportional_to_timing_flag;
    698  TRUE_OR_RETURN(br->ReadBool(&vui_poc_proportional_to_timing_flag));
    699  if (vui_poc_proportional_to_timing_flag) {
    700  // vui_num_ticks_poc_diff_one_minus1
    701  TRUE_OR_RETURN(br->ReadUE(&ignored));
    702  }
    703 
    704  bool vui_hdr_parameters_present_flag;
    705  TRUE_OR_RETURN(br->ReadBool(&vui_hdr_parameters_present_flag));
    706  if (vui_hdr_parameters_present_flag) {
    707  OK_OR_RETURN(SkipHrdParameters(max_num_sub_layers_minus1, br));
    708  }
    709  }
    710 
    711  TRUE_OR_RETURN(br->ReadBool(&vui->bitstream_restriction_flag));
    712  if (vui->bitstream_restriction_flag) {
    713  // tiles_fixed_structure_flag, motion_vectors_over_pic_boundaries_flag,
    714  // restricted_ref_pic_lists_flag.
    715  TRUE_OR_RETURN(br->SkipBits(3));
    716 
    717  TRUE_OR_RETURN(br->ReadUE(&vui->min_spatial_segmentation_idc));
    718  TRUE_OR_RETURN(br->ReadUE(&ignored)); // max_bytes_per_pic_denom
    719  TRUE_OR_RETURN(br->ReadUE(&ignored)); // max_bits_per_min_cu_denum
    720  TRUE_OR_RETURN(br->ReadUE(&ignored)); // log2_max_mv_length_horizontal
    721  TRUE_OR_RETURN(br->ReadUE(&ignored)); // log2_max_mv_length_vertical
    722  }
    723 
    724  return kOk;
    725 }
    726 
    727 H265Parser::Result H265Parser::ParseReferencePictureSet(
    728  int num_short_term_ref_pic_sets,
    729  int st_rps_idx,
    730  const std::vector<H265ReferencePictureSet>& ref_pic_sets,
    731  H26xBitReader* br,
    732  H265ReferencePictureSet* out_ref_pic_set) {
    733  // Parses and processess a short-term reference picture set. This needs to
    734  // be done since the size of this element may be dependent on previous
    735  // reference picture sets.
    736 
    737  bool inter_ref_pic_set_prediction = false;
    738  if (st_rps_idx != 0) {
    739  TRUE_OR_RETURN(br->ReadBool(&inter_ref_pic_set_prediction));
    740  }
    741 
    742  if (inter_ref_pic_set_prediction) {
    743  int delta_idx = 1;
    744  if (st_rps_idx == num_short_term_ref_pic_sets) {
    745  TRUE_OR_RETURN(br->ReadUE(&delta_idx));
    746  delta_idx++;
    747  TRUE_OR_RETURN(delta_idx <= st_rps_idx);
    748  }
    749 
    750  int ref_rps_idx = st_rps_idx - delta_idx;
    751  DCHECK_LE(0, ref_rps_idx);
    752  DCHECK_LT(ref_rps_idx, st_rps_idx);
    753 
    754  bool delta_rps_sign;
    755  int abs_delta_rps_minus1;
    756  TRUE_OR_RETURN(br->ReadBool(&delta_rps_sign));
    757  TRUE_OR_RETURN(br->ReadUE(&abs_delta_rps_minus1));
    758  int delta_rps =
    759  delta_rps_sign ? -(abs_delta_rps_minus1 + 1) : abs_delta_rps_minus1 + 1;
    760 
    761  int ref_num_delta_pocs = ref_pic_sets[ref_rps_idx].num_delta_pocs;
    762  std::vector<bool> used_by_curr_pic(ref_num_delta_pocs + 1);
    763  std::vector<bool> use_delta(ref_num_delta_pocs + 1);
    764  for (int j = 0; j <= ref_num_delta_pocs; j++) {
    765  bool temp;
    766  TRUE_OR_RETURN(br->ReadBool(&temp));
    767  used_by_curr_pic[j] = temp;
    768 
    769  if (!used_by_curr_pic[j]) {
    770  TRUE_OR_RETURN(br->ReadBool(&temp));
    771  use_delta[j] = temp;
    772  } else {
    773  use_delta[j] = true;
    774  }
    775  }
    776 
    777  int ref_num_positive_pics = ref_pic_sets[ref_rps_idx].num_positive_pics;
    778  int ref_num_negative_pics = ref_pic_sets[ref_rps_idx].num_negative_pics;
    779  int i;
    780 
    781  // Update list 0.
    782  {
    783  i = 0;
    784  for (int j = ref_num_positive_pics - 1; j >= 0; j--) {
    785  int d_poc = ref_pic_sets[ref_rps_idx].delta_poc_s1[j] + delta_rps;
    786  if (d_poc < 0 && use_delta[ref_num_negative_pics + j]) {
    787  out_ref_pic_set->delta_poc_s0[i] = d_poc;
    788  out_ref_pic_set->used_by_curr_pic_s0[i] =
    789  used_by_curr_pic[ref_num_negative_pics + j];
    790  i++;
    791  }
    792  }
    793  if (delta_rps < 0 && use_delta[ref_num_delta_pocs]) {
    794  out_ref_pic_set->delta_poc_s0[i] = delta_rps;
    795  out_ref_pic_set->used_by_curr_pic_s0[i] =
    796  used_by_curr_pic[ref_num_delta_pocs];
    797  i++;
    798  }
    799  for (int j = 0; j < ref_num_negative_pics; j++) {
    800  int d_poc = ref_pic_sets[ref_rps_idx].delta_poc_s0[j] + delta_rps;
    801  if (d_poc < 0 && use_delta[j]) {
    802  out_ref_pic_set->delta_poc_s0[i] = d_poc;
    803  out_ref_pic_set->used_by_curr_pic_s0[i] = used_by_curr_pic[j];
    804  i++;
    805  }
    806  }
    807  out_ref_pic_set->num_negative_pics = i;
    808  }
    809 
    810  // Update list 1.
    811  {
    812  i = 0;
    813  for (int j = ref_num_negative_pics - 1; j >= 0; j--) {
    814  int d_poc = ref_pic_sets[ref_rps_idx].delta_poc_s0[j] + delta_rps;
    815  if (d_poc > 0 && use_delta[j]) {
    816  out_ref_pic_set->delta_poc_s1[i] = d_poc;
    817  out_ref_pic_set->used_by_curr_pic_s1[i] = used_by_curr_pic[j];
    818  i++;
    819  }
    820  }
    821  if (delta_rps > 0 && use_delta[ref_num_delta_pocs]) {
    822  out_ref_pic_set->delta_poc_s1[i] = delta_rps;
    823  out_ref_pic_set->used_by_curr_pic_s1[i] =
    824  used_by_curr_pic[ref_num_delta_pocs];
    825  i++;
    826  }
    827  for (int j = 0; j < ref_num_positive_pics; j++) {
    828  int d_poc = ref_pic_sets[ref_rps_idx].delta_poc_s1[j] + delta_rps;
    829  if (d_poc > 0 && use_delta[ref_num_negative_pics + j]) {
    830  out_ref_pic_set->delta_poc_s1[i] = d_poc;
    831  out_ref_pic_set->used_by_curr_pic_s1[i] =
    832  used_by_curr_pic[ref_num_negative_pics + j];
    833  i++;
    834  }
    835  }
    836  out_ref_pic_set->num_positive_pics = i;
    837  }
    838  } else {
    839  TRUE_OR_RETURN(br->ReadUE(&out_ref_pic_set->num_negative_pics));
    840  TRUE_OR_RETURN(out_ref_pic_set->num_negative_pics <= kMaxRefPicSetCount);
    841  TRUE_OR_RETURN(br->ReadUE(&out_ref_pic_set->num_positive_pics));
    842  TRUE_OR_RETURN(out_ref_pic_set->num_positive_pics <= kMaxRefPicSetCount);
    843 
    844  int prev_poc = 0;
    845  for (int i = 0; i < out_ref_pic_set->num_negative_pics; i++) {
    846  int delta_poc_s0_minus1;
    847  TRUE_OR_RETURN(br->ReadUE(&delta_poc_s0_minus1));
    848  out_ref_pic_set->delta_poc_s0[i] = prev_poc - (delta_poc_s0_minus1 + 1);
    849  prev_poc = out_ref_pic_set->delta_poc_s0[i];
    850 
    851  TRUE_OR_RETURN(br->ReadBool(&out_ref_pic_set->used_by_curr_pic_s0[i]));
    852  }
    853 
    854  prev_poc = 0;
    855  for (int i = 0; i < out_ref_pic_set->num_positive_pics; i++) {
    856  int delta_poc_s1_minus1;
    857  TRUE_OR_RETURN(br->ReadUE(&delta_poc_s1_minus1));
    858  out_ref_pic_set->delta_poc_s1[i] = prev_poc + delta_poc_s1_minus1 + 1;
    859  prev_poc = out_ref_pic_set->delta_poc_s1[i];
    860 
    861  TRUE_OR_RETURN(br->ReadBool(&out_ref_pic_set->used_by_curr_pic_s1[i]));
    862  }
    863  }
    864 
    865  out_ref_pic_set->num_delta_pocs =
    866  out_ref_pic_set->num_positive_pics + out_ref_pic_set->num_negative_pics;
    867  return kOk;
    868 }
    869 
    870 H265Parser::Result H265Parser::SkipReferencePictureListModification(
    871  const H265SliceHeader& slice_header,
    872  const H265Pps& pps,
    873  int num_pic_total_curr,
    874  H26xBitReader* br) {
    875  // Reads whole element but ignores it all.
    876 
    877  bool ref_pic_list_modification_flag_l0;
    878  TRUE_OR_RETURN(br->ReadBool(&ref_pic_list_modification_flag_l0));
    879  if (ref_pic_list_modification_flag_l0) {
    880  for (int i = 0; i <= pps.num_ref_idx_l0_default_active_minus1; i++) {
    881  TRUE_OR_RETURN(br->SkipBits(ceil(log2(num_pic_total_curr))));
    882  }
    883  }
    884 
    885  if (slice_header.slice_type == kBSlice) {
    886  bool ref_pic_list_modification_flag_l1;
    887  TRUE_OR_RETURN(br->ReadBool(&ref_pic_list_modification_flag_l1));
    888  if (ref_pic_list_modification_flag_l1) {
    889  for (int i = 0; i <= pps.num_ref_idx_l1_default_active_minus1; i++) {
    890  TRUE_OR_RETURN(br->SkipBits(ceil(log2(num_pic_total_curr))));
    891  }
    892  }
    893  }
    894 
    895  return kOk;
    896 }
    897 
    898 H265Parser::Result H265Parser::SkipPredictionWeightTablePart(
    899  int num_ref_idx_minus1,
    900  int chroma_array_type,
    901  H26xBitReader* br) {
    902  // Reads whole element, ignores it.
    903  int ignored;
    904  std::vector<bool> luma_weight_flag(num_ref_idx_minus1 + 1);
    905  std::vector<bool> chroma_weight_flag(num_ref_idx_minus1 + 1);
    906 
    907  for (int i = 0; i <= num_ref_idx_minus1; i++) {
    908  bool temp;
    909  TRUE_OR_RETURN(br->ReadBool(&temp));
    910  luma_weight_flag[i] = temp;
    911  }
    912  if (chroma_array_type != 0) {
    913  for (int i = 0; i <= num_ref_idx_minus1; i++) {
    914  bool temp;
    915  TRUE_OR_RETURN(br->ReadBool(&temp));
    916  chroma_weight_flag[i] = temp;
    917  }
    918  }
    919  for (int i = 0; i <= num_ref_idx_minus1; i++) {
    920  if (luma_weight_flag[i]) {
    921  TRUE_OR_RETURN(br->ReadSE(&ignored)); // delta_luma_weight_l#
    922  TRUE_OR_RETURN(br->ReadSE(&ignored)); // luma_offset_l#
    923  }
    924  if (chroma_weight_flag[i]) {
    925  for (int j = 0; j < 2; j++) {
    926  TRUE_OR_RETURN(br->ReadSE(&ignored)); // delta_chroma_weight_l#
    927  TRUE_OR_RETURN(br->ReadSE(&ignored)); // delta_chroma_offset_l#
    928  }
    929  }
    930  }
    931 
    932  return kOk;
    933 }
    934 
    935 H265Parser::Result H265Parser::SkipPredictionWeightTable(
    936  bool is_b_slice,
    937  const H265Sps& sps,
    938  const H265SliceHeader& slice_header,
    939  H26xBitReader* br) {
    940  // Reads whole element, ignores it.
    941  int ignored;
    942  int chroma_array_type = sps.GetChromaArrayType();
    943 
    944  TRUE_OR_RETURN(br->ReadUE(&ignored)); // luma_log2_weight_denom
    945  if (chroma_array_type != 0) {
    946  TRUE_OR_RETURN(br->ReadSE(&ignored)); // delta_chroma_log2_weight_denom
    947  }
    948  OK_OR_RETURN(SkipPredictionWeightTablePart(
    949  slice_header.num_ref_idx_l0_active_minus1, chroma_array_type, br));
    950  if (is_b_slice) {
    951  OK_OR_RETURN(SkipPredictionWeightTablePart(
    952  slice_header.num_ref_idx_l1_active_minus1, chroma_array_type, br));
    953  }
    954 
    955  return kOk;
    956 }
    957 
    958 H265Parser::Result H265Parser::ReadProfileTierLevel(
    959  bool profile_present,
    960  int max_num_sub_layers_minus1,
    961  H26xBitReader* br,
    962  H265Sps* sps) {
    963  // Reads whole element, ignores it.
    964 
    965  if (profile_present) {
    966  // 11 bytes of general_profile_tier flags:
    967  // general_profile_space, general_tier_flag, general_profile_idc
    968  // general_profile_compativility_flag
    969  // general_progressive_source_flag
    970  // general_interlaced_source_flag
    971  // general_non_packed_constraint_flag
    972  // general_frame_only_constraint_flag
    973  // 44-bits of other flags
    974  for (int i = 0; i < 11; i++)
    975  TRUE_OR_RETURN(br->ReadBits(8, &sps->general_profile_tier_level_data[i]));
    976  }
    977  // general_level_idc
    978  TRUE_OR_RETURN(br->ReadBits(8, &sps->general_profile_tier_level_data[11]));
    979 
    980  std::vector<bool> sub_layer_profile_present(max_num_sub_layers_minus1);
    981  std::vector<bool> sub_layer_level_present(max_num_sub_layers_minus1);
    982  for (int i = 0; i < max_num_sub_layers_minus1; i++) {
    983  bool profile, level;
    984  TRUE_OR_RETURN(br->ReadBool(&profile));
    985  TRUE_OR_RETURN(br->ReadBool(&level));
    986  sub_layer_profile_present[i] = profile;
    987  sub_layer_level_present[i] = level;
    988  }
    989 
    990  if (max_num_sub_layers_minus1 > 0) {
    991  for (int i = max_num_sub_layers_minus1; i < 8; i++)
    992  TRUE_OR_RETURN(br->SkipBits(2)); // reserved_zero_2bits
    993  }
    994 
    995  for (int i = 0; i < max_num_sub_layers_minus1; i++) {
    996  if (sub_layer_profile_present[i]) {
    997  // sub_layer_profile_space, sub_layer_tier_flag, sub_layer_profile_idc
    998  // sub_layer_profile_compatibility
    999  // sub_layer_reserved_zero_43bits
    1000  // sub_layer_reserved_zero_bit
    1001  TRUE_OR_RETURN(br->SkipBits(2 + 1 + 5 + 32 + 4 + 43 + 1));
    1002  }
    1003  if (sub_layer_level_present[i]) {
    1004  TRUE_OR_RETURN(br->SkipBits(8));
    1005  }
    1006  }
    1007 
    1008  return kOk;
    1009 }
    1010 
    1011 H265Parser::Result H265Parser::SkipScalingListData(H26xBitReader* br) {
    1012  // Reads whole element, ignores it.
    1013  int ignored;
    1014  for (int size_id = 0; size_id < 4; size_id++) {
    1015  for (int matrix_id = 0; matrix_id < 6;
    1016  matrix_id += ((size_id == 3) ? 3 : 1)) {
    1017  bool scaling_list_pred_mode;
    1018  TRUE_OR_RETURN(br->ReadBool(&scaling_list_pred_mode));
    1019  if (!scaling_list_pred_mode) {
    1020  // scaling_list_pred_matrix_id_delta
    1021  TRUE_OR_RETURN(br->ReadUE(&ignored));
    1022  } else {
    1023  int coefNum = std::min(64, (1 << (4 + (size_id << 1))));
    1024  if (size_id > 1) {
    1025  TRUE_OR_RETURN(br->ReadSE(&ignored)); // scaling_list_dc_coef_minus8
    1026  }
    1027 
    1028  for (int i = 0; i < coefNum; i++) {
    1029  TRUE_OR_RETURN(br->ReadSE(&ignored)); // scaling_list_delta_coef
    1030  }
    1031  }
    1032  }
    1033  }
    1034 
    1035  return kOk;
    1036 }
    1037 
    1038 H265Parser::Result H265Parser::SkipHrdParameters(int max_num_sub_layers_minus1,
    1039  H26xBitReader* br) {
    1040  // common_inf_present_flag is always 1 when parsing vui_parameters.
    1041  const bool common_inf_present_flag = true;
    1042 
    1043  int ignored;
    1044  bool nal_hdr_parameters_present_flag;
    1045  bool vcl_hdr_parameters_present_flag;
    1046  bool sub_pic_hdr_params_present_flag = false;
    1047  if (common_inf_present_flag) {
    1048  TRUE_OR_RETURN(br->ReadBool(&nal_hdr_parameters_present_flag));
    1049  TRUE_OR_RETURN(br->ReadBool(&vcl_hdr_parameters_present_flag));
    1050  if (nal_hdr_parameters_present_flag || vcl_hdr_parameters_present_flag) {
    1051  TRUE_OR_RETURN(br->ReadBool(&sub_pic_hdr_params_present_flag));
    1052  if (sub_pic_hdr_params_present_flag) {
    1053  // tick_divisor_minus2, du_cpb_removal_delay_increment_length_minus1,
    1054  // sub_pic_cpb_params_in_pic_timing_sei_flag
    1055  // dpb_output_delay_du_length_minus1
    1056  TRUE_OR_RETURN(br->SkipBits(8 + 5 + 1 + 5));
    1057  }
    1058 
    1059  // bit_rate_scale, cpb_size_scale
    1060  TRUE_OR_RETURN(br->SkipBits(4 + 4));
    1061  if (sub_pic_hdr_params_present_flag)
    1062  TRUE_OR_RETURN(br->SkipBits(4)); // cpb_size_du_scale
    1063 
    1064  // initial_cpb_removal_delay_length_minus1,
    1065  // au_cpb_removal_delay_length_minus1, dpb_output_delay_length_minus1
    1066  TRUE_OR_RETURN(br->SkipBits(5 + 5 + 5));
    1067  }
    1068  }
    1069 
    1070  for (int i = 0; i <= max_num_sub_layers_minus1; i++) {
    1071  bool fixed_pic_rate_general_flag;
    1072  bool fixed_pic_rate_within_cvs_flag = true;
    1073  bool low_delay_hdr_flag = false;
    1074  int cpb_cnt_minus1 = 0;
    1075  TRUE_OR_RETURN(br->ReadBool(&fixed_pic_rate_general_flag));
    1076  if (!fixed_pic_rate_general_flag)
    1077  TRUE_OR_RETURN(br->ReadBool(&fixed_pic_rate_within_cvs_flag));
    1078  if (fixed_pic_rate_within_cvs_flag)
    1079  TRUE_OR_RETURN(br->ReadUE(&ignored)); // elemental_duration_ic_tc_minus1
    1080  else
    1081  TRUE_OR_RETURN(br->ReadBool(&low_delay_hdr_flag));
    1082  if (!low_delay_hdr_flag)
    1083  TRUE_OR_RETURN(br->ReadUE(&cpb_cnt_minus1));
    1084 
    1085  if (nal_hdr_parameters_present_flag) {
    1086  OK_OR_RETURN(SkipSubLayerHrdParameters(
    1087  cpb_cnt_minus1, sub_pic_hdr_params_present_flag, br));
    1088  }
    1089  if (vcl_hdr_parameters_present_flag) {
    1090  OK_OR_RETURN(SkipSubLayerHrdParameters(
    1091  cpb_cnt_minus1, sub_pic_hdr_params_present_flag, br));
    1092  }
    1093  }
    1094 
    1095  return kOk;
    1096 }
    1097 
    1098 H265Parser::Result H265Parser::SkipSubLayerHrdParameters(
    1099  int cpb_cnt_minus1,
    1100  bool sub_pic_hdr_params_present_flag,
    1101  H26xBitReader* br) {
    1102  int ignored;
    1103  for (int i = 0; i <= cpb_cnt_minus1; i++) {
    1104  TRUE_OR_RETURN(br->ReadUE(&ignored)); // bit_rate_value_minus1
    1105  TRUE_OR_RETURN(br->ReadUE(&ignored)); // cpb_size_value_minus1
    1106  if (sub_pic_hdr_params_present_flag) {
    1107  TRUE_OR_RETURN(br->ReadUE(&ignored)); // cpb_size_du_value_minus1
    1108  TRUE_OR_RETURN(br->ReadUE(&ignored)); // bit_rate_du_value_minus1
    1109  }
    1110 
    1111  TRUE_OR_RETURN(br->SkipBits(1)); // cbr_flag
    1112  }
    1113 
    1114  return kOk;
    1115 }
    1116 
    1117 H265Parser::Result H265Parser::ByteAlignment(H26xBitReader* br) {
    1118  TRUE_OR_RETURN(br->SkipBits(1));
    1119  TRUE_OR_RETURN(br->SkipBits(br->NumBitsLeft() % 8));
    1120  return kOk;
    1121 }
    1122 
    1123 } // namespace media
    1124 } // namespace shaka
    bool is_video_slice() const
    Slice data partition NALs are not considered as slice NALs.
    Definition: nalu_reader.h:117
    - - -
    Result ParseSliceHeader(const Nalu &nalu, H265SliceHeader *slice_header)
    Definition: h265_parser.cc:183
    -
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    - -
    Result ParsePps(const Nalu &nalu, int *pps_id)
    Definition: h265_parser.cc:401
    -
    All the methods that are virtual are virtual for mocking.
    -
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    - - -
    const H265Sps * GetSps(int sps_id)
    Definition: h265_parser.cc:630
    -
    const H265Pps * GetPps(int pps_id)
    Definition: h265_parser.cc:626
    -
    int type() const
    Definition: nalu_reader.h:113
    - -
    Result ParseSps(const Nalu &nalu, int *sps_id)
    Definition: h265_parser.cc:509
    - -
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/h265_parser.h"
    +
    8 
    +
    9 #include <math.h>
    +
    10 #include <algorithm>
    +
    11 
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/media/base/macros.h"
    +
    14 #include "packager/media/codecs/nalu_reader.h"
    +
    15 
    +
    16 #define TRUE_OR_RETURN(a) \
    +
    17  do { \
    +
    18  if (!(a)) { \
    +
    19  DVLOG(1) << "Failure while processing " << #a; \
    +
    20  return kInvalidStream; \
    +
    21  } \
    +
    22  } while (0)
    +
    23 
    +
    24 #define OK_OR_RETURN(a) \
    +
    25  do { \
    +
    26  Result status = (a); \
    +
    27  if (status != kOk) \
    +
    28  return status; \
    +
    29  } while (false)
    +
    30 
    +
    31 namespace shaka {
    +
    32 namespace media {
    +
    33 
    +
    34 namespace {
    +
    35 int GetNumPicTotalCurr(const H265SliceHeader& slice_header,
    +
    36  const H265Sps& sps) {
    +
    37  int num_pic_total_curr = 0;
    +
    38  const H265ReferencePictureSet& ref_pic_set =
    +
    39  slice_header.short_term_ref_pic_set_sps_flag
    +
    40  ? sps.st_ref_pic_sets[slice_header.short_term_ref_pic_set_idx]
    +
    41  : slice_header.st_ref_pic_set;
    +
    42 
    +
    43  for (int i = 0; i < ref_pic_set.num_negative_pics; i++) {
    +
    44  if (ref_pic_set.used_by_curr_pic_s0[i])
    +
    45  num_pic_total_curr++;
    +
    46  }
    +
    47  for (int i = 0; i < ref_pic_set.num_positive_pics; i++) {
    +
    48  if (ref_pic_set.used_by_curr_pic_s1[i])
    +
    49  num_pic_total_curr++;
    +
    50  }
    +
    51 
    +
    52  return num_pic_total_curr + slice_header.used_by_curr_pic_lt;
    +
    53 }
    +
    54 
    +
    55 void GetAspectRatioInfo(const H265Sps& sps,
    +
    56  uint32_t* pixel_width,
    +
    57  uint32_t* pixel_height) {
    +
    58  // The default value is 0; so if this is not in the SPS, it will correctly
    +
    59  // assume unspecified.
    +
    60  int aspect_ratio_idc = sps.vui_parameters.aspect_ratio_idc;
    +
    61 
    +
    62  // Table E.1
    +
    63  switch (aspect_ratio_idc) {
    +
    64  case 1: *pixel_width = 1; *pixel_height = 1; break;
    +
    65  case 2: *pixel_width = 12; *pixel_height = 11; break;
    +
    66  case 3: *pixel_width = 10; *pixel_height = 11; break;
    +
    67  case 4: *pixel_width = 16; *pixel_height = 11; break;
    +
    68  case 5: *pixel_width = 40; *pixel_height = 33; break;
    +
    69  case 6: *pixel_width = 24; *pixel_height = 11; break;
    +
    70  case 7: *pixel_width = 20; *pixel_height = 11; break;
    +
    71  case 8: *pixel_width = 32; *pixel_height = 11; break;
    +
    72  case 9: *pixel_width = 80; *pixel_height = 33; break;
    +
    73  case 10: *pixel_width = 18; *pixel_height = 11; break;
    +
    74  case 11: *pixel_width = 15; *pixel_height = 11; break;
    +
    75  case 12: *pixel_width = 64; *pixel_height = 33; break;
    +
    76  case 13: *pixel_width = 160; *pixel_height = 99; break;
    +
    77  case 14: *pixel_width = 4; *pixel_height = 3; break;
    +
    78  case 15: *pixel_width = 3; *pixel_height = 2; break;
    +
    79  case 16: *pixel_width = 2; *pixel_height = 1; break;
    +
    80 
    +
    81  case 255:
    +
    82  *pixel_width = sps.vui_parameters.sar_width;
    +
    83  *pixel_height = sps.vui_parameters.sar_height;
    +
    84  break;
    +
    85 
    +
    86  default:
    +
    87  // Section E.3.1 specifies that other values should be interpreted as 0.
    +
    88  LOG(WARNING) << "Unknown aspect_ratio_idc " << aspect_ratio_idc;
    +
    89  FALLTHROUGH_INTENDED;
    +
    90  case 0:
    +
    91  // Unlike the spec, assume 1:1 if not specified.
    +
    92  *pixel_width = 1;
    +
    93  *pixel_height = 1;
    +
    94  break;
    +
    95  }
    +
    96 }
    +
    97 } // namespace
    +
    98 
    +
    99 bool ExtractResolutionFromSps(const H265Sps& sps,
    +
    100  uint32_t* coded_width,
    +
    101  uint32_t* coded_height,
    +
    102  uint32_t* pixel_width,
    +
    103  uint32_t* pixel_height) {
    +
    104  int crop_x = 0;
    +
    105  int crop_y = 0;
    +
    106  if (sps.conformance_window_flag) {
    +
    107  int sub_width_c = 0;
    +
    108  int sub_height_c = 0;
    +
    109 
    +
    110  // Table 6-1
    +
    111  switch (sps.chroma_format_idc) {
    +
    112  case 0: // Monochrome
    +
    113  sub_width_c = 1;
    +
    114  sub_height_c = 1;
    +
    115  break;
    +
    116  case 1: // 4:2:0
    +
    117  sub_width_c = 2;
    +
    118  sub_height_c = 2;
    +
    119  break;
    +
    120  case 2: // 4:2:2
    +
    121  sub_width_c = 2;
    +
    122  sub_height_c = 1;
    +
    123  break;
    +
    124  case 3: // 4:4:4
    +
    125  sub_width_c = 1;
    +
    126  sub_height_c = 1;
    +
    127  break;
    +
    128  default:
    +
    129  LOG(ERROR) << "Unexpected chroma_format_idc " << sps.chroma_format_idc;
    +
    130  return false;
    +
    131  }
    +
    132 
    +
    133  // Formula D-28, D-29
    +
    134  crop_x =
    +
    135  sub_width_c * (sps.conf_win_right_offset + sps.conf_win_left_offset);
    +
    136  crop_y =
    +
    137  sub_height_c * (sps.conf_win_bottom_offset + sps.conf_win_top_offset);
    +
    138  }
    +
    139 
    +
    140  // Formula D-28, D-29
    +
    141  *coded_width = sps.pic_width_in_luma_samples - crop_x;
    +
    142  *coded_height = sps.pic_height_in_luma_samples - crop_y;
    +
    143  GetAspectRatioInfo(sps, pixel_width, pixel_height);
    +
    144  return true;
    +
    145 }
    +
    146 
    +
    147 H265Pps::H265Pps() {}
    +
    148 H265Pps::~H265Pps() {}
    +
    149 
    +
    150 H265Sps::H265Sps() {}
    +
    151 H265Sps::~H265Sps() {}
    +
    152 
    +
    153 int H265Sps::GetPicSizeInCtbsY() const {
    +
    154  int min_cb_log2_size_y = log2_min_luma_coding_block_size_minus3 + 3;
    +
    155  int ctb_log2_size_y =
    +
    156  min_cb_log2_size_y + log2_diff_max_min_luma_coding_block_size;
    +
    157  int ctb_size_y = 1 << ctb_log2_size_y;
    +
    158 
    +
    159  // Round-up division.
    +
    160  int pic_width_in_ctbs_y = (pic_width_in_luma_samples - 1) / ctb_size_y + 1;
    +
    161  int pic_height_in_ctbs_y = (pic_height_in_luma_samples - 1) / ctb_size_y + 1;
    +
    162  return pic_width_in_ctbs_y * pic_height_in_ctbs_y;
    +
    163 }
    +
    164 
    +
    165 int H265Sps::GetChromaArrayType() const {
    +
    166  if (!separate_colour_plane_flag)
    +
    167  return chroma_format_idc;
    +
    168  else
    +
    169  return 0;
    +
    170 }
    +
    171 
    +
    172 H265ReferencePictureListModifications::H265ReferencePictureListModifications() {
    +
    173 }
    +
    174 H265ReferencePictureListModifications::
    +
    175  ~H265ReferencePictureListModifications() {}
    +
    176 
    +
    177 H265SliceHeader::H265SliceHeader() {}
    +
    178 H265SliceHeader::~H265SliceHeader() {}
    +
    179 
    +
    180 H265Parser::H265Parser() {}
    +
    181 H265Parser::~H265Parser() {}
    +
    182 
    +
    183 H265Parser::Result H265Parser::ParseSliceHeader(const Nalu& nalu,
    +
    184  H265SliceHeader* slice_header) {
    +
    185  DCHECK(nalu.is_video_slice());
    +
    186  *slice_header = H265SliceHeader();
    +
    187 
    +
    188  // Parses whole element.
    +
    189  H26xBitReader reader;
    +
    190  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    +
    191  H26xBitReader* br = &reader;
    +
    192 
    +
    193  TRUE_OR_RETURN(br->ReadBool(&slice_header->first_slice_segment_in_pic_flag));
    +
    194  if (nalu.type() >= Nalu::H265_BLA_W_LP &&
    +
    195  nalu.type() <= Nalu::H265_RSV_IRAP_VCL23) {
    +
    196  TRUE_OR_RETURN(br->ReadBool(&slice_header->no_output_of_prior_pics_flag));
    +
    197  }
    +
    198 
    +
    199  TRUE_OR_RETURN(br->ReadUE(&slice_header->pic_parameter_set_id));
    +
    200  const H265Pps* pps = GetPps(slice_header->pic_parameter_set_id);
    +
    201  TRUE_OR_RETURN(pps);
    +
    202 
    +
    203  const H265Sps* sps = GetSps(pps->seq_parameter_set_id);
    +
    204  TRUE_OR_RETURN(sps);
    +
    205 
    +
    206  if (!slice_header->first_slice_segment_in_pic_flag) {
    +
    207  if (pps->dependent_slice_segments_enabled_flag) {
    +
    208  TRUE_OR_RETURN(br->ReadBool(&slice_header->dependent_slice_segment_flag));
    +
    209  }
    +
    210  const int bit_length = ceil(log2(sps->GetPicSizeInCtbsY()));
    +
    211  TRUE_OR_RETURN(br->ReadBits(bit_length, &slice_header->segment_address));
    +
    212  }
    +
    213 
    +
    214  if (!slice_header->dependent_slice_segment_flag) {
    +
    215  TRUE_OR_RETURN(br->SkipBits(pps->num_extra_slice_header_bits));
    +
    216  TRUE_OR_RETURN(br->ReadUE(&slice_header->slice_type));
    +
    217  if (pps->output_flag_present_flag) {
    +
    218  TRUE_OR_RETURN(br->ReadBool(&slice_header->pic_output_flag));
    +
    219  }
    +
    220  if (sps->separate_colour_plane_flag) {
    +
    221  TRUE_OR_RETURN(br->ReadBits(2, &slice_header->colour_plane_id));
    +
    222  }
    +
    223 
    +
    224  if (nalu.type() != Nalu::H265_IDR_W_RADL &&
    +
    225  nalu.type() != Nalu::H265_IDR_N_LP) {
    +
    226  TRUE_OR_RETURN(br->ReadBits(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
    +
    227  &slice_header->slice_pic_order_cnt_lsb));
    +
    228 
    +
    229  TRUE_OR_RETURN(
    +
    230  br->ReadBool(&slice_header->short_term_ref_pic_set_sps_flag));
    +
    231  if (!slice_header->short_term_ref_pic_set_sps_flag) {
    +
    232  OK_OR_RETURN(ParseReferencePictureSet(
    +
    233  sps->num_short_term_ref_pic_sets, sps->num_short_term_ref_pic_sets,
    +
    234  sps->st_ref_pic_sets, br, &slice_header->st_ref_pic_set));
    +
    235  } else if (sps->num_short_term_ref_pic_sets > 1) {
    +
    236  TRUE_OR_RETURN(
    +
    237  br->ReadBits(ceil(log2(sps->num_short_term_ref_pic_sets)),
    +
    238  &slice_header->short_term_ref_pic_set_idx));
    +
    239  TRUE_OR_RETURN(slice_header->short_term_ref_pic_set_idx <
    +
    240  sps->num_short_term_ref_pic_sets);
    +
    241  }
    +
    242 
    +
    243  if (sps->long_term_ref_pic_present_flag) {
    +
    244  if (sps->num_long_term_ref_pics > 0) {
    +
    245  TRUE_OR_RETURN(br->ReadUE(&slice_header->num_long_term_sps));
    +
    246  }
    +
    247  TRUE_OR_RETURN(br->ReadUE(&slice_header->num_long_term_pics));
    +
    248 
    +
    249  const int pic_count =
    +
    250  slice_header->num_long_term_sps + slice_header->num_long_term_pics;
    +
    251  slice_header->long_term_pics_info.resize(pic_count);
    +
    252  for (int i = 0; i < pic_count; i++) {
    +
    253  if (i < slice_header->num_long_term_sps) {
    +
    254  int lt_idx_sps = 0;
    +
    255  if (sps->num_long_term_ref_pics > 1) {
    +
    256  TRUE_OR_RETURN(br->ReadBits(
    +
    257  ceil(log2(sps->num_long_term_ref_pics)), &lt_idx_sps));
    +
    258  }
    +
    259  if (sps->used_by_curr_pic_lt_flag[lt_idx_sps])
    +
    260  slice_header->used_by_curr_pic_lt++;
    +
    261  } else {
    +
    262  TRUE_OR_RETURN(br->SkipBits(sps->log2_max_pic_order_cnt_lsb_minus4 +
    +
    263  4)); // poc_lsb_lt
    +
    264  bool used_by_curr_pic_lt_flag;
    +
    265  TRUE_OR_RETURN(br->ReadBool(&used_by_curr_pic_lt_flag));
    +
    266  if (used_by_curr_pic_lt_flag)
    +
    267  slice_header->used_by_curr_pic_lt++;
    +
    268  }
    +
    269  TRUE_OR_RETURN(br->ReadBool(&slice_header->long_term_pics_info[i]
    +
    270  .delta_poc_msb_present_flag));
    +
    271  if (slice_header->long_term_pics_info[i].delta_poc_msb_present_flag) {
    +
    272  TRUE_OR_RETURN(br->ReadUE(
    +
    273  &slice_header->long_term_pics_info[i].delta_poc_msb_cycle_lt));
    +
    274  }
    +
    275  }
    +
    276  }
    +
    277 
    +
    278  if (sps->temporal_mvp_enabled_flag) {
    +
    279  TRUE_OR_RETURN(
    +
    280  br->ReadBool(&slice_header->slice_temporal_mvp_enabled_flag));
    +
    281  }
    +
    282  }
    +
    283 
    +
    284  if (nalu.nuh_layer_id() != 0) {
    +
    285  NOTIMPLEMENTED() << "Multi-layer streams are not supported.";
    +
    286  return kUnsupportedStream;
    +
    287  }
    +
    288 
    +
    289  if (sps->sample_adaptive_offset_enabled_flag) {
    +
    290  TRUE_OR_RETURN(br->ReadBool(&slice_header->slice_sao_luma_flag));
    +
    291  if (sps->GetChromaArrayType() != 0) {
    +
    292  TRUE_OR_RETURN(br->ReadBool(&slice_header->slice_sao_chroma_flag));
    +
    293  }
    +
    294  }
    +
    295 
    +
    296  slice_header->num_ref_idx_l0_active_minus1 =
    +
    297  pps->num_ref_idx_l0_default_active_minus1;
    +
    298  slice_header->num_ref_idx_l1_active_minus1 =
    +
    299  pps->num_ref_idx_l1_default_active_minus1;
    +
    300  if (slice_header->slice_type == kPSlice ||
    +
    301  slice_header->slice_type == kBSlice) {
    +
    302  TRUE_OR_RETURN(
    +
    303  br->ReadBool(&slice_header->num_ref_idx_active_override_flag));
    +
    304  if (slice_header->num_ref_idx_active_override_flag) {
    +
    305  TRUE_OR_RETURN(br->ReadUE(&slice_header->num_ref_idx_l0_active_minus1));
    +
    306  if (slice_header->slice_type == kBSlice) {
    +
    307  TRUE_OR_RETURN(
    +
    308  br->ReadUE(&slice_header->num_ref_idx_l1_active_minus1));
    +
    309  }
    +
    310  }
    +
    311 
    +
    312  const int num_pic_total_curr = GetNumPicTotalCurr(*slice_header, *sps);
    +
    313  if (pps->lists_modification_present_flag && num_pic_total_curr > 1) {
    +
    314  OK_OR_RETURN(SkipReferencePictureListModification(
    +
    315  *slice_header, *pps, num_pic_total_curr, br));
    +
    316  }
    +
    317 
    +
    318  if (slice_header->slice_type == kBSlice) {
    +
    319  TRUE_OR_RETURN(br->ReadBool(&slice_header->mvd_l1_zero_flag));
    +
    320  }
    +
    321  if (pps->cabac_init_present_flag) {
    +
    322  TRUE_OR_RETURN(br->ReadBool(&slice_header->cabac_init_flag));
    +
    323  }
    +
    324  if (slice_header->slice_temporal_mvp_enabled_flag) {
    +
    325  if (slice_header->slice_type == kBSlice) {
    +
    326  TRUE_OR_RETURN(br->ReadBool(&slice_header->collocated_from_l0));
    +
    327  }
    +
    328  bool l0_greater_than_0 = slice_header->num_ref_idx_l0_active_minus1 > 0;
    +
    329  bool l1_greater_than_0 = slice_header->num_ref_idx_l1_active_minus1 > 0;
    +
    330  if (slice_header->collocated_from_l0 ? l0_greater_than_0
    +
    331  : l1_greater_than_0) {
    +
    332  TRUE_OR_RETURN(br->ReadUE(&slice_header->collocated_ref_idx));
    +
    333  }
    +
    334  }
    +
    335 
    +
    336  if ((pps->weighted_pred_flag && slice_header->slice_type == kPSlice) ||
    +
    337  (pps->weighted_bipred_flag && slice_header->slice_type == kBSlice)) {
    +
    338  OK_OR_RETURN(SkipPredictionWeightTable(
    +
    339  slice_header->slice_type == kBSlice, *sps, *slice_header, br));
    +
    340  }
    +
    341  TRUE_OR_RETURN(br->ReadUE(&slice_header->five_minus_max_num_merge_cand));
    +
    342  }
    +
    343 
    +
    344  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_qp_delta));
    +
    345  if (pps->slice_chroma_qp_offsets_present_flag) {
    +
    346  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_cb_qp_offset));
    +
    347  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_cr_qp_offset));
    +
    348  }
    +
    349 
    +
    350  if (pps->chroma_qp_offset_list_enabled_flag) {
    +
    351  TRUE_OR_RETURN(
    +
    352  br->ReadBool(&slice_header->cu_chroma_qp_offset_enabled_flag));
    +
    353  }
    +
    354  if (pps->deblocking_filter_override_enabled_flag) {
    +
    355  TRUE_OR_RETURN(
    +
    356  br->ReadBool(&slice_header->deblocking_filter_override_flag));
    +
    357  }
    +
    358  if (slice_header->deblocking_filter_override_flag) {
    +
    359  TRUE_OR_RETURN(
    +
    360  br->ReadBool(&slice_header->slice_deblocking_filter_disabled_flag));
    +
    361  if (!slice_header->slice_deblocking_filter_disabled_flag) {
    +
    362  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_beta_offset_div2));
    +
    363  TRUE_OR_RETURN(br->ReadSE(&slice_header->slice_tc_offset_div2));
    +
    364  }
    +
    365  }
    +
    366  if (pps->loop_filter_across_slices_enabled_flag &&
    +
    367  (slice_header->slice_sao_luma_flag ||
    +
    368  slice_header->slice_sao_chroma_flag ||
    +
    369  !slice_header->slice_deblocking_filter_disabled_flag)) {
    +
    370  TRUE_OR_RETURN(br->ReadBool(
    +
    371  &slice_header->slice_loop_filter_across_slices_enabled_flag));
    +
    372  }
    +
    373  }
    +
    374 
    +
    375  if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
    +
    376  TRUE_OR_RETURN(br->ReadUE(&slice_header->num_entry_point_offsets));
    +
    377  if (slice_header->num_entry_point_offsets > 0) {
    +
    378  TRUE_OR_RETURN(br->ReadUE(&slice_header->offset_len_minus1));
    +
    379  slice_header->entry_point_offset_minus1.resize(
    +
    380  slice_header->num_entry_point_offsets);
    +
    381  for (int i = 0; i < slice_header->num_entry_point_offsets; i++) {
    +
    382  TRUE_OR_RETURN(
    +
    383  br->ReadBits(slice_header->offset_len_minus1 + 1,
    +
    384  &slice_header->entry_point_offset_minus1[i]));
    +
    385  }
    +
    386  }
    +
    387  }
    +
    388 
    +
    389  if (pps->slice_segment_header_extension_present_flag) {
    +
    390  int extension_length;
    +
    391  TRUE_OR_RETURN(br->ReadUE(&extension_length));
    +
    392  TRUE_OR_RETURN(br->SkipBits(extension_length * 8));
    +
    393  }
    +
    394 
    +
    395  OK_OR_RETURN(ByteAlignment(br));
    +
    396 
    +
    397  slice_header->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
    +
    398  return kOk;
    +
    399 }
    +
    400 
    +
    401 H265Parser::Result H265Parser::ParsePps(const Nalu& nalu, int* pps_id) {
    +
    402  DCHECK_EQ(Nalu::H265_PPS, nalu.type());
    +
    403 
    +
    404  // Reads most of the element, not reading the extension data.
    +
    405  H26xBitReader reader;
    +
    406  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    +
    407  H26xBitReader* br = &reader;
    +
    408 
    +
    409  *pps_id = -1;
    +
    410  std::unique_ptr<H265Pps> pps(new H265Pps);
    +
    411 
    +
    412  TRUE_OR_RETURN(br->ReadUE(&pps->pic_parameter_set_id));
    +
    413  TRUE_OR_RETURN(br->ReadUE(&pps->seq_parameter_set_id));
    +
    414 
    +
    415  TRUE_OR_RETURN(br->ReadBool(&pps->dependent_slice_segments_enabled_flag));
    +
    416  TRUE_OR_RETURN(br->ReadBool(&pps->output_flag_present_flag));
    +
    417  TRUE_OR_RETURN(br->ReadBits(3, &pps->num_extra_slice_header_bits));
    +
    418  TRUE_OR_RETURN(br->ReadBool(&pps->sign_data_hiding_enabled_flag));
    +
    419  TRUE_OR_RETURN(br->ReadBool(&pps->cabac_init_present_flag));
    +
    420 
    +
    421  TRUE_OR_RETURN(br->ReadUE(&pps->num_ref_idx_l0_default_active_minus1));
    +
    422  TRUE_OR_RETURN(br->ReadUE(&pps->num_ref_idx_l1_default_active_minus1));
    +
    423  TRUE_OR_RETURN(br->ReadSE(&pps->init_qp_minus26));
    +
    424  TRUE_OR_RETURN(br->ReadBool(&pps->constrained_intra_pred_flag));
    +
    425  TRUE_OR_RETURN(br->ReadBool(&pps->transform_skip_enabled_flag));
    +
    426 
    +
    427  TRUE_OR_RETURN(br->ReadBool(&pps->cu_qp_delta_enabled_flag));
    +
    428  if (pps->cu_qp_delta_enabled_flag)
    +
    429  TRUE_OR_RETURN(br->ReadUE(&pps->diff_cu_qp_delta_depth));
    +
    430  TRUE_OR_RETURN(br->ReadSE(&pps->cb_qp_offset));
    +
    431  TRUE_OR_RETURN(br->ReadSE(&pps->cr_qp_offset));
    +
    432 
    +
    433  TRUE_OR_RETURN(br->ReadBool(&pps->slice_chroma_qp_offsets_present_flag));
    +
    434  TRUE_OR_RETURN(br->ReadBool(&pps->weighted_pred_flag));
    +
    435  TRUE_OR_RETURN(br->ReadBool(&pps->weighted_bipred_flag));
    +
    436  TRUE_OR_RETURN(br->ReadBool(&pps->transquant_bypass_enabled_flag));
    +
    437  TRUE_OR_RETURN(br->ReadBool(&pps->tiles_enabled_flag));
    +
    438  TRUE_OR_RETURN(br->ReadBool(&pps->entropy_coding_sync_enabled_flag));
    +
    439 
    +
    440  if (pps->tiles_enabled_flag) {
    +
    441  TRUE_OR_RETURN(br->ReadUE(&pps->num_tile_columns_minus1));
    +
    442  TRUE_OR_RETURN(br->ReadUE(&pps->num_tile_rows_minus1));
    +
    443  TRUE_OR_RETURN(br->ReadBool(&pps->uniform_spacing_flag));
    +
    444  if (!pps->uniform_spacing_flag) {
    +
    445  pps->column_width_minus1.resize(pps->num_tile_columns_minus1);
    +
    446  for (int i = 0; i < pps->num_tile_columns_minus1; i++) {
    +
    447  TRUE_OR_RETURN(br->ReadUE(&pps->column_width_minus1[i]));
    +
    448  }
    +
    449  pps->row_height_minus1.resize(pps->num_tile_rows_minus1);
    +
    450  for (int i = 0; i < pps->num_tile_rows_minus1; i++) {
    +
    451  TRUE_OR_RETURN(br->ReadUE(&pps->row_height_minus1[i]));
    +
    452  }
    +
    453  }
    +
    454  TRUE_OR_RETURN(br->ReadBool(&pps->loop_filter_across_tiles_enabled_flag));
    +
    455  }
    +
    456 
    +
    457  TRUE_OR_RETURN(br->ReadBool(&pps->loop_filter_across_slices_enabled_flag));
    +
    458  TRUE_OR_RETURN(br->ReadBool(&pps->deblocking_filter_control_present_flag));
    +
    459  if (pps->deblocking_filter_control_present_flag) {
    +
    460  TRUE_OR_RETURN(br->ReadBool(&pps->deblocking_filter_override_enabled_flag));
    +
    461  TRUE_OR_RETURN(br->ReadBool(&pps->deblocking_filter_disabled_flag));
    +
    462  if (!pps->deblocking_filter_disabled_flag) {
    +
    463  TRUE_OR_RETURN(br->ReadSE(&pps->beta_offset_div2));
    +
    464  TRUE_OR_RETURN(br->ReadSE(&pps->tc_offset_div2));
    +
    465  }
    +
    466  }
    +
    467 
    +
    468  TRUE_OR_RETURN(br->ReadBool(&pps->scaling_list_data_present_flag));
    +
    469  if (pps->scaling_list_data_present_flag) {
    +
    470  OK_OR_RETURN(SkipScalingListData(br));
    +
    471  }
    +
    472 
    +
    473  TRUE_OR_RETURN(br->ReadBool(&pps->lists_modification_present_flag));
    +
    474  TRUE_OR_RETURN(br->ReadUE(&pps->log2_parallel_merge_level_minus2));
    +
    475 
    +
    476  TRUE_OR_RETURN(
    +
    477  br->ReadBool(&pps->slice_segment_header_extension_present_flag));
    +
    478 
    +
    479  bool pps_extension_present_flag;
    +
    480  bool pps_range_extension_flag = false;
    +
    481  TRUE_OR_RETURN(br->ReadBool(&pps_extension_present_flag));
    +
    482  if (pps_extension_present_flag) {
    +
    483  TRUE_OR_RETURN(br->ReadBool(&pps_range_extension_flag));
    +
    484  // pps_multilayer_extension_flag, pps_3d_extension_flag, pps_extension_5bits
    +
    485  TRUE_OR_RETURN(br->SkipBits(1 + 1 + 5));
    +
    486  }
    +
    487 
    +
    488  if (pps_range_extension_flag) {
    +
    489  if (pps->transform_skip_enabled_flag) {
    +
    490  // log2_max_transform_skip_block_size_minus2
    +
    491  int ignored;
    +
    492  TRUE_OR_RETURN(br->ReadUE(&ignored));
    +
    493  }
    +
    494 
    +
    495  TRUE_OR_RETURN(br->SkipBits(1)); // cross_component_prediction_enabled_flag
    +
    496  TRUE_OR_RETURN(br->ReadBool(&pps->chroma_qp_offset_list_enabled_flag));
    +
    497  // Incomplete
    +
    498  }
    +
    499 
    +
    500  // Ignore remaining extension data.
    +
    501 
    +
    502  // This will replace any existing PPS instance.
    +
    503  *pps_id = pps->pic_parameter_set_id;
    +
    504  active_ppses_[*pps_id] = std::move(pps);
    +
    505 
    +
    506  return kOk;
    +
    507 }
    +
    508 
    +
    509 H265Parser::Result H265Parser::ParseSps(const Nalu& nalu, int* sps_id) {
    +
    510  DCHECK_EQ(Nalu::H265_SPS, nalu.type());
    +
    511 
    +
    512  // Reads most of the element, not reading the extension data.
    +
    513  H26xBitReader reader;
    +
    514  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    +
    515  H26xBitReader* br = &reader;
    +
    516 
    +
    517  *sps_id = -1;
    +
    518 
    +
    519  std::unique_ptr<H265Sps> sps(new H265Sps);
    +
    520 
    +
    521  TRUE_OR_RETURN(br->ReadBits(4, &sps->video_parameter_set_id));
    +
    522  TRUE_OR_RETURN(br->ReadBits(3, &sps->max_sub_layers_minus1));
    +
    523  TRUE_OR_RETURN(br->ReadBool(&sps->temporal_id_nesting_flag));
    +
    524 
    +
    525  OK_OR_RETURN(
    +
    526  ReadProfileTierLevel(true, sps->max_sub_layers_minus1, br, sps.get()));
    +
    527 
    +
    528  TRUE_OR_RETURN(br->ReadUE(&sps->seq_parameter_set_id));
    +
    529  TRUE_OR_RETURN(br->ReadUE(&sps->chroma_format_idc));
    +
    530  if (sps->chroma_format_idc == 3) {
    +
    531  TRUE_OR_RETURN(br->ReadBool(&sps->separate_colour_plane_flag));
    +
    532  }
    +
    533  TRUE_OR_RETURN(br->ReadUE(&sps->pic_width_in_luma_samples));
    +
    534  TRUE_OR_RETURN(br->ReadUE(&sps->pic_height_in_luma_samples));
    +
    535 
    +
    536  TRUE_OR_RETURN(br->ReadBool(&sps->conformance_window_flag));
    +
    537  if (sps->conformance_window_flag) {
    +
    538  TRUE_OR_RETURN(br->ReadUE(&sps->conf_win_left_offset));
    +
    539  TRUE_OR_RETURN(br->ReadUE(&sps->conf_win_right_offset));
    +
    540  TRUE_OR_RETURN(br->ReadUE(&sps->conf_win_top_offset));
    +
    541  TRUE_OR_RETURN(br->ReadUE(&sps->conf_win_bottom_offset));
    +
    542  }
    +
    543 
    +
    544  TRUE_OR_RETURN(br->ReadUE(&sps->bit_depth_luma_minus8));
    +
    545  TRUE_OR_RETURN(br->ReadUE(&sps->bit_depth_chroma_minus8));
    +
    546  TRUE_OR_RETURN(br->ReadUE(&sps->log2_max_pic_order_cnt_lsb_minus4));
    +
    547 
    +
    548  TRUE_OR_RETURN(br->ReadBool(&sps->sub_layer_ordering_info_present_flag));
    +
    549  int start = sps->sub_layer_ordering_info_present_flag
    +
    550  ? 0
    +
    551  : sps->max_sub_layers_minus1;
    +
    552  for (int i = start; i <= sps->max_sub_layers_minus1; i++) {
    +
    553  TRUE_OR_RETURN(br->ReadUE(&sps->max_dec_pic_buffering_minus1[i]));
    +
    554  TRUE_OR_RETURN(br->ReadUE(&sps->max_num_reorder_pics[i]));
    +
    555  TRUE_OR_RETURN(br->ReadUE(&sps->max_latency_increase_plus1[i]));
    +
    556  }
    +
    557 
    +
    558  TRUE_OR_RETURN(br->ReadUE(&sps->log2_min_luma_coding_block_size_minus3));
    +
    559  TRUE_OR_RETURN(br->ReadUE(&sps->log2_diff_max_min_luma_coding_block_size));
    +
    560  TRUE_OR_RETURN(br->ReadUE(&sps->log2_min_luma_transform_block_size_minus2));
    +
    561  TRUE_OR_RETURN(br->ReadUE(&sps->log2_diff_max_min_luma_transform_block_size));
    +
    562  TRUE_OR_RETURN(br->ReadUE(&sps->max_transform_hierarchy_depth_inter));
    +
    563  TRUE_OR_RETURN(br->ReadUE(&sps->max_transform_hierarchy_depth_intra));
    +
    564 
    +
    565  TRUE_OR_RETURN(br->ReadBool(&sps->scaling_list_enabled_flag));
    +
    566  if (sps->scaling_list_enabled_flag) {
    +
    567  TRUE_OR_RETURN(br->ReadBool(&sps->scaling_list_data_present_flag));
    +
    568  if (sps->scaling_list_data_present_flag) {
    +
    569  OK_OR_RETURN(SkipScalingListData(br));
    +
    570  }
    +
    571  }
    +
    572 
    +
    573  TRUE_OR_RETURN(br->ReadBool(&sps->amp_enabled_flag));
    +
    574  TRUE_OR_RETURN(br->ReadBool(&sps->sample_adaptive_offset_enabled_flag));
    +
    575  TRUE_OR_RETURN(br->ReadBool(&sps->pcm_enabled_flag));
    +
    576  if (sps->pcm_enabled_flag) {
    +
    577  TRUE_OR_RETURN(br->ReadBits(4, &sps->pcm_sample_bit_depth_luma_minus1));
    +
    578  TRUE_OR_RETURN(br->ReadBits(4, &sps->pcm_sample_bit_depth_chroma_minus1));
    +
    579  TRUE_OR_RETURN(
    +
    580  br->ReadUE(&sps->log2_min_pcm_luma_coding_block_size_minus3));
    +
    581  TRUE_OR_RETURN(
    +
    582  br->ReadUE(&sps->log2_diff_max_min_pcm_luma_coding_block_size));
    +
    583  TRUE_OR_RETURN(br->ReadBool(&sps->pcm_loop_filter_disabled_flag));
    +
    584  }
    +
    585 
    +
    586  TRUE_OR_RETURN(br->ReadUE(&sps->num_short_term_ref_pic_sets));
    +
    587  sps->st_ref_pic_sets.resize(sps->num_short_term_ref_pic_sets);
    +
    588  for (int i = 0; i < sps->num_short_term_ref_pic_sets; i++) {
    +
    589  OK_OR_RETURN(ParseReferencePictureSet(sps->num_short_term_ref_pic_sets, i,
    +
    590  sps->st_ref_pic_sets, br,
    +
    591  &sps->st_ref_pic_sets[i]));
    +
    592  }
    +
    593 
    +
    594  TRUE_OR_RETURN(br->ReadBool(&sps->long_term_ref_pic_present_flag));
    +
    595  if (sps->long_term_ref_pic_present_flag) {
    +
    596  TRUE_OR_RETURN(br->ReadUE(&sps->num_long_term_ref_pics));
    +
    597  sps->lt_ref_pic_poc_lsb.resize(sps->num_long_term_ref_pics);
    +
    598  sps->used_by_curr_pic_lt_flag.resize(sps->num_long_term_ref_pics);
    +
    599  for (int i = 0; i < sps->num_long_term_ref_pics; i++) {
    +
    600  TRUE_OR_RETURN(br->ReadBits(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
    +
    601  &sps->lt_ref_pic_poc_lsb[i]));
    +
    602  bool temp;
    +
    603  TRUE_OR_RETURN(br->ReadBool(&temp));
    +
    604  sps->used_by_curr_pic_lt_flag[i] = temp;
    +
    605  }
    +
    606  }
    +
    607 
    +
    608  TRUE_OR_RETURN(br->ReadBool(&sps->temporal_mvp_enabled_flag));
    +
    609  TRUE_OR_RETURN(br->ReadBool(&sps->strong_intra_smoothing_enabled_flag));
    +
    610 
    +
    611  TRUE_OR_RETURN(br->ReadBool(&sps->vui_parameters_present));
    +
    612  if (sps->vui_parameters_present) {
    +
    613  OK_OR_RETURN(ParseVuiParameters(sps->max_sub_layers_minus1, br,
    +
    614  &sps->vui_parameters));
    +
    615  }
    +
    616 
    +
    617  // Ignore remaining extension data.
    +
    618 
    +
    619  // This will replace any existing SPS instance.
    +
    620  *sps_id = sps->seq_parameter_set_id;
    +
    621  active_spses_[*sps_id] = std::move(sps);
    +
    622 
    +
    623  return kOk;
    +
    624 }
    +
    625 
    +
    626 const H265Pps* H265Parser::GetPps(int pps_id) {
    +
    627  return active_ppses_[pps_id].get();
    +
    628 }
    +
    629 
    +
    630 const H265Sps* H265Parser::GetSps(int sps_id) {
    +
    631  return active_spses_[sps_id].get();
    +
    632 }
    +
    633 
    +
    634 H265Parser::Result H265Parser::ParseVuiParameters(int max_num_sub_layers_minus1,
    +
    635  H26xBitReader* br,
    +
    636  H265VuiParameters* vui) {
    +
    637  // Reads whole element but ignores most of it.
    +
    638  int ignored;
    +
    639 
    +
    640  TRUE_OR_RETURN(br->ReadBool(&vui->aspect_ratio_info_present_flag));
    +
    641  if (vui->aspect_ratio_info_present_flag) {
    +
    642  TRUE_OR_RETURN(br->ReadBits(8, &vui->aspect_ratio_idc));
    +
    643  if (vui->aspect_ratio_idc == H265VuiParameters::kExtendedSar) {
    +
    644  TRUE_OR_RETURN(br->ReadBits(16, &vui->sar_width));
    +
    645  TRUE_OR_RETURN(br->ReadBits(16, &vui->sar_height));
    +
    646  }
    +
    647  }
    +
    648 
    +
    649  bool overscan_info_present_flag;
    +
    650  TRUE_OR_RETURN(br->ReadBool(&overscan_info_present_flag));
    +
    651  if (overscan_info_present_flag) {
    +
    652  TRUE_OR_RETURN(br->SkipBits(1)); // overscan_appropriate_flag
    +
    653  }
    +
    654 
    +
    655  bool video_signal_type_present_flag;
    +
    656  TRUE_OR_RETURN(br->ReadBool(&video_signal_type_present_flag));
    +
    657  if (video_signal_type_present_flag) {
    +
    658  TRUE_OR_RETURN(br->SkipBits(3)); // video_format
    +
    659  TRUE_OR_RETURN(br->SkipBits(1)); // video_full_range_flag
    +
    660 
    +
    661  bool colour_description_present_flag;
    +
    662  TRUE_OR_RETURN(br->ReadBool(&colour_description_present_flag));
    +
    663  if (colour_description_present_flag) {
    +
    664  TRUE_OR_RETURN(br->SkipBits(8)); // colour_primaries
    +
    665  TRUE_OR_RETURN(br->ReadBits(8, &vui->transfer_characteristics));
    +
    666  TRUE_OR_RETURN(br->SkipBits(8)); // matrix_coeffs
    +
    667  }
    +
    668  }
    +
    669 
    +
    670  bool chroma_loc_info_present_flag;
    +
    671  TRUE_OR_RETURN(br->ReadBool(&chroma_loc_info_present_flag));
    +
    672  if (chroma_loc_info_present_flag) {
    +
    673  // chroma_sample_log_type_top_field, chroma_sample_log_type_bottom_field
    +
    674  TRUE_OR_RETURN(br->ReadUE(&ignored));
    +
    675  TRUE_OR_RETURN(br->ReadUE(&ignored));
    +
    676  }
    +
    677 
    +
    678  // neutral_chroma_indication_flag, field_seq_flag,
    +
    679  // frame_field_info_present_flag.
    +
    680  TRUE_OR_RETURN(br->SkipBits(3));
    +
    681 
    +
    682  bool default_display_window_flag;
    +
    683  TRUE_OR_RETURN(br->ReadBool(&default_display_window_flag));
    +
    684  if (default_display_window_flag) {
    +
    685  TRUE_OR_RETURN(br->ReadUE(&ignored)); // def_disp_win_left_offset
    +
    686  TRUE_OR_RETURN(br->ReadUE(&ignored)); // def_disp_win_right_offset
    +
    687  TRUE_OR_RETURN(br->ReadUE(&ignored)); // def_disp_win_top_offset
    +
    688  TRUE_OR_RETURN(br->ReadUE(&ignored)); // def_disp_win_bottom_offset
    +
    689  }
    +
    690 
    +
    691  bool vui_timing_info_present_flag;
    +
    692  TRUE_OR_RETURN(br->ReadBool(&vui_timing_info_present_flag));
    +
    693  if (vui_timing_info_present_flag) {
    +
    694  // vui_num_units_in_tick, vui_time_scale
    +
    695  TRUE_OR_RETURN(br->SkipBits(32 + 32));
    +
    696 
    +
    697  bool vui_poc_proportional_to_timing_flag;
    +
    698  TRUE_OR_RETURN(br->ReadBool(&vui_poc_proportional_to_timing_flag));
    +
    699  if (vui_poc_proportional_to_timing_flag) {
    +
    700  // vui_num_ticks_poc_diff_one_minus1
    +
    701  TRUE_OR_RETURN(br->ReadUE(&ignored));
    +
    702  }
    +
    703 
    +
    704  bool vui_hdr_parameters_present_flag;
    +
    705  TRUE_OR_RETURN(br->ReadBool(&vui_hdr_parameters_present_flag));
    +
    706  if (vui_hdr_parameters_present_flag) {
    +
    707  OK_OR_RETURN(SkipHrdParameters(max_num_sub_layers_minus1, br));
    +
    708  }
    +
    709  }
    +
    710 
    +
    711  TRUE_OR_RETURN(br->ReadBool(&vui->bitstream_restriction_flag));
    +
    712  if (vui->bitstream_restriction_flag) {
    +
    713  // tiles_fixed_structure_flag, motion_vectors_over_pic_boundaries_flag,
    +
    714  // restricted_ref_pic_lists_flag.
    +
    715  TRUE_OR_RETURN(br->SkipBits(3));
    +
    716 
    +
    717  TRUE_OR_RETURN(br->ReadUE(&vui->min_spatial_segmentation_idc));
    +
    718  TRUE_OR_RETURN(br->ReadUE(&ignored)); // max_bytes_per_pic_denom
    +
    719  TRUE_OR_RETURN(br->ReadUE(&ignored)); // max_bits_per_min_cu_denum
    +
    720  TRUE_OR_RETURN(br->ReadUE(&ignored)); // log2_max_mv_length_horizontal
    +
    721  TRUE_OR_RETURN(br->ReadUE(&ignored)); // log2_max_mv_length_vertical
    +
    722  }
    +
    723 
    +
    724  return kOk;
    +
    725 }
    +
    726 
    +
    727 H265Parser::Result H265Parser::ParseReferencePictureSet(
    +
    728  int num_short_term_ref_pic_sets,
    +
    729  int st_rps_idx,
    +
    730  const std::vector<H265ReferencePictureSet>& ref_pic_sets,
    +
    731  H26xBitReader* br,
    +
    732  H265ReferencePictureSet* out_ref_pic_set) {
    +
    733  // Parses and processess a short-term reference picture set. This needs to
    +
    734  // be done since the size of this element may be dependent on previous
    +
    735  // reference picture sets.
    +
    736 
    +
    737  bool inter_ref_pic_set_prediction = false;
    +
    738  if (st_rps_idx != 0) {
    +
    739  TRUE_OR_RETURN(br->ReadBool(&inter_ref_pic_set_prediction));
    +
    740  }
    +
    741 
    +
    742  if (inter_ref_pic_set_prediction) {
    +
    743  int delta_idx = 1;
    +
    744  if (st_rps_idx == num_short_term_ref_pic_sets) {
    +
    745  TRUE_OR_RETURN(br->ReadUE(&delta_idx));
    +
    746  delta_idx++;
    +
    747  TRUE_OR_RETURN(delta_idx <= st_rps_idx);
    +
    748  }
    +
    749 
    +
    750  int ref_rps_idx = st_rps_idx - delta_idx;
    +
    751  DCHECK_LE(0, ref_rps_idx);
    +
    752  DCHECK_LT(ref_rps_idx, st_rps_idx);
    +
    753 
    +
    754  bool delta_rps_sign;
    +
    755  int abs_delta_rps_minus1;
    +
    756  TRUE_OR_RETURN(br->ReadBool(&delta_rps_sign));
    +
    757  TRUE_OR_RETURN(br->ReadUE(&abs_delta_rps_minus1));
    +
    758  int delta_rps =
    +
    759  delta_rps_sign ? -(abs_delta_rps_minus1 + 1) : abs_delta_rps_minus1 + 1;
    +
    760 
    +
    761  int ref_num_delta_pocs = ref_pic_sets[ref_rps_idx].num_delta_pocs;
    +
    762  std::vector<bool> used_by_curr_pic(ref_num_delta_pocs + 1);
    +
    763  std::vector<bool> use_delta(ref_num_delta_pocs + 1);
    +
    764  for (int j = 0; j <= ref_num_delta_pocs; j++) {
    +
    765  bool temp;
    +
    766  TRUE_OR_RETURN(br->ReadBool(&temp));
    +
    767  used_by_curr_pic[j] = temp;
    +
    768 
    +
    769  if (!used_by_curr_pic[j]) {
    +
    770  TRUE_OR_RETURN(br->ReadBool(&temp));
    +
    771  use_delta[j] = temp;
    +
    772  } else {
    +
    773  use_delta[j] = true;
    +
    774  }
    +
    775  }
    +
    776 
    +
    777  int ref_num_positive_pics = ref_pic_sets[ref_rps_idx].num_positive_pics;
    +
    778  int ref_num_negative_pics = ref_pic_sets[ref_rps_idx].num_negative_pics;
    +
    779  int i;
    +
    780 
    +
    781  // Update list 0.
    +
    782  {
    +
    783  i = 0;
    +
    784  for (int j = ref_num_positive_pics - 1; j >= 0; j--) {
    +
    785  int d_poc = ref_pic_sets[ref_rps_idx].delta_poc_s1[j] + delta_rps;
    +
    786  if (d_poc < 0 && use_delta[ref_num_negative_pics + j]) {
    +
    787  out_ref_pic_set->delta_poc_s0[i] = d_poc;
    +
    788  out_ref_pic_set->used_by_curr_pic_s0[i] =
    +
    789  used_by_curr_pic[ref_num_negative_pics + j];
    +
    790  i++;
    +
    791  }
    +
    792  }
    +
    793  if (delta_rps < 0 && use_delta[ref_num_delta_pocs]) {
    +
    794  out_ref_pic_set->delta_poc_s0[i] = delta_rps;
    +
    795  out_ref_pic_set->used_by_curr_pic_s0[i] =
    +
    796  used_by_curr_pic[ref_num_delta_pocs];
    +
    797  i++;
    +
    798  }
    +
    799  for (int j = 0; j < ref_num_negative_pics; j++) {
    +
    800  int d_poc = ref_pic_sets[ref_rps_idx].delta_poc_s0[j] + delta_rps;
    +
    801  if (d_poc < 0 && use_delta[j]) {
    +
    802  out_ref_pic_set->delta_poc_s0[i] = d_poc;
    +
    803  out_ref_pic_set->used_by_curr_pic_s0[i] = used_by_curr_pic[j];
    +
    804  i++;
    +
    805  }
    +
    806  }
    +
    807  out_ref_pic_set->num_negative_pics = i;
    +
    808  }
    +
    809 
    +
    810  // Update list 1.
    +
    811  {
    +
    812  i = 0;
    +
    813  for (int j = ref_num_negative_pics - 1; j >= 0; j--) {
    +
    814  int d_poc = ref_pic_sets[ref_rps_idx].delta_poc_s0[j] + delta_rps;
    +
    815  if (d_poc > 0 && use_delta[j]) {
    +
    816  out_ref_pic_set->delta_poc_s1[i] = d_poc;
    +
    817  out_ref_pic_set->used_by_curr_pic_s1[i] = used_by_curr_pic[j];
    +
    818  i++;
    +
    819  }
    +
    820  }
    +
    821  if (delta_rps > 0 && use_delta[ref_num_delta_pocs]) {
    +
    822  out_ref_pic_set->delta_poc_s1[i] = delta_rps;
    +
    823  out_ref_pic_set->used_by_curr_pic_s1[i] =
    +
    824  used_by_curr_pic[ref_num_delta_pocs];
    +
    825  i++;
    +
    826  }
    +
    827  for (int j = 0; j < ref_num_positive_pics; j++) {
    +
    828  int d_poc = ref_pic_sets[ref_rps_idx].delta_poc_s1[j] + delta_rps;
    +
    829  if (d_poc > 0 && use_delta[ref_num_negative_pics + j]) {
    +
    830  out_ref_pic_set->delta_poc_s1[i] = d_poc;
    +
    831  out_ref_pic_set->used_by_curr_pic_s1[i] =
    +
    832  used_by_curr_pic[ref_num_negative_pics + j];
    +
    833  i++;
    +
    834  }
    +
    835  }
    +
    836  out_ref_pic_set->num_positive_pics = i;
    +
    837  }
    +
    838  } else {
    +
    839  TRUE_OR_RETURN(br->ReadUE(&out_ref_pic_set->num_negative_pics));
    +
    840  TRUE_OR_RETURN(out_ref_pic_set->num_negative_pics <= kMaxRefPicSetCount);
    +
    841  TRUE_OR_RETURN(br->ReadUE(&out_ref_pic_set->num_positive_pics));
    +
    842  TRUE_OR_RETURN(out_ref_pic_set->num_positive_pics <= kMaxRefPicSetCount);
    +
    843 
    +
    844  int prev_poc = 0;
    +
    845  for (int i = 0; i < out_ref_pic_set->num_negative_pics; i++) {
    +
    846  int delta_poc_s0_minus1;
    +
    847  TRUE_OR_RETURN(br->ReadUE(&delta_poc_s0_minus1));
    +
    848  out_ref_pic_set->delta_poc_s0[i] = prev_poc - (delta_poc_s0_minus1 + 1);
    +
    849  prev_poc = out_ref_pic_set->delta_poc_s0[i];
    +
    850 
    +
    851  TRUE_OR_RETURN(br->ReadBool(&out_ref_pic_set->used_by_curr_pic_s0[i]));
    +
    852  }
    +
    853 
    +
    854  prev_poc = 0;
    +
    855  for (int i = 0; i < out_ref_pic_set->num_positive_pics; i++) {
    +
    856  int delta_poc_s1_minus1;
    +
    857  TRUE_OR_RETURN(br->ReadUE(&delta_poc_s1_minus1));
    +
    858  out_ref_pic_set->delta_poc_s1[i] = prev_poc + delta_poc_s1_minus1 + 1;
    +
    859  prev_poc = out_ref_pic_set->delta_poc_s1[i];
    +
    860 
    +
    861  TRUE_OR_RETURN(br->ReadBool(&out_ref_pic_set->used_by_curr_pic_s1[i]));
    +
    862  }
    +
    863  }
    +
    864 
    +
    865  out_ref_pic_set->num_delta_pocs =
    +
    866  out_ref_pic_set->num_positive_pics + out_ref_pic_set->num_negative_pics;
    +
    867  return kOk;
    +
    868 }
    +
    869 
    +
    870 H265Parser::Result H265Parser::SkipReferencePictureListModification(
    +
    871  const H265SliceHeader& slice_header,
    +
    872  const H265Pps& pps,
    +
    873  int num_pic_total_curr,
    +
    874  H26xBitReader* br) {
    +
    875  // Reads whole element but ignores it all.
    +
    876 
    +
    877  bool ref_pic_list_modification_flag_l0;
    +
    878  TRUE_OR_RETURN(br->ReadBool(&ref_pic_list_modification_flag_l0));
    +
    879  if (ref_pic_list_modification_flag_l0) {
    +
    880  for (int i = 0; i <= slice_header.num_ref_idx_l0_active_minus1; i++) {
    +
    881  TRUE_OR_RETURN(br->SkipBits(ceil(log2(num_pic_total_curr))));
    +
    882  }
    +
    883  }
    +
    884 
    +
    885  if (slice_header.slice_type == kBSlice) {
    +
    886  bool ref_pic_list_modification_flag_l1;
    +
    887  TRUE_OR_RETURN(br->ReadBool(&ref_pic_list_modification_flag_l1));
    +
    888  if (ref_pic_list_modification_flag_l1) {
    +
    889  for (int i = 0; i <= slice_header.num_ref_idx_l1_active_minus1; i++) {
    +
    890  TRUE_OR_RETURN(br->SkipBits(ceil(log2(num_pic_total_curr))));
    +
    891  }
    +
    892  }
    +
    893  }
    +
    894 
    +
    895  return kOk;
    +
    896 }
    +
    897 
    +
    898 H265Parser::Result H265Parser::SkipPredictionWeightTablePart(
    +
    899  int num_ref_idx_minus1,
    +
    900  int chroma_array_type,
    +
    901  H26xBitReader* br) {
    +
    902  // Reads whole element, ignores it.
    +
    903  int ignored;
    +
    904  std::vector<bool> luma_weight_flag(num_ref_idx_minus1 + 1);
    +
    905  std::vector<bool> chroma_weight_flag(num_ref_idx_minus1 + 1);
    +
    906 
    +
    907  for (int i = 0; i <= num_ref_idx_minus1; i++) {
    +
    908  bool temp;
    +
    909  TRUE_OR_RETURN(br->ReadBool(&temp));
    +
    910  luma_weight_flag[i] = temp;
    +
    911  }
    +
    912  if (chroma_array_type != 0) {
    +
    913  for (int i = 0; i <= num_ref_idx_minus1; i++) {
    +
    914  bool temp;
    +
    915  TRUE_OR_RETURN(br->ReadBool(&temp));
    +
    916  chroma_weight_flag[i] = temp;
    +
    917  }
    +
    918  }
    +
    919  for (int i = 0; i <= num_ref_idx_minus1; i++) {
    +
    920  if (luma_weight_flag[i]) {
    +
    921  TRUE_OR_RETURN(br->ReadSE(&ignored)); // delta_luma_weight_l#
    +
    922  TRUE_OR_RETURN(br->ReadSE(&ignored)); // luma_offset_l#
    +
    923  }
    +
    924  if (chroma_weight_flag[i]) {
    +
    925  for (int j = 0; j < 2; j++) {
    +
    926  TRUE_OR_RETURN(br->ReadSE(&ignored)); // delta_chroma_weight_l#
    +
    927  TRUE_OR_RETURN(br->ReadSE(&ignored)); // delta_chroma_offset_l#
    +
    928  }
    +
    929  }
    +
    930  }
    +
    931 
    +
    932  return kOk;
    +
    933 }
    +
    934 
    +
    935 H265Parser::Result H265Parser::SkipPredictionWeightTable(
    +
    936  bool is_b_slice,
    +
    937  const H265Sps& sps,
    +
    938  const H265SliceHeader& slice_header,
    +
    939  H26xBitReader* br) {
    +
    940  // Reads whole element, ignores it.
    +
    941  int ignored;
    +
    942  int chroma_array_type = sps.GetChromaArrayType();
    +
    943 
    +
    944  TRUE_OR_RETURN(br->ReadUE(&ignored)); // luma_log2_weight_denom
    +
    945  if (chroma_array_type != 0) {
    +
    946  TRUE_OR_RETURN(br->ReadSE(&ignored)); // delta_chroma_log2_weight_denom
    +
    947  }
    +
    948  OK_OR_RETURN(SkipPredictionWeightTablePart(
    +
    949  slice_header.num_ref_idx_l0_active_minus1, chroma_array_type, br));
    +
    950  if (is_b_slice) {
    +
    951  OK_OR_RETURN(SkipPredictionWeightTablePart(
    +
    952  slice_header.num_ref_idx_l1_active_minus1, chroma_array_type, br));
    +
    953  }
    +
    954 
    +
    955  return kOk;
    +
    956 }
    +
    957 
    +
    958 H265Parser::Result H265Parser::ReadProfileTierLevel(
    +
    959  bool profile_present,
    +
    960  int max_num_sub_layers_minus1,
    +
    961  H26xBitReader* br,
    +
    962  H265Sps* sps) {
    +
    963  // Reads whole element, ignores it.
    +
    964 
    +
    965  if (profile_present) {
    +
    966  // 11 bytes of general_profile_tier flags:
    +
    967  // general_profile_space, general_tier_flag, general_profile_idc
    +
    968  // general_profile_compativility_flag
    +
    969  // general_progressive_source_flag
    +
    970  // general_interlaced_source_flag
    +
    971  // general_non_packed_constraint_flag
    +
    972  // general_frame_only_constraint_flag
    +
    973  // 44-bits of other flags
    +
    974  for (int i = 0; i < 11; i++)
    +
    975  TRUE_OR_RETURN(br->ReadBits(8, &sps->general_profile_tier_level_data[i]));
    +
    976  }
    +
    977  // general_level_idc
    +
    978  TRUE_OR_RETURN(br->ReadBits(8, &sps->general_profile_tier_level_data[11]));
    +
    979 
    +
    980  std::vector<bool> sub_layer_profile_present(max_num_sub_layers_minus1);
    +
    981  std::vector<bool> sub_layer_level_present(max_num_sub_layers_minus1);
    +
    982  for (int i = 0; i < max_num_sub_layers_minus1; i++) {
    +
    983  bool profile, level;
    +
    984  TRUE_OR_RETURN(br->ReadBool(&profile));
    +
    985  TRUE_OR_RETURN(br->ReadBool(&level));
    +
    986  sub_layer_profile_present[i] = profile;
    +
    987  sub_layer_level_present[i] = level;
    +
    988  }
    +
    989 
    +
    990  if (max_num_sub_layers_minus1 > 0) {
    +
    991  for (int i = max_num_sub_layers_minus1; i < 8; i++)
    +
    992  TRUE_OR_RETURN(br->SkipBits(2)); // reserved_zero_2bits
    +
    993  }
    +
    994 
    +
    995  for (int i = 0; i < max_num_sub_layers_minus1; i++) {
    +
    996  if (sub_layer_profile_present[i]) {
    +
    997  // sub_layer_profile_space, sub_layer_tier_flag, sub_layer_profile_idc
    +
    998  // sub_layer_profile_compatibility
    +
    999  // sub_layer_reserved_zero_43bits
    +
    1000  // sub_layer_reserved_zero_bit
    +
    1001  TRUE_OR_RETURN(br->SkipBits(2 + 1 + 5 + 32 + 4 + 43 + 1));
    +
    1002  }
    +
    1003  if (sub_layer_level_present[i]) {
    +
    1004  TRUE_OR_RETURN(br->SkipBits(8));
    +
    1005  }
    +
    1006  }
    +
    1007 
    +
    1008  return kOk;
    +
    1009 }
    +
    1010 
    +
    1011 H265Parser::Result H265Parser::SkipScalingListData(H26xBitReader* br) {
    +
    1012  // Reads whole element, ignores it.
    +
    1013  int ignored;
    +
    1014  for (int size_id = 0; size_id < 4; size_id++) {
    +
    1015  for (int matrix_id = 0; matrix_id < 6;
    +
    1016  matrix_id += ((size_id == 3) ? 3 : 1)) {
    +
    1017  bool scaling_list_pred_mode;
    +
    1018  TRUE_OR_RETURN(br->ReadBool(&scaling_list_pred_mode));
    +
    1019  if (!scaling_list_pred_mode) {
    +
    1020  // scaling_list_pred_matrix_id_delta
    +
    1021  TRUE_OR_RETURN(br->ReadUE(&ignored));
    +
    1022  } else {
    +
    1023  int coefNum = std::min(64, (1 << (4 + (size_id << 1))));
    +
    1024  if (size_id > 1) {
    +
    1025  TRUE_OR_RETURN(br->ReadSE(&ignored)); // scaling_list_dc_coef_minus8
    +
    1026  }
    +
    1027 
    +
    1028  for (int i = 0; i < coefNum; i++) {
    +
    1029  TRUE_OR_RETURN(br->ReadSE(&ignored)); // scaling_list_delta_coef
    +
    1030  }
    +
    1031  }
    +
    1032  }
    +
    1033  }
    +
    1034 
    +
    1035  return kOk;
    +
    1036 }
    +
    1037 
    +
    1038 H265Parser::Result H265Parser::SkipHrdParameters(int max_num_sub_layers_minus1,
    +
    1039  H26xBitReader* br) {
    +
    1040  // common_inf_present_flag is always 1 when parsing vui_parameters.
    +
    1041  const bool common_inf_present_flag = true;
    +
    1042 
    +
    1043  int ignored;
    +
    1044  bool nal_hdr_parameters_present_flag;
    +
    1045  bool vcl_hdr_parameters_present_flag;
    +
    1046  bool sub_pic_hdr_params_present_flag = false;
    +
    1047  if (common_inf_present_flag) {
    +
    1048  TRUE_OR_RETURN(br->ReadBool(&nal_hdr_parameters_present_flag));
    +
    1049  TRUE_OR_RETURN(br->ReadBool(&vcl_hdr_parameters_present_flag));
    +
    1050  if (nal_hdr_parameters_present_flag || vcl_hdr_parameters_present_flag) {
    +
    1051  TRUE_OR_RETURN(br->ReadBool(&sub_pic_hdr_params_present_flag));
    +
    1052  if (sub_pic_hdr_params_present_flag) {
    +
    1053  // tick_divisor_minus2, du_cpb_removal_delay_increment_length_minus1,
    +
    1054  // sub_pic_cpb_params_in_pic_timing_sei_flag
    +
    1055  // dpb_output_delay_du_length_minus1
    +
    1056  TRUE_OR_RETURN(br->SkipBits(8 + 5 + 1 + 5));
    +
    1057  }
    +
    1058 
    +
    1059  // bit_rate_scale, cpb_size_scale
    +
    1060  TRUE_OR_RETURN(br->SkipBits(4 + 4));
    +
    1061  if (sub_pic_hdr_params_present_flag)
    +
    1062  TRUE_OR_RETURN(br->SkipBits(4)); // cpb_size_du_scale
    +
    1063 
    +
    1064  // initial_cpb_removal_delay_length_minus1,
    +
    1065  // au_cpb_removal_delay_length_minus1, dpb_output_delay_length_minus1
    +
    1066  TRUE_OR_RETURN(br->SkipBits(5 + 5 + 5));
    +
    1067  }
    +
    1068  }
    +
    1069 
    +
    1070  for (int i = 0; i <= max_num_sub_layers_minus1; i++) {
    +
    1071  bool fixed_pic_rate_general_flag;
    +
    1072  bool fixed_pic_rate_within_cvs_flag = true;
    +
    1073  bool low_delay_hdr_flag = false;
    +
    1074  int cpb_cnt_minus1 = 0;
    +
    1075  TRUE_OR_RETURN(br->ReadBool(&fixed_pic_rate_general_flag));
    +
    1076  if (!fixed_pic_rate_general_flag)
    +
    1077  TRUE_OR_RETURN(br->ReadBool(&fixed_pic_rate_within_cvs_flag));
    +
    1078  if (fixed_pic_rate_within_cvs_flag)
    +
    1079  TRUE_OR_RETURN(br->ReadUE(&ignored)); // elemental_duration_ic_tc_minus1
    +
    1080  else
    +
    1081  TRUE_OR_RETURN(br->ReadBool(&low_delay_hdr_flag));
    +
    1082  if (!low_delay_hdr_flag)
    +
    1083  TRUE_OR_RETURN(br->ReadUE(&cpb_cnt_minus1));
    +
    1084 
    +
    1085  if (nal_hdr_parameters_present_flag) {
    +
    1086  OK_OR_RETURN(SkipSubLayerHrdParameters(
    +
    1087  cpb_cnt_minus1, sub_pic_hdr_params_present_flag, br));
    +
    1088  }
    +
    1089  if (vcl_hdr_parameters_present_flag) {
    +
    1090  OK_OR_RETURN(SkipSubLayerHrdParameters(
    +
    1091  cpb_cnt_minus1, sub_pic_hdr_params_present_flag, br));
    +
    1092  }
    +
    1093  }
    +
    1094 
    +
    1095  return kOk;
    +
    1096 }
    +
    1097 
    +
    1098 H265Parser::Result H265Parser::SkipSubLayerHrdParameters(
    +
    1099  int cpb_cnt_minus1,
    +
    1100  bool sub_pic_hdr_params_present_flag,
    +
    1101  H26xBitReader* br) {
    +
    1102  int ignored;
    +
    1103  for (int i = 0; i <= cpb_cnt_minus1; i++) {
    +
    1104  TRUE_OR_RETURN(br->ReadUE(&ignored)); // bit_rate_value_minus1
    +
    1105  TRUE_OR_RETURN(br->ReadUE(&ignored)); // cpb_size_value_minus1
    +
    1106  if (sub_pic_hdr_params_present_flag) {
    +
    1107  TRUE_OR_RETURN(br->ReadUE(&ignored)); // cpb_size_du_value_minus1
    +
    1108  TRUE_OR_RETURN(br->ReadUE(&ignored)); // bit_rate_du_value_minus1
    +
    1109  }
    +
    1110 
    +
    1111  TRUE_OR_RETURN(br->SkipBits(1)); // cbr_flag
    +
    1112  }
    +
    1113 
    +
    1114  return kOk;
    +
    1115 }
    +
    1116 
    +
    1117 H265Parser::Result H265Parser::ByteAlignment(H26xBitReader* br) {
    +
    1118  TRUE_OR_RETURN(br->SkipBits(1));
    +
    1119  TRUE_OR_RETURN(br->SkipBits(br->NumBitsLeft() % 8));
    +
    1120  return kOk;
    +
    1121 }
    +
    1122 
    +
    1123 } // namespace media
    +
    1124 } // namespace shaka
    +
    Result ParseSps(const Nalu &nalu, int *sps_id)
    Definition: h265_parser.cc:509
    +
    Result ParsePps(const Nalu &nalu, int *pps_id)
    Definition: h265_parser.cc:401
    +
    const H265Sps * GetSps(int sps_id)
    Definition: h265_parser.cc:630
    +
    Result ParseSliceHeader(const Nalu &nalu, H265SliceHeader *slice_header)
    Definition: h265_parser.cc:183
    +
    const H265Pps * GetPps(int pps_id)
    Definition: h265_parser.cc:626
    + + +
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    +
    bool is_video_slice() const
    Slice data partition NALs are not considered as slice NALs.
    Definition: nalu_reader.h:117
    +
    int type() const
    Definition: nalu_reader.h:113
    +
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    +
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    All the methods that are virtual are virtual for mocking.
    + + + +
    diff --git a/docs/db/de1/mock__aes__cryptor_8h_source.html b/docs/db/de1/mock__aes__cryptor_8h_source.html index 4a707c5c36..abcdde9281 100644 --- a/docs/db/de1/mock__aes__cryptor_8h_source.html +++ b/docs/db/de1/mock__aes__cryptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/mock_aes_cryptor.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mock_aes_cryptor.h
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_MOCK_AES_CRYPTOR_H_
    8 #define PACKAGER_MEDIA_BASE_MOCK_AES_CRYPTOR_H_
    9 
    10 #include "packager/media/base/aes_cryptor.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    15 class MockAesCryptor : public AesCryptor {
    16  public:
    17  MockAesCryptor() : AesCryptor(kDontUseConstantIv) {}
    18 
    19  MOCK_METHOD2(InitializeWithIv,
    20  bool(const std::vector<uint8_t>& key,
    21  const std::vector<uint8_t>& iv));
    22  MOCK_METHOD4(CryptInternal,
    23  bool(const uint8_t* text,
    24  size_t text_size,
    25  uint8_t* crypt_text,
    26  size_t* crypt_text_size));
    27  MOCK_METHOD0(SetIvInternal, void());
    28 };
    29 
    30 } // namespace media
    31 } // namespace shaka
    32 
    33 #endif // PACKAGER_MEDIA_BASE_MOCK_AES_CRYPTOR_H_
    - -
    AesCryptor(ConstantIvFlag constant_iv_flag)
    Definition: aes_cryptor.cc:32
    -
    All the methods that are virtual are virtual for mocking.
    -
    virtual bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv)=0
    -
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_MOCK_AES_CRYPTOR_H_
    +
    8 #define PACKAGER_MEDIA_BASE_MOCK_AES_CRYPTOR_H_
    +
    9 
    +
    10 #include "packager/media/base/aes_cryptor.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    15 class MockAesCryptor : public AesCryptor {
    +
    16  public:
    +
    17  MockAesCryptor() : AesCryptor(kDontUseConstantIv) {}
    +
    18 
    +
    19  MOCK_METHOD2(InitializeWithIv,
    +
    20  bool(const std::vector<uint8_t>& key,
    +
    21  const std::vector<uint8_t>& iv));
    +
    22  MOCK_METHOD4(CryptInternal,
    +
    23  bool(const uint8_t* text,
    +
    24  size_t text_size,
    +
    25  uint8_t* crypt_text,
    +
    26  size_t* crypt_text_size));
    +
    27  MOCK_METHOD0(SetIvInternal, void());
    +
    28 };
    +
    29 
    +
    30 } // namespace media
    +
    31 } // namespace shaka
    +
    32 
    +
    33 #endif // PACKAGER_MEDIA_BASE_MOCK_AES_CRYPTOR_H_
    + +
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    +
    virtual bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv)=0
    +
    AesCryptor(ConstantIvFlag constant_iv_flag)
    Definition: aes_cryptor.cc:32
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/de2/classshaka_1_1media_1_1LineReader.html b/docs/db/de2/classshaka_1_1media_1_1LineReader.html index dfd2e32733..c74cee9044 100644 --- a/docs/db/de2/classshaka_1_1media_1_1LineReader.html +++ b/docs/db/de2/classshaka_1_1media_1_1LineReader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::LineReader Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Public Member Functions

    -LineReader (std::unique_ptr< FileReader > source) -  - -bool Next (std::string *out) + +void PushData (const uint8_t *data, size_t data_size) + Pushes data onto the end of the buffer.
    +  +bool Next (std::string *out)   +void Flush () + 

    Detailed Description

    -

    Definition at line 62 of file text_readers.h.

    -

    The documentation for this class was generated from the following files:

    Member Function Documentation

    + +

    ◆ Flush()

    + +
    +
    + + + + + + + +
    void shaka::media::LineReader::Flush ()
    +
    +

    Indicates that no more data is coming and that calls to Next should return even possibly-incomplete data.

    + +

    Definition at line 67 of file text_readers.cc.

    + +
    +
    + +

    ◆ Next()

    + +
    +
    + + + + + + + + +
    bool shaka::media::LineReader::Next (std::string * out)
    +
    +

    Reads the next line from the buffer.

    Returns
    True if a line is read, false if there's no line in the buffer.
    + +

    Definition at line 24 of file text_readers.cc.

    + +
    +
    +
    The documentation for this class was generated from the following files: diff --git a/docs/db/dea/classshaka_1_1media_1_1TrickPlayHandler.html b/docs/db/dea/classshaka_1_1media_1_1TrickPlayHandler.html index 1f6a8fca2c..cd6a17eec2 100644 --- a/docs/db/dea/classshaka_1_1media_1_1TrickPlayHandler.html +++ b/docs/db/dea/classshaka_1_1media_1_1TrickPlayHandler.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::TrickPlayHandler Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MediaHandler - -
    + + @@ -105,9 +108,9 @@ bool  - - + + @@ -171,9 +174,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/db/dec/audio__timestamp__helper_8cc_source.html b/docs/db/dec/audio__timestamp__helper_8cc_source.html index a08def1bd5..bb212bcab8 100644 --- a/docs/db/dec/audio__timestamp__helper_8cc_source.html +++ b/docs/db/dec/audio__timestamp__helper_8cc_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/base/audio_timestamp_helper.cc Source File @@ -29,18 +29,21 @@

    Public Member Functions

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    virtual bool ValidateOutputStreamIndex (size_t stream_index) const
    - + +/* @license-end */
    audio_timestamp_helper.cc
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/base/audio_timestamp_helper.h"
    6 
    7 #include "packager/base/logging.h"
    8 #include "packager/media/base/timestamp.h"
    9 
    10 namespace shaka {
    11 namespace media {
    12 
    13 AudioTimestampHelper::AudioTimestampHelper(uint32_t timescale,
    14  uint32_t samples_per_second)
    15  : base_timestamp_(kNoTimestamp), frame_count_(0) {
    16  DCHECK_GT(samples_per_second, 0u);
    17  double fps = samples_per_second;
    18  ticks_per_frame_ = timescale / fps;
    19 }
    20 
    21 void AudioTimestampHelper::SetBaseTimestamp(int64_t base_timestamp) {
    22  base_timestamp_ = base_timestamp;
    23  frame_count_ = 0;
    24 }
    25 
    26 int64_t AudioTimestampHelper::base_timestamp() const {
    27  return base_timestamp_;
    28 }
    29 
    30 void AudioTimestampHelper::AddFrames(int64_t frame_count) {
    31  DCHECK_GE(frame_count, 0);
    32  DCHECK(base_timestamp_ != kNoTimestamp);
    33  frame_count_ += frame_count;
    34 }
    35 
    36 int64_t AudioTimestampHelper::GetTimestamp() const {
    37  return ComputeTimestamp(frame_count_);
    38 }
    39 
    40 int64_t AudioTimestampHelper::GetFrameDuration(int64_t frame_count) const {
    41  DCHECK_GE(frame_count, 0);
    42  int64_t end_timestamp = ComputeTimestamp(frame_count_ + frame_count);
    43  return end_timestamp - GetTimestamp();
    44 }
    45 
    46 int64_t AudioTimestampHelper::GetFramesToTarget(int64_t target) const {
    47  DCHECK(base_timestamp_ != kNoTimestamp);
    48  DCHECK(target >= base_timestamp_);
    49 
    50  int64_t delta_in_ticks = (target - GetTimestamp());
    51  if (delta_in_ticks == 0)
    52  return 0;
    53 
    54  // Compute a timestamp relative to |base_timestamp_| since timestamps
    55  // created from |frame_count_| are computed relative to this base.
    56  // This ensures that the time to frame computation here is the proper inverse
    57  // of the frame to time computation in ComputeTimestamp().
    58  int64_t delta_from_base = target - base_timestamp_;
    59 
    60  // Compute frame count for the time delta. This computation rounds to
    61  // the nearest whole number of frames.
    62  double threshold = ticks_per_frame_ / 2;
    63  int64_t target_frame_count = (delta_from_base + threshold) / ticks_per_frame_;
    64  return target_frame_count - frame_count_;
    65 }
    66 
    67 int64_t AudioTimestampHelper::ComputeTimestamp(int64_t frame_count) const {
    68  DCHECK_GE(frame_count, 0);
    69  DCHECK(base_timestamp_ != kNoTimestamp);
    70  double frames_ticks = ticks_per_frame_ * frame_count;
    71  return base_timestamp_ + frames_ticks;
    72 }
    73 
    74 } // namespace media
    75 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/base/audio_timestamp_helper.h"
    +
    6 
    +
    7 #include "packager/base/logging.h"
    +
    8 #include "packager/media/base/timestamp.h"
    +
    9 
    +
    10 namespace shaka {
    +
    11 namespace media {
    +
    12 
    +
    13 AudioTimestampHelper::AudioTimestampHelper(uint32_t timescale,
    +
    14  uint32_t samples_per_second)
    +
    15  : base_timestamp_(kNoTimestamp), frame_count_(0) {
    +
    16  DCHECK_GT(samples_per_second, 0u);
    +
    17  double fps = samples_per_second;
    +
    18  ticks_per_frame_ = timescale / fps;
    +
    19 }
    +
    20 
    +
    21 void AudioTimestampHelper::SetBaseTimestamp(int64_t base_timestamp) {
    +
    22  base_timestamp_ = base_timestamp;
    +
    23  frame_count_ = 0;
    +
    24 }
    +
    25 
    +
    26 int64_t AudioTimestampHelper::base_timestamp() const {
    +
    27  return base_timestamp_;
    +
    28 }
    +
    29 
    +
    30 void AudioTimestampHelper::AddFrames(int64_t frame_count) {
    +
    31  DCHECK_GE(frame_count, 0);
    +
    32  DCHECK(base_timestamp_ != kNoTimestamp);
    +
    33  frame_count_ += frame_count;
    +
    34 }
    +
    35 
    +
    36 int64_t AudioTimestampHelper::GetTimestamp() const {
    +
    37  return ComputeTimestamp(frame_count_);
    +
    38 }
    +
    39 
    +
    40 int64_t AudioTimestampHelper::GetFrameDuration(int64_t frame_count) const {
    +
    41  DCHECK_GE(frame_count, 0);
    +
    42  int64_t end_timestamp = ComputeTimestamp(frame_count_ + frame_count);
    +
    43  return end_timestamp - GetTimestamp();
    +
    44 }
    +
    45 
    +
    46 int64_t AudioTimestampHelper::GetFramesToTarget(int64_t target) const {
    +
    47  DCHECK(base_timestamp_ != kNoTimestamp);
    +
    48  DCHECK(target >= base_timestamp_);
    +
    49 
    +
    50  int64_t delta_in_ticks = (target - GetTimestamp());
    +
    51  if (delta_in_ticks == 0)
    +
    52  return 0;
    +
    53 
    +
    54  // Compute a timestamp relative to |base_timestamp_| since timestamps
    +
    55  // created from |frame_count_| are computed relative to this base.
    +
    56  // This ensures that the time to frame computation here is the proper inverse
    +
    57  // of the frame to time computation in ComputeTimestamp().
    +
    58  int64_t delta_from_base = target - base_timestamp_;
    +
    59 
    +
    60  // Compute frame count for the time delta. This computation rounds to
    +
    61  // the nearest whole number of frames.
    +
    62  double threshold = ticks_per_frame_ / 2;
    +
    63  int64_t target_frame_count = (delta_from_base + threshold) / ticks_per_frame_;
    +
    64  return target_frame_count - frame_count_;
    +
    65 }
    +
    66 
    +
    67 int64_t AudioTimestampHelper::ComputeTimestamp(int64_t frame_count) const {
    +
    68  DCHECK_GE(frame_count, 0);
    +
    69  DCHECK(base_timestamp_ != kNoTimestamp);
    +
    70  double frames_ticks = ticks_per_frame_ * frame_count;
    +
    71  return base_timestamp_ + frames_ticks;
    +
    72 }
    +
    73 
    +
    74 } // namespace media
    +
    75 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/dee/pes__packet_8cc_source.html b/docs/db/dee/pes__packet_8cc_source.html index bd4bbf310e..23d1445641 100644 --- a/docs/db/dee/pes__packet_8cc_source.html +++ b/docs/db/dee/pes__packet_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/pes_packet.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    pes_packet.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp2t/pes_packet.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 namespace mp2t {
    12 
    13 PesPacket::PesPacket() {}
    14 PesPacket::~PesPacket() {}
    15 
    16 } // namespace mp2t
    17 } // namespace media
    18 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/pes_packet.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 namespace mp2t {
    +
    12 
    +
    13 PesPacket::PesPacket() {}
    +
    14 PesPacket::~PesPacket() {}
    +
    15 
    +
    16 } // namespace mp2t
    +
    17 } // namespace media
    +
    18 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/df2/structshaka_1_1media_1_1H265SliceHeader-members.html b/docs/db/df2/structshaka_1_1media_1_1H265SliceHeader-members.html index 5863a3c1cb..ef4b357c40 100644 --- a/docs/db/df2/structshaka_1_1media_1_1H265SliceHeader-members.html +++ b/docs/db/df2/structshaka_1_1media_1_1H265SliceHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/df6/classshaka_1_1media_1_1Cluster-members.html b/docs/db/df6/classshaka_1_1media_1_1Cluster-members.html index f1614fcdee..fe4f65ae45 100644 --- a/docs/db/df6/classshaka_1_1media_1_1Cluster-members.html +++ b/docs/db/df6/classshaka_1_1media_1_1Cluster-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/db/df6/muxer_8h_source.html b/docs/db/df6/muxer_8h_source.html index 247a8f5ebe..b96adc70ef 100644 --- a/docs/db/df6/muxer_8h_source.html +++ b/docs/db/df6/muxer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/muxer.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    muxer.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Defines the muxer interface.
    8 
    9 #ifndef PACKAGER_MEDIA_BASE_MUXER_H_
    10 #define PACKAGER_MEDIA_BASE_MUXER_H_
    11 
    12 #include <memory>
    13 #include <vector>
    14 
    15 #include "packager/base/time/clock.h"
    16 #include "packager/media/base/media_handler.h"
    17 #include "packager/media/base/muxer_options.h"
    18 #include "packager/media/event/muxer_listener.h"
    19 #include "packager/media/event/progress_listener.h"
    20 #include "packager/status.h"
    21 
    22 namespace shaka {
    23 namespace media {
    24 
    25 class MediaSample;
    26 
    30 class Muxer : public MediaHandler {
    31  public:
    32  explicit Muxer(const MuxerOptions& options);
    33  virtual ~Muxer();
    34 
    37  void Cancel();
    38 
    41  void SetMuxerListener(std::unique_ptr<MuxerListener> muxer_listener);
    42 
    45  void SetProgressListener(std::unique_ptr<ProgressListener> progress_listener);
    46 
    47  const std::vector<std::shared_ptr<const StreamInfo>>& streams() const {
    48  return streams_;
    49  }
    50 
    57  void set_clock(base::Clock* clock) {
    58  clock_ = clock;
    59  }
    60 
    61  protected:
    64  Status InitializeInternal() override { return Status::OK; }
    65  Status Process(std::unique_ptr<StreamData> stream_data) override;
    66  Status OnFlushRequest(size_t input_stream_index) override;
    68 
    69  const MuxerOptions& options() const { return options_; }
    70  MuxerListener* muxer_listener() { return muxer_listener_.get(); }
    71  ProgressListener* progress_listener() { return progress_listener_.get(); }
    72  base::Clock* clock() { return clock_; }
    73 
    74  private:
    75  Muxer(const Muxer&) = delete;
    76  Muxer& operator=(const Muxer&) = delete;
    77 
    78  // Initialize the muxer. InitializeMuxer may be called multiple times with
    79  // |options()| updated between calls, which is used to support separate file
    80  // per Representation per Period for Ad Insertion.
    81  virtual Status InitializeMuxer() = 0;
    82 
    83  // Final clean up.
    84  virtual Status Finalize() = 0;
    85 
    86  // Add a new sample.
    87  virtual Status AddSample(
    88  size_t stream_id,
    89  const MediaSample& sample) = 0;
    90 
    91  // Finalize the segment or subsegment.
    92  virtual Status FinalizeSegment(
    93  size_t stream_id,
    94  const SegmentInfo& segment_info) = 0;
    95 
    96  // Re-initialize Muxer. Could be called on StreamInfo or CueEvent.
    97  // |timestamp| may be used to set the output file name.
    98  Status ReinitializeMuxer(int64_t timestamp);
    99 
    100  MuxerOptions options_;
    101  std::vector<std::shared_ptr<const StreamInfo>> streams_;
    102  std::vector<uint8_t> current_key_id_;
    103  bool encryption_started_ = false;
    104  bool cancelled_ = false;
    105 
    106  std::unique_ptr<MuxerListener> muxer_listener_;
    107  std::unique_ptr<ProgressListener> progress_listener_;
    108  // An external injected clock, can be NULL.
    109  base::Clock* clock_ = nullptr;
    110 
    111  // In VOD single segment case with Ad Cues, |output_file_name| is allowed to
    112  // be a template. In this case, there will be NumAdCues + 1 files generated.
    113  std::string output_file_template_;
    114  size_t output_file_index_ = 0;
    115 };
    116 
    117 } // namespace media
    118 } // namespace shaka
    119 
    120 #endif // PACKAGER_MEDIA_BASE_MUXER_H_
    -
    Status OnFlushRequest(size_t input_stream_index) override
    Event handler for flush request at the specific input stream index.
    Definition: muxer.cc:98
    - - -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    This class listens to progress updates events.
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    -
    void SetProgressListener(std::unique_ptr< ProgressListener > progress_listener)
    Definition: muxer.cc:39
    - -
    Status InitializeInternal() override
    Definition: muxer.h:64
    -
    Status Process(std::unique_ptr< StreamData > stream_data) override
    Definition: muxer.cc:44
    -
    void set_clock(base::Clock *clock)
    Definition: muxer.h:57
    -
    void SetMuxerListener(std::unique_ptr< MuxerListener > muxer_listener)
    Definition: muxer.cc:35
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Defines the muxer interface.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_BASE_MUXER_H_
    +
    10 #define PACKAGER_MEDIA_BASE_MUXER_H_
    +
    11 
    +
    12 #include <memory>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/base/time/clock.h"
    +
    16 #include "packager/media/base/media_handler.h"
    +
    17 #include "packager/media/base/muxer_options.h"
    +
    18 #include "packager/media/event/muxer_listener.h"
    +
    19 #include "packager/media/event/progress_listener.h"
    +
    20 #include "packager/status.h"
    +
    21 
    +
    22 namespace shaka {
    +
    23 namespace media {
    +
    24 
    +
    25 class MediaSample;
    +
    26 
    +
    30 class Muxer : public MediaHandler {
    +
    31  public:
    +
    32  explicit Muxer(const MuxerOptions& options);
    +
    33  virtual ~Muxer();
    +
    34 
    +
    37  void Cancel();
    +
    38 
    +
    41  void SetMuxerListener(std::unique_ptr<MuxerListener> muxer_listener);
    +
    42 
    +
    45  void SetProgressListener(std::unique_ptr<ProgressListener> progress_listener);
    +
    46 
    +
    47  const std::vector<std::shared_ptr<const StreamInfo>>& streams() const {
    +
    48  return streams_;
    +
    49  }
    +
    50 
    +
    57  void set_clock(base::Clock* clock) {
    +
    58  clock_ = clock;
    +
    59  }
    +
    60 
    +
    61  protected:
    +
    64  Status InitializeInternal() override { return Status::OK; }
    +
    65  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    66  Status OnFlushRequest(size_t input_stream_index) override;
    +
    68 
    +
    69  const MuxerOptions& options() const { return options_; }
    +
    70  MuxerListener* muxer_listener() { return muxer_listener_.get(); }
    +
    71  ProgressListener* progress_listener() { return progress_listener_.get(); }
    +
    72  base::Clock* clock() { return clock_; }
    +
    73 
    +
    74  private:
    +
    75  Muxer(const Muxer&) = delete;
    +
    76  Muxer& operator=(const Muxer&) = delete;
    +
    77 
    +
    78  // Initialize the muxer. InitializeMuxer may be called multiple times with
    +
    79  // |options()| updated between calls, which is used to support separate file
    +
    80  // per Representation per Period for Ad Insertion.
    +
    81  virtual Status InitializeMuxer() = 0;
    +
    82 
    +
    83  // Final clean up.
    +
    84  virtual Status Finalize() = 0;
    +
    85 
    +
    86  // Add a new media sample. This does nothing by default; so subclasses that
    +
    87  // handle media samples will need to replace this.
    +
    88  virtual Status AddMediaSample(size_t stream_id, const MediaSample& sample);
    +
    89 
    +
    90  // Add a new text sample. This does nothing by default; so subclasses that
    +
    91  // handle text samples will need to replace this.
    +
    92  virtual Status AddTextSample(size_t stream_id, const TextSample& sample);
    +
    93 
    +
    94  // Finalize the segment or subsegment.
    +
    95  virtual Status FinalizeSegment(
    +
    96  size_t stream_id,
    +
    97  const SegmentInfo& segment_info) = 0;
    +
    98 
    +
    99  // Re-initialize Muxer. Could be called on StreamInfo or CueEvent.
    +
    100  // |timestamp| may be used to set the output file name.
    +
    101  Status ReinitializeMuxer(int64_t timestamp);
    +
    102 
    +
    103  MuxerOptions options_;
    +
    104  std::vector<std::shared_ptr<const StreamInfo>> streams_;
    +
    105  std::vector<uint8_t> current_key_id_;
    +
    106  bool encryption_started_ = false;
    +
    107  bool cancelled_ = false;
    +
    108 
    +
    109  std::unique_ptr<MuxerListener> muxer_listener_;
    +
    110  std::unique_ptr<ProgressListener> progress_listener_;
    +
    111  // An external injected clock, can be NULL.
    +
    112  base::Clock* clock_ = nullptr;
    +
    113 
    +
    114  // In VOD single segment case with Ad Cues, |output_file_name| is allowed to
    +
    115  // be a template. In this case, there will be NumAdCues + 1 files generated.
    +
    116  std::string output_file_template_;
    +
    117  size_t output_file_index_ = 0;
    +
    118 };
    +
    119 
    +
    120 } // namespace media
    +
    121 } // namespace shaka
    +
    122 
    +
    123 #endif // PACKAGER_MEDIA_BASE_MUXER_H_
    + + + +
    void SetMuxerListener(std::unique_ptr< MuxerListener > muxer_listener)
    Definition: muxer.cc:35
    +
    void SetProgressListener(std::unique_ptr< ProgressListener > progress_listener)
    Definition: muxer.cc:39
    +
    Status InitializeInternal() override
    Definition: muxer.h:64
    +
    void set_clock(base::Clock *clock)
    Definition: muxer.h:57
    + +
    Status OnFlushRequest(size_t input_stream_index) override
    Event handler for flush request at the specific input stream index.
    Definition: muxer.cc:102
    +
    Status Process(std::unique_ptr< StreamData > stream_data) override
    Definition: muxer.cc:44
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/db/df8/classshaka_1_1media_1_1H265ByteToUnitStreamConverter.html b/docs/db/df8/classshaka_1_1media_1_1H265ByteToUnitStreamConverter.html index 900ef91b1b..aff0e8005a 100644 --- a/docs/db/df8/classshaka_1_1media_1_1H265ByteToUnitStreamConverter.html +++ b/docs/db/df8/classshaka_1_1media_1_1H265ByteToUnitStreamConverter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265ByteToUnitStreamConverter Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::media::H26xByteToUnitStreamConverter - -
    +shaka::media::H26xByteToUnitStreamConverter + + @@ -193,7 +196,7 @@ void 

    Public Member Functions

    WarnIfNotMatch (i
    -

    Creates either an AVCDecoderConfigurationRecord or a HEVCDecoderConfigurationRecord from the units extracted from the byte stream.

    Parameters
    +

    Creates either an AVCDecoderConfigurationRecord or a HEVCDecoderConfigurationRecord from the units extracted from the byte stream.

    Parameters
    decoder_configis a pointer to a vector, which on successful return will contain the computed record.
    @@ -214,9 +217,7 @@ void WarnIfNotMatch (i
    diff --git a/docs/db/df8/pssh__generator__util_8cc_source.html b/docs/db/df8/pssh__generator__util_8cc_source.html index e75696561c..5602060485 100644 --- a/docs/db/df8/pssh__generator__util_8cc_source.html +++ b/docs/db/df8/pssh__generator__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/pssh_generator_util.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    pssh_generator_util.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/pssh_generator_util.h"
    8 
    9 #include <string>
    10 
    11 #include "packager/media/base/widevine_pssh_data.pb.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace {
    16 
    17 std::vector<uint8_t> StringToBytes(const std::string& string) {
    18  return std::vector<uint8_t>(string.begin(), string.end());
    19 }
    20 } // namespace
    21 
    22 std::vector<uint8_t> GenerateWidevinePsshDataFromKeyIds(
    23  const std::vector<std::vector<uint8_t>>& key_ids) {
    24  media::WidevinePsshData widevine_pssh_data;
    25  for (const std::vector<uint8_t>& key_id : key_ids)
    26  widevine_pssh_data.add_key_id(key_id.data(), key_id.size());
    27  return StringToBytes(widevine_pssh_data.SerializeAsString());
    28 }
    29 } // namespace media
    30 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/pssh_generator_util.h"
    +
    8 
    +
    9 #include <string>
    +
    10 
    +
    11 #include "packager/media/base/widevine_pssh_data.pb.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace {
    +
    16 
    +
    17 std::vector<uint8_t> StringToBytes(const std::string& string) {
    +
    18  return std::vector<uint8_t>(string.begin(), string.end());
    +
    19 }
    +
    20 } // namespace
    +
    21 
    +
    22 std::vector<uint8_t> GenerateWidevinePsshDataFromKeyIds(
    +
    23  const std::vector<std::vector<uint8_t>>& key_ids) {
    +
    24  media::WidevinePsshData widevine_pssh_data;
    +
    25  for (const std::vector<uint8_t>& key_id : key_ids)
    +
    26  widevine_pssh_data.add_key_id(key_id.data(), key_id.size());
    +
    27  return StringToBytes(widevine_pssh_data.SerializeAsString());
    +
    28 }
    +
    29 } // namespace media
    +
    30 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/db/dfb/mpd__utils_8cc_source.html b/docs/db/dfb/mpd__utils_8cc_source.html index e7ab8cdc1b..b2689e20fa 100644 --- a/docs/db/dfb/mpd__utils_8cc_source.html +++ b/docs/db/dfb/mpd__utils_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mpd_utils.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mpd_utils.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/mpd/base/mpd_utils.h"
    8 
    9 #include <gflags/gflags.h>
    10 #include <libxml/tree.h>
    11 
    12 #include "packager/base/base64.h"
    13 #include "packager/base/logging.h"
    14 #include "packager/base/strings/string_number_conversions.h"
    15 #include "packager/base/strings/string_util.h"
    16 #include "packager/media/base/language_utils.h"
    17 #include "packager/mpd/base/adaptation_set.h"
    18 #include "packager/mpd/base/content_protection_element.h"
    19 #include "packager/mpd/base/representation.h"
    20 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
    21 
    22 DEFINE_bool(
    23  use_legacy_vp9_codec_string,
    24  false,
    25  "Use legacy vp9 codec string 'vp9' if set to true; otherwise new style "
    26  "vp09.xx.xx.xx... codec string will be used. Default to false as indicated "
    27  "in https://github.com/google/shaka-packager/issues/406, all major "
    28  "browsers and platforms already support the new 'vp09' codec string.");
    29 
    30 namespace shaka {
    31 namespace {
    32 
    33 bool IsKeyRotationDefaultKeyId(const std::string& key_id) {
    34  for (char c : key_id) {
    35  if (c != '\0')
    36  return false;
    37  }
    38  return true;
    39 }
    40 
    41 std::string TextCodecString(const MediaInfo& media_info) {
    42  CHECK(media_info.has_text_info());
    43  const auto container_type = media_info.container_type();
    44 
    45  // Codecs are not needed when mimeType is "text/*". Having a codec would be
    46  // redundant.
    47  if (container_type == MediaInfo::CONTAINER_TEXT) {
    48  return "";
    49  }
    50 
    51  // DASH IOP mentions that the codec for ttml in mp4 is stpp, so override
    52  // the default codec value.
    53  const std::string& codec = media_info.text_info().codec();
    54  if (codec == "ttml" && container_type == MediaInfo::CONTAINER_MP4) {
    55  return "stpp";
    56  }
    57 
    58  return codec;
    59 }
    60 
    61 } // namespace
    62 
    63 bool HasVODOnlyFields(const MediaInfo& media_info) {
    64  return media_info.has_init_range() || media_info.has_index_range() ||
    65  media_info.has_media_file_url();
    66 }
    67 
    68 bool HasLiveOnlyFields(const MediaInfo& media_info) {
    69  return media_info.has_init_segment_url() ||
    70  media_info.has_segment_template_url();
    71 }
    72 
    73 void RemoveDuplicateAttributes(
    74  ContentProtectionElement* content_protection_element) {
    75  DCHECK(content_protection_element);
    76  typedef std::map<std::string, std::string> AttributesMap;
    77 
    78  AttributesMap& attributes = content_protection_element->additional_attributes;
    79  if (!content_protection_element->value.empty())
    80  attributes.erase("value");
    81 
    82  if (!content_protection_element->scheme_id_uri.empty())
    83  attributes.erase("schemeIdUri");
    84 }
    85 
    86 std::string GetLanguage(const MediaInfo& media_info) {
    87  std::string lang;
    88  if (media_info.has_audio_info()) {
    89  lang = media_info.audio_info().language();
    90  } else if (media_info.has_text_info()) {
    91  lang = media_info.text_info().language();
    92  }
    93  return LanguageToShortestForm(lang);
    94 }
    95 
    96 std::string GetCodecs(const MediaInfo& media_info) {
    97  CHECK(OnlyOneTrue(media_info.has_video_info(), media_info.has_audio_info(),
    98  media_info.has_text_info()));
    99 
    100  if (media_info.has_video_info()) {
    101  if (media_info.container_type() == MediaInfo::CONTAINER_WEBM) {
    102  std::string codec = media_info.video_info().codec().substr(0, 4);
    103  // media_info.video_info().codec() contains new revised codec string
    104  // specified by "VPx in ISO BMFF" document, which is not compatible to
    105  // old codec strings in WebM. Hack it here before all browsers support
    106  // new codec strings.
    107  if (codec == "vp08")
    108  return "vp8";
    109  if (FLAGS_use_legacy_vp9_codec_string) {
    110  if (codec == "vp09")
    111  return "vp9";
    112  }
    113  }
    114  return media_info.video_info().codec();
    115  }
    116 
    117  if (media_info.has_audio_info())
    118  return media_info.audio_info().codec();
    119 
    120  if (media_info.has_text_info())
    121  return TextCodecString(media_info);
    122 
    123  NOTREACHED();
    124  return "";
    125 }
    126 
    127 std::string GetBaseCodec(const MediaInfo& media_info) {
    128  std::string codec;
    129  if (media_info.has_video_info()) {
    130  codec = media_info.video_info().codec();
    131  } else if (media_info.has_audio_info()) {
    132  codec = media_info.audio_info().codec();
    133  } else if (media_info.has_text_info()) {
    134  codec = media_info.text_info().codec();
    135  }
    136  // Convert, for example, "mp4a.40.2" to simply "mp4a".
    137  // "mp4a.40.2" and "mp4a.40.5" can exist in the same AdaptationSet.
    138  size_t dot = codec.find('.');
    139  if (dot != std::string::npos) {
    140  codec.erase(dot);
    141  }
    142  return codec;
    143 }
    144 
    145 std::string GetAdaptationSetKey(const MediaInfo& media_info) {
    146  std::string key;
    147 
    148  if (media_info.has_video_info()) {
    149  key.append("video:");
    150  } else if (media_info.has_audio_info()) {
    151  key.append("audio:");
    152  } else if (media_info.has_text_info()) {
    153  key.append(MediaInfo_TextInfo_TextType_Name(media_info.text_info().type()));
    154  key.append(":");
    155  } else {
    156  key.append("unknown:");
    157  }
    158 
    159  key.append(MediaInfo_ContainerType_Name(media_info.container_type()));
    160  key.append(":");
    161  key.append(GetBaseCodec(media_info));
    162  key.append(":");
    163  key.append(GetLanguage(media_info));
    164 
    165  // Trick play streams of the same original stream, but possibly with
    166  // different trick_play_factors, belong to the same trick play AdaptationSet.
    167  if (media_info.video_info().has_playback_rate()) {
    168  key.append(":trick_play");
    169  }
    170 
    171  if (!media_info.dash_accessibilities().empty()) {
    172  key.append(":accessibility_");
    173  for (const std::string& accessibility : media_info.dash_accessibilities())
    174  key.append(accessibility);
    175  }
    176 
    177  if (!media_info.dash_roles().empty()) {
    178  key.append(":roles_");
    179  for (const std::string& role : media_info.dash_roles())
    180  key.append(role);
    181  }
    182 
    183  return key;
    184 }
    185 
    186 std::string SecondsToXmlDuration(double seconds) {
    187  // Chrome internally uses time accurate to microseconds, which is implemented
    188  // per MSE spec (https://www.w3.org/TR/media-source/).
    189  // We need a string formatter that has at least microseconds accuracy for a
    190  // normal video (with duration up to 3 hours). Chrome's DoubleToString
    191  // implementation meets the requirement.
    192  return "PT" + base::DoubleToString(seconds) + "S";
    193 }
    194 
    195 bool GetDurationAttribute(xmlNodePtr node, float* duration) {
    196  DCHECK(node);
    197  DCHECK(duration);
    198  static const char kDuration[] = "duration";
    199  xml::scoped_xml_ptr<xmlChar> duration_value(
    200  xmlGetProp(node, BAD_CAST kDuration));
    201 
    202  if (!duration_value)
    203  return false;
    204 
    205  double duration_double_precision = 0.0;
    206  if (!base::StringToDouble(reinterpret_cast<const char*>(duration_value.get()),
    207  &duration_double_precision)) {
    208  return false;
    209  }
    210 
    211  *duration = static_cast<float>(duration_double_precision);
    212  return true;
    213 }
    214 
    215 bool MoreThanOneTrue(bool b1, bool b2, bool b3) {
    216  return (b1 && b2) || (b2 && b3) || (b3 && b1);
    217 }
    218 
    219 bool AtLeastOneTrue(bool b1, bool b2, bool b3) {
    220  return b1 || b2 || b3;
    221 }
    222 
    223 bool OnlyOneTrue(bool b1, bool b2, bool b3) {
    224  return !MoreThanOneTrue(b1, b2, b3) && AtLeastOneTrue(b1, b2, b3);
    225 }
    226 
    227 // Coverts binary data into human readable UUID format.
    228 bool HexToUUID(const std::string& data, std::string* uuid_format) {
    229  DCHECK(uuid_format);
    230  const size_t kExpectedUUIDSize = 16;
    231  if (data.size() != kExpectedUUIDSize) {
    232  LOG(ERROR) << "UUID size is expected to be " << kExpectedUUIDSize
    233  << " but is " << data.size() << " and the data in hex is "
    234  << base::HexEncode(data.data(), data.size());
    235  return false;
    236  }
    237 
    238  const std::string hex_encoded =
    239  base::ToLowerASCII(base::HexEncode(data.data(), data.size()));
    240  DCHECK_EQ(hex_encoded.size(), kExpectedUUIDSize * 2);
    241  base::StringPiece all(hex_encoded);
    242  // Note UUID has 5 parts separated with dashes.
    243  // e.g. 123e4567-e89b-12d3-a456-426655440000
    244  // These StringPieces have each part.
    245  base::StringPiece first = all.substr(0, 8);
    246  base::StringPiece second = all.substr(8, 4);
    247  base::StringPiece third = all.substr(12, 4);
    248  base::StringPiece fourth = all.substr(16, 4);
    249  base::StringPiece fifth = all.substr(20, 12);
    250 
    251  // 32 hexadecimal characters with 4 hyphens.
    252  const size_t kHumanReadableUUIDSize = 36;
    253  uuid_format->reserve(kHumanReadableUUIDSize);
    254  first.CopyToString(uuid_format);
    255  uuid_format->append("-");
    256  second.AppendToString(uuid_format);
    257  uuid_format->append("-");
    258  third.AppendToString(uuid_format);
    259  uuid_format->append("-");
    260  fourth.AppendToString(uuid_format);
    261  uuid_format->append("-");
    262  fifth.AppendToString(uuid_format);
    263  return true;
    264 }
    265 
    266 void UpdateContentProtectionPsshHelper(
    267  const std::string& drm_uuid,
    268  const std::string& pssh,
    269  std::list<ContentProtectionElement>* content_protection_elements) {
    270  const std::string drm_uuid_schemd_id_uri_form = "urn:uuid:" + drm_uuid;
    271  for (std::list<ContentProtectionElement>::iterator protection =
    272  content_protection_elements->begin();
    273  protection != content_protection_elements->end(); ++protection) {
    274  if (protection->scheme_id_uri != drm_uuid_schemd_id_uri_form) {
    275  continue;
    276  }
    277 
    278  for (std::vector<Element>::iterator subelement =
    279  protection->subelements.begin();
    280  subelement != protection->subelements.end(); ++subelement) {
    281  if (subelement->name == kPsshElementName) {
    282  // For now, we want to remove the PSSH element because some players do
    283  // not support updating pssh.
    284  protection->subelements.erase(subelement);
    285 
    286  // TODO(rkuroiwa): Uncomment this and remove the line above when
    287  // shaka-player supports updating PSSH.
    288  // subelement->content = pssh;
    289  return;
    290  }
    291  }
    292 
    293  // Reaching here means <cenc:pssh> does not exist under the
    294  // ContentProtection element. Add it.
    295  // TODO(rkuroiwa): Uncomment this when shaka-player supports updating PSSH.
    296  // Element cenc_pssh;
    297  // cenc_pssh.name = kPsshElementName;
    298  // cenc_pssh.content = pssh;
    299  // protection->subelements.push_back(cenc_pssh);
    300  return;
    301  }
    302 
    303  // Reaching here means that ContentProtection for the DRM does not exist.
    304  // Add it.
    305  ContentProtectionElement content_protection;
    306  content_protection.scheme_id_uri = drm_uuid_schemd_id_uri_form;
    307  // TODO(rkuroiwa): Uncomment this when shaka-player supports updating PSSH.
    308  // Element cenc_pssh;
    309  // cenc_pssh.name = kPsshElementName;
    310  // cenc_pssh.content = pssh;
    311  // content_protection.subelements.push_back(cenc_pssh);
    312  content_protection_elements->push_back(content_protection);
    313  return;
    314 }
    315 
    316 namespace {
    317 
    318 // UUID for Marlin Adaptive Streaming Specification – Simple Profile from
    319 // https://dashif.org/identifiers/content_protection/.
    320 const char kMarlinUUID[] = "5e629af5-38da-4063-8977-97ffbd9902d4";
    321 // Unofficial FairPlay system id extracted from
    322 // https://forums.developer.apple.com/thread/6185.
    323 const char kFairPlayUUID[] = "29701fe4-3cc7-4a34-8c5b-ae90c7439a47";
    324 
    325 Element GenerateMarlinContentIds(const std::string& key_id) {
    326  // See https://github.com/google/shaka-packager/issues/381 for details.
    327  static const char kMarlinContentIdName[] = "mas:MarlinContentId";
    328  static const char kMarlinContentIdPrefix[] = "urn:marlin:kid:";
    329  static const char kMarlinContentIdsName[] = "mas:MarlinContentIds";
    330 
    331  Element marlin_content_id;
    332  marlin_content_id.name = kMarlinContentIdName;
    333  marlin_content_id.content =
    334  kMarlinContentIdPrefix +
    335  base::ToLowerASCII(base::HexEncode(key_id.data(), key_id.size()));
    336 
    337  Element marlin_content_ids;
    338  marlin_content_ids.name = kMarlinContentIdsName;
    339  marlin_content_ids.subelements.push_back(marlin_content_id);
    340 
    341  return marlin_content_ids;
    342 }
    343 
    344 Element GenerateCencPsshElement(const std::string& pssh) {
    345  std::string base64_encoded_pssh;
    346  base::Base64Encode(base::StringPiece(pssh.data(), pssh.size()),
    347  &base64_encoded_pssh);
    348  Element cenc_pssh;
    349  cenc_pssh.name = kPsshElementName;
    350  cenc_pssh.content = base64_encoded_pssh;
    351  return cenc_pssh;
    352 }
    353 
    354 // Helper function. This works because Representation and AdaptationSet both
    355 // have AddContentProtectionElement().
    356 template <typename ContentProtectionParent>
    357 void AddContentProtectionElementsHelperTemplated(
    358  const MediaInfo& media_info,
    359  ContentProtectionParent* parent) {
    360  DCHECK(parent);
    361  if (!media_info.has_protected_content())
    362  return;
    363 
    364  const MediaInfo::ProtectedContent& protected_content =
    365  media_info.protected_content();
    366 
    367  // DASH MPD spec specifies a default ContentProtection element for ISO BMFF
    368  // (MP4) files.
    369  const bool is_mp4_container =
    370  media_info.container_type() == MediaInfo::CONTAINER_MP4;
    371  std::string key_id_uuid_format;
    372  if (protected_content.has_default_key_id() &&
    373  !IsKeyRotationDefaultKeyId(protected_content.default_key_id())) {
    374  if (!HexToUUID(protected_content.default_key_id(), &key_id_uuid_format)) {
    375  LOG(ERROR) << "Failed to convert default key ID into UUID format.";
    376  }
    377  }
    378 
    379  if (is_mp4_container) {
    380  ContentProtectionElement mp4_content_protection;
    381  mp4_content_protection.scheme_id_uri = kEncryptedMp4Scheme;
    382  mp4_content_protection.value = protected_content.protection_scheme();
    383  if (!key_id_uuid_format.empty()) {
    384  mp4_content_protection.additional_attributes["cenc:default_KID"] =
    385  key_id_uuid_format;
    386  }
    387 
    388  parent->AddContentProtectionElement(mp4_content_protection);
    389  }
    390 
    391  for (const auto& entry : protected_content.content_protection_entry()) {
    392  if (!entry.has_uuid()) {
    393  LOG(WARNING)
    394  << "ContentProtectionEntry was specified but no UUID is set for "
    395  << entry.name_version() << ", skipping.";
    396  continue;
    397  }
    398 
    399  ContentProtectionElement drm_content_protection;
    400 
    401  if (entry.has_name_version())
    402  drm_content_protection.value = entry.name_version();
    403 
    404  if (entry.uuid() == kFairPlayUUID) {
    405  VLOG(1) << "Skipping FairPlay ContentProtection element as FairPlay does "
    406  "not support DASH signaling.";
    407  continue;
    408  } else if (entry.uuid() == kMarlinUUID) {
    409  // Marlin requires its uuid to be in upper case. See #525 for details.
    410  drm_content_protection.scheme_id_uri =
    411  "urn:uuid:" + base::ToUpperASCII(entry.uuid());
    412  drm_content_protection.subelements.push_back(
    413  GenerateMarlinContentIds(protected_content.default_key_id()));
    414  } else {
    415  drm_content_protection.scheme_id_uri = "urn:uuid:" + entry.uuid();
    416  if (!entry.pssh().empty()) {
    417  drm_content_protection.subelements.push_back(
    418  GenerateCencPsshElement(entry.pssh()));
    419  }
    420  }
    421 
    422  if (!key_id_uuid_format.empty() && !is_mp4_container) {
    423  drm_content_protection.additional_attributes["cenc:default_KID"] =
    424  key_id_uuid_format;
    425  }
    426 
    427  parent->AddContentProtectionElement(drm_content_protection);
    428  }
    429 
    430  VLOG_IF(1, protected_content.content_protection_entry().size() == 0)
    431  << "The media is encrypted but no content protection specified (can "
    432  "happen with key rotation).";
    433 }
    434 } // namespace
    435 
    436 void AddContentProtectionElements(const MediaInfo& media_info,
    437  Representation* parent) {
    438  AddContentProtectionElementsHelperTemplated(media_info, parent);
    439 }
    440 
    441 void AddContentProtectionElements(const MediaInfo& media_info,
    442  AdaptationSet* parent) {
    443  AddContentProtectionElementsHelperTemplated(media_info, parent);
    444 }
    445 
    446 } // namespace shaka
    - -
    std::string LanguageToShortestForm(const std::string &language)
    -
    All the methods that are virtual are virtual for mocking.
    - -
    void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
    Definition: mpd_utils.cc:436
    -
    bool HexToUUID(const std::string &data, std::string *uuid_format)
    Definition: mpd_utils.cc:228
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/mpd/base/mpd_utils.h"
    +
    8 
    +
    9 #include <gflags/gflags.h>
    +
    10 #include <libxml/tree.h>
    +
    11 
    +
    12 #include "packager/base/base64.h"
    +
    13 #include "packager/base/logging.h"
    +
    14 #include "packager/base/strings/string_number_conversions.h"
    +
    15 #include "packager/base/strings/string_util.h"
    +
    16 #include "packager/media/base/language_utils.h"
    +
    17 #include "packager/media/base/protection_system_specific_info.h"
    +
    18 #include "packager/mpd/base/adaptation_set.h"
    +
    19 #include "packager/mpd/base/content_protection_element.h"
    +
    20 #include "packager/mpd/base/representation.h"
    +
    21 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
    +
    22 
    +
    23 DEFINE_bool(
    +
    24  use_legacy_vp9_codec_string,
    +
    25  false,
    +
    26  "Use legacy vp9 codec string 'vp9' if set to true; otherwise new style "
    +
    27  "vp09.xx.xx.xx... codec string will be used. Default to false as indicated "
    +
    28  "in https://github.com/google/shaka-packager/issues/406, all major "
    +
    29  "browsers and platforms already support the new 'vp09' codec string.");
    +
    30 
    +
    31 namespace shaka {
    +
    32 namespace {
    +
    33 
    +
    34 bool IsKeyRotationDefaultKeyId(const std::string& key_id) {
    +
    35  for (char c : key_id) {
    +
    36  if (c != '\0')
    +
    37  return false;
    +
    38  }
    +
    39  return true;
    +
    40 }
    +
    41 
    +
    42 std::string TextCodecString(const MediaInfo& media_info) {
    +
    43  CHECK(media_info.has_text_info());
    +
    44  const auto container_type = media_info.container_type();
    +
    45 
    +
    46  // Codecs are not needed when mimeType is "text/*". Having a codec would be
    +
    47  // redundant.
    +
    48  if (container_type == MediaInfo::CONTAINER_TEXT) {
    +
    49  return "";
    +
    50  }
    +
    51 
    +
    52  // DASH IOP mentions that the codec for ttml in mp4 is stpp, so override
    +
    53  // the default codec value.
    +
    54  const std::string& codec = media_info.text_info().codec();
    +
    55  if (codec == "ttml" && container_type == MediaInfo::CONTAINER_MP4) {
    +
    56  return "stpp";
    +
    57  }
    +
    58 
    +
    59  return codec;
    +
    60 }
    +
    61 
    +
    62 } // namespace
    +
    63 
    +
    64 bool HasVODOnlyFields(const MediaInfo& media_info) {
    +
    65  return media_info.has_init_range() || media_info.has_index_range() ||
    +
    66  media_info.has_media_file_url();
    +
    67 }
    +
    68 
    +
    69 bool HasLiveOnlyFields(const MediaInfo& media_info) {
    +
    70  return media_info.has_init_segment_url() ||
    +
    71  media_info.has_segment_template_url();
    +
    72 }
    +
    73 
    +
    74 void RemoveDuplicateAttributes(
    +
    75  ContentProtectionElement* content_protection_element) {
    +
    76  DCHECK(content_protection_element);
    +
    77  typedef std::map<std::string, std::string> AttributesMap;
    +
    78 
    +
    79  AttributesMap& attributes = content_protection_element->additional_attributes;
    +
    80  if (!content_protection_element->value.empty())
    +
    81  attributes.erase("value");
    +
    82 
    +
    83  if (!content_protection_element->scheme_id_uri.empty())
    +
    84  attributes.erase("schemeIdUri");
    +
    85 }
    +
    86 
    +
    87 std::string GetLanguage(const MediaInfo& media_info) {
    +
    88  std::string lang;
    +
    89  if (media_info.has_audio_info()) {
    +
    90  lang = media_info.audio_info().language();
    +
    91  } else if (media_info.has_text_info()) {
    +
    92  lang = media_info.text_info().language();
    +
    93  }
    +
    94  return LanguageToShortestForm(lang);
    +
    95 }
    +
    96 
    +
    97 std::string GetCodecs(const MediaInfo& media_info) {
    +
    98  CHECK(OnlyOneTrue(media_info.has_video_info(), media_info.has_audio_info(),
    +
    99  media_info.has_text_info()));
    +
    100 
    +
    101  if (media_info.has_video_info()) {
    +
    102  if (media_info.container_type() == MediaInfo::CONTAINER_WEBM) {
    +
    103  std::string codec = media_info.video_info().codec().substr(0, 4);
    +
    104  // media_info.video_info().codec() contains new revised codec string
    +
    105  // specified by "VPx in ISO BMFF" document, which is not compatible to
    +
    106  // old codec strings in WebM. Hack it here before all browsers support
    +
    107  // new codec strings.
    +
    108  if (codec == "vp08")
    +
    109  return "vp8";
    +
    110  if (FLAGS_use_legacy_vp9_codec_string) {
    +
    111  if (codec == "vp09")
    +
    112  return "vp9";
    +
    113  }
    +
    114  }
    +
    115  return media_info.video_info().codec();
    +
    116  }
    +
    117 
    +
    118  if (media_info.has_audio_info())
    +
    119  return media_info.audio_info().codec();
    +
    120 
    +
    121  if (media_info.has_text_info())
    +
    122  return TextCodecString(media_info);
    +
    123 
    +
    124  NOTREACHED();
    +
    125  return "";
    +
    126 }
    +
    127 
    +
    128 std::string GetBaseCodec(const MediaInfo& media_info) {
    +
    129  std::string codec;
    +
    130  if (media_info.has_video_info()) {
    +
    131  codec = media_info.video_info().codec();
    +
    132  } else if (media_info.has_audio_info()) {
    +
    133  codec = media_info.audio_info().codec();
    +
    134  } else if (media_info.has_text_info()) {
    +
    135  codec = media_info.text_info().codec();
    +
    136  }
    +
    137  // Convert, for example, "mp4a.40.2" to simply "mp4a".
    +
    138  // "mp4a.40.2" and "mp4a.40.5" can exist in the same AdaptationSet.
    +
    139  size_t dot = codec.find('.');
    +
    140  if (dot != std::string::npos) {
    +
    141  codec.erase(dot);
    +
    142  }
    +
    143  return codec;
    +
    144 }
    +
    145 
    +
    146 std::string GetAdaptationSetKey(const MediaInfo& media_info,
    +
    147  bool ignore_codec) {
    +
    148  std::string key;
    +
    149 
    +
    150  if (media_info.has_video_info()) {
    +
    151  key.append("video:");
    +
    152  } else if (media_info.has_audio_info()) {
    +
    153  key.append("audio:");
    +
    154  } else if (media_info.has_text_info()) {
    +
    155  key.append(MediaInfo_TextInfo_TextType_Name(media_info.text_info().type()));
    +
    156  key.append(":");
    +
    157  } else {
    +
    158  key.append("unknown:");
    +
    159  }
    +
    160 
    +
    161  key.append(MediaInfo_ContainerType_Name(media_info.container_type()));
    +
    162  if (!ignore_codec) {
    +
    163  key.append(":");
    +
    164  key.append(GetBaseCodec(media_info));
    +
    165  }
    +
    166  key.append(":");
    +
    167  key.append(GetLanguage(media_info));
    +
    168 
    +
    169  // Trick play streams of the same original stream, but possibly with
    +
    170  // different trick_play_factors, belong to the same trick play AdaptationSet.
    +
    171  if (media_info.video_info().has_playback_rate()) {
    +
    172  key.append(":trick_play");
    +
    173  }
    +
    174 
    +
    175  if (!media_info.dash_accessibilities().empty()) {
    +
    176  key.append(":accessibility_");
    +
    177  for (const std::string& accessibility : media_info.dash_accessibilities())
    +
    178  key.append(accessibility);
    +
    179  }
    +
    180 
    +
    181  if (!media_info.dash_roles().empty()) {
    +
    182  key.append(":roles_");
    +
    183  for (const std::string& role : media_info.dash_roles())
    +
    184  key.append(role);
    +
    185  }
    +
    186 
    +
    187  return key;
    +
    188 }
    +
    189 
    +
    190 std::string SecondsToXmlDuration(double seconds) {
    +
    191  // Chrome internally uses time accurate to microseconds, which is implemented
    +
    192  // per MSE spec (https://www.w3.org/TR/media-source/).
    +
    193  // We need a string formatter that has at least microseconds accuracy for a
    +
    194  // normal video (with duration up to 3 hours). Chrome's DoubleToString
    +
    195  // implementation meets the requirement.
    +
    196  return "PT" + base::DoubleToString(seconds) + "S";
    +
    197 }
    +
    198 
    +
    199 bool GetDurationAttribute(xmlNodePtr node, float* duration) {
    +
    200  DCHECK(node);
    +
    201  DCHECK(duration);
    +
    202  static const char kDuration[] = "duration";
    +
    203  xml::scoped_xml_ptr<xmlChar> duration_value(
    +
    204  xmlGetProp(node, BAD_CAST kDuration));
    +
    205 
    +
    206  if (!duration_value)
    +
    207  return false;
    +
    208 
    +
    209  double duration_double_precision = 0.0;
    +
    210  if (!base::StringToDouble(reinterpret_cast<const char*>(duration_value.get()),
    +
    211  &duration_double_precision)) {
    +
    212  return false;
    +
    213  }
    +
    214 
    +
    215  *duration = static_cast<float>(duration_double_precision);
    +
    216  return true;
    +
    217 }
    +
    218 
    +
    219 bool MoreThanOneTrue(bool b1, bool b2, bool b3) {
    +
    220  return (b1 && b2) || (b2 && b3) || (b3 && b1);
    +
    221 }
    +
    222 
    +
    223 bool AtLeastOneTrue(bool b1, bool b2, bool b3) {
    +
    224  return b1 || b2 || b3;
    +
    225 }
    +
    226 
    +
    227 bool OnlyOneTrue(bool b1, bool b2, bool b3) {
    +
    228  return !MoreThanOneTrue(b1, b2, b3) && AtLeastOneTrue(b1, b2, b3);
    +
    229 }
    +
    230 
    +
    231 // Coverts binary data into human readable UUID format.
    +
    232 bool HexToUUID(const std::string& data, std::string* uuid_format) {
    +
    233  DCHECK(uuid_format);
    +
    234  const size_t kExpectedUUIDSize = 16;
    +
    235  if (data.size() != kExpectedUUIDSize) {
    +
    236  LOG(ERROR) << "UUID size is expected to be " << kExpectedUUIDSize
    +
    237  << " but is " << data.size() << " and the data in hex is "
    +
    238  << base::HexEncode(data.data(), data.size());
    +
    239  return false;
    +
    240  }
    +
    241 
    +
    242  const std::string hex_encoded =
    +
    243  base::ToLowerASCII(base::HexEncode(data.data(), data.size()));
    +
    244  DCHECK_EQ(hex_encoded.size(), kExpectedUUIDSize * 2);
    +
    245  base::StringPiece all(hex_encoded);
    +
    246  // Note UUID has 5 parts separated with dashes.
    +
    247  // e.g. 123e4567-e89b-12d3-a456-426655440000
    +
    248  // These StringPieces have each part.
    +
    249  base::StringPiece first = all.substr(0, 8);
    +
    250  base::StringPiece second = all.substr(8, 4);
    +
    251  base::StringPiece third = all.substr(12, 4);
    +
    252  base::StringPiece fourth = all.substr(16, 4);
    +
    253  base::StringPiece fifth = all.substr(20, 12);
    +
    254 
    +
    255  // 32 hexadecimal characters with 4 hyphens.
    +
    256  const size_t kHumanReadableUUIDSize = 36;
    +
    257  uuid_format->reserve(kHumanReadableUUIDSize);
    +
    258  first.CopyToString(uuid_format);
    +
    259  uuid_format->append("-");
    +
    260  second.AppendToString(uuid_format);
    +
    261  uuid_format->append("-");
    +
    262  third.AppendToString(uuid_format);
    +
    263  uuid_format->append("-");
    +
    264  fourth.AppendToString(uuid_format);
    +
    265  uuid_format->append("-");
    +
    266  fifth.AppendToString(uuid_format);
    +
    267  return true;
    +
    268 }
    +
    269 
    +
    270 void UpdateContentProtectionPsshHelper(
    +
    271  const std::string& drm_uuid,
    +
    272  const std::string& pssh,
    +
    273  std::list<ContentProtectionElement>* content_protection_elements) {
    +
    274  const std::string drm_uuid_schemd_id_uri_form = "urn:uuid:" + drm_uuid;
    +
    275  for (std::list<ContentProtectionElement>::iterator protection =
    +
    276  content_protection_elements->begin();
    +
    277  protection != content_protection_elements->end(); ++protection) {
    +
    278  if (protection->scheme_id_uri != drm_uuid_schemd_id_uri_form) {
    +
    279  continue;
    +
    280  }
    +
    281 
    +
    282  for (std::vector<Element>::iterator subelement =
    +
    283  protection->subelements.begin();
    +
    284  subelement != protection->subelements.end(); ++subelement) {
    +
    285  if (subelement->name == kPsshElementName) {
    +
    286  // For now, we want to remove the PSSH element because some players do
    +
    287  // not support updating pssh.
    +
    288  protection->subelements.erase(subelement);
    +
    289 
    +
    290  // TODO(rkuroiwa): Uncomment this and remove the line above when
    +
    291  // shaka-player supports updating PSSH.
    +
    292  // subelement->content = pssh;
    +
    293  return;
    +
    294  }
    +
    295  }
    +
    296 
    +
    297  // Reaching here means <cenc:pssh> does not exist under the
    +
    298  // ContentProtection element. Add it.
    +
    299  // TODO(rkuroiwa): Uncomment this when shaka-player supports updating PSSH.
    +
    300  // Element cenc_pssh;
    +
    301  // cenc_pssh.name = kPsshElementName;
    +
    302  // cenc_pssh.content = pssh;
    +
    303  // protection->subelements.push_back(cenc_pssh);
    +
    304  return;
    +
    305  }
    +
    306 
    +
    307  // Reaching here means that ContentProtection for the DRM does not exist.
    +
    308  // Add it.
    +
    309  ContentProtectionElement content_protection;
    +
    310  content_protection.scheme_id_uri = drm_uuid_schemd_id_uri_form;
    +
    311  // TODO(rkuroiwa): Uncomment this when shaka-player supports updating PSSH.
    +
    312  // Element cenc_pssh;
    +
    313  // cenc_pssh.name = kPsshElementName;
    +
    314  // cenc_pssh.content = pssh;
    +
    315  // content_protection.subelements.push_back(cenc_pssh);
    +
    316  content_protection_elements->push_back(content_protection);
    +
    317  return;
    +
    318 }
    +
    319 
    +
    320 namespace {
    +
    321 
    +
    322 // UUID for Marlin Adaptive Streaming Specification – Simple Profile from
    +
    323 // https://dashif.org/identifiers/content_protection/.
    +
    324 const char kMarlinUUID[] = "5e629af5-38da-4063-8977-97ffbd9902d4";
    +
    325 // Unofficial FairPlay system id extracted from
    +
    326 // https://forums.developer.apple.com/thread/6185.
    +
    327 const char kFairPlayUUID[] = "29701fe4-3cc7-4a34-8c5b-ae90c7439a47";
    +
    328 // String representation of media::kPlayReadySystemId.
    +
    329 const char kPlayReadyUUID[] = "9a04f079-9840-4286-ab92-e65be0885f95";
    +
    330 // It is RECOMMENDED to include the @value attribute with name and version "MSPR 2.0".
    +
    331 // See https://docs.microsoft.com/en-us/playready/specifications/mpeg-dash-playready#221-general.
    +
    332 const char kContentProtectionValueMSPR20[] = "MSPR 2.0";
    +
    333 
    +
    334 Element GenerateMarlinContentIds(const std::string& key_id) {
    +
    335  // See https://github.com/google/shaka-packager/issues/381 for details.
    +
    336  static const char kMarlinContentIdName[] = "mas:MarlinContentId";
    +
    337  static const char kMarlinContentIdPrefix[] = "urn:marlin:kid:";
    +
    338  static const char kMarlinContentIdsName[] = "mas:MarlinContentIds";
    +
    339 
    +
    340  Element marlin_content_id;
    +
    341  marlin_content_id.name = kMarlinContentIdName;
    +
    342  marlin_content_id.content =
    +
    343  kMarlinContentIdPrefix +
    +
    344  base::ToLowerASCII(base::HexEncode(key_id.data(), key_id.size()));
    +
    345 
    +
    346  Element marlin_content_ids;
    +
    347  marlin_content_ids.name = kMarlinContentIdsName;
    +
    348  marlin_content_ids.subelements.push_back(marlin_content_id);
    +
    349 
    +
    350  return marlin_content_ids;
    +
    351 }
    +
    352 
    +
    353 Element GenerateCencPsshElement(const std::string& pssh) {
    +
    354  std::string base64_encoded_pssh;
    +
    355  base::Base64Encode(base::StringPiece(pssh.data(), pssh.size()),
    +
    356  &base64_encoded_pssh);
    +
    357  Element cenc_pssh;
    +
    358  cenc_pssh.name = kPsshElementName;
    +
    359  cenc_pssh.content = base64_encoded_pssh;
    +
    360  return cenc_pssh;
    +
    361 }
    +
    362 
    +
    363 // Extract MS PlayReady Object from given PSSH
    +
    364 // and encode it in base64.
    +
    365 Element GenerateMsprProElement(const std::string& pssh) {
    +
    366  std::unique_ptr<media::PsshBoxBuilder> b =
    + +
    368  reinterpret_cast<const uint8_t*>(pssh.data()),
    +
    369  pssh.size()
    +
    370  );
    +
    371 
    +
    372  const std::vector<uint8_t> *p_pssh = &b->pssh_data();
    +
    373  std::string base64_encoded_mspr;
    +
    374  base::Base64Encode(
    +
    375  base::StringPiece(
    +
    376  reinterpret_cast<const char*>(p_pssh->data()),
    +
    377  p_pssh->size()),
    +
    378  &base64_encoded_mspr
    +
    379  );
    +
    380  Element mspr_pro;
    +
    381  mspr_pro.name = kMsproElementName;
    +
    382  mspr_pro.content = base64_encoded_mspr;
    +
    383  return mspr_pro;
    +
    384 }
    +
    385 
    +
    386 // Helper function. This works because Representation and AdaptationSet both
    +
    387 // have AddContentProtectionElement().
    +
    388 template <typename ContentProtectionParent>
    +
    389 void AddContentProtectionElementsHelperTemplated(
    +
    390  const MediaInfo& media_info,
    +
    391  ContentProtectionParent* parent) {
    +
    392  DCHECK(parent);
    +
    393  if (!media_info.has_protected_content())
    +
    394  return;
    +
    395 
    +
    396  const MediaInfo::ProtectedContent& protected_content =
    +
    397  media_info.protected_content();
    +
    398 
    +
    399  // DASH MPD spec specifies a default ContentProtection element for ISO BMFF
    +
    400  // (MP4) files.
    +
    401  const bool is_mp4_container =
    +
    402  media_info.container_type() == MediaInfo::CONTAINER_MP4;
    +
    403  std::string key_id_uuid_format;
    +
    404  if (protected_content.has_default_key_id() &&
    +
    405  !IsKeyRotationDefaultKeyId(protected_content.default_key_id())) {
    +
    406  if (!HexToUUID(protected_content.default_key_id(), &key_id_uuid_format)) {
    +
    407  LOG(ERROR) << "Failed to convert default key ID into UUID format.";
    +
    408  }
    +
    409  }
    +
    410 
    +
    411  if (is_mp4_container) {
    +
    412  ContentProtectionElement mp4_content_protection;
    +
    413  mp4_content_protection.scheme_id_uri = kEncryptedMp4Scheme;
    +
    414  mp4_content_protection.value = protected_content.protection_scheme();
    +
    415  if (!key_id_uuid_format.empty()) {
    +
    416  mp4_content_protection.additional_attributes["cenc:default_KID"] =
    +
    417  key_id_uuid_format;
    +
    418  }
    +
    419 
    +
    420  parent->AddContentProtectionElement(mp4_content_protection);
    +
    421  }
    +
    422 
    +
    423  for (const auto& entry : protected_content.content_protection_entry()) {
    +
    424  if (!entry.has_uuid()) {
    +
    425  LOG(WARNING)
    +
    426  << "ContentProtectionEntry was specified but no UUID is set for "
    +
    427  << entry.name_version() << ", skipping.";
    +
    428  continue;
    +
    429  }
    +
    430 
    +
    431  ContentProtectionElement drm_content_protection;
    +
    432 
    +
    433  if (entry.has_name_version())
    +
    434  drm_content_protection.value = entry.name_version();
    +
    435 
    +
    436  if (entry.uuid() == kFairPlayUUID) {
    +
    437  VLOG(1) << "Skipping FairPlay ContentProtection element as FairPlay does "
    +
    438  "not support DASH signaling.";
    +
    439  continue;
    +
    440  } else if (entry.uuid() == kMarlinUUID) {
    +
    441  // Marlin requires its uuid to be in upper case. See #525 for details.
    +
    442  drm_content_protection.scheme_id_uri =
    +
    443  "urn:uuid:" + base::ToUpperASCII(entry.uuid());
    +
    444  drm_content_protection.subelements.push_back(
    +
    445  GenerateMarlinContentIds(protected_content.default_key_id()));
    +
    446  } else {
    +
    447  drm_content_protection.scheme_id_uri = "urn:uuid:" + entry.uuid();
    +
    448  if (!entry.pssh().empty()) {
    +
    449  drm_content_protection.subelements.push_back(
    +
    450  GenerateCencPsshElement(entry.pssh()));
    +
    451  if(entry.uuid() == kPlayReadyUUID && protected_content.include_mspr_pro()) {
    +
    452  drm_content_protection.subelements.push_back(
    +
    453  GenerateMsprProElement(entry.pssh()));
    +
    454  drm_content_protection.value = kContentProtectionValueMSPR20;
    +
    455  }
    +
    456  }
    +
    457  }
    +
    458 
    +
    459  if (!key_id_uuid_format.empty() && !is_mp4_container) {
    +
    460  drm_content_protection.additional_attributes["cenc:default_KID"] =
    +
    461  key_id_uuid_format;
    +
    462  }
    +
    463 
    +
    464  parent->AddContentProtectionElement(drm_content_protection);
    +
    465  }
    +
    466 
    +
    467  VLOG_IF(1, protected_content.content_protection_entry().size() == 0)
    +
    468  << "The media is encrypted but no content protection specified (can "
    +
    469  "happen with key rotation).";
    +
    470 }
    +
    471 } // namespace
    +
    472 
    +
    473 void AddContentProtectionElements(const MediaInfo& media_info,
    +
    474  Representation* parent) {
    +
    475  AddContentProtectionElementsHelperTemplated(media_info, parent);
    +
    476 }
    +
    477 
    +
    478 void AddContentProtectionElements(const MediaInfo& media_info,
    +
    479  AdaptationSet* parent) {
    +
    480  AddContentProtectionElementsHelperTemplated(media_info, parent);
    +
    481 }
    +
    482 
    +
    483 } // namespace shaka
    + + +
    static std::unique_ptr< PsshBoxBuilder > ParseFromBox(const uint8_t *data, size_t data_size)
    +
    All the methods that are virtual are virtual for mocking.
    +
    bool HexToUUID(const std::string &data, std::string *uuid_format)
    Definition: mpd_utils.cc:232
    +
    std::string LanguageToShortestForm(const std::string &language)
    +
    void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
    Definition: mpd_utils.cc:473
    diff --git a/docs/db/dfc/mpd__notify__muxer__listener_8cc_source.html b/docs/db/dfc/mpd__notify__muxer__listener_8cc_source.html index 2c142886f0..12ce3cbffd 100644 --- a/docs/db/dfc/mpd__notify__muxer__listener_8cc_source.html +++ b/docs/db/dfc/mpd__notify__muxer__listener_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/mpd_notify_muxer_listener.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mpd_notify_muxer_listener.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/event/mpd_notify_muxer_listener.h"
    8 
    9 #include <cmath>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/media/base/audio_stream_info.h"
    13 #include "packager/media/base/protection_system_specific_info.h"
    14 #include "packager/media/base/video_stream_info.h"
    15 #include "packager/media/event/muxer_listener_internal.h"
    16 #include "packager/mpd/base/media_info.pb.h"
    17 #include "packager/mpd/base/mpd_notifier.h"
    18 
    19 namespace shaka {
    20 namespace media {
    21 
    23  : mpd_notifier_(mpd_notifier), is_encrypted_(false) {
    24  DCHECK(mpd_notifier);
    25  DCHECK(mpd_notifier->dash_profile() == DashProfile::kOnDemand ||
    26  mpd_notifier->dash_profile() == DashProfile::kLive);
    27 }
    28 
    29 MpdNotifyMuxerListener::~MpdNotifyMuxerListener() {}
    30 
    32  bool is_initial_encryption_info,
    33  FourCC protection_scheme,
    34  const std::vector<uint8_t>& key_id,
    35  const std::vector<uint8_t>& iv,
    36  const std::vector<ProtectionSystemSpecificInfo>& key_system_info) {
    37  if (is_initial_encryption_info) {
    38  LOG_IF(WARNING, is_encrypted_)
    39  << "Updating initial encryption information.";
    40  protection_scheme_ = protection_scheme;
    41  default_key_id_ = key_id;
    42  key_system_info_ = key_system_info;
    43  is_encrypted_ = true;
    44  return;
    45  }
    46  if (!notification_id_)
    47  return;
    48  DCHECK_EQ(protection_scheme, protection_scheme_);
    49 
    50  for (const ProtectionSystemSpecificInfo& info : key_system_info) {
    51  const std::string drm_uuid = internal::CreateUUIDString(info.system_id);
    52  bool updated = mpd_notifier_->NotifyEncryptionUpdate(
    53  notification_id_.value(), drm_uuid, key_id, info.psshs);
    54  LOG_IF(WARNING, !updated) << "Failed to update encryption info.";
    55  }
    56 }
    57 
    59 
    61  const MuxerOptions& muxer_options,
    62  const StreamInfo& stream_info,
    63  uint32_t time_scale,
    64  ContainerType container_type) {
    65  std::unique_ptr<MediaInfo> media_info(new MediaInfo());
    66  if (!internal::GenerateMediaInfo(muxer_options,
    67  stream_info,
    68  time_scale,
    69  container_type,
    70  media_info.get())) {
    71  LOG(ERROR) << "Failed to generate MediaInfo from input.";
    72  return;
    73  }
    74  for (const std::string& accessibility : accessibilities_)
    75  media_info->add_dash_accessibilities(accessibility);
    76  for (const std::string& role : roles_)
    77  media_info->add_dash_roles(role);
    78 
    79  if (is_encrypted_) {
    80  internal::SetContentProtectionFields(protection_scheme_, default_key_id_,
    81  key_system_info_, media_info.get());
    82  }
    83 
    84  // The content may be splitted into multiple files, but their MediaInfo
    85  // should be compatible.
    86  if (media_info_ &&
    87  !internal::IsMediaInfoCompatible(*media_info, *media_info_)) {
    88  LOG(WARNING) << "Incompatible MediaInfo \n"
    89  << media_info->ShortDebugString() << "\n vs \n"
    90  << media_info_->ShortDebugString()
    91  << "\nThe result manifest may not be playable.";
    92  }
    93  media_info_ = std::move(media_info);
    94 
    95  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    96  if (!NotifyNewContainer())
    97  return;
    98  DCHECK(notification_id_);
    99  }
    100 }
    101 
    102 // Record the sample duration in the media info for VOD so that OnMediaEnd, all
    103 // the information is in the media info.
    105  uint32_t sample_duration) {
    106  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    107  mpd_notifier_->NotifySampleDuration(notification_id_.value(),
    108  sample_duration);
    109  return;
    110  }
    111 
    112  if (!media_info_) {
    113  LOG(WARNING) << "Got sample duration " << sample_duration
    114  << " but no media was specified.";
    115  return;
    116  }
    117  if (!media_info_->has_video_info()) {
    118  // If non video, don't worry about it (at the moment).
    119  return;
    120  }
    121 
    122  media_info_->mutable_video_info()->set_frame_duration(sample_duration);
    123 }
    124 
    126  float duration_seconds) {
    127  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    128  DCHECK(event_info_.empty());
    129  // TODO(kqyang): Set mpd duration to |duration_seconds|, which is more
    130  // accurate than the duration coded in the original media header.
    131  if (mpd_notifier_->mpd_type() == MpdType::kStatic)
    132  mpd_notifier_->Flush();
    133  return;
    134  }
    135 
    136  DCHECK(media_info_);
    137  if (!internal::SetVodInformation(media_ranges, duration_seconds,
    138  media_info_.get())) {
    139  LOG(ERROR) << "Failed to generate VOD information from input.";
    140  return;
    141  }
    142 
    143  if (notification_id_) {
    144  mpd_notifier_->NotifyMediaInfoUpdate(notification_id_.value(),
    145  *media_info_);
    146  } else {
    147  if (!NotifyNewContainer())
    148  return;
    149  DCHECK(notification_id_);
    150  }
    151  // TODO(rkuroiwa): Use media_ranges.subsegment_ranges instead of caching the
    152  // subsegments.
    153  for (const auto& event_info : event_info_) {
    154  switch (event_info.type) {
    155  case EventInfoType::kSegment:
    156  mpd_notifier_->NotifyNewSegment(
    157  notification_id_.value(), event_info.segment_info.start_time,
    158  event_info.segment_info.duration,
    159  event_info.segment_info.segment_file_size);
    160  break;
    161  case EventInfoType::kKeyFrame:
    162  // NO-OP for DASH.
    163  break;
    164  case EventInfoType::kCue:
    165  mpd_notifier_->NotifyCueEvent(notification_id_.value(),
    166  event_info.cue_event_info.timestamp);
    167  break;
    168  }
    169  }
    170  event_info_.clear();
    171  mpd_notifier_->Flush();
    172 }
    173 
    174 void MpdNotifyMuxerListener::OnNewSegment(const std::string& file_name,
    175  int64_t start_time,
    176  int64_t duration,
    177  uint64_t segment_file_size) {
    178  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    179  mpd_notifier_->NotifyNewSegment(notification_id_.value(), start_time,
    180  duration, segment_file_size);
    181  if (mpd_notifier_->mpd_type() == MpdType::kDynamic)
    182  mpd_notifier_->Flush();
    183  } else {
    184  EventInfo event_info;
    185  event_info.type = EventInfoType::kSegment;
    186  event_info.segment_info = {start_time, duration, segment_file_size};
    187  event_info_.push_back(event_info);
    188  }
    189 }
    190 
    191 void MpdNotifyMuxerListener::OnKeyFrame(int64_t timestamp,
    192  uint64_t start_byte_offset,
    193  uint64_t size) {
    194  // NO-OP for DASH.
    195 }
    196 
    197 void MpdNotifyMuxerListener::OnCueEvent(int64_t timestamp,
    198  const std::string& cue_data) {
    199  // Not using |cue_data| at this moment.
    200  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    201  mpd_notifier_->NotifyCueEvent(notification_id_.value(), timestamp);
    202  } else {
    203  EventInfo event_info;
    204  event_info.type = EventInfoType::kCue;
    205  event_info.cue_event_info = {timestamp};
    206  event_info_.push_back(event_info);
    207  }
    208 }
    209 
    210 bool MpdNotifyMuxerListener::NotifyNewContainer() {
    211  uint32_t notification_id;
    212  if (!mpd_notifier_->NotifyNewContainer(*media_info_, &notification_id)) {
    213  LOG(ERROR) << "Failed to notify MpdNotifier.";
    214  return false;
    215  }
    216  notification_id_ = notification_id;
    217  return true;
    218 }
    219 
    220 } // namespace media
    221 } // namespace shaka
    virtual bool Flush()=0
    -
    MpdType mpd_type() const
    Definition: mpd_notifier.h:111
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    virtual bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0
    -
    DashProfile dash_profile() const
    Definition: mpd_notifier.h:108
    - -
    void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    -
    virtual bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    -
    virtual bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0
    -
    void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
    -
    void OnSampleDurationReady(uint32_t sample_duration) override
    - -
    void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
    -
    MpdNotifyMuxerListener(MpdNotifier *mpd_notifier)
    - -
    virtual bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0
    -
    virtual bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0
    - -
    virtual bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0
    -
    void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
    - -
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    -
    void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/event/mpd_notify_muxer_listener.h"
    +
    8 
    +
    9 #include <cmath>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/audio_stream_info.h"
    +
    13 #include "packager/media/base/protection_system_specific_info.h"
    +
    14 #include "packager/media/base/video_stream_info.h"
    +
    15 #include "packager/media/event/muxer_listener_internal.h"
    +
    16 #include "packager/mpd/base/media_info.pb.h"
    +
    17 #include "packager/mpd/base/mpd_notifier.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 
    + +
    23  : mpd_notifier_(mpd_notifier), is_encrypted_(false) {
    +
    24  DCHECK(mpd_notifier);
    +
    25  DCHECK(mpd_notifier->dash_profile() == DashProfile::kOnDemand ||
    +
    26  mpd_notifier->dash_profile() == DashProfile::kLive);
    +
    27 }
    +
    28 
    +
    29 MpdNotifyMuxerListener::~MpdNotifyMuxerListener() {}
    +
    30 
    + +
    32  bool is_initial_encryption_info,
    +
    33  FourCC protection_scheme,
    +
    34  const std::vector<uint8_t>& key_id,
    +
    35  const std::vector<uint8_t>& iv,
    +
    36  const std::vector<ProtectionSystemSpecificInfo>& key_system_info) {
    +
    37  if (is_initial_encryption_info) {
    +
    38  LOG_IF(WARNING, is_encrypted_)
    +
    39  << "Updating initial encryption information.";
    +
    40  protection_scheme_ = protection_scheme;
    +
    41  default_key_id_ = key_id;
    +
    42  key_system_info_ = key_system_info;
    +
    43  is_encrypted_ = true;
    +
    44  return;
    +
    45  }
    +
    46  if (!notification_id_)
    +
    47  return;
    +
    48  DCHECK_EQ(protection_scheme, protection_scheme_);
    +
    49 
    +
    50  for (const ProtectionSystemSpecificInfo& info : key_system_info) {
    +
    51  const std::string drm_uuid = internal::CreateUUIDString(info.system_id);
    +
    52  bool updated = mpd_notifier_->NotifyEncryptionUpdate(
    +
    53  notification_id_.value(), drm_uuid, key_id, info.psshs);
    +
    54  LOG_IF(WARNING, !updated) << "Failed to update encryption info.";
    +
    55  }
    +
    56 }
    +
    57 
    + +
    59 
    + +
    61  const MuxerOptions& muxer_options,
    +
    62  const StreamInfo& stream_info,
    +
    63  uint32_t time_scale,
    +
    64  ContainerType container_type) {
    +
    65  std::unique_ptr<MediaInfo> media_info(new MediaInfo());
    +
    66  if (!internal::GenerateMediaInfo(muxer_options,
    +
    67  stream_info,
    +
    68  time_scale,
    +
    69  container_type,
    +
    70  media_info.get())) {
    +
    71  LOG(ERROR) << "Failed to generate MediaInfo from input.";
    +
    72  return;
    +
    73  }
    +
    74  for (const std::string& accessibility : accessibilities_)
    +
    75  media_info->add_dash_accessibilities(accessibility);
    +
    76  if (roles_.empty() && stream_info.stream_type() == kStreamText) {
    +
    77  // If there aren't any roles, default to "subtitle" since some apps may
    +
    78  // require it to distinguish between subtitle/caption.
    +
    79  media_info->add_dash_roles("subtitle");
    +
    80  } else {
    +
    81  for (const std::string& role : roles_)
    +
    82  media_info->add_dash_roles(role);
    +
    83  }
    +
    84 
    +
    85  if (is_encrypted_) {
    +
    86  internal::SetContentProtectionFields(protection_scheme_, default_key_id_,
    +
    87  key_system_info_, media_info.get());
    +
    88  media_info->mutable_protected_content()->set_include_mspr_pro(mpd_notifier_->include_mspr_pro());
    +
    89  }
    +
    90 
    +
    91  // The content may be splitted into multiple files, but their MediaInfo
    +
    92  // should be compatible.
    +
    93  if (media_info_ &&
    +
    94  !internal::IsMediaInfoCompatible(*media_info, *media_info_)) {
    +
    95  LOG(WARNING) << "Incompatible MediaInfo \n"
    +
    96  << media_info->ShortDebugString() << "\n vs \n"
    +
    97  << media_info_->ShortDebugString()
    +
    98  << "\nThe result manifest may not be playable.";
    +
    99  }
    +
    100  media_info_ = std::move(media_info);
    +
    101 
    +
    102  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    +
    103  if (!NotifyNewContainer())
    +
    104  return;
    +
    105  DCHECK(notification_id_);
    +
    106  }
    +
    107 }
    +
    108 
    +
    109 // Record the sample duration in the media info for VOD so that OnMediaEnd, all
    +
    110 // the information is in the media info.
    + +
    112  uint32_t sample_duration) {
    +
    113  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    +
    114  mpd_notifier_->NotifySampleDuration(notification_id_.value(),
    +
    115  sample_duration);
    +
    116  return;
    +
    117  }
    +
    118 
    +
    119  if (!media_info_) {
    +
    120  LOG(WARNING) << "Got sample duration " << sample_duration
    +
    121  << " but no media was specified.";
    +
    122  return;
    +
    123  }
    +
    124  if (!media_info_->has_video_info()) {
    +
    125  // If non video, don't worry about it (at the moment).
    +
    126  return;
    +
    127  }
    +
    128 
    +
    129  media_info_->mutable_video_info()->set_frame_duration(sample_duration);
    +
    130 }
    +
    131 
    + +
    133  float duration_seconds) {
    +
    134  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    +
    135  DCHECK(event_info_.empty());
    +
    136  // TODO(kqyang): Set mpd duration to |duration_seconds|, which is more
    +
    137  // accurate than the duration coded in the original media header.
    +
    138  if (mpd_notifier_->mpd_type() == MpdType::kStatic)
    +
    139  mpd_notifier_->Flush();
    +
    140  return;
    +
    141  }
    +
    142 
    +
    143  DCHECK(media_info_);
    +
    144  if (!internal::SetVodInformation(media_ranges, duration_seconds,
    +
    145  media_info_.get())) {
    +
    146  LOG(ERROR) << "Failed to generate VOD information from input.";
    +
    147  return;
    +
    148  }
    +
    149 
    +
    150  if (notification_id_) {
    +
    151  mpd_notifier_->NotifyMediaInfoUpdate(notification_id_.value(),
    +
    152  *media_info_);
    +
    153  } else {
    +
    154  if (!NotifyNewContainer())
    +
    155  return;
    +
    156  DCHECK(notification_id_);
    +
    157  }
    +
    158  // TODO(rkuroiwa): Use media_ranges.subsegment_ranges instead of caching the
    +
    159  // subsegments.
    +
    160  for (const auto& event_info : event_info_) {
    +
    161  switch (event_info.type) {
    +
    162  case EventInfoType::kSegment:
    +
    163  mpd_notifier_->NotifyNewSegment(
    +
    164  notification_id_.value(), event_info.segment_info.start_time,
    +
    165  event_info.segment_info.duration,
    +
    166  event_info.segment_info.segment_file_size);
    +
    167  break;
    +
    168  case EventInfoType::kKeyFrame:
    +
    169  // NO-OP for DASH.
    +
    170  break;
    +
    171  case EventInfoType::kCue:
    +
    172  mpd_notifier_->NotifyCueEvent(notification_id_.value(),
    +
    173  event_info.cue_event_info.timestamp);
    +
    174  break;
    +
    175  }
    +
    176  }
    +
    177  event_info_.clear();
    +
    178  mpd_notifier_->Flush();
    +
    179 }
    +
    180 
    +
    181 void MpdNotifyMuxerListener::OnNewSegment(const std::string& file_name,
    +
    182  int64_t start_time,
    +
    183  int64_t duration,
    +
    184  uint64_t segment_file_size) {
    +
    185  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    +
    186  mpd_notifier_->NotifyNewSegment(notification_id_.value(), start_time,
    +
    187  duration, segment_file_size);
    +
    188  if (mpd_notifier_->mpd_type() == MpdType::kDynamic)
    +
    189  mpd_notifier_->Flush();
    +
    190  } else {
    +
    191  EventInfo event_info;
    +
    192  event_info.type = EventInfoType::kSegment;
    +
    193  event_info.segment_info = {start_time, duration, segment_file_size};
    +
    194  event_info_.push_back(event_info);
    +
    195  }
    +
    196 }
    +
    197 
    +
    198 void MpdNotifyMuxerListener::OnKeyFrame(int64_t timestamp,
    +
    199  uint64_t start_byte_offset,
    +
    200  uint64_t size) {
    +
    201  // NO-OP for DASH.
    +
    202 }
    +
    203 
    +
    204 void MpdNotifyMuxerListener::OnCueEvent(int64_t timestamp,
    +
    205  const std::string& cue_data) {
    +
    206  // Not using |cue_data| at this moment.
    +
    207  if (mpd_notifier_->dash_profile() == DashProfile::kLive) {
    +
    208  mpd_notifier_->NotifyCueEvent(notification_id_.value(), timestamp);
    +
    209  } else {
    +
    210  EventInfo event_info;
    +
    211  event_info.type = EventInfoType::kCue;
    +
    212  event_info.cue_event_info = {timestamp};
    +
    213  event_info_.push_back(event_info);
    +
    214  }
    +
    215 }
    +
    216 
    +
    217 bool MpdNotifyMuxerListener::NotifyNewContainer() {
    +
    218  uint32_t notification_id;
    +
    219  if (!mpd_notifier_->NotifyNewContainer(*media_info_, &notification_id)) {
    +
    220  LOG(ERROR) << "Failed to notify MpdNotifier.";
    +
    221  return false;
    +
    222  }
    +
    223  notification_id_ = notification_id;
    +
    224  return true;
    +
    225 }
    +
    226 
    +
    227 } // namespace media
    +
    228 } // namespace shaka
    + +
    MpdType mpd_type() const
    Definition: mpd_notifier.h:114
    +
    virtual bool NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0
    +
    DashProfile dash_profile() const
    Definition: mpd_notifier.h:111
    +
    virtual bool NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0
    +
    virtual bool NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0
    +
    virtual bool NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0
    +
    virtual bool NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0
    +
    virtual bool NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0
    +
    bool include_mspr_pro() const
    Definition: mpd_notifier.h:108
    +
    virtual bool Flush()=0
    +
    void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
    +
    void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
    +
    void OnSampleDurationReady(uint32_t sample_duration) override
    + +
    void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
    +
    MpdNotifyMuxerListener(MpdNotifier *mpd_notifier)
    +
    void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
    +
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    +
    void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    + + +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    diff --git a/docs/db/dff/structshaka_1_1media_1_1mp4_1_1ChunkInfo-members.html b/docs/db/dff/structshaka_1_1media_1_1mp4_1_1ChunkInfo-members.html index 657263200a..640b6f7732 100644 --- a/docs/db/dff/structshaka_1_1media_1_1mp4_1_1ChunkInfo-members.html +++ b/docs/db/dff/structshaka_1_1media_1_1mp4_1_1ChunkInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/db/dff/webvtt__file__buffer_8h_source.html b/docs/db/dff/webvtt__file__buffer_8h_source.html index ff42a553e1..cd88531fbf 100644 --- a/docs/db/dff/webvtt__file__buffer_8h_source.html +++ b/docs/db/dff/webvtt__file__buffer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/webvtt_file_buffer.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webvtt_file_buffer.h
    -
    1 // Copyright 2018 Google LLC All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_FILE_BUFFER_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_FILE_BUFFER_H_
    9 
    10 #include <string>
    11 
    12 #include "packager/file/file.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 class TextSample;
    18 
    19 // A class to abstract writing a webvtt file to disk. This class will handle
    20 // all the formatting requirements for a webvtt file.
    22  public:
    23  WebVttFileBuffer(uint32_t transport_stream_timestamp_offset_ms,
    24  const std::string& style_region_config);
    25  virtual ~WebVttFileBuffer() = default;
    26 
    27  void Reset();
    28  void Append(const TextSample& sample);
    29 
    30  bool WriteTo(File* file);
    31 
    32  // Get the number of samples that have been appended to this file.
    33  size_t sample_count() const { return sample_count_; }
    34 
    35  private:
    36  WebVttFileBuffer(const WebVttFileBuffer&) = delete;
    37  WebVttFileBuffer& operator=(const WebVttFileBuffer&) = delete;
    38 
    39  const uint32_t transport_stream_timestamp_offset_ = 0;
    40  const std::string style_region_config_;
    41  std::string buffer_;
    42  size_t sample_count_ = 0;
    43 };
    44 
    45 } // namespace media
    46 } // namespace shaka
    47 
    48 #endif // PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_FILE_BUFFER_H_
    Define an abstract file interface.
    Definition: file.h:26
    -
    All the methods that are virtual are virtual for mocking.
    - - +
    1 // Copyright 2018 Google LLC All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_FILE_BUFFER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_FILE_BUFFER_H_
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 #include "packager/file/file.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 class TextSample;
    +
    18 
    +
    19 // A class to abstract writing a webvtt file to disk. This class will handle
    +
    20 // all the formatting requirements for a webvtt file.
    + +
    22  public:
    +
    23  WebVttFileBuffer(uint32_t transport_stream_timestamp_offset_ms,
    +
    24  const std::string& style_region_config);
    +
    25  virtual ~WebVttFileBuffer() = default;
    +
    26 
    +
    27  void Reset();
    +
    28  void Append(const TextSample& sample);
    +
    29 
    +
    30  bool WriteTo(File* file, uint64_t* size);
    +
    31 
    +
    32  // Get the number of samples that have been appended to this file.
    +
    33  size_t sample_count() const { return sample_count_; }
    +
    34 
    +
    35  private:
    +
    36  WebVttFileBuffer(const WebVttFileBuffer&) = delete;
    +
    37  WebVttFileBuffer& operator=(const WebVttFileBuffer&) = delete;
    +
    38 
    +
    39  const uint32_t transport_stream_timestamp_offset_ = 0;
    +
    40  const std::string style_region_config_;
    +
    41  std::string buffer_;
    +
    42  size_t sample_count_ = 0;
    +
    43 };
    +
    44 
    +
    45 } // namespace media
    +
    46 } // namespace shaka
    +
    47 
    +
    48 #endif // PACKAGER_MEDIA_FORMATS_WEBVTT_WEBVTT_FILE_BUFFER_H_
    +
    Define an abstract file interface.
    Definition: file.h:27
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d03/classshaka_1_1media_1_1mp2t_1_1ProgramMapTableWriter.html b/docs/dc/d03/classshaka_1_1media_1_1mp2t_1_1ProgramMapTableWriter.html index dc1327d509..67bfedd44e 100644 --- a/docs/dc/d03/classshaka_1_1media_1_1mp2t_1_1ProgramMapTableWriter.html +++ b/docs/dc/d03/classshaka_1_1media_1_1mp2t_1_1ProgramMapTableWriter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::ProgramMapTableWriter Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::media::mp2t::AudioProgramMapTableWriter -shaka::media::mp2t::VideoProgramMapTableWriter - -
    +shaka::media::mp2t::AudioProgramMapTableWriter +shaka::media::mp2t::VideoProgramMapTableWriter + + @@ -155,9 +158,7 @@ Protected Member Functions diff --git a/docs/dc/d06/classshaka_1_1media_1_1StreamInfo-members.html b/docs/dc/d06/classshaka_1_1media_1_1StreamInfo-members.html index 7b25be7e91..c4eff29718 100644 --- a/docs/dc/d06/classshaka_1_1media_1_1StreamInfo-members.html +++ b/docs/dc/d06/classshaka_1_1media_1_1StreamInfo-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    diff --git a/docs/dc/d08/raw__key__encryption__flags_8cc_source.html b/docs/dc/d08/raw__key__encryption__flags_8cc_source.html index c7159681d1..daff7e17db 100644 --- a/docs/dc/d08/raw__key__encryption__flags_8cc_source.html +++ b/docs/dc/d08/raw__key__encryption__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/raw_key_encryption_flags.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    raw_key_encryption_flags.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Defines command line flags for raw key encryption/decryption.
    8 
    9 #include "packager/app/raw_key_encryption_flags.h"
    10 
    11 #include "packager/app/validate_flag.h"
    12 
    13 DEFINE_bool(enable_fixed_key_encryption,
    14  false,
    15  "Same as --enable_raw_key_encryption. Will be deprecated.");
    16 DEFINE_bool(enable_fixed_key_decryption,
    17  false,
    18  "Same as --enable_raw_key_decryption. Will be deprecated.");
    19 DEFINE_bool(enable_raw_key_encryption,
    20  false,
    21  "Enable encryption with raw key (key provided in command line).");
    22 DEFINE_bool(enable_raw_key_decryption,
    23  false,
    24  "Enable decryption with raw key (key provided in command line).");
    25 DEFINE_hex_bytes(
    26  key_id,
    27  "",
    28  "Key id in hex string format. Will be deprecated. Use --keys.");
    29 DEFINE_hex_bytes(key,
    30  "",
    31  "Key in hex string format. Will be deprecated. Use --keys.");
    32 DEFINE_string(keys,
    33  "",
    34  "A list of key information in the form of label=<drm "
    35  "label>:key_id=<32-digit key id in hex>:key=<32-digit key in "
    36  "hex>,label=...");
    37 DEFINE_hex_bytes(
    38  iv,
    39  "",
    40  "IV in hex string format. If not specified, a random IV will be "
    41  "generated. This flag should only be used for testing.");
    42 DEFINE_hex_bytes(
    43  pssh,
    44  "",
    45  "One or more PSSH boxes in hex string format. If not specified, "
    46  "will generate a v1 common PSSH box as specified in "
    47  "https://goo.gl/s8RIhr.");
    48 
    49 namespace shaka {
    50 
    52  bool success = true;
    53 
    54  if (FLAGS_enable_fixed_key_encryption)
    55  FLAGS_enable_raw_key_encryption = true;
    56  if (FLAGS_enable_fixed_key_decryption)
    57  FLAGS_enable_raw_key_decryption = true;
    58  if (FLAGS_enable_fixed_key_encryption || FLAGS_enable_fixed_key_decryption) {
    60  "--enable_fixed_key_encryption and --enable_fixed_key_decryption are "
    61  "going to be deprecated. Please switch to --enable_raw_key_encryption "
    62  "and --enable_raw_key_decryption as soon as possible.");
    63  }
    64 
    65  const bool raw_key_crypto =
    66  FLAGS_enable_raw_key_encryption || FLAGS_enable_raw_key_decryption;
    67  const char raw_key_crypto_label[] = "--enable_raw_key_encryption/decryption";
    68  // --key_id and --key are associated with --enable_raw_key_encryption and
    69  // --enable_raw_key_decryption.
    70  if (FLAGS_keys.empty()) {
    71  if (!ValidateFlag("key_id", FLAGS_key_id_bytes, raw_key_crypto, false,
    72  raw_key_crypto_label)) {
    73  success = false;
    74  }
    75  if (!ValidateFlag("key", FLAGS_key_bytes, raw_key_crypto, false,
    76  raw_key_crypto_label)) {
    77  success = false;
    78  }
    79  if (success && (!FLAGS_key_id_bytes.empty() || !FLAGS_key_bytes.empty())) {
    81  "--key_id and --key are going to be deprecated. Please switch to "
    82  "--keys as soon as possible.");
    83  }
    84  } else {
    85  if (!FLAGS_key_id_bytes.empty() || !FLAGS_key_bytes.empty()) {
    86  PrintError("--key_id or --key cannot be used together with --keys.");
    87  success = false;
    88  }
    89  }
    90  if (!ValidateFlag("iv", FLAGS_iv_bytes, FLAGS_enable_raw_key_encryption, true,
    91  "--enable_raw_key_encryption")) {
    92  success = false;
    93  }
    94  if (!FLAGS_iv_bytes.empty()) {
    95  if (FLAGS_iv_bytes.size() != 8 && FLAGS_iv_bytes.size() != 16) {
    96  PrintError(
    97  "--iv should be either 8 bytes (16 hex digits) or 16 bytes (32 hex "
    98  "digits).");
    99  success = false;
    100  }
    101  }
    102 
    103  // --pssh is associated with --enable_raw_key_encryption.
    104  if (!ValidateFlag("pssh", FLAGS_pssh_bytes, FLAGS_enable_raw_key_encryption,
    105  true, "--enable_raw_key_encryption")) {
    106  success = false;
    107  }
    108  return success;
    109 }
    110 
    111 } // namespace shaka
    void PrintError(const std::string &error_message)
    -
    bool ValidateFlag(const char *flag_name, const FlagType &flag_value, bool condition, bool optional, const char *label)
    Definition: validate_flag.h:37
    -
    bool ValidateRawKeyCryptoFlags()
    -
    All the methods that are virtual are virtual for mocking.
    -
    void PrintWarning(const std::string &warning_message)
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Defines command line flags for raw key encryption/decryption.
    +
    8 
    +
    9 #include "packager/app/raw_key_encryption_flags.h"
    +
    10 
    +
    11 #include "packager/app/validate_flag.h"
    +
    12 
    +
    13 DEFINE_bool(enable_fixed_key_encryption,
    +
    14  false,
    +
    15  "Same as --enable_raw_key_encryption. Will be deprecated.");
    +
    16 DEFINE_bool(enable_fixed_key_decryption,
    +
    17  false,
    +
    18  "Same as --enable_raw_key_decryption. Will be deprecated.");
    +
    19 DEFINE_bool(enable_raw_key_encryption,
    +
    20  false,
    +
    21  "Enable encryption with raw key (key provided in command line).");
    +
    22 DEFINE_bool(enable_raw_key_decryption,
    +
    23  false,
    +
    24  "Enable decryption with raw key (key provided in command line).");
    +
    25 DEFINE_hex_bytes(
    +
    26  key_id,
    +
    27  "",
    +
    28  "Key id in hex string format. Will be deprecated. Use --keys.");
    +
    29 DEFINE_hex_bytes(key,
    +
    30  "",
    +
    31  "Key in hex string format. Will be deprecated. Use --keys.");
    +
    32 DEFINE_string(keys,
    +
    33  "",
    +
    34  "A list of key information in the form of label=<drm "
    +
    35  "label>:key_id=<32-digit key id in hex>:key=<32-digit key in "
    +
    36  "hex>,label=...");
    +
    37 DEFINE_hex_bytes(
    +
    38  iv,
    +
    39  "",
    +
    40  "IV in hex string format. If not specified, a random IV will be "
    +
    41  "generated. This flag should only be used for testing.");
    +
    42 DEFINE_hex_bytes(
    +
    43  pssh,
    +
    44  "",
    +
    45  "One or more PSSH boxes in hex string format. If not specified, "
    +
    46  "will generate a v1 common PSSH box as specified in "
    +
    47  "https://goo.gl/s8RIhr.");
    +
    48 
    +
    49 namespace shaka {
    +
    50 
    + +
    52  bool success = true;
    +
    53 
    +
    54  if (FLAGS_enable_fixed_key_encryption)
    +
    55  FLAGS_enable_raw_key_encryption = true;
    +
    56  if (FLAGS_enable_fixed_key_decryption)
    +
    57  FLAGS_enable_raw_key_decryption = true;
    +
    58  if (FLAGS_enable_fixed_key_encryption || FLAGS_enable_fixed_key_decryption) {
    + +
    60  "--enable_fixed_key_encryption and --enable_fixed_key_decryption are "
    +
    61  "going to be deprecated. Please switch to --enable_raw_key_encryption "
    +
    62  "and --enable_raw_key_decryption as soon as possible.");
    +
    63  }
    +
    64 
    +
    65  const bool raw_key_crypto =
    +
    66  FLAGS_enable_raw_key_encryption || FLAGS_enable_raw_key_decryption;
    +
    67  const char raw_key_crypto_label[] = "--enable_raw_key_encryption/decryption";
    +
    68  // --key_id and --key are associated with --enable_raw_key_encryption and
    +
    69  // --enable_raw_key_decryption.
    +
    70  if (FLAGS_keys.empty()) {
    +
    71  if (!ValidateFlag("key_id", FLAGS_key_id_bytes, raw_key_crypto, false,
    +
    72  raw_key_crypto_label)) {
    +
    73  success = false;
    +
    74  }
    +
    75  if (!ValidateFlag("key", FLAGS_key_bytes, raw_key_crypto, false,
    +
    76  raw_key_crypto_label)) {
    +
    77  success = false;
    +
    78  }
    +
    79  if (success && (!FLAGS_key_id_bytes.empty() || !FLAGS_key_bytes.empty())) {
    + +
    81  "--key_id and --key are going to be deprecated. Please switch to "
    +
    82  "--keys as soon as possible.");
    +
    83  }
    +
    84  } else {
    +
    85  if (!FLAGS_key_id_bytes.empty() || !FLAGS_key_bytes.empty()) {
    +
    86  PrintError("--key_id or --key cannot be used together with --keys.");
    +
    87  success = false;
    +
    88  }
    +
    89  }
    +
    90  if (!ValidateFlag("iv", FLAGS_iv_bytes, FLAGS_enable_raw_key_encryption, true,
    +
    91  "--enable_raw_key_encryption")) {
    +
    92  success = false;
    +
    93  }
    +
    94  if (!FLAGS_iv_bytes.empty()) {
    +
    95  if (FLAGS_iv_bytes.size() != 8 && FLAGS_iv_bytes.size() != 16) {
    +
    96  PrintError(
    +
    97  "--iv should be either 8 bytes (16 hex digits) or 16 bytes (32 hex "
    +
    98  "digits).");
    +
    99  success = false;
    +
    100  }
    +
    101  }
    +
    102 
    +
    103  // --pssh is associated with --enable_raw_key_encryption.
    +
    104  if (!ValidateFlag("pssh", FLAGS_pssh_bytes, FLAGS_enable_raw_key_encryption,
    +
    105  true, "--enable_raw_key_encryption")) {
    +
    106  success = false;
    +
    107  }
    +
    108  return success;
    +
    109 }
    +
    110 
    +
    111 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    void PrintWarning(const std::string &warning_message)
    +
    void PrintError(const std::string &error_message)
    +
    bool ValidateFlag(const char *flag_name, const FlagType &flag_value, bool condition, bool optional, const char *label)
    Definition: validate_flag.h:37
    +
    bool ValidateRawKeyCryptoFlags()
    diff --git a/docs/dc/d0b/classshaka_1_1media_1_1ESDescriptor-members.html b/docs/dc/d0b/classshaka_1_1media_1_1ESDescriptor-members.html index f3b50a3b65..4a7a716dd0 100644 --- a/docs/dc/d0b/classshaka_1_1media_1_1ESDescriptor-members.html +++ b/docs/dc/d0b/classshaka_1_1media_1_1ESDescriptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mutable_decoder_config_descriptor() (defined in shaka::media::ESDescriptor)shaka::media::ESDescriptorinline Parse(const std::vector< uint8_t > &data)shaka::media::BaseDescriptor Read(BitReader *reader)shaka::media::BaseDescriptor - set_esid(uint16_t esid) (defined in shaka::media::ESDescriptor)shaka::media::ESDescriptorinline - Write(BufferWriter *writer)shaka::media::BaseDescriptor - WriteHeader(BufferWriter *writer)shaka::media::BaseDescriptorprotected + Write(BufferWriter *writer)shaka::media::BaseDescriptor + WriteHeader(BufferWriter *writer)shaka::media::BaseDescriptorprotected
    diff --git a/docs/dc/d16/classshaka_1_1media_1_1SeekHead.html b/docs/dc/d16/classshaka_1_1media_1_1SeekHead.html index 418311b07a..0215511a1d 100644 --- a/docs/dc/d16/classshaka_1_1media_1_1SeekHead.html +++ b/docs/dc/d16/classshaka_1_1media_1_1SeekHead.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SeekHead Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    set_tracks_pos (u
    diff --git a/docs/dc/d17/status__test__util_8h_source.html b/docs/dc/d17/status__test__util_8h_source.html index 76265c2fee..be33a2149b 100644 --- a/docs/dc/d17/status__test__util_8h_source.html +++ b/docs/dc/d17/status__test__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/status_test_util.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    status_test_util.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_STATUS_TEST_UTIL_H_
    8 #define PACKAGER_STATUS_TEST_UTIL_H_
    9 
    10 #include <gtest/gtest.h>
    11 
    12 #include "packager/status.h"
    13 
    14 #define EXPECT_OK(val) EXPECT_EQ(shaka::Status::OK, (val))
    15 #define ASSERT_OK(val) ASSERT_EQ(shaka::Status::OK, (val))
    16 #define EXPECT_NOT_OK(val) EXPECT_NE(shaka::Status::OK, (val))
    17 #define ASSERT_NOT_OK(val) ASSERT_NE(shaka::Status::OK, (val))
    18 
    19 #endif // PACKAGER_STATUS_TEST_UTIL_H_
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_STATUS_TEST_UTIL_H_
    +
    8 #define PACKAGER_STATUS_TEST_UTIL_H_
    +
    9 
    +
    10 #include <gtest/gtest.h>
    +
    11 
    +
    12 #include "packager/status.h"
    +
    13 
    +
    14 #define EXPECT_OK(val) EXPECT_EQ(shaka::Status::OK, (val))
    +
    15 #define ASSERT_OK(val) ASSERT_EQ(shaka::Status::OK, (val))
    +
    16 #define EXPECT_NOT_OK(val) EXPECT_NE(shaka::Status::OK, (val))
    +
    17 #define ASSERT_NOT_OK(val) ASSERT_NE(shaka::Status::OK, (val))
    +
    18 
    +
    19 #endif // PACKAGER_STATUS_TEST_UTIL_H_
    +
    diff --git a/docs/dc/d18/classshaka_1_1media_1_1wvm_1_1WvmMediaParser.html b/docs/dc/d18/classshaka_1_1media_1_1wvm_1_1WvmMediaParser.html index 3c7149a428..b1cecfa950 100644 --- a/docs/dc/d18/classshaka_1_1media_1_1wvm_1_1WvmMediaParser.html +++ b/docs/dc/d18/classshaka_1_1media_1_1wvm_1_1WvmMediaParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::wvm::WvmMediaParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MediaParser - -
    + + - - + + @@ -93,8 +96,10 @@ Additional Inherited Members - - + + + +

    Public Member Functions

    MediaParser implementation overrides.
    void Init (const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
     
    void Init (const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
     
    bool Flush () override WARN_UNUSED_RESULT
     
    bool Parse (const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    - Public Types inherited from shaka::media::MediaParser
    typedef base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
     
    typedef base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
     
    typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
     
    typedef base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
     

    Detailed Description

    @@ -126,12 +131,12 @@ Additional Inherited Members

    Implements shaka::media::MediaParser.

    -

    Definition at line 518 of file wvm_media_parser.cc.

    +

    Definition at line 519 of file wvm_media_parser.cc.

    - -

    ◆ Init()

    + +

    ◆ Init()

    @@ -148,8 +153,14 @@ Additional Inherited Members - const NewSampleCB &  - new_sample_cb, + const NewMediaSampleCB &  + new_media_sample_cb, + + + + + const NewTextSampleCB &  + new_text_sample_cb, @@ -172,12 +183,14 @@ Additional Inherited Members

    Initialize the parser with necessary callbacks. Must be called before any data is passed to Parse().

    Parameters
    - + + +
    init_cbwill be called once enough data has been parsed to determine the initial stream configurations.
    new_sample_cbwill be called each time a new media sample is available from the parser. May be NULL, and caller retains ownership.
    new_media_sample_cbwill be called each time a new media sample is available from the parser.
    new_text_sample_cbwill be called each time a new text sample is available from the parser.
    decryption_key_sourcethe key source to decrypt the frames. May be NULL, and caller retains ownership.
    -

    Implements shaka::media::MediaParser.

    +

    Implements shaka::media::MediaParser.

    Definition at line 114 of file wvm_media_parser.cc.

    @@ -220,7 +233,7 @@ Additional Inherited Members

    Implements shaka::media::MediaParser.

    -

    Definition at line 125 of file wvm_media_parser.cc.

    +

    Definition at line 126 of file wvm_media_parser.cc.

    @@ -231,9 +244,7 @@ Additional Inherited Members diff --git a/docs/dc/d18/structshaka_1_1media_1_1mp4_1_1ProtectionSchemeInfo-members.html b/docs/dc/d18/structshaka_1_1media_1_1mp4_1_1ProtectionSchemeInfo-members.html index f90f7064c0..85fadb1e7f 100644 --- a/docs/dc/d18/structshaka_1_1media_1_1mp4_1_1ProtectionSchemeInfo-members.html +++ b/docs/dc/d18/structshaka_1_1media_1_1mp4_1_1ProtectionSchemeInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/d19/box_8h_source.html b/docs/dc/d19/box_8h_source.html index 1cf83c2ed7..2248d8ca77 100644 --- a/docs/dc/d19/box_8h_source.html +++ b/docs/dc/d19/box_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/box.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    box.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include "packager/media/base/fourccs.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 class BufferWriter;
    18 
    19 namespace mp4 {
    20 
    21 class BoxBuffer;
    22 class BoxReader;
    23 
    27 struct Box {
    28  public:
    29  Box();
    30  virtual ~Box();
    33  bool Parse(BoxReader* reader);
    38  void Write(BufferWriter* writer);
    43  void WriteHeader(BufferWriter* writer);
    47  uint32_t ComputeSize();
    49  virtual uint32_t HeaderSize() const;
    51  virtual FourCC BoxType() const = 0;
    52 
    54  // function expects that ComputeSize has been invoked already.
    55  uint32_t box_size() { return box_size_; }
    56 
    57  protected:
    61  virtual bool ReadWriteHeaderInternal(BoxBuffer* buffer);
    62 
    63  private:
    64  friend class BoxBuffer;
    65  // Read/write the mp4 box from/to BoxBuffer. Note that this function expects
    66  // that ComputeSize has been invoked already.
    67  virtual bool ReadWriteInternal(BoxBuffer* buffer) = 0;
    68  // Compute the size of this box. A value of 0 should be returned if the box
    69  // should not be written. Note that this function won't update box size.
    70  virtual size_t ComputeSizeInternal() = 0;
    71 
    72  // We don't support 64-bit box sizes. 32-bit should be large enough for our
    73  // current needs.
    74  uint32_t box_size_;
    75 
    76  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
    77  // generated copy constructor and assignment operator.
    78 };
    79 
    83 struct FullBox : Box {
    84  public:
    85  FullBox();
    86  ~FullBox() override;
    87 
    88  uint32_t HeaderSize() const final;
    89 
    90  uint8_t version = 0;
    91  uint32_t flags = 0;
    92 
    93  protected:
    94  bool ReadWriteHeaderInternal(BoxBuffer* buffer) final;
    95 
    96  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
    97  // generated copy constructor and assignment operator.
    98 };
    99 
    100 } // namespace mp4
    101 } // namespace media
    102 } // namespace shaka
    103 
    104 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_H_
    virtual FourCC BoxType() const =0
    - - -
    virtual bool ReadWriteHeaderInternal(BoxBuffer *buffer)
    Definition: box.cc:61
    -
    All the methods that are virtual are virtual for mocking.
    - -
    uint32_t ComputeSize()
    Definition: box.cc:50
    -
    uint32_t box_size()
    Definition: box.h:55
    - -
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    -
    virtual uint32_t HeaderSize() const
    Definition: box.cc:55
    -
    bool Parse(BoxReader *reader)
    Definition: box.cc:19
    -
    void Write(BufferWriter *writer)
    Definition: box.cc:25
    -
    void WriteHeader(BufferWriter *writer)
    Definition: box.cc:38
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include "packager/media/base/fourccs.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 class BufferWriter;
    +
    18 
    +
    19 namespace mp4 {
    +
    20 
    +
    21 class BoxBuffer;
    +
    22 class BoxReader;
    +
    23 
    +
    27 struct Box {
    +
    28  public:
    +
    29  Box();
    +
    30  virtual ~Box();
    +
    33  bool Parse(BoxReader* reader);
    +
    38  void Write(BufferWriter* writer);
    +
    43  void WriteHeader(BufferWriter* writer);
    +
    47  uint32_t ComputeSize();
    +
    49  virtual uint32_t HeaderSize() const;
    +
    51  virtual FourCC BoxType() const = 0;
    +
    52 
    +
    54  // function expects that ComputeSize has been invoked already.
    +
    55  uint32_t box_size() { return box_size_; }
    +
    56 
    +
    57  protected:
    +
    61  virtual bool ReadWriteHeaderInternal(BoxBuffer* buffer);
    +
    62 
    +
    63  private:
    +
    64  friend class BoxBuffer;
    +
    65  // Read/write the mp4 box from/to BoxBuffer. Note that this function expects
    +
    66  // that ComputeSize has been invoked already.
    +
    67  virtual bool ReadWriteInternal(BoxBuffer* buffer) = 0;
    +
    68  // Compute the size of this box. A value of 0 should be returned if the box
    +
    69  // should not be written. Note that this function won't update box size.
    +
    70  virtual size_t ComputeSizeInternal() = 0;
    +
    71 
    +
    72  // We don't support 64-bit box sizes. 32-bit should be large enough for our
    +
    73  // current needs.
    +
    74  uint32_t box_size_;
    +
    75 
    +
    76  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
    +
    77  // generated copy constructor and assignment operator.
    +
    78 };
    +
    79 
    +
    83 struct FullBox : Box {
    +
    84  public:
    +
    85  FullBox();
    +
    86  ~FullBox() override;
    +
    87 
    +
    88  uint32_t HeaderSize() const final;
    +
    89 
    +
    90  uint8_t version = 0;
    +
    91  uint32_t flags = 0;
    +
    92 
    +
    93  protected:
    +
    94  bool ReadWriteHeaderInternal(BoxBuffer* buffer) final;
    +
    95 
    +
    96  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
    +
    97  // generated copy constructor and assignment operator.
    +
    98 };
    +
    99 
    +
    100 } // namespace mp4
    +
    101 } // namespace media
    +
    102 } // namespace shaka
    +
    103 
    +
    104 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_H_
    + + +
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    +
    All the methods that are virtual are virtual for mocking.
    + +
    virtual uint32_t HeaderSize() const
    Definition: box.cc:55
    +
    void Write(BufferWriter *writer)
    Definition: box.cc:25
    +
    virtual bool ReadWriteHeaderInternal(BoxBuffer *buffer)
    Definition: box.cc:61
    +
    bool Parse(BoxReader *reader)
    Definition: box.cc:19
    +
    void WriteHeader(BufferWriter *writer)
    Definition: box.cc:38
    +
    uint32_t ComputeSize()
    Definition: box.cc:50
    +
    virtual FourCC BoxType() const =0
    +
    uint32_t box_size()
    Definition: box.h:55
    + +
    uint32_t HeaderSize() const final
    Definition: box.cc:75
    +
    bool ReadWriteHeaderInternal(BoxBuffer *buffer) final
    Definition: box.cc:80
    diff --git a/docs/dc/d1c/classshaka_1_1media_1_1mp2t_1_1AudioProgramMapTableWriter.html b/docs/dc/d1c/classshaka_1_1media_1_1mp2t_1_1AudioProgramMapTableWriter.html index 3eec85c4f4..89edb3d5be 100644 --- a/docs/dc/d1c/classshaka_1_1media_1_1mp2t_1_1AudioProgramMapTableWriter.html +++ b/docs/dc/d1c/classshaka_1_1media_1_1mp2t_1_1AudioProgramMapTableWriter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::AudioProgramMapTableWriter Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -

    ProgramMapTableWriter for video codecs. +

    ProgramMapTableWriter for video codecs. More...

    #include <program_map_table_writer.h>

    @@ -80,9 +83,9 @@ Inheritance diagram for shaka::media::mp2t::AudioProgramMapTableWriter:
    -shaka::media::mp2t::ProgramMapTableWriter - -
    +shaka::media::mp2t::ProgramMapTableWriter + + @@ -116,7 +119,7 @@ static const uint8_t 

    Public Member Functions

    kElem
     

    Detailed Description

    -

    ProgramMapTableWriter for video codecs.

    +

    ProgramMapTableWriter for video codecs.

    Definition at line 79 of file program_map_table_writer.h.


    The documentation for this class was generated from the following files:
      @@ -126,9 +129,7 @@ static const uint8_t kElem
    diff --git a/docs/dc/d1c/replicator_8h_source.html b/docs/dc/d1c/replicator_8h_source.html index a98b355242..ae2a1dc459 100644 --- a/docs/dc/d1c/replicator_8h_source.html +++ b/docs/dc/d1c/replicator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/replicator/replicator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    replicator.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_REPLICATOR_HANDLER_H_
    8 #define PACKAGER_MEDIA_REPLICATOR_HANDLER_H_
    9 
    10 #include "packager/media/base/media_handler.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    19 class Replicator : public MediaHandler {
    20  private:
    21  Status InitializeInternal() override;
    22  Status Process(std::unique_ptr<StreamData> stream_data) override;
    23  bool ValidateOutputStreamIndex(size_t stream_index) const override;
    24  Status OnFlushRequest(size_t input_stream_index) override;
    25 };
    26 
    27 } // namespace media
    28 } // namespace shaka
    29 
    30 #endif // PACKAGER_MEDIA_REPLICATOR_HANDLER_H_
    -
    All the methods that are virtual are virtual for mocking.
    - - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_REPLICATOR_HANDLER_H_
    +
    8 #define PACKAGER_MEDIA_REPLICATOR_HANDLER_H_
    +
    9 
    +
    10 #include "packager/media/base/media_handler.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    19 class Replicator : public MediaHandler {
    +
    20  private:
    +
    21  Status InitializeInternal() override;
    +
    22  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    23  bool ValidateOutputStreamIndex(size_t stream_index) const override;
    +
    24  Status OnFlushRequest(size_t input_stream_index) override;
    +
    25 };
    +
    26 
    +
    27 } // namespace media
    +
    28 } // namespace shaka
    +
    29 
    +
    30 #endif // PACKAGER_MEDIA_REPLICATOR_HANDLER_H_
    + + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d1f/classshaka_1_1media_1_1WebVttParser-members.html b/docs/dc/d1f/classshaka_1_1media_1_1WebVttParser-members.html index d3d7cf081d..2028b31842 100644 --- a/docs/dc/d1f/classshaka_1_1media_1_1WebVttParser-members.html +++ b/docs/dc/d1f/classshaka_1_1media_1_1WebVttParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::WebVttParser, including all inherited members.

    - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + +
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
    Cancel() override (defined in shaka::media::WebVttParser)shaka::media::WebVttParservirtual
    Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
    DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) constshaka::media::MediaHandlerinlineprotected
    DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) constshaka::media::MediaHandlerinlineprotected
    DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) constshaka::media::MediaHandlerinlineprotected
    DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) constshaka::media::MediaHandlerinlineprotected
    FlushAllDownstreams()shaka::media::MediaHandlerprotected
    FlushDownstream(size_t output_stream_index)shaka::media::MediaHandlerprotected
    Initialize()shaka::media::MediaHandler
    initialized() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    IsConnected()shaka::media::MediaHandlerinline
    MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandler
    next_output_stream_index() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    num_input_streams() const (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    OnFlushRequest(size_t input_stream_index)shaka::media::MediaHandlerprotectedvirtual
    OriginHandler()=default (defined in shaka::media::OriginHandler)shaka::media::OriginHandler
    output_handlers() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    Run() override (defined in shaka::media::WebVttParser)shaka::media::WebVttParservirtual
    SetHandler(size_t output_stream_index, std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandler
    WebVttParser(std::unique_ptr< FileReader > source, const std::string &language) (defined in shaka::media::WebVttParser)shaka::media::WebVttParser
    ~MediaHandler()=default (defined in shaka::media::MediaHandler)shaka::media::MediaHandlervirtual
    Flush() overrideshaka::media::WebVttParservirtual
    Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) overrideshaka::media::WebVttParservirtual
    InitCB typedefshaka::media::MediaParser
    MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinline
    NewMediaSampleCB typedefshaka::media::MediaParser
    NewTextSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) overrideshaka::media::WebVttParservirtual
    WebVttParser() (defined in shaka::media::WebVttParser)shaka::media::WebVttParser
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    diff --git a/docs/dc/d21/classshaka_1_1media_1_1mp2t_1_1Ac3Header.html b/docs/dc/d21/classshaka_1_1media_1_1mp2t_1_1Ac3Header.html index dd9e5fb3ce..26546bf428 100644 --- a/docs/dc/d21/classshaka_1_1media_1_1mp2t_1_1Ac3Header.html +++ b/docs/dc/d21/classshaka_1_1media_1_1mp2t_1_1Ac3Header.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::Ac3Header Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp2t::AudioHeader - -
    + + @@ -491,9 +494,7 @@ Public Member Functions diff --git a/docs/dc/d35/structshaka_1_1EncryptionParams-members.html b/docs/dc/d35/structshaka_1_1EncryptionParams-members.html index 215a4a63ca..d2005862a4 100644 --- a/docs/dc/d35/structshaka_1_1EncryptionParams-members.html +++ b/docs/dc/d35/structshaka_1_1EncryptionParams-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    This is the complete list of members for shaka::EncryptionParams, including all inherited members.

    - - - - - - - - + + + + + + + + + + - - - + + +
    clear_lead_in_secondsshaka::EncryptionParams
    crypto_period_duration_in_seconds (defined in shaka::EncryptionParams)shaka::EncryptionParams
    key_providershaka::EncryptionParams
    kNoKeyRotationshaka::EncryptionParamsstatic
    kProtectionSchemeCbc1 (defined in shaka::EncryptionParams)shaka::EncryptionParamsstatic
    kProtectionSchemeCbcs (defined in shaka::EncryptionParams)shaka::EncryptionParamsstatic
    kProtectionSchemeCencshaka::EncryptionParamsstatic
    kProtectionSchemeCens (defined in shaka::EncryptionParams)shaka::EncryptionParamsstatic
    playready (defined in shaka::EncryptionParams)shaka::EncryptionParams
    crypt_byte_blockshaka::EncryptionParams
    crypto_period_duration_in_seconds (defined in shaka::EncryptionParams)shaka::EncryptionParams
    key_providershaka::EncryptionParams
    kNoKeyRotationshaka::EncryptionParamsstatic
    kProtectionSchemeCbc1 (defined in shaka::EncryptionParams)shaka::EncryptionParamsstatic
    kProtectionSchemeCbcs (defined in shaka::EncryptionParams)shaka::EncryptionParamsstatic
    kProtectionSchemeCencshaka::EncryptionParamsstatic
    kProtectionSchemeCens (defined in shaka::EncryptionParams)shaka::EncryptionParamsstatic
    playready (defined in shaka::EncryptionParams)shaka::EncryptionParams
    playready_extra_header_datashaka::EncryptionParams
    protection_scheme (defined in shaka::EncryptionParams)shaka::EncryptionParams
    protection_systemsshaka::EncryptionParams
    ProtectionSystem enum nameshaka::EncryptionParams
    raw_key (defined in shaka::EncryptionParams)shaka::EncryptionParams
    protection_systemsshaka::EncryptionParams
    raw_key (defined in shaka::EncryptionParams)shaka::EncryptionParams
    skip_byte_blockshaka::EncryptionParams
    stream_label_funcshaka::EncryptionParams
    vp9_subsample_encryptionshaka::EncryptionParams
    widevine (defined in shaka::EncryptionParams)shaka::EncryptionParams
    diff --git a/docs/dc/d3c/webm__cluster__parser_8h_source.html b/docs/dc/d3c/webm__cluster__parser_8h_source.html index b61bc1a5f6..62d3fc32bc 100644 --- a/docs/dc/d3c/webm__cluster__parser_8h_source.html +++ b/docs/dc/d3c/webm__cluster__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_cluster_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webm_cluster_parser.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
    7 
    8 #include <deque>
    9 #include <map>
    10 #include <memory>
    11 #include <set>
    12 #include <string>
    13 
    14 #include "packager/base/compiler_specific.h"
    15 #include "packager/media/base/decryptor_source.h"
    16 #include "packager/media/base/media_parser.h"
    17 #include "packager/media/base/media_sample.h"
    18 #include "packager/media/formats/webm/webm_parser.h"
    19 #include "packager/media/formats/webm/webm_tracks_parser.h"
    20 
    21 namespace shaka {
    22 namespace media {
    23 
    25  public:
    28  enum {
    31 
    35  };
    36 
    37  private:
    38  // Helper class that manages per-track state.
    39  class Track {
    40  public:
    41  Track(int track_num,
    42  bool is_video,
    43  int64_t default_duration,
    44  const MediaParser::NewSampleCB& new_sample_cb);
    45  ~Track();
    46 
    47  int track_num() const { return track_num_; }
    48 
    49  // If |last_added_buffer_missing_duration_| is set, updates its duration
    50  // relative to |buffer|'s timestamp, and emits it and unsets
    51  // |last_added_buffer_missing_duration_|. Otherwise, if |buffer| is missing
    52  // duration, saves |buffer| into |last_added_buffer_missing_duration_|.
    53  bool EmitBuffer(const std::shared_ptr<MediaSample>& buffer);
    54 
    55  // If |last_added_buffer_missing_duration_| is set, estimate the duration
    56  // for this buffer using helper function GetDurationEstimate() then emits it
    57  // and unsets |last_added_buffer_missing_duration_| (This method helps
    58  // stream parser emit all buffers in a media segment).
    59  bool ApplyDurationEstimateIfNeeded();
    60 
    61  // Clears all buffer state, including any possibly held-aside buffer that
    62  // was missing duration.
    63  void Reset();
    64 
    65  private:
    66  // Helper that sanity-checks |buffer| duration, updates
    67  // |estimated_next_frame_duration_|, and emits |buffer|.
    68  // Returns false if |buffer| failed sanity check and therefore was not
    69  // emitted. Returns true otherwise.
    70  bool EmitBufferHelp(const std::shared_ptr<MediaSample>& buffer);
    71 
    72  // Helper function that calculates the buffer duration to use in
    73  // ApplyDurationEstimateIfNeeded().
    74  int64_t GetDurationEstimate();
    75 
    76  int track_num_;
    77  bool is_video_;
    78 
    79  // Holding the sample that is missing duration. The duration will be
    80  // computed from the difference in timestamp when next sample arrives; or
    81  // estimated if it is the last sample in this track.
    82  std::shared_ptr<MediaSample> last_added_buffer_missing_duration_;
    83 
    84  // If kNoTimestamp, then |estimated_next_frame_duration_| will be used.
    85  int64_t default_duration_;
    86 
    87  // If kNoTimestamp, then a hardcoded default value will be used. This
    88  // estimate is the maximum duration seen so far for this track, and is used
    89  // only if |default_duration_| is kNoTimestamp.
    90  int64_t estimated_next_frame_duration_;
    91 
    92  MediaParser::NewSampleCB new_sample_cb_;
    93  };
    94 
    95  typedef std::map<int, Track> TextTrackMap;
    96 
    97  public:
    122  WebMClusterParser(int64_t timecode_scale,
    123  std::shared_ptr<AudioStreamInfo> audio_stream_info,
    124  std::shared_ptr<VideoStreamInfo> video_stream_info,
    125  const VPCodecConfigurationRecord& vp_config,
    126  int64_t audio_default_duration,
    127  int64_t video_default_duration,
    128  const WebMTracksParser::TextTracks& text_tracks,
    129  const std::set<int64_t>& ignored_tracks,
    130  const std::string& audio_encryption_key_id,
    131  const std::string& video_encryption_key_id,
    132  const MediaParser::NewSampleCB& new_sample_cb,
    133  const MediaParser::InitCB& init_cb,
    134  KeySource* decryption_key_source);
    135  ~WebMClusterParser() override;
    136 
    138  void Reset();
    139 
    143  bool Flush() WARN_UNUSED_RESULT;
    144 
    149  int Parse(const uint8_t* buf, int size);
    150 
    151  int64_t cluster_start_time() const { return cluster_start_time_; }
    152 
    154  bool cluster_ended() const { return cluster_ended_; }
    155 
    156  private:
    157  // WebMParserClient methods.
    158  WebMParserClient* OnListStart(int id) override;
    159  bool OnListEnd(int id) override;
    160  bool OnUInt(int id, int64_t val) override;
    161  bool OnBinary(int id, const uint8_t* data, int size) override;
    162 
    163  bool ParseBlock(bool is_simple_block,
    164  const uint8_t* buf,
    165  int size,
    166  const uint8_t* additional,
    167  int additional_size,
    168  int duration,
    169  int64_t discard_padding,
    170  bool reference_block_set);
    171  bool OnBlock(bool is_simple_block,
    172  int track_num,
    173  int timecode,
    174  int duration,
    175  const uint8_t* data,
    176  int size,
    177  const uint8_t* additional,
    178  int additional_size,
    179  int64_t discard_padding,
    180  bool is_key_frame);
    181 
    182  // Resets the Track objects associated with each text track.
    183  void ResetTextTracks();
    184 
    185  // Search for the indicated track_num among the text tracks. Returns NULL
    186  // if that track num is not a text track.
    187  Track* FindTextTrack(int track_num);
    188 
    189  // Multiplier used to convert timecodes into microseconds.
    190  double timecode_multiplier_;
    191 
    192  std::shared_ptr<AudioStreamInfo> audio_stream_info_;
    193  std::shared_ptr<VideoStreamInfo> video_stream_info_;
    194  VPCodecConfigurationRecord vp_config_;
    195  std::set<int64_t> ignored_tracks_;
    196 
    197  std::unique_ptr<DecryptorSource> decryptor_source_;
    198  std::string audio_encryption_key_id_;
    199  std::string video_encryption_key_id_;
    200 
    201  WebMListParser parser_;
    202 
    203  // Indicates whether init_cb has been executed. |init_cb| is executed when we
    204  // have codec configuration of video stream, which is extracted from the first
    205  // video sample.
    206  bool initialized_;
    207  MediaParser::InitCB init_cb_;
    208 
    209  int64_t last_block_timecode_ = -1;
    210  std::unique_ptr<uint8_t[]> block_data_;
    211  int block_data_size_ = -1;
    212  int64_t block_duration_ = -1;
    213  int64_t block_add_id_ = -1;
    214 
    215  std::unique_ptr<uint8_t[]> block_additional_data_;
    216  // Must be 0 if |block_additional_data_| is null. Must be > 0 if
    217  // |block_additional_data_| is NOT null.
    218  int block_additional_data_size_ = 0;
    219 
    220  int64_t discard_padding_ = -1;
    221  bool discard_padding_set_ = false;
    222 
    223  bool reference_block_set_ = false;
    224 
    225  int64_t cluster_timecode_ = -1;
    226  int64_t cluster_start_time_;
    227  bool cluster_ended_ = false;
    228 
    229  Track audio_;
    230  Track video_;
    231  TextTrackMap text_track_map_;
    232 
    233  DISALLOW_COPY_AND_ASSIGN(WebMClusterParser);
    234 };
    235 
    236 } // namespace media
    237 } // namespace shaka
    238 
    239 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
    -
    Class for parsing or writing VP codec configuration record.
    -
    WebMClusterParser(int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)
    -
    All the methods that are virtual are virtual for mocking.
    -
    int Parse(const uint8_t *buf, int size)
    -
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:34
    -
    base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
    Definition: media_parser.h:43
    -
    bool Flush() WARN_UNUSED_RESULT
    - -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    - - - - -
    void Reset()
    Resets the parser state so it can accept a new cluster.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
    +
    7 
    +
    8 #include <deque>
    +
    9 #include <map>
    +
    10 #include <memory>
    +
    11 #include <set>
    +
    12 #include <string>
    +
    13 
    +
    14 #include "packager/base/compiler_specific.h"
    +
    15 #include "packager/media/base/decryptor_source.h"
    +
    16 #include "packager/media/base/media_parser.h"
    +
    17 #include "packager/media/base/media_sample.h"
    +
    18 #include "packager/media/formats/webm/webm_parser.h"
    +
    19 #include "packager/media/formats/webm/webm_tracks_parser.h"
    +
    20 
    +
    21 namespace shaka {
    +
    22 namespace media {
    +
    23 
    + +
    25  public:
    +
    28  enum {
    + +
    31 
    + +
    35  };
    +
    36 
    +
    37  private:
    +
    38  // Helper class that manages per-track state.
    +
    39  class Track {
    +
    40  public:
    +
    41  Track(int track_num,
    +
    42  bool is_video,
    +
    43  int64_t default_duration,
    +
    44  const MediaParser::NewMediaSampleCB& new_sample_cb);
    +
    45  ~Track();
    +
    46 
    +
    47  int track_num() const { return track_num_; }
    +
    48 
    +
    49  // If |last_added_buffer_missing_duration_| is set, updates its duration
    +
    50  // relative to |buffer|'s timestamp, and emits it and unsets
    +
    51  // |last_added_buffer_missing_duration_|. Otherwise, if |buffer| is missing
    +
    52  // duration, saves |buffer| into |last_added_buffer_missing_duration_|.
    +
    53  bool EmitBuffer(const std::shared_ptr<MediaSample>& buffer);
    +
    54 
    +
    55  // If |last_added_buffer_missing_duration_| is set, estimate the duration
    +
    56  // for this buffer using helper function GetDurationEstimate() then emits it
    +
    57  // and unsets |last_added_buffer_missing_duration_| (This method helps
    +
    58  // stream parser emit all buffers in a media segment).
    +
    59  bool ApplyDurationEstimateIfNeeded();
    +
    60 
    +
    61  // Clears all buffer state, including any possibly held-aside buffer that
    +
    62  // was missing duration.
    +
    63  void Reset();
    +
    64 
    +
    65  private:
    +
    66  // Helper that sanity-checks |buffer| duration, updates
    +
    67  // |estimated_next_frame_duration_|, and emits |buffer|.
    +
    68  // Returns false if |buffer| failed sanity check and therefore was not
    +
    69  // emitted. Returns true otherwise.
    +
    70  bool EmitBufferHelp(const std::shared_ptr<MediaSample>& buffer);
    +
    71 
    +
    72  // Helper function that calculates the buffer duration to use in
    +
    73  // ApplyDurationEstimateIfNeeded().
    +
    74  int64_t GetDurationEstimate();
    +
    75 
    +
    76  int track_num_;
    +
    77  bool is_video_;
    +
    78 
    +
    79  // Holding the sample that is missing duration. The duration will be
    +
    80  // computed from the difference in timestamp when next sample arrives; or
    +
    81  // estimated if it is the last sample in this track.
    +
    82  std::shared_ptr<MediaSample> last_added_buffer_missing_duration_;
    +
    83 
    +
    84  // If kNoTimestamp, then |estimated_next_frame_duration_| will be used.
    +
    85  int64_t default_duration_;
    +
    86 
    +
    87  // If kNoTimestamp, then a hardcoded default value will be used. This
    +
    88  // estimate is the maximum duration seen so far for this track, and is used
    +
    89  // only if |default_duration_| is kNoTimestamp.
    +
    90  int64_t estimated_next_frame_duration_;
    +
    91 
    +
    92  MediaParser::NewMediaSampleCB new_sample_cb_;
    +
    93  };
    +
    94 
    +
    95  typedef std::map<int, Track> TextTrackMap;
    +
    96 
    +
    97  public:
    +
    122  WebMClusterParser(int64_t timecode_scale,
    +
    123  std::shared_ptr<AudioStreamInfo> audio_stream_info,
    +
    124  std::shared_ptr<VideoStreamInfo> video_stream_info,
    +
    125  const VPCodecConfigurationRecord& vp_config,
    +
    126  int64_t audio_default_duration,
    +
    127  int64_t video_default_duration,
    +
    128  const WebMTracksParser::TextTracks& text_tracks,
    +
    129  const std::set<int64_t>& ignored_tracks,
    +
    130  const std::string& audio_encryption_key_id,
    +
    131  const std::string& video_encryption_key_id,
    +
    132  const MediaParser::NewMediaSampleCB& new_sample_cb,
    +
    133  const MediaParser::InitCB& init_cb,
    +
    134  KeySource* decryption_key_source);
    +
    135  ~WebMClusterParser() override;
    +
    136 
    +
    138  void Reset();
    +
    139 
    +
    143  bool Flush() WARN_UNUSED_RESULT;
    +
    144 
    +
    149  int Parse(const uint8_t* buf, int size);
    +
    150 
    +
    151  int64_t cluster_start_time() const { return cluster_start_time_; }
    +
    152 
    +
    154  bool cluster_ended() const { return cluster_ended_; }
    +
    155 
    +
    156  private:
    +
    157  // WebMParserClient methods.
    +
    158  WebMParserClient* OnListStart(int id) override;
    +
    159  bool OnListEnd(int id) override;
    +
    160  bool OnUInt(int id, int64_t val) override;
    +
    161  bool OnBinary(int id, const uint8_t* data, int size) override;
    +
    162 
    +
    163  bool ParseBlock(bool is_simple_block,
    +
    164  const uint8_t* buf,
    +
    165  int size,
    +
    166  const uint8_t* additional,
    +
    167  int additional_size,
    +
    168  int duration,
    +
    169  int64_t discard_padding,
    +
    170  bool reference_block_set);
    +
    171  bool OnBlock(bool is_simple_block,
    +
    172  int track_num,
    +
    173  int timecode,
    +
    174  int duration,
    +
    175  const uint8_t* data,
    +
    176  int size,
    +
    177  const uint8_t* additional,
    +
    178  int additional_size,
    +
    179  int64_t discard_padding,
    +
    180  bool is_key_frame);
    +
    181 
    +
    182  // Resets the Track objects associated with each text track.
    +
    183  void ResetTextTracks();
    +
    184 
    +
    185  // Search for the indicated track_num among the text tracks. Returns NULL
    +
    186  // if that track num is not a text track.
    +
    187  Track* FindTextTrack(int track_num);
    +
    188 
    +
    189  // Multiplier used to convert timecodes into microseconds.
    +
    190  double timecode_multiplier_;
    +
    191 
    +
    192  std::shared_ptr<AudioStreamInfo> audio_stream_info_;
    +
    193  std::shared_ptr<VideoStreamInfo> video_stream_info_;
    +
    194  VPCodecConfigurationRecord vp_config_;
    +
    195  std::set<int64_t> ignored_tracks_;
    +
    196 
    +
    197  std::unique_ptr<DecryptorSource> decryptor_source_;
    +
    198  std::string audio_encryption_key_id_;
    +
    199  std::string video_encryption_key_id_;
    +
    200 
    +
    201  WebMListParser parser_;
    +
    202 
    +
    203  // Indicates whether init_cb has been executed. |init_cb| is executed when we
    +
    204  // have codec configuration of video stream, which is extracted from the first
    +
    205  // video sample.
    +
    206  bool initialized_;
    +
    207  MediaParser::InitCB init_cb_;
    +
    208 
    +
    209  int64_t last_block_timecode_ = -1;
    +
    210  std::unique_ptr<uint8_t[]> block_data_;
    +
    211  int block_data_size_ = -1;
    +
    212  int64_t block_duration_ = -1;
    +
    213  int64_t block_add_id_ = -1;
    +
    214 
    +
    215  std::unique_ptr<uint8_t[]> block_additional_data_;
    +
    216  // Must be 0 if |block_additional_data_| is null. Must be > 0 if
    +
    217  // |block_additional_data_| is NOT null.
    +
    218  int block_additional_data_size_ = 0;
    +
    219 
    +
    220  int64_t discard_padding_ = -1;
    +
    221  bool discard_padding_set_ = false;
    +
    222 
    +
    223  bool reference_block_set_ = false;
    +
    224 
    +
    225  int64_t cluster_timecode_ = -1;
    +
    226  int64_t cluster_start_time_;
    +
    227  bool cluster_ended_ = false;
    +
    228 
    +
    229  Track audio_;
    +
    230  Track video_;
    +
    231  TextTrackMap text_track_map_;
    +
    232 
    +
    233  DISALLOW_COPY_AND_ASSIGN(WebMClusterParser);
    +
    234 };
    +
    235 
    +
    236 } // namespace media
    +
    237 } // namespace shaka
    +
    238 
    +
    239 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    +
    Class for parsing or writing VP codec configuration record.
    + +
    @ kDefaultAudioBufferDurationInMs
    Common 1k samples @44.1kHz.
    + +
    WebMClusterParser(int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewMediaSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)
    + +
    int Parse(const uint8_t *buf, int size)
    +
    void Reset()
    Resets the parser state so it can accept a new cluster.
    +
    bool Flush() WARN_UNUSED_RESULT
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d3f/key__source_8h_source.html b/docs/dc/d3f/key__source_8h_source.html index c0b89f3034..1c60ae833f 100644 --- a/docs/dc/d3f/key__source_8h_source.html +++ b/docs/dc/d3f/key__source_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/key_source.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    key_source.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_KEY_SOURCE_H_
    8 #define PACKAGER_MEDIA_BASE_KEY_SOURCE_H_
    9 
    10 #include <map>
    11 #include <memory>
    12 #include <string>
    13 #include <vector>
    14 
    15 #include "packager/media/base/fourccs.h"
    16 #include "packager/media/base/protection_system_specific_info.h"
    17 #include "packager/media/base/pssh_generator.h"
    18 #include "packager/status.h"
    19 
    20 namespace shaka {
    21 namespace media {
    22 
    25 enum class EmeInitDataType {
    26  UNKNOWN,
    28  CENC,
    30  WEBM,
    32  KEYIDS,
    34  WIDEVINE_CLASSIC,
    35  MAX = WIDEVINE_CLASSIC
    36 };
    37 
    38 struct EncryptionKey {
    39  std::vector<ProtectionSystemSpecificInfo> key_system_info;
    40  std::vector<uint8_t> key_id;
    41  std::vector<uint8_t> key;
    42  std::vector<uint8_t> iv;
    43 };
    44 
    45 typedef std::map<std::string, std::unique_ptr<EncryptionKey>> EncryptionKeyMap;
    46 
    48 class KeySource {
    49  public:
    50  KeySource(int protection_systems_flags, FourCC protection_scheme);
    51 
    52  virtual ~KeySource();
    53 
    58  virtual Status FetchKeys(EmeInitDataType init_data_type,
    59  const std::vector<uint8_t>& init_data) = 0;
    60 
    66  virtual Status GetKey(const std::string& stream_label,
    67  EncryptionKey* key) = 0;
    68 
    74  virtual Status GetKey(const std::vector<uint8_t>& key_id,
    75  EncryptionKey* key) = 0;
    76 
    86  virtual Status GetCryptoPeriodKey(uint32_t crypto_period_index,
    87  uint32_t crypto_period_duration_in_seconds,
    88  const std::string& stream_label,
    89  EncryptionKey* key) = 0;
    90 
    91  protected:
    94  Status UpdateProtectionSystemInfo(EncryptionKeyMap* encryption_key_map);
    95 
    96  private:
    97  std::vector<std::unique_ptr<PsshGenerator>> pssh_generators_;
    98  std::vector<std::vector<uint8_t>> no_pssh_systems_;
    99 
    100  DISALLOW_COPY_AND_ASSIGN(KeySource);
    101 };
    102 
    103 } // namespace media
    104 } // namespace shaka
    105 
    106 #endif // PACKAGER_MEDIA_BASE_KEY_SOURCE_H_
    All the methods that are virtual are virtual for mocking.
    - - -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_KEY_SOURCE_H_
    +
    8 #define PACKAGER_MEDIA_BASE_KEY_SOURCE_H_
    +
    9 
    +
    10 #include <map>
    +
    11 #include <memory>
    +
    12 #include <string>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/media/base/fourccs.h"
    +
    16 #include "packager/media/base/protection_system_specific_info.h"
    +
    17 #include "packager/media/base/pssh_generator.h"
    +
    18 #include "packager/status.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 namespace media {
    +
    22 
    +
    25 enum class EmeInitDataType {
    +
    26  UNKNOWN,
    +
    28  CENC,
    +
    30  WEBM,
    +
    32  KEYIDS,
    +
    34  WIDEVINE_CLASSIC,
    +
    35  MAX = WIDEVINE_CLASSIC
    +
    36 };
    +
    37 
    +
    38 struct EncryptionKey {
    +
    39  std::vector<ProtectionSystemSpecificInfo> key_system_info;
    +
    41  std::vector<uint8_t> key_id;
    +
    43  std::vector<std::vector<uint8_t>> key_ids;
    +
    44  std::vector<uint8_t> key;
    +
    45  std::vector<uint8_t> iv;
    +
    46 };
    +
    47 
    +
    48 typedef std::map<std::string, std::unique_ptr<EncryptionKey>> EncryptionKeyMap;
    +
    49 
    +
    51 class KeySource {
    +
    52  public:
    +
    53  KeySource();
    +
    54 
    +
    55  virtual ~KeySource();
    +
    56 
    +
    61  virtual Status FetchKeys(EmeInitDataType init_data_type,
    +
    62  const std::vector<uint8_t>& init_data) = 0;
    +
    63 
    +
    69  virtual Status GetKey(const std::string& stream_label,
    +
    70  EncryptionKey* key) = 0;
    +
    71 
    +
    77  virtual Status GetKey(const std::vector<uint8_t>& key_id,
    +
    78  EncryptionKey* key) = 0;
    +
    79 
    +
    89  virtual Status GetCryptoPeriodKey(uint32_t crypto_period_index,
    +
    90  uint32_t crypto_period_duration_in_seconds,
    +
    91  const std::string& stream_label,
    +
    92  EncryptionKey* key) = 0;
    +
    93 
    +
    94  private:
    +
    95  DISALLOW_COPY_AND_ASSIGN(KeySource);
    +
    96 };
    +
    97 
    +
    98 } // namespace media
    +
    99 } // namespace shaka
    +
    100 
    +
    101 #endif // PACKAGER_MEDIA_BASE_KEY_SOURCE_H_
    + +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    +
    virtual Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data)=0
    +
    virtual Status GetKey(const std::vector< uint8_t > &key_id, EncryptionKey *key)=0
    +
    virtual Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key)=0
    +
    virtual Status GetKey(const std::string &stream_label, EncryptionKey *key)=0
    +
    All the methods that are virtual are virtual for mocking.
    + +
    std::vector< std::vector< uint8_t > > key_ids
    The IDs of the other keys to include in PSSH info.
    Definition: key_source.h:43
    +
    std::vector< uint8_t > key_id
    The ID of this key.
    Definition: key_source.h:41
    diff --git a/docs/dc/d40/classshaka_1_1hls_1_1HlsNotifier-members.html b/docs/dc/d40/classshaka_1_1hls_1_1HlsNotifier-members.html index e161358a9d..c825732e83 100644 --- a/docs/dc/d40/classshaka_1_1hls_1_1HlsNotifier-members.html +++ b/docs/dc/d40/classshaka_1_1hls_1_1HlsNotifier-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dc/d40/classshaka_1_1xml_1_1XmlNode-members.html b/docs/dc/d40/classshaka_1_1xml_1_1XmlNode-members.html index b817739264..3d3c7235c9 100644 --- a/docs/dc/d40/classshaka_1_1xml_1_1XmlNode-members.html +++ b/docs/dc/d40/classshaka_1_1xml_1_1XmlNode-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    This is the complete list of members for shaka::xml::XmlNode, including all inherited members.

    - - - - - - + + + + + + - - - - - - + + + + + + + + +
    AddChild(scoped_xml_ptr< xmlNode > child)shaka::xml::XmlNode
    AddElements(const std::vector< Element > &elements)shaka::xml::XmlNode
    ExtractReferencedNamespaces()shaka::xml::XmlNode
    GetRawPtr()shaka::xml::XmlNode
    PassScopedPtr()shaka::xml::XmlNode
    Release()shaka::xml::XmlNode
    AddChild(XmlNode child) WARN_UNUSED_RESULTshaka::xml::XmlNode
    AddContent(const std::string &content)shaka::xml::XmlNode
    AddElements(const std::vector< Element > &elements) WARN_UNUSED_RESULTshaka::xml::XmlNode
    ExtractReferencedNamespaces() constshaka::xml::XmlNode
    GetAttribute(const std::string &name, std::string *value) constshaka::xml::XmlNode
    operator=(XmlNode &&) (defined in shaka::xml::XmlNode)shaka::xml::XmlNode
    SetContent(const std::string &content)shaka::xml::XmlNode
    SetFloatingPointAttribute(const char *attribute_name, double number)shaka::xml::XmlNode
    SetId(uint32_t id)shaka::xml::XmlNode
    SetIntegerAttribute(const char *attribute_name, uint64_t number)shaka::xml::XmlNode
    SetStringAttribute(const char *attribute_name, const std::string &attribute)shaka::xml::XmlNode
    XmlNode(const char *name)shaka::xml::XmlNodeexplicit
    ~XmlNode() (defined in shaka::xml::XmlNode)shaka::xml::XmlNodevirtual
    SetFloatingPointAttribute(const std::string &attribute_name, double number) WARN_UNUSED_RESULTshaka::xml::XmlNode
    SetId(uint32_t id) WARN_UNUSED_RESULTshaka::xml::XmlNode
    SetIntegerAttribute(const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULTshaka::xml::XmlNode
    SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULTshaka::xml::XmlNode
    shaka::XmlEqual (defined in shaka::xml::XmlNode)shaka::xml::XmlNodefriend
    ToString(const std::string &comment) constshaka::xml::XmlNode
    XmlNode(const std::string &name)shaka::xml::XmlNodeexplicit
    XmlNode(XmlNode &&) (defined in shaka::xml::XmlNode)shaka::xml::XmlNode
    ~XmlNode() (defined in shaka::xml::XmlNode)shaka::xml::XmlNodevirtual
    diff --git a/docs/dc/d41/classshaka_1_1media_1_1BufferWriter.html b/docs/dc/d41/classshaka_1_1media_1_1BufferWriter.html index 428964ce44..569fa1e1ba 100644 --- a/docs/dc/d41/classshaka_1_1media_1_1BufferWriter.html +++ b/docs/dc/d41/classshaka_1_1media_1_1BufferWriter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::BufferWriter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    AppendInt (int64_
    diff --git a/docs/dc/d48/pssh__generator_8h_source.html b/docs/dc/d48/pssh__generator_8h_source.html index 7977f2f584..abfef4a351 100644 --- a/docs/dc/d48/pssh__generator_8h_source.html +++ b/docs/dc/d48/pssh__generator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/pssh_generator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    pssh_generator.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_PSSH_GENERATOR_H_
    8 #define PACKAGER_MEDIA_BASE_PSSH_GENERATOR_H_
    9 
    10 #include <vector>
    11 
    12 #include "packager/base/optional.h"
    13 #include "packager/media/base/protection_system_specific_info.h"
    14 #include "packager/status.h"
    15 
    16 // TODO(hmchen): move pssh related files into a sperate folder.
    17 namespace shaka {
    18 namespace media {
    19 
    21  public:
    24  PsshGenerator(const std::vector<uint8_t>& system_id, uint8_t box_version);
    25  virtual ~PsshGenerator();
    26 
    29  virtual bool SupportMultipleKeys() = 0;
    30 
    36  const std::vector<std::vector<uint8_t>>& key_ids,
    37  ProtectionSystemSpecificInfo* info) const;
    38 
    44  Status GeneratePsshFromKeyIdAndKey(const std::vector<uint8_t>& key_id,
    45  const std::vector<uint8_t>& key,
    46  ProtectionSystemSpecificInfo* info) const;
    47 
    48  private:
    52  virtual base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
    53  const std::vector<std::vector<uint8_t>>& key_ids) const = 0;
    54 
    59  virtual base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
    60  const std::vector<uint8_t>& key_id,
    61  const std::vector<uint8_t>& key) const = 0;
    62 
    63  std::vector<uint8_t> system_id_;
    64  uint8_t box_version_ = 0;
    65 };
    66 
    67 } // namespace media
    68 } // namespace shaka
    69 
    70 #endif // PACKAGER_MEDIA_BASE_PSSH_GENERATOR_H_
    PsshGenerator(const std::vector< uint8_t > &system_id, uint8_t box_version)
    -
    Status GeneratePsshFromKeyIds(const std::vector< std::vector< uint8_t >> &key_ids, ProtectionSystemSpecificInfo *info) const
    -
    All the methods that are virtual are virtual for mocking.
    - -
    virtual bool SupportMultipleKeys()=0
    - -
    Status GeneratePsshFromKeyIdAndKey(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key, ProtectionSystemSpecificInfo *info) const
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_PSSH_GENERATOR_H_
    +
    8 #define PACKAGER_MEDIA_BASE_PSSH_GENERATOR_H_
    +
    9 
    +
    10 #include <vector>
    +
    11 
    +
    12 #include "packager/base/optional.h"
    +
    13 #include "packager/media/base/protection_system_specific_info.h"
    +
    14 #include "packager/status.h"
    +
    15 
    +
    16 // TODO(hmchen): move pssh related files into a sperate folder.
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    + +
    21  public:
    +
    24  PsshGenerator(const std::vector<uint8_t>& system_id, uint8_t box_version);
    +
    25  virtual ~PsshGenerator();
    +
    26 
    +
    29  virtual bool SupportMultipleKeys() = 0;
    +
    30 
    + +
    36  const std::vector<std::vector<uint8_t>>& key_ids,
    +
    37  ProtectionSystemSpecificInfo* info) const;
    +
    38 
    +
    44  Status GeneratePsshFromKeyIdAndKey(const std::vector<uint8_t>& key_id,
    +
    45  const std::vector<uint8_t>& key,
    +
    46  ProtectionSystemSpecificInfo* info) const;
    +
    47 
    +
    48  private:
    +
    52  virtual base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
    +
    53  const std::vector<std::vector<uint8_t>>& key_ids) const = 0;
    +
    54 
    +
    59  virtual base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
    +
    60  const std::vector<uint8_t>& key_id,
    +
    61  const std::vector<uint8_t>& key) const = 0;
    +
    62 
    +
    63  std::vector<uint8_t> system_id_;
    +
    64  uint8_t box_version_ = 0;
    +
    65 };
    +
    66 
    +
    67 } // namespace media
    +
    68 } // namespace shaka
    +
    69 
    +
    70 #endif // PACKAGER_MEDIA_BASE_PSSH_GENERATOR_H_
    + + +
    virtual bool SupportMultipleKeys()=0
    +
    Status GeneratePsshFromKeyIds(const std::vector< std::vector< uint8_t >> &key_ids, ProtectionSystemSpecificInfo *info) const
    +
    PsshGenerator(const std::vector< uint8_t > &system_id, uint8_t box_version)
    +
    Status GeneratePsshFromKeyIdAndKey(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key, ProtectionSystemSpecificInfo *info) const
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/dc/d4a/structshaka_1_1media_1_1mp4_1_1ProtectionSystemSpecificHeader-members.html b/docs/dc/d4a/structshaka_1_1media_1_1mp4_1_1ProtectionSystemSpecificHeader-members.html index 260a00ccc8..61d1bbedcb 100644 --- a/docs/dc/d4a/structshaka_1_1media_1_1mp4_1_1ProtectionSystemSpecificHeader-members.html +++ b/docs/dc/d4a/structshaka_1_1media_1_1mp4_1_1ProtectionSystemSpecificHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dc/d4f/structshaka_1_1media_1_1mp4_1_1TrackHeader-members.html b/docs/dc/d4f/structshaka_1_1media_1_1mp4_1_1TrackHeader-members.html index e5c6a60397..c8b76b68be 100644 --- a/docs/dc/d4f/structshaka_1_1media_1_1mp4_1_1TrackHeader-members.html +++ b/docs/dc/d4f/structshaka_1_1media_1_1mp4_1_1TrackHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/d51/h265__byte__to__unit__stream__converter_8cc_source.html b/docs/dc/d51/h265__byte__to__unit__stream__converter_8cc_source.html index 0ec9375077..626e002bf6 100644 --- a/docs/dc/d51/h265__byte__to__unit__stream__converter_8cc_source.html +++ b/docs/dc/d51/h265__byte__to__unit__stream__converter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h265_byte_to_unit_stream_converter.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    h265_byte_to_unit_stream_converter.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/h265_byte_to_unit_stream_converter.h"
    8 
    9 #include <limits>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/media/base/buffer_writer.h"
    13 #include "packager/media/base/rcheck.h"
    14 #include "packager/media/codecs/h265_parser.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    21 
    23  H26xStreamFormat stream_format)
    24  : H26xByteToUnitStreamConverter(Nalu::kH265, stream_format) {}
    25 
    26 H265ByteToUnitStreamConverter::~H265ByteToUnitStreamConverter() {}
    27 
    29  std::vector<uint8_t>* decoder_config) const {
    30  DCHECK(decoder_config);
    31 
    32  if (last_sps_.empty() || last_pps_.empty() || last_vps_.empty()) {
    33  // No data available to construct HEVCDecoderConfigurationRecord.
    34  return false;
    35  }
    36 
    37  // We need to parse the SPS to get the data to add to the record.
    38  int id;
    39  Nalu nalu;
    40  H265Parser parser;
    41  RCHECK(nalu.Initialize(Nalu::kH265, last_sps_.data(), last_sps_.size()));
    42  RCHECK(parser.ParseSps(nalu, &id) == H265Parser::kOk);
    43  const H265Sps* sps = parser.GetSps(id);
    44 
    45  // Construct an HEVCDecoderConfigurationRecord containing a single SPS, PPS,
    46  // and VPS NALU. Please refer to ISO/IEC 14496-15 for format specifics.
    47  BufferWriter buffer(last_sps_.size() + last_pps_.size() + last_vps_.size() +
    48  100);
    49  buffer.AppendInt(static_cast<uint8_t>(1) /* version */);
    50  // (1) general_profile_space, general_tier_flag, general_profile_idc
    51  // (4) general_profile_compatibility_flags
    52  // (6) general_constraint_indicator_flags
    53  // (1) general_level_idc
    54  for (int byte : sps->general_profile_tier_level_data)
    55  buffer.AppendInt(static_cast<uint8_t>(byte));
    56 
    57  // The default value for this field is 0, which is Unknown.
    58  int min_spatial_segmentation_idc =
    59  sps->vui_parameters.min_spatial_segmentation_idc;
    60 
    61  buffer.AppendInt(
    62  static_cast<uint16_t>(0xf000 | min_spatial_segmentation_idc));
    63  buffer.AppendInt(static_cast<uint8_t>(0xfc) /* parallelismType = 0 */);
    64  buffer.AppendInt(static_cast<uint8_t>(0xfc | sps->chroma_format_idc));
    65  buffer.AppendInt(static_cast<uint8_t>(0xf8 | sps->bit_depth_luma_minus8));
    66  buffer.AppendInt(static_cast<uint8_t>(0xf8 | sps->bit_depth_chroma_minus8));
    67  buffer.AppendInt(static_cast<uint16_t>(0) /* avgFrameRate */);
    68  // Following flags are 0:
    69  // constantFrameRate
    70  // numTemporalLayers
    71  // temporalIdNested
    72  buffer.AppendInt(static_cast<uint8_t>(kUnitStreamNaluLengthSize - 1));
    73  buffer.AppendInt(static_cast<uint8_t>(3) /* numOfArrays */);
    74 
    75  // VPS
    76  const uint8_t kArrayCompleteness = 0x80;
    77  buffer.AppendInt(static_cast<uint8_t>(kArrayCompleteness | Nalu::H265_VPS));
    78  buffer.AppendInt(static_cast<uint16_t>(1) /* numNalus */);
    79  buffer.AppendInt(static_cast<uint16_t>(last_vps_.size()));
    80  buffer.AppendVector(last_vps_);
    81 
    82  // SPS
    83  buffer.AppendInt(static_cast<uint8_t>(kArrayCompleteness | Nalu::H265_SPS));
    84  buffer.AppendInt(static_cast<uint16_t>(1) /* numNalus */);
    85  buffer.AppendInt(static_cast<uint16_t>(last_sps_.size()));
    86  buffer.AppendVector(last_sps_);
    87 
    88  // PPS
    89  buffer.AppendInt(static_cast<uint8_t>(kArrayCompleteness | Nalu::H265_PPS));
    90  buffer.AppendInt(static_cast<uint16_t>(1) /* numNalus */);
    91  buffer.AppendInt(static_cast<uint16_t>(last_pps_.size()));
    92  buffer.AppendVector(last_pps_);
    93 
    94  buffer.SwapBuffer(decoder_config);
    95  return true;
    96 }
    97 
    98 bool H265ByteToUnitStreamConverter::ProcessNalu(const Nalu& nalu) {
    99  DCHECK(nalu.data());
    100 
    101  // Skip the start code, but keep the 2-byte NALU header.
    102  const uint8_t* nalu_ptr = nalu.data();
    103  const uint64_t nalu_size = nalu.payload_size() + nalu.header_size();
    104 
    105  switch (nalu.type()) {
    106  case Nalu::H265_SPS:
    107  if (strip_parameter_set_nalus())
    108  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_sps_);
    109  // Grab SPS NALU.
    110  last_sps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    111  return strip_parameter_set_nalus();
    112  case Nalu::H265_PPS:
    113  if (strip_parameter_set_nalus())
    114  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_pps_);
    115  // Grab PPS NALU.
    116  last_pps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    117  return strip_parameter_set_nalus();
    118  case Nalu::H265_VPS:
    119  if (strip_parameter_set_nalus())
    120  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_vps_);
    121  // Grab VPS NALU.
    122  last_vps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    123  return strip_parameter_set_nalus();
    124  case Nalu::H265_AUD:
    125  // Ignore AUD NALU.
    126  return true;
    127  default:
    128  // Have the base class handle other NALU types.
    129  return false;
    130  }
    131 }
    132 
    133 } // namespace media
    134 } // namespace shaka
    bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const override
    -
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    - -
    All the methods that are virtual are virtual for mocking.
    - -
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    - - -
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    - -
    const H265Sps * GetSps(int sps_id)
    Definition: h265_parser.cc:630
    - -
    int type() const
    Definition: nalu_reader.h:113
    -
    Result ParseSps(const Nalu &nalu, int *sps_id)
    Definition: h265_parser.cc:509
    -
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/h265_byte_to_unit_stream_converter.h"
    +
    8 
    +
    9 #include <limits>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/buffer_writer.h"
    +
    13 #include "packager/media/base/rcheck.h"
    +
    14 #include "packager/media/codecs/h265_parser.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    + + +
    21 
    + +
    23  H26xStreamFormat stream_format)
    +
    24  : H26xByteToUnitStreamConverter(Nalu::kH265, stream_format) {}
    +
    25 
    +
    26 H265ByteToUnitStreamConverter::~H265ByteToUnitStreamConverter() {}
    +
    27 
    + +
    29  std::vector<uint8_t>* decoder_config) const {
    +
    30  DCHECK(decoder_config);
    +
    31 
    +
    32  if (last_sps_.empty() || last_pps_.empty() || last_vps_.empty()) {
    +
    33  // No data available to construct HEVCDecoderConfigurationRecord.
    +
    34  return false;
    +
    35  }
    +
    36 
    +
    37  // We need to parse the SPS to get the data to add to the record.
    +
    38  int id;
    +
    39  Nalu nalu;
    +
    40  H265Parser parser;
    +
    41  RCHECK(nalu.Initialize(Nalu::kH265, last_sps_.data(), last_sps_.size()));
    +
    42  RCHECK(parser.ParseSps(nalu, &id) == H265Parser::kOk);
    +
    43  const H265Sps* sps = parser.GetSps(id);
    +
    44 
    +
    45  // Construct an HEVCDecoderConfigurationRecord containing a single SPS, PPS,
    +
    46  // and VPS NALU. Please refer to ISO/IEC 14496-15 for format specifics.
    +
    47  BufferWriter buffer(last_sps_.size() + last_pps_.size() + last_vps_.size() +
    +
    48  100);
    +
    49  buffer.AppendInt(static_cast<uint8_t>(1) /* version */);
    +
    50  // (1) general_profile_space, general_tier_flag, general_profile_idc
    +
    51  // (4) general_profile_compatibility_flags
    +
    52  // (6) general_constraint_indicator_flags
    +
    53  // (1) general_level_idc
    +
    54  for (int byte : sps->general_profile_tier_level_data)
    +
    55  buffer.AppendInt(static_cast<uint8_t>(byte));
    +
    56 
    +
    57  // The default value for this field is 0, which is Unknown.
    +
    58  int min_spatial_segmentation_idc =
    +
    59  sps->vui_parameters.min_spatial_segmentation_idc;
    +
    60 
    +
    61  buffer.AppendInt(
    +
    62  static_cast<uint16_t>(0xf000 | min_spatial_segmentation_idc));
    +
    63  buffer.AppendInt(static_cast<uint8_t>(0xfc) /* parallelismType = 0 */);
    +
    64  buffer.AppendInt(static_cast<uint8_t>(0xfc | sps->chroma_format_idc));
    +
    65  buffer.AppendInt(static_cast<uint8_t>(0xf8 | sps->bit_depth_luma_minus8));
    +
    66  buffer.AppendInt(static_cast<uint8_t>(0xf8 | sps->bit_depth_chroma_minus8));
    +
    67  buffer.AppendInt(static_cast<uint16_t>(0) /* avgFrameRate */);
    +
    68  // Following flags are 0:
    +
    69  // constantFrameRate
    +
    70  // numTemporalLayers
    +
    71  // temporalIdNested
    +
    72  buffer.AppendInt(static_cast<uint8_t>(kUnitStreamNaluLengthSize - 1));
    +
    73  buffer.AppendInt(static_cast<uint8_t>(3) /* numOfArrays */);
    +
    74 
    +
    75  // VPS
    +
    76  const uint8_t kArrayCompleteness = 0x80;
    +
    77  buffer.AppendInt(static_cast<uint8_t>(kArrayCompleteness | Nalu::H265_VPS));
    +
    78  buffer.AppendInt(static_cast<uint16_t>(1) /* numNalus */);
    +
    79  buffer.AppendInt(static_cast<uint16_t>(last_vps_.size()));
    +
    80  buffer.AppendVector(last_vps_);
    +
    81 
    +
    82  // SPS
    +
    83  buffer.AppendInt(static_cast<uint8_t>(kArrayCompleteness | Nalu::H265_SPS));
    +
    84  buffer.AppendInt(static_cast<uint16_t>(1) /* numNalus */);
    +
    85  buffer.AppendInt(static_cast<uint16_t>(last_sps_.size()));
    +
    86  buffer.AppendVector(last_sps_);
    +
    87 
    +
    88  // PPS
    +
    89  buffer.AppendInt(static_cast<uint8_t>(kArrayCompleteness | Nalu::H265_PPS));
    +
    90  buffer.AppendInt(static_cast<uint16_t>(1) /* numNalus */);
    +
    91  buffer.AppendInt(static_cast<uint16_t>(last_pps_.size()));
    +
    92  buffer.AppendVector(last_pps_);
    +
    93 
    +
    94  buffer.SwapBuffer(decoder_config);
    +
    95  return true;
    +
    96 }
    +
    97 
    +
    98 bool H265ByteToUnitStreamConverter::ProcessNalu(const Nalu& nalu) {
    +
    99  DCHECK(nalu.data());
    +
    100 
    +
    101  // Skip the start code, but keep the 2-byte NALU header.
    +
    102  const uint8_t* nalu_ptr = nalu.data();
    +
    103  const uint64_t nalu_size = nalu.payload_size() + nalu.header_size();
    +
    104 
    +
    105  switch (nalu.type()) {
    +
    106  case Nalu::H265_SPS:
    +
    107  if (strip_parameter_set_nalus())
    +
    108  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_sps_);
    +
    109  // Grab SPS NALU.
    +
    110  last_sps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    +
    111  return strip_parameter_set_nalus();
    +
    112  case Nalu::H265_PPS:
    +
    113  if (strip_parameter_set_nalus())
    +
    114  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_pps_);
    +
    115  // Grab PPS NALU.
    +
    116  last_pps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    +
    117  return strip_parameter_set_nalus();
    +
    118  case Nalu::H265_VPS:
    +
    119  if (strip_parameter_set_nalus())
    +
    120  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_vps_);
    +
    121  // Grab VPS NALU.
    +
    122  last_vps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    +
    123  return strip_parameter_set_nalus();
    +
    124  case Nalu::H265_AUD:
    +
    125  // Ignore AUD NALU.
    +
    126  return true;
    +
    127  default:
    +
    128  // Have the base class handle other NALU types.
    +
    129  return false;
    +
    130  }
    +
    131 }
    +
    132 
    +
    133 } // namespace media
    +
    134 } // namespace shaka
    + + + +
    bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const override
    + +
    Result ParseSps(const Nalu &nalu, int *sps_id)
    Definition: h265_parser.cc:509
    +
    const H265Sps * GetSps(int sps_id)
    Definition: h265_parser.cc:630
    +
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    + +
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    +
    int type() const
    Definition: nalu_reader.h:113
    +
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    +
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/dc/d52/decoding__time__iterator_8h_source.html b/docs/dc/d52/decoding__time__iterator_8h_source.html index 6c25f09144..e2f6f6dd9a 100644 --- a/docs/dc/d52/decoding__time__iterator_8h_source.html +++ b/docs/dc/d52/decoding__time__iterator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/decoding_time_iterator.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    decoding_time_iterator.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_DECODING_TIME_ITERATOR_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_DECODING_TIME_ITERATOR_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <vector>
    13 
    14 #include "packager/base/macros.h"
    15 #include "packager/media/formats/mp4/box_definitions.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 namespace mp4 {
    20 
    25  public:
    27  explicit DecodingTimeIterator(
    28  const DecodingTimeToSample& decoding_time_to_sample);
    30 
    33  bool AdvanceSample();
    34 
    37  bool IsValid() const;
    38 
    40  uint32_t sample_delta() const { return iterator_->sample_delta; }
    41 
    43  uint64_t Duration(uint32_t start_sample, uint32_t end_sample) const;
    44 
    46  uint32_t NumSamples() const;
    47 
    48  private:
    49  uint32_t sample_index_;
    50  const std::vector<DecodingTime>& decoding_time_table_;
    51  std::vector<DecodingTime>::const_iterator iterator_;
    52 
    53  DISALLOW_COPY_AND_ASSIGN(DecodingTimeIterator);
    54 };
    55 
    56 } // namespace mp4
    57 } // namespace media
    58 } // namespace shaka
    59 
    60 #endif // PACKAGER_MEDIA_FORMATS_MP4_DECODING_TIME_ITERATOR_H_
    - -
    All the methods that are virtual are virtual for mocking.
    -
    uint64_t Duration(uint32_t start_sample, uint32_t end_sample) const
    -
    DecodingTimeIterator(const DecodingTimeToSample &decoding_time_to_sample)
    Create DecodingTimeIterator from decoding time to sample box.
    - - - - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_DECODING_TIME_ITERATOR_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_DECODING_TIME_ITERATOR_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/macros.h"
    +
    15 #include "packager/media/formats/mp4/box_definitions.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 namespace mp4 {
    +
    20 
    + +
    25  public:
    +
    27  explicit DecodingTimeIterator(
    +
    28  const DecodingTimeToSample& decoding_time_to_sample);
    + +
    30 
    +
    33  bool AdvanceSample();
    +
    34 
    +
    37  bool IsValid() const;
    +
    38 
    +
    40  uint32_t sample_delta() const { return iterator_->sample_delta; }
    +
    41 
    +
    43  uint64_t Duration(uint32_t start_sample, uint32_t end_sample) const;
    +
    44 
    +
    46  uint32_t NumSamples() const;
    +
    47 
    +
    48  private:
    +
    49  uint32_t sample_index_;
    +
    50  const std::vector<DecodingTime>& decoding_time_table_;
    +
    51  std::vector<DecodingTime>::const_iterator iterator_;
    +
    52 
    +
    53  DISALLOW_COPY_AND_ASSIGN(DecodingTimeIterator);
    +
    54 };
    +
    55 
    +
    56 } // namespace mp4
    +
    57 } // namespace media
    +
    58 } // namespace shaka
    +
    59 
    +
    60 #endif // PACKAGER_MEDIA_FORMATS_MP4_DECODING_TIME_ITERATOR_H_
    + +
    uint64_t Duration(uint32_t start_sample, uint32_t end_sample) const
    + +
    DecodingTimeIterator(const DecodingTimeToSample &decoding_time_to_sample)
    Create DecodingTimeIterator from decoding time to sample box.
    + + + +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/dc/d52/sync__point__queue_8cc_source.html b/docs/dc/d52/sync__point__queue_8cc_source.html index 8064409db1..b616058a16 100644 --- a/docs/dc/d52/sync__point__queue_8cc_source.html +++ b/docs/dc/d52/sync__point__queue_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking/sync_point_queue.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    sync_point_queue.cc
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/chunking/sync_point_queue.h"
    8 #include "packager/media/base/media_handler.h"
    9 
    10 #include <algorithm>
    11 #include <limits>
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 SyncPointQueue::SyncPointQueue(const AdCueGeneratorParams& params)
    17  : sync_condition_(&lock_) {
    18  for (const Cuepoint& point : params.cue_points) {
    19  std::shared_ptr<CueEvent> event = std::make_shared<CueEvent>();
    20  event->time_in_seconds = point.start_time_in_seconds;
    21  unpromoted_[point.start_time_in_seconds] = std::move(event);
    22  }
    23 }
    24 
    26  base::AutoLock auto_lock(lock_);
    27  thread_count_++;
    28 }
    29 
    31  {
    32  base::AutoLock auto_lock(lock_);
    33  cancelled_ = true;
    34  }
    35  sync_condition_.Broadcast();
    36 }
    37 
    38 double SyncPointQueue::GetHint(double time_in_seconds) {
    39  base::AutoLock auto_lock(lock_);
    40 
    41  auto iter = promoted_.upper_bound(time_in_seconds);
    42  if (iter != promoted_.end())
    43  return iter->first;
    44 
    45  iter = unpromoted_.upper_bound(time_in_seconds);
    46  if (iter != unpromoted_.end())
    47  return iter->first;
    48 
    49  // Use MAX DOUBLE as the fall back so that we can force all streams to run
    50  // out all their samples even when there are no cues.
    51  return std::numeric_limits<double>::max();
    52 }
    53 
    54 std::shared_ptr<const CueEvent> SyncPointQueue::GetNext(
    55  double hint_in_seconds) {
    56  base::AutoLock auto_lock(lock_);
    57  while (!cancelled_) {
    58  // Find the promoted cue that would line up with our hint, which is the
    59  // first cue that is not less than |hint_in_seconds|.
    60  auto iter = promoted_.lower_bound(hint_in_seconds);
    61  if (iter != promoted_.end()) {
    62  return iter->second;
    63  }
    64 
    65  // Promote |hint_in_seconds| if everyone is waiting.
    66  if (waiting_thread_count_ + 1 == thread_count_) {
    67  std::shared_ptr<const CueEvent> cue = PromoteAtNoLocking(hint_in_seconds);
    68  CHECK(cue);
    69  return cue;
    70  }
    71 
    72  waiting_thread_count_++;
    73  // This blocks until either a cue is promoted or all threads are blocked
    74  // (in which case, the unpromoted cue at the hint will be self-promoted
    75  // and returned - see section above). Spurious signal events are possible
    76  // with most condition variable implementations, so if it returns, we go
    77  // back and check if a cue is actually promoted or not.
    78  sync_condition_.Wait();
    79  waiting_thread_count_--;
    80  }
    81  return nullptr;
    82 }
    83 
    84 std::shared_ptr<const CueEvent> SyncPointQueue::PromoteAt(
    85  double time_in_seconds) {
    86  base::AutoLock auto_lock(lock_);
    87  return PromoteAtNoLocking(time_in_seconds);
    88 }
    89 
    90 bool SyncPointQueue::HasMore(double hint_in_seconds) const {
    91  return hint_in_seconds < std::numeric_limits<double>::max();
    92 }
    93 
    94 std::shared_ptr<const CueEvent> SyncPointQueue::PromoteAtNoLocking(
    95  double time_in_seconds) {
    96  lock_.AssertAcquired();
    97 
    98  // It is possible that |time_in_seconds| has been promoted.
    99  auto iter = promoted_.find(time_in_seconds);
    100  if (iter != promoted_.end())
    101  return iter->second;
    102 
    103  // Find the unpromoted cue that would work for the given time, which is the
    104  // first cue that is not greater than |time_in_seconds|.
    105  // So find the the first cue that is greater than |time_in_seconds| first and
    106  // then get the previous one.
    107  iter = unpromoted_.upper_bound(time_in_seconds);
    108  // The first cue in |unpromoted_| should not be greater than
    109  // |time_in_seconds|. It could happen only if it has been promoted at a
    110  // different timestamp, which can only be the result of unaligned GOPs.
    111  if (iter == unpromoted_.begin())
    112  return nullptr;
    113  auto prev_iter = std::prev(iter);
    114  DCHECK(prev_iter != unpromoted_.end());
    115 
    116  std::shared_ptr<CueEvent> cue = prev_iter->second;
    117  cue->time_in_seconds = time_in_seconds;
    118 
    119  promoted_[time_in_seconds] = cue;
    120  // Remove all unpromoted cues up to the cue that was just promoted.
    121  // User may provide multiple cue points at the same or similar timestamps. The
    122  // extra unused cues are simply ignored.
    123  unpromoted_.erase(unpromoted_.begin(), iter);
    124 
    125  // Wake up other threads that may be waiting.
    126  sync_condition_.Broadcast();
    127  return std::move(cue);
    128 }
    129 
    130 } // namespace media
    131 } // namespace shaka
    -
    bool HasMore(double hint_in_seconds) const
    -
    All the methods that are virtual are virtual for mocking.
    -
    std::shared_ptr< const CueEvent > GetNext(double hint_in_seconds)
    -
    std::shared_ptr< const CueEvent > PromoteAt(double time_in_seconds)
    -
    void Cancel()
    Cancel the queue and unblock all threads.
    -
    double GetHint(double time_in_seconds)
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/chunking/sync_point_queue.h"
    +
    8 #include "packager/media/base/media_handler.h"
    +
    9 
    +
    10 #include <algorithm>
    +
    11 #include <limits>
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 SyncPointQueue::SyncPointQueue(const AdCueGeneratorParams& params)
    +
    17  : sync_condition_(&lock_) {
    +
    18  for (const Cuepoint& point : params.cue_points) {
    +
    19  std::shared_ptr<CueEvent> event = std::make_shared<CueEvent>();
    +
    20  event->time_in_seconds = point.start_time_in_seconds;
    +
    21  unpromoted_[point.start_time_in_seconds] = std::move(event);
    +
    22  }
    +
    23 }
    +
    24 
    +
    25 void SyncPointQueue::AddThread() {
    +
    26  base::AutoLock auto_lock(lock_);
    +
    27  thread_count_++;
    +
    28 }
    +
    29 
    +
    30 void SyncPointQueue::Cancel() {
    +
    31  {
    +
    32  base::AutoLock auto_lock(lock_);
    +
    33  cancelled_ = true;
    +
    34  }
    +
    35  sync_condition_.Broadcast();
    +
    36 }
    +
    37 
    +
    38 double SyncPointQueue::GetHint(double time_in_seconds) {
    +
    39  base::AutoLock auto_lock(lock_);
    +
    40 
    +
    41  auto iter = promoted_.upper_bound(time_in_seconds);
    +
    42  if (iter != promoted_.end())
    +
    43  return iter->first;
    +
    44 
    +
    45  iter = unpromoted_.upper_bound(time_in_seconds);
    +
    46  if (iter != unpromoted_.end())
    +
    47  return iter->first;
    +
    48 
    +
    49  // Use MAX DOUBLE as the fall back so that we can force all streams to run
    +
    50  // out all their samples even when there are no cues.
    +
    51  return std::numeric_limits<double>::max();
    +
    52 }
    +
    53 
    +
    54 std::shared_ptr<const CueEvent> SyncPointQueue::GetNext(
    +
    55  double hint_in_seconds) {
    +
    56  base::AutoLock auto_lock(lock_);
    +
    57  while (!cancelled_) {
    +
    58  // Find the promoted cue that would line up with our hint, which is the
    +
    59  // first cue that is not less than |hint_in_seconds|.
    +
    60  auto iter = promoted_.lower_bound(hint_in_seconds);
    +
    61  if (iter != promoted_.end()) {
    +
    62  return iter->second;
    +
    63  }
    +
    64 
    +
    65  // Promote |hint_in_seconds| if everyone is waiting.
    +
    66  if (waiting_thread_count_ + 1 == thread_count_) {
    +
    67  std::shared_ptr<const CueEvent> cue = PromoteAtNoLocking(hint_in_seconds);
    +
    68  CHECK(cue);
    +
    69  return cue;
    +
    70  }
    +
    71 
    +
    72  waiting_thread_count_++;
    +
    73  // This blocks until either a cue is promoted or all threads are blocked
    +
    74  // (in which case, the unpromoted cue at the hint will be self-promoted
    +
    75  // and returned - see section above). Spurious signal events are possible
    +
    76  // with most condition variable implementations, so if it returns, we go
    +
    77  // back and check if a cue is actually promoted or not.
    +
    78  sync_condition_.Wait();
    +
    79  waiting_thread_count_--;
    +
    80  }
    +
    81  return nullptr;
    +
    82 }
    +
    83 
    +
    84 std::shared_ptr<const CueEvent> SyncPointQueue::PromoteAt(
    +
    85  double time_in_seconds) {
    +
    86  base::AutoLock auto_lock(lock_);
    +
    87  return PromoteAtNoLocking(time_in_seconds);
    +
    88 }
    +
    89 
    +
    90 bool SyncPointQueue::HasMore(double hint_in_seconds) const {
    +
    91  return hint_in_seconds < std::numeric_limits<double>::max();
    +
    92 }
    +
    93 
    +
    94 std::shared_ptr<const CueEvent> SyncPointQueue::PromoteAtNoLocking(
    +
    95  double time_in_seconds) {
    +
    96  lock_.AssertAcquired();
    +
    97 
    +
    98  // It is possible that |time_in_seconds| has been promoted.
    +
    99  auto iter = promoted_.find(time_in_seconds);
    +
    100  if (iter != promoted_.end())
    +
    101  return iter->second;
    +
    102 
    +
    103  // Find the unpromoted cue that would work for the given time, which is the
    +
    104  // first cue that is not greater than |time_in_seconds|.
    +
    105  // So find the the first cue that is greater than |time_in_seconds| first and
    +
    106  // then get the previous one.
    +
    107  iter = unpromoted_.upper_bound(time_in_seconds);
    +
    108  // The first cue in |unpromoted_| should not be greater than
    +
    109  // |time_in_seconds|. It could happen only if it has been promoted at a
    +
    110  // different timestamp, which can only be the result of unaligned GOPs.
    +
    111  if (iter == unpromoted_.begin())
    +
    112  return nullptr;
    +
    113  auto prev_iter = std::prev(iter);
    +
    114  DCHECK(prev_iter != unpromoted_.end());
    +
    115 
    +
    116  std::shared_ptr<CueEvent> cue = prev_iter->second;
    +
    117  cue->time_in_seconds = time_in_seconds;
    +
    118 
    +
    119  promoted_[time_in_seconds] = cue;
    +
    120  // Remove all unpromoted cues up to the cue that was just promoted.
    +
    121  // User may provide multiple cue points at the same or similar timestamps. The
    +
    122  // extra unused cues are simply ignored.
    +
    123  unpromoted_.erase(unpromoted_.begin(), iter);
    +
    124 
    +
    125  // Wake up other threads that may be waiting.
    +
    126  sync_condition_.Broadcast();
    +
    127  return std::move(cue);
    +
    128 }
    +
    129 
    +
    130 } // namespace media
    +
    131 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d53/webm_2segmenter_8cc_source.html b/docs/dc/d53/webm_2segmenter_8cc_source.html index a7a95a0319..512381065b 100644 --- a/docs/dc/d53/webm_2segmenter_8cc_source.html +++ b/docs/dc/d53/webm_2segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/segmenter.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    segmenter.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/webm/segmenter.h"
    8 
    9 #include "packager/base/time/time.h"
    10 #include "packager/media/base/audio_stream_info.h"
    11 #include "packager/media/base/media_handler.h"
    12 #include "packager/media/base/media_sample.h"
    13 #include "packager/media/base/muxer_options.h"
    14 #include "packager/media/base/muxer_util.h"
    15 #include "packager/media/base/stream_info.h"
    16 #include "packager/media/base/video_stream_info.h"
    17 #include "packager/media/codecs/vp_codec_configuration_record.h"
    18 #include "packager/media/event/muxer_listener.h"
    19 #include "packager/media/event/progress_listener.h"
    20 #include "packager/media/formats/webm/encryptor.h"
    21 #include "packager/media/formats/webm/webm_constants.h"
    22 #include "packager/third_party/libwebm/src/mkvmuxerutil.hpp"
    23 #include "packager/third_party/libwebm/src/webmids.hpp"
    24 #include "packager/version/version.h"
    25 
    26 using mkvmuxer::AudioTrack;
    27 using mkvmuxer::VideoTrack;
    28 
    29 namespace shaka {
    30 namespace media {
    31 namespace webm {
    32 namespace {
    33 const int64_t kTimecodeScale = 1000000;
    34 const int64_t kSecondsToNs = 1000000000L;
    35 
    36 // Round to closest integer.
    37 uint64_t Round(double value) {
    38  return static_cast<uint64_t>(value + 0.5);
    39 }
    40 
    41 // There are three different kinds of timestamp here:
    42 // (1) ISO-BMFF timestamp (seconds scaled by ISO-BMFF timescale)
    43 // This is used in our MediaSample and StreamInfo structures.
    44 // (2) WebM timecode (seconds scaled by kSecondsToNs / WebM timecode scale)
    45 // This is used in most WebM structures.
    46 // (3) Nanoseconds (seconds scaled by kSecondsToNs)
    47 // This is used in some WebM structures, e.g. Frame.
    48 // We use Nanoseconds as intermediate format here for conversion, in
    49 // uint64_t/int64_t, which is sufficient to represent a time as large as 292
    50 // years.
    51 
    52 uint64_t BmffTimestampToNs(uint64_t timestamp, uint64_t time_scale) {
    53  // Casting to double is needed otherwise kSecondsToNs * timestamp may overflow
    54  // uint64_t/int64_t.
    55  return Round(static_cast<double>(timestamp) / time_scale * kSecondsToNs);
    56 }
    57 
    58 uint64_t NsToBmffTimestamp(uint64_t ns, uint64_t time_scale) {
    59  // Casting to double is needed otherwise ns * time_scale may overflow
    60  // uint64_t/int64_t.
    61  return Round(static_cast<double>(ns) / kSecondsToNs * time_scale);
    62 }
    63 
    64 uint64_t NsToWebMTimecode(uint64_t ns, uint64_t timecode_scale) {
    65  return ns / timecode_scale;
    66 }
    67 
    68 uint64_t WebMTimecodeToNs(uint64_t timecode, uint64_t timecode_scale) {
    69  return timecode * timecode_scale;
    70 }
    71 
    72 } // namespace
    73 
    74 Segmenter::Segmenter(const MuxerOptions& options) : options_(options) {}
    75 
    76 Segmenter::~Segmenter() {}
    77 
    79  ProgressListener* progress_listener,
    80  MuxerListener* muxer_listener) {
    81  is_encrypted_ = info.is_encrypted();
    82  duration_ = info.duration();
    83  time_scale_ = info.time_scale();
    84 
    85  muxer_listener_ = muxer_listener;
    86 
    87  // Use media duration as progress target.
    88  progress_target_ = info.duration();
    89  progress_listener_ = progress_listener;
    90 
    91  segment_info_.Init();
    92  segment_info_.set_timecode_scale(kTimecodeScale);
    93 
    94  const std::string version = GetPackagerVersion();
    95  if (!version.empty()) {
    96  segment_info_.set_writing_app(
    97  (GetPackagerProjectUrl() + " version " + version).c_str());
    98  }
    99 
    100  if (options().segment_template.empty()) {
    101  // Set an initial duration so the duration element is written; will be
    102  // overwritten at the end. This works because this is a float and floats
    103  // are always the same size.
    104  segment_info_.set_duration(1);
    105  }
    106 
    107  // Create the track info.
    108  // The seed is only used to create a UID which we overwrite later.
    109  unsigned int seed = 0;
    110  std::unique_ptr<mkvmuxer::Track> track;
    111  Status status;
    112  switch (info.stream_type()) {
    113  case kStreamVideo: {
    114  std::unique_ptr<VideoTrack> video_track(new VideoTrack(&seed));
    115  status = InitializeVideoTrack(static_cast<const VideoStreamInfo&>(info),
    116  video_track.get());
    117  track = std::move(video_track);
    118  break;
    119  }
    120  case kStreamAudio: {
    121  std::unique_ptr<AudioTrack> audio_track(new AudioTrack(&seed));
    122  status = InitializeAudioTrack(static_cast<const AudioStreamInfo&>(info),
    123  audio_track.get());
    124  track = std::move(audio_track);
    125  break;
    126  }
    127  default:
    128  NOTIMPLEMENTED() << "Not implemented for stream type: "
    129  << info.stream_type();
    130  status = Status(error::UNIMPLEMENTED, "Not implemented for stream type");
    131  }
    132  if (!status.ok())
    133  return status;
    134 
    135  if (info.is_encrypted()) {
    136  if (info.encryption_config().per_sample_iv_size != kWebMIvSize)
    137  return Status(error::MUXER_FAILURE, "Incorrect size WebM encryption IV.");
    138  status = UpdateTrackForEncryption(info.encryption_config().key_id,
    139  track.get());
    140  if (!status.ok())
    141  return status;
    142  }
    143 
    144  tracks_.AddTrack(track.get(), info.track_id());
    145  // number() is only available after the above instruction.
    146  track_id_ = track->number();
    147  // |tracks_| owns |track|.
    148  track.release();
    149  return DoInitialize();
    150 }
    151 
    153  uint64_t duration =
    154  prev_sample_->pts() - first_timestamp_ + prev_sample_->duration();
    155  segment_info_.set_duration(FromBmffTimestamp(duration));
    156  return DoFinalize();
    157 }
    158 
    159 Status Segmenter::AddSample(const MediaSample& source_sample) {
    160  std::shared_ptr<MediaSample> sample(source_sample.Clone());
    161 
    162  if (sample_duration_ == 0) {
    163  first_timestamp_ = sample->pts();
    164  sample_duration_ = sample->duration();
    165  if (muxer_listener_)
    166  muxer_listener_->OnSampleDurationReady(sample_duration_);
    167  }
    168 
    169  UpdateProgress(sample->duration());
    170 
    171  // This writes frames in a delay. Meaning that the previous frame is written
    172  // on this call to AddSample. The current frame is stored until the next
    173  // call. This is done to determine which frame is the last in a Cluster.
    174  // This first block determines if this is a new Cluster and writes the
    175  // previous frame first before creating the new Cluster.
    176 
    177  Status status;
    178  if (new_segment_ || new_subsegment_) {
    179  status = NewSegment(sample->pts(), new_subsegment_);
    180  } else {
    181  status = WriteFrame(false /* write_duration */);
    182  }
    183  if (!status.ok())
    184  return status;
    185 
    186  if (is_encrypted_)
    187  UpdateFrameForEncryption(sample.get());
    188 
    189  new_subsegment_ = false;
    190  new_segment_ = false;
    191  prev_sample_ = sample;
    192  return Status::OK;
    193 }
    194 
    195 Status Segmenter::FinalizeSegment(uint64_t start_timestamp,
    196  uint64_t duration_timestamp,
    197  bool is_subsegment) {
    198  if (is_subsegment)
    199  new_subsegment_ = true;
    200  else
    201  new_segment_ = true;
    202  return WriteFrame(true /* write duration */);
    203 }
    204 
    205 float Segmenter::GetDurationInSeconds() const {
    206  return WebMTimecodeToNs(segment_info_.duration(),
    207  segment_info_.timecode_scale()) /
    208  static_cast<double>(kSecondsToNs);
    209 }
    210 
    211 uint64_t Segmenter::FromBmffTimestamp(uint64_t bmff_timestamp) {
    212  return NsToWebMTimecode(
    213  BmffTimestampToNs(bmff_timestamp, time_scale_),
    214  segment_info_.timecode_scale());
    215 }
    216 
    217 uint64_t Segmenter::FromWebMTimecode(uint64_t webm_timecode) {
    218  return NsToBmffTimestamp(
    219  WebMTimecodeToNs(webm_timecode, segment_info_.timecode_scale()),
    220  time_scale_);
    221 }
    222 
    223 Status Segmenter::WriteSegmentHeader(uint64_t file_size, MkvWriter* writer) {
    224  Status error_status(error::FILE_FAILURE, "Error writing segment header.");
    225 
    226  if (!WriteEbmlHeader(writer))
    227  return error_status;
    228 
    229  if (WriteID(writer, mkvmuxer::kMkvSegment) != 0)
    230  return error_status;
    231 
    232  const uint64_t segment_size_size = 8;
    233  segment_payload_pos_ = writer->Position() + segment_size_size;
    234  if (file_size > 0) {
    235  // We want the size of the segment element, so subtract the header.
    236  if (WriteUIntSize(writer, file_size - segment_payload_pos_,
    237  segment_size_size) != 0)
    238  return error_status;
    239  if (!seek_head_.Write(writer))
    240  return error_status;
    241  } else {
    242  if (SerializeInt(writer, mkvmuxer::kEbmlUnknownValue, segment_size_size) !=
    243  0)
    244  return error_status;
    245  // We don't know the header size, so write a placeholder.
    246  if (!seek_head_.WriteVoid(writer))
    247  return error_status;
    248  }
    249 
    250  seek_head_.set_info_pos(writer->Position() - segment_payload_pos_);
    251  if (!segment_info_.Write(writer))
    252  return error_status;
    253 
    254  seek_head_.set_tracks_pos(writer->Position() - segment_payload_pos_);
    255  if (!tracks_.Write(writer))
    256  return error_status;
    257 
    258  return Status::OK;
    259 }
    260 
    261 Status Segmenter::SetCluster(uint64_t start_webm_timecode,
    262  uint64_t position,
    263  MkvWriter* writer) {
    264  const uint64_t scale = segment_info_.timecode_scale();
    265  cluster_.reset(new mkvmuxer::Cluster(start_webm_timecode, position, scale));
    266  cluster_->Init(writer);
    267  return Status::OK;
    268 }
    269 
    270 void Segmenter::UpdateProgress(uint64_t progress) {
    271  accumulated_progress_ += progress;
    272  if (!progress_listener_ || progress_target_ == 0)
    273  return;
    274  // It might happen that accumulated progress exceeds progress_target due to
    275  // computation errors, e.g. rounding error. Cap it so it never reports > 100%
    276  // progress.
    277  if (accumulated_progress_ >= progress_target_) {
    278  progress_listener_->OnProgress(1.0);
    279  } else {
    280  progress_listener_->OnProgress(static_cast<double>(accumulated_progress_) /
    281  progress_target_);
    282  }
    283 }
    284 
    285 Status Segmenter::InitializeVideoTrack(const VideoStreamInfo& info,
    286  VideoTrack* track) {
    287  if (info.codec() == kCodecAV1) {
    288  track->set_codec_id("V_AV1");
    289  if (!track->SetCodecPrivate(info.codec_config().data(),
    290  info.codec_config().size())) {
    291  return Status(error::INTERNAL_ERROR,
    292  "Private codec data required for AV1 streams");
    293  }
    294  } else if (info.codec() == kCodecVP8) {
    295  track->set_codec_id("V_VP8");
    296  } else if (info.codec() == kCodecVP9) {
    297  track->set_codec_id("V_VP9");
    298 
    299  // The |StreamInfo::codec_config| field is stored using the MP4 format; we
    300  // need to convert it to the WebM format.
    301  VPCodecConfigurationRecord vp_config;
    302  if (!vp_config.ParseMP4(info.codec_config())) {
    303  return Status(error::INTERNAL_ERROR,
    304  "Unable to parse VP9 codec configuration");
    305  }
    306 
    307  mkvmuxer::Colour colour;
    308  if (vp_config.matrix_coefficients() != AVCOL_SPC_UNSPECIFIED) {
    309  colour.set_matrix_coefficients(vp_config.matrix_coefficients());
    310  }
    311  if (vp_config.transfer_characteristics() != AVCOL_TRC_UNSPECIFIED) {
    312  colour.set_transfer_characteristics(vp_config.transfer_characteristics());
    313  }
    314  if (vp_config.color_primaries() != AVCOL_PRI_UNSPECIFIED) {
    315  colour.set_primaries(vp_config.color_primaries());
    316  }
    317  if (!track->SetColour(colour)) {
    318  return Status(error::INTERNAL_ERROR,
    319  "Failed to setup color element for VPx streams");
    320  }
    321 
    322  std::vector<uint8_t> codec_config;
    323  vp_config.WriteWebM(&codec_config);
    324  if (!track->SetCodecPrivate(codec_config.data(), codec_config.size())) {
    325  return Status(error::INTERNAL_ERROR,
    326  "Private codec data required for VPx streams");
    327  }
    328  } else {
    329  LOG(ERROR) << "Only VP8, VP9 and AV1 video codecs are supported in WebM.";
    330  return Status(error::UNIMPLEMENTED,
    331  "Only VP8, VP9 and AV1 video codecs are supported in WebM.");
    332  }
    333 
    334  track->set_uid(info.track_id());
    335  if (!info.language().empty())
    336  track->set_language(info.language().c_str());
    337  track->set_type(mkvmuxer::Tracks::kVideo);
    338  track->set_width(info.width());
    339  track->set_height(info.height());
    340  track->set_display_height(info.height());
    341  track->set_display_width(info.width() * info.pixel_width() /
    342  info.pixel_height());
    343  return Status::OK;
    344 }
    345 
    346 Status Segmenter::InitializeAudioTrack(const AudioStreamInfo& info,
    347  AudioTrack* track) {
    348  if (info.codec() == kCodecOpus) {
    349  track->set_codec_id(mkvmuxer::Tracks::kOpusCodecId);
    350  } else if (info.codec() == kCodecVorbis) {
    351  track->set_codec_id(mkvmuxer::Tracks::kVorbisCodecId);
    352  } else {
    353  LOG(ERROR) << "Only Vorbis and Opus audio codec are supported in WebM.";
    354  return Status(error::UNIMPLEMENTED,
    355  "Only Vorbis and Opus audio codecs are supported in WebM.");
    356  }
    357  if (!track->SetCodecPrivate(info.codec_config().data(),
    358  info.codec_config().size())) {
    359  return Status(error::INTERNAL_ERROR,
    360  "Private codec data required for audio streams");
    361  }
    362 
    363  track->set_uid(info.track_id());
    364  if (!info.language().empty())
    365  track->set_language(info.language().c_str());
    366  track->set_type(mkvmuxer::Tracks::kAudio);
    367  track->set_sample_rate(info.sampling_frequency());
    368  track->set_channels(info.num_channels());
    369  track->set_seek_pre_roll(info.seek_preroll_ns());
    370  track->set_codec_delay(info.codec_delay_ns());
    371  return Status::OK;
    372 }
    373 
    374 Status Segmenter::WriteFrame(bool write_duration) {
    375  // Create a frame manually so we can create non-SimpleBlock frames. This
    376  // is required to allow the frame duration to be added. If the duration
    377  // is not set, then a SimpleBlock will still be written.
    378  mkvmuxer::Frame frame;
    379 
    380  if (!frame.Init(prev_sample_->data(), prev_sample_->data_size())) {
    381  return Status(error::MUXER_FAILURE,
    382  "Error adding sample to segment: Frame::Init failed");
    383  }
    384 
    385  if (write_duration) {
    386  frame.set_duration(
    387  BmffTimestampToNs(prev_sample_->duration(), time_scale_));
    388  }
    389  frame.set_is_key(prev_sample_->is_key_frame());
    390  frame.set_timestamp(
    391  BmffTimestampToNs(prev_sample_->pts(), time_scale_));
    392  frame.set_track_number(track_id_);
    393 
    394  if (prev_sample_->side_data_size() > 0) {
    395  uint64_t block_add_id;
    396  // First 8 bytes of side_data is the BlockAddID element's value, which is
    397  // done to mimic ffmpeg behavior. See webm_cluster_parser.cc for details.
    398  CHECK_GT(prev_sample_->side_data_size(), sizeof(block_add_id));
    399  memcpy(&block_add_id, prev_sample_->side_data(), sizeof(block_add_id));
    400  if (!frame.AddAdditionalData(
    401  prev_sample_->side_data() + sizeof(block_add_id),
    402  prev_sample_->side_data_size() - sizeof(block_add_id),
    403  block_add_id)) {
    404  return Status(
    405  error::MUXER_FAILURE,
    406  "Error adding sample to segment: Frame::AddAditionalData Failed");
    407  }
    408  }
    409 
    410  if (!prev_sample_->is_key_frame() && !frame.CanBeSimpleBlock()) {
    411  frame.set_reference_block_timestamp(
    412  BmffTimestampToNs(reference_frame_timestamp_, time_scale_));
    413  }
    414 
    415  // GetRelativeTimecode will return -1 if the relative timecode is too large
    416  // to fit in the frame.
    417  if (cluster_->GetRelativeTimecode(NsToWebMTimecode(
    418  frame.timestamp(), cluster_->timecode_scale())) < 0) {
    419  const double segment_duration =
    420  static_cast<double>(frame.timestamp() -
    421  WebMTimecodeToNs(cluster_->timecode(),
    422  cluster_->timecode_scale())) /
    423  kSecondsToNs;
    424  LOG(ERROR) << "Error adding sample to segment: segment too large, "
    425  << segment_duration
    426  << " seconds. Please check your GOP size and segment duration.";
    427  return Status(error::MUXER_FAILURE,
    428  "Error adding sample to segment: segment too large");
    429  }
    430 
    431  if (!cluster_->AddFrame(&frame)) {
    432  return Status(error::MUXER_FAILURE,
    433  "Error adding sample to segment: Cluster::AddFrame failed");
    434  }
    435 
    436  // A reference frame is needed for non-keyframes. Having a reference to the
    437  // previous block is good enough.
    438  // See libwebm Segment::AddGenericFrame
    439  reference_frame_timestamp_ = prev_sample_->pts();
    440  return Status::OK;
    441 }
    442 
    443 } // namespace webm
    444 } // namespace media
    445 } // namespace shaka
    std::shared_ptr< MediaSample > Clone() const
    Clone the object and return a new MediaSample.
    Definition: media_sample.cc:81
    -
    void WriteWebM(std::vector< uint8_t > *data) const
    -
    Status Initialize(const std::vector< std::shared_ptr< const StreamInfo >> &streams, MuxerListener *muxer_listener, ProgressListener *progress_listener)
    Definition: segmenter.cc:51
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    void UpdateProgress(uint64_t progress)
    Update segmentation progress using ProgressListener.
    Definition: segmenter.cc:250
    -
    virtual void OnSampleDurationReady(uint32_t sample_duration)=0
    -
    Class for parsing or writing VP codec configuration record.
    -
    Status AddSample(size_t stream_id, const MediaSample &sample)
    Definition: segmenter.cc:123
    -
    All the methods that are virtual are virtual for mocking.
    - -
    This class listens to progress updates events.
    -
    mkvmuxer::int64 Position() const override
    Definition: mkv_writer.cc:74
    -
    An implementation of IMkvWriter using our File type.
    Definition: mkv_writer.h:21
    - -
    bool ParseMP4(const std::vector< uint8_t > &data)
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - -
    virtual void OnProgress(double progress)=0
    -
    Status FinalizeSegment(size_t stream_id, const SegmentInfo &segment_info)
    Definition: segmenter.cc:147
    - -
    Holds video stream information.
    -
    Holds audio stream information.
    - +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webm/segmenter.h"
    +
    8 
    +
    9 #include "packager/base/time/time.h"
    +
    10 #include "packager/media/base/audio_stream_info.h"
    +
    11 #include "packager/media/base/media_handler.h"
    +
    12 #include "packager/media/base/media_sample.h"
    +
    13 #include "packager/media/base/muxer_options.h"
    +
    14 #include "packager/media/base/muxer_util.h"
    +
    15 #include "packager/media/base/stream_info.h"
    +
    16 #include "packager/media/base/video_stream_info.h"
    +
    17 #include "packager/media/codecs/vp_codec_configuration_record.h"
    +
    18 #include "packager/media/event/muxer_listener.h"
    +
    19 #include "packager/media/event/progress_listener.h"
    +
    20 #include "packager/media/formats/webm/encryptor.h"
    +
    21 #include "packager/media/formats/webm/webm_constants.h"
    +
    22 #include "packager/third_party/libwebm/src/mkvmuxerutil.hpp"
    +
    23 #include "packager/third_party/libwebm/src/webmids.hpp"
    +
    24 #include "packager/version/version.h"
    +
    25 
    +
    26 using mkvmuxer::AudioTrack;
    +
    27 using mkvmuxer::VideoTrack;
    +
    28 
    +
    29 namespace shaka {
    +
    30 namespace media {
    +
    31 namespace webm {
    +
    32 namespace {
    +
    33 const int64_t kTimecodeScale = 1000000;
    +
    34 const int64_t kSecondsToNs = 1000000000L;
    +
    35 
    +
    36 // Round to closest integer.
    +
    37 uint64_t Round(double value) {
    +
    38  return static_cast<uint64_t>(value + 0.5);
    +
    39 }
    +
    40 
    +
    41 // There are three different kinds of timestamp here:
    +
    42 // (1) ISO-BMFF timestamp (seconds scaled by ISO-BMFF timescale)
    +
    43 // This is used in our MediaSample and StreamInfo structures.
    +
    44 // (2) WebM timecode (seconds scaled by kSecondsToNs / WebM timecode scale)
    +
    45 // This is used in most WebM structures.
    +
    46 // (3) Nanoseconds (seconds scaled by kSecondsToNs)
    +
    47 // This is used in some WebM structures, e.g. Frame.
    +
    48 // We use Nanoseconds as intermediate format here for conversion, in
    +
    49 // uint64_t/int64_t, which is sufficient to represent a time as large as 292
    +
    50 // years.
    +
    51 
    +
    52 uint64_t BmffTimestampToNs(uint64_t timestamp, uint64_t time_scale) {
    +
    53  // Casting to double is needed otherwise kSecondsToNs * timestamp may overflow
    +
    54  // uint64_t/int64_t.
    +
    55  return Round(static_cast<double>(timestamp) / time_scale * kSecondsToNs);
    +
    56 }
    +
    57 
    +
    58 uint64_t NsToBmffTimestamp(uint64_t ns, uint64_t time_scale) {
    +
    59  // Casting to double is needed otherwise ns * time_scale may overflow
    +
    60  // uint64_t/int64_t.
    +
    61  return Round(static_cast<double>(ns) / kSecondsToNs * time_scale);
    +
    62 }
    +
    63 
    +
    64 uint64_t NsToWebMTimecode(uint64_t ns, uint64_t timecode_scale) {
    +
    65  return ns / timecode_scale;
    +
    66 }
    +
    67 
    +
    68 uint64_t WebMTimecodeToNs(uint64_t timecode, uint64_t timecode_scale) {
    +
    69  return timecode * timecode_scale;
    +
    70 }
    +
    71 
    +
    72 } // namespace
    +
    73 
    +
    74 Segmenter::Segmenter(const MuxerOptions& options) : options_(options) {}
    +
    75 
    +
    76 Segmenter::~Segmenter() {}
    +
    77 
    +
    78 Status Segmenter::Initialize(const StreamInfo& info,
    +
    79  ProgressListener* progress_listener,
    +
    80  MuxerListener* muxer_listener) {
    +
    81  is_encrypted_ = info.is_encrypted();
    +
    82  duration_ = info.duration();
    +
    83  time_scale_ = info.time_scale();
    +
    84 
    +
    85  muxer_listener_ = muxer_listener;
    +
    86 
    +
    87  // Use media duration as progress target.
    +
    88  progress_target_ = info.duration();
    +
    89  progress_listener_ = progress_listener;
    +
    90 
    +
    91  segment_info_.Init();
    +
    92  segment_info_.set_timecode_scale(kTimecodeScale);
    +
    93 
    +
    94  const std::string version = GetPackagerVersion();
    +
    95  if (!version.empty()) {
    +
    96  segment_info_.set_writing_app(
    +
    97  (GetPackagerProjectUrl() + " version " + version).c_str());
    +
    98  }
    +
    99 
    +
    100  if (options().segment_template.empty()) {
    +
    101  // Set an initial duration so the duration element is written; will be
    +
    102  // overwritten at the end. This works because this is a float and floats
    +
    103  // are always the same size.
    +
    104  segment_info_.set_duration(1);
    +
    105  }
    +
    106 
    +
    107  // Create the track info.
    +
    108  // The seed is only used to create a UID which we overwrite later.
    +
    109  unsigned int seed = 0;
    +
    110  std::unique_ptr<mkvmuxer::Track> track;
    +
    111  Status status;
    +
    112  switch (info.stream_type()) {
    +
    113  case kStreamVideo: {
    +
    114  std::unique_ptr<VideoTrack> video_track(new VideoTrack(&seed));
    +
    115  status = InitializeVideoTrack(static_cast<const VideoStreamInfo&>(info),
    +
    116  video_track.get());
    +
    117  track = std::move(video_track);
    +
    118  break;
    +
    119  }
    +
    120  case kStreamAudio: {
    +
    121  std::unique_ptr<AudioTrack> audio_track(new AudioTrack(&seed));
    +
    122  status = InitializeAudioTrack(static_cast<const AudioStreamInfo&>(info),
    +
    123  audio_track.get());
    +
    124  track = std::move(audio_track);
    +
    125  break;
    +
    126  }
    +
    127  default:
    +
    128  NOTIMPLEMENTED() << "Not implemented for stream type: "
    +
    129  << info.stream_type();
    +
    130  status = Status(error::UNIMPLEMENTED, "Not implemented for stream type");
    +
    131  }
    +
    132  if (!status.ok())
    +
    133  return status;
    +
    134 
    +
    135  if (info.is_encrypted()) {
    +
    136  if (info.encryption_config().per_sample_iv_size != kWebMIvSize)
    +
    137  return Status(error::MUXER_FAILURE, "Incorrect size WebM encryption IV.");
    +
    138  status = UpdateTrackForEncryption(info.encryption_config().key_id,
    +
    139  track.get());
    +
    140  if (!status.ok())
    +
    141  return status;
    +
    142  }
    +
    143 
    +
    144  tracks_.AddTrack(track.get(), info.track_id());
    +
    145  // number() is only available after the above instruction.
    +
    146  track_id_ = track->number();
    +
    147  // |tracks_| owns |track|.
    +
    148  track.release();
    +
    149  return DoInitialize();
    +
    150 }
    +
    151 
    +
    152 Status Segmenter::Finalize() {
    +
    153  if (prev_sample_ && !prev_sample_->end_of_stream()) {
    +
    154  uint64_t duration =
    +
    155  prev_sample_->pts() - first_timestamp_ + prev_sample_->duration();
    +
    156  segment_info_.set_duration(FromBmffTimestamp(duration));
    +
    157  }
    +
    158  return DoFinalize();
    +
    159 }
    +
    160 
    +
    161 Status Segmenter::AddSample(const MediaSample& source_sample) {
    +
    162  std::shared_ptr<MediaSample> sample(source_sample.Clone());
    +
    163 
    +
    164  if (sample_duration_ == 0) {
    +
    165  first_timestamp_ = sample->pts();
    +
    166  sample_duration_ = sample->duration();
    +
    167  if (muxer_listener_)
    +
    168  muxer_listener_->OnSampleDurationReady(sample_duration_);
    +
    169  }
    +
    170 
    +
    171  UpdateProgress(sample->duration());
    +
    172 
    +
    173  // This writes frames in a delay. Meaning that the previous frame is written
    +
    174  // on this call to AddSample. The current frame is stored until the next
    +
    175  // call. This is done to determine which frame is the last in a Cluster.
    +
    176  // This first block determines if this is a new Cluster and writes the
    +
    177  // previous frame first before creating the new Cluster.
    +
    178 
    +
    179  Status status;
    +
    180  if (new_segment_ || new_subsegment_) {
    +
    181  status = NewSegment(sample->pts(), new_subsegment_);
    +
    182  } else {
    +
    183  status = WriteFrame(false /* write_duration */);
    +
    184  }
    +
    185  if (!status.ok())
    +
    186  return status;
    +
    187 
    +
    188  if (is_encrypted_)
    +
    189  UpdateFrameForEncryption(sample.get());
    +
    190 
    +
    191  new_subsegment_ = false;
    +
    192  new_segment_ = false;
    +
    193  prev_sample_ = sample;
    +
    194  return Status::OK;
    +
    195 }
    +
    196 
    +
    197 Status Segmenter::FinalizeSegment(uint64_t start_timestamp,
    +
    198  uint64_t duration_timestamp,
    +
    199  bool is_subsegment) {
    +
    200  if (is_subsegment)
    +
    201  new_subsegment_ = true;
    +
    202  else
    +
    203  new_segment_ = true;
    +
    204  return WriteFrame(true /* write duration */);
    +
    205 }
    +
    206 
    +
    207 float Segmenter::GetDurationInSeconds() const {
    +
    208  return WebMTimecodeToNs(segment_info_.duration(),
    +
    209  segment_info_.timecode_scale()) /
    +
    210  static_cast<double>(kSecondsToNs);
    +
    211 }
    +
    212 
    +
    213 uint64_t Segmenter::FromBmffTimestamp(uint64_t bmff_timestamp) {
    +
    214  return NsToWebMTimecode(
    +
    215  BmffTimestampToNs(bmff_timestamp, time_scale_),
    +
    216  segment_info_.timecode_scale());
    +
    217 }
    +
    218 
    +
    219 uint64_t Segmenter::FromWebMTimecode(uint64_t webm_timecode) {
    +
    220  return NsToBmffTimestamp(
    +
    221  WebMTimecodeToNs(webm_timecode, segment_info_.timecode_scale()),
    +
    222  time_scale_);
    +
    223 }
    +
    224 
    +
    225 Status Segmenter::WriteSegmentHeader(uint64_t file_size, MkvWriter* writer) {
    +
    226  Status error_status(error::FILE_FAILURE, "Error writing segment header.");
    +
    227 
    +
    228  if (!WriteEbmlHeader(writer))
    +
    229  return error_status;
    +
    230 
    +
    231  if (WriteID(writer, mkvmuxer::kMkvSegment) != 0)
    +
    232  return error_status;
    +
    233 
    +
    234  const uint64_t segment_size_size = 8;
    +
    235  segment_payload_pos_ = writer->Position() + segment_size_size;
    +
    236  if (file_size > 0) {
    +
    237  // We want the size of the segment element, so subtract the header.
    +
    238  if (WriteUIntSize(writer, file_size - segment_payload_pos_,
    +
    239  segment_size_size) != 0)
    +
    240  return error_status;
    +
    241  if (!seek_head_.Write(writer))
    +
    242  return error_status;
    +
    243  } else {
    +
    244  if (SerializeInt(writer, mkvmuxer::kEbmlUnknownValue, segment_size_size) !=
    +
    245  0)
    +
    246  return error_status;
    +
    247  // We don't know the header size, so write a placeholder.
    +
    248  if (!seek_head_.WriteVoid(writer))
    +
    249  return error_status;
    +
    250  }
    +
    251 
    +
    252  seek_head_.set_info_pos(writer->Position() - segment_payload_pos_);
    +
    253  if (!segment_info_.Write(writer))
    +
    254  return error_status;
    +
    255 
    +
    256  seek_head_.set_tracks_pos(writer->Position() - segment_payload_pos_);
    +
    257  if (!tracks_.Write(writer))
    +
    258  return error_status;
    +
    259 
    +
    260  return Status::OK;
    +
    261 }
    +
    262 
    +
    263 Status Segmenter::SetCluster(uint64_t start_webm_timecode,
    +
    264  uint64_t position,
    +
    265  MkvWriter* writer) {
    +
    266  const uint64_t scale = segment_info_.timecode_scale();
    +
    267  cluster_.reset(new mkvmuxer::Cluster(start_webm_timecode, position, scale));
    +
    268  cluster_->Init(writer);
    +
    269  return Status::OK;
    +
    270 }
    +
    271 
    +
    272 void Segmenter::UpdateProgress(uint64_t progress) {
    +
    273  accumulated_progress_ += progress;
    +
    274  if (!progress_listener_ || progress_target_ == 0)
    +
    275  return;
    +
    276  // It might happen that accumulated progress exceeds progress_target due to
    +
    277  // computation errors, e.g. rounding error. Cap it so it never reports > 100%
    +
    278  // progress.
    +
    279  if (accumulated_progress_ >= progress_target_) {
    +
    280  progress_listener_->OnProgress(1.0);
    +
    281  } else {
    +
    282  progress_listener_->OnProgress(static_cast<double>(accumulated_progress_) /
    +
    283  progress_target_);
    +
    284  }
    +
    285 }
    +
    286 
    +
    287 Status Segmenter::InitializeVideoTrack(const VideoStreamInfo& info,
    +
    288  VideoTrack* track) {
    +
    289  if (info.codec() == kCodecAV1) {
    +
    290  track->set_codec_id("V_AV1");
    +
    291  if (!track->SetCodecPrivate(info.codec_config().data(),
    +
    292  info.codec_config().size())) {
    +
    293  return Status(error::INTERNAL_ERROR,
    +
    294  "Private codec data required for AV1 streams");
    +
    295  }
    +
    296  } else if (info.codec() == kCodecVP8) {
    +
    297  track->set_codec_id("V_VP8");
    +
    298  } else if (info.codec() == kCodecVP9) {
    +
    299  track->set_codec_id("V_VP9");
    +
    300 
    +
    301  // The |StreamInfo::codec_config| field is stored using the MP4 format; we
    +
    302  // need to convert it to the WebM format.
    +
    303  VPCodecConfigurationRecord vp_config;
    +
    304  if (!vp_config.ParseMP4(info.codec_config())) {
    +
    305  return Status(error::INTERNAL_ERROR,
    +
    306  "Unable to parse VP9 codec configuration");
    +
    307  }
    +
    308 
    +
    309  mkvmuxer::Colour colour;
    +
    310  if (vp_config.matrix_coefficients() != AVCOL_SPC_UNSPECIFIED) {
    +
    311  colour.set_matrix_coefficients(vp_config.matrix_coefficients());
    +
    312  }
    +
    313  if (vp_config.transfer_characteristics() != AVCOL_TRC_UNSPECIFIED) {
    +
    314  colour.set_transfer_characteristics(vp_config.transfer_characteristics());
    +
    315  }
    +
    316  if (vp_config.color_primaries() != AVCOL_PRI_UNSPECIFIED) {
    +
    317  colour.set_primaries(vp_config.color_primaries());
    +
    318  }
    +
    319  if (!track->SetColour(colour)) {
    +
    320  return Status(error::INTERNAL_ERROR,
    +
    321  "Failed to setup color element for VPx streams");
    +
    322  }
    +
    323 
    +
    324  std::vector<uint8_t> codec_config;
    +
    325  vp_config.WriteWebM(&codec_config);
    +
    326  if (!track->SetCodecPrivate(codec_config.data(), codec_config.size())) {
    +
    327  return Status(error::INTERNAL_ERROR,
    +
    328  "Private codec data required for VPx streams");
    +
    329  }
    +
    330  } else {
    +
    331  LOG(ERROR) << "Only VP8, VP9 and AV1 video codecs are supported in WebM.";
    +
    332  return Status(error::UNIMPLEMENTED,
    +
    333  "Only VP8, VP9 and AV1 video codecs are supported in WebM.");
    +
    334  }
    +
    335 
    +
    336  track->set_uid(info.track_id());
    +
    337  if (!info.language().empty())
    +
    338  track->set_language(info.language().c_str());
    +
    339  track->set_type(mkvmuxer::Tracks::kVideo);
    +
    340  track->set_width(info.width());
    +
    341  track->set_height(info.height());
    +
    342  track->set_display_height(info.height());
    +
    343  track->set_display_width(info.width() * info.pixel_width() /
    +
    344  info.pixel_height());
    +
    345  return Status::OK;
    +
    346 }
    +
    347 
    +
    348 Status Segmenter::InitializeAudioTrack(const AudioStreamInfo& info,
    +
    349  AudioTrack* track) {
    +
    350  if (info.codec() == kCodecOpus) {
    +
    351  track->set_codec_id(mkvmuxer::Tracks::kOpusCodecId);
    +
    352  } else if (info.codec() == kCodecVorbis) {
    +
    353  track->set_codec_id(mkvmuxer::Tracks::kVorbisCodecId);
    +
    354  } else {
    +
    355  LOG(ERROR) << "Only Vorbis and Opus audio codec are supported in WebM.";
    +
    356  return Status(error::UNIMPLEMENTED,
    +
    357  "Only Vorbis and Opus audio codecs are supported in WebM.");
    +
    358  }
    +
    359  if (!track->SetCodecPrivate(info.codec_config().data(),
    +
    360  info.codec_config().size())) {
    +
    361  return Status(error::INTERNAL_ERROR,
    +
    362  "Private codec data required for audio streams");
    +
    363  }
    +
    364 
    +
    365  track->set_uid(info.track_id());
    +
    366  if (!info.language().empty())
    +
    367  track->set_language(info.language().c_str());
    +
    368  track->set_type(mkvmuxer::Tracks::kAudio);
    +
    369  track->set_sample_rate(info.sampling_frequency());
    +
    370  track->set_channels(info.num_channels());
    +
    371  track->set_seek_pre_roll(info.seek_preroll_ns());
    +
    372  track->set_codec_delay(info.codec_delay_ns());
    +
    373  return Status::OK;
    +
    374 }
    +
    375 
    +
    376 Status Segmenter::WriteFrame(bool write_duration) {
    +
    377  // Create a frame manually so we can create non-SimpleBlock frames. This
    +
    378  // is required to allow the frame duration to be added. If the duration
    +
    379  // is not set, then a SimpleBlock will still be written.
    +
    380  mkvmuxer::Frame frame;
    +
    381 
    +
    382  if (!frame.Init(prev_sample_->data(), prev_sample_->data_size())) {
    +
    383  return Status(error::MUXER_FAILURE,
    +
    384  "Error adding sample to segment: Frame::Init failed");
    +
    385  }
    +
    386 
    +
    387  if (write_duration) {
    +
    388  frame.set_duration(
    +
    389  BmffTimestampToNs(prev_sample_->duration(), time_scale_));
    +
    390  }
    +
    391  frame.set_is_key(prev_sample_->is_key_frame());
    +
    392  frame.set_timestamp(
    +
    393  BmffTimestampToNs(prev_sample_->pts(), time_scale_));
    +
    394  frame.set_track_number(track_id_);
    +
    395 
    +
    396  if (prev_sample_->side_data_size() > 0) {
    +
    397  uint64_t block_add_id;
    +
    398  // First 8 bytes of side_data is the BlockAddID element's value, which is
    +
    399  // done to mimic ffmpeg behavior. See webm_cluster_parser.cc for details.
    +
    400  CHECK_GT(prev_sample_->side_data_size(), sizeof(block_add_id));
    +
    401  memcpy(&block_add_id, prev_sample_->side_data(), sizeof(block_add_id));
    +
    402  if (!frame.AddAdditionalData(
    +
    403  prev_sample_->side_data() + sizeof(block_add_id),
    +
    404  prev_sample_->side_data_size() - sizeof(block_add_id),
    +
    405  block_add_id)) {
    +
    406  return Status(
    +
    407  error::MUXER_FAILURE,
    +
    408  "Error adding sample to segment: Frame::AddAditionalData Failed");
    +
    409  }
    +
    410  }
    +
    411 
    +
    412  if (!prev_sample_->is_key_frame() && !frame.CanBeSimpleBlock()) {
    +
    413  frame.set_reference_block_timestamp(
    +
    414  BmffTimestampToNs(reference_frame_timestamp_, time_scale_));
    +
    415  }
    +
    416 
    +
    417  // GetRelativeTimecode will return -1 if the relative timecode is too large
    +
    418  // to fit in the frame.
    +
    419  if (cluster_->GetRelativeTimecode(NsToWebMTimecode(
    +
    420  frame.timestamp(), cluster_->timecode_scale())) < 0) {
    +
    421  const double segment_duration =
    +
    422  static_cast<double>(frame.timestamp() -
    +
    423  WebMTimecodeToNs(cluster_->timecode(),
    +
    424  cluster_->timecode_scale())) /
    +
    425  kSecondsToNs;
    +
    426  LOG(ERROR) << "Error adding sample to segment: segment too large, "
    +
    427  << segment_duration
    +
    428  << " seconds. Please check your GOP size and segment duration.";
    +
    429  return Status(error::MUXER_FAILURE,
    +
    430  "Error adding sample to segment: segment too large");
    +
    431  }
    +
    432 
    +
    433  if (!cluster_->AddFrame(&frame)) {
    +
    434  return Status(error::MUXER_FAILURE,
    +
    435  "Error adding sample to segment: Cluster::AddFrame failed");
    +
    436  }
    +
    437 
    +
    438  // A reference frame is needed for non-keyframes. Having a reference to the
    +
    439  // previous block is good enough.
    +
    440  // See libwebm Segment::AddGenericFrame
    +
    441  reference_frame_timestamp_ = prev_sample_->pts();
    +
    442  return Status::OK;
    +
    443 }
    +
    444 
    +
    445 } // namespace webm
    +
    446 } // namespace media
    +
    447 } // namespace shaka
    + +
    Holds audio stream information.
    +
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    std::shared_ptr< MediaSample > Clone() const
    Clone the object and return a new MediaSample.
    Definition: media_sample.cc:81
    +
    An implementation of IMkvWriter using our File type.
    Definition: mkv_writer.h:21
    +
    mkvmuxer::int64 Position() const override
    Definition: mkv_writer.cc:74
    + +
    This class listens to progress updates events.
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    Holds video stream information.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d54/structshaka_1_1media_1_1H264DecRefPicMarking.html b/docs/dc/d54/structshaka_1_1media_1_1H264DecRefPicMarking.html index bff9342fcc..178c8b7b5b 100644 --- a/docs/dc/d54/structshaka_1_1media_1_1H264DecRefPicMarking.html +++ b/docs/dc/d54/structshaka_1_1media_1_1H264DecRefPicMarking.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264DecRefPicMarking Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    max_long_term_frame_id

    Detailed Description

    -

    Definition at line 138 of file h264_parser.h.

    +

    Definition at line 134 of file h264_parser.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/dc/d56/audio__header_8h_source.html b/docs/dc/d56/audio__header_8h_source.html index ff668c8215..a7e52da6a2 100644 --- a/docs/dc/d56/audio__header_8h_source.html +++ b/docs/dc/d56/audio__header_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/audio_header.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    audio_header.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_AUDIO_HEADER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_AUDIO_HEADER_H_
    9 
    10 #include <stddef.h>
    11 #include <stdint.h>
    12 
    13 #include <vector>
    14 
    15 namespace shaka {
    16 namespace media {
    17 namespace mp2t {
    18 
    19 class AudioHeader {
    20  public:
    21  AudioHeader() = default;
    22  virtual ~AudioHeader() = default;
    23 
    27  virtual bool IsSyncWord(const uint8_t* buf) const = 0;
    28 
    30  virtual size_t GetMinFrameSize() const = 0;
    31 
    33  virtual size_t GetSamplesPerFrame() const = 0;
    34 
    43  virtual bool Parse(const uint8_t* audio_frame, size_t audio_frame_size) = 0;
    44 
    47  virtual size_t GetHeaderSize() const = 0;
    48 
    51  virtual size_t GetFrameSize() const = 0;
    52 
    56  virtual size_t GetFrameSizeWithoutParsing(const uint8_t* data,
    57  size_t num_bytes) const = 0;
    58 
    65  virtual void GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const = 0;
    66 
    69  virtual uint8_t GetObjectType() const = 0;
    70 
    73  virtual uint32_t GetSamplingFrequency() const = 0;
    74 
    77  virtual uint8_t GetNumChannels() const = 0;
    78 
    79  private:
    80  AudioHeader(const AudioHeader&) = delete;
    81  AudioHeader& operator=(const AudioHeader&) = delete;
    82 };
    83 
    84 } // namespace mp2t
    85 } // namespace media
    86 } // namespace shaka
    87 
    88 #endif // PACKAGER_MEDIA_FORMATS_MP2T_AUDIO_HEADER_H_
    virtual void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const =0
    -
    virtual bool Parse(const uint8_t *audio_frame, size_t audio_frame_size)=0
    -
    All the methods that are virtual are virtual for mocking.
    -
    virtual uint32_t GetSamplingFrequency() const =0
    -
    virtual size_t GetHeaderSize() const =0
    -
    virtual size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const =0
    -
    virtual uint8_t GetObjectType() const =0
    -
    virtual uint8_t GetNumChannels() const =0
    - -
    virtual bool IsSyncWord(const uint8_t *buf) const =0
    -
    virtual size_t GetSamplesPerFrame() const =0
    -
    virtual size_t GetFrameSize() const =0
    -
    virtual size_t GetMinFrameSize() const =0
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_AUDIO_HEADER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_AUDIO_HEADER_H_
    +
    9 
    +
    10 #include <stddef.h>
    +
    11 #include <stdint.h>
    +
    12 
    +
    13 #include <vector>
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 namespace mp2t {
    +
    18 
    +
    19 class AudioHeader {
    +
    20  public:
    +
    21  AudioHeader() = default;
    +
    22  virtual ~AudioHeader() = default;
    +
    23 
    +
    27  virtual bool IsSyncWord(const uint8_t* buf) const = 0;
    +
    28 
    +
    30  virtual size_t GetMinFrameSize() const = 0;
    +
    31 
    +
    33  virtual size_t GetSamplesPerFrame() const = 0;
    +
    34 
    +
    43  virtual bool Parse(const uint8_t* audio_frame, size_t audio_frame_size) = 0;
    +
    44 
    +
    47  virtual size_t GetHeaderSize() const = 0;
    +
    48 
    +
    51  virtual size_t GetFrameSize() const = 0;
    +
    52 
    +
    56  virtual size_t GetFrameSizeWithoutParsing(const uint8_t* data,
    +
    57  size_t num_bytes) const = 0;
    +
    58 
    +
    65  virtual void GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const = 0;
    +
    66 
    +
    69  virtual uint8_t GetObjectType() const = 0;
    +
    70 
    +
    73  virtual uint32_t GetSamplingFrequency() const = 0;
    +
    74 
    +
    77  virtual uint8_t GetNumChannels() const = 0;
    +
    78 
    +
    79  private:
    +
    80  AudioHeader(const AudioHeader&) = delete;
    +
    81  AudioHeader& operator=(const AudioHeader&) = delete;
    +
    82 };
    +
    83 
    +
    84 } // namespace mp2t
    +
    85 } // namespace media
    +
    86 } // namespace shaka
    +
    87 
    +
    88 #endif // PACKAGER_MEDIA_FORMATS_MP2T_AUDIO_HEADER_H_
    + +
    virtual bool IsSyncWord(const uint8_t *buf) const =0
    +
    virtual bool Parse(const uint8_t *audio_frame, size_t audio_frame_size)=0
    +
    virtual uint8_t GetNumChannels() const =0
    +
    virtual size_t GetHeaderSize() const =0
    +
    virtual void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const =0
    +
    virtual size_t GetMinFrameSize() const =0
    +
    virtual uint8_t GetObjectType() const =0
    +
    virtual size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const =0
    +
    virtual size_t GetSamplesPerFrame() const =0
    +
    virtual uint32_t GetSamplingFrequency() const =0
    +
    virtual size_t GetFrameSize() const =0
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d58/webm__media__parser_8h_source.html b/docs/dc/d58/webm__media__parser_8h_source.html index 18b99e9828..642067fbb3 100644 --- a/docs/dc/d58/webm__media__parser_8h_source.html +++ b/docs/dc/d58/webm__media__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_media_parser.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    webm_media_parser.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_
    7 
    8 #include "packager/base/callback_forward.h"
    9 #include "packager/base/compiler_specific.h"
    10 #include "packager/media/base/byte_queue.h"
    11 #include "packager/media/base/media_parser.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 class WebMClusterParser;
    17 
    18 class WebMMediaParser : public MediaParser {
    19  public:
    21  ~WebMMediaParser() override;
    22 
    25  void Init(const InitCB& init_cb,
    26  const NewSampleCB& new_sample_cb,
    27  KeySource* decryption_key_source) override;
    28  bool Flush() override WARN_UNUSED_RESULT;
    29  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
    31 
    32  private:
    33  enum State {
    34  kWaitingForInit,
    35  kParsingHeaders,
    36  kParsingClusters,
    37  kError
    38  };
    39 
    40  void ChangeState(State new_state);
    41 
    42  // Parses WebM Header, Info, Tracks elements. It also skips other level 1
    43  // elements that are not used right now. Once the Info & Tracks elements have
    44  // been parsed, this method will transition the parser from PARSING_HEADERS to
    45  // PARSING_CLUSTERS.
    46  //
    47  // Returns < 0 if the parse fails.
    48  // Returns 0 if more data is needed.
    49  // Returning > 0 indicates success & the number of bytes parsed.
    50  int ParseInfoAndTracks(const uint8_t* data, int size);
    51 
    52  // Incrementally parses WebM cluster elements. This method also skips
    53  // CUES elements if they are encountered since we currently don't use the
    54  // data in these elements.
    55  //
    56  // Returns < 0 if the parse fails.
    57  // Returns 0 if more data is needed.
    58  // Returning > 0 indicates success & the number of bytes parsed.
    59  int ParseCluster(const uint8_t* data, int size);
    60 
    61  // Fetch keys for the input key ids. Returns true on success, false otherwise.
    62  bool FetchKeysIfNecessary(const std::string& audio_encryption_key_id,
    63  const std::string& video_encryption_key_id);
    64 
    65  State state_;
    66  InitCB init_cb_;
    67  NewSampleCB new_sample_cb_;
    68  KeySource* decryption_key_source_;
    69  bool ignore_text_tracks_;
    70 
    71  bool unknown_segment_size_;
    72 
    73  std::unique_ptr<WebMClusterParser> cluster_parser_;
    74  ByteQueue byte_queue_;
    75 
    76  DISALLOW_COPY_AND_ASSIGN(WebMMediaParser);
    77 };
    78 
    79 } // namespace media
    80 } // namespace shaka
    81 
    82 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_
    -
    bool Flush() override WARN_UNUSED_RESULT
    -
    bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    -
    All the methods that are virtual are virtual for mocking.
    -
    void Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
    -
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:34
    - -
    base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
    Definition: media_parser.h:43
    - -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_
    +
    7 
    +
    8 #include "packager/base/callback_forward.h"
    +
    9 #include "packager/base/compiler_specific.h"
    +
    10 #include "packager/media/base/byte_queue.h"
    +
    11 #include "packager/media/base/media_parser.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 class WebMClusterParser;
    +
    17 
    +
    18 class WebMMediaParser : public MediaParser {
    +
    19  public:
    + +
    21  ~WebMMediaParser() override;
    +
    22 
    +
    25  void Init(const InitCB& init_cb,
    +
    26  const NewMediaSampleCB& new_media_sample_cb,
    +
    27  const NewTextSampleCB& new_text_sample_cb,
    +
    28  KeySource* decryption_key_source) override;
    +
    29  bool Flush() override WARN_UNUSED_RESULT;
    +
    30  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
    +
    32 
    +
    33  private:
    +
    34  enum State {
    +
    35  kWaitingForInit,
    +
    36  kParsingHeaders,
    +
    37  kParsingClusters,
    +
    38  kError
    +
    39  };
    +
    40 
    +
    41  void ChangeState(State new_state);
    +
    42 
    +
    43  // Parses WebM Header, Info, Tracks elements. It also skips other level 1
    +
    44  // elements that are not used right now. Once the Info & Tracks elements have
    +
    45  // been parsed, this method will transition the parser from PARSING_HEADERS to
    +
    46  // PARSING_CLUSTERS.
    +
    47  //
    +
    48  // Returns < 0 if the parse fails.
    +
    49  // Returns 0 if more data is needed.
    +
    50  // Returning > 0 indicates success & the number of bytes parsed.
    +
    51  int ParseInfoAndTracks(const uint8_t* data, int size);
    +
    52 
    +
    53  // Incrementally parses WebM cluster elements. This method also skips
    +
    54  // CUES elements if they are encountered since we currently don't use the
    +
    55  // data in these elements.
    +
    56  //
    +
    57  // Returns < 0 if the parse fails.
    +
    58  // Returns 0 if more data is needed.
    +
    59  // Returning > 0 indicates success & the number of bytes parsed.
    +
    60  int ParseCluster(const uint8_t* data, int size);
    +
    61 
    +
    62  // Fetch keys for the input key ids. Returns true on success, false otherwise.
    +
    63  bool FetchKeysIfNecessary(const std::string& audio_encryption_key_id,
    +
    64  const std::string& video_encryption_key_id);
    +
    65 
    +
    66  State state_;
    +
    67  InitCB init_cb_;
    +
    68  NewMediaSampleCB new_sample_cb_;
    +
    69  KeySource* decryption_key_source_;
    +
    70  bool ignore_text_tracks_;
    +
    71 
    +
    72  bool unknown_segment_size_;
    +
    73 
    +
    74  std::unique_ptr<WebMClusterParser> cluster_parser_;
    +
    75  ByteQueue byte_queue_;
    +
    76 
    +
    77  DISALLOW_COPY_AND_ASSIGN(WebMMediaParser);
    +
    78 };
    +
    79 
    +
    80 } // namespace media
    +
    81 } // namespace shaka
    +
    82 
    +
    83 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MEDIA_PARSER_H_
    + +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    + +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
    Definition: media_parser.h:53
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    + +
    bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    +
    bool Flush() override WARN_UNUSED_RESULT
    +
    void Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d5c/classshaka_1_1MockMpdNotifier.html b/docs/dc/d5c/classshaka_1_1MockMpdNotifier.html index 2fe90ffe5a..c03c469302 100644 --- a/docs/dc/d5c/classshaka_1_1MockMpdNotifier.html +++ b/docs/dc/d5c/classshaka_1_1MockMpdNotifier.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MockMpdNotifier Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::MpdNotifier - -
    + + @@ -128,6 +131,8 @@ Public Member Functions + + @@ -143,9 +148,7 @@ Public Member Functions diff --git a/docs/dc/d65/dvb__sub__parser_8h_source.html b/docs/dc/d65/dvb__sub__parser_8h_source.html new file mode 100644 index 0000000000..c2fdb227b0 --- /dev/null +++ b/docs/dc/d65/dvb__sub__parser_8h_source.html @@ -0,0 +1,170 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/dvb/dvb_sub_parser.h Source File + + + + + + + + + +
    +
    +

    Public Member Functions

     
    virtual bool Flush ()=0
     
    bool include_mspr_pro () const
     
    DashProfile dash_profile () const
     
    MpdType mpd_type () const
    + + + + + +
    +
    Shaka Packager SDK +
    +
    + + + + + + + + + +
    +
    + + +
    + +
    + + + +
    +
    +
    dvb_sub_parser.h
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_DVB_DVB_SUB_PARSER_H_
    +
    8 #define PACKAGER_MEDIA_DVB_DVB_SUB_PARSER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <vector>
    +
    12 
    +
    13 #include "packager/media/base/bit_reader.h"
    +
    14 #include "packager/media/base/text_sample.h"
    +
    15 #include "packager/media/formats/dvb/dvb_image.h"
    +
    16 #include "packager/media/formats/dvb/subtitle_composer.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    +
    21 // See ETSI EN 300 743 Section 7.2.0.1 and Table 7.
    +
    22 enum class DvbSubSegmentType : uint16_t {
    +
    23  kPageComposition = 0x10,
    +
    24  kRegionComposition = 0x11,
    +
    25  kClutDefinition = 0x12,
    +
    26  kObjectData = 0x13,
    +
    27  kDisplayDefinition = 0x14,
    +
    28  kDisparitySignalling = 0x15,
    +
    29  kAlternativeClut = 0x16,
    +
    30  kEndOfDisplay = 0x80,
    +
    31 };
    +
    32 
    +
    33 class DvbSubParser {
    +
    34  public:
    +
    35  DvbSubParser();
    +
    36  ~DvbSubParser();
    +
    37 
    +
    38  DvbSubParser(const DvbSubParser&) = delete;
    +
    39  DvbSubParser& operator=(const DvbSubParser&) = delete;
    +
    40 
    +
    41  bool Parse(DvbSubSegmentType segment_type,
    +
    42  int64_t pts,
    +
    43  const uint8_t* payload,
    +
    44  size_t size,
    +
    45  std::vector<std::shared_ptr<TextSample>>* samples);
    +
    46  bool Flush(std::vector<std::shared_ptr<TextSample>>* samples);
    +
    47 
    +
    48  private:
    +
    49  friend class DvbSubParserTest;
    +
    50 
    +
    51  const DvbImageColorSpace* GetColorSpace(uint8_t clut_id);
    +
    52  const DvbImageBuilder* GetImageForObject(uint16_t object_id);
    +
    53 
    +
    54  bool ParsePageComposition(int64_t pts,
    +
    55  const uint8_t* data,
    +
    56  size_t size,
    +
    57  std::vector<std::shared_ptr<TextSample>>* samples);
    +
    58  bool ParseRegionComposition(const uint8_t* data, size_t size);
    +
    59  bool ParseClutDefinition(const uint8_t* data, size_t size);
    +
    60  bool ParseObjectData(int64_t pts, const uint8_t* data, size_t size);
    +
    61  bool ParseDisplayDefinition(const uint8_t* data, size_t size);
    +
    62 
    +
    63  bool ParsePixelDataSubObject(size_t sub_object_length,
    +
    64  bool is_top_fields,
    +
    65  BitReader* reader,
    +
    66  DvbImageColorSpace* color_space,
    +
    67  DvbImageBuilder* image);
    +
    68  bool Parse2BitPixelData(bool is_top_fields,
    +
    69  BitReader* reader,
    +
    70  DvbImageBuilder* image);
    +
    71  bool Parse4BitPixelData(bool is_top_fields,
    +
    72  BitReader* reader,
    +
    73  DvbImageBuilder* image);
    +
    74  bool Parse8BitPixelData(bool is_top_fields,
    +
    75  BitReader* reader,
    +
    76  DvbImageBuilder* image);
    +
    77 
    +
    78  SubtitleComposer composer_;
    +
    79  int64_t last_pts_;
    +
    80  uint8_t timeout_;
    +
    81 };
    +
    82 
    +
    83 } // namespace media
    +
    84 } // namespace shaka
    +
    85 
    +
    86 #endif // PACKAGER_MEDIA_DVB_DVB_SUB_PARSER_H_
    +
    A class to read bit streams.
    Definition: bit_reader.h:17
    + + + + +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/dc/d69/structshaka_1_1media_1_1mp4_1_1CueSettingsBox-members.html b/docs/dc/d69/structshaka_1_1media_1_1mp4_1_1CueSettingsBox-members.html index 75fcd1240a..cde8ae7b10 100644 --- a/docs/dc/d69/structshaka_1_1media_1_1mp4_1_1CueSettingsBox-members.html +++ b/docs/dc/d69/structshaka_1_1media_1_1mp4_1_1CueSettingsBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/d6f/classshaka_1_1media_1_1webm_1_1Segmenter-members.html b/docs/dc/d6f/classshaka_1_1media_1_1webm_1_1Segmenter-members.html index 407532c675..eb19623fff 100644 --- a/docs/dc/d6f/classshaka_1_1media_1_1webm_1_1Segmenter-members.html +++ b/docs/dc/d6f/classshaka_1_1media_1_1webm_1_1Segmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/d71/classshaka_1_1media_1_1mp2t_1_1TsSection-members.html b/docs/dc/d71/classshaka_1_1media_1_1mp2t_1_1TsSection-members.html index 125d8a9396..de0beda9c8 100644 --- a/docs/dc/d71/classshaka_1_1media_1_1mp2t_1_1TsSection-members.html +++ b/docs/dc/d71/classshaka_1_1media_1_1mp2t_1_1TsSection-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/d73/classshaka_1_1media_1_1MockMuxerListener.html b/docs/dc/d73/classshaka_1_1media_1_1MockMuxerListener.html index 9d74758d2b..576ad59701 100644 --- a/docs/dc/d73/classshaka_1_1media_1_1MockMuxerListener.html +++ b/docs/dc/d73/classshaka_1_1media_1_1MockMuxerListener.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MockMuxerListener Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::MuxerListener - -
    + + @@ -127,13 +130,13 @@ Public Member Functions Additional Inherited Members @@ -196,9 +199,7 @@ Additional Inherited Members diff --git a/docs/dc/d76/classshaka_1_1media_1_1BitWriter.html b/docs/dc/d76/classshaka_1_1media_1_1BitWriter.html index 546c29b1d4..356117ea60 100644 --- a/docs/dc/d76/classshaka_1_1media_1_1BitWriter.html +++ b/docs/dc/d76/classshaka_1_1media_1_1BitWriter.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::BitWriter Class Reference @@ -29,18 +29,21 @@

    Public Member Functions

    - Public Types inherited from shaka::media::MuxerListener
    enum  ContainerType {
    -  kContainerUnknown = 0, -kContainerMp4, -kContainerMpeg2ts, -kContainerWebM, -
    -  kContainerText, -kContainerPackedAudio +  kContainerUnknown = 0 +, kContainerMp4 +, kContainerMpeg2ts +, kContainerWebM +,
    +  kContainerText +, kContainerPackedAudio
    }
     
    - + +/* @license-end */
    diff --git a/docs/dc/d7b/classshaka_1_1media_1_1PsshBoxBuilder-members.html b/docs/dc/d7b/classshaka_1_1media_1_1PsshBoxBuilder-members.html index e1de4ce1cd..2bd49356d6 100644 --- a/docs/dc/d7b/classshaka_1_1media_1_1PsshBoxBuilder-members.html +++ b/docs/dc/d7b/classshaka_1_1media_1_1PsshBoxBuilder-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dc/d7b/closure__thread_8cc_source.html b/docs/dc/d7b/closure__thread_8cc_source.html index f1cb87a710..588c2a2929 100644 --- a/docs/dc/d7b/closure__thread_8cc_source.html +++ b/docs/dc/d7b/closure__thread_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/closure_thread.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    closure_thread.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/closure_thread.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 
    13  const std::string& name_prefix,
    14  const base::Closure& task)
    15  : base::SimpleThread(name_prefix), task_(task) {}
    16 
    18  if (HasBeenStarted() && !HasBeenJoined())
    19  Join();
    20 }
    21 
    22 void ClosureThread::Run() { task_.Run(); }
    23 
    24 } // namespace media
    25 } // namespace shaka
    void Run() override
    SimpleThread implementation overrides.
    -
    ClosureThread(const std::string &name_prefix, const base::Closure &task)
    -
    All the methods that are virtual are virtual for mocking.
    -
    ~ClosureThread() override
    The destructor calls Join automatically if it is not yet joined.
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/closure_thread.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 
    + +
    13  const std::string& name_prefix,
    +
    14  const base::Closure& task)
    +
    15  : base::SimpleThread(name_prefix), task_(task) {}
    +
    16 
    + +
    18  if (HasBeenStarted() && !HasBeenJoined())
    +
    19  Join();
    +
    20 }
    +
    21 
    +
    22 void ClosureThread::Run() { task_.Run(); }
    +
    23 
    +
    24 } // namespace media
    +
    25 } // namespace shaka
    +
    void Run() override
    SimpleThread implementation overrides.
    +
    ClosureThread(const std::string &name_prefix, const base::Closure &task)
    +
    ~ClosureThread() override
    The destructor calls Join automatically if it is not yet joined.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d7b/h264__parser_8cc_source.html b/docs/dc/d7b/h264__parser_8cc_source.html index 7a46419d71..6a56339fcc 100644 --- a/docs/dc/d7b/h264__parser_8cc_source.html +++ b/docs/dc/d7b/h264__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h264_parser.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    h264_parser.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/codecs/h264_parser.h"
    6 
    7 #include <memory>
    8 #include "packager/base/logging.h"
    9 #include "packager/media/base/buffer_reader.h"
    10 
    11 #define LOG_ERROR_ONCE(msg) \
    12  do { \
    13  static bool logged_once = false; \
    14  LOG_IF(ERROR, !logged_once) << msg; \
    15  logged_once = true; \
    16  } while (0)
    17 
    18 namespace shaka {
    19 namespace media {
    20 
    21 // Implemented according to ISO/IEC 14496-10:2005 7.4.2.1 Sequence parameter set
    22 // RBSP semantics.
    23 bool ExtractResolutionFromSps(const H264Sps& sps,
    24  uint32_t* coded_width,
    25  uint32_t* coded_height,
    26  uint32_t* pixel_width,
    27  uint32_t* pixel_height) {
    28  int crop_x = 0;
    29  int crop_y = 0;
    30  if (sps.frame_cropping_flag) {
    31  int sub_width_c = 0;
    32  int sub_height_c = 0;
    33  // Table 6-1.
    34  switch (sps.chroma_format_idc) {
    35  case 0: // monochrome
    36  // SubWidthC and SubHeightC are not defined for monochrome. For ease of
    37  // computation afterwards, assign both to 1.
    38  sub_width_c = 1;
    39  sub_height_c = 1;
    40  break;
    41  case 1: // 4:2:0
    42  sub_width_c = 2;
    43  sub_height_c = 2;
    44  break;
    45  case 2: // 4:2:2
    46  sub_width_c = 2;
    47  sub_height_c = 1;
    48  break;
    49  case 3: // 4:4:4
    50  sub_width_c = 1;
    51  sub_height_c = 1;
    52  break;
    53  default:
    54  LOG(ERROR) << "Unexpected chroma_format_idc " << sps.chroma_format_idc;
    55  return false;
    56  }
    57 
    58  // Formula 7-16, 7-17, 7-18, 7-19.
    59  int crop_unit_x = sub_width_c;
    60  int crop_unit_y = sub_height_c * (2 - (sps.frame_mbs_only_flag ? 1 : 0));
    61  crop_x = crop_unit_x *
    62  (sps.frame_crop_left_offset + sps.frame_crop_right_offset);
    63  crop_y = crop_unit_y *
    64  (sps.frame_crop_top_offset + sps.frame_crop_bottom_offset);
    65  }
    66 
    67  // Formula 7-10, 7-11.
    68  int pic_width_in_mbs = sps.pic_width_in_mbs_minus1 + 1;
    69  *coded_width = pic_width_in_mbs * 16 - crop_x;
    70 
    71  // Formula 7-13, 7-15.
    72  int pic_height_in_mbs = (2 - (sps.frame_mbs_only_flag ? 1 : 0)) *
    73  (sps.pic_height_in_map_units_minus1 + 1);
    74  *coded_height = pic_height_in_mbs * 16 - crop_y;
    75 
    76  // 0 means it wasn't in the SPS and therefore assume 1.
    77  *pixel_width = sps.sar_width == 0 ? 1 : sps.sar_width;
    78  *pixel_height = sps.sar_height == 0 ? 1 : sps.sar_height;
    79  DVLOG(2) << "Found coded_width: " << *coded_width
    80  << " coded_height: " << *coded_height
    81  << " pixel_width: " << *pixel_width
    82  << " pixel_height: " << *pixel_height;
    83  return true;
    84 }
    85 
    86 bool H264SliceHeader::IsPSlice() const {
    87  return (slice_type % 5 == kPSlice);
    88 }
    89 
    90 bool H264SliceHeader::IsBSlice() const {
    91  return (slice_type % 5 == kBSlice);
    92 }
    93 
    94 bool H264SliceHeader::IsISlice() const {
    95  return (slice_type % 5 == kISlice);
    96 }
    97 
    98 bool H264SliceHeader::IsSPSlice() const {
    99  return (slice_type % 5 == kSPSlice);
    100 }
    101 
    102 bool H264SliceHeader::IsSISlice() const {
    103  return (slice_type % 5 == kSISlice);
    104 }
    105 
    106 H264Sps::H264Sps() {
    107  memset(this, 0, sizeof(*this));
    108 }
    109 
    110 H264Pps::H264Pps() {
    111  memset(this, 0, sizeof(*this));
    112 }
    113 
    114 H264SliceHeader::H264SliceHeader() {
    115  memset(this, 0, sizeof(*this));
    116 }
    117 
    118 H264SEIMessage::H264SEIMessage() {
    119  memset(this, 0, sizeof(*this));
    120 }
    121 
    122 #define READ_BITS_OR_RETURN(num_bits, out) \
    123  do { \
    124  if (!br->ReadBits(num_bits, (out))) { \
    125  DVLOG(1) \
    126  << "Error in stream: unexpected EOS while trying to read " #out; \
    127  return kInvalidStream; \
    128  } \
    129  } while (0)
    130 
    131 #define READ_BOOL_OR_RETURN(out) \
    132  do { \
    133  int _out; \
    134  if (!br->ReadBits(1, &_out)) { \
    135  DVLOG(1) \
    136  << "Error in stream: unexpected EOS while trying to read " #out; \
    137  return kInvalidStream; \
    138  } \
    139  *(out) = _out != 0; \
    140  } while (0)
    141 
    142 #define READ_UE_OR_RETURN(out) \
    143  do { \
    144  if (!br->ReadUE(out)) { \
    145  DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
    146  return kInvalidStream; \
    147  } \
    148  } while (0)
    149 
    150 #define READ_SE_OR_RETURN(out) \
    151  do { \
    152  if (!br->ReadSE(out)) { \
    153  DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
    154  return kInvalidStream; \
    155  } \
    156  } while (0)
    157 
    158 #define IN_RANGE_OR_RETURN(val, min, max) \
    159  do { \
    160  if ((val) < (min) || (val) > (max)) { \
    161  DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
    162  << " in range [" << (min) << ":" << (max) << "]" \
    163  << " found " << (val) << " instead"; \
    164  return kInvalidStream; \
    165  } \
    166  } while (0)
    167 
    168 #define TRUE_OR_RETURN(a) \
    169  do { \
    170  if (!(a)) { \
    171  DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
    172  return kInvalidStream; \
    173  } \
    174  } while (0)
    175 
    176 enum AspectRatioIdc {
    177  kExtendedSar = 255,
    178 };
    179 
    180 // ISO 14496 part 10
    181 // VUI parameters: Table E-1 "Meaning of sample aspect ratio indicator"
    182 static const int kTableSarWidth[] = {
    183  0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
    184 };
    185 static const int kTableSarHeight[] = {
    186  0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
    187 };
    188 static_assert(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
    189  "sar_tables_must_have_same_size");
    190 
    191 H264Parser::H264Parser() {}
    192 
    193 H264Parser::~H264Parser() {}
    194 
    195 const H264Pps* H264Parser::GetPps(int pps_id) {
    196  return active_PPSes_[pps_id].get();
    197 }
    198 
    199 const H264Sps* H264Parser::GetSps(int sps_id) {
    200  return active_SPSes_[sps_id].get();
    201 }
    202 
    203 // Default scaling lists (per spec).
    204 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
    205  6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
    206 
    207 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
    208  10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
    209 
    210 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
    211  6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
    212  23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
    213  27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
    214  31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
    215 
    216 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
    217  9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
    218  21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
    219  24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
    220  27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
    221 
    222 static inline void DefaultScalingList4x4(
    223  int i,
    224  int scaling_list4x4[][kH264ScalingList4x4Length]) {
    225  DCHECK_LT(i, 6);
    226 
    227  if (i < 3)
    228  memcpy(scaling_list4x4[i], kDefault4x4Intra, sizeof(kDefault4x4Intra));
    229  else if (i < 6)
    230  memcpy(scaling_list4x4[i], kDefault4x4Inter, sizeof(kDefault4x4Inter));
    231 }
    232 
    233 static inline void DefaultScalingList8x8(
    234  int i,
    235  int scaling_list8x8[][kH264ScalingList8x8Length]) {
    236  DCHECK_LT(i, 6);
    237 
    238  if (i % 2 == 0)
    239  memcpy(scaling_list8x8[i], kDefault8x8Intra, sizeof(kDefault8x8Intra));
    240  else
    241  memcpy(scaling_list8x8[i], kDefault8x8Inter, sizeof(kDefault8x8Inter));
    242 }
    243 
    244 static void FallbackScalingList4x4(
    245  int i,
    246  const int default_scaling_list_intra[],
    247  const int default_scaling_list_inter[],
    248  int scaling_list4x4[][kH264ScalingList4x4Length]) {
    249  static const int kScalingList4x4ByteSize =
    250  sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
    251 
    252  switch (i) {
    253  case 0:
    254  memcpy(scaling_list4x4[i], default_scaling_list_intra,
    255  kScalingList4x4ByteSize);
    256  break;
    257 
    258  case 1:
    259  memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
    260  break;
    261 
    262  case 2:
    263  memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
    264  break;
    265 
    266  case 3:
    267  memcpy(scaling_list4x4[i], default_scaling_list_inter,
    268  kScalingList4x4ByteSize);
    269  break;
    270 
    271  case 4:
    272  memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
    273  break;
    274 
    275  case 5:
    276  memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
    277  break;
    278 
    279  default:
    280  NOTREACHED();
    281  break;
    282  }
    283 }
    284 
    285 static void FallbackScalingList8x8(
    286  int i,
    287  const int default_scaling_list_intra[],
    288  const int default_scaling_list_inter[],
    289  int scaling_list8x8[][kH264ScalingList8x8Length]) {
    290  static const int kScalingList8x8ByteSize =
    291  sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
    292 
    293  switch (i) {
    294  case 0:
    295  memcpy(scaling_list8x8[i], default_scaling_list_intra,
    296  kScalingList8x8ByteSize);
    297  break;
    298 
    299  case 1:
    300  memcpy(scaling_list8x8[i], default_scaling_list_inter,
    301  kScalingList8x8ByteSize);
    302  break;
    303 
    304  case 2:
    305  memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
    306  break;
    307 
    308  case 3:
    309  memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
    310  break;
    311 
    312  case 4:
    313  memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
    314  break;
    315 
    316  case 5:
    317  memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
    318  break;
    319 
    320  default:
    321  NOTREACHED();
    322  break;
    323  }
    324 }
    325 
    326 H264Parser::Result H264Parser::ParseScalingList(H26xBitReader* br,
    327  int size,
    328  int* scaling_list,
    329  bool* use_default) {
    330  // See chapter 7.3.2.1.1.1.
    331  int last_scale = 8;
    332  int next_scale = 8;
    333  int delta_scale;
    334 
    335  *use_default = false;
    336 
    337  for (int j = 0; j < size; ++j) {
    338  if (next_scale != 0) {
    339  READ_SE_OR_RETURN(&delta_scale);
    340  IN_RANGE_OR_RETURN(delta_scale, -128, 127);
    341  next_scale = (last_scale + delta_scale + 256) & 0xff;
    342 
    343  if (j == 0 && next_scale == 0) {
    344  *use_default = true;
    345  return kOk;
    346  }
    347  }
    348 
    349  scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
    350  last_scale = scaling_list[j];
    351  }
    352 
    353  return kOk;
    354 }
    355 
    356 H264Parser::Result H264Parser::ParseSpsScalingLists(H26xBitReader* br,
    357  H264Sps* sps) {
    358  // See 7.4.2.1.1.
    359  bool seq_scaling_list_present_flag;
    360  bool use_default;
    361  Result res;
    362 
    363  // Parse scaling_list4x4.
    364  for (int i = 0; i < 6; ++i) {
    365  READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
    366 
    367  if (seq_scaling_list_present_flag) {
    368  res = ParseScalingList(br,
    369  arraysize(sps->scaling_list4x4[i]),
    370  sps->scaling_list4x4[i],
    371  &use_default);
    372  if (res != kOk)
    373  return res;
    374 
    375  if (use_default)
    376  DefaultScalingList4x4(i, sps->scaling_list4x4);
    377 
    378  } else {
    379  FallbackScalingList4x4(
    380  i, kDefault4x4Intra, kDefault4x4Inter, sps->scaling_list4x4);
    381  }
    382  }
    383 
    384  // Parse scaling_list8x8.
    385  for (int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
    386  READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
    387 
    388  if (seq_scaling_list_present_flag) {
    389  res = ParseScalingList(br,
    390  arraysize(sps->scaling_list8x8[i]),
    391  sps->scaling_list8x8[i],
    392  &use_default);
    393  if (res != kOk)
    394  return res;
    395 
    396  if (use_default)
    397  DefaultScalingList8x8(i, sps->scaling_list8x8);
    398 
    399  } else {
    400  FallbackScalingList8x8(
    401  i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8);
    402  }
    403  }
    404 
    405  return kOk;
    406 }
    407 
    408 H264Parser::Result H264Parser::ParsePpsScalingLists(H26xBitReader* br,
    409  const H264Sps& sps,
    410  H264Pps* pps) {
    411  // See 7.4.2.2.
    412  bool pic_scaling_list_present_flag;
    413  bool use_default;
    414  Result res;
    415 
    416  for (int i = 0; i < 6; ++i) {
    417  READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
    418 
    419  if (pic_scaling_list_present_flag) {
    420  res = ParseScalingList(br,
    421  arraysize(pps->scaling_list4x4[i]),
    422  pps->scaling_list4x4[i],
    423  &use_default);
    424  if (res != kOk)
    425  return res;
    426 
    427  if (use_default)
    428  DefaultScalingList4x4(i, pps->scaling_list4x4);
    429 
    430  } else {
    431  if (sps.seq_scaling_matrix_present_flag) {
    432  // Table 7-2 fallback rule A in spec.
    433  FallbackScalingList4x4(
    434  i, kDefault4x4Intra, kDefault4x4Inter, pps->scaling_list4x4);
    435  } else {
    436  // Table 7-2 fallback rule B in spec.
    437  FallbackScalingList4x4(i,
    438  sps.scaling_list4x4[0],
    439  sps.scaling_list4x4[3],
    440  pps->scaling_list4x4);
    441  }
    442  }
    443  }
    444 
    445  if (pps->transform_8x8_mode_flag) {
    446  for (int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
    447  READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
    448 
    449  if (pic_scaling_list_present_flag) {
    450  res = ParseScalingList(br,
    451  arraysize(pps->scaling_list8x8[i]),
    452  pps->scaling_list8x8[i],
    453  &use_default);
    454  if (res != kOk)
    455  return res;
    456 
    457  if (use_default)
    458  DefaultScalingList8x8(i, pps->scaling_list8x8);
    459 
    460  } else {
    461  if (sps.seq_scaling_matrix_present_flag) {
    462  // Table 7-2 fallback rule A in spec.
    463  FallbackScalingList8x8(
    464  i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8);
    465  } else {
    466  // Table 7-2 fallback rule B in spec.
    467  FallbackScalingList8x8(i,
    468  sps.scaling_list8x8[0],
    469  sps.scaling_list8x8[1],
    470  pps->scaling_list8x8);
    471  }
    472  }
    473  }
    474  }
    475  return kOk;
    476 }
    477 
    478 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
    479  H26xBitReader* br, bool* hrd_parameters_present) {
    480  int data;
    481  READ_BOOL_OR_RETURN(&data); // {nal,vcl}_hrd_parameters_present_flag
    482  if (!data)
    483  return kOk;
    484 
    485  *hrd_parameters_present = true;
    486 
    487  int cpb_cnt_minus1;
    488  READ_UE_OR_RETURN(&cpb_cnt_minus1);
    489  IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
    490  READ_BITS_OR_RETURN(8, &data); // bit_rate_scale, cpb_size_scale
    491  for (int i = 0; i <= cpb_cnt_minus1; ++i) {
    492  READ_UE_OR_RETURN(&data); // bit_rate_value_minus1[i]
    493  READ_UE_OR_RETURN(&data); // cpb_size_value_minus1[i]
    494  READ_BOOL_OR_RETURN(&data); // cbr_flag
    495  }
    496  READ_BITS_OR_RETURN(20, &data); // cpb/dpb delays, etc.
    497 
    498  return kOk;
    499 }
    500 
    501 H264Parser::Result H264Parser::ParseVUIParameters(H26xBitReader* br,
    502  H264Sps* sps) {
    503  bool aspect_ratio_info_present_flag;
    504  READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
    505  if (aspect_ratio_info_present_flag) {
    506  int aspect_ratio_idc;
    507  READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
    508  if (aspect_ratio_idc == kExtendedSar) {
    509  READ_BITS_OR_RETURN(16, &sps->sar_width);
    510  READ_BITS_OR_RETURN(16, &sps->sar_height);
    511  } else {
    512  const int max_aspect_ratio_idc = arraysize(kTableSarWidth) - 1;
    513  IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
    514  sps->sar_width = kTableSarWidth[aspect_ratio_idc];
    515  sps->sar_height = kTableSarHeight[aspect_ratio_idc];
    516  }
    517  }
    518 
    519  int data;
    520  // Read and ignore overscan and video signal type info.
    521  READ_BOOL_OR_RETURN(&data); // overscan_info_present_flag
    522  if (data)
    523  READ_BOOL_OR_RETURN(&data); // overscan_appropriate_flag
    524 
    525  READ_BOOL_OR_RETURN(&data); // video_signal_type_present_flag
    526  if (data) {
    527  READ_BITS_OR_RETURN(3, &data); // video_format
    528  READ_BOOL_OR_RETURN(&data); // video_full_range_flag
    529  READ_BOOL_OR_RETURN(&data); // colour_description_present_flag
    530  if (data) {
    531  READ_BITS_OR_RETURN(8, &data); // colour primaries
    532  READ_BITS_OR_RETURN(8, &sps->transfer_characteristics);
    533  READ_BITS_OR_RETURN(8, &data); // matrix coeffs
    534  }
    535  }
    536 
    537  READ_BOOL_OR_RETURN(&data); // chroma_loc_info_present_flag
    538  if (data) {
    539  READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_top_field
    540  READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_bottom_field
    541  }
    542 
    543  // Read and ignore timing info.
    544  READ_BOOL_OR_RETURN(&data); // timing_info_present_flag
    545  if (data) {
    546  READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
    547  READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
    548  READ_BITS_OR_RETURN(16, &data); // time_scale
    549  READ_BITS_OR_RETURN(16, &data); // time_scale
    550  READ_BOOL_OR_RETURN(&data); // fixed_frame_rate_flag
    551  }
    552 
    553  // Read and ignore NAL HRD parameters, if present.
    554  bool hrd_parameters_present = false;
    555  Result res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
    556  if (res != kOk)
    557  return res;
    558 
    559  // Read and ignore VCL HRD parameters, if present.
    560  res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
    561  if (res != kOk)
    562  return res;
    563 
    564  if (hrd_parameters_present) // One of NAL or VCL params present is enough.
    565  READ_BOOL_OR_RETURN(&data); // low_delay_hrd_flag
    566 
    567  READ_BOOL_OR_RETURN(&data); // pic_struct_present_flag
    568  READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
    569  if (sps->bitstream_restriction_flag) {
    570  READ_BOOL_OR_RETURN(&data); // motion_vectors_over_pic_boundaries_flag
    571  READ_UE_OR_RETURN(&data); // max_bytes_per_pic_denom
    572  READ_UE_OR_RETURN(&data); // max_bits_per_mb_denom
    573  READ_UE_OR_RETURN(&data); // log2_max_mv_length_horizontal
    574  READ_UE_OR_RETURN(&data); // log2_max_mv_length_vertical
    575  READ_UE_OR_RETURN(&sps->max_num_reorder_frames);
    576  READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
    577  TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
    578  IN_RANGE_OR_RETURN(
    579  sps->max_num_reorder_frames, 0, sps->max_dec_frame_buffering);
    580  }
    581 
    582  return kOk;
    583 }
    584 
    585 static void FillDefaultSeqScalingLists(H264Sps* sps) {
    586  for (int i = 0; i < 6; ++i)
    587  for (int j = 0; j < kH264ScalingList4x4Length; ++j)
    588  sps->scaling_list4x4[i][j] = 16;
    589 
    590  for (int i = 0; i < 6; ++i)
    591  for (int j = 0; j < kH264ScalingList8x8Length; ++j)
    592  sps->scaling_list8x8[i][j] = 16;
    593 }
    594 
    595 H264Parser::Result H264Parser::ParseSps(const Nalu& nalu, int* sps_id) {
    596  // See 7.4.2.1.
    597  int data;
    598  Result res;
    599  H26xBitReader reader;
    600  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    601  H26xBitReader* br = &reader;
    602 
    603  *sps_id = -1;
    604 
    605  std::unique_ptr<H264Sps> sps(new H264Sps());
    606 
    607  READ_BITS_OR_RETURN(8, &sps->profile_idc);
    608  READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
    609  READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
    610  READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
    611  READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
    612  READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
    613  READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
    614  READ_BITS_OR_RETURN(2, &data); // reserved_zero_2bits
    615  READ_BITS_OR_RETURN(8, &sps->level_idc);
    616  READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
    617  TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
    618 
    619  if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
    620  sps->profile_idc == 122 || sps->profile_idc == 244 ||
    621  sps->profile_idc == 44 || sps->profile_idc == 83 ||
    622  sps->profile_idc == 86 || sps->profile_idc == 118 ||
    623  sps->profile_idc == 128) {
    624  READ_UE_OR_RETURN(&sps->chroma_format_idc);
    625  TRUE_OR_RETURN(sps->chroma_format_idc < 4);
    626 
    627  if (sps->chroma_format_idc == 3)
    628  READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
    629 
    630  READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
    631  TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
    632 
    633  READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
    634  TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
    635 
    636  READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
    637  READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
    638 
    639  if (sps->seq_scaling_matrix_present_flag) {
    640  DVLOG(4) << "Scaling matrix present";
    641  res = ParseSpsScalingLists(br, sps.get());
    642  if (res != kOk)
    643  return res;
    644  } else {
    645  FillDefaultSeqScalingLists(sps.get());
    646  }
    647  } else {
    648  sps->chroma_format_idc = 1;
    649  FillDefaultSeqScalingLists(sps.get());
    650  }
    651 
    652  if (sps->separate_colour_plane_flag)
    653  sps->chroma_array_type = 0;
    654  else
    655  sps->chroma_array_type = sps->chroma_format_idc;
    656 
    657  READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
    658  TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
    659 
    660  READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
    661  TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
    662 
    663  sps->expected_delta_per_pic_order_cnt_cycle = 0;
    664  if (sps->pic_order_cnt_type == 0) {
    665  READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
    666  TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
    667  } else if (sps->pic_order_cnt_type == 1) {
    668  READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
    669  READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
    670  READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
    671  READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
    672  TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
    673 
    674  for (int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
    675  READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
    676  sps->expected_delta_per_pic_order_cnt_cycle +=
    677  sps->offset_for_ref_frame[i];
    678  }
    679  }
    680 
    681  READ_UE_OR_RETURN(&sps->max_num_ref_frames);
    682  READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
    683 
    684  READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
    685  READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
    686 
    687  READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
    688  if (!sps->frame_mbs_only_flag)
    689  READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
    690 
    691  READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
    692 
    693  READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
    694  if (sps->frame_cropping_flag) {
    695  READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
    696  READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
    697  READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
    698  READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
    699  }
    700 
    701  READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
    702  if (sps->vui_parameters_present_flag) {
    703  DVLOG(4) << "VUI parameters present";
    704  res = ParseVUIParameters(br, sps.get());
    705  if (res != kOk)
    706  return res;
    707  }
    708 
    709  // If an SPS with the same id already exists, replace it.
    710  *sps_id = sps->seq_parameter_set_id;
    711  active_SPSes_[*sps_id] = std::move(sps);
    712 
    713  return kOk;
    714 }
    715 
    716 H264Parser::Result H264Parser::ParsePps(const Nalu& nalu, int* pps_id) {
    717  // See 7.4.2.2.
    718  const H264Sps* sps;
    719  Result res;
    720  H26xBitReader reader;
    721  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    722  H26xBitReader* br = &reader;
    723 
    724  *pps_id = -1;
    725 
    726  std::unique_ptr<H264Pps> pps(new H264Pps());
    727 
    728  READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
    729  READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
    730  TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
    731 
    732  sps = GetSps(pps->seq_parameter_set_id);
    733  TRUE_OR_RETURN(sps);
    734 
    735  READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
    736  READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
    737 
    738  READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
    739  if (pps->num_slice_groups_minus1 > 1) {
    740  LOG_ERROR_ONCE("Slice groups not supported");
    741  return kUnsupportedStream;
    742  }
    743 
    744  READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
    745  TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
    746 
    747  READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
    748  TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
    749 
    750  READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
    751  READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
    752  TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
    753 
    754  READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
    755  IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
    756 
    757  READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
    758  IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
    759 
    760  READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
    761  IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
    762  pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
    763 
    764  READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
    765  READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
    766  READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
    767 
    768  if (br->HasMoreRBSPData()) {
    769  READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
    770  READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
    771 
    772  if (pps->pic_scaling_matrix_present_flag) {
    773  DVLOG(4) << "Picture scaling matrix present";
    774  res = ParsePpsScalingLists(br, *sps, pps.get());
    775  if (res != kOk)
    776  return res;
    777  }
    778 
    779  READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
    780  }
    781 
    782  // If a PPS with the same id already exists, replace it.
    783  *pps_id = pps->pic_parameter_set_id;
    784  active_PPSes_[*pps_id] = std::move(pps);
    785 
    786  return kOk;
    787 }
    788 
    789 H264Parser::Result H264Parser::ParseRefPicListModification(
    790  H26xBitReader* br,
    791  int num_ref_idx_active_minus1,
    792  H264ModificationOfPicNum* ref_list_mods) {
    793  H264ModificationOfPicNum* pic_num_mod;
    794 
    795  if (num_ref_idx_active_minus1 >= 32)
    796  return kInvalidStream;
    797 
    798  for (int i = 0; i < 32; ++i) {
    799  pic_num_mod = &ref_list_mods[i];
    800  READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
    801  TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
    802 
    803  switch (pic_num_mod->modification_of_pic_nums_idc) {
    804  case 0:
    805  case 1:
    806  READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
    807  break;
    808 
    809  case 2:
    810  READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
    811  break;
    812 
    813  case 3:
    814  // Per spec, list cannot be empty.
    815  if (i == 0)
    816  return kInvalidStream;
    817  return kOk;
    818 
    819  default:
    820  return kInvalidStream;
    821  }
    822  }
    823 
    824  // If we got here, we didn't get loop end marker prematurely,
    825  // so make sure it is there for our client.
    826  int modification_of_pic_nums_idc;
    827  READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
    828  TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
    829 
    830  return kOk;
    831 }
    832 
    833 H264Parser::Result H264Parser::ParseRefPicListModifications(
    834  H26xBitReader* br, H264SliceHeader* shdr) {
    835  Result res;
    836 
    837  if (!shdr->IsISlice() && !shdr->IsSISlice()) {
    838  READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
    839  if (shdr->ref_pic_list_modification_flag_l0) {
    840  res = ParseRefPicListModification(br, shdr->num_ref_idx_l0_active_minus1,
    841  shdr->ref_list_l0_modifications);
    842  if (res != kOk)
    843  return res;
    844  }
    845  }
    846 
    847  if (shdr->IsBSlice()) {
    848  READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
    849  if (shdr->ref_pic_list_modification_flag_l1) {
    850  res = ParseRefPicListModification(br, shdr->num_ref_idx_l1_active_minus1,
    851  shdr->ref_list_l1_modifications);
    852  if (res != kOk)
    853  return res;
    854  }
    855  }
    856 
    857  return kOk;
    858 }
    859 
    860 H264Parser::Result H264Parser::ParseWeightingFactors(
    861  H26xBitReader* br,
    862  int num_ref_idx_active_minus1,
    863  int chroma_array_type,
    864  int luma_log2_weight_denom,
    865  int chroma_log2_weight_denom,
    866  H264WeightingFactors* w_facts) {
    867  int def_luma_weight = 1 << luma_log2_weight_denom;
    868  int def_chroma_weight = 1 << chroma_log2_weight_denom;
    869 
    870  for (int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
    871  READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag[i]);
    872  if (w_facts->luma_weight_flag[i]) {
    873  READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
    874  IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
    875 
    876  READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
    877  IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
    878  } else {
    879  w_facts->luma_weight[i] = def_luma_weight;
    880  w_facts->luma_offset[i] = 0;
    881  }
    882 
    883  if (chroma_array_type != 0) {
    884  READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag[i]);
    885  if (w_facts->chroma_weight_flag[i]) {
    886  for (int j = 0; j < 2; ++j) {
    887  READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
    888  IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
    889 
    890  READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
    891  IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
    892  }
    893  } else {
    894  for (int j = 0; j < 2; ++j) {
    895  w_facts->chroma_weight[i][j] = def_chroma_weight;
    896  w_facts->chroma_offset[i][j] = 0;
    897  }
    898  }
    899  }
    900  }
    901 
    902  return kOk;
    903 }
    904 
    905 H264Parser::Result H264Parser::ParsePredWeightTable(H26xBitReader* br,
    906  const H264Sps& sps,
    907  H264SliceHeader* shdr) {
    908  READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
    909  TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
    910 
    911  if (sps.chroma_array_type != 0)
    912  READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
    913  TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
    914 
    915  Result res = ParseWeightingFactors(br,
    916  shdr->num_ref_idx_l0_active_minus1,
    917  sps.chroma_array_type,
    918  shdr->luma_log2_weight_denom,
    919  shdr->chroma_log2_weight_denom,
    920  &shdr->pred_weight_table_l0);
    921  if (res != kOk)
    922  return res;
    923 
    924  if (shdr->IsBSlice()) {
    925  res = ParseWeightingFactors(br,
    926  shdr->num_ref_idx_l1_active_minus1,
    927  sps.chroma_array_type,
    928  shdr->luma_log2_weight_denom,
    929  shdr->chroma_log2_weight_denom,
    930  &shdr->pred_weight_table_l1);
    931  if (res != kOk)
    932  return res;
    933  }
    934 
    935  return kOk;
    936 }
    937 
    938 H264Parser::Result H264Parser::ParseDecRefPicMarking(H26xBitReader* br,
    939  H264SliceHeader* shdr) {
    940  if (shdr->idr_pic_flag) {
    941  READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
    942  READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
    943  } else {
    944  READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
    945 
    946  H264DecRefPicMarking* marking;
    947  if (shdr->adaptive_ref_pic_marking_mode_flag) {
    948  size_t i;
    949  for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) {
    950  marking = &shdr->ref_pic_marking[i];
    951 
    952  READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
    953  if (marking->memory_mgmnt_control_operation == 0)
    954  break;
    955 
    956  if (marking->memory_mgmnt_control_operation == 1 ||
    957  marking->memory_mgmnt_control_operation == 3)
    958  READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
    959 
    960  if (marking->memory_mgmnt_control_operation == 2)
    961  READ_UE_OR_RETURN(&marking->long_term_pic_num);
    962 
    963  if (marking->memory_mgmnt_control_operation == 3 ||
    964  marking->memory_mgmnt_control_operation == 6)
    965  READ_UE_OR_RETURN(&marking->long_term_frame_idx);
    966 
    967  if (marking->memory_mgmnt_control_operation == 4)
    968  READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
    969 
    970  if (marking->memory_mgmnt_control_operation > 6)
    971  return kInvalidStream;
    972  }
    973 
    974  if (i == arraysize(shdr->ref_pic_marking)) {
    975  LOG_ERROR_ONCE("Ran out of dec ref pic marking fields");
    976  return kUnsupportedStream;
    977  }
    978  }
    979  }
    980 
    981  return kOk;
    982 }
    983 
    984 H264Parser::Result H264Parser::ParseSliceHeader(const Nalu& nalu,
    985  H264SliceHeader* shdr) {
    986  // See 7.4.3.
    987  const H264Sps* sps;
    988  const H264Pps* pps;
    989  Result res;
    990  H26xBitReader reader;
    991  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    992  H26xBitReader* br = &reader;
    993 
    994  memset(reinterpret_cast<void*>(shdr), 0, sizeof(*shdr));
    995 
    996  shdr->idr_pic_flag = (nalu.type() == 5);
    997  shdr->nal_ref_idc = nalu.ref_idc();
    998  shdr->nalu_data = nalu.data();
    999  shdr->nalu_size = nalu.header_size() + nalu.payload_size();
    1000 
    1001  READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
    1002  READ_UE_OR_RETURN(&shdr->slice_type);
    1003  TRUE_OR_RETURN(shdr->slice_type < 10);
    1004 
    1005  READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
    1006 
    1007  pps = GetPps(shdr->pic_parameter_set_id);
    1008  TRUE_OR_RETURN(pps);
    1009 
    1010  sps = GetSps(pps->seq_parameter_set_id);
    1011  TRUE_OR_RETURN(sps);
    1012 
    1013  if (sps->separate_colour_plane_flag) {
    1014  LOG_ERROR_ONCE("Interlaced streams not supported");
    1015  return kUnsupportedStream;
    1016  }
    1017 
    1018  READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
    1019  if (!sps->frame_mbs_only_flag) {
    1020  READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
    1021  if (shdr->field_pic_flag) {
    1022  LOG_ERROR_ONCE("Interlaced streams not supported");
    1023  return kUnsupportedStream;
    1024  }
    1025  }
    1026 
    1027  if (shdr->idr_pic_flag)
    1028  READ_UE_OR_RETURN(&shdr->idr_pic_id);
    1029 
    1030  if (sps->pic_order_cnt_type == 0) {
    1031  READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
    1032  &shdr->pic_order_cnt_lsb);
    1033  if (pps->bottom_field_pic_order_in_frame_present_flag &&
    1034  !shdr->field_pic_flag)
    1035  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
    1036  }
    1037 
    1038  if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
    1039  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[0]);
    1040  if (pps->bottom_field_pic_order_in_frame_present_flag &&
    1041  !shdr->field_pic_flag)
    1042  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[1]);
    1043  }
    1044 
    1045  if (pps->redundant_pic_cnt_present_flag) {
    1046  READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
    1047  TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
    1048  }
    1049 
    1050  if (shdr->IsBSlice())
    1051  READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
    1052 
    1053  if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
    1054  READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
    1055  if (shdr->num_ref_idx_active_override_flag) {
    1056  READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
    1057  if (shdr->IsBSlice())
    1058  READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
    1059  } else {
    1060  shdr->num_ref_idx_l0_active_minus1 =
    1061  pps->num_ref_idx_l0_default_active_minus1;
    1062  if (shdr->IsBSlice()) {
    1063  shdr->num_ref_idx_l1_active_minus1 =
    1064  pps->num_ref_idx_l1_default_active_minus1;
    1065  }
    1066  }
    1067  }
    1068  if (shdr->field_pic_flag) {
    1069  TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
    1070  TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
    1071  } else {
    1072  TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
    1073  TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
    1074  }
    1075 
    1076  if (nalu.type() == Nalu::H264_CodedSliceExtension) {
    1077  return kUnsupportedStream;
    1078  } else {
    1079  res = ParseRefPicListModifications(br, shdr);
    1080  if (res != kOk)
    1081  return res;
    1082  }
    1083 
    1084  if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
    1085  (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
    1086  res = ParsePredWeightTable(br, *sps, shdr);
    1087  if (res != kOk)
    1088  return res;
    1089  }
    1090 
    1091  if (nalu.ref_idc() != 0) {
    1092  res = ParseDecRefPicMarking(br, shdr);
    1093  if (res != kOk)
    1094  return res;
    1095  }
    1096 
    1097  if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
    1098  !shdr->IsSISlice()) {
    1099  READ_UE_OR_RETURN(&shdr->cabac_init_idc);
    1100  TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
    1101  }
    1102 
    1103  READ_SE_OR_RETURN(&shdr->slice_qp_delta);
    1104 
    1105  if (shdr->IsSPSlice() || shdr->IsSISlice()) {
    1106  if (shdr->IsSPSlice())
    1107  READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
    1108  READ_SE_OR_RETURN(&shdr->slice_qs_delta);
    1109  }
    1110 
    1111  if (pps->deblocking_filter_control_present_flag) {
    1112  READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
    1113  TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
    1114 
    1115  if (shdr->disable_deblocking_filter_idc != 1) {
    1116  READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
    1117  IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
    1118 
    1119  READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
    1120  IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
    1121  }
    1122  }
    1123 
    1124  if (pps->num_slice_groups_minus1 > 0) {
    1125  LOG_ERROR_ONCE("Slice groups not supported");
    1126  return kUnsupportedStream;
    1127  }
    1128 
    1129  shdr->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
    1130  return kOk;
    1131 }
    1132 
    1133 H264Parser::Result H264Parser::ParseSEI(const Nalu& nalu,
    1134  H264SEIMessage* sei_msg) {
    1135  int byte;
    1136  H26xBitReader reader;
    1137  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    1138  H26xBitReader* br = &reader;
    1139 
    1140  memset(reinterpret_cast<void*>(sei_msg), 0, sizeof(*sei_msg));
    1141 
    1142  READ_BITS_OR_RETURN(8, &byte);
    1143  while (byte == 0xff) {
    1144  sei_msg->type += 255;
    1145  READ_BITS_OR_RETURN(8, &byte);
    1146  }
    1147  sei_msg->type += byte;
    1148 
    1149  READ_BITS_OR_RETURN(8, &byte);
    1150  while (byte == 0xff) {
    1151  sei_msg->payload_size += 255;
    1152  READ_BITS_OR_RETURN(8, &byte);
    1153  }
    1154  sei_msg->payload_size += byte;
    1155 
    1156  DVLOG(4) << "Found SEI message type: " << sei_msg->type
    1157  << " payload size: " << sei_msg->payload_size;
    1158 
    1159  switch (sei_msg->type) {
    1160  case H264SEIMessage::kSEIRecoveryPoint:
    1161  READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
    1162  READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
    1163  READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
    1164  READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
    1165  break;
    1166 
    1167  default:
    1168  DVLOG(4) << "Unsupported SEI message";
    1169  break;
    1170  }
    1171 
    1172  return kOk;
    1173 }
    1174 
    1175 } // namespace media
    1176 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/codecs/h264_parser.h"
    +
    6 
    +
    7 #include <memory>
    +
    8 #include "packager/base/logging.h"
    +
    9 #include "packager/media/base/buffer_reader.h"
    +
    10 
    +
    11 #define LOG_ERROR_ONCE(msg) \
    +
    12  do { \
    +
    13  static bool logged_once = false; \
    +
    14  LOG_IF(ERROR, !logged_once) << msg; \
    +
    15  logged_once = true; \
    +
    16  } while (0)
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    +
    21 // Implemented according to ISO/IEC 14496-10:2005 7.4.2.1 Sequence parameter set
    +
    22 // RBSP semantics.
    +
    23 bool ExtractResolutionFromSps(const H264Sps& sps,
    +
    24  uint32_t* coded_width,
    +
    25  uint32_t* coded_height,
    +
    26  uint32_t* pixel_width,
    +
    27  uint32_t* pixel_height) {
    +
    28  int crop_x = 0;
    +
    29  int crop_y = 0;
    +
    30  if (sps.frame_cropping_flag) {
    +
    31  int sub_width_c = 0;
    +
    32  int sub_height_c = 0;
    +
    33  // Table 6-1.
    +
    34  switch (sps.chroma_format_idc) {
    +
    35  case 0: // monochrome
    +
    36  // SubWidthC and SubHeightC are not defined for monochrome. For ease of
    +
    37  // computation afterwards, assign both to 1.
    +
    38  sub_width_c = 1;
    +
    39  sub_height_c = 1;
    +
    40  break;
    +
    41  case 1: // 4:2:0
    +
    42  sub_width_c = 2;
    +
    43  sub_height_c = 2;
    +
    44  break;
    +
    45  case 2: // 4:2:2
    +
    46  sub_width_c = 2;
    +
    47  sub_height_c = 1;
    +
    48  break;
    +
    49  case 3: // 4:4:4
    +
    50  sub_width_c = 1;
    +
    51  sub_height_c = 1;
    +
    52  break;
    +
    53  default:
    +
    54  LOG(ERROR) << "Unexpected chroma_format_idc " << sps.chroma_format_idc;
    +
    55  return false;
    +
    56  }
    +
    57 
    +
    58  // Formula 7-16, 7-17, 7-18, 7-19.
    +
    59  int crop_unit_x = sub_width_c;
    +
    60  int crop_unit_y = sub_height_c * (2 - (sps.frame_mbs_only_flag ? 1 : 0));
    +
    61  crop_x = crop_unit_x *
    +
    62  (sps.frame_crop_left_offset + sps.frame_crop_right_offset);
    +
    63  crop_y = crop_unit_y *
    +
    64  (sps.frame_crop_top_offset + sps.frame_crop_bottom_offset);
    +
    65  }
    +
    66 
    +
    67  // Formula 7-10, 7-11.
    +
    68  int pic_width_in_mbs = sps.pic_width_in_mbs_minus1 + 1;
    +
    69  *coded_width = pic_width_in_mbs * 16 - crop_x;
    +
    70 
    +
    71  // Formula 7-13, 7-15.
    +
    72  int pic_height_in_mbs = (2 - (sps.frame_mbs_only_flag ? 1 : 0)) *
    +
    73  (sps.pic_height_in_map_units_minus1 + 1);
    +
    74  *coded_height = pic_height_in_mbs * 16 - crop_y;
    +
    75 
    +
    76  // 0 means it wasn't in the SPS and therefore assume 1.
    +
    77  *pixel_width = sps.sar_width == 0 ? 1 : sps.sar_width;
    +
    78  *pixel_height = sps.sar_height == 0 ? 1 : sps.sar_height;
    +
    79  DVLOG(2) << "Found coded_width: " << *coded_width
    +
    80  << " coded_height: " << *coded_height
    +
    81  << " pixel_width: " << *pixel_width
    +
    82  << " pixel_height: " << *pixel_height;
    +
    83  return true;
    +
    84 }
    +
    85 
    +
    86 bool H264SliceHeader::IsPSlice() const {
    +
    87  return (slice_type % 5 == kPSlice);
    +
    88 }
    +
    89 
    +
    90 bool H264SliceHeader::IsBSlice() const {
    +
    91  return (slice_type % 5 == kBSlice);
    +
    92 }
    +
    93 
    +
    94 bool H264SliceHeader::IsISlice() const {
    +
    95  return (slice_type % 5 == kISlice);
    +
    96 }
    +
    97 
    +
    98 bool H264SliceHeader::IsSPSlice() const {
    +
    99  return (slice_type % 5 == kSPSlice);
    +
    100 }
    +
    101 
    +
    102 bool H264SliceHeader::IsSISlice() const {
    +
    103  return (slice_type % 5 == kSISlice);
    +
    104 }
    +
    105 
    +
    106 #define READ_BITS_OR_RETURN(num_bits, out) \
    +
    107  do { \
    +
    108  if (!br->ReadBits(num_bits, (out))) { \
    +
    109  DVLOG(1) \
    +
    110  << "Error in stream: unexpected EOS while trying to read " #out; \
    +
    111  return kInvalidStream; \
    +
    112  } \
    +
    113  } while (0)
    +
    114 
    +
    115 #define READ_BOOL_OR_RETURN(out) \
    +
    116  do { \
    +
    117  int _out; \
    +
    118  if (!br->ReadBits(1, &_out)) { \
    +
    119  DVLOG(1) \
    +
    120  << "Error in stream: unexpected EOS while trying to read " #out; \
    +
    121  return kInvalidStream; \
    +
    122  } \
    +
    123  *(out) = _out != 0; \
    +
    124  } while (0)
    +
    125 
    +
    126 #define READ_UE_OR_RETURN(out) \
    +
    127  do { \
    +
    128  if (!br->ReadUE(out)) { \
    +
    129  DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
    +
    130  return kInvalidStream; \
    +
    131  } \
    +
    132  } while (0)
    +
    133 
    +
    134 #define READ_SE_OR_RETURN(out) \
    +
    135  do { \
    +
    136  if (!br->ReadSE(out)) { \
    +
    137  DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
    +
    138  return kInvalidStream; \
    +
    139  } \
    +
    140  } while (0)
    +
    141 
    +
    142 #define IN_RANGE_OR_RETURN(val, min, max) \
    +
    143  do { \
    +
    144  if ((val) < (min) || (val) > (max)) { \
    +
    145  DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
    +
    146  << " in range [" << (min) << ":" << (max) << "]" \
    +
    147  << " found " << (val) << " instead"; \
    +
    148  return kInvalidStream; \
    +
    149  } \
    +
    150  } while (0)
    +
    151 
    +
    152 #define TRUE_OR_RETURN(a) \
    +
    153  do { \
    +
    154  if (!(a)) { \
    +
    155  DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
    +
    156  return kInvalidStream; \
    +
    157  } \
    +
    158  } while (0)
    +
    159 
    +
    160 enum AspectRatioIdc {
    +
    161  kExtendedSar = 255,
    +
    162 };
    +
    163 
    +
    164 // ISO 14496 part 10
    +
    165 // VUI parameters: Table E-1 "Meaning of sample aspect ratio indicator"
    +
    166 static const int kTableSarWidth[] = {
    +
    167  0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
    +
    168 };
    +
    169 static const int kTableSarHeight[] = {
    +
    170  0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
    +
    171 };
    +
    172 static_assert(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
    +
    173  "sar_tables_must_have_same_size");
    +
    174 
    +
    175 H264Parser::H264Parser() {}
    +
    176 
    +
    177 H264Parser::~H264Parser() {}
    +
    178 
    +
    179 const H264Pps* H264Parser::GetPps(int pps_id) {
    +
    180  return active_PPSes_[pps_id].get();
    +
    181 }
    +
    182 
    +
    183 const H264Sps* H264Parser::GetSps(int sps_id) {
    +
    184  return active_SPSes_[sps_id].get();
    +
    185 }
    +
    186 
    +
    187 // Default scaling lists (per spec).
    +
    188 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
    +
    189  6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
    +
    190 
    +
    191 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
    +
    192  10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
    +
    193 
    +
    194 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
    +
    195  6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
    +
    196  23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
    +
    197  27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
    +
    198  31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
    +
    199 
    +
    200 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
    +
    201  9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
    +
    202  21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
    +
    203  24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
    +
    204  27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
    +
    205 
    +
    206 static inline void DefaultScalingList4x4(
    +
    207  int i,
    +
    208  int scaling_list4x4[][kH264ScalingList4x4Length]) {
    +
    209  DCHECK_LT(i, 6);
    +
    210 
    +
    211  if (i < 3)
    +
    212  memcpy(scaling_list4x4[i], kDefault4x4Intra, sizeof(kDefault4x4Intra));
    +
    213  else if (i < 6)
    +
    214  memcpy(scaling_list4x4[i], kDefault4x4Inter, sizeof(kDefault4x4Inter));
    +
    215 }
    +
    216 
    +
    217 static inline void DefaultScalingList8x8(
    +
    218  int i,
    +
    219  int scaling_list8x8[][kH264ScalingList8x8Length]) {
    +
    220  DCHECK_LT(i, 6);
    +
    221 
    +
    222  if (i % 2 == 0)
    +
    223  memcpy(scaling_list8x8[i], kDefault8x8Intra, sizeof(kDefault8x8Intra));
    +
    224  else
    +
    225  memcpy(scaling_list8x8[i], kDefault8x8Inter, sizeof(kDefault8x8Inter));
    +
    226 }
    +
    227 
    +
    228 static void FallbackScalingList4x4(
    +
    229  int i,
    +
    230  const int default_scaling_list_intra[],
    +
    231  const int default_scaling_list_inter[],
    +
    232  int scaling_list4x4[][kH264ScalingList4x4Length]) {
    +
    233  static const int kScalingList4x4ByteSize =
    +
    234  sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
    +
    235 
    +
    236  switch (i) {
    +
    237  case 0:
    +
    238  memcpy(scaling_list4x4[i], default_scaling_list_intra,
    +
    239  kScalingList4x4ByteSize);
    +
    240  break;
    +
    241 
    +
    242  case 1:
    +
    243  memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
    +
    244  break;
    +
    245 
    +
    246  case 2:
    +
    247  memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
    +
    248  break;
    +
    249 
    +
    250  case 3:
    +
    251  memcpy(scaling_list4x4[i], default_scaling_list_inter,
    +
    252  kScalingList4x4ByteSize);
    +
    253  break;
    +
    254 
    +
    255  case 4:
    +
    256  memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
    +
    257  break;
    +
    258 
    +
    259  case 5:
    +
    260  memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
    +
    261  break;
    +
    262 
    +
    263  default:
    +
    264  NOTREACHED();
    +
    265  break;
    +
    266  }
    +
    267 }
    +
    268 
    +
    269 static void FallbackScalingList8x8(
    +
    270  int i,
    +
    271  const int default_scaling_list_intra[],
    +
    272  const int default_scaling_list_inter[],
    +
    273  int scaling_list8x8[][kH264ScalingList8x8Length]) {
    +
    274  static const int kScalingList8x8ByteSize =
    +
    275  sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
    +
    276 
    +
    277  switch (i) {
    +
    278  case 0:
    +
    279  memcpy(scaling_list8x8[i], default_scaling_list_intra,
    +
    280  kScalingList8x8ByteSize);
    +
    281  break;
    +
    282 
    +
    283  case 1:
    +
    284  memcpy(scaling_list8x8[i], default_scaling_list_inter,
    +
    285  kScalingList8x8ByteSize);
    +
    286  break;
    +
    287 
    +
    288  case 2:
    +
    289  memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
    +
    290  break;
    +
    291 
    +
    292  case 3:
    +
    293  memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
    +
    294  break;
    +
    295 
    +
    296  case 4:
    +
    297  memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
    +
    298  break;
    +
    299 
    +
    300  case 5:
    +
    301  memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
    +
    302  break;
    +
    303 
    +
    304  default:
    +
    305  NOTREACHED();
    +
    306  break;
    +
    307  }
    +
    308 }
    +
    309 
    +
    310 H264Parser::Result H264Parser::ParseScalingList(H26xBitReader* br,
    +
    311  int size,
    +
    312  int* scaling_list,
    +
    313  bool* use_default) {
    +
    314  // See chapter 7.3.2.1.1.1.
    +
    315  int last_scale = 8;
    +
    316  int next_scale = 8;
    +
    317  int delta_scale;
    +
    318 
    +
    319  *use_default = false;
    +
    320 
    +
    321  for (int j = 0; j < size; ++j) {
    +
    322  if (next_scale != 0) {
    +
    323  READ_SE_OR_RETURN(&delta_scale);
    +
    324  IN_RANGE_OR_RETURN(delta_scale, -128, 127);
    +
    325  next_scale = (last_scale + delta_scale + 256) & 0xff;
    +
    326 
    +
    327  if (j == 0 && next_scale == 0) {
    +
    328  *use_default = true;
    +
    329  return kOk;
    +
    330  }
    +
    331  }
    +
    332 
    +
    333  scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
    +
    334  last_scale = scaling_list[j];
    +
    335  }
    +
    336 
    +
    337  return kOk;
    +
    338 }
    +
    339 
    +
    340 H264Parser::Result H264Parser::ParseSpsScalingLists(H26xBitReader* br,
    +
    341  H264Sps* sps) {
    +
    342  // See 7.4.2.1.1.
    +
    343  bool seq_scaling_list_present_flag;
    +
    344  bool use_default;
    +
    345  Result res;
    +
    346 
    +
    347  // Parse scaling_list4x4.
    +
    348  for (int i = 0; i < 6; ++i) {
    +
    349  READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
    +
    350 
    +
    351  if (seq_scaling_list_present_flag) {
    +
    352  res = ParseScalingList(br,
    +
    353  arraysize(sps->scaling_list4x4[i]),
    +
    354  sps->scaling_list4x4[i],
    +
    355  &use_default);
    +
    356  if (res != kOk)
    +
    357  return res;
    +
    358 
    +
    359  if (use_default)
    +
    360  DefaultScalingList4x4(i, sps->scaling_list4x4);
    +
    361 
    +
    362  } else {
    +
    363  FallbackScalingList4x4(
    +
    364  i, kDefault4x4Intra, kDefault4x4Inter, sps->scaling_list4x4);
    +
    365  }
    +
    366  }
    +
    367 
    +
    368  // Parse scaling_list8x8.
    +
    369  for (int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
    +
    370  READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
    +
    371 
    +
    372  if (seq_scaling_list_present_flag) {
    +
    373  res = ParseScalingList(br,
    +
    374  arraysize(sps->scaling_list8x8[i]),
    +
    375  sps->scaling_list8x8[i],
    +
    376  &use_default);
    +
    377  if (res != kOk)
    +
    378  return res;
    +
    379 
    +
    380  if (use_default)
    +
    381  DefaultScalingList8x8(i, sps->scaling_list8x8);
    +
    382 
    +
    383  } else {
    +
    384  FallbackScalingList8x8(
    +
    385  i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8);
    +
    386  }
    +
    387  }
    +
    388 
    +
    389  return kOk;
    +
    390 }
    +
    391 
    +
    392 H264Parser::Result H264Parser::ParsePpsScalingLists(H26xBitReader* br,
    +
    393  const H264Sps& sps,
    +
    394  H264Pps* pps) {
    +
    395  // See 7.4.2.2.
    +
    396  bool pic_scaling_list_present_flag;
    +
    397  bool use_default;
    +
    398  Result res;
    +
    399 
    +
    400  for (int i = 0; i < 6; ++i) {
    +
    401  READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
    +
    402 
    +
    403  if (pic_scaling_list_present_flag) {
    +
    404  res = ParseScalingList(br,
    +
    405  arraysize(pps->scaling_list4x4[i]),
    +
    406  pps->scaling_list4x4[i],
    +
    407  &use_default);
    +
    408  if (res != kOk)
    +
    409  return res;
    +
    410 
    +
    411  if (use_default)
    +
    412  DefaultScalingList4x4(i, pps->scaling_list4x4);
    +
    413 
    +
    414  } else {
    +
    415  if (sps.seq_scaling_matrix_present_flag) {
    +
    416  // Table 7-2 fallback rule A in spec.
    +
    417  FallbackScalingList4x4(
    +
    418  i, kDefault4x4Intra, kDefault4x4Inter, pps->scaling_list4x4);
    +
    419  } else {
    +
    420  // Table 7-2 fallback rule B in spec.
    +
    421  FallbackScalingList4x4(i,
    +
    422  sps.scaling_list4x4[0],
    +
    423  sps.scaling_list4x4[3],
    +
    424  pps->scaling_list4x4);
    +
    425  }
    +
    426  }
    +
    427  }
    +
    428 
    +
    429  if (pps->transform_8x8_mode_flag) {
    +
    430  for (int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
    +
    431  READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
    +
    432 
    +
    433  if (pic_scaling_list_present_flag) {
    +
    434  res = ParseScalingList(br,
    +
    435  arraysize(pps->scaling_list8x8[i]),
    +
    436  pps->scaling_list8x8[i],
    +
    437  &use_default);
    +
    438  if (res != kOk)
    +
    439  return res;
    +
    440 
    +
    441  if (use_default)
    +
    442  DefaultScalingList8x8(i, pps->scaling_list8x8);
    +
    443 
    +
    444  } else {
    +
    445  if (sps.seq_scaling_matrix_present_flag) {
    +
    446  // Table 7-2 fallback rule A in spec.
    +
    447  FallbackScalingList8x8(
    +
    448  i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8);
    +
    449  } else {
    +
    450  // Table 7-2 fallback rule B in spec.
    +
    451  FallbackScalingList8x8(i,
    +
    452  sps.scaling_list8x8[0],
    +
    453  sps.scaling_list8x8[1],
    +
    454  pps->scaling_list8x8);
    +
    455  }
    +
    456  }
    +
    457  }
    +
    458  }
    +
    459  return kOk;
    +
    460 }
    +
    461 
    +
    462 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
    +
    463  H26xBitReader* br, bool* hrd_parameters_present) {
    +
    464  int data;
    +
    465  READ_BOOL_OR_RETURN(&data); // {nal,vcl}_hrd_parameters_present_flag
    +
    466  if (!data)
    +
    467  return kOk;
    +
    468 
    +
    469  *hrd_parameters_present = true;
    +
    470 
    +
    471  int cpb_cnt_minus1;
    +
    472  READ_UE_OR_RETURN(&cpb_cnt_minus1);
    +
    473  IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
    +
    474  READ_BITS_OR_RETURN(8, &data); // bit_rate_scale, cpb_size_scale
    +
    475  for (int i = 0; i <= cpb_cnt_minus1; ++i) {
    +
    476  READ_UE_OR_RETURN(&data); // bit_rate_value_minus1[i]
    +
    477  READ_UE_OR_RETURN(&data); // cpb_size_value_minus1[i]
    +
    478  READ_BOOL_OR_RETURN(&data); // cbr_flag
    +
    479  }
    +
    480  READ_BITS_OR_RETURN(20, &data); // cpb/dpb delays, etc.
    +
    481 
    +
    482  return kOk;
    +
    483 }
    +
    484 
    +
    485 H264Parser::Result H264Parser::ParseVUIParameters(H26xBitReader* br,
    +
    486  H264Sps* sps) {
    +
    487  bool aspect_ratio_info_present_flag;
    +
    488  READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
    +
    489  if (aspect_ratio_info_present_flag) {
    +
    490  int aspect_ratio_idc;
    +
    491  READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
    +
    492  if (aspect_ratio_idc == kExtendedSar) {
    +
    493  READ_BITS_OR_RETURN(16, &sps->sar_width);
    +
    494  READ_BITS_OR_RETURN(16, &sps->sar_height);
    +
    495  } else {
    +
    496  const int max_aspect_ratio_idc = arraysize(kTableSarWidth) - 1;
    +
    497  IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
    +
    498  sps->sar_width = kTableSarWidth[aspect_ratio_idc];
    +
    499  sps->sar_height = kTableSarHeight[aspect_ratio_idc];
    +
    500  }
    +
    501  }
    +
    502 
    +
    503  int data;
    +
    504  // Read and ignore overscan and video signal type info.
    +
    505  READ_BOOL_OR_RETURN(&data); // overscan_info_present_flag
    +
    506  if (data)
    +
    507  READ_BOOL_OR_RETURN(&data); // overscan_appropriate_flag
    +
    508 
    +
    509  READ_BOOL_OR_RETURN(&data); // video_signal_type_present_flag
    +
    510  if (data) {
    +
    511  READ_BITS_OR_RETURN(3, &data); // video_format
    +
    512  READ_BOOL_OR_RETURN(&data); // video_full_range_flag
    +
    513  READ_BOOL_OR_RETURN(&data); // colour_description_present_flag
    +
    514  if (data) {
    +
    515  READ_BITS_OR_RETURN(8, &data); // colour primaries
    +
    516  READ_BITS_OR_RETURN(8, &sps->transfer_characteristics);
    +
    517  READ_BITS_OR_RETURN(8, &data); // matrix coeffs
    +
    518  }
    +
    519  }
    +
    520 
    +
    521  READ_BOOL_OR_RETURN(&data); // chroma_loc_info_present_flag
    +
    522  if (data) {
    +
    523  READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_top_field
    +
    524  READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_bottom_field
    +
    525  }
    +
    526 
    +
    527  // Read and ignore timing info.
    +
    528  READ_BOOL_OR_RETURN(&data); // timing_info_present_flag
    +
    529  if (data) {
    +
    530  READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
    +
    531  READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
    +
    532  READ_BITS_OR_RETURN(16, &data); // time_scale
    +
    533  READ_BITS_OR_RETURN(16, &data); // time_scale
    +
    534  READ_BOOL_OR_RETURN(&data); // fixed_frame_rate_flag
    +
    535  }
    +
    536 
    +
    537  // Read and ignore NAL HRD parameters, if present.
    +
    538  bool hrd_parameters_present = false;
    +
    539  Result res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
    +
    540  if (res != kOk)
    +
    541  return res;
    +
    542 
    +
    543  // Read and ignore VCL HRD parameters, if present.
    +
    544  res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
    +
    545  if (res != kOk)
    +
    546  return res;
    +
    547 
    +
    548  if (hrd_parameters_present) // One of NAL or VCL params present is enough.
    +
    549  READ_BOOL_OR_RETURN(&data); // low_delay_hrd_flag
    +
    550 
    +
    551  READ_BOOL_OR_RETURN(&data); // pic_struct_present_flag
    +
    552  READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
    +
    553  if (sps->bitstream_restriction_flag) {
    +
    554  READ_BOOL_OR_RETURN(&data); // motion_vectors_over_pic_boundaries_flag
    +
    555  READ_UE_OR_RETURN(&data); // max_bytes_per_pic_denom
    +
    556  READ_UE_OR_RETURN(&data); // max_bits_per_mb_denom
    +
    557  READ_UE_OR_RETURN(&data); // log2_max_mv_length_horizontal
    +
    558  READ_UE_OR_RETURN(&data); // log2_max_mv_length_vertical
    +
    559  READ_UE_OR_RETURN(&sps->max_num_reorder_frames);
    +
    560  READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
    +
    561  TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
    +
    562  IN_RANGE_OR_RETURN(
    +
    563  sps->max_num_reorder_frames, 0, sps->max_dec_frame_buffering);
    +
    564  }
    +
    565 
    +
    566  return kOk;
    +
    567 }
    +
    568 
    +
    569 static void FillDefaultSeqScalingLists(H264Sps* sps) {
    +
    570  for (int i = 0; i < 6; ++i)
    +
    571  for (int j = 0; j < kH264ScalingList4x4Length; ++j)
    +
    572  sps->scaling_list4x4[i][j] = 16;
    +
    573 
    +
    574  for (int i = 0; i < 6; ++i)
    +
    575  for (int j = 0; j < kH264ScalingList8x8Length; ++j)
    +
    576  sps->scaling_list8x8[i][j] = 16;
    +
    577 }
    +
    578 
    +
    579 H264Parser::Result H264Parser::ParseSps(const Nalu& nalu, int* sps_id) {
    +
    580  // See 7.4.2.1.
    +
    581  int data;
    +
    582  Result res;
    +
    583  H26xBitReader reader;
    +
    584  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    +
    585  H26xBitReader* br = &reader;
    +
    586 
    +
    587  *sps_id = -1;
    +
    588 
    +
    589  std::unique_ptr<H264Sps> sps(new H264Sps());
    +
    590 
    +
    591  READ_BITS_OR_RETURN(8, &sps->profile_idc);
    +
    592  READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
    +
    593  READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
    +
    594  READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
    +
    595  READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
    +
    596  READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
    +
    597  READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
    +
    598  READ_BITS_OR_RETURN(2, &data); // reserved_zero_2bits
    +
    599  READ_BITS_OR_RETURN(8, &sps->level_idc);
    +
    600  READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
    +
    601  TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
    +
    602 
    +
    603  if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
    +
    604  sps->profile_idc == 122 || sps->profile_idc == 244 ||
    +
    605  sps->profile_idc == 44 || sps->profile_idc == 83 ||
    +
    606  sps->profile_idc == 86 || sps->profile_idc == 118 ||
    +
    607  sps->profile_idc == 128) {
    +
    608  READ_UE_OR_RETURN(&sps->chroma_format_idc);
    +
    609  TRUE_OR_RETURN(sps->chroma_format_idc < 4);
    +
    610 
    +
    611  if (sps->chroma_format_idc == 3)
    +
    612  READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
    +
    613 
    +
    614  READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
    +
    615  TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
    +
    616 
    +
    617  READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
    +
    618  TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
    +
    619 
    +
    620  READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
    +
    621  READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
    +
    622 
    +
    623  if (sps->seq_scaling_matrix_present_flag) {
    +
    624  DVLOG(4) << "Scaling matrix present";
    +
    625  res = ParseSpsScalingLists(br, sps.get());
    +
    626  if (res != kOk)
    +
    627  return res;
    +
    628  } else {
    +
    629  FillDefaultSeqScalingLists(sps.get());
    +
    630  }
    +
    631  } else {
    +
    632  sps->chroma_format_idc = 1;
    +
    633  FillDefaultSeqScalingLists(sps.get());
    +
    634  }
    +
    635 
    +
    636  if (sps->separate_colour_plane_flag)
    +
    637  sps->chroma_array_type = 0;
    +
    638  else
    +
    639  sps->chroma_array_type = sps->chroma_format_idc;
    +
    640 
    +
    641  READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
    +
    642  TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
    +
    643 
    +
    644  READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
    +
    645  TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
    +
    646 
    +
    647  sps->expected_delta_per_pic_order_cnt_cycle = 0;
    +
    648  if (sps->pic_order_cnt_type == 0) {
    +
    649  READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
    +
    650  TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
    +
    651  } else if (sps->pic_order_cnt_type == 1) {
    +
    652  READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
    +
    653  READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
    +
    654  READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
    +
    655  READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
    +
    656  TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
    +
    657 
    +
    658  for (int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
    +
    659  READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
    +
    660  sps->expected_delta_per_pic_order_cnt_cycle +=
    +
    661  sps->offset_for_ref_frame[i];
    +
    662  }
    +
    663  }
    +
    664 
    +
    665  READ_UE_OR_RETURN(&sps->max_num_ref_frames);
    +
    666  READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
    +
    667 
    +
    668  READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
    +
    669  READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
    +
    670 
    +
    671  READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
    +
    672  if (!sps->frame_mbs_only_flag)
    +
    673  READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
    +
    674 
    +
    675  READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
    +
    676 
    +
    677  READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
    +
    678  if (sps->frame_cropping_flag) {
    +
    679  READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
    +
    680  READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
    +
    681  READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
    +
    682  READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
    +
    683  }
    +
    684 
    +
    685  READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
    +
    686  if (sps->vui_parameters_present_flag) {
    +
    687  DVLOG(4) << "VUI parameters present";
    +
    688  res = ParseVUIParameters(br, sps.get());
    +
    689  if (res != kOk)
    +
    690  return res;
    +
    691  }
    +
    692 
    +
    693  // If an SPS with the same id already exists, replace it.
    +
    694  *sps_id = sps->seq_parameter_set_id;
    +
    695  active_SPSes_[*sps_id] = std::move(sps);
    +
    696 
    +
    697  return kOk;
    +
    698 }
    +
    699 
    +
    700 H264Parser::Result H264Parser::ParsePps(const Nalu& nalu, int* pps_id) {
    +
    701  // See 7.4.2.2.
    +
    702  const H264Sps* sps;
    +
    703  Result res;
    +
    704  H26xBitReader reader;
    +
    705  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    +
    706  H26xBitReader* br = &reader;
    +
    707 
    +
    708  *pps_id = -1;
    +
    709 
    +
    710  std::unique_ptr<H264Pps> pps(new H264Pps());
    +
    711 
    +
    712  READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
    +
    713  READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
    +
    714  TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
    +
    715 
    +
    716  sps = GetSps(pps->seq_parameter_set_id);
    +
    717  TRUE_OR_RETURN(sps);
    +
    718 
    +
    719  READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
    +
    720  READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
    +
    721 
    +
    722  READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
    +
    723  if (pps->num_slice_groups_minus1 > 1) {
    +
    724  LOG_ERROR_ONCE("Slice groups not supported");
    +
    725  return kUnsupportedStream;
    +
    726  }
    +
    727 
    +
    728  READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
    +
    729  TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
    +
    730 
    +
    731  READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
    +
    732  TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
    +
    733 
    +
    734  READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
    +
    735  READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
    +
    736  TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
    +
    737 
    +
    738  READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
    +
    739  IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
    +
    740 
    +
    741  READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
    +
    742  IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
    +
    743 
    +
    744  READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
    +
    745  IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
    +
    746  pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
    +
    747 
    +
    748  READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
    +
    749  READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
    +
    750  READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
    +
    751 
    +
    752  if (br->HasMoreRBSPData()) {
    +
    753  READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
    +
    754  READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
    +
    755 
    +
    756  if (pps->pic_scaling_matrix_present_flag) {
    +
    757  DVLOG(4) << "Picture scaling matrix present";
    +
    758  res = ParsePpsScalingLists(br, *sps, pps.get());
    +
    759  if (res != kOk)
    +
    760  return res;
    +
    761  }
    +
    762 
    +
    763  READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
    +
    764  }
    +
    765 
    +
    766  // If a PPS with the same id already exists, replace it.
    +
    767  *pps_id = pps->pic_parameter_set_id;
    +
    768  active_PPSes_[*pps_id] = std::move(pps);
    +
    769 
    +
    770  return kOk;
    +
    771 }
    +
    772 
    +
    773 H264Parser::Result H264Parser::ParseRefPicListModification(
    +
    774  H26xBitReader* br,
    +
    775  int num_ref_idx_active_minus1,
    +
    776  H264ModificationOfPicNum* ref_list_mods) {
    +
    777  H264ModificationOfPicNum* pic_num_mod;
    +
    778 
    +
    779  if (num_ref_idx_active_minus1 >= 32)
    +
    780  return kInvalidStream;
    +
    781 
    +
    782  for (int i = 0; i < 32; ++i) {
    +
    783  pic_num_mod = &ref_list_mods[i];
    +
    784  READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
    +
    785  TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
    +
    786 
    +
    787  switch (pic_num_mod->modification_of_pic_nums_idc) {
    +
    788  case 0:
    +
    789  case 1:
    +
    790  READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
    +
    791  break;
    +
    792 
    +
    793  case 2:
    +
    794  READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
    +
    795  break;
    +
    796 
    +
    797  case 3:
    +
    798  // Per spec, list cannot be empty.
    +
    799  if (i == 0)
    +
    800  return kInvalidStream;
    +
    801  return kOk;
    +
    802 
    +
    803  default:
    +
    804  return kInvalidStream;
    +
    805  }
    +
    806  }
    +
    807 
    +
    808  // If we got here, we didn't get loop end marker prematurely,
    +
    809  // so make sure it is there for our client.
    +
    810  int modification_of_pic_nums_idc;
    +
    811  READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
    +
    812  TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
    +
    813 
    +
    814  return kOk;
    +
    815 }
    +
    816 
    +
    817 H264Parser::Result H264Parser::ParseRefPicListModifications(
    +
    818  H26xBitReader* br, H264SliceHeader* shdr) {
    +
    819  Result res;
    +
    820 
    +
    821  if (!shdr->IsISlice() && !shdr->IsSISlice()) {
    +
    822  READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
    +
    823  if (shdr->ref_pic_list_modification_flag_l0) {
    +
    824  res = ParseRefPicListModification(br, shdr->num_ref_idx_l0_active_minus1,
    +
    825  shdr->ref_list_l0_modifications);
    +
    826  if (res != kOk)
    +
    827  return res;
    +
    828  }
    +
    829  }
    +
    830 
    +
    831  if (shdr->IsBSlice()) {
    +
    832  READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
    +
    833  if (shdr->ref_pic_list_modification_flag_l1) {
    +
    834  res = ParseRefPicListModification(br, shdr->num_ref_idx_l1_active_minus1,
    +
    835  shdr->ref_list_l1_modifications);
    +
    836  if (res != kOk)
    +
    837  return res;
    +
    838  }
    +
    839  }
    +
    840 
    +
    841  return kOk;
    +
    842 }
    +
    843 
    +
    844 H264Parser::Result H264Parser::ParseWeightingFactors(
    +
    845  H26xBitReader* br,
    +
    846  int num_ref_idx_active_minus1,
    +
    847  int chroma_array_type,
    +
    848  int luma_log2_weight_denom,
    +
    849  int chroma_log2_weight_denom,
    +
    850  H264WeightingFactors* w_facts) {
    +
    851  int def_luma_weight = 1 << luma_log2_weight_denom;
    +
    852  int def_chroma_weight = 1 << chroma_log2_weight_denom;
    +
    853 
    +
    854  for (int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
    +
    855  READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag[i]);
    +
    856  if (w_facts->luma_weight_flag[i]) {
    +
    857  READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
    +
    858  IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
    +
    859 
    +
    860  READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
    +
    861  IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
    +
    862  } else {
    +
    863  w_facts->luma_weight[i] = def_luma_weight;
    +
    864  w_facts->luma_offset[i] = 0;
    +
    865  }
    +
    866 
    +
    867  if (chroma_array_type != 0) {
    +
    868  READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag[i]);
    +
    869  if (w_facts->chroma_weight_flag[i]) {
    +
    870  for (int j = 0; j < 2; ++j) {
    +
    871  READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
    +
    872  IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
    +
    873 
    +
    874  READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
    +
    875  IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
    +
    876  }
    +
    877  } else {
    +
    878  for (int j = 0; j < 2; ++j) {
    +
    879  w_facts->chroma_weight[i][j] = def_chroma_weight;
    +
    880  w_facts->chroma_offset[i][j] = 0;
    +
    881  }
    +
    882  }
    +
    883  }
    +
    884  }
    +
    885 
    +
    886  return kOk;
    +
    887 }
    +
    888 
    +
    889 H264Parser::Result H264Parser::ParsePredWeightTable(H26xBitReader* br,
    +
    890  const H264Sps& sps,
    +
    891  H264SliceHeader* shdr) {
    +
    892  READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
    +
    893  TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
    +
    894 
    +
    895  if (sps.chroma_array_type != 0)
    +
    896  READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
    +
    897  TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
    +
    898 
    +
    899  Result res = ParseWeightingFactors(br,
    +
    900  shdr->num_ref_idx_l0_active_minus1,
    +
    901  sps.chroma_array_type,
    +
    902  shdr->luma_log2_weight_denom,
    +
    903  shdr->chroma_log2_weight_denom,
    +
    904  &shdr->pred_weight_table_l0);
    +
    905  if (res != kOk)
    +
    906  return res;
    +
    907 
    +
    908  if (shdr->IsBSlice()) {
    +
    909  res = ParseWeightingFactors(br,
    +
    910  shdr->num_ref_idx_l1_active_minus1,
    +
    911  sps.chroma_array_type,
    +
    912  shdr->luma_log2_weight_denom,
    +
    913  shdr->chroma_log2_weight_denom,
    +
    914  &shdr->pred_weight_table_l1);
    +
    915  if (res != kOk)
    +
    916  return res;
    +
    917  }
    +
    918 
    +
    919  return kOk;
    +
    920 }
    +
    921 
    +
    922 H264Parser::Result H264Parser::ParseDecRefPicMarking(H26xBitReader* br,
    +
    923  H264SliceHeader* shdr) {
    +
    924  if (shdr->idr_pic_flag) {
    +
    925  READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
    +
    926  READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
    +
    927  } else {
    +
    928  READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
    +
    929 
    +
    930  H264DecRefPicMarking* marking;
    +
    931  if (shdr->adaptive_ref_pic_marking_mode_flag) {
    +
    932  size_t i;
    +
    933  for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) {
    +
    934  marking = &shdr->ref_pic_marking[i];
    +
    935 
    +
    936  READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
    +
    937  if (marking->memory_mgmnt_control_operation == 0)
    +
    938  break;
    +
    939 
    +
    940  if (marking->memory_mgmnt_control_operation == 1 ||
    +
    941  marking->memory_mgmnt_control_operation == 3)
    +
    942  READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
    +
    943 
    +
    944  if (marking->memory_mgmnt_control_operation == 2)
    +
    945  READ_UE_OR_RETURN(&marking->long_term_pic_num);
    +
    946 
    +
    947  if (marking->memory_mgmnt_control_operation == 3 ||
    +
    948  marking->memory_mgmnt_control_operation == 6)
    +
    949  READ_UE_OR_RETURN(&marking->long_term_frame_idx);
    +
    950 
    +
    951  if (marking->memory_mgmnt_control_operation == 4)
    +
    952  READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
    +
    953 
    +
    954  if (marking->memory_mgmnt_control_operation > 6)
    +
    955  return kInvalidStream;
    +
    956  }
    +
    957 
    +
    958  if (i == arraysize(shdr->ref_pic_marking)) {
    +
    959  LOG_ERROR_ONCE("Ran out of dec ref pic marking fields");
    +
    960  return kUnsupportedStream;
    +
    961  }
    +
    962  }
    +
    963  }
    +
    964 
    +
    965  return kOk;
    +
    966 }
    +
    967 
    +
    968 H264Parser::Result H264Parser::ParseSliceHeader(const Nalu& nalu,
    +
    969  H264SliceHeader* shdr) {
    +
    970  // See 7.4.3.
    +
    971  const H264Sps* sps;
    +
    972  const H264Pps* pps;
    +
    973  Result res;
    +
    974  H26xBitReader reader;
    +
    975  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    +
    976  H26xBitReader* br = &reader;
    +
    977 
    +
    978  *shdr = {};
    +
    979 
    +
    980  shdr->idr_pic_flag = (nalu.type() == 5);
    +
    981  shdr->nal_ref_idc = nalu.ref_idc();
    +
    982  shdr->nalu_data = nalu.data();
    +
    983  shdr->nalu_size = nalu.header_size() + nalu.payload_size();
    +
    984 
    +
    985  READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
    +
    986  READ_UE_OR_RETURN(&shdr->slice_type);
    +
    987  TRUE_OR_RETURN(shdr->slice_type < 10);
    +
    988 
    +
    989  READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
    +
    990 
    +
    991  pps = GetPps(shdr->pic_parameter_set_id);
    +
    992  TRUE_OR_RETURN(pps);
    +
    993 
    +
    994  sps = GetSps(pps->seq_parameter_set_id);
    +
    995  TRUE_OR_RETURN(sps);
    +
    996 
    +
    997  if (sps->separate_colour_plane_flag) {
    +
    998  LOG_ERROR_ONCE("Interlaced streams not supported");
    +
    999  return kUnsupportedStream;
    +
    1000  }
    +
    1001 
    +
    1002  READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
    +
    1003  if (!sps->frame_mbs_only_flag) {
    +
    1004  READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
    +
    1005  if (shdr->field_pic_flag) {
    +
    1006  LOG_ERROR_ONCE("Interlaced streams not supported");
    +
    1007  return kUnsupportedStream;
    +
    1008  }
    +
    1009  }
    +
    1010 
    +
    1011  if (shdr->idr_pic_flag)
    +
    1012  READ_UE_OR_RETURN(&shdr->idr_pic_id);
    +
    1013 
    +
    1014  if (sps->pic_order_cnt_type == 0) {
    +
    1015  READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
    +
    1016  &shdr->pic_order_cnt_lsb);
    +
    1017  if (pps->bottom_field_pic_order_in_frame_present_flag &&
    +
    1018  !shdr->field_pic_flag)
    +
    1019  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
    +
    1020  }
    +
    1021 
    +
    1022  if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
    +
    1023  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[0]);
    +
    1024  if (pps->bottom_field_pic_order_in_frame_present_flag &&
    +
    1025  !shdr->field_pic_flag)
    +
    1026  READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[1]);
    +
    1027  }
    +
    1028 
    +
    1029  if (pps->redundant_pic_cnt_present_flag) {
    +
    1030  READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
    +
    1031  TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
    +
    1032  }
    +
    1033 
    +
    1034  if (shdr->IsBSlice())
    +
    1035  READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
    +
    1036 
    +
    1037  if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
    +
    1038  READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
    +
    1039  if (shdr->num_ref_idx_active_override_flag) {
    +
    1040  READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
    +
    1041  if (shdr->IsBSlice())
    +
    1042  READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
    +
    1043  } else {
    +
    1044  shdr->num_ref_idx_l0_active_minus1 =
    +
    1045  pps->num_ref_idx_l0_default_active_minus1;
    +
    1046  if (shdr->IsBSlice()) {
    +
    1047  shdr->num_ref_idx_l1_active_minus1 =
    +
    1048  pps->num_ref_idx_l1_default_active_minus1;
    +
    1049  }
    +
    1050  }
    +
    1051  }
    +
    1052  if (shdr->field_pic_flag) {
    +
    1053  TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
    +
    1054  TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
    +
    1055  } else {
    +
    1056  TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
    +
    1057  TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
    +
    1058  }
    +
    1059 
    +
    1060  if (nalu.type() == Nalu::H264_CodedSliceExtension) {
    +
    1061  return kUnsupportedStream;
    +
    1062  } else {
    +
    1063  res = ParseRefPicListModifications(br, shdr);
    +
    1064  if (res != kOk)
    +
    1065  return res;
    +
    1066  }
    +
    1067 
    +
    1068  if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
    +
    1069  (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
    +
    1070  res = ParsePredWeightTable(br, *sps, shdr);
    +
    1071  if (res != kOk)
    +
    1072  return res;
    +
    1073  }
    +
    1074 
    +
    1075  if (nalu.ref_idc() != 0) {
    +
    1076  res = ParseDecRefPicMarking(br, shdr);
    +
    1077  if (res != kOk)
    +
    1078  return res;
    +
    1079  }
    +
    1080 
    +
    1081  if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
    +
    1082  !shdr->IsSISlice()) {
    +
    1083  READ_UE_OR_RETURN(&shdr->cabac_init_idc);
    +
    1084  TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
    +
    1085  }
    +
    1086 
    +
    1087  READ_SE_OR_RETURN(&shdr->slice_qp_delta);
    +
    1088 
    +
    1089  if (shdr->IsSPSlice() || shdr->IsSISlice()) {
    +
    1090  if (shdr->IsSPSlice())
    +
    1091  READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
    +
    1092  READ_SE_OR_RETURN(&shdr->slice_qs_delta);
    +
    1093  }
    +
    1094 
    +
    1095  if (pps->deblocking_filter_control_present_flag) {
    +
    1096  READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
    +
    1097  TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
    +
    1098 
    +
    1099  if (shdr->disable_deblocking_filter_idc != 1) {
    +
    1100  READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
    +
    1101  IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
    +
    1102 
    +
    1103  READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
    +
    1104  IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
    +
    1105  }
    +
    1106  }
    +
    1107 
    +
    1108  if (pps->num_slice_groups_minus1 > 0) {
    +
    1109  LOG_ERROR_ONCE("Slice groups not supported");
    +
    1110  return kUnsupportedStream;
    +
    1111  }
    +
    1112 
    +
    1113  shdr->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
    +
    1114  return kOk;
    +
    1115 }
    +
    1116 
    +
    1117 H264Parser::Result H264Parser::ParseSEI(const Nalu& nalu,
    +
    1118  H264SEIMessage* sei_msg) {
    +
    1119  int byte;
    +
    1120  H26xBitReader reader;
    +
    1121  reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
    +
    1122  H26xBitReader* br = &reader;
    +
    1123 
    +
    1124  *sei_msg = {};
    +
    1125 
    +
    1126  READ_BITS_OR_RETURN(8, &byte);
    +
    1127  while (byte == 0xff) {
    +
    1128  sei_msg->type += 255;
    +
    1129  READ_BITS_OR_RETURN(8, &byte);
    +
    1130  }
    +
    1131  sei_msg->type += byte;
    +
    1132 
    +
    1133  READ_BITS_OR_RETURN(8, &byte);
    +
    1134  while (byte == 0xff) {
    +
    1135  sei_msg->payload_size += 255;
    +
    1136  READ_BITS_OR_RETURN(8, &byte);
    +
    1137  }
    +
    1138  sei_msg->payload_size += byte;
    +
    1139 
    +
    1140  DVLOG(4) << "Found SEI message type: " << sei_msg->type
    +
    1141  << " payload size: " << sei_msg->payload_size;
    +
    1142 
    +
    1143  switch (sei_msg->type) {
    +
    1144  case H264SEIMessage::kSEIRecoveryPoint:
    +
    1145  READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
    +
    1146  READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
    +
    1147  READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
    +
    1148  READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
    +
    1149  break;
    +
    1150 
    +
    1151  default:
    +
    1152  DVLOG(4) << "Unsupported SEI message";
    +
    1153  break;
    +
    1154  }
    +
    1155 
    +
    1156  return kOk;
    +
    1157 }
    +
    1158 
    +
    1159 } // namespace media
    +
    1160 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/d86/structshaka_1_1media_1_1mp4_1_1ElementaryStreamDescriptor-members.html b/docs/dc/d86/structshaka_1_1media_1_1mp4_1_1ElementaryStreamDescriptor-members.html index 8a65bb4c74..72ff638cec 100644 --- a/docs/dc/d86/structshaka_1_1media_1_1mp4_1_1ElementaryStreamDescriptor-members.html +++ b/docs/dc/d86/structshaka_1_1media_1_1mp4_1_1ElementaryStreamDescriptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dc/d8a/classshaka_1_1media_1_1mp2t_1_1EsParserAudio.html b/docs/dc/d8a/classshaka_1_1media_1_1mp2t_1_1EsParserAudio.html index 1a9dd9fe10..d717afa61f 100644 --- a/docs/dc/d8a/classshaka_1_1media_1_1mp2t_1_1EsParserAudio.html +++ b/docs/dc/d8a/classshaka_1_1media_1_1mp2t_1_1EsParserAudio.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::EsParserAudio Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp2t::EsParser - -
    + + @@ -87,9 +90,9 @@ Public Member Functions - - + + @@ -104,12 +107,15 @@ uint32_t  - - - - + + + + + +

    Public Member Functions

    bool Parse (const uint8_t *buf, int size, int64_t pts, int64_t dts) override
     
    -void Flush () override
     
    +bool Flush () override
     
    void Reset () override
     
    pid ()

    Additional Inherited Members

    - Public Types inherited from shaka::media::mp2t::EsParser
    -typedef base::Callback< void(const std::shared_ptr< StreamInfo > &)> NewStreamInfoCB
     
    -typedef base::Callback< void(uint32_t, const std::shared_ptr< MediaSample > &)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< StreamInfo >)> NewStreamInfoCB
     
    +typedef base::Callback< void(std::shared_ptr< MediaSample >)> EmitSampleCB
     
    +typedef base::Callback< void(std::shared_ptr< TextSample >)> EmitTextSampleCB
     

    Detailed Description

    @@ -121,9 +127,7 @@ typedef base::Callback< void(uint32_t, const std::shared_ptr< diff --git a/docs/dc/d8f/structshaka_1_1media_1_1mp4_1_1MovieFragmentHeader.html b/docs/dc/d8f/structshaka_1_1media_1_1mp4_1_1MovieFragmentHeader.html index 8c90b77e61..5acf4876bb 100644 --- a/docs/dc/d8f/structshaka_1_1media_1_1mp4_1_1MovieFragmentHeader.html +++ b/docs/dc/d8f/structshaka_1_1media_1_1mp4_1_1MovieFragmentHeader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::MovieFragmentHeader Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 683 of file box_definitions.h.

    +

    Definition at line 701 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2372 of file box_definitions.cc.

    +

    Definition at line 2461 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/dc/d9a/structshaka_1_1media_1_1Range-members.html b/docs/dc/d9a/structshaka_1_1media_1_1Range-members.html index 005e3e6bbd..3c4884ad68 100644 --- a/docs/dc/d9a/structshaka_1_1media_1_1Range-members.html +++ b/docs/dc/d9a/structshaka_1_1media_1_1Range-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/da0/structshaka_1_1EncryptionParams.html b/docs/dc/da0/structshaka_1_1EncryptionParams.html index d710cd81ee..2523f9d0f8 100644 --- a/docs/dc/da0/structshaka_1_1EncryptionParams.html +++ b/docs/dc/da0/structshaka_1_1EncryptionParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::EncryptionParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    @@ -84,20 +86,6 @@ Classes  Encrypted stream information that is used to determine stream label. More...
      - - - - -

    -Public Types

    enum  ProtectionSystem {
    -  kCommonSystem, -kFairPlay, -kMarlin, -kPlayReady, -
    -  kWidevine -
    - }
     Supported protection systems.
     
    @@ -111,10 +99,14 @@ Public Attributes - - - + + + + + + @@ -122,6 +114,10 @@ double  + + + + @@ -153,8 +149,25 @@ static constexpr uint32_t 

    Public Attributes

    KeyProvider key_provider = KeyProvider::kNone
    RawKeyParams raw_key
     
    -std::vector< ProtectionSystemprotection_systems
     Protection systems to be generated.
     
    +ProtectionSystem protection_systems
     The protection systems to generate, multiple can be OR'd together.
     
    +std::string playready_extra_header_data
     Extra XML data to add to PlayReady data.
     
    double clear_lead_in_seconds = 0
     Clear lead duration in seconds.
    uint32_t protection_scheme = kProtectionSchemeCenc
     
    uint8_t crypt_byte_block = 1
     
    uint8_t skip_byte_block = 9
     
    double crypto_period_duration_in_seconds = kNoKeyRotation
     

    Detailed Description

    Encryption parameters.

    -

    Definition at line 108 of file crypto_params.h.

    +

    Definition at line 146 of file crypto_params.h.

    Member Data Documentation

    + +

    ◆ crypt_byte_block

    + +
    +
    + + + + +
    uint8_t shaka::EncryptionParams::crypt_byte_block = 1
    +
    +

    The count of the encrypted blocks in the protection pattern, where each block is of size 16-bytes. There are three common patterns (crypt_byte_block:skip_byte_block): 1:9 (default), 5:5, 10:0. Applies to video streams with "cbcs" and "cens" protection schemes only; Ignored otherwise.

    + +

    Definition at line 174 of file crypto_params.h.

    + +
    +

    ◆ key_provider

    @@ -168,7 +181,7 @@ static constexpr uint32_t 

    Specifies the key provider, which determines which key provider is used and which encryption params is valid. 'kNone' means not to encrypt the streams.

    -

    Definition at line 112 of file crypto_params.h.

    +

    Definition at line 150 of file crypto_params.h.

    @@ -187,13 +200,30 @@ static constexpr uint32_t 
    -static +staticconstexpr

    Crypto period duration in seconds. A positive value means key rotation is enabled, the key provider must support key rotation in this case.

    -

    Definition at line 139 of file crypto_params.h.

    +

    Definition at line 181 of file crypto_params.h.

    + +
    + + +

    ◆ skip_byte_block

    + +
    +
    + + + + +
    uint8_t shaka::EncryptionParams::skip_byte_block = 9
    +
    +

    The count of the unencrypted blocks in the protection pattern. Applies to video streams with "cbcs" and "cens" protection schemes only; Ignored otherwise.

    + +

    Definition at line 178 of file crypto_params.h.

    @@ -210,7 +240,7 @@ static constexpr uint32_t 

    Stream label function assigns a stream label to the stream to be encrypted. Stream label is used to associate KeyPair with streams. Streams with the same stream label always uses the same keyPair; Streams with different stream label could use the same or different KeyPairs. A default stream label function will be generated if not set.

    -

    Definition at line 174 of file crypto_params.h.

    +

    Definition at line 216 of file crypto_params.h.

    @@ -220,9 +250,7 @@ static constexpr uint32_t  diff --git a/docs/dc/da0/structshaka_1_1media_1_1mp4_1_1DTSSpecific.html b/docs/dc/da0/structshaka_1_1media_1_1mp4_1_1DTSSpecific.html index e446f33621..2f584a5c6e 100644 --- a/docs/dc/da0/structshaka_1_1media_1_1mp4_1_1DTSSpecific.html +++ b/docs/dc/da0/structshaka_1_1media_1_1mp4_1_1DTSSpecific.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::DTSSpecific Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -124,7 +127,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 314 of file box_definitions.h.

    +

    Definition at line 315 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -152,7 +155,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1690 of file box_definitions.cc.

    +

    Definition at line 1716 of file box_definitions.cc.

    @@ -163,9 +166,7 @@ Additional Inherited Members diff --git a/docs/dc/da1/classshaka_1_1MpdBuilder.html b/docs/dc/da1/classshaka_1_1MpdBuilder.html index 7ee5980d78..86b317d177 100644 --- a/docs/dc/da1/classshaka_1_1MpdBuilder.html +++ b/docs/dc/da1/classshaka_1_1MpdBuilder.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MpdBuilder Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::MockMpdBuilder - -
    + + @@ -94,8 +97,8 @@ Public Member Functions - - + + @@ -119,7 +122,7 @@ template<DashProfile profile>

    Detailed Description

    This class generates DASH MPDs (Media Presentation Descriptions).

    -

    Definition at line 37 of file mpd_builder.h.

    +

    Definition at line 36 of file mpd_builder.h.

    Constructor & Destructor Documentation

    ◆ MpdBuilder()

    @@ -144,14 +147,14 @@ template<DashProfile profile>

    Public Member Functions

     
    virtual PeriodGetOrCreatePeriod (double start_time_in_seconds)
     
    virtual bool ToString (std::string *output)
     
    virtual bool ToString (std::string *output) WARN_UNUSED_RESULT
     
    void InjectClockForTesting (std::unique_ptr< base::Clock > clock)
     This is for testing.
    -

    Constructs MpdBuilder.

    Parameters
    +

    Constructs MpdBuilder.

    Parameters
    mpd_optionscontains options on how this MPD should be built.
    -

    Definition at line 134 of file mpd_builder.cc.

    +

    Definition at line 136 of file mpd_builder.cc.

    @@ -178,7 +181,7 @@ template<DashProfile profile> -

    Definition at line 139 of file mpd_builder.cc.

    +

    Definition at line 141 of file mpd_builder.cc.

    @@ -213,7 +216,7 @@ template<DashProfile profile>
    Returns
    the Period matching start_time_in_seconds if found; otherwise return a new Period.
    -

    Definition at line 143 of file mpd_builder.cc.

    +

    Definition at line 145 of file mpd_builder.cc.

    @@ -258,12 +261,12 @@ template<DashProfile profile> -

    Definition at line 420 of file mpd_builder.cc.

    +

    Definition at line 415 of file mpd_builder.cc.

    - -

    ◆ ToString()

    + +

    ◆ ToString()

    @@ -293,7 +296,7 @@ template<DashProfile profile>
    Returns
    true on success, false otherwise.
    -

    Definition at line 157 of file mpd_builder.cc.

    +

    Definition at line 159 of file mpd_builder.cc.

    @@ -304,9 +307,7 @@ template<DashProfile profile> diff --git a/docs/dc/da3/buffer__callback__params_8h_source.html b/docs/dc/da3/buffer__callback__params_8h_source.html index 7792171a46..bf062789d2 100644 --- a/docs/dc/da3/buffer__callback__params_8h_source.html +++ b/docs/dc/da3/buffer__callback__params_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/public/buffer_callback_params.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    buffer_callback_params.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_FILE_PUBLIC_BUFFER_CALLBACK_PARAMS_H_
    8 #define PACKAGER_FILE_PUBLIC_BUFFER_CALLBACK_PARAMS_H_
    9 
    10 #include <functional>
    11 
    12 namespace shaka {
    13 
    19  std::function<int64_t(const std::string& name, void* buffer, uint64_t size)>
    28  std::function<
    29  int64_t(const std::string& name, const void* buffer, uint64_t size)>
    31 };
    32 
    33 } // namespace shaka
    34 
    35 #endif // PACKAGER_FILE_PUBLIC_BUFFER_CALLBACK_PARAMS_H_
    std::function< int64_t(const std::string &name, void *buffer, uint64_t size)> read_func
    -
    All the methods that are virtual are virtual for mocking.
    -
    std::function< int64_t(const std::string &name, const void *buffer, uint64_t size)> write_func
    -
    Buffer callback params.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_FILE_PUBLIC_BUFFER_CALLBACK_PARAMS_H_
    +
    8 #define PACKAGER_FILE_PUBLIC_BUFFER_CALLBACK_PARAMS_H_
    +
    9 
    +
    10 #include <functional>
    +
    11 
    +
    12 namespace shaka {
    +
    13 
    + +
    19  std::function<int64_t(const std::string& name, void* buffer, uint64_t size)>
    + +
    28  std::function<
    +
    29  int64_t(const std::string& name, const void* buffer, uint64_t size)>
    + +
    31 };
    +
    32 
    +
    33 } // namespace shaka
    +
    34 
    +
    35 #endif // PACKAGER_FILE_PUBLIC_BUFFER_CALLBACK_PARAMS_H_
    +
    All the methods that are virtual are virtual for mocking.
    + +
    std::function< int64_t(const std::string &name, void *buffer, uint64_t size)> read_func
    +
    std::function< int64_t(const std::string &name, const void *buffer, uint64_t size)> write_func
    diff --git a/docs/dc/da3/es__parser__audio_8h_source.html b/docs/dc/da3/es__parser__audio_8h_source.html index deb399853d..6f5ab32061 100644 --- a/docs/dc/da3/es__parser__audio_8h_source.html +++ b/docs/dc/da3/es__parser__audio_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser_audio.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    es_parser_audio.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_AUDIO_H_
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_AUDIO_H_
    7 
    8 #include <list>
    9 #include <memory>
    10 #include <utility>
    11 
    12 #include "packager/base/callback.h"
    13 #include "packager/base/compiler_specific.h"
    14 #include "packager/media/base/audio_stream_info.h"
    15 #include "packager/media/base/byte_queue.h"
    16 #include "packager/media/formats/mp2t/es_parser.h"
    17 #include "packager/media/formats/mp2t/ts_stream_type.h"
    18 
    19 namespace shaka {
    20 namespace media {
    21 class AudioTimestampHelper;
    22 class BitReader;
    23 
    24 namespace mp2t {
    25 
    26 class AudioHeader;
    27 
    28 class EsParserAudio : public EsParser {
    29  public:
    30  EsParserAudio(uint32_t pid,
    31  TsStreamType stream_type,
    32  const NewStreamInfoCB& new_stream_info_cb,
    33  const EmitSampleCB& emit_sample_cb,
    34  bool sbr_in_mimetype);
    35  ~EsParserAudio() override;
    36 
    37  // EsParser implementation.
    38  bool Parse(const uint8_t* buf, int size, int64_t pts, int64_t dts) override;
    39  void Flush() override;
    40  void Reset() override;
    41 
    42  private:
    43  EsParserAudio(const EsParserAudio&) = delete;
    44  EsParserAudio& operator=(const EsParserAudio&) = delete;
    45 
    46  // Used to link a PTS with a byte position in the ES stream.
    47  typedef std::pair<int, int64_t> EsPts;
    48  typedef std::list<EsPts> EsPtsList;
    49 
    50  // Signal any audio configuration change (if any).
    51  // Return false if the current audio config is not a supported audio config.
    52  bool UpdateAudioConfiguration(const AudioHeader& audio_header);
    53 
    54  // Discard some bytes from the ES stream.
    55  void DiscardEs(int nbytes);
    56 
    57  const TsStreamType stream_type_;
    58  std::unique_ptr<AudioHeader> audio_header_;
    59 
    60  // Callbacks:
    61  // - to signal a new audio configuration,
    62  // - to send ES buffers.
    63  NewStreamInfoCB new_stream_info_cb_;
    64  EmitSampleCB emit_sample_cb_;
    65 
    66  // True when AAC SBR extension is signalled in the mimetype
    67  // (mp4a.40.5 in the codecs parameter).
    68  bool sbr_in_mimetype_;
    69 
    70  // Bytes of the ES stream that have not been emitted yet.
    71  ByteQueue es_byte_queue_;
    72 
    73  // List of PTS associated with a position in the ES stream.
    74  EsPtsList pts_list_;
    75 
    76  // Interpolated PTS for frames that don't have one.
    77  std::unique_ptr<AudioTimestampHelper> audio_timestamp_helper_;
    78 
    79  std::shared_ptr<StreamInfo> last_audio_decoder_config_;
    80 };
    81 
    82 } // namespace mp2t
    83 } // namespace media
    84 } // namespace shaka
    85 
    86 #endif // PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_AUDIO_H_
    All the methods that are virtual are virtual for mocking.
    - - - - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_AUDIO_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_AUDIO_H_
    +
    7 
    +
    8 #include <list>
    +
    9 #include <memory>
    +
    10 #include <utility>
    +
    11 
    +
    12 #include "packager/base/callback.h"
    +
    13 #include "packager/base/compiler_specific.h"
    +
    14 #include "packager/media/base/audio_stream_info.h"
    +
    15 #include "packager/media/base/byte_queue.h"
    +
    16 #include "packager/media/formats/mp2t/es_parser.h"
    +
    17 #include "packager/media/formats/mp2t/ts_stream_type.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 class AudioTimestampHelper;
    +
    22 class BitReader;
    +
    23 
    +
    24 namespace mp2t {
    +
    25 
    +
    26 class AudioHeader;
    +
    27 
    +
    28 class EsParserAudio : public EsParser {
    +
    29  public:
    +
    30  EsParserAudio(uint32_t pid,
    +
    31  TsStreamType stream_type,
    +
    32  const NewStreamInfoCB& new_stream_info_cb,
    +
    33  const EmitSampleCB& emit_sample_cb,
    +
    34  bool sbr_in_mimetype);
    +
    35  ~EsParserAudio() override;
    +
    36 
    +
    37  // EsParser implementation.
    +
    38  bool Parse(const uint8_t* buf, int size, int64_t pts, int64_t dts) override;
    +
    39  bool Flush() override;
    +
    40  void Reset() override;
    +
    41 
    +
    42  private:
    +
    43  EsParserAudio(const EsParserAudio&) = delete;
    +
    44  EsParserAudio& operator=(const EsParserAudio&) = delete;
    +
    45 
    +
    46  // Used to link a PTS with a byte position in the ES stream.
    +
    47  typedef std::pair<int, int64_t> EsPts;
    +
    48  typedef std::list<EsPts> EsPtsList;
    +
    49 
    +
    50  // Signal any audio configuration change (if any).
    +
    51  // Return false if the current audio config is not a supported audio config.
    +
    52  bool UpdateAudioConfiguration(const AudioHeader& audio_header);
    +
    53 
    +
    54  // Discard some bytes from the ES stream.
    +
    55  void DiscardEs(int nbytes);
    +
    56 
    +
    57  const TsStreamType stream_type_;
    +
    58  std::unique_ptr<AudioHeader> audio_header_;
    +
    59 
    +
    60  // Callbacks:
    +
    61  // - to signal a new audio configuration,
    +
    62  // - to send ES buffers.
    +
    63  NewStreamInfoCB new_stream_info_cb_;
    +
    64  EmitSampleCB emit_sample_cb_;
    +
    65 
    +
    66  // True when AAC SBR extension is signalled in the mimetype
    +
    67  // (mp4a.40.5 in the codecs parameter).
    +
    68  bool sbr_in_mimetype_;
    +
    69 
    +
    70  // Bytes of the ES stream that have not been emitted yet.
    +
    71  ByteQueue es_byte_queue_;
    +
    72 
    +
    73  // List of PTS associated with a position in the ES stream.
    +
    74  EsPtsList pts_list_;
    +
    75 
    +
    76  // Interpolated PTS for frames that don't have one.
    +
    77  std::unique_ptr<AudioTimestampHelper> audio_timestamp_helper_;
    +
    78 
    +
    79  std::shared_ptr<StreamInfo> last_audio_decoder_config_;
    +
    80 };
    +
    81 
    +
    82 } // namespace mp2t
    +
    83 } // namespace media
    +
    84 } // namespace shaka
    +
    85 
    +
    86 #endif // PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_AUDIO_H_
    + + + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/da4/muxer__listener__factory_8h_source.html b/docs/dc/da4/muxer__listener__factory_8h_source.html index cb444da7e3..0528170668 100644 --- a/docs/dc/da4/muxer__listener__factory_8h_source.html +++ b/docs/dc/da4/muxer__listener__factory_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/muxer_listener_factory.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    muxer_listener_factory.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_EVENT_MUXER_LISTENER_FACTORY_H_
    8 #define PACKAGER_MEDIA_EVENT_MUXER_LISTENER_FACTORY_H_
    9 
    10 #include <memory>
    11 #include <string>
    12 #include <vector>
    13 
    14 namespace shaka {
    15 class MpdNotifier;
    16 
    17 namespace hls {
    18 class HlsNotifier;
    19 }
    20 
    21 namespace media {
    22 class MuxerListener;
    23 
    34  public:
    37  struct StreamData {
    38  // The stream's output destination. Will only be used if the factory is
    39  // told to output media info.
    40  std::string media_info_output;
    41 
    42  // HLS specific values needed to write to HLS manifests. Will only be used
    43  // if an HlsNotifier is given to the factory.
    44  std::string hls_group_id;
    45  std::string hls_name;
    46  std::string hls_playlist_name;
    47  std::string hls_iframe_playlist_name;
    48  std::vector<std::string> hls_characteristics;
    49 
    50  // DASH specific values needed to write DASH mpd. Will only be used if an
    51  // MpdNotifier is given to the factory.
    52  std::vector<std::string> dash_accessiblities;
    53  std::vector<std::string> dash_roles;
    54  };
    55 
    63  MuxerListenerFactory(bool output_media_info,
    64  MpdNotifier* mpd_notifier,
    65  hls::HlsNotifier* hls_notifier);
    66 
    68  std::unique_ptr<MuxerListener> CreateListener(const StreamData& stream);
    69 
    72  std::unique_ptr<MuxerListener> CreateHlsListener(const StreamData& stream);
    73 
    74  private:
    76  MuxerListenerFactory operator=(const MuxerListenerFactory&) = delete;
    77 
    78  bool output_media_info_;
    79  MpdNotifier* mpd_notifier_;
    80  hls::HlsNotifier* hls_notifier_;
    81 
    82  // A counter to track which stream we are on.
    83  int stream_index_ = 0;
    84 };
    85 } // namespace media
    86 } // namespace shaka
    87 
    88 #endif // PACKAGER_MEDIA_EVENT_MUXER_LISTENER_FACTORY_H_
    All the methods that are virtual are virtual for mocking.
    - - - - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_EVENT_MUXER_LISTENER_FACTORY_H_
    +
    8 #define PACKAGER_MEDIA_EVENT_MUXER_LISTENER_FACTORY_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <string>
    +
    12 #include <vector>
    +
    13 
    +
    14 namespace shaka {
    +
    15 class MpdNotifier;
    +
    16 
    +
    17 namespace hls {
    +
    18 class HlsNotifier;
    +
    19 }
    +
    20 
    +
    21 namespace media {
    +
    22 class MuxerListener;
    +
    23 
    + +
    34  public:
    +
    37  struct StreamData {
    +
    38  // The stream's output destination. Will only be used if the factory is
    +
    39  // told to output media info.
    +
    40  std::string media_info_output;
    +
    41 
    +
    42  // HLS specific values needed to write to HLS manifests. Will only be used
    +
    43  // if an HlsNotifier is given to the factory.
    +
    44  std::string hls_group_id;
    +
    45  std::string hls_name;
    +
    46  std::string hls_playlist_name;
    +
    47  std::string hls_iframe_playlist_name;
    +
    48  std::vector<std::string> hls_characteristics;
    +
    49  bool hls_only = false;
    +
    50 
    +
    51  // DASH specific values needed to write DASH mpd. Will only be used if an
    +
    52  // MpdNotifier is given to the factory.
    +
    53  std::vector<std::string> dash_accessiblities;
    +
    54  std::vector<std::string> dash_roles;
    +
    55  bool dash_only = false;
    +
    56  };
    +
    57 
    +
    65  MuxerListenerFactory(bool output_media_info,
    +
    66  MpdNotifier* mpd_notifier,
    +
    67  hls::HlsNotifier* hls_notifier);
    +
    68 
    +
    70  std::unique_ptr<MuxerListener> CreateListener(const StreamData& stream);
    +
    71 
    +
    74  std::unique_ptr<MuxerListener> CreateHlsListener(const StreamData& stream);
    +
    75 
    +
    76  private:
    + +
    78  MuxerListenerFactory operator=(const MuxerListenerFactory&) = delete;
    +
    79 
    +
    80  bool output_media_info_;
    +
    81  MpdNotifier* mpd_notifier_;
    +
    82  hls::HlsNotifier* hls_notifier_;
    +
    83 
    +
    84  // A counter to track which stream we are on.
    +
    85  int stream_index_ = 0;
    +
    86 };
    +
    87 } // namespace media
    +
    88 } // namespace shaka
    +
    89 
    +
    90 #endif // PACKAGER_MEDIA_EVENT_MUXER_LISTENER_FACTORY_H_
    + + + +
    std::unique_ptr< MuxerListener > CreateHlsListener(const StreamData &stream)
    +
    std::unique_ptr< MuxerListener > CreateListener(const StreamData &stream)
    Create a listener for a stream.
    +
    MuxerListenerFactory(bool output_media_info, MpdNotifier *mpd_notifier, hls::HlsNotifier *hls_notifier)
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/dc/da6/classshaka_1_1media_1_1ContentEncoding.html b/docs/dc/da6/classshaka_1_1media_1_1ContentEncoding.html index 0da4cee0e4..c36ab95f3e 100644 --- a/docs/dc/da6/classshaka_1_1media_1_1ContentEncoding.html +++ b/docs/dc/da6/classshaka_1_1media_1_1ContentEncoding.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ContentEncoding Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Public Types

    enum  Scope {
    -  kScopeInvalid = 0, -kScopeAllFrameContents = 1, -kScopeTrackPrivateData = 2, -kScopeNextContentEncodingData = 4, -
    +  kScopeInvalid = 0 +, kScopeAllFrameContents = 1 +, kScopeTrackPrivateData = 2 +, kScopeNextContentEncodingData = 4 +,
      kScopeMax = 7
    }   -enum  Type { kTypeInvalid = -1, -kTypeCompression = 0, -kTypeEncryption = 1 +enum  Type { kTypeInvalid = -1 +, kTypeCompression = 0 +, kTypeEncryption = 1 }   enum  EncryptionAlgo {
    -  kEncAlgoInvalid = -1, -kEncAlgoNotEncrypted = 0, -kEncAlgoDes = 1, -kEncAlgo3des = 2, -
    -  kEncAlgoTwofish = 3, -kEncAlgoBlowfish = 4, -kEncAlgoAes = 5 +  kEncAlgoInvalid = -1 +, kEncAlgoNotEncrypted = 0 +, kEncAlgoDes = 1 +, kEncAlgo3des = 2 +,
    +  kEncAlgoTwofish = 3 +, kEncAlgoBlowfish = 4 +, kEncAlgoAes = 5
    }   -enum  CipherMode { kCipherModeInvalid = 0, -kCipherModeCtr = 1 +enum  CipherMode { kCipherModeInvalid = 0 +, kCipherModeCtr = 1 }   @@ -186,9 +189,7 @@ Static Public Attributes diff --git a/docs/dc/dbf/box__buffer_8h_source.html b/docs/dc/dbf/box__buffer_8h_source.html index 850fa33ae5..50472fbf15 100644 --- a/docs/dc/dbf/box__buffer_8h_source.html +++ b/docs/dc/dbf/box__buffer_8h_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/formats/mp4/box_buffer.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    box_buffer.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_BUFFER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_BUFFER_H_
    9 
    10 #include <string>
    11 
    12 #include "packager/base/compiler_specific.h"
    13 #include "packager/media/base/buffer_writer.h"
    14 #include "packager/media/formats/mp4/box.h"
    15 #include "packager/media/formats/mp4/box_reader.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 namespace mp4 {
    20 
    25 class BoxBuffer {
    26  public:
    29  explicit BoxBuffer(BoxReader* reader) : reader_(reader), writer_(NULL) {
    30  DCHECK(reader);
    31  }
    34  explicit BoxBuffer(BufferWriter* writer) : reader_(NULL), writer_(writer) {
    35  DCHECK(writer);
    36  }
    37  ~BoxBuffer() {}
    38 
    40  bool Reading() const { return reader_ != NULL; }
    41 
    44  size_t Pos() const {
    45  if (reader_)
    46  return reader_->pos();
    47  return writer_->Size();
    48  }
    49 
    54  size_t Size() const {
    55  if (reader_)
    56  return reader_->size();
    57  return writer_->Size();
    58  }
    59 
    62  size_t BytesLeft() const {
    63  if (reader_)
    64  return reader_->size() - reader_->pos();
    65  return 0;
    66  }
    67 
    70  bool ReadWriteUInt8(uint8_t* v) {
    71  if (reader_)
    72  return reader_->Read1(v);
    73  writer_->AppendInt(*v);
    74  return true;
    75  }
    76  bool ReadWriteUInt16(uint16_t* v) {
    77  if (reader_)
    78  return reader_->Read2(v);
    79  writer_->AppendInt(*v);
    80  return true;
    81  }
    82  bool ReadWriteUInt32(uint32_t* v) {
    83  if (reader_)
    84  return reader_->Read4(v);
    85  writer_->AppendInt(*v);
    86  return true;
    87  }
    88  bool ReadWriteUInt64(uint64_t* v) {
    89  if (reader_)
    90  return reader_->Read8(v);
    91  writer_->AppendInt(*v);
    92  return true;
    93  }
    94  bool ReadWriteInt16(int16_t* v) {
    95  if (reader_)
    96  return reader_->Read2s(v);
    97  writer_->AppendInt(*v);
    98  return true;
    99  }
    100  bool ReadWriteInt32(int32_t* v) {
    101  if (reader_)
    102  return reader_->Read4s(v);
    103  writer_->AppendInt(*v);
    104  return true;
    105  }
    106  bool ReadWriteInt64(int64_t* v) {
    107  if (reader_)
    108  return reader_->Read8s(v);
    109  writer_->AppendInt(*v);
    110  return true;
    111  }
    113 
    117  bool ReadWriteUInt64NBytes(uint64_t* v, size_t num_bytes) {
    118  if (reader_)
    119  return reader_->ReadNBytesInto8(v, num_bytes);
    120  writer_->AppendNBytes(*v, num_bytes);
    121  return true;
    122  }
    123  bool ReadWriteInt64NBytes(int64_t* v, size_t num_bytes) {
    124  if (reader_)
    125  return reader_->ReadNBytesInto8s(v, num_bytes);
    126  writer_->AppendNBytes(*v, num_bytes);
    127  return true;
    128  }
    129  bool ReadWriteVector(std::vector<uint8_t>* vector, size_t count) {
    130  if (reader_)
    131  return reader_->ReadToVector(vector, count);
    132  DCHECK_EQ(vector->size(), count);
    133  writer_->AppendArray(vector->data(), count);
    134  return true;
    135  }
    136 
    139  bool ReadWriteString(std::string* str, size_t size) {
    140  if (reader_)
    141  return reader_->ReadToString(str, size);
    142  DCHECK_EQ(str->size(), size);
    143  writer_->AppendArray(reinterpret_cast<const uint8_t*>(str->data()),
    144  str->size());
    145  return true;
    146  }
    147 
    148  bool ReadWriteFourCC(FourCC* fourcc) {
    149  if (reader_)
    150  return reader_->ReadFourCC(fourcc);
    151  writer_->AppendInt(static_cast<uint32_t>(*fourcc));
    152  return true;
    153  }
    154 
    158  if (reader_)
    159  return reader_->ScanChildren();
    160  // NOP in write mode.
    161  return true;
    162  }
    163 
    166  bool ReadWriteChild(Box* box) {
    167  if (reader_)
    168  return reader_->ReadChild(box);
    169  // The box is mandatory, i.e. the box size should not be 0.
    170  DCHECK_NE(0u, box->box_size());
    171  CHECK(box->ReadWriteInternal(this));
    172  return true;
    173  }
    174 
    177  bool TryReadWriteChild(Box* box) {
    178  if (reader_)
    179  return reader_->TryReadChild(box);
    180  // The box is optional, i.e. it can be skipped if the box size is 0.
    181  if (box->box_size() != 0)
    182  CHECK(box->ReadWriteInternal(this));
    183  return true;
    184  }
    185 
    189  bool IgnoreBytes(size_t num_bytes) {
    190  if (reader_)
    191  return reader_->SkipBytes(num_bytes);
    192  std::vector<uint8_t> vector(num_bytes, 0);
    193  writer_->AppendVector(vector);
    194  return true;
    195  }
    196 
    198  BoxReader* reader() { return reader_; }
    200  BufferWriter* writer() { return writer_; }
    201 
    202  private:
    203  BoxReader* reader_;
    204  BufferWriter* writer_;
    205 
    206  DISALLOW_COPY_AND_ASSIGN(BoxBuffer);
    207 };
    208 
    209 } // namespace mp4
    210 } // namespace media
    211 } // namespace shaka
    212 
    213 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_BUFFER_H_
    -
    bool TryReadWriteChild(Box *box)
    Definition: box_buffer.h:177
    - -
    size_t BytesLeft() const
    Definition: box_buffer.h:62
    -
    All the methods that are virtual are virtual for mocking.
    - -
    bool ScanChildren() WARN_UNUSED_RESULT
    Definition: box_reader.cc:67
    - -
    void AppendNBytes(uint64_t v, size_t num_bytes)
    - -
    bool ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULT
    - - - -
    bool Read1(uint8_t *v) WARN_UNUSED_RESULT
    -
    uint32_t box_size()
    Definition: box.h:55
    -
    BufferWriter * writer()
    Definition: box_buffer.h:200
    - -
    bool IgnoreBytes(size_t num_bytes)
    Definition: box_buffer.h:189
    -
    bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
    -
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    -
    bool ReadWriteString(std::string *str, size_t size)
    Definition: box_buffer.h:139
    -
    bool ReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:90
    -
    bool ReadWriteUInt64NBytes(uint64_t *v, size_t num_bytes)
    Definition: box_buffer.h:117
    -
    bool TryReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:106
    -
    BoxBuffer(BufferWriter *writer)
    Definition: box_buffer.h:34
    -
    BoxBuffer(BoxReader *reader)
    Definition: box_buffer.h:29
    -
    bool ReadWriteChild(Box *box)
    Definition: box_buffer.h:166
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_BUFFER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_BUFFER_H_
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 #include "packager/base/compiler_specific.h"
    +
    13 #include "packager/media/base/buffer_writer.h"
    +
    14 #include "packager/media/formats/mp4/box.h"
    +
    15 #include "packager/media/formats/mp4/box_reader.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 namespace mp4 {
    +
    20 
    +
    25 class BoxBuffer {
    +
    26  public:
    +
    29  explicit BoxBuffer(BoxReader* reader) : reader_(reader), writer_(NULL) {
    +
    30  DCHECK(reader);
    +
    31  }
    +
    34  explicit BoxBuffer(BufferWriter* writer) : reader_(NULL), writer_(writer) {
    +
    35  DCHECK(writer);
    +
    36  }
    +
    37  ~BoxBuffer() {}
    +
    38 
    +
    40  bool Reading() const { return reader_ != NULL; }
    +
    41 
    +
    44  size_t Pos() const {
    +
    45  if (reader_)
    +
    46  return reader_->pos();
    +
    47  return writer_->Size();
    +
    48  }
    +
    49 
    +
    54  size_t Size() const {
    +
    55  if (reader_)
    +
    56  return reader_->size();
    +
    57  return writer_->Size();
    +
    58  }
    +
    59 
    +
    62  size_t BytesLeft() const {
    +
    63  if (reader_)
    +
    64  return reader_->size() - reader_->pos();
    +
    65  return 0;
    +
    66  }
    +
    67 
    +
    70  bool ReadWriteUInt8(uint8_t* v) {
    +
    71  if (reader_)
    +
    72  return reader_->Read1(v);
    +
    73  writer_->AppendInt(*v);
    +
    74  return true;
    +
    75  }
    +
    76  bool ReadWriteUInt16(uint16_t* v) {
    +
    77  if (reader_)
    +
    78  return reader_->Read2(v);
    +
    79  writer_->AppendInt(*v);
    +
    80  return true;
    +
    81  }
    +
    82  bool ReadWriteUInt32(uint32_t* v) {
    +
    83  if (reader_)
    +
    84  return reader_->Read4(v);
    +
    85  writer_->AppendInt(*v);
    +
    86  return true;
    +
    87  }
    +
    88  bool ReadWriteUInt64(uint64_t* v) {
    +
    89  if (reader_)
    +
    90  return reader_->Read8(v);
    +
    91  writer_->AppendInt(*v);
    +
    92  return true;
    +
    93  }
    +
    94  bool ReadWriteInt16(int16_t* v) {
    +
    95  if (reader_)
    +
    96  return reader_->Read2s(v);
    +
    97  writer_->AppendInt(*v);
    +
    98  return true;
    +
    99  }
    +
    100  bool ReadWriteInt32(int32_t* v) {
    +
    101  if (reader_)
    +
    102  return reader_->Read4s(v);
    +
    103  writer_->AppendInt(*v);
    +
    104  return true;
    +
    105  }
    +
    106  bool ReadWriteInt64(int64_t* v) {
    +
    107  if (reader_)
    +
    108  return reader_->Read8s(v);
    +
    109  writer_->AppendInt(*v);
    +
    110  return true;
    +
    111  }
    +
    113 
    +
    117  bool ReadWriteUInt64NBytes(uint64_t* v, size_t num_bytes) {
    +
    118  if (reader_)
    +
    119  return reader_->ReadNBytesInto8(v, num_bytes);
    +
    120  writer_->AppendNBytes(*v, num_bytes);
    +
    121  return true;
    +
    122  }
    +
    123  bool ReadWriteInt64NBytes(int64_t* v, size_t num_bytes) {
    +
    124  if (reader_)
    +
    125  return reader_->ReadNBytesInto8s(v, num_bytes);
    +
    126  writer_->AppendNBytes(*v, num_bytes);
    +
    127  return true;
    +
    128  }
    +
    129  bool ReadWriteVector(std::vector<uint8_t>* vector, size_t count) {
    +
    130  if (reader_)
    +
    131  return reader_->ReadToVector(vector, count);
    +
    132  DCHECK_EQ(vector->size(), count);
    +
    133  writer_->AppendArray(vector->data(), count);
    +
    134  return true;
    +
    135  }
    +
    136 
    +
    139  bool ReadWriteString(std::string* str, size_t size) {
    +
    140  if (reader_)
    +
    141  return reader_->ReadToString(str, size);
    +
    142  DCHECK_EQ(str->size(), size);
    +
    143  writer_->AppendArray(reinterpret_cast<const uint8_t*>(str->data()),
    +
    144  str->size());
    +
    145  return true;
    +
    146  }
    +
    147 
    +
    148  bool ReadWriteCString(std::string* str) {
    +
    149  if (reader_)
    +
    150  return reader_->ReadCString(str);
    +
    151  // Cannot contain embedded nulls.
    +
    152  DCHECK_EQ(str->find('\0'), std::string::npos);
    +
    153  writer_->AppendString(*str);
    +
    154  writer_->AppendInt(static_cast<uint8_t>('\0'));
    +
    155  return true;
    +
    156  }
    +
    157 
    +
    158  bool ReadWriteFourCC(FourCC* fourcc) {
    +
    159  if (reader_)
    +
    160  return reader_->ReadFourCC(fourcc);
    +
    161  writer_->AppendInt(static_cast<uint32_t>(*fourcc));
    +
    162  return true;
    +
    163  }
    +
    164 
    + +
    168  if (reader_)
    +
    169  return reader_->ScanChildren();
    +
    170  // NOP in write mode.
    +
    171  return true;
    +
    172  }
    +
    173 
    +
    176  bool ReadWriteChild(Box* box) {
    +
    177  if (reader_)
    +
    178  return reader_->ReadChild(box);
    +
    179  // The box is mandatory, i.e. the box size should not be 0.
    +
    180  DCHECK_NE(0u, box->box_size());
    +
    181  CHECK(box->ReadWriteInternal(this));
    +
    182  return true;
    +
    183  }
    +
    184 
    +
    187  bool TryReadWriteChild(Box* box) {
    +
    188  if (reader_)
    +
    189  return reader_->TryReadChild(box);
    +
    190  // The box is optional, i.e. it can be skipped if the box size is 0.
    +
    191  if (box->box_size() != 0)
    +
    192  CHECK(box->ReadWriteInternal(this));
    +
    193  return true;
    +
    194  }
    +
    195 
    +
    199  bool IgnoreBytes(size_t num_bytes) {
    +
    200  if (reader_)
    +
    201  return reader_->SkipBytes(num_bytes);
    +
    202  std::vector<uint8_t> vector(num_bytes, 0);
    +
    203  writer_->AppendVector(vector);
    +
    204  return true;
    +
    205  }
    +
    206 
    +
    208  BoxReader* reader() { return reader_; }
    +
    210  BufferWriter* writer() { return writer_; }
    +
    211 
    +
    212  private:
    +
    213  BoxReader* reader_;
    +
    214  BufferWriter* writer_;
    +
    215 
    +
    216  DISALLOW_COPY_AND_ASSIGN(BoxBuffer);
    +
    217 };
    +
    218 
    +
    219 } // namespace mp4
    +
    220 } // namespace media
    +
    221 } // namespace shaka
    +
    222 
    +
    223 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_BUFFER_H_
    +
    bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
    +
    bool Read1(uint8_t *v) WARN_UNUSED_RESULT
    +
    bool ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULT
    +
    bool ReadCString(std::string *str) WARN_UNUSED_RESULT
    Reads a null-terminated string.
    + + +
    void AppendNBytes(uint64_t v, size_t num_bytes)
    + +
    BoxBuffer(BufferWriter *writer)
    Definition: box_buffer.h:34
    +
    BufferWriter * writer()
    Definition: box_buffer.h:210
    +
    bool IgnoreBytes(size_t num_bytes)
    Definition: box_buffer.h:199
    + + +
    bool ReadWriteUInt64NBytes(uint64_t *v, size_t num_bytes)
    Definition: box_buffer.h:117
    + +
    BoxBuffer(BoxReader *reader)
    Definition: box_buffer.h:29
    +
    bool TryReadWriteChild(Box *box)
    Definition: box_buffer.h:187
    +
    size_t BytesLeft() const
    Definition: box_buffer.h:62
    + +
    bool ReadWriteString(std::string *str, size_t size)
    Definition: box_buffer.h:139
    +
    bool ReadWriteChild(Box *box)
    Definition: box_buffer.h:176
    + +
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    +
    bool TryReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:106
    +
    bool ReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:90
    +
    bool ScanChildren() WARN_UNUSED_RESULT
    Definition: box_reader.cc:67
    +
    All the methods that are virtual are virtual for mocking.
    + +
    uint32_t box_size()
    Definition: box.h:55
    diff --git a/docs/dc/dc1/classshaka_1_1xml_1_1RepresentationXmlNode-members.html b/docs/dc/dc1/classshaka_1_1xml_1_1RepresentationXmlNode-members.html index 3bf7f2bb42..cdc682186d 100644 --- a/docs/dc/dc1/classshaka_1_1xml_1_1RepresentationXmlNode-members.html +++ b/docs/dc/dc1/classshaka_1_1xml_1_1RepresentationXmlNode-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::xml::RepresentationXmlNode, including all inherited members.

    - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + + +
    AddAudioInfo(const MediaInfo::AudioInfo &audio_info)shaka::xml::RepresentationXmlNode
    AddChild(scoped_xml_ptr< xmlNode > child)shaka::xml::XmlNode
    AddContentProtectionElements(const std::list< ContentProtectionElement > &content_protection_elements) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
    AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNodeprotected
    AddElements(const std::vector< Element > &elements)shaka::xml::XmlNode
    AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNode
    AddLiveOnlyInfo(const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number)shaka::xml::RepresentationXmlNode
    AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value)shaka::xml::RepresentationBaseXmlNode
    AddVideoInfo(const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate)shaka::xml::RepresentationXmlNode
    AddVODOnlyInfo(const MediaInfo &media_info)shaka::xml::RepresentationXmlNode
    ExtractReferencedNamespaces()shaka::xml::XmlNode
    GetRawPtr()shaka::xml::XmlNode
    PassScopedPtr()shaka::xml::XmlNode
    Release()shaka::xml::XmlNode
    RepresentationBaseXmlNode(const char *name) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNodeexplicitprotected
    AddAudioInfo(const MediaInfo::AudioInfo &audio_info) WARN_UNUSED_RESULTshaka::xml::RepresentationXmlNode
    AddChild(XmlNode child) WARN_UNUSED_RESULTshaka::xml::XmlNode
    AddContent(const std::string &content)shaka::xml::XmlNode
    AddContentProtectionElements(const std::list< ContentProtectionElement > &content_protection_elements) WARN_UNUSED_RESULT (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
    AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNodeprotected
    AddElements(const std::vector< Element > &elements) WARN_UNUSED_RESULTshaka::xml::XmlNode
    AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNode
    AddLiveOnlyInfo(const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number) WARN_UNUSED_RESULTshaka::xml::RepresentationXmlNode
    AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULTshaka::xml::RepresentationBaseXmlNode
    AddVideoInfo(const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate) WARN_UNUSED_RESULTshaka::xml::RepresentationXmlNode
    AddVODOnlyInfo(const MediaInfo &media_info) WARN_UNUSED_RESULTshaka::xml::RepresentationXmlNode
    ExtractReferencedNamespaces() constshaka::xml::XmlNode
    GetAttribute(const std::string &name, std::string *value) constshaka::xml::XmlNode
    operator=(XmlNode &&) (defined in shaka::xml::XmlNode)shaka::xml::XmlNode
    RepresentationBaseXmlNode(const std::string &name) (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNodeexplicitprotected
    RepresentationXmlNode() (defined in shaka::xml::RepresentationXmlNode)shaka::xml::RepresentationXmlNode
    SetContent(const std::string &content)shaka::xml::XmlNode
    SetFloatingPointAttribute(const char *attribute_name, double number)shaka::xml::XmlNode
    SetId(uint32_t id)shaka::xml::XmlNode
    SetIntegerAttribute(const char *attribute_name, uint64_t number)shaka::xml::XmlNode
    SetStringAttribute(const char *attribute_name, const std::string &attribute)shaka::xml::XmlNode
    XmlNode(const char *name)shaka::xml::XmlNodeexplicit
    SetFloatingPointAttribute(const std::string &attribute_name, double number) WARN_UNUSED_RESULTshaka::xml::XmlNode
    SetId(uint32_t id) WARN_UNUSED_RESULTshaka::xml::XmlNode
    SetIntegerAttribute(const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULTshaka::xml::XmlNode
    SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULTshaka::xml::XmlNode
    ToString(const std::string &comment) constshaka::xml::XmlNode
    XmlNode(const std::string &name)shaka::xml::XmlNodeexplicit
    XmlNode(XmlNode &&) (defined in shaka::xml::XmlNode)shaka::xml::XmlNode
    ~RepresentationBaseXmlNode() override (defined in shaka::xml::RepresentationBaseXmlNode)shaka::xml::RepresentationBaseXmlNode
    ~RepresentationXmlNode() override (defined in shaka::xml::RepresentationXmlNode)shaka::xml::RepresentationXmlNode
    ~XmlNode() (defined in shaka::xml::XmlNode)shaka::xml::XmlNodevirtual
    diff --git a/docs/dc/dc2/classshaka_1_1media_1_1mp2t_1_1EsParserAudio-members.html b/docs/dc/dc2/classshaka_1_1media_1_1mp2t_1_1EsParserAudio-members.html index 1be7932b32..3bb6baab9c 100644 --- a/docs/dc/dc2/classshaka_1_1media_1_1mp2t_1_1EsParserAudio-members.html +++ b/docs/dc/dc2/classshaka_1_1media_1_1mp2t_1_1EsParserAudio-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    This is the complete list of members for shaka::media::mp2t::EsParserAudio, including all inherited members.

    - - - - - - - - - + + + + + + + + + +
    EmitSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    EsParserAudio(uint32_t pid, TsStreamType stream_type, const NewStreamInfoCB &new_stream_info_cb, const EmitSampleCB &emit_sample_cb, bool sbr_in_mimetype) (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudio
    Flush() override (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudiovirtual
    NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudiovirtual
    pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    Reset() override (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudiovirtual
    ~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
    ~EsParserAudio() override (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudio
    EmitTextSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    EsParserAudio(uint32_t pid, TsStreamType stream_type, const NewStreamInfoCB &new_stream_info_cb, const EmitSampleCB &emit_sample_cb, bool sbr_in_mimetype) (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudio
    Flush() override (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudiovirtual
    NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudiovirtual
    pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    Reset() override (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudiovirtual
    ~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
    ~EsParserAudio() override (defined in shaka::media::mp2t::EsParserAudio)shaka::media::mp2t::EsParserAudio
    diff --git a/docs/dc/dca/classshaka_1_1media_1_1WebMListParser.html b/docs/dc/dca/classshaka_1_1media_1_1WebMListParser.html index 92a6320e81..738e57ab97 100644 --- a/docs/dc/dca/classshaka_1_1media_1_1WebMListParser.html +++ b/docs/dc/dca/classshaka_1_1media_1_1WebMListParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::WebMListParser Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/dd8/structshaka_1_1media_1_1CueEvent-members.html b/docs/dc/dd8/structshaka_1_1media_1_1CueEvent-members.html index bb16017e5d..527982643c 100644 --- a/docs/dc/dd8/structshaka_1_1media_1_1CueEvent-members.html +++ b/docs/dc/dd8/structshaka_1_1media_1_1CueEvent-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dc/dd9/rsa__key_8cc_source.html b/docs/dc/dd9/rsa__key_8cc_source.html index 3adf5e98eb..e3829689a8 100644 --- a/docs/dc/dd9/rsa__key_8cc_source.html +++ b/docs/dc/dd9/rsa__key_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/rsa_key.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    rsa_key.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // RSA signature details:
    8 // Algorithm: RSASSA-PSS
    9 // Hash algorithm: SHA1
    10 // Mask generation function: mgf1SHA1
    11 // Salt length: 20 bytes
    12 // Trailer field: 0xbc
    13 //
    14 // RSA encryption details:
    15 // Algorithm: RSA-OAEP
    16 // Mask generation function: mgf1SHA1
    17 // Label (encoding paramter): empty std::string
    18 
    19 #include "packager/media/base/rsa_key.h"
    20 
    21 #include <openssl/err.h>
    22 #include <openssl/rsa.h>
    23 #include <openssl/x509.h>
    24 #include <vector>
    25 
    26 #include "packager/base/logging.h"
    27 #include "packager/base/sha1.h"
    28 
    29 namespace {
    30 
    31 const size_t kPssSaltLength = 20u;
    32 
    33 // Serialize rsa key from DER encoded PKCS#1 RSAPrivateKey.
    34 RSA* DeserializeRsaKey(const std::string& serialized_key,
    35  bool deserialize_private_key) {
    36  if (serialized_key.empty()) {
    37  LOG(ERROR) << "Serialized RSA Key is empty.";
    38  return NULL;
    39  }
    40 
    41  BIO* bio = BIO_new_mem_buf(const_cast<char*>(serialized_key.data()),
    42  serialized_key.size());
    43  if (bio == NULL) {
    44  LOG(ERROR) << "BIO_new_mem_buf returned NULL.";
    45  return NULL;
    46  }
    47  RSA* rsa_key = deserialize_private_key ? d2i_RSAPrivateKey_bio(bio, NULL)
    48  : d2i_RSAPublicKey_bio(bio, NULL);
    49  BIO_free(bio);
    50  return rsa_key;
    51 }
    52 
    53 RSA* DeserializeRsaPrivateKey(const std::string& serialized_key) {
    54  RSA* rsa_key = DeserializeRsaKey(serialized_key, true);
    55  if (!rsa_key) {
    56  LOG(ERROR) << "Private RSA key deserialization failure.";
    57  return NULL;
    58  }
    59  if (RSA_check_key(rsa_key) != 1) {
    60  LOG(ERROR) << "Invalid RSA Private key: " << ERR_error_string(
    61  ERR_get_error(), NULL);
    62  RSA_free(rsa_key);
    63  return NULL;
    64  }
    65  return rsa_key;
    66 }
    67 
    68 RSA* DeserializeRsaPublicKey(const std::string& serialized_key) {
    69  RSA* rsa_key = DeserializeRsaKey(serialized_key, false);
    70  if (!rsa_key) {
    71  LOG(ERROR) << "Private RSA key deserialization failure.";
    72  return NULL;
    73  }
    74  if (RSA_size(rsa_key) <= 0) {
    75  LOG(ERROR) << "Invalid RSA Public key: " << ERR_error_string(
    76  ERR_get_error(), NULL);
    77  RSA_free(rsa_key);
    78  return NULL;
    79  }
    80  return rsa_key;
    81 }
    82 
    83 } // namespace
    84 
    85 namespace shaka {
    86 namespace media {
    87 
    88 RsaPrivateKey::RsaPrivateKey(RSA* rsa_key) : rsa_key_(rsa_key) {
    89  DCHECK(rsa_key);
    90 }
    91 RsaPrivateKey::~RsaPrivateKey() {
    92  if (rsa_key_ != NULL)
    93  RSA_free(rsa_key_);
    94 }
    95 
    96 RsaPrivateKey* RsaPrivateKey::Create(const std::string& serialized_key) {
    97  RSA* rsa_key = DeserializeRsaPrivateKey(serialized_key);
    98  return rsa_key == NULL ? NULL : new RsaPrivateKey(rsa_key);
    99 }
    100 
    101 bool RsaPrivateKey::Decrypt(const std::string& encrypted_message,
    102  std::string* decrypted_message) {
    103  DCHECK(decrypted_message);
    104 
    105  size_t rsa_size = RSA_size(rsa_key_);
    106  if (encrypted_message.size() != rsa_size) {
    107  LOG(ERROR) << "Encrypted RSA message has the wrong size (expected "
    108  << rsa_size << ", actual " << encrypted_message.size() << ").";
    109  return false;
    110  }
    111 
    112  decrypted_message->resize(rsa_size);
    113  int decrypted_size = RSA_private_decrypt(
    114  rsa_size, reinterpret_cast<const uint8_t*>(encrypted_message.data()),
    115  reinterpret_cast<uint8_t*>(&(*decrypted_message)[0]), rsa_key_,
    116  RSA_PKCS1_OAEP_PADDING);
    117 
    118  if (decrypted_size == -1) {
    119  LOG(ERROR) << "RSA private decrypt failure: " << ERR_error_string(
    120  ERR_get_error(), NULL);
    121  return false;
    122  }
    123  decrypted_message->resize(decrypted_size);
    124  return true;
    125 }
    126 
    127 bool RsaPrivateKey::GenerateSignature(const std::string& message,
    128  std::string* signature) {
    129  DCHECK(signature);
    130  if (message.empty()) {
    131  LOG(ERROR) << "Message to be signed is empty.";
    132  return false;
    133  }
    134 
    135  std::string message_digest = base::SHA1HashString(message);
    136 
    137  // Add PSS padding.
    138  size_t rsa_size = RSA_size(rsa_key_);
    139  std::vector<uint8_t> padded_digest(rsa_size);
    140  if (!RSA_padding_add_PKCS1_PSS_mgf1(
    141  rsa_key_, &padded_digest[0],
    142  reinterpret_cast<uint8_t*>(&message_digest[0]), EVP_sha1(),
    143  EVP_sha1(), kPssSaltLength)) {
    144  LOG(ERROR) << "RSA padding failure: " << ERR_error_string(ERR_get_error(),
    145  NULL);
    146  return false;
    147  }
    148 
    149  // Encrypt PSS padded digest.
    150  signature->resize(rsa_size);
    151  int signature_size = RSA_private_encrypt(
    152  padded_digest.size(), &padded_digest[0],
    153  reinterpret_cast<uint8_t*>(&(*signature)[0]), rsa_key_, RSA_NO_PADDING);
    154 
    155  if (signature_size != static_cast<int>(rsa_size)) {
    156  LOG(ERROR) << "RSA private encrypt failure: " << ERR_error_string(
    157  ERR_get_error(), NULL);
    158  return false;
    159  }
    160  return true;
    161 }
    162 
    163 RsaPublicKey::RsaPublicKey(RSA* rsa_key) : rsa_key_(rsa_key) {
    164  DCHECK(rsa_key);
    165 }
    166 RsaPublicKey::~RsaPublicKey() {
    167  if (rsa_key_ != NULL)
    168  RSA_free(rsa_key_);
    169 }
    170 
    171 RsaPublicKey* RsaPublicKey::Create(const std::string& serialized_key) {
    172  RSA* rsa_key = DeserializeRsaPublicKey(serialized_key);
    173  return rsa_key == NULL ? NULL : new RsaPublicKey(rsa_key);
    174 }
    175 
    176 bool RsaPublicKey::Encrypt(const std::string& clear_message,
    177  std::string* encrypted_message) {
    178  DCHECK(encrypted_message);
    179  if (clear_message.empty()) {
    180  LOG(ERROR) << "Message to be encrypted is empty.";
    181  return false;
    182  }
    183 
    184  size_t rsa_size = RSA_size(rsa_key_);
    185  encrypted_message->resize(rsa_size);
    186  int encrypted_size =
    187  RSA_public_encrypt(clear_message.size(),
    188  reinterpret_cast<const uint8_t*>(clear_message.data()),
    189  reinterpret_cast<uint8_t*>(&(*encrypted_message)[0]),
    190  rsa_key_, RSA_PKCS1_OAEP_PADDING);
    191 
    192  if (encrypted_size != static_cast<int>(rsa_size)) {
    193  LOG(ERROR) << "RSA public encrypt failure: " << ERR_error_string(
    194  ERR_get_error(), NULL);
    195  return false;
    196  }
    197  return true;
    198 }
    199 
    200 bool RsaPublicKey::VerifySignature(const std::string& message,
    201  const std::string& signature) {
    202  if (message.empty()) {
    203  LOG(ERROR) << "Signed message is empty.";
    204  return false;
    205  }
    206 
    207  size_t rsa_size = RSA_size(rsa_key_);
    208  if (signature.size() != rsa_size) {
    209  LOG(ERROR) << "Message signature is of the wrong size (expected "
    210  << rsa_size << ", actual " << signature.size() << ").";
    211  return false;
    212  }
    213 
    214  // Decrypt the signature.
    215  std::vector<uint8_t> padded_digest(signature.size());
    216  int decrypted_size =
    217  RSA_public_decrypt(signature.size(),
    218  reinterpret_cast<const uint8_t*>(signature.data()),
    219  &padded_digest[0],
    220  rsa_key_,
    221  RSA_NO_PADDING);
    222 
    223  if (decrypted_size != static_cast<int>(rsa_size)) {
    224  LOG(ERROR) << "RSA public decrypt failure: " << ERR_error_string(
    225  ERR_get_error(), NULL);
    226  return false;
    227  }
    228 
    229  std::string message_digest = base::SHA1HashString(message);
    230 
    231  // Verify PSS padding.
    232  return RSA_verify_PKCS1_PSS_mgf1(
    233  rsa_key_,
    234  reinterpret_cast<const uint8_t*>(message_digest.data()),
    235  EVP_sha1(),
    236  EVP_sha1(),
    237  &padded_digest[0],
    238  kPssSaltLength) != 0;
    239 }
    240 
    241 } // namespace media
    242 } // namespace shaka
    Rsa public key, used for signature verification and encryption.
    Definition: rsa_key.h:53
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool Encrypt(const std::string &clear_message, std::string *encrypted_message)
    Definition: rsa_key.cc:176
    -
    bool Decrypt(const std::string &encrypted_message, std::string *decrypted_message)
    Definition: rsa_key.cc:101
    -
    Rsa private key, used for message signing and decryption.
    Definition: rsa_key.h:24
    -
    bool VerifySignature(const std::string &message, const std::string &signature)
    Definition: rsa_key.cc:200
    -
    static RsaPublicKey * Create(const std::string &serialized_key)
    Definition: rsa_key.cc:171
    -
    bool GenerateSignature(const std::string &message, std::string *signature)
    Definition: rsa_key.cc:127
    -
    static RsaPrivateKey * Create(const std::string &serialized_key)
    Definition: rsa_key.cc:96
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // RSA signature details:
    +
    8 // Algorithm: RSASSA-PSS
    +
    9 // Hash algorithm: SHA1
    +
    10 // Mask generation function: mgf1SHA1
    +
    11 // Salt length: 20 bytes
    +
    12 // Trailer field: 0xbc
    +
    13 //
    +
    14 // RSA encryption details:
    +
    15 // Algorithm: RSA-OAEP
    +
    16 // Mask generation function: mgf1SHA1
    +
    17 // Label (encoding paramter): empty std::string
    +
    18 
    +
    19 #include "packager/media/base/rsa_key.h"
    +
    20 
    +
    21 #include <openssl/err.h>
    +
    22 #include <openssl/rsa.h>
    +
    23 #include <openssl/x509.h>
    +
    24 #include <vector>
    +
    25 
    +
    26 #include "packager/base/logging.h"
    +
    27 #include "packager/base/sha1.h"
    +
    28 
    +
    29 namespace {
    +
    30 
    +
    31 const size_t kPssSaltLength = 20u;
    +
    32 
    +
    33 // Serialize rsa key from DER encoded PKCS#1 RSAPrivateKey.
    +
    34 RSA* DeserializeRsaKey(const std::string& serialized_key,
    +
    35  bool deserialize_private_key) {
    +
    36  if (serialized_key.empty()) {
    +
    37  LOG(ERROR) << "Serialized RSA Key is empty.";
    +
    38  return NULL;
    +
    39  }
    +
    40 
    +
    41  BIO* bio = BIO_new_mem_buf(const_cast<char*>(serialized_key.data()),
    +
    42  serialized_key.size());
    +
    43  if (bio == NULL) {
    +
    44  LOG(ERROR) << "BIO_new_mem_buf returned NULL.";
    +
    45  return NULL;
    +
    46  }
    +
    47  RSA* rsa_key = deserialize_private_key ? d2i_RSAPrivateKey_bio(bio, NULL)
    +
    48  : d2i_RSAPublicKey_bio(bio, NULL);
    +
    49  BIO_free(bio);
    +
    50  return rsa_key;
    +
    51 }
    +
    52 
    +
    53 RSA* DeserializeRsaPrivateKey(const std::string& serialized_key) {
    +
    54  RSA* rsa_key = DeserializeRsaKey(serialized_key, true);
    +
    55  if (!rsa_key) {
    +
    56  LOG(ERROR) << "Private RSA key deserialization failure.";
    +
    57  return NULL;
    +
    58  }
    +
    59  if (RSA_check_key(rsa_key) != 1) {
    +
    60  LOG(ERROR) << "Invalid RSA Private key: " << ERR_error_string(
    +
    61  ERR_get_error(), NULL);
    +
    62  RSA_free(rsa_key);
    +
    63  return NULL;
    +
    64  }
    +
    65  return rsa_key;
    +
    66 }
    +
    67 
    +
    68 RSA* DeserializeRsaPublicKey(const std::string& serialized_key) {
    +
    69  RSA* rsa_key = DeserializeRsaKey(serialized_key, false);
    +
    70  if (!rsa_key) {
    +
    71  LOG(ERROR) << "Private RSA key deserialization failure.";
    +
    72  return NULL;
    +
    73  }
    +
    74  if (RSA_size(rsa_key) <= 0) {
    +
    75  LOG(ERROR) << "Invalid RSA Public key: " << ERR_error_string(
    +
    76  ERR_get_error(), NULL);
    +
    77  RSA_free(rsa_key);
    +
    78  return NULL;
    +
    79  }
    +
    80  return rsa_key;
    +
    81 }
    +
    82 
    +
    83 } // namespace
    +
    84 
    +
    85 namespace shaka {
    +
    86 namespace media {
    +
    87 
    +
    88 RsaPrivateKey::RsaPrivateKey(RSA* rsa_key) : rsa_key_(rsa_key) {
    +
    89  DCHECK(rsa_key);
    +
    90 }
    +
    91 RsaPrivateKey::~RsaPrivateKey() {
    +
    92  if (rsa_key_ != NULL)
    +
    93  RSA_free(rsa_key_);
    +
    94 }
    +
    95 
    +
    96 RsaPrivateKey* RsaPrivateKey::Create(const std::string& serialized_key) {
    +
    97  RSA* rsa_key = DeserializeRsaPrivateKey(serialized_key);
    +
    98  return rsa_key == NULL ? NULL : new RsaPrivateKey(rsa_key);
    +
    99 }
    +
    100 
    +
    101 bool RsaPrivateKey::Decrypt(const std::string& encrypted_message,
    +
    102  std::string* decrypted_message) {
    +
    103  DCHECK(decrypted_message);
    +
    104 
    +
    105  size_t rsa_size = RSA_size(rsa_key_);
    +
    106  if (encrypted_message.size() != rsa_size) {
    +
    107  LOG(ERROR) << "Encrypted RSA message has the wrong size (expected "
    +
    108  << rsa_size << ", actual " << encrypted_message.size() << ").";
    +
    109  return false;
    +
    110  }
    +
    111 
    +
    112  decrypted_message->resize(rsa_size);
    +
    113  int decrypted_size = RSA_private_decrypt(
    +
    114  rsa_size, reinterpret_cast<const uint8_t*>(encrypted_message.data()),
    +
    115  reinterpret_cast<uint8_t*>(&(*decrypted_message)[0]), rsa_key_,
    +
    116  RSA_PKCS1_OAEP_PADDING);
    +
    117 
    +
    118  if (decrypted_size == -1) {
    +
    119  LOG(ERROR) << "RSA private decrypt failure: " << ERR_error_string(
    +
    120  ERR_get_error(), NULL);
    +
    121  return false;
    +
    122  }
    +
    123  decrypted_message->resize(decrypted_size);
    +
    124  return true;
    +
    125 }
    +
    126 
    +
    127 bool RsaPrivateKey::GenerateSignature(const std::string& message,
    +
    128  std::string* signature) {
    +
    129  DCHECK(signature);
    +
    130  if (message.empty()) {
    +
    131  LOG(ERROR) << "Message to be signed is empty.";
    +
    132  return false;
    +
    133  }
    +
    134 
    +
    135  std::string message_digest = base::SHA1HashString(message);
    +
    136 
    +
    137  // Add PSS padding.
    +
    138  size_t rsa_size = RSA_size(rsa_key_);
    +
    139  std::vector<uint8_t> padded_digest(rsa_size);
    +
    140  if (!RSA_padding_add_PKCS1_PSS_mgf1(
    +
    141  rsa_key_, &padded_digest[0],
    +
    142  reinterpret_cast<uint8_t*>(&message_digest[0]), EVP_sha1(),
    +
    143  EVP_sha1(), kPssSaltLength)) {
    +
    144  LOG(ERROR) << "RSA padding failure: " << ERR_error_string(ERR_get_error(),
    +
    145  NULL);
    +
    146  return false;
    +
    147  }
    +
    148 
    +
    149  // Encrypt PSS padded digest.
    +
    150  signature->resize(rsa_size);
    +
    151  int signature_size = RSA_private_encrypt(
    +
    152  padded_digest.size(), &padded_digest[0],
    +
    153  reinterpret_cast<uint8_t*>(&(*signature)[0]), rsa_key_, RSA_NO_PADDING);
    +
    154 
    +
    155  if (signature_size != static_cast<int>(rsa_size)) {
    +
    156  LOG(ERROR) << "RSA private encrypt failure: " << ERR_error_string(
    +
    157  ERR_get_error(), NULL);
    +
    158  return false;
    +
    159  }
    +
    160  return true;
    +
    161 }
    +
    162 
    +
    163 RsaPublicKey::RsaPublicKey(RSA* rsa_key) : rsa_key_(rsa_key) {
    +
    164  DCHECK(rsa_key);
    +
    165 }
    +
    166 RsaPublicKey::~RsaPublicKey() {
    +
    167  if (rsa_key_ != NULL)
    +
    168  RSA_free(rsa_key_);
    +
    169 }
    +
    170 
    +
    171 RsaPublicKey* RsaPublicKey::Create(const std::string& serialized_key) {
    +
    172  RSA* rsa_key = DeserializeRsaPublicKey(serialized_key);
    +
    173  return rsa_key == NULL ? NULL : new RsaPublicKey(rsa_key);
    +
    174 }
    +
    175 
    +
    176 bool RsaPublicKey::Encrypt(const std::string& clear_message,
    +
    177  std::string* encrypted_message) {
    +
    178  DCHECK(encrypted_message);
    +
    179  if (clear_message.empty()) {
    +
    180  LOG(ERROR) << "Message to be encrypted is empty.";
    +
    181  return false;
    +
    182  }
    +
    183 
    +
    184  size_t rsa_size = RSA_size(rsa_key_);
    +
    185  encrypted_message->resize(rsa_size);
    +
    186  int encrypted_size =
    +
    187  RSA_public_encrypt(clear_message.size(),
    +
    188  reinterpret_cast<const uint8_t*>(clear_message.data()),
    +
    189  reinterpret_cast<uint8_t*>(&(*encrypted_message)[0]),
    +
    190  rsa_key_, RSA_PKCS1_OAEP_PADDING);
    +
    191 
    +
    192  if (encrypted_size != static_cast<int>(rsa_size)) {
    +
    193  LOG(ERROR) << "RSA public encrypt failure: " << ERR_error_string(
    +
    194  ERR_get_error(), NULL);
    +
    195  return false;
    +
    196  }
    +
    197  return true;
    +
    198 }
    +
    199 
    +
    200 bool RsaPublicKey::VerifySignature(const std::string& message,
    +
    201  const std::string& signature) {
    +
    202  if (message.empty()) {
    +
    203  LOG(ERROR) << "Signed message is empty.";
    +
    204  return false;
    +
    205  }
    +
    206 
    +
    207  size_t rsa_size = RSA_size(rsa_key_);
    +
    208  if (signature.size() != rsa_size) {
    +
    209  LOG(ERROR) << "Message signature is of the wrong size (expected "
    +
    210  << rsa_size << ", actual " << signature.size() << ").";
    +
    211  return false;
    +
    212  }
    +
    213 
    +
    214  // Decrypt the signature.
    +
    215  std::vector<uint8_t> padded_digest(signature.size());
    +
    216  int decrypted_size =
    +
    217  RSA_public_decrypt(signature.size(),
    +
    218  reinterpret_cast<const uint8_t*>(signature.data()),
    +
    219  &padded_digest[0],
    +
    220  rsa_key_,
    +
    221  RSA_NO_PADDING);
    +
    222 
    +
    223  if (decrypted_size != static_cast<int>(rsa_size)) {
    +
    224  LOG(ERROR) << "RSA public decrypt failure: " << ERR_error_string(
    +
    225  ERR_get_error(), NULL);
    +
    226  return false;
    +
    227  }
    +
    228 
    +
    229  std::string message_digest = base::SHA1HashString(message);
    +
    230 
    +
    231  // Verify PSS padding.
    +
    232  return RSA_verify_PKCS1_PSS_mgf1(
    +
    233  rsa_key_,
    +
    234  reinterpret_cast<const uint8_t*>(message_digest.data()),
    +
    235  EVP_sha1(),
    +
    236  EVP_sha1(),
    +
    237  &padded_digest[0],
    +
    238  kPssSaltLength) != 0;
    +
    239 }
    +
    240 
    +
    241 } // namespace media
    +
    242 } // namespace shaka
    +
    Rsa private key, used for message signing and decryption.
    Definition: rsa_key.h:24
    +
    Rsa public key, used for signature verification and encryption.
    Definition: rsa_key.h:53
    +
    bool VerifySignature(const std::string &message, const std::string &signature)
    Definition: rsa_key.cc:200
    +
    static RsaPublicKey * Create(const std::string &serialized_key)
    Definition: rsa_key.cc:171
    +
    bool Encrypt(const std::string &clear_message, std::string *encrypted_message)
    Definition: rsa_key.cc:176
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/ddf/structshaka_1_1media_1_1mp4_1_1Media.html b/docs/dc/ddf/structshaka_1_1media_1_1mp4_1_1Media.html index 532bbe629d..31f0294922 100644 --- a/docs/dc/ddf/structshaka_1_1media_1_1mp4_1_1Media.html +++ b/docs/dc/ddf/structshaka_1_1media_1_1mp4_1_1Media.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Media Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -118,7 +121,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 627 of file box_definitions.h.

    +

    Definition at line 645 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -146,7 +149,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2178 of file box_definitions.cc.

    +

    Definition at line 2259 of file box_definitions.cc.

    @@ -157,9 +160,7 @@ Additional Inherited Members diff --git a/docs/dc/de1/structshaka_1_1SegmentInfo.html b/docs/dc/de1/structshaka_1_1SegmentInfo.html index d5e225dc03..3ab7506512 100644 --- a/docs/dc/de1/structshaka_1_1SegmentInfo.html +++ b/docs/dc/de1/structshaka_1_1SegmentInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::SegmentInfo Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    repeat
    diff --git a/docs/dc/deb/classshaka_1_1media_1_1mp4_1_1Fragmenter-members.html b/docs/dc/deb/classshaka_1_1media_1_1mp4_1_1Fragmenter-members.html index 6ac1b56d42..4b876cb03a 100644 --- a/docs/dc/deb/classshaka_1_1media_1_1mp4_1_1Fragmenter-members.html +++ b/docs/dc/deb/classshaka_1_1media_1_1mp4_1_1Fragmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/deb/h265__byte__to__unit__stream__converter_8h_source.html b/docs/dc/deb/h265__byte__to__unit__stream__converter_8h_source.html index 9c7c5d0bb3..e50d150b84 100644 --- a/docs/dc/deb/h265__byte__to__unit__stream__converter_8h_source.html +++ b/docs/dc/deb/h265__byte__to__unit__stream__converter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h265_byte_to_unit_stream_converter.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    h265_byte_to_unit_stream_converter.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    8 #define PACKAGER_MEDIA_CODECS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    9 
    10 #include <stddef.h>
    11 #include <stdint.h>
    12 
    13 #include <vector>
    14 
    15 #include "packager/media/codecs/h26x_byte_to_unit_stream_converter.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    23  public:
    27 
    30  explicit H265ByteToUnitStreamConverter(H26xStreamFormat stream_format);
    31 
    33 
    37  std::vector<uint8_t>* decoder_config) const override;
    39 
    40  private:
    41  bool ProcessNalu(const Nalu& nalu) override;
    42 
    43  std::vector<uint8_t> last_sps_;
    44  std::vector<uint8_t> last_pps_;
    45  std::vector<uint8_t> last_vps_;
    46 
    47  DISALLOW_COPY_AND_ASSIGN(H265ByteToUnitStreamConverter);
    48 };
    49 
    50 } // namespace media
    51 } // namespace shaka
    52 
    53 #endif // PACKAGER_MEDIA_CODECS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const override
    - -
    All the methods that are virtual are virtual for mocking.
    - -
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    +
    9 
    +
    10 #include <stddef.h>
    +
    11 #include <stdint.h>
    +
    12 
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/media/codecs/h26x_byte_to_unit_stream_converter.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    + +
    23  public:
    + +
    27 
    +
    30  explicit H265ByteToUnitStreamConverter(H26xStreamFormat stream_format);
    +
    31 
    + +
    33 
    + +
    37  std::vector<uint8_t>* decoder_config) const override;
    +
    39 
    +
    40  private:
    +
    41  bool ProcessNalu(const Nalu& nalu) override;
    +
    42 
    +
    43  std::vector<uint8_t> last_sps_;
    +
    44  std::vector<uint8_t> last_pps_;
    +
    45  std::vector<uint8_t> last_vps_;
    +
    46 
    +
    47  DISALLOW_COPY_AND_ASSIGN(H265ByteToUnitStreamConverter);
    +
    48 };
    +
    49 
    +
    50 } // namespace media
    +
    51 } // namespace shaka
    +
    52 
    +
    53 #endif // PACKAGER_MEDIA_CODECS_H265_BYTE_TO_UNIT_STREAM_CONVERTER_H_
    + + +
    bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const override
    +
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/dec/ts__section__pmt_8cc_source.html b/docs/dc/dec/ts__section__pmt_8cc_source.html index 12da6b99f2..bdce242ec5 100644 --- a/docs/dc/dec/ts__section__pmt_8cc_source.html +++ b/docs/dc/dec/ts__section__pmt_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section_pmt.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    ts_section_pmt.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/mp2t/ts_section_pmt.h"
    6 
    7 #include <map>
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/media/base/bit_reader.h"
    11 #include "packager/media/formats/mp2t/mp2t_common.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace mp2t {
    16 
    17 TsSectionPmt::TsSectionPmt(const RegisterPesCb& register_pes_cb)
    18  : register_pes_cb_(register_pes_cb) {
    19 }
    20 
    21 TsSectionPmt::~TsSectionPmt() {
    22 }
    23 
    24 bool TsSectionPmt::ParsePsiSection(BitReader* bit_reader) {
    25  // Read up to |last_section_number|.
    26  int table_id;
    27  int section_syntax_indicator;
    28  int dummy_zero;
    29  int reserved;
    30  int section_length;
    31  int program_number;
    32  int version_number;
    33  int current_next_indicator;
    34  int section_number;
    35  int last_section_number;
    36  RCHECK(bit_reader->ReadBits(8, &table_id));
    37  RCHECK(bit_reader->ReadBits(1, &section_syntax_indicator));
    38  RCHECK(bit_reader->ReadBits(1, &dummy_zero));
    39  RCHECK(bit_reader->ReadBits(2, &reserved));
    40  RCHECK(bit_reader->ReadBits(12, &section_length));
    41  int section_start_marker = static_cast<int>(bit_reader->bits_available()) / 8;
    42 
    43  RCHECK(bit_reader->ReadBits(16, &program_number));
    44  RCHECK(bit_reader->ReadBits(2, &reserved));
    45  RCHECK(bit_reader->ReadBits(5, &version_number));
    46  RCHECK(bit_reader->ReadBits(1, &current_next_indicator));
    47  RCHECK(bit_reader->ReadBits(8, &section_number));
    48  RCHECK(bit_reader->ReadBits(8, &last_section_number));
    49 
    50  // Perform a few verifications:
    51  // - table ID should be 2 for a PMT.
    52  // - section_syntax_indicator should be one.
    53  // - section length should not exceed 1021.
    54  RCHECK(table_id == 0x2);
    55  RCHECK(section_syntax_indicator);
    56  RCHECK(!dummy_zero);
    57  RCHECK(section_length <= 1021);
    58  RCHECK(section_number == 0);
    59  RCHECK(last_section_number == 0);
    60 
    61  // Read the end of the fixed length section.
    62  int pcr_pid;
    63  int program_info_length;
    64  RCHECK(bit_reader->ReadBits(3, &reserved));
    65  RCHECK(bit_reader->ReadBits(13, &pcr_pid));
    66  RCHECK(bit_reader->ReadBits(4, &reserved));
    67  RCHECK(bit_reader->ReadBits(12, &program_info_length));
    68  RCHECK(program_info_length < 1024);
    69 
    70  // Read the program info descriptor.
    71  // Defined in section 2.6 of ISO-13818.
    72  RCHECK(bit_reader->SkipBits(8 * program_info_length));
    73 
    74  // Read the ES description table.
    75  // The end of the PID map if 4 bytes away from the end of the section
    76  // (4 bytes = size of the CRC).
    77  int pid_map_end_marker = section_start_marker - section_length + 4;
    78  std::map<int, int> pid_map;
    79  while (static_cast<int>(bit_reader->bits_available()) >
    80  8 * pid_map_end_marker) {
    81  int stream_type;
    82  int reserved;
    83  int pid_es;
    84  int es_info_length;
    85  RCHECK(bit_reader->ReadBits(8, &stream_type));
    86  RCHECK(bit_reader->ReadBits(3, &reserved));
    87  RCHECK(bit_reader->ReadBits(13, &pid_es));
    88  RCHECK(bit_reader->ReadBits(4, &reserved));
    89  RCHECK(bit_reader->ReadBits(12, &es_info_length));
    90 
    91  // Do not register the PID right away.
    92  // Wait for the end of the section to be fully parsed
    93  // to make sure there is no error.
    94  pid_map.insert(std::pair<int, int>(pid_es, stream_type));
    95 
    96  // Read the ES info descriptors.
    97  // Defined in section 2.6 of ISO-13818.
    98  RCHECK(bit_reader->SkipBits(8 * es_info_length));
    99  }
    100 
    101  // Read the CRC.
    102  int crc32;
    103  RCHECK(bit_reader->ReadBits(32, &crc32));
    104 
    105  // Once the PMT has been proved to be correct, register the PIDs.
    106  for (std::map<int, int>::iterator it = pid_map.begin();
    107  it != pid_map.end(); ++it)
    108  register_pes_cb_.Run(it->first, it->second);
    109 
    110  return true;
    111 }
    112 
    113 void TsSectionPmt::ResetPsiSection() {
    114 }
    115 
    116 } // namespace mp2t
    117 } // namespace media
    118 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/mp2t/ts_section_pmt.h"
    +
    6 
    +
    7 #include <vector>
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/media/base/bit_reader.h"
    +
    11 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    12 #include "packager/media/formats/mp2t/ts_stream_type.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 namespace mp2t {
    +
    17 
    +
    18 TsSectionPmt::TsSectionPmt(const RegisterPesCb& register_pes_cb)
    +
    19  : register_pes_cb_(register_pes_cb) {
    +
    20 }
    +
    21 
    +
    22 TsSectionPmt::~TsSectionPmt() {
    +
    23 }
    +
    24 
    +
    25 bool TsSectionPmt::ParsePsiSection(BitReader* bit_reader) {
    +
    26  // Read up to |last_section_number|.
    +
    27  int table_id;
    +
    28  int section_syntax_indicator;
    +
    29  int dummy_zero;
    +
    30  int reserved;
    +
    31  int section_length;
    +
    32  int program_number;
    +
    33  int version_number;
    +
    34  int current_next_indicator;
    +
    35  int section_number;
    +
    36  int last_section_number;
    +
    37  RCHECK(bit_reader->ReadBits(8, &table_id));
    +
    38  RCHECK(bit_reader->ReadBits(1, &section_syntax_indicator));
    +
    39  RCHECK(bit_reader->ReadBits(1, &dummy_zero));
    +
    40  RCHECK(bit_reader->ReadBits(2, &reserved));
    +
    41  RCHECK(bit_reader->ReadBits(12, &section_length));
    +
    42  int section_start_marker = static_cast<int>(bit_reader->bits_available()) / 8;
    +
    43 
    +
    44  RCHECK(bit_reader->ReadBits(16, &program_number));
    +
    45  RCHECK(bit_reader->ReadBits(2, &reserved));
    +
    46  RCHECK(bit_reader->ReadBits(5, &version_number));
    +
    47  RCHECK(bit_reader->ReadBits(1, &current_next_indicator));
    +
    48  RCHECK(bit_reader->ReadBits(8, &section_number));
    +
    49  RCHECK(bit_reader->ReadBits(8, &last_section_number));
    +
    50 
    +
    51  // Perform a few verifications:
    +
    52  // - table ID should be 2 for a PMT.
    +
    53  // - section_syntax_indicator should be one.
    +
    54  // - section length should not exceed 1021.
    +
    55  RCHECK(table_id == 0x2);
    +
    56  RCHECK(section_syntax_indicator);
    +
    57  RCHECK(!dummy_zero);
    +
    58  RCHECK(section_length <= 1021);
    +
    59  RCHECK(section_number == 0);
    +
    60  RCHECK(last_section_number == 0);
    +
    61 
    +
    62  // Read the end of the fixed length section.
    +
    63  int pcr_pid;
    +
    64  int program_info_length;
    +
    65  RCHECK(bit_reader->ReadBits(3, &reserved));
    +
    66  RCHECK(bit_reader->ReadBits(13, &pcr_pid));
    +
    67  RCHECK(bit_reader->ReadBits(4, &reserved));
    +
    68  RCHECK(bit_reader->ReadBits(12, &program_info_length));
    +
    69  RCHECK(program_info_length < 1024);
    +
    70 
    +
    71  // Read the program info descriptor.
    +
    72  // Defined in section 2.6 of ISO-13818.
    +
    73  RCHECK(bit_reader->SkipBits(8 * program_info_length));
    +
    74 
    +
    75  // Read the ES description table.
    +
    76  // The end of the PID map if 4 bytes away from the end of the section
    +
    77  // (4 bytes = size of the CRC).
    +
    78  int pid_map_end_marker = section_start_marker - section_length + 4;
    +
    79  struct Info {
    +
    80  int pid_es;
    +
    81  TsStreamType stream_type;
    +
    82  const uint8_t* descriptor;
    +
    83  size_t descriptor_length;
    +
    84  };
    +
    85  std::vector<Info> pid_info;
    +
    86  while (static_cast<int>(bit_reader->bits_available()) >
    +
    87  8 * pid_map_end_marker) {
    +
    88  TsStreamType stream_type;
    +
    89  int pid_es;
    +
    90  size_t es_info_length;
    +
    91  RCHECK(bit_reader->ReadBits(8, &stream_type));
    +
    92  RCHECK(bit_reader->SkipBits(3)); // reserved
    +
    93  RCHECK(bit_reader->ReadBits(13, &pid_es));
    +
    94  RCHECK(bit_reader->ReadBits(4, &reserved));
    +
    95  RCHECK(bit_reader->ReadBits(12, &es_info_length));
    +
    96  const uint8_t* descriptor = bit_reader->current_byte_ptr();
    +
    97 
    +
    98  // Do not register the PID right away.
    +
    99  // Wait for the end of the section to be fully parsed
    +
    100  // to make sure there is no error.
    +
    101  pid_info.push_back({pid_es, stream_type, descriptor, es_info_length});
    +
    102 
    +
    103  // Read the ES info descriptors.
    +
    104  // Defined in section 2.6 of ISO-13818.
    +
    105  if (es_info_length > 0) {
    +
    106  uint8_t descriptor_tag;
    +
    107  RCHECK(bit_reader->ReadBits(8, &descriptor_tag));
    +
    108  es_info_length--;
    +
    109 
    +
    110  // See ETSI EN 300 468 Section 6.1
    +
    111  if (stream_type == TsStreamType::kPesPrivateData &&
    +
    112  descriptor_tag == 0x59) { // subtitling_descriptor
    +
    113  pid_info.back().stream_type = TsStreamType::kDvbSubtitles;
    +
    114  }
    +
    115  }
    +
    116  RCHECK(bit_reader->SkipBits(8 * es_info_length));
    +
    117  }
    +
    118 
    +
    119  // Read the CRC.
    +
    120  int crc32;
    +
    121  RCHECK(bit_reader->ReadBits(32, &crc32));
    +
    122 
    +
    123  // Once the PMT has been proved to be correct, register the PIDs.
    +
    124  for (auto& info : pid_info) {
    +
    125  register_pes_cb_.Run(info.pid_es, info.stream_type, info.descriptor,
    +
    126  info.descriptor_length);
    +
    127  }
    +
    128 
    +
    129  return true;
    +
    130 }
    +
    131 
    +
    132 void TsSectionPmt::ResetPsiSection() {
    +
    133 }
    +
    134 
    +
    135 } // namespace mp2t
    +
    136 } // namespace media
    +
    137 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dc/df0/classshaka_1_1media_1_1ClosureThread.html b/docs/dc/df0/classshaka_1_1media_1_1ClosureThread.html index 73d74695a2..3536dd6a62 100644 --- a/docs/dc/df0/classshaka_1_1media_1_1ClosureThread.html +++ b/docs/dc/df0/classshaka_1_1media_1_1ClosureThread.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::ClosureThread Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    - - - +

    @@ -156,9 +157,7 @@ void 

    diff --git a/docs/dc/df0/classshaka_1_1media_1_1ClosureThread.png b/docs/dc/df0/classshaka_1_1media_1_1ClosureThread.png index 2754ac07b61e62db9a3134417c07dc5776020ca3..8d11646ed9501040aa701451f248eda39ca9d7b7 100644 GIT binary patch delta 616 zcmbQox|4N6OudJvi(^OyH)U{{MgcveP|IUFCF-jsCD zylHnxB~zSrol2!a%|bFzr7XToL<;}r&g%s z-Ym!MCx6#1d4HzFv%<`GN9Nx|3#&So? z_D^lxt-MafQUm0LMs3fy`l`pXX67n0@b6{#b}??p`s-nPsvqvlEPr&D$J~#N!JbvG zVLFre0q;ic2TKpIeh7NNRH0eGxJP6MLmXEOgFcG1?Y}c;z6r8z=!R)v+@8K)^5pHD zZ8o=l^mSM3&QFs+#QLISPxLWH0}W~Bn2bZd^(QUz=1+KC_I$y{d>^}S-kYB-j9OOs zadMc-os?^5N~%kCJfAoJ<(}$!YaT3jWZn^TS+&%(uq|MI@sGa zT^m2oxrL0;EB?(++a(ZwG+Vuz>Sn%lMT**2c4YgbQRkd;}x zd5`0}Puo7G-}#o}@mJRV5W_xX|L4aTZ_fR~ZXA}j{k-v(00toNboFyt=akR{0GRVD Awg3PC delta 589 zcmdnVI*)ZiOueqBi(^Oyl>|Ej!Dcc)KUn^g|B9z6O* z)Od600hLVApzukHJYqe&9!cK~Z`~*5nPnL_)oR|+Glx`PD(|~+*UsSol=|OlZ|d&u zy?beU`Y(?k^L{y(*WY43U7P#vqAuHRhnZi$zSVe|$?ZSh>4z%2oa93u{$(nQng>#y|Pb(|5Omq>Zby%a-p7uMVHI_0GQX z^TpR=!_}MP4^$dWF`Bxh{^R2Kt-I@_f`KmlF>#&BUB_2mK_V-)Jp*k@&z_masL;fI zz-rCX-xWGfcTanFxlHx`(UQ;gDGVLTrHnu?HE0BhD|B69?NGwQz5DOXnQM&95v@>l zFG`}n^M`-pkyhSr^e?63yw|=j|2)JOBvzZpvOBo*vh7H?pnLMhtm~7`zx>87{@y9> z<7I>LVz+6}ljnTuToipMrrzJ!eev$|KVPleeEnQ-4Szw? + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dc/df4/classshaka_1_1media_1_1webm_1_1SingleSegmentSegmenter-members.html b/docs/dc/df4/classshaka_1_1media_1_1webm_1_1SingleSegmentSegmenter-members.html index 5b58affc0c..08969e02cf 100644 --- a/docs/dc/df4/classshaka_1_1media_1_1webm_1_1SingleSegmentSegmenter-members.html +++ b/docs/dc/df4/classshaka_1_1media_1_1webm_1_1SingleSegmentSegmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/df7/structshaka_1_1media_1_1mp4_1_1TrackFragmentRun-members.html b/docs/dc/df7/structshaka_1_1media_1_1mp4_1_1TrackFragmentRun-members.html index 1863b9ccc5..8f2879d615 100644 --- a/docs/dc/df7/structshaka_1_1media_1_1mp4_1_1TrackFragmentRun-members.html +++ b/docs/dc/df7/structshaka_1_1media_1_1mp4_1_1TrackFragmentRun-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dc/df8/closure__thread_8h_source.html b/docs/dc/df8/closure__thread_8h_source.html index 41c48393d7..fa2d5e6a64 100644 --- a/docs/dc/df8/closure__thread_8h_source.html +++ b/docs/dc/df8/closure__thread_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/closure_thread.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    closure_thread.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_CLOSURE_THREAD_H_
    8 #define PACKAGER_MEDIA_BASE_CLOSURE_THREAD_H_
    9 
    10 #include "packager/base/callback.h"
    11 #include "packager/base/threading/simple_thread.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    25 class ClosureThread : public base::SimpleThread {
    26  public:
    32  explicit ClosureThread(const std::string& name_prefix,
    33  const base::Closure& task);
    34 
    36  ~ClosureThread() override;
    37 
    38  protected:
    40  void Run() override;
    41 
    42  private:
    43  const base::Closure task_;
    44 };
    45 
    46 } // namespace media
    47 } // namespace shaka
    48 
    49 #endif // PACKAGER_MEDIA_BASE_CLOSURE_THREAD_H_
    void Run() override
    SimpleThread implementation overrides.
    -
    ClosureThread(const std::string &name_prefix, const base::Closure &task)
    -
    All the methods that are virtual are virtual for mocking.
    -
    ~ClosureThread() override
    The destructor calls Join automatically if it is not yet joined.
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_CLOSURE_THREAD_H_
    +
    8 #define PACKAGER_MEDIA_BASE_CLOSURE_THREAD_H_
    +
    9 
    +
    10 #include "packager/base/callback.h"
    +
    11 #include "packager/base/threading/simple_thread.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    25 class ClosureThread : public base::SimpleThread {
    +
    26  public:
    +
    32  explicit ClosureThread(const std::string& name_prefix,
    +
    33  const base::Closure& task);
    +
    34 
    +
    36  ~ClosureThread() override;
    +
    37 
    +
    38  protected:
    +
    40  void Run() override;
    +
    41 
    +
    42  private:
    +
    43  const base::Closure task_;
    +
    44 };
    +
    45 
    +
    46 } // namespace media
    +
    47 } // namespace shaka
    +
    48 
    +
    49 #endif // PACKAGER_MEDIA_BASE_CLOSURE_THREAD_H_
    + +
    void Run() override
    SimpleThread implementation overrides.
    +
    ClosureThread(const std::string &name_prefix, const base::Closure &task)
    +
    ~ClosureThread() override
    The destructor calls Join automatically if it is not yet joined.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d03/structshaka_1_1media_1_1SegmentEventInfo.html b/docs/dd/d03/structshaka_1_1media_1_1SegmentEventInfo.html index b88ba1c839..acd6fc2fde 100644 --- a/docs/dd/d03/structshaka_1_1media_1_1SegmentEventInfo.html +++ b/docs/dd/d03/structshaka_1_1media_1_1SegmentEventInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SegmentEventInfo Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    segment_file_size
    diff --git a/docs/dd/d05/encryption__config_8h_source.html b/docs/dd/d05/encryption__config_8h_source.html index 87d9acc90c..3d7faf2b1d 100644 --- a/docs/dd/d05/encryption__config_8h_source.html +++ b/docs/dd/d05/encryption__config_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/encryption_config.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    encryption_config.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_ENCRYPTION_CONFIG_H_
    8 #define PACKAGER_MEDIA_BASE_ENCRYPTION_CONFIG_H_
    9 
    10 #include "packager/media/base/fourccs.h"
    11 #include "packager/media/base/protection_system_specific_info.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    17  FourCC protection_scheme = FOURCC_cenc;
    18  uint8_t crypt_byte_block = 0;
    19  uint8_t skip_byte_block = 0;
    20  uint8_t per_sample_iv_size = 0;
    21  std::vector<uint8_t> constant_iv;
    22  std::vector<uint8_t> key_id;
    23  std::vector<ProtectionSystemSpecificInfo> key_system_info;
    24 };
    25 
    26 } // namespace media
    27 } // namespace shaka
    28 
    29 #endif // PACKAGER_MEDIA_BASE_ENCRYPTION_CONFIG_H_
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_ENCRYPTION_CONFIG_H_
    +
    8 #define PACKAGER_MEDIA_BASE_ENCRYPTION_CONFIG_H_
    +
    9 
    +
    10 #include "packager/media/base/fourccs.h"
    +
    11 #include "packager/media/base/protection_system_specific_info.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    + +
    17  FourCC protection_scheme = FOURCC_cenc;
    +
    18  uint8_t crypt_byte_block = 0;
    +
    19  uint8_t skip_byte_block = 0;
    +
    20  uint8_t per_sample_iv_size = 0;
    +
    21  std::vector<uint8_t> constant_iv;
    +
    22  std::vector<uint8_t> key_id;
    +
    23  std::vector<ProtectionSystemSpecificInfo> key_system_info;
    +
    24 };
    +
    25 
    +
    26 } // namespace media
    +
    27 } // namespace shaka
    +
    28 
    +
    29 #endif // PACKAGER_MEDIA_BASE_ENCRYPTION_CONFIG_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/dd/d06/structshaka_1_1media_1_1mp4_1_1ChunkOffset.html b/docs/dd/d06/structshaka_1_1media_1_1mp4_1_1ChunkOffset.html index ec81abf205..34d4180a3b 100644 --- a/docs/dd/d06/structshaka_1_1media_1_1mp4_1_1ChunkOffset.html +++ b/docs/dd/d06/structshaka_1_1media_1_1mp4_1_1ChunkOffset.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::ChunkOffset Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::ChunkLargeOffset shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -119,7 +122,7 @@ uint32_t 

    Detailed Description

    -

    Definition at line 485 of file box_definitions.h.

    +

    Definition at line 498 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -147,7 +150,7 @@ uint32_t Reimplemented from shaka::media::mp4::ChunkLargeOffset.

    -

    Definition at line 876 of file box_definitions.cc.

    +

    Definition at line 889 of file box_definitions.cc.

    @@ -158,9 +161,7 @@ uint32_t  diff --git a/docs/dd/d0c/classshaka_1_1ThreadedIoFile.html b/docs/dd/d0c/classshaka_1_1ThreadedIoFile.html index b480b9777f..287faf3dce 100644 --- a/docs/dd/d0c/classshaka_1_1ThreadedIoFile.html +++ b/docs/dd/d0c/classshaka_1_1ThreadedIoFile.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::ThreadedIoFile Class Reference @@ -29,18 +29,21 @@

    Public Member Functions

    flags = 0 flags = 0 flags = 0
    - + +/* @license-end */
    -shaka::File - -
    +shaka::File + + -

    Public Types

    enum  Mode { kInputMode, -kOutputMode +
    enum  Mode { kInputMode +, kOutputMode }
     
    @@ -187,7 +190,7 @@ Additional Inherited Members
    -

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.
    +

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.

    Implements shaka::File.

    @@ -217,7 +220,7 @@ Additional Inherited Members
    -

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.
    +

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.

    Implements shaka::File.

    @@ -432,9 +435,7 @@ Additional Inherited Members
    diff --git a/docs/dd/d10/muxer__factory_8h_source.html b/docs/dd/d10/muxer__factory_8h_source.html index 0ecc2436c9..ce3d6ed23a 100644 --- a/docs/dd/d10/muxer__factory_8h_source.html +++ b/docs/dd/d10/muxer__factory_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/muxer_factory.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    muxer_factory.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_APP_MUXER_FACTORY_H_
    8 #define PACKAGER_APP_MUXER_FACTORY_H_
    9 
    10 #include <memory>
    11 #include <string>
    12 
    13 #include "packager/media/base/container_names.h"
    14 #include "packager/media/public/mp4_output_params.h"
    15 
    16 namespace base {
    17 class Clock;
    18 } // namespace base
    19 
    20 namespace shaka {
    21 struct PackagingParams;
    22 struct StreamDescriptor;
    23 
    24 namespace media {
    25 
    26 class Muxer;
    27 class MuxerListener;
    28 
    32 class MuxerFactory {
    33  public:
    34  MuxerFactory(const PackagingParams& packaging_params);
    35 
    38  std::shared_ptr<Muxer> CreateMuxer(MediaContainerName output_format,
    39  const StreamDescriptor& stream);
    40 
    43  void OverrideClock(base::Clock* clock);
    44 
    45  private:
    46  MuxerFactory(const MuxerFactory&) = delete;
    47  MuxerFactory& operator=(const MuxerFactory&) = delete;
    48 
    49  const Mp4OutputParams mp4_params_;
    50  const uint32_t transport_stream_timestamp_offset_ms_ = 0;
    51  const std::string temp_dir_;
    52  base::Clock* clock_ = nullptr;
    53 };
    54 
    55 } // namespace media
    56 } // namespace shaka
    57 
    58 #endif // PACKAGER_APP_MUXER_FACTORY_H_
    Defines a single input/output stream.
    Definition: packager.h:73
    -
    All the methods that are virtual are virtual for mocking.
    -
    MP4 (ISO-BMFF) output related parameters.
    - -
    Packaging parameters.
    Definition: packager.h:38
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_APP_MUXER_FACTORY_H_
    +
    8 #define PACKAGER_APP_MUXER_FACTORY_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <string>
    +
    12 
    +
    13 #include "packager/media/base/container_names.h"
    +
    14 #include "packager/media/public/mp4_output_params.h"
    +
    15 
    +
    16 namespace base {
    +
    17 class Clock;
    +
    18 } // namespace base
    +
    19 
    +
    20 namespace shaka {
    +
    21 struct PackagingParams;
    +
    22 struct StreamDescriptor;
    +
    23 
    +
    24 namespace media {
    +
    25 
    +
    26 class Muxer;
    +
    27 class MuxerListener;
    +
    28 
    +
    32 class MuxerFactory {
    +
    33  public:
    +
    34  MuxerFactory(const PackagingParams& packaging_params);
    +
    35 
    +
    38  std::shared_ptr<Muxer> CreateMuxer(MediaContainerName output_format,
    +
    39  const StreamDescriptor& stream);
    +
    40 
    +
    43  void OverrideClock(base::Clock* clock);
    +
    44 
    +
    45  void SetTsStreamOffset(uint32_t offset_ms) {
    +
    46  transport_stream_timestamp_offset_ms_ = offset_ms;
    +
    47  }
    +
    48 
    +
    49  private:
    +
    50  MuxerFactory(const MuxerFactory&) = delete;
    +
    51  MuxerFactory& operator=(const MuxerFactory&) = delete;
    +
    52 
    +
    53  const Mp4OutputParams mp4_params_;
    +
    54  const std::string temp_dir_;
    +
    55  uint32_t transport_stream_timestamp_offset_ms_ = 0;
    +
    56  base::Clock* clock_ = nullptr;
    +
    57 };
    +
    58 
    +
    59 } // namespace media
    +
    60 } // namespace shaka
    +
    61 
    +
    62 #endif // PACKAGER_APP_MUXER_FACTORY_H_
    + +
    std::shared_ptr< Muxer > CreateMuxer(MediaContainerName output_format, const StreamDescriptor &stream)
    +
    void OverrideClock(base::Clock *clock)
    +
    All the methods that are virtual are virtual for mocking.
    +
    MP4 (ISO-BMFF) output related parameters.
    +
    Packaging parameters.
    Definition: packager.h:38
    +
    Defines a single input/output stream.
    Definition: packager.h:76
    diff --git a/docs/dd/d11/mpd__builder_8cc_source.html b/docs/dd/d11/mpd__builder_8cc_source.html index d02893c1b0..572ba82721 100644 --- a/docs/dd/d11/mpd__builder_8cc_source.html +++ b/docs/dd/d11/mpd__builder_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mpd_builder.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mpd_builder.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/mpd/base/mpd_builder.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/base/files/file_path.h"
    12 #include "packager/base/logging.h"
    13 #include "packager/base/optional.h"
    14 #include "packager/base/strings/string_number_conversions.h"
    15 #include "packager/base/strings/stringprintf.h"
    16 #include "packager/base/synchronization/lock.h"
    17 #include "packager/base/time/default_clock.h"
    18 #include "packager/base/time/time.h"
    19 #include "packager/mpd/base/adaptation_set.h"
    20 #include "packager/mpd/base/mpd_utils.h"
    21 #include "packager/mpd/base/period.h"
    22 #include "packager/mpd/base/representation.h"
    23 #include "packager/mpd/base/xml/xml_node.h"
    24 #include "packager/version/version.h"
    25 
    26 namespace shaka {
    27 
    28 using base::FilePath;
    29 using xml::XmlNode;
    30 
    31 namespace {
    32 
    33 void AddMpdNameSpaceInfo(XmlNode* mpd) {
    34  DCHECK(mpd);
    35 
    36  const std::set<std::string> namespaces = mpd->ExtractReferencedNamespaces();
    37 
    38  static const char kXmlNamespace[] = "urn:mpeg:dash:schema:mpd:2011";
    39  static const char kXmlNamespaceXsi[] =
    40  "http://www.w3.org/2001/XMLSchema-instance";
    41  static const char kDashSchemaMpd2011[] =
    42  "urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd";
    43 
    44  mpd->SetStringAttribute("xmlns", kXmlNamespace);
    45  mpd->SetStringAttribute("xmlns:xsi", kXmlNamespaceXsi);
    46  mpd->SetStringAttribute("xsi:schemaLocation", kDashSchemaMpd2011);
    47 
    48  static const char kCencNamespace[] = "urn:mpeg:cenc:2013";
    49  static const char kMarlinNamespace[] =
    50  "urn:marlin:mas:1-0:services:schemas:mpd";
    51  static const char kXmlNamespaceXlink[] = "http://www.w3.org/1999/xlink";
    52 
    53  const std::map<std::string, std::string> uris = {
    54  {"cenc", kCencNamespace},
    55  {"mas", kMarlinNamespace},
    56  {"xlink", kXmlNamespaceXlink},
    57  };
    58 
    59  for (const std::string& namespace_name : namespaces) {
    60  auto iter = uris.find(namespace_name);
    61  CHECK(iter != uris.end()) << " unexpected namespace " << namespace_name;
    62 
    63  mpd->SetStringAttribute(
    64  base::StringPrintf("xmlns:%s", namespace_name.c_str()).c_str(),
    65  iter->second);
    66  }
    67 }
    68 
    69 bool Positive(double d) {
    70  return d > 0.0;
    71 }
    72 
    73 // Return current time in XML DateTime format. The value is in UTC, so the
    74 // string ends with a 'Z'.
    75 std::string XmlDateTimeNowWithOffset(
    76  int32_t offset_seconds,
    77  base::Clock* clock) {
    78  base::Time time = clock->Now();
    79  time += base::TimeDelta::FromSeconds(offset_seconds);
    80  base::Time::Exploded time_exploded;
    81  time.UTCExplode(&time_exploded);
    82 
    83  return base::StringPrintf("%4d-%02d-%02dT%02d:%02d:%02dZ", time_exploded.year,
    84  time_exploded.month, time_exploded.day_of_month,
    85  time_exploded.hour, time_exploded.minute,
    86  time_exploded.second);
    87 }
    88 
    89 void SetIfPositive(const char* attr_name, double value, XmlNode* mpd) {
    90  if (Positive(value)) {
    91  mpd->SetStringAttribute(attr_name, SecondsToXmlDuration(value));
    92  }
    93 }
    94 
    95 std::string MakePathRelative(const std::string& media_path,
    96  const FilePath& parent_path) {
    97  FilePath relative_path;
    98  const FilePath child_path = FilePath::FromUTF8Unsafe(media_path);
    99  const bool is_child =
    100  parent_path.AppendRelativePath(child_path, &relative_path);
    101  if (!is_child)
    102  relative_path = child_path;
    103  return relative_path.NormalizePathSeparatorsTo('/').AsUTF8Unsafe();
    104 }
    105 
    106 // Spooky static initialization/cleanup of libxml.
    107 class LibXmlInitializer {
    108  public:
    109  LibXmlInitializer() : initialized_(false) {
    110  base::AutoLock lock(lock_);
    111  if (!initialized_) {
    112  xmlInitParser();
    113  initialized_ = true;
    114  }
    115  }
    116 
    117  ~LibXmlInitializer() {
    118  base::AutoLock lock(lock_);
    119  if (initialized_) {
    120  xmlCleanupParser();
    121  initialized_ = false;
    122  }
    123  }
    124 
    125  private:
    126  base::Lock lock_;
    127  bool initialized_;
    128 
    129  DISALLOW_COPY_AND_ASSIGN(LibXmlInitializer);
    130 };
    131 
    132 } // namespace
    133 
    135  : mpd_options_(mpd_options), clock_(new base::DefaultClock()) {}
    136 
    137 MpdBuilder::~MpdBuilder() {}
    138 
    139 void MpdBuilder::AddBaseUrl(const std::string& base_url) {
    140  base_urls_.push_back(base_url);
    141 }
    142 
    143 Period* MpdBuilder::GetOrCreatePeriod(double start_time_in_seconds) {
    144  for (auto& period : periods_) {
    145  const double kPeriodTimeDriftThresholdInSeconds = 1.0;
    146  const bool match =
    147  std::fabs(period->start_time_in_seconds() - start_time_in_seconds) <
    148  kPeriodTimeDriftThresholdInSeconds;
    149  if (match)
    150  return period.get();
    151  }
    152  periods_.emplace_back(new Period(period_counter_++, start_time_in_seconds,
    153  mpd_options_, &representation_counter_));
    154  return periods_.back().get();
    155 }
    156 
    157 bool MpdBuilder::ToString(std::string* output) {
    158  DCHECK(output);
    159  static LibXmlInitializer lib_xml_initializer;
    160 
    161  xml::scoped_xml_ptr<xmlDoc> doc(GenerateMpd());
    162  if (!doc)
    163  return false;
    164 
    165  static const int kNiceFormat = 1;
    166  int doc_str_size = 0;
    167  xmlChar* doc_str = nullptr;
    168  xmlDocDumpFormatMemoryEnc(doc.get(), &doc_str, &doc_str_size, "UTF-8",
    169  kNiceFormat);
    170  output->assign(doc_str, doc_str + doc_str_size);
    171  xmlFree(doc_str);
    172 
    173  // Cleanup, free the doc.
    174  doc.reset();
    175  return true;
    176 }
    177 
    178 xmlDocPtr MpdBuilder::GenerateMpd() {
    179  // Setup nodes.
    180  static const char kXmlVersion[] = "1.0";
    181  xml::scoped_xml_ptr<xmlDoc> doc(xmlNewDoc(BAD_CAST kXmlVersion));
    182  XmlNode mpd("MPD");
    183 
    184  // Add baseurls to MPD.
    185  for (const std::string& base_url : base_urls_) {
    186  XmlNode xml_base_url("BaseURL");
    187  xml_base_url.SetContent(base_url);
    188 
    189  if (!mpd.AddChild(xml_base_url.PassScopedPtr()))
    190  return nullptr;
    191  }
    192 
    193  bool output_period_duration = false;
    194  if (mpd_options_.mpd_type == MpdType::kStatic) {
    195  UpdatePeriodDurationAndPresentationTimestamp();
    196  // Only output period duration if there are more than one period. In the
    197  // case of only one period, Period@duration is redundant as it is identical
    198  // to Mpd Duration so the convention is not to output Period@duration.
    199  output_period_duration = periods_.size() > 1;
    200  }
    201 
    202  for (const auto& period : periods_) {
    203  xml::scoped_xml_ptr<xmlNode> period_node(
    204  period->GetXml(output_period_duration));
    205  if (!period_node || !mpd.AddChild(std::move(period_node)))
    206  return nullptr;
    207  }
    208 
    209  AddMpdNameSpaceInfo(&mpd);
    210 
    211  static const char kOnDemandProfile[] =
    212  "urn:mpeg:dash:profile:isoff-on-demand:2011";
    213  static const char kLiveProfile[] =
    214  "urn:mpeg:dash:profile:isoff-live:2011";
    215  switch (mpd_options_.dash_profile) {
    216  case DashProfile::kOnDemand:
    217  mpd.SetStringAttribute("profiles", kOnDemandProfile);
    218  break;
    219  case DashProfile::kLive:
    220  mpd.SetStringAttribute("profiles", kLiveProfile);
    221  break;
    222  default:
    223  NOTREACHED() << "Unknown DASH profile: "
    224  << static_cast<int>(mpd_options_.dash_profile);
    225  break;
    226  }
    227 
    228  AddCommonMpdInfo(&mpd);
    229  switch (mpd_options_.mpd_type) {
    230  case MpdType::kStatic:
    231  AddStaticMpdInfo(&mpd);
    232  break;
    233  case MpdType::kDynamic:
    234  AddDynamicMpdInfo(&mpd);
    235  // Must be after Period element.
    236  AddUtcTiming(&mpd);
    237  break;
    238  default:
    239  NOTREACHED() << "Unknown MPD type: "
    240  << static_cast<int>(mpd_options_.mpd_type);
    241  break;
    242  }
    243 
    244  DCHECK(doc);
    245  const std::string version = GetPackagerVersion();
    246  if (!version.empty()) {
    247  std::string version_string =
    248  base::StringPrintf("Generated with %s version %s",
    249  GetPackagerProjectUrl().c_str(), version.c_str());
    250  xml::scoped_xml_ptr<xmlNode> comment(
    251  xmlNewDocComment(doc.get(), BAD_CAST version_string.c_str()));
    252  xmlDocSetRootElement(doc.get(), comment.get());
    253  xmlAddSibling(comment.release(), mpd.Release());
    254  } else {
    255  xmlDocSetRootElement(doc.get(), mpd.Release());
    256  }
    257  return doc.release();
    258 }
    259 
    260 void MpdBuilder::AddCommonMpdInfo(XmlNode* mpd_node) {
    261  if (Positive(mpd_options_.mpd_params.min_buffer_time)) {
    262  mpd_node->SetStringAttribute(
    263  "minBufferTime",
    264  SecondsToXmlDuration(mpd_options_.mpd_params.min_buffer_time));
    265  } else {
    266  LOG(ERROR) << "minBufferTime value not specified.";
    267  // TODO(tinskip): Propagate error.
    268  }
    269 }
    270 
    271 void MpdBuilder::AddStaticMpdInfo(XmlNode* mpd_node) {
    272  DCHECK(mpd_node);
    273  DCHECK_EQ(MpdType::kStatic, mpd_options_.mpd_type);
    274 
    275  static const char kStaticMpdType[] = "static";
    276  mpd_node->SetStringAttribute("type", kStaticMpdType);
    277  mpd_node->SetStringAttribute("mediaPresentationDuration",
    278  SecondsToXmlDuration(GetStaticMpdDuration()));
    279 }
    280 
    281 void MpdBuilder::AddDynamicMpdInfo(XmlNode* mpd_node) {
    282  DCHECK(mpd_node);
    283  DCHECK_EQ(MpdType::kDynamic, mpd_options_.mpd_type);
    284 
    285  static const char kDynamicMpdType[] = "dynamic";
    286  mpd_node->SetStringAttribute("type", kDynamicMpdType);
    287 
    288  // No offset from NOW.
    289  mpd_node->SetStringAttribute("publishTime",
    290  XmlDateTimeNowWithOffset(0, clock_.get()));
    291 
    292  // 'availabilityStartTime' is required for dynamic profile. Calculate if
    293  // not already calculated.
    294  if (availability_start_time_.empty()) {
    295  double earliest_presentation_time;
    296  if (GetEarliestTimestamp(&earliest_presentation_time)) {
    297  availability_start_time_ = XmlDateTimeNowWithOffset(
    298  -std::ceil(earliest_presentation_time), clock_.get());
    299  } else {
    300  LOG(ERROR) << "Could not determine the earliest segment presentation "
    301  "time for availabilityStartTime calculation.";
    302  // TODO(tinskip). Propagate an error.
    303  }
    304  }
    305  if (!availability_start_time_.empty())
    306  mpd_node->SetStringAttribute("availabilityStartTime",
    307  availability_start_time_);
    308 
    309  if (Positive(mpd_options_.mpd_params.minimum_update_period)) {
    310  mpd_node->SetStringAttribute(
    311  "minimumUpdatePeriod",
    312  SecondsToXmlDuration(mpd_options_.mpd_params.minimum_update_period));
    313  } else {
    314  LOG(WARNING) << "The profile is dynamic but no minimumUpdatePeriod "
    315  "specified.";
    316  }
    317 
    318  SetIfPositive("timeShiftBufferDepth",
    319  mpd_options_.mpd_params.time_shift_buffer_depth, mpd_node);
    320  SetIfPositive("suggestedPresentationDelay",
    321  mpd_options_.mpd_params.suggested_presentation_delay, mpd_node);
    322 }
    323 
    324 void MpdBuilder::AddUtcTiming(XmlNode* mpd_node) {
    325  DCHECK(mpd_node);
    326  DCHECK_EQ(MpdType::kDynamic, mpd_options_.mpd_type);
    327 
    328  for (const MpdParams::UtcTiming& utc_timing :
    329  mpd_options_.mpd_params.utc_timings) {
    330  XmlNode utc_timing_node("UTCTiming");
    331  utc_timing_node.SetStringAttribute("schemeIdUri", utc_timing.scheme_id_uri);
    332  utc_timing_node.SetStringAttribute("value", utc_timing.value);
    333  mpd_node->AddChild(utc_timing_node.PassScopedPtr());
    334  }
    335 }
    336 
    337 float MpdBuilder::GetStaticMpdDuration() {
    338  DCHECK_EQ(MpdType::kStatic, mpd_options_.mpd_type);
    339 
    340  float total_duration = 0.0f;
    341  for (const auto& period : periods_) {
    342  total_duration += period->duration_seconds();
    343  }
    344  return total_duration;
    345 }
    346 
    347 bool MpdBuilder::GetEarliestTimestamp(double* timestamp_seconds) {
    348  DCHECK(timestamp_seconds);
    349  DCHECK(!periods_.empty());
    350  double timestamp = 0;
    351  double earliest_timestamp = -1;
    352  // TODO(kqyang): This is used to set availabilityStartTime. We may consider
    353  // set presentationTimeOffset in the Representations then we can set
    354  // availabilityStartTime to the time when MPD is first generated.
    355  // The first period should have the earliest timestamp.
    356  for (const auto* adaptation_set : periods_.front()->GetAdaptationSets()) {
    357  for (const auto* representation : adaptation_set->GetRepresentations()) {
    358  if (representation->GetStartAndEndTimestamps(&timestamp, nullptr) &&
    359  (earliest_timestamp < 0 || timestamp < earliest_timestamp)) {
    360  earliest_timestamp = timestamp;
    361  }
    362  }
    363  }
    364  if (earliest_timestamp < 0)
    365  return false;
    366  *timestamp_seconds = earliest_timestamp;
    367  return true;
    368 }
    369 
    370 void MpdBuilder::UpdatePeriodDurationAndPresentationTimestamp() {
    371  DCHECK_EQ(MpdType::kStatic, mpd_options_.mpd_type);
    372 
    373  for (const auto& period : periods_) {
    374  std::list<Representation*> video_representations;
    375  std::list<Representation*> non_video_representations;
    376  for (const auto& adaptation_set : period->GetAdaptationSets()) {
    377  const auto& representations = adaptation_set->GetRepresentations();
    378  if (adaptation_set->IsVideo()) {
    379  video_representations.insert(video_representations.end(),
    380  representations.begin(),
    381  representations.end());
    382  } else {
    383  non_video_representations.insert(non_video_representations.end(),
    384  representations.begin(),
    385  representations.end());
    386  }
    387  }
    388 
    389  base::Optional<double> earliest_start_time;
    390  base::Optional<double> latest_end_time;
    391  // The timestamps are based on Video Representations if exist.
    392  const auto& representations = video_representations.size() > 0
    393  ? video_representations
    394  : non_video_representations;
    395  for (const auto& representation : representations) {
    396  double start_time = 0;
    397  double end_time = 0;
    398  if (representation->GetStartAndEndTimestamps(&start_time, &end_time)) {
    399  earliest_start_time =
    400  std::min(earliest_start_time.value_or(start_time), start_time);
    401  latest_end_time =
    402  std::max(latest_end_time.value_or(end_time), end_time);
    403  }
    404  }
    405 
    406  if (!earliest_start_time)
    407  return;
    408 
    409  period->set_duration_seconds(*latest_end_time - *earliest_start_time);
    410 
    411  double presentation_time_offset = *earliest_start_time;
    412  for (const auto& adaptation_set : period->GetAdaptationSets()) {
    413  for (const auto& representation : adaptation_set->GetRepresentations()) {
    414  representation->SetPresentationTimeOffset(presentation_time_offset);
    415  }
    416  }
    417  }
    418 }
    419 
    420 void MpdBuilder::MakePathsRelativeToMpd(const std::string& mpd_path,
    421  MediaInfo* media_info) {
    422  DCHECK(media_info);
    423  const std::string kFileProtocol("file://");
    424  std::string mpd_file_path = (mpd_path.find(kFileProtocol) == 0)
    425  ? mpd_path.substr(kFileProtocol.size())
    426  : mpd_path;
    427 
    428  if (!mpd_file_path.empty()) {
    429  const FilePath mpd_dir(FilePath::FromUTF8Unsafe(mpd_file_path)
    430  .DirName()
    431  .AsEndingWithSeparator());
    432  if (!mpd_dir.empty()) {
    433  if (media_info->has_media_file_name()) {
    434  media_info->set_media_file_url(
    435  MakePathRelative(media_info->media_file_name(), mpd_dir));
    436  }
    437  if (media_info->has_init_segment_name()) {
    438  media_info->set_init_segment_url(
    439  MakePathRelative(media_info->init_segment_name(), mpd_dir));
    440  }
    441  if (media_info->has_segment_template()) {
    442  media_info->set_segment_template_url(
    443  MakePathRelative(media_info->segment_template(), mpd_dir));
    444  }
    445  }
    446  }
    447 }
    448 
    449 } // namespace shaka
    double min_buffer_time
    Definition: mpd_params.h:27
    -
    UTCTimings. For dynamic MPD only.
    Definition: mpd_params.h:48
    - -
    scoped_xml_ptr< xmlNode > PassScopedPtr()
    Definition: xml_node.cc:204
    -
    All the methods that are virtual are virtual for mocking.
    -
    void SetStringAttribute(const char *attribute_name, const std::string &attribute)
    Definition: xml_node.cc:166
    -
    bool AddChild(scoped_xml_ptr< xmlNode > child)
    Definition: xml_node.cc:121
    -
    xmlNodePtr Release()
    Definition: xml_node.cc:210
    -
    virtual Period * GetOrCreatePeriod(double start_time_in_seconds)
    Definition: mpd_builder.cc:143
    -
    MpdBuilder(const MpdOptions &mpd_options)
    Definition: mpd_builder.cc:134
    -
    void AddBaseUrl(const std::string &base_url)
    Definition: mpd_builder.cc:139
    -
    virtual bool ToString(std::string *output)
    Definition: mpd_builder.cc:157
    - -
    static void MakePathsRelativeToMpd(const std::string &mpd_path, MediaInfo *media_info)
    Definition: mpd_builder.cc:420
    -
    double minimum_update_period
    Definition: mpd_params.h:30
    -
    Defines Mpd Options.
    Definition: mpd_options.h:25
    -
    void SetContent(const std::string &content)
    Definition: xml_node.cc:193
    -
    double time_shift_buffer_depth
    Definition: mpd_params.h:39
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/mpd/base/mpd_builder.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/files/file_path.h"
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/base/optional.h"
    +
    14 #include "packager/base/strings/string_number_conversions.h"
    +
    15 #include "packager/base/strings/stringprintf.h"
    +
    16 #include "packager/base/synchronization/lock.h"
    +
    17 #include "packager/base/time/default_clock.h"
    +
    18 #include "packager/base/time/time.h"
    +
    19 #include "packager/media/base/rcheck.h"
    +
    20 #include "packager/mpd/base/adaptation_set.h"
    +
    21 #include "packager/mpd/base/mpd_utils.h"
    +
    22 #include "packager/mpd/base/period.h"
    +
    23 #include "packager/mpd/base/representation.h"
    +
    24 #include "packager/version/version.h"
    +
    25 
    +
    26 namespace shaka {
    +
    27 
    +
    28 using base::FilePath;
    +
    29 using xml::XmlNode;
    +
    30 
    +
    31 namespace {
    +
    32 
    +
    33 bool AddMpdNameSpaceInfo(XmlNode* mpd) {
    +
    34  DCHECK(mpd);
    +
    35 
    +
    36  const std::set<std::string> namespaces = mpd->ExtractReferencedNamespaces();
    +
    37 
    +
    38  static const char kXmlNamespace[] = "urn:mpeg:dash:schema:mpd:2011";
    +
    39  static const char kXmlNamespaceXsi[] =
    +
    40  "http://www.w3.org/2001/XMLSchema-instance";
    +
    41  static const char kDashSchemaMpd2011[] =
    +
    42  "urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd";
    +
    43 
    +
    44  RCHECK(mpd->SetStringAttribute("xmlns", kXmlNamespace));
    +
    45  RCHECK(mpd->SetStringAttribute("xmlns:xsi", kXmlNamespaceXsi));
    +
    46  RCHECK(mpd->SetStringAttribute("xsi:schemaLocation", kDashSchemaMpd2011));
    +
    47 
    +
    48  static const char kCencNamespace[] = "urn:mpeg:cenc:2013";
    +
    49  static const char kMarlinNamespace[] =
    +
    50  "urn:marlin:mas:1-0:services:schemas:mpd";
    +
    51  static const char kXmlNamespaceXlink[] = "http://www.w3.org/1999/xlink";
    +
    52  static const char kMsprNamespace[] = "urn:microsoft:playready";
    +
    53 
    +
    54  const std::map<std::string, std::string> uris = {
    +
    55  {"cenc", kCencNamespace},
    +
    56  {"mas", kMarlinNamespace},
    +
    57  {"xlink", kXmlNamespaceXlink},
    +
    58  {"mspr", kMsprNamespace},
    +
    59  };
    +
    60 
    +
    61  for (const std::string& namespace_name : namespaces) {
    +
    62  auto iter = uris.find(namespace_name);
    +
    63  CHECK(iter != uris.end()) << " unexpected namespace " << namespace_name;
    +
    64 
    +
    65  RCHECK(mpd->SetStringAttribute(
    +
    66  base::StringPrintf("xmlns:%s", namespace_name.c_str()).c_str(),
    +
    67  iter->second));
    +
    68  }
    +
    69  return true;
    +
    70 }
    +
    71 
    +
    72 bool Positive(double d) {
    +
    73  return d > 0.0;
    +
    74 }
    +
    75 
    +
    76 // Return current time in XML DateTime format. The value is in UTC, so the
    +
    77 // string ends with a 'Z'.
    +
    78 std::string XmlDateTimeNowWithOffset(
    +
    79  int32_t offset_seconds,
    +
    80  base::Clock* clock) {
    +
    81  base::Time time = clock->Now();
    +
    82  time += base::TimeDelta::FromSeconds(offset_seconds);
    +
    83  base::Time::Exploded time_exploded;
    +
    84  time.UTCExplode(&time_exploded);
    +
    85 
    +
    86  return base::StringPrintf("%4d-%02d-%02dT%02d:%02d:%02dZ", time_exploded.year,
    +
    87  time_exploded.month, time_exploded.day_of_month,
    +
    88  time_exploded.hour, time_exploded.minute,
    +
    89  time_exploded.second);
    +
    90 }
    +
    91 
    +
    92 bool SetIfPositive(const char* attr_name, double value, XmlNode* mpd) {
    +
    93  return !Positive(value) ||
    +
    94  mpd->SetStringAttribute(attr_name, SecondsToXmlDuration(value));
    +
    95 }
    +
    96 
    +
    97 std::string MakePathRelative(const std::string& media_path,
    +
    98  const FilePath& parent_path) {
    +
    99  FilePath relative_path;
    +
    100  const FilePath child_path = FilePath::FromUTF8Unsafe(media_path);
    +
    101  const bool is_child =
    +
    102  parent_path.AppendRelativePath(child_path, &relative_path);
    +
    103  if (!is_child)
    +
    104  relative_path = child_path;
    +
    105  return relative_path.NormalizePathSeparatorsTo('/').AsUTF8Unsafe();
    +
    106 }
    +
    107 
    +
    108 // Spooky static initialization/cleanup of libxml.
    +
    109 class LibXmlInitializer {
    +
    110  public:
    +
    111  LibXmlInitializer() : initialized_(false) {
    +
    112  base::AutoLock lock(lock_);
    +
    113  if (!initialized_) {
    +
    114  xmlInitParser();
    +
    115  initialized_ = true;
    +
    116  }
    +
    117  }
    +
    118 
    +
    119  ~LibXmlInitializer() {
    +
    120  base::AutoLock lock(lock_);
    +
    121  if (initialized_) {
    +
    122  xmlCleanupParser();
    +
    123  initialized_ = false;
    +
    124  }
    +
    125  }
    +
    126 
    +
    127  private:
    +
    128  base::Lock lock_;
    +
    129  bool initialized_;
    +
    130 
    +
    131  DISALLOW_COPY_AND_ASSIGN(LibXmlInitializer);
    +
    132 };
    +
    133 
    +
    134 } // namespace
    +
    135 
    + +
    137  : mpd_options_(mpd_options), clock_(new base::DefaultClock()) {}
    +
    138 
    +
    139 MpdBuilder::~MpdBuilder() {}
    +
    140 
    +
    141 void MpdBuilder::AddBaseUrl(const std::string& base_url) {
    +
    142  base_urls_.push_back(base_url);
    +
    143 }
    +
    144 
    +
    145 Period* MpdBuilder::GetOrCreatePeriod(double start_time_in_seconds) {
    +
    146  for (auto& period : periods_) {
    +
    147  const double kPeriodTimeDriftThresholdInSeconds = 1.0;
    +
    148  const bool match =
    +
    149  std::fabs(period->start_time_in_seconds() - start_time_in_seconds) <
    +
    150  kPeriodTimeDriftThresholdInSeconds;
    +
    151  if (match)
    +
    152  return period.get();
    +
    153  }
    +
    154  periods_.emplace_back(new Period(period_counter_++, start_time_in_seconds,
    +
    155  mpd_options_, &representation_counter_));
    +
    156  return periods_.back().get();
    +
    157 }
    +
    158 
    +
    159 bool MpdBuilder::ToString(std::string* output) {
    +
    160  DCHECK(output);
    +
    161  static LibXmlInitializer lib_xml_initializer;
    +
    162 
    +
    163  auto mpd = GenerateMpd();
    +
    164  if (!mpd)
    +
    165  return false;
    +
    166 
    +
    167  std::string version = GetPackagerVersion();
    +
    168  if (!version.empty()) {
    +
    169  version =
    +
    170  base::StringPrintf("Generated with %s version %s",
    +
    171  GetPackagerProjectUrl().c_str(), version.c_str());
    +
    172  }
    +
    173  *output = mpd->ToString(version);
    +
    174  return true;
    +
    175 }
    +
    176 
    +
    177 base::Optional<xml::XmlNode> MpdBuilder::GenerateMpd() {
    +
    178  XmlNode mpd("MPD");
    +
    179 
    +
    180  // Add baseurls to MPD.
    +
    181  for (const std::string& base_url : base_urls_) {
    +
    182  XmlNode xml_base_url("BaseURL");
    +
    183  xml_base_url.SetContent(base_url);
    +
    184 
    +
    185  if (!mpd.AddChild(std::move(xml_base_url)))
    +
    186  return base::nullopt;
    +
    187  }
    +
    188 
    +
    189  bool output_period_duration = false;
    +
    190  if (mpd_options_.mpd_type == MpdType::kStatic) {
    +
    191  UpdatePeriodDurationAndPresentationTimestamp();
    +
    192  // Only output period duration if there are more than one period. In the
    +
    193  // case of only one period, Period@duration is redundant as it is identical
    +
    194  // to Mpd Duration so the convention is not to output Period@duration.
    +
    195  output_period_duration = periods_.size() > 1;
    +
    196  }
    +
    197 
    +
    198  for (const auto& period : periods_) {
    +
    199  auto period_node = period->GetXml(output_period_duration);
    +
    200  if (!period_node || !mpd.AddChild(std::move(*period_node)))
    +
    201  return base::nullopt;
    +
    202  }
    +
    203 
    +
    204  if (!AddMpdNameSpaceInfo(&mpd))
    +
    205  return base::nullopt;
    +
    206 
    +
    207  static const char kOnDemandProfile[] =
    +
    208  "urn:mpeg:dash:profile:isoff-on-demand:2011";
    +
    209  static const char kLiveProfile[] =
    +
    210  "urn:mpeg:dash:profile:isoff-live:2011";
    +
    211  switch (mpd_options_.dash_profile) {
    +
    212  case DashProfile::kOnDemand:
    +
    213  if (!mpd.SetStringAttribute("profiles", kOnDemandProfile))
    +
    214  return base::nullopt;
    +
    215  break;
    +
    216  case DashProfile::kLive:
    +
    217  if (!mpd.SetStringAttribute("profiles", kLiveProfile))
    +
    218  return base::nullopt;
    +
    219  break;
    +
    220  default:
    +
    221  NOTREACHED() << "Unknown DASH profile: "
    +
    222  << static_cast<int>(mpd_options_.dash_profile);
    +
    223  break;
    +
    224  }
    +
    225 
    +
    226  if (!AddCommonMpdInfo(&mpd))
    +
    227  return base::nullopt;
    +
    228  switch (mpd_options_.mpd_type) {
    +
    229  case MpdType::kStatic:
    +
    230  if (!AddStaticMpdInfo(&mpd))
    +
    231  return base::nullopt;
    +
    232  break;
    +
    233  case MpdType::kDynamic:
    +
    234  if (!AddDynamicMpdInfo(&mpd))
    +
    235  return base::nullopt;
    +
    236  // Must be after Period element.
    +
    237  if (!AddUtcTiming(&mpd))
    +
    238  return base::nullopt;
    +
    239  break;
    +
    240  default:
    +
    241  NOTREACHED() << "Unknown MPD type: "
    +
    242  << static_cast<int>(mpd_options_.mpd_type);
    +
    243  break;
    +
    244  }
    +
    245  return mpd;
    +
    246 }
    +
    247 
    +
    248 bool MpdBuilder::AddCommonMpdInfo(XmlNode* mpd_node) {
    +
    249  if (Positive(mpd_options_.mpd_params.min_buffer_time)) {
    +
    250  RCHECK(mpd_node->SetStringAttribute(
    +
    251  "minBufferTime",
    +
    252  SecondsToXmlDuration(mpd_options_.mpd_params.min_buffer_time)));
    +
    253  } else {
    +
    254  LOG(ERROR) << "minBufferTime value not specified.";
    +
    255  return false;
    +
    256  }
    +
    257  return true;
    +
    258 }
    +
    259 
    +
    260 bool MpdBuilder::AddStaticMpdInfo(XmlNode* mpd_node) {
    +
    261  DCHECK(mpd_node);
    +
    262  DCHECK_EQ(MpdType::kStatic, mpd_options_.mpd_type);
    +
    263 
    +
    264  static const char kStaticMpdType[] = "static";
    +
    265  return mpd_node->SetStringAttribute("type", kStaticMpdType) &&
    +
    266  mpd_node->SetStringAttribute(
    +
    267  "mediaPresentationDuration",
    +
    268  SecondsToXmlDuration(GetStaticMpdDuration()));
    +
    269 }
    +
    270 
    +
    271 bool MpdBuilder::AddDynamicMpdInfo(XmlNode* mpd_node) {
    +
    272  DCHECK(mpd_node);
    +
    273  DCHECK_EQ(MpdType::kDynamic, mpd_options_.mpd_type);
    +
    274 
    +
    275  static const char kDynamicMpdType[] = "dynamic";
    +
    276  RCHECK(mpd_node->SetStringAttribute("type", kDynamicMpdType));
    +
    277 
    +
    278  // No offset from NOW.
    +
    279  RCHECK(mpd_node->SetStringAttribute(
    +
    280  "publishTime", XmlDateTimeNowWithOffset(0, clock_.get())));
    +
    281 
    +
    282  // 'availabilityStartTime' is required for dynamic profile. Calculate if
    +
    283  // not already calculated.
    +
    284  if (availability_start_time_.empty()) {
    +
    285  double earliest_presentation_time;
    +
    286  if (GetEarliestTimestamp(&earliest_presentation_time)) {
    +
    287  availability_start_time_ = XmlDateTimeNowWithOffset(
    +
    288  -std::ceil(earliest_presentation_time), clock_.get());
    +
    289  } else {
    +
    290  LOG(ERROR) << "Could not determine the earliest segment presentation "
    +
    291  "time for availabilityStartTime calculation.";
    +
    292  // TODO(tinskip). Propagate an error.
    +
    293  }
    +
    294  }
    +
    295  if (!availability_start_time_.empty()) {
    +
    296  RCHECK(mpd_node->SetStringAttribute("availabilityStartTime",
    +
    297  availability_start_time_));
    +
    298  }
    +
    299 
    +
    300  if (Positive(mpd_options_.mpd_params.minimum_update_period)) {
    +
    301  RCHECK(mpd_node->SetStringAttribute(
    +
    302  "minimumUpdatePeriod",
    +
    303  SecondsToXmlDuration(mpd_options_.mpd_params.minimum_update_period)));
    +
    304  } else {
    +
    305  LOG(WARNING) << "The profile is dynamic but no minimumUpdatePeriod "
    +
    306  "specified.";
    +
    307  }
    +
    308 
    +
    309  return SetIfPositive("timeShiftBufferDepth",
    +
    310  mpd_options_.mpd_params.time_shift_buffer_depth,
    +
    311  mpd_node) &&
    +
    312  SetIfPositive("suggestedPresentationDelay",
    +
    313  mpd_options_.mpd_params.suggested_presentation_delay,
    +
    314  mpd_node);
    +
    315 }
    +
    316 
    +
    317 bool MpdBuilder::AddUtcTiming(XmlNode* mpd_node) {
    +
    318  DCHECK(mpd_node);
    +
    319  DCHECK_EQ(MpdType::kDynamic, mpd_options_.mpd_type);
    +
    320 
    +
    321  for (const MpdParams::UtcTiming& utc_timing :
    +
    322  mpd_options_.mpd_params.utc_timings) {
    +
    323  XmlNode utc_timing_node("UTCTiming");
    +
    324  RCHECK(utc_timing_node.SetStringAttribute("schemeIdUri",
    +
    325  utc_timing.scheme_id_uri));
    +
    326  RCHECK(utc_timing_node.SetStringAttribute("value", utc_timing.value));
    +
    327  RCHECK(mpd_node->AddChild(std::move(utc_timing_node)));
    +
    328  }
    +
    329  return true;
    +
    330 }
    +
    331 
    +
    332 float MpdBuilder::GetStaticMpdDuration() {
    +
    333  DCHECK_EQ(MpdType::kStatic, mpd_options_.mpd_type);
    +
    334 
    +
    335  float total_duration = 0.0f;
    +
    336  for (const auto& period : periods_) {
    +
    337  total_duration += period->duration_seconds();
    +
    338  }
    +
    339  return total_duration;
    +
    340 }
    +
    341 
    +
    342 bool MpdBuilder::GetEarliestTimestamp(double* timestamp_seconds) {
    +
    343  DCHECK(timestamp_seconds);
    +
    344  DCHECK(!periods_.empty());
    +
    345  double timestamp = 0;
    +
    346  double earliest_timestamp = -1;
    +
    347  // TODO(kqyang): This is used to set availabilityStartTime. We may consider
    +
    348  // set presentationTimeOffset in the Representations then we can set
    +
    349  // availabilityStartTime to the time when MPD is first generated.
    +
    350  // The first period should have the earliest timestamp.
    +
    351  for (const auto* adaptation_set : periods_.front()->GetAdaptationSets()) {
    +
    352  for (const auto* representation : adaptation_set->GetRepresentations()) {
    +
    353  if (representation->GetStartAndEndTimestamps(&timestamp, nullptr) &&
    +
    354  (earliest_timestamp < 0 || timestamp < earliest_timestamp)) {
    +
    355  earliest_timestamp = timestamp;
    +
    356  }
    +
    357  }
    +
    358  }
    +
    359  if (earliest_timestamp < 0)
    +
    360  return false;
    +
    361  *timestamp_seconds = earliest_timestamp;
    +
    362  return true;
    +
    363 }
    +
    364 
    +
    365 void MpdBuilder::UpdatePeriodDurationAndPresentationTimestamp() {
    +
    366  DCHECK_EQ(MpdType::kStatic, mpd_options_.mpd_type);
    +
    367 
    +
    368  for (const auto& period : periods_) {
    +
    369  std::list<Representation*> video_representations;
    +
    370  std::list<Representation*> non_video_representations;
    +
    371  for (const auto& adaptation_set : period->GetAdaptationSets()) {
    +
    372  const auto& representations = adaptation_set->GetRepresentations();
    +
    373  if (adaptation_set->IsVideo()) {
    +
    374  video_representations.insert(video_representations.end(),
    +
    375  representations.begin(),
    +
    376  representations.end());
    +
    377  } else {
    +
    378  non_video_representations.insert(non_video_representations.end(),
    +
    379  representations.begin(),
    +
    380  representations.end());
    +
    381  }
    +
    382  }
    +
    383 
    +
    384  base::Optional<double> earliest_start_time;
    +
    385  base::Optional<double> latest_end_time;
    +
    386  // The timestamps are based on Video Representations if exist.
    +
    387  const auto& representations = video_representations.size() > 0
    +
    388  ? video_representations
    +
    389  : non_video_representations;
    +
    390  for (const auto& representation : representations) {
    +
    391  double start_time = 0;
    +
    392  double end_time = 0;
    +
    393  if (representation->GetStartAndEndTimestamps(&start_time, &end_time)) {
    +
    394  earliest_start_time =
    +
    395  std::min(earliest_start_time.value_or(start_time), start_time);
    +
    396  latest_end_time =
    +
    397  std::max(latest_end_time.value_or(end_time), end_time);
    +
    398  }
    +
    399  }
    +
    400 
    +
    401  if (!earliest_start_time)
    +
    402  return;
    +
    403 
    +
    404  period->set_duration_seconds(*latest_end_time - *earliest_start_time);
    +
    405 
    +
    406  double presentation_time_offset = *earliest_start_time;
    +
    407  for (const auto& adaptation_set : period->GetAdaptationSets()) {
    +
    408  for (const auto& representation : adaptation_set->GetRepresentations()) {
    +
    409  representation->SetPresentationTimeOffset(presentation_time_offset);
    +
    410  }
    +
    411  }
    +
    412  }
    +
    413 }
    +
    414 
    +
    415 void MpdBuilder::MakePathsRelativeToMpd(const std::string& mpd_path,
    +
    416  MediaInfo* media_info) {
    +
    417  DCHECK(media_info);
    +
    418  const std::string kFileProtocol("file://");
    +
    419  std::string mpd_file_path = (mpd_path.find(kFileProtocol) == 0)
    +
    420  ? mpd_path.substr(kFileProtocol.size())
    +
    421  : mpd_path;
    +
    422 
    +
    423  if (!mpd_file_path.empty()) {
    +
    424  const FilePath mpd_dir(FilePath::FromUTF8Unsafe(mpd_file_path)
    +
    425  .DirName()
    +
    426  .AsEndingWithSeparator());
    +
    427  if (!mpd_dir.empty()) {
    +
    428  if (media_info->has_media_file_name()) {
    +
    429  media_info->set_media_file_url(
    +
    430  MakePathRelative(media_info->media_file_name(), mpd_dir));
    +
    431  }
    +
    432  if (media_info->has_init_segment_name()) {
    +
    433  media_info->set_init_segment_url(
    +
    434  MakePathRelative(media_info->init_segment_name(), mpd_dir));
    +
    435  }
    +
    436  if (media_info->has_segment_template()) {
    +
    437  media_info->set_segment_template_url(
    +
    438  MakePathRelative(media_info->segment_template(), mpd_dir));
    +
    439  }
    +
    440  }
    +
    441  }
    +
    442 }
    +
    443 
    +
    444 } // namespace shaka
    +
    virtual bool ToString(std::string *output) WARN_UNUSED_RESULT
    Definition: mpd_builder.cc:159
    +
    static void MakePathsRelativeToMpd(const std::string &mpd_path, MediaInfo *media_info)
    Definition: mpd_builder.cc:415
    +
    MpdBuilder(const MpdOptions &mpd_options)
    Definition: mpd_builder.cc:136
    +
    void AddBaseUrl(const std::string &base_url)
    Definition: mpd_builder.cc:141
    +
    virtual Period * GetOrCreatePeriod(double start_time_in_seconds)
    Definition: mpd_builder.cc:145
    + + +
    All the methods that are virtual are virtual for mocking.
    +
    Defines Mpd Options.
    Definition: mpd_options.h:25
    +
    double minimum_update_period
    Definition: mpd_params.h:30
    +
    double time_shift_buffer_depth
    Definition: mpd_params.h:39
    +
    double min_buffer_time
    Definition: mpd_params.h:27
    diff --git a/docs/dd/d12/mpd__writer_8cc_source.html b/docs/dd/d12/mpd__writer_8cc_source.html index 0cef6aaba8..4abb9bba97 100644 --- a/docs/dd/d12/mpd__writer_8cc_source.html +++ b/docs/dd/d12/mpd__writer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/util/mpd_writer.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mpd_writer.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/mpd/util/mpd_writer.h"
    8 
    9 #include <gflags/gflags.h>
    10 #include <google/protobuf/text_format.h>
    11 #include <stdint.h>
    12 
    13 #include "packager/base/files/file_path.h"
    14 #include "packager/base/files/file_util.h"
    15 #include "packager/file/file.h"
    16 #include "packager/mpd/base/mpd_builder.h"
    17 #include "packager/mpd/base/mpd_notifier.h"
    18 #include "packager/mpd/base/mpd_utils.h"
    19 #include "packager/mpd/base/simple_mpd_notifier.h"
    20 
    21 DEFINE_bool(generate_dash_if_iop_compliant_mpd,
    22  true,
    23  "Try to generate DASH-IF IOP compliant MPD. This is best effort "
    24  "and does not guarantee compliance.");
    25 
    26 namespace shaka {
    27 
    28 namespace {
    29 
    30 // Factory that creates SimpleMpdNotifier instances.
    31 class SimpleMpdNotifierFactory : public MpdNotifierFactory {
    32  public:
    33  SimpleMpdNotifierFactory() {}
    34  ~SimpleMpdNotifierFactory() override {}
    35 
    36  std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options) override {
    37  return std::unique_ptr<MpdNotifier>(new SimpleMpdNotifier(mpd_options));
    38  }
    39 };
    40 
    41 } // namespace
    42 
    43 MpdWriter::MpdWriter() : notifier_factory_(new SimpleMpdNotifierFactory()) {}
    44 MpdWriter::~MpdWriter() {}
    45 
    46 bool MpdWriter::AddFile(const std::string& media_info_path) {
    47  std::string file_content;
    48  if (!File::ReadFileToString(media_info_path.c_str(), &file_content)) {
    49  LOG(ERROR) << "Failed to read " << media_info_path << " to string.";
    50  return false;
    51  }
    52 
    53  MediaInfo media_info;
    54  if (!::google::protobuf::TextFormat::ParseFromString(file_content,
    55  &media_info)) {
    56  LOG(ERROR) << "Failed to parse " << file_content << " to MediaInfo.";
    57  return false;
    58  }
    59 
    60  media_infos_.push_back(media_info);
    61  return true;
    62 }
    63 
    64 void MpdWriter::AddBaseUrl(const std::string& base_url) {
    65  base_urls_.push_back(base_url);
    66 }
    67 
    68 bool MpdWriter::WriteMpdToFile(const char* file_name) {
    69  CHECK(file_name);
    70  MpdOptions mpd_options;
    71  mpd_options.mpd_params.base_urls = base_urls_;
    72  mpd_options.mpd_params.mpd_output = file_name;
    73  mpd_options.mpd_params.generate_dash_if_iop_compliant_mpd =
    74  FLAGS_generate_dash_if_iop_compliant_mpd;
    75  std::unique_ptr<MpdNotifier> notifier =
    76  notifier_factory_->Create(mpd_options);
    77  if (!notifier->Init()) {
    78  LOG(ERROR) << "failed to initialize MpdNotifier.";
    79  return false;
    80  }
    81 
    82  for (const MediaInfo& media_info : media_infos_) {
    83  uint32_t unused_conatiner_id;
    84  if (!notifier->NotifyNewContainer(media_info, &unused_conatiner_id)) {
    85  LOG(ERROR) << "Failed to add MediaInfo for media file: "
    86  << media_info.media_file_name();
    87  return false;
    88  }
    89  }
    90 
    91  if (!notifier->Flush()) {
    92  LOG(ERROR) << "Failed to flush MPD notifier.";
    93  return false;
    94  }
    95  return true;
    96 }
    97 
    98 void MpdWriter::SetMpdNotifierFactoryForTest(
    99  std::unique_ptr<MpdNotifierFactory> factory) {
    100  notifier_factory_ = std::move(factory);
    101 }
    102 
    103 } // namespace shaka
    static bool ReadFileToString(const char *file_name, std::string *contents)
    Definition: file.cc:216
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/mpd/util/mpd_writer.h"
    +
    8 
    +
    9 #include <gflags/gflags.h>
    +
    10 #include <google/protobuf/text_format.h>
    +
    11 #include <stdint.h>
    +
    12 
    +
    13 #include "packager/base/files/file_path.h"
    +
    14 #include "packager/base/files/file_util.h"
    +
    15 #include "packager/file/file.h"
    +
    16 #include "packager/mpd/base/mpd_builder.h"
    +
    17 #include "packager/mpd/base/mpd_notifier.h"
    +
    18 #include "packager/mpd/base/mpd_utils.h"
    +
    19 #include "packager/mpd/base/simple_mpd_notifier.h"
    +
    20 
    +
    21 DEFINE_bool(generate_dash_if_iop_compliant_mpd,
    +
    22  true,
    +
    23  "Try to generate DASH-IF IOP compliant MPD. This is best effort "
    +
    24  "and does not guarantee compliance.");
    +
    25 
    +
    26 namespace shaka {
    +
    27 
    +
    28 namespace {
    +
    29 
    +
    30 // Factory that creates SimpleMpdNotifier instances.
    +
    31 class SimpleMpdNotifierFactory : public MpdNotifierFactory {
    +
    32  public:
    +
    33  SimpleMpdNotifierFactory() {}
    +
    34  ~SimpleMpdNotifierFactory() override {}
    +
    35 
    +
    36  std::unique_ptr<MpdNotifier> Create(const MpdOptions& mpd_options) override {
    +
    37  return std::unique_ptr<MpdNotifier>(new SimpleMpdNotifier(mpd_options));
    +
    38  }
    +
    39 };
    +
    40 
    +
    41 } // namespace
    +
    42 
    +
    43 MpdWriter::MpdWriter() : notifier_factory_(new SimpleMpdNotifierFactory()) {}
    +
    44 MpdWriter::~MpdWriter() {}
    +
    45 
    +
    46 bool MpdWriter::AddFile(const std::string& media_info_path) {
    +
    47  std::string file_content;
    +
    48  if (!File::ReadFileToString(media_info_path.c_str(), &file_content)) {
    +
    49  LOG(ERROR) << "Failed to read " << media_info_path << " to string.";
    +
    50  return false;
    +
    51  }
    +
    52 
    +
    53  MediaInfo media_info;
    +
    54  if (!::google::protobuf::TextFormat::ParseFromString(file_content,
    +
    55  &media_info)) {
    +
    56  LOG(ERROR) << "Failed to parse " << file_content << " to MediaInfo.";
    +
    57  return false;
    +
    58  }
    +
    59 
    +
    60  media_infos_.push_back(media_info);
    +
    61  return true;
    +
    62 }
    +
    63 
    +
    64 void MpdWriter::AddBaseUrl(const std::string& base_url) {
    +
    65  base_urls_.push_back(base_url);
    +
    66 }
    +
    67 
    +
    68 bool MpdWriter::WriteMpdToFile(const char* file_name) {
    +
    69  CHECK(file_name);
    +
    70  MpdOptions mpd_options;
    +
    71  mpd_options.mpd_params.base_urls = base_urls_;
    +
    72  mpd_options.mpd_params.mpd_output = file_name;
    +
    73  mpd_options.mpd_params.generate_dash_if_iop_compliant_mpd =
    +
    74  FLAGS_generate_dash_if_iop_compliant_mpd;
    +
    75  std::unique_ptr<MpdNotifier> notifier =
    +
    76  notifier_factory_->Create(mpd_options);
    +
    77  if (!notifier->Init()) {
    +
    78  LOG(ERROR) << "failed to initialize MpdNotifier.";
    +
    79  return false;
    +
    80  }
    +
    81 
    +
    82  for (const MediaInfo& media_info : media_infos_) {
    +
    83  uint32_t unused_conatiner_id;
    +
    84  if (!notifier->NotifyNewContainer(media_info, &unused_conatiner_id)) {
    +
    85  LOG(ERROR) << "Failed to add MediaInfo for media file: "
    +
    86  << media_info.media_file_name();
    +
    87  return false;
    +
    88  }
    +
    89  }
    +
    90 
    +
    91  if (!notifier->Flush()) {
    +
    92  LOG(ERROR) << "Failed to flush MPD notifier.";
    +
    93  return false;
    +
    94  }
    +
    95  return true;
    +
    96 }
    +
    97 
    +
    98 void MpdWriter::SetMpdNotifierFactoryForTest(
    +
    99  std::unique_ptr<MpdNotifierFactory> factory) {
    +
    100  notifier_factory_ = std::move(factory);
    +
    101 }
    +
    102 
    +
    103 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d13/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationSize.html b/docs/dd/d13/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationSize.html index 5bdf7d5d78..9b09761fd0 100644 --- a/docs/dd/d13/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationSize.html +++ b/docs/dd/d13/structshaka_1_1media_1_1mp4_1_1SampleAuxiliaryInformationSize.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SampleAuxiliaryInformationSize Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -127,7 +130,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 70 of file box_definitions.h.

    +

    Definition at line 71 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -155,7 +158,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 218 of file box_definitions.cc.

    +

    Definition at line 230 of file box_definitions.cc.

    @@ -166,9 +169,7 @@ Additional Inherited Members diff --git a/docs/dd/d14/job__manager_8cc_source.html b/docs/dd/d14/job__manager_8cc_source.html index 3223625a32..0b80065f86 100644 --- a/docs/dd/d14/job__manager_8cc_source.html +++ b/docs/dd/d14/job__manager_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/job_manager.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    job_manager.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/app/job_manager.h"
    8 
    9 #include "packager/app/libcrypto_threading.h"
    10 #include "packager/media/chunking/sync_point_queue.h"
    11 #include "packager/media/origin/origin_handler.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 Job::Job(const std::string& name, std::shared_ptr<OriginHandler> work)
    17  : SimpleThread(name),
    18  work_(std::move(work)),
    19  wait_(base::WaitableEvent::ResetPolicy::MANUAL,
    20  base::WaitableEvent::InitialState::NOT_SIGNALED) {
    21  DCHECK(work_);
    22 }
    23 
    24 void Job::Cancel() {
    25  work_->Cancel();
    26 }
    27 
    28 void Job::Run() {
    29  status_ = work_->Run();
    30  wait_.Signal();
    31 }
    32 
    33 JobManager::JobManager(std::unique_ptr<SyncPointQueue> sync_points)
    34  : sync_points_(std::move(sync_points)) {}
    35 
    36 void JobManager::Add(const std::string& name,
    37  std::shared_ptr<OriginHandler> handler) {
    38  // Stores Job entries for delayed construction of Job objects, to avoid
    39  // setting up SimpleThread until we know all workers can be initialized
    40  // successfully.
    41  job_entries_.push_back({name, std::move(handler)});
    42 }
    43 
    44 Status JobManager::InitializeJobs() {
    45  Status status;
    46  for (const JobEntry& job_entry : job_entries_)
    47  status.Update(job_entry.worker->Initialize());
    48  if (!status.ok())
    49  return status;
    50 
    51  // Create Job objects after successfully initialized all workers.
    52  for (const JobEntry& job_entry : job_entries_)
    53  jobs_.emplace_back(new Job(job_entry.name, std::move(job_entry.worker)));
    54  return status;
    55 }
    56 
    57 Status JobManager::RunJobs() {
    58  // We need to store the jobs and the waits separately in order to use the
    59  // |WaitMany| function. |WaitMany| takes an array of WaitableEvents but we
    60  // need to access the jobs in order to join the thread and check the status.
    61  // The indexes needs to be check in sync or else we won't be able to relate a
    62  // WaitableEvent back to the job.
    63  std::vector<Job*> active_jobs;
    64  std::vector<base::WaitableEvent*> active_waits;
    65 
    66  // Start every job and add it to the active jobs list so that we can wait
    67  // on each one.
    68  for (auto& job : jobs_) {
    69  job->Start();
    70 
    71  active_jobs.push_back(job.get());
    72  active_waits.push_back(job->wait());
    73  }
    74 
    75  // Wait for all jobs to complete or an error occurs.
    76  Status status;
    77  while (status.ok() && active_jobs.size()) {
    78  // Wait for an event to finish and then update our status so that we can
    79  // quit if something has gone wrong.
    80  const size_t done =
    81  base::WaitableEvent::WaitMany(active_waits.data(), active_waits.size());
    82  Job* job = active_jobs[done];
    83 
    84  job->Join();
    85  status.Update(job->status());
    86 
    87  // Remove the job and the wait from our tracking.
    88  active_jobs.erase(active_jobs.begin() + done);
    89  active_waits.erase(active_waits.begin() + done);
    90  }
    91 
    92  // If the main loop has exited and there are still jobs running,
    93  // we need to cancel them and clean-up.
    94  if (sync_points_)
    95  sync_points_->Cancel();
    96  for (auto& job : active_jobs) {
    97  job->Cancel();
    98  }
    99 
    100  for (auto& job : active_jobs) {
    101  job->Join();
    102  }
    103 
    104  return status;
    105 }
    106 
    107 void JobManager::CancelJobs() {
    108  if (sync_points_)
    109  sync_points_->Cancel();
    110  for (auto& job : jobs_) {
    111  job->Cancel();
    112  }
    113 }
    114 
    115 } // namespace media
    116 } // namespace shaka
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/app/job_manager.h"
    +
    8 
    +
    9 #include "packager/app/libcrypto_threading.h"
    +
    10 #include "packager/media/chunking/sync_point_queue.h"
    +
    11 #include "packager/media/origin/origin_handler.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 Job::Job(const std::string& name, std::shared_ptr<OriginHandler> work)
    +
    17  : SimpleThread(name),
    +
    18  work_(std::move(work)),
    +
    19  wait_(base::WaitableEvent::ResetPolicy::MANUAL,
    +
    20  base::WaitableEvent::InitialState::NOT_SIGNALED) {
    +
    21  DCHECK(work_);
    +
    22 }
    +
    23 
    +
    24 void Job::Cancel() {
    +
    25  work_->Cancel();
    +
    26 }
    +
    27 
    +
    28 void Job::Run() {
    +
    29  status_ = work_->Run();
    +
    30  wait_.Signal();
    +
    31 }
    +
    32 
    +
    33 JobManager::JobManager(std::unique_ptr<SyncPointQueue> sync_points)
    +
    34  : sync_points_(std::move(sync_points)) {}
    +
    35 
    +
    36 void JobManager::Add(const std::string& name,
    +
    37  std::shared_ptr<OriginHandler> handler) {
    +
    38  // Stores Job entries for delayed construction of Job objects, to avoid
    +
    39  // setting up SimpleThread until we know all workers can be initialized
    +
    40  // successfully.
    +
    41  job_entries_.push_back({name, std::move(handler)});
    +
    42 }
    +
    43 
    +
    44 Status JobManager::InitializeJobs() {
    +
    45  Status status;
    +
    46  for (const JobEntry& job_entry : job_entries_)
    +
    47  status.Update(job_entry.worker->Initialize());
    +
    48  if (!status.ok())
    +
    49  return status;
    +
    50 
    +
    51  // Create Job objects after successfully initialized all workers.
    +
    52  for (const JobEntry& job_entry : job_entries_)
    +
    53  jobs_.emplace_back(new Job(job_entry.name, std::move(job_entry.worker)));
    +
    54  return status;
    +
    55 }
    +
    56 
    +
    57 Status JobManager::RunJobs() {
    +
    58  // We need to store the jobs and the waits separately in order to use the
    +
    59  // |WaitMany| function. |WaitMany| takes an array of WaitableEvents but we
    +
    60  // need to access the jobs in order to join the thread and check the status.
    +
    61  // The indexes needs to be check in sync or else we won't be able to relate a
    +
    62  // WaitableEvent back to the job.
    +
    63  std::vector<Job*> active_jobs;
    +
    64  std::vector<base::WaitableEvent*> active_waits;
    +
    65 
    +
    66  // Start every job and add it to the active jobs list so that we can wait
    +
    67  // on each one.
    +
    68  for (auto& job : jobs_) {
    +
    69  job->Start();
    +
    70 
    +
    71  active_jobs.push_back(job.get());
    +
    72  active_waits.push_back(job->wait());
    +
    73  }
    +
    74 
    +
    75  // Wait for all jobs to complete or an error occurs.
    +
    76  Status status;
    +
    77  while (status.ok() && active_jobs.size()) {
    +
    78  // Wait for an event to finish and then update our status so that we can
    +
    79  // quit if something has gone wrong.
    +
    80  const size_t done =
    +
    81  base::WaitableEvent::WaitMany(active_waits.data(), active_waits.size());
    +
    82  Job* job = active_jobs[done];
    +
    83 
    +
    84  job->Join();
    +
    85  status.Update(job->status());
    +
    86 
    +
    87  // Remove the job and the wait from our tracking.
    +
    88  active_jobs.erase(active_jobs.begin() + done);
    +
    89  active_waits.erase(active_waits.begin() + done);
    +
    90  }
    +
    91 
    +
    92  // If the main loop has exited and there are still jobs running,
    +
    93  // we need to cancel them and clean-up.
    +
    94  if (sync_points_)
    +
    95  sync_points_->Cancel();
    +
    96  for (auto& job : active_jobs) {
    +
    97  job->Cancel();
    +
    98  }
    +
    99 
    +
    100  for (auto& job : active_jobs) {
    +
    101  job->Join();
    +
    102  }
    +
    103 
    +
    104  return status;
    +
    105 }
    +
    106 
    +
    107 void JobManager::CancelJobs() {
    +
    108  if (sync_points_)
    +
    109  sync_points_->Cancel();
    +
    110  for (auto& job : jobs_) {
    +
    111  job->Cancel();
    +
    112  }
    +
    113 }
    +
    114 
    +
    115 } // namespace media
    +
    116 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d17/classshaka_1_1media_1_1Demuxer.html b/docs/dd/d17/classshaka_1_1media_1_1Demuxer.html index 2ab6c1240d..fd2eedd482 100644 --- a/docs/dd/d17/classshaka_1_1media_1_1Demuxer.html +++ b/docs/dd/d17/classshaka_1_1media_1_1Demuxer.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::Demuxer Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::OriginHandler shaka::media::MediaHandler - -
    + + @@ -184,9 +187,9 @@ const std::map< size_t, std::pair< std::shared_ptr< - - + +

    Public Member Functions

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     

    Detailed Description

    Demuxer is responsible for extracting elementary stream samples from a media file, e.g. an ISO BMFF file.

    @@ -218,12 +221,12 @@ static Status
    Parameters
    - +
    file_namespecifies the input source. It uses prefix matching to create a proper File object. The user can extend File to support a custom File object with its own prefix.
    file_namespecifies the input source. It uses prefix matching to create a proper File object. The user can extend File to support a custom File object with its own prefix.
    -

    Definition at line 75 of file demuxer.cc.

    +

    Definition at line 76 of file demuxer.cc.

    @@ -254,7 +257,7 @@ static Status

    Implements shaka::media::OriginHandler.

    -

    Definition at line 128 of file demuxer.cc.

    +

    Definition at line 129 of file demuxer.cc.

    @@ -373,7 +376,7 @@ static Status

    Implements shaka::media::OriginHandler.

    -

    Definition at line 87 of file demuxer.cc.

    +

    Definition at line 88 of file demuxer.cc.

    @@ -410,7 +413,7 @@ static Status -

    Definition at line 132 of file demuxer.cc.

    +

    Definition at line 133 of file demuxer.cc.

    @@ -429,14 +432,14 @@ static Status
    -

    Set the KeySource for media decryption.

    Parameters
    +

    Set the KeySource for media decryption.

    Parameters
    key_sourcepoints to the source of decryption keys. The key source must support fetching of keys for the type of media being demuxed.
    -

    Definition at line 83 of file demuxer.cc.

    +

    Definition at line 84 of file demuxer.cc.

    @@ -473,7 +476,7 @@ static Status -

    Definition at line 142 of file demuxer.cc.

    +

    Definition at line 143 of file demuxer.cc.

    @@ -484,9 +487,7 @@ static Status diff --git a/docs/dd/d18/av1__parser_8h_source.html b/docs/dd/d18/av1__parser_8h_source.html index 3f6a8cec84..869819ae39 100644 --- a/docs/dd/d18/av1__parser_8h_source.html +++ b/docs/dd/d18/av1__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/av1_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    av1_parser.h
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_AV1_PARSER_H_
    8 #define PACKAGER_MEDIA_CODECS_AV1_PARSER_H_
    9 
    10 #include <stdint.h>
    11 #include <stdlib.h>
    12 
    13 #include <vector>
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    18 class BitReader;
    19 
    22 class AV1Parser {
    23  public:
    24  struct Tile {
    25  size_t start_offset_in_bytes;
    26  size_t size_in_bytes;
    27  };
    28 
    29  AV1Parser();
    30  virtual ~AV1Parser();
    31 
    40  virtual bool Parse(const uint8_t* data,
    41  size_t data_size,
    42  std::vector<Tile>* tiles);
    43 
    44  private:
    45  AV1Parser(const AV1Parser&) = delete;
    46  AV1Parser& operator=(const AV1Parser&) = delete;
    47 
    48  // The structure names and the method names match the names in the spec but in
    49  // CamelCase.
    50  // Not all fields are populated. In particular, fields not referenced and not
    51  // needed to parse other parts of the bitstream are not populated.
    52 
    53  struct ObuExtensionHeader {
    54  int temporal_id = 0;
    55  int spatial_id = 0;
    56  };
    57 
    58  struct ObuHeader {
    59  int obu_type = 0;
    60  bool obu_has_size_field = false;
    61  ObuExtensionHeader extension_header;
    62  };
    63 
    64  struct ColorConfig {
    65  int bit_depth = 0;
    66  bool mono_chrome = false;
    67  int num_planes = 0;
    68  int color_primaries = 0;
    69  int transfer_chracteristics = 0;
    70  int matrix_coefficients = 0;
    71  bool color_range = false;
    72  bool subsampling_x = false;
    73  bool subsampling_y = false;
    74  int chroma_sampling_position = 0;
    75  bool separate_uv_delta_q = false;
    76  };
    77 
    78  struct TimingInfo {
    79  bool equal_picture_interval = false;
    80  };
    81 
    82  struct DecoderModelInfo {
    83  int buffer_delay_length_minus_1 = 0;
    84  int buffer_removal_time_length_minus_1 = 0;
    85  int frame_presentation_time_length_minus_1 = 0;
    86  };
    87 
    88  struct SequenceHeaderObu {
    89  int seq_profile = 0;
    90  bool reduced_still_picture_header = false;
    91 
    92  TimingInfo timing_info;
    93  bool decoder_model_info_present_flag = false;
    94  DecoderModelInfo decoder_model_info;
    95 
    96  int operating_points_cnt_minus_1 = 0;
    97  static constexpr int kMaxOperatingPointsCount = 1 << 5;
    98  int operating_point_idc[kMaxOperatingPointsCount] = {};
    99  bool decoder_model_present_for_this_op[kMaxOperatingPointsCount] = {};
    100 
    101  int frame_width_bits_minus_1 = 0;
    102  int frame_height_bits_minus_1 = 0;
    103  int max_frame_width_minus_1 = 0;
    104  int max_frame_height_minus_1 = 0;
    105 
    106  bool frame_id_numbers_present_flag = false;
    107  int delta_frame_id_length_minus_2 = 0;
    108  int additional_frame_id_length_minus_1 = 0;
    109 
    110  bool use_128x128_superblock = false;
    111 
    112  bool enable_warped_motion = false;
    113  bool enable_order_hint = false;
    114  bool enable_ref_frame_mvs = false;
    115  int order_hint_bits = 0;
    116 
    117  int seq_force_screen_content_tools = 0;
    118  int seq_force_integer_mv = 0;
    119 
    120  bool enable_superres = false;
    121  bool enable_cdef = false;
    122  bool enable_restoration = false;
    123  ColorConfig color_config;
    124  bool film_grain_params_present = false;
    125  };
    126 
    127  struct TileInfo {
    128  int tile_cols = 0;
    129  int tile_rows = 0;
    130  int tile_cols_log2 = 0;
    131  int tile_rows_log2 = 0;
    132  int tile_size_bytes = 0;
    133  };
    134 
    135  struct QuantizationParams {
    136  int base_q_idx = 0;
    137  int delta_qydc = 0;
    138  int delta_quac = 0;
    139  int delta_qudc = 0;
    140  int delta_qvac = 0;
    141  int delta_qvdc = 0;
    142  };
    143 
    144  static constexpr int kMaxSegments = 8;
    145  static constexpr int kSegLvlMax = 8;
    146  struct SegmentationParams {
    147  bool segmentation_enabled = false;
    148  bool feature_enabled[kMaxSegments][kSegLvlMax] = {};
    149  int feature_data[kMaxSegments][kSegLvlMax] = {};
    150  };
    151 
    152  static constexpr int kRefsPerFrame = 7;
    153  struct FrameHeaderObu {
    154  bool seen_frame_header = false;
    155 
    156  bool show_existing_frame = false;
    157  int frame_to_show_map_idx = 0;
    158 
    159  int frame_type = 0;
    160  int refresh_frame_flags = 0;
    161 
    162  int ref_frame_idx[kRefsPerFrame] = {};
    163 
    164  int order_hint = 0;
    165 
    166  int frame_width = 0;
    167  int frame_height = 0;
    168  int upscaled_width = 0;
    169  int render_width = 0;
    170  int render_height = 0;
    171 
    172  int mi_cols = 0;
    173  int mi_rows = 0;
    174 
    175  TileInfo tile_info;
    176  QuantizationParams quantization_params;
    177  SegmentationParams segmentation_params;
    178  };
    179 
    180  struct ReferenceFrame {
    181  int frame_type = 0;
    182  int order_hint = 0;
    183 
    184  int frame_width = 0;
    185  int frame_height = 0;
    186  int upscaled_width = 0;
    187  int render_width = 0;
    188  int render_height = 0;
    189 
    190  int mi_cols = 0;
    191  int mi_rows = 0;
    192 
    193  int bit_depth = 0;
    194  bool subsampling_x = false;
    195  bool subsampling_y = false;
    196  };
    197 
    198  bool ParseOpenBitstreamUnit(BitReader* reader, std::vector<Tile>* tiles);
    199  bool ParseObuHeader(BitReader* reader, ObuHeader* obu_header);
    200  bool ParseObuExtensionHeader(BitReader* reader,
    201  ObuExtensionHeader* obu_extension_header);
    202  bool ParseTrailingBits(size_t nb_bits, BitReader* reader);
    203  bool ByteAlignment(BitReader* reader);
    204 
    205  // SequenceHeader OBU and children structures.
    206  bool ParseSequenceHeaderObu(BitReader* reader);
    207  bool ParseColorConfig(BitReader* reader);
    208  bool ParseTimingInfo(BitReader* reader);
    209  bool ParseDecoderModelInfo(BitReader* reader);
    210  bool SkipOperatingParametersInfo(BitReader* reader);
    211 
    212  // FrameHeader OBU and children structures.
    213  bool ParseFrameHeaderObu(const ObuHeader& obu_header, BitReader* reader);
    214  bool ParseUncompressedHeader(const ObuHeader& obu_header, BitReader* reader);
    215  int GetRelativeDist(int a, int b);
    216  bool ParseFrameSize(bool frame_size_override_flag, BitReader* reader);
    217  bool ParseRenderSize(BitReader* reader);
    218  bool ParseFrameSizeWithRefs(bool frame_size_override_flag, BitReader* reader);
    219  bool ParseSuperresParams(BitReader* reader);
    220  void ComputeImageSize();
    221  bool SkipInterpolationFilter(BitReader* reader);
    222  bool ParseLoopFilterParams(bool coded_lossless,
    223  bool allow_intrabc,
    224  BitReader* reader);
    225  bool ParseTileInfo(BitReader* reader);
    226  bool ParseQuantizationParams(BitReader* reader);
    227  bool ReadDeltaQ(BitReader* reader, int* delta_q);
    228  bool ParseSegmentationParams(int primary_ref_frame, BitReader* reader);
    229  bool SkipDeltaQParams(BitReader* reader, bool* delta_q_present);
    230  bool SkipDeltaLfParams(bool delta_q_present,
    231  bool allow_intrabc,
    232  BitReader* reader);
    233  bool ParseCdefParams(bool coded_lossless,
    234  bool allow_intrabc,
    235  BitReader* reader);
    236  bool ParseLrParams(bool all_lossless, bool allow_intrabc, BitReader* reader);
    237  bool SkipTxMode(bool coded_lossless, BitReader* reader);
    238  bool SkipSkipModeParams(bool frame_is_intra,
    239  bool reference_select,
    240  BitReader* reader);
    241  bool ParseFrameReferenceMode(bool frame_is_intra,
    242  BitReader* reader,
    243  bool* reference_select);
    244  bool SkipGlobalMotionParams(bool frame_is_intra,
    245  bool allow_high_precision_mv,
    246  BitReader* reader);
    247  bool SkipGlobalParam(int type,
    248  int ref,
    249  int idx,
    250  bool allow_high_precision_mv,
    251  BitReader* reader);
    252  bool SkipDecodeSignedSubexpWithRef(int low, int high, BitReader* reader);
    253  bool SkipDecodeUnsignedSubexpWithRef(int mx, BitReader* reader);
    254  bool SkipDecodeSubexp(int num_syms, BitReader* reader);
    255  bool SkipFilmGrainParams(bool show_frame,
    256  bool showable_frame,
    257  BitReader* reader);
    258  bool SkipTemporalPointInfo(BitReader* reader);
    259 
    260  // Frame OBU.
    261  bool ParseFrameObu(const ObuHeader& obu_header,
    262  size_t size,
    263  BitReader* reader,
    264  std::vector<Tile>* tiles);
    265 
    266  // TileGroup OBU.
    267  bool ParseTileGroupObu(size_t size,
    268  BitReader* reader,
    269  std::vector<Tile>* tiles);
    270  bool SegFeatureActiveIdx(int idx, int feature);
    271 
    272  // Decoding process related helper functions.
    273  // We do not care about decoding itself, but we need to take care of reference
    274  // frame states.
    275  void DecodeFrameWrapup();
    276  bool SetFrameRefs(int last_frame_idx, int gold_frame_idx);
    277  int GetQIndex(bool ignore_delta_q, int segment_id);
    278 
    279  SequenceHeaderObu sequence_header_;
    280  FrameHeaderObu frame_header_;
    281  static constexpr int kNumRefFrames = 8;
    282  ReferenceFrame reference_frames_[kNumRefFrames];
    283 };
    284 
    285 } // namespace media
    286 } // namespace shaka
    287 
    288 #endif // PACKAGER_MEDIA_CODECS_AV1_PARSER_H_
    A class to read bit streams.
    Definition: bit_reader.h:17
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    virtual bool Parse(const uint8_t *data, size_t data_size, std::vector< Tile > *tiles)
    Definition: av1_parser.cc:255
    +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_AV1_PARSER_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_AV1_PARSER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <stdlib.h>
    +
    12 
    +
    13 #include <vector>
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    18 class BitReader;
    +
    19 
    +
    22 class AV1Parser {
    +
    23  public:
    +
    24  struct Tile {
    +
    25  size_t start_offset_in_bytes;
    +
    26  size_t size_in_bytes;
    +
    27  };
    +
    28 
    +
    29  AV1Parser();
    +
    30  virtual ~AV1Parser();
    +
    31 
    +
    40  virtual bool Parse(const uint8_t* data,
    +
    41  size_t data_size,
    +
    42  std::vector<Tile>* tiles);
    +
    43 
    +
    44  private:
    +
    45  AV1Parser(const AV1Parser&) = delete;
    +
    46  AV1Parser& operator=(const AV1Parser&) = delete;
    +
    47 
    +
    48  // The structure names and the method names match the names in the spec but in
    +
    49  // CamelCase.
    +
    50  // Not all fields are populated. In particular, fields not referenced and not
    +
    51  // needed to parse other parts of the bitstream are not populated.
    +
    52 
    +
    53  struct ObuExtensionHeader {
    +
    54  int temporal_id = 0;
    +
    55  int spatial_id = 0;
    +
    56  };
    +
    57 
    +
    58  struct ObuHeader {
    +
    59  int obu_type = 0;
    +
    60  bool obu_has_size_field = false;
    +
    61  ObuExtensionHeader extension_header;
    +
    62  };
    +
    63 
    +
    64  struct ColorConfig {
    +
    65  int bit_depth = 0;
    +
    66  bool mono_chrome = false;
    +
    67  int num_planes = 0;
    +
    68  int color_primaries = 0;
    +
    69  int transfer_chracteristics = 0;
    +
    70  int matrix_coefficients = 0;
    +
    71  bool color_range = false;
    +
    72  bool subsampling_x = false;
    +
    73  bool subsampling_y = false;
    +
    74  int chroma_sampling_position = 0;
    +
    75  bool separate_uv_delta_q = false;
    +
    76  };
    +
    77 
    +
    78  struct TimingInfo {
    +
    79  bool equal_picture_interval = false;
    +
    80  };
    +
    81 
    +
    82  struct DecoderModelInfo {
    +
    83  int buffer_delay_length_minus_1 = 0;
    +
    84  int buffer_removal_time_length_minus_1 = 0;
    +
    85  int frame_presentation_time_length_minus_1 = 0;
    +
    86  };
    +
    87 
    +
    88  struct SequenceHeaderObu {
    +
    89  int seq_profile = 0;
    +
    90  bool reduced_still_picture_header = false;
    +
    91 
    +
    92  TimingInfo timing_info;
    +
    93  bool decoder_model_info_present_flag = false;
    +
    94  DecoderModelInfo decoder_model_info;
    +
    95 
    +
    96  int operating_points_cnt_minus_1 = 0;
    +
    97  static constexpr int kMaxOperatingPointsCount = 1 << 5;
    +
    98  int operating_point_idc[kMaxOperatingPointsCount] = {};
    +
    99  bool decoder_model_present_for_this_op[kMaxOperatingPointsCount] = {};
    +
    100 
    +
    101  int frame_width_bits_minus_1 = 0;
    +
    102  int frame_height_bits_minus_1 = 0;
    +
    103  int max_frame_width_minus_1 = 0;
    +
    104  int max_frame_height_minus_1 = 0;
    +
    105 
    +
    106  bool frame_id_numbers_present_flag = false;
    +
    107  int delta_frame_id_length_minus_2 = 0;
    +
    108  int additional_frame_id_length_minus_1 = 0;
    +
    109 
    +
    110  bool use_128x128_superblock = false;
    +
    111 
    +
    112  bool enable_warped_motion = false;
    +
    113  bool enable_order_hint = false;
    +
    114  bool enable_ref_frame_mvs = false;
    +
    115  int order_hint_bits = 0;
    +
    116 
    +
    117  int seq_force_screen_content_tools = 0;
    +
    118  int seq_force_integer_mv = 0;
    +
    119 
    +
    120  bool enable_superres = false;
    +
    121  bool enable_cdef = false;
    +
    122  bool enable_restoration = false;
    +
    123  ColorConfig color_config;
    +
    124  bool film_grain_params_present = false;
    +
    125  };
    +
    126 
    +
    127  struct TileInfo {
    +
    128  int tile_cols = 0;
    +
    129  int tile_rows = 0;
    +
    130  int tile_cols_log2 = 0;
    +
    131  int tile_rows_log2 = 0;
    +
    132  int tile_size_bytes = 0;
    +
    133  };
    +
    134 
    +
    135  struct QuantizationParams {
    +
    136  int base_q_idx = 0;
    +
    137  int delta_qydc = 0;
    +
    138  int delta_quac = 0;
    +
    139  int delta_qudc = 0;
    +
    140  int delta_qvac = 0;
    +
    141  int delta_qvdc = 0;
    +
    142  };
    +
    143 
    +
    144  static constexpr int kMaxSegments = 8;
    +
    145  static constexpr int kSegLvlMax = 8;
    +
    146  struct SegmentationParams {
    +
    147  bool segmentation_enabled = false;
    +
    148  bool feature_enabled[kMaxSegments][kSegLvlMax] = {};
    +
    149  int feature_data[kMaxSegments][kSegLvlMax] = {};
    +
    150  };
    +
    151 
    +
    152  static constexpr int kRefsPerFrame = 7;
    +
    153  struct FrameHeaderObu {
    +
    154  bool seen_frame_header = false;
    +
    155 
    +
    156  bool show_existing_frame = false;
    +
    157  int frame_to_show_map_idx = 0;
    +
    158 
    +
    159  int frame_type = 0;
    +
    160  int refresh_frame_flags = 0;
    +
    161 
    +
    162  int ref_frame_idx[kRefsPerFrame] = {};
    +
    163 
    +
    164  int order_hint = 0;
    +
    165 
    +
    166  int frame_width = 0;
    +
    167  int frame_height = 0;
    +
    168  int upscaled_width = 0;
    +
    169  int render_width = 0;
    +
    170  int render_height = 0;
    +
    171 
    +
    172  int mi_cols = 0;
    +
    173  int mi_rows = 0;
    +
    174 
    +
    175  TileInfo tile_info;
    +
    176  QuantizationParams quantization_params;
    +
    177  SegmentationParams segmentation_params;
    +
    178  };
    +
    179 
    +
    180  struct ReferenceFrame {
    +
    181  int frame_type = 0;
    +
    182  int order_hint = 0;
    +
    183 
    +
    184  int frame_width = 0;
    +
    185  int frame_height = 0;
    +
    186  int upscaled_width = 0;
    +
    187  int render_width = 0;
    +
    188  int render_height = 0;
    +
    189 
    +
    190  int mi_cols = 0;
    +
    191  int mi_rows = 0;
    +
    192 
    +
    193  int bit_depth = 0;
    +
    194  bool subsampling_x = false;
    +
    195  bool subsampling_y = false;
    +
    196  };
    +
    197 
    +
    198  bool ParseOpenBitstreamUnit(BitReader* reader, std::vector<Tile>* tiles);
    +
    199  bool ParseObuHeader(BitReader* reader, ObuHeader* obu_header);
    +
    200  bool ParseObuExtensionHeader(BitReader* reader,
    +
    201  ObuExtensionHeader* obu_extension_header);
    +
    202  bool ParseTrailingBits(size_t nb_bits, BitReader* reader);
    +
    203  bool ByteAlignment(BitReader* reader);
    +
    204 
    +
    205  // SequenceHeader OBU and children structures.
    +
    206  bool ParseSequenceHeaderObu(BitReader* reader);
    +
    207  bool ParseColorConfig(BitReader* reader);
    +
    208  bool ParseTimingInfo(BitReader* reader);
    +
    209  bool ParseDecoderModelInfo(BitReader* reader);
    +
    210  bool SkipOperatingParametersInfo(BitReader* reader);
    +
    211 
    +
    212  // FrameHeader OBU and children structures.
    +
    213  bool ParseFrameHeaderObu(const ObuHeader& obu_header, BitReader* reader);
    +
    214  bool ParseUncompressedHeader(const ObuHeader& obu_header, BitReader* reader);
    +
    215  int GetRelativeDist(int a, int b);
    +
    216  bool ParseFrameSize(bool frame_size_override_flag, BitReader* reader);
    +
    217  bool ParseRenderSize(BitReader* reader);
    +
    218  bool ParseFrameSizeWithRefs(bool frame_size_override_flag, BitReader* reader);
    +
    219  bool ParseSuperresParams(BitReader* reader);
    +
    220  void ComputeImageSize();
    +
    221  bool SkipInterpolationFilter(BitReader* reader);
    +
    222  bool ParseLoopFilterParams(bool coded_lossless,
    +
    223  bool allow_intrabc,
    +
    224  BitReader* reader);
    +
    225  bool ParseTileInfo(BitReader* reader);
    +
    226  bool ParseQuantizationParams(BitReader* reader);
    +
    227  bool ReadDeltaQ(BitReader* reader, int* delta_q);
    +
    228  bool ParseSegmentationParams(int primary_ref_frame, BitReader* reader);
    +
    229  bool SkipDeltaQParams(BitReader* reader, bool* delta_q_present);
    +
    230  bool SkipDeltaLfParams(bool delta_q_present,
    +
    231  bool allow_intrabc,
    +
    232  BitReader* reader);
    +
    233  bool ParseCdefParams(bool coded_lossless,
    +
    234  bool allow_intrabc,
    +
    235  BitReader* reader);
    +
    236  bool ParseLrParams(bool all_lossless, bool allow_intrabc, BitReader* reader);
    +
    237  bool SkipTxMode(bool coded_lossless, BitReader* reader);
    +
    238  bool SkipSkipModeParams(bool frame_is_intra,
    +
    239  bool reference_select,
    +
    240  BitReader* reader);
    +
    241  bool ParseFrameReferenceMode(bool frame_is_intra,
    +
    242  BitReader* reader,
    +
    243  bool* reference_select);
    +
    244  bool SkipGlobalMotionParams(bool frame_is_intra,
    +
    245  bool allow_high_precision_mv,
    +
    246  BitReader* reader);
    +
    247  bool SkipGlobalParam(int type,
    +
    248  int ref,
    +
    249  int idx,
    +
    250  bool allow_high_precision_mv,
    +
    251  BitReader* reader);
    +
    252  bool SkipDecodeSignedSubexpWithRef(int low, int high, BitReader* reader);
    +
    253  bool SkipDecodeUnsignedSubexpWithRef(int mx, BitReader* reader);
    +
    254  bool SkipDecodeSubexp(int num_syms, BitReader* reader);
    +
    255  bool SkipFilmGrainParams(bool show_frame,
    +
    256  bool showable_frame,
    +
    257  BitReader* reader);
    +
    258  bool SkipTemporalPointInfo(BitReader* reader);
    +
    259 
    +
    260  // Frame OBU.
    +
    261  bool ParseFrameObu(const ObuHeader& obu_header,
    +
    262  size_t size,
    +
    263  BitReader* reader,
    +
    264  std::vector<Tile>* tiles);
    +
    265 
    +
    266  // TileGroup OBU.
    +
    267  bool ParseTileGroupObu(size_t size,
    +
    268  BitReader* reader,
    +
    269  std::vector<Tile>* tiles);
    +
    270  bool SegFeatureActiveIdx(int idx, int feature);
    +
    271 
    +
    272  // Decoding process related helper functions.
    +
    273  // We do not care about decoding itself, but we need to take care of reference
    +
    274  // frame states.
    +
    275  void DecodeFrameWrapup();
    +
    276  bool SetFrameRefs(int last_frame_idx, int gold_frame_idx);
    +
    277  int GetQIndex(bool ignore_delta_q, int segment_id);
    +
    278 
    +
    279  SequenceHeaderObu sequence_header_;
    +
    280  FrameHeaderObu frame_header_;
    +
    281  static constexpr int kNumRefFrames = 8;
    +
    282  ReferenceFrame reference_frames_[kNumRefFrames];
    +
    283 };
    +
    284 
    +
    285 } // namespace media
    +
    286 } // namespace shaka
    +
    287 
    +
    288 #endif // PACKAGER_MEDIA_CODECS_AV1_PARSER_H_
    + +
    virtual bool Parse(const uint8_t *data, size_t data_size, std::vector< Tile > *tiles)
    Definition: av1_parser.cc:255
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/dd/d19/video__stream__info_8cc_source.html b/docs/dd/d19/video__stream__info_8cc_source.html index 7f127d1ffd..3b3693cf32 100644 --- a/docs/dd/d19/video__stream__info_8cc_source.html +++ b/docs/dd/d19/video__stream__info_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/video_stream_info.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    video_stream_info.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/video_stream_info.h"
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/base/strings/string_number_conversions.h"
    11 #include "packager/base/strings/string_util.h"
    12 #include "packager/base/strings/stringprintf.h"
    13 #include "packager/media/base/limits.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    18 namespace {
    19 std::string VideoCodecToString(Codec codec) {
    20  switch (codec) {
    21  case kCodecAV1:
    22  return "AV1";
    23  case kCodecH264:
    24  return "H264";
    25  case kCodecH265:
    26  return "H265";
    27  case kCodecH265DolbyVision:
    28  return "H265 Dolby Vision";
    29  case kCodecVP8:
    30  return "VP8";
    31  case kCodecVP9:
    32  return "VP9";
    33  default:
    34  NOTIMPLEMENTED() << "Unknown Video Codec: " << codec;
    35  return "UnknownCodec";
    36  }
    37 }
    38 
    39 } // namespace
    40 
    41 VideoStreamInfo::VideoStreamInfo(int track_id,
    42  uint32_t time_scale,
    43  uint64_t duration,
    44  Codec codec,
    45  H26xStreamFormat h26x_stream_format,
    46  const std::string& codec_string,
    47  const uint8_t* codec_config,
    48  size_t codec_config_size,
    49  uint16_t width,
    50  uint16_t height,
    51  uint32_t pixel_width,
    52  uint32_t pixel_height,
    53  uint8_t transfer_characteristics,
    54  uint32_t trick_play_factor,
    55  uint8_t nalu_length_size,
    56  const std::string& language,
    57  bool is_encrypted)
    58  : StreamInfo(kStreamVideo,
    59  track_id,
    60  time_scale,
    61  duration,
    62  codec,
    63  codec_string,
    64  codec_config,
    65  codec_config_size,
    66  language,
    67  is_encrypted),
    68  h26x_stream_format_(h26x_stream_format),
    69  width_(width),
    70  height_(height),
    71  pixel_width_(pixel_width),
    72  pixel_height_(pixel_height),
    73  transfer_characteristics_(transfer_characteristics),
    74  trick_play_factor_(trick_play_factor),
    75  nalu_length_size_(nalu_length_size) {}
    76 
    77 VideoStreamInfo::~VideoStreamInfo() {}
    78 
    80  return codec() != kUnknownCodec && width_ > 0 &&
    81  width_ <= limits::kMaxDimension && height_ > 0 &&
    82  height_ <= limits::kMaxDimension &&
    83  (nalu_length_size_ <= 2 || nalu_length_size_ == 4);
    84 }
    85 
    86 std::string VideoStreamInfo::ToString() const {
    87  return base::StringPrintf(
    88  "%s codec: %s\n width: %d\n height: %d\n pixel_aspect_ratio: %d:%d\n "
    89  "trick_play_factor: %d\n nalu_length_size: %d\n",
    90  StreamInfo::ToString().c_str(), VideoCodecToString(codec()).c_str(),
    91  width_, height_, pixel_width_, pixel_height_, trick_play_factor_,
    92  nalu_length_size_);
    93 }
    94 
    95 std::unique_ptr<StreamInfo> VideoStreamInfo::Clone() const {
    96  return std::unique_ptr<StreamInfo>(new VideoStreamInfo(*this));
    97 }
    98 
    99 } // namespace media
    100 } // namespace shaka
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    bool IsValidConfig() const override
    -
    std::unique_ptr< StreamInfo > Clone() const override
    -
    virtual std::string ToString() const
    Definition: stream_info.cc:58
    -
    All the methods that are virtual are virtual for mocking.
    -
    Holds video stream information.
    -
    std::string ToString() const override
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/video_stream_info.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/base/strings/string_number_conversions.h"
    +
    11 #include "packager/base/strings/string_util.h"
    +
    12 #include "packager/base/strings/stringprintf.h"
    +
    13 #include "packager/media/base/limits.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    18 namespace {
    +
    19 std::string VideoCodecToString(Codec codec) {
    +
    20  switch (codec) {
    +
    21  case kCodecAV1:
    +
    22  return "AV1";
    +
    23  case kCodecH264:
    +
    24  return "H264";
    +
    25  case kCodecH265:
    +
    26  return "H265";
    +
    27  case kCodecH265DolbyVision:
    +
    28  return "H265 Dolby Vision";
    +
    29  case kCodecVP8:
    +
    30  return "VP8";
    +
    31  case kCodecVP9:
    +
    32  return "VP9";
    +
    33  default:
    +
    34  NOTIMPLEMENTED() << "Unknown Video Codec: " << codec;
    +
    35  return "UnknownCodec";
    +
    36  }
    +
    37 }
    +
    38 
    +
    39 } // namespace
    +
    40 
    +
    41 VideoStreamInfo::VideoStreamInfo(int track_id,
    +
    42  uint32_t time_scale,
    +
    43  uint64_t duration,
    +
    44  Codec codec,
    +
    45  H26xStreamFormat h26x_stream_format,
    +
    46  const std::string& codec_string,
    +
    47  const uint8_t* codec_config,
    +
    48  size_t codec_config_size,
    +
    49  uint16_t width,
    +
    50  uint16_t height,
    +
    51  uint32_t pixel_width,
    +
    52  uint32_t pixel_height,
    +
    53  uint8_t transfer_characteristics,
    +
    54  uint32_t trick_play_factor,
    +
    55  uint8_t nalu_length_size,
    +
    56  const std::string& language,
    +
    57  bool is_encrypted)
    +
    58  : StreamInfo(kStreamVideo,
    +
    59  track_id,
    +
    60  time_scale,
    +
    61  duration,
    +
    62  codec,
    +
    63  codec_string,
    +
    64  codec_config,
    +
    65  codec_config_size,
    +
    66  language,
    +
    67  is_encrypted),
    +
    68  h26x_stream_format_(h26x_stream_format),
    +
    69  width_(width),
    +
    70  height_(height),
    +
    71  pixel_width_(pixel_width),
    +
    72  pixel_height_(pixel_height),
    +
    73  transfer_characteristics_(transfer_characteristics),
    +
    74  trick_play_factor_(trick_play_factor),
    +
    75  nalu_length_size_(nalu_length_size) {}
    +
    76 
    +
    77 VideoStreamInfo::~VideoStreamInfo() {}
    +
    78 
    + +
    80  return codec() != kUnknownCodec && width_ > 0 &&
    +
    81  width_ <= limits::kMaxDimension && height_ > 0 &&
    +
    82  height_ <= limits::kMaxDimension &&
    +
    83  (nalu_length_size_ <= 2 || nalu_length_size_ == 4);
    +
    84 }
    +
    85 
    +
    86 std::string VideoStreamInfo::ToString() const {
    +
    87  return base::StringPrintf(
    +
    88  "%s codec: %s\n width: %d\n height: %d\n pixel_aspect_ratio: %d:%d\n "
    +
    89  "trick_play_factor: %d\n nalu_length_size: %d\n",
    +
    90  StreamInfo::ToString().c_str(), VideoCodecToString(codec()).c_str(),
    +
    91  width_, height_, pixel_width_, pixel_height_, trick_play_factor_,
    +
    92  nalu_length_size_);
    +
    93 }
    +
    94 
    +
    95 std::unique_ptr<StreamInfo> VideoStreamInfo::Clone() const {
    +
    96  return std::unique_ptr<StreamInfo>(new VideoStreamInfo(*this));
    +
    97 }
    +
    98 
    +
    99 } // namespace media
    +
    100 } // namespace shaka
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    virtual std::string ToString() const
    Definition: stream_info.cc:59
    +
    Holds video stream information.
    +
    std::unique_ptr< StreamInfo > Clone() const override
    +
    bool IsValidConfig() const override
    +
    std::string ToString() const override
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d1c/classshaka_1_1hls_1_1MediaPlaylist.html b/docs/dd/d1c/classshaka_1_1hls_1_1MediaPlaylist.html index 92e44c5277..2b8d007b19 100644 --- a/docs/dd/d1c/classshaka_1_1hls_1_1MediaPlaylist.html +++ b/docs/dd/d1c/classshaka_1_1hls_1_1MediaPlaylist.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::hls::MediaPlaylist Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::hls::MockMediaPlaylist - -
    + + - -

    Public Types

    enum  MediaPlaylistStreamType {
    -  kUnknown, -kAudio, -kVideo, -kVideoIFramesOnly, -
    +
    enum class  MediaPlaylistStreamType {
    +  kUnknown +, kAudio +, kVideo +, kVideoIFramesOnly +,
      kSubtitle
    }
     
    enum  EncryptionMethod { kNone, -kAes128, -kSampleAes, -kSampleAesCenc +
    enum class  EncryptionMethod { kNone +, kAes128 +, kSampleAes +, kSampleAesCenc }
     
    @@ -164,6 +167,12 @@ void  + + + + + + @@ -175,6 +184,9 @@ void  + +
     
    virtual int GetNumChannels () const
     
    virtual int GetEC3JocComplexity () const
     
    virtual bool GetAC4ImsFlag () const
     
    virtual bool GetAC4CbiFlag () const
     
    virtual bool GetDisplayResolution (uint32_t *width, uint32_t *height) const
     
    virtual std::string GetVideoRange () const
    const std::vector< std::string > & characteristics () const
     
    +bool is_dvs () const
     

    Detailed Description

    Methods are virtual for mocking.

    @@ -301,7 +313,7 @@ const std::vector< std::string > &  -

    Definition at line 444 of file media_playlist.cc.

    +

    Definition at line 451 of file media_playlist.cc.

    @@ -353,7 +365,7 @@ const std::vector< std::string > &  -

    Definition at line 429 of file media_playlist.cc.

    +

    Definition at line 436 of file media_playlist.cc.

    @@ -381,7 +393,7 @@ const std::vector< std::string > & 

    Add #EXT-X-PLACEMENT-OPPORTUNITY for mid-roll ads. See https://support.google.com/dfp_premium/answer/7295798?hl=en.

    -

    Definition at line 461 of file media_playlist.cc.

    +

    Definition at line 468 of file media_playlist.cc.

    @@ -447,7 +459,7 @@ const std::vector< std::string > &  -

    Definition at line 401 of file media_playlist.cc.

    +

    Definition at line 408 of file media_playlist.cc.

    @@ -473,9 +485,65 @@ const std::vector< std::string > & 
    -

    Unlike MaxBitrate, AvgBitrate is always computed from the segment size and duration.

    Returns
    The average bitrate (in bits per second) of this MediaPlaylist.
    +

    Unlike MaxBitrate, AvgBitrate is always computed from the segment size and duration.

    Returns
    The average bitrate (in bits per second) of this MediaPlaylist.
    -

    Definition at line 494 of file media_playlist.cc.

    +

    Definition at line 501 of file media_playlist.cc.

    + +
    + + +

    ◆ GetAC4CbiFlag()

    + +
    +
    + + + + + +
    + + + + + + + +
    bool shaka::hls::MediaPlaylist::GetAC4CbiFlag () const
    +
    +virtual
    +
    +
    Returns
    true if it's an AC-4 CBI stream, based on ETSI TS 103 190-2 Digital Audio Compression (AC-4) Standard; Part 2: Immersive and personalized audio 4.3.
    + +

    Definition at line 532 of file media_playlist.cc.

    + +
    +
    + +

    ◆ GetAC4ImsFlag()

    + +
    +
    + + + + + +
    + + + + + + + +
    bool shaka::hls::MediaPlaylist::GetAC4ImsFlag () const
    +
    +virtual
    +
    +
    Returns
    true if it's an AC-4 IMS stream, based on Dolby AC-4 in MPEG-DASH for Online Delivery Specification 2.5.3. https://developer.dolby.com/tools-media/online-delivery-kits/dolby-ac-4/
    + +

    Definition at line 528 of file media_playlist.cc.

    @@ -514,7 +582,35 @@ const std::vector< std::string > & 
    Returns
    true if |width| and |height| have been set with a valid resolution values.
    -

    Definition at line 517 of file media_playlist.cc.

    +

    Definition at line 536 of file media_playlist.cc.

    + +
    + + +

    ◆ GetEC3JocComplexity()

    + +
    +
    + + + + + +
    + + + + + + + +
    int shaka::hls::MediaPlaylist::GetEC3JocComplexity () const
    +
    +virtual
    +
    +
    Returns
    Dolby Digital Plus JOC decoding complexity, ETSI TS 103 420 v1.2.1 Backwards-compatible object audio carriage using Enhanced AC-3 Standard C.3.2.3.
    + +

    Definition at line 524 of file media_playlist.cc.

    @@ -542,7 +638,7 @@ const std::vector< std::string > & 
    Returns
    the frame rate.
    -

    Definition at line 555 of file media_playlist.cc.

    +

    Definition at line 574 of file media_playlist.cc.

    @@ -570,7 +666,7 @@ const std::vector< std::string > & 
    Returns
    the longest segment’s duration. This will return 0 if no segments have been added.
    -

    Definition at line 498 of file media_playlist.cc.

    +

    Definition at line 505 of file media_playlist.cc.

    @@ -598,7 +694,7 @@ const std::vector< std::string > & 
    Returns
    number of channels for audio. 0 is returned for video.
    -

    Definition at line 513 of file media_playlist.cc.

    +

    Definition at line 520 of file media_playlist.cc.

    @@ -626,7 +722,7 @@ const std::vector< std::string > & 
    Returns
    The video range of the stream.
    -

    Definition at line 535 of file media_playlist.cc.

    +

    Definition at line 554 of file media_playlist.cc.

    @@ -654,7 +750,7 @@ const std::vector< std::string > & 
    Returns
    the language of the media, as an ISO language tag in its shortest form. May be an empty string for video.
    -

    Definition at line 203 of file media_playlist.h.

    +

    Definition at line 218 of file media_playlist.h.

    @@ -680,9 +776,9 @@ const std::vector< std::string > & 
    -

    If bitrate is specified in MediaInfo then it will use that value. Otherwise, returns the max bitrate.

    Returns
    the max bitrate (in bits per second) of this MediaPlaylist.
    +

    If bitrate is specified in MediaInfo then it will use that value. Otherwise, returns the max bitrate.

    Returns
    the max bitrate (in bits per second) of this MediaPlaylist.
    -

    Definition at line 488 of file media_playlist.cc.

    +

    Definition at line 495 of file media_playlist.cc.

    @@ -717,7 +813,7 @@ const std::vector< std::string > & 
    Returns
    true on success, false otherwise.
    -

    Definition at line 368 of file media_playlist.cc.

    +

    Definition at line 373 of file media_playlist.cc.

    @@ -751,7 +847,7 @@ const std::vector< std::string > &  -

    Definition at line 396 of file media_playlist.cc.

    +

    Definition at line 403 of file media_playlist.cc.

    @@ -778,14 +874,14 @@ const std::vector< std::string > & 
    -

    Set the target duration of this MediaPlaylist. In other words this is the value for EXT-X-TARGETDURATION. If this is not called before calling Write(), it will estimate the best target duration. The spec does not allow changing EXT-X-TARGETDURATION. However, this class has no control over the input source.

    Parameters
    +

    Set the target duration of this MediaPlaylist. In other words this is the value for EXT-X-TARGETDURATION. If this is not called before calling Write(), it will estimate the best target duration. The spec does not allow changing EXT-X-TARGETDURATION. However, this class has no control over the input source.

    Parameters
    target_durationis the target duration for this playlist.
    -

    Definition at line 502 of file media_playlist.cc.

    +

    Definition at line 509 of file media_playlist.cc.

    @@ -812,15 +908,15 @@ const std::vector< std::string > & 
    -

    Write the playlist to |file_path|. This does not close the file. If target duration is not set expliticly, this will try to find the target duration. Note that target duration cannot be changed. So calling this without explicitly setting the target duration and before adding any segments will end up setting the target duration to 0 and will always generate an invalid playlist.

    Parameters
    +

    Write the playlist to |file_path|. This does not close the file. If target duration is not set explicitly, this will try to find the target duration. Note that target duration cannot be changed. So calling this without explicitly setting the target duration and before adding any segments will end up setting the target duration to 0 and will always generate an invalid playlist.

    Parameters
    - +
    file_pathis the output file path accepted by the File implementation.
    file_pathis the output file path accepted by the File implementation.
    Returns
    true on success, false otherwise.
    -

    Definition at line 465 of file media_playlist.cc.

    +

    Definition at line 472 of file media_playlist.cc.

    @@ -831,9 +927,7 @@ const std::vector< std::string > &  diff --git a/docs/dd/d20/cue__alignment__handler_8h_source.html b/docs/dd/d20/cue__alignment__handler_8h_source.html index ae3f779e68..cc8d12c30c 100644 --- a/docs/dd/d20/cue__alignment__handler_8h_source.html +++ b/docs/dd/d20/cue__alignment__handler_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking/cue_alignment_handler.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    cue_alignment_handler.h
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CHUNKING_CUE_ALIGNMENT_HANDLER_
    8 #define PACKAGER_MEDIA_CHUNKING_CUE_ALIGNMENT_HANDLER_
    9 
    10 #include <list>
    11 
    12 #include "packager/media/base/media_handler.h"
    13 #include "packager/media/chunking/sync_point_queue.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    26  public:
    27  explicit CueAlignmentHandler(SyncPointQueue* sync_points);
    28  ~CueAlignmentHandler() = default;
    29 
    30  private:
    32  CueAlignmentHandler& operator=(const CueAlignmentHandler&) = delete;
    33 
    34  struct StreamState {
    35  // Information for the stream.
    36  std::shared_ptr<const StreamInfo> info;
    37  // Cached samples that cannot be dispatched. All the samples should be at or
    38  // after |hint|.
    39  std::list<std::unique_ptr<StreamData>> samples;
    40  // If set, the stream is pending to be flushed.
    41  bool to_be_flushed = false;
    42  // Only set for text stream.
    43  double max_text_sample_end_time_seconds = 0;
    44 
    45  // A list of cues that the stream should inject between media samples. When
    46  // there are no cues, the stream should run up to the hint.
    47  std::list<std::unique_ptr<StreamData>> cues;
    48  };
    49 
    50  // MediaHandler overrides.
    51  Status InitializeInternal() override;
    52  Status Process(std::unique_ptr<StreamData> data) override;
    53  Status OnFlushRequest(size_t stream_index) override;
    54 
    55  // Internal handling functions for different stream data.
    56  Status OnStreamInfo(std::unique_ptr<StreamData> data);
    57 
    58  Status OnVideoSample(std::unique_ptr<StreamData> sample);
    59  Status OnNonVideoSample(std::unique_ptr<StreamData> sample);
    60  Status OnSample(std::unique_ptr<StreamData> sample);
    61 
    62  // Update stream states with new sync point.
    63  Status UseNewSyncPoint(std::shared_ptr<const CueEvent> new_sync);
    64 
    65  // Check if everyone is waiting for new hint points.
    66  bool EveryoneWaitingAtHint() const;
    67 
    68  // Dispatch or save incoming sample.
    69  Status AcceptSample(std::unique_ptr<StreamData> sample,
    70  StreamState* stream_state);
    71 
    72  // Dispatch all samples and cues (in the correct order) for the given stream.
    73  Status RunThroughSamples(StreamState* stream);
    74 
    75  SyncPointQueue* const sync_points_ = nullptr;
    76  std::vector<StreamState> stream_states_;
    77 
    78  // A common hint used by all streams. When a new cue is given to all streams,
    79  // the hint will be updated. The hint will always be larger than any cue. The
    80  // hint represents the min time in seconds for the next cue appear. The hints
    81  // are based off the un-promoted cue event times in |sync_points_|.
    82  //
    83  // When a video stream passes the hint, it will promote the corresponding cue
    84  // event. If all streams get to the hint and there are no video streams, the
    85  // thread will block until |sync_points_| gives back a promoted cue event.
    86  double hint_;
    87 };
    88 
    89 } // namespace media
    90 } // namespace shaka
    91 
    92 #endif // PACKAGER_MEDIA_CHUNKING_CUE_ALIGNMENT_HANDLER_
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    A synchronized queue for cue points.
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CHUNKING_CUE_ALIGNMENT_HANDLER_
    +
    8 #define PACKAGER_MEDIA_CHUNKING_CUE_ALIGNMENT_HANDLER_
    +
    9 
    +
    10 #include <list>
    +
    11 
    +
    12 #include "packager/media/base/media_handler.h"
    +
    13 #include "packager/media/chunking/sync_point_queue.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    + +
    26  public:
    +
    27  explicit CueAlignmentHandler(SyncPointQueue* sync_points);
    +
    28  ~CueAlignmentHandler() = default;
    +
    29 
    +
    30  private:
    + +
    32  CueAlignmentHandler& operator=(const CueAlignmentHandler&) = delete;
    +
    33 
    +
    34  struct StreamState {
    +
    35  // Information for the stream.
    +
    36  std::shared_ptr<const StreamInfo> info;
    +
    37  // Cached samples that cannot be dispatched. All the samples should be at or
    +
    38  // after |hint|.
    +
    39  std::list<std::unique_ptr<StreamData>> samples;
    +
    40  // If set, the stream is pending to be flushed.
    +
    41  bool to_be_flushed = false;
    +
    42  // Only set for text stream.
    +
    43  double max_text_sample_end_time_seconds = 0;
    +
    44 
    +
    45  // A list of cues that the stream should inject between media samples. When
    +
    46  // there are no cues, the stream should run up to the hint.
    +
    47  std::list<std::unique_ptr<StreamData>> cues;
    +
    48  };
    +
    49 
    +
    50  // MediaHandler overrides.
    +
    51  Status InitializeInternal() override;
    +
    52  Status Process(std::unique_ptr<StreamData> data) override;
    +
    53  Status OnFlushRequest(size_t stream_index) override;
    +
    54 
    +
    55  // Internal handling functions for different stream data.
    +
    56  Status OnStreamInfo(std::unique_ptr<StreamData> data);
    +
    57 
    +
    58  Status OnVideoSample(std::unique_ptr<StreamData> sample);
    +
    59  Status OnNonVideoSample(std::unique_ptr<StreamData> sample);
    +
    60  Status OnSample(std::unique_ptr<StreamData> sample);
    +
    61 
    +
    62  // Update stream states with new sync point.
    +
    63  Status UseNewSyncPoint(std::shared_ptr<const CueEvent> new_sync);
    +
    64 
    +
    65  // Check if everyone is waiting for new hint points.
    +
    66  bool EveryoneWaitingAtHint() const;
    +
    67 
    +
    68  // Dispatch or save incoming sample.
    +
    69  Status AcceptSample(std::unique_ptr<StreamData> sample,
    +
    70  StreamState* stream_state);
    +
    71 
    +
    72  // Dispatch all samples and cues (in the correct order) for the given stream.
    +
    73  Status RunThroughSamples(StreamState* stream);
    +
    74 
    +
    75  SyncPointQueue* const sync_points_ = nullptr;
    +
    76  std::vector<StreamState> stream_states_;
    +
    77 
    +
    78  // A common hint used by all streams. When a new cue is given to all streams,
    +
    79  // the hint will be updated. The hint will always be larger than any cue. The
    +
    80  // hint represents the min time in seconds for the next cue appear. The hints
    +
    81  // are based off the un-promoted cue event times in |sync_points_|.
    +
    82  //
    +
    83  // When a video stream passes the hint, it will promote the corresponding cue
    +
    84  // event. If all streams get to the hint and there are no video streams, the
    +
    85  // thread will block until |sync_points_| gives back a promoted cue event.
    +
    86  double hint_;
    +
    87 };
    +
    88 
    +
    89 } // namespace media
    +
    90 } // namespace shaka
    +
    91 
    +
    92 #endif // PACKAGER_MEDIA_CHUNKING_CUE_ALIGNMENT_HANDLER_
    + + + +
    A synchronized queue for cue points.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d30/wvm__media__parser_8cc_source.html b/docs/dd/d30/wvm__media__parser_8cc_source.html index 673aa05c62..4ba5180fe7 100644 --- a/docs/dd/d30/wvm__media__parser_8cc_source.html +++ b/docs/dd/d30/wvm__media__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/wvm/wvm_media_parser.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    wvm_media_parser.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/wvm/wvm_media_parser.h"
    6 
    7 #include <map>
    8 #include <sstream>
    9 #include <vector>
    10 
    11 #include "packager/base/strings/string_number_conversions.h"
    12 #include "packager/media/base/aes_decryptor.h"
    13 #include "packager/media/base/audio_stream_info.h"
    14 #include "packager/media/base/key_source.h"
    15 #include "packager/media/base/media_sample.h"
    16 #include "packager/media/base/video_stream_info.h"
    17 #include "packager/media/codecs/aac_audio_specific_config.h"
    18 #include "packager/media/codecs/avc_decoder_configuration_record.h"
    19 #include "packager/media/codecs/es_descriptor.h"
    20 #include "packager/media/formats/mp2t/adts_header.h"
    21 #include "packager/status.h"
    22 
    23 #define HAS_HEADER_EXTENSION(x) ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) \
    24  && (x != 0xF0) && (x != 0xF2) && (x != 0xF8) \
    25  && (x != 0xFF))
    26 
    27 namespace {
    28 const uint32_t kMpeg2ClockRate = 90000;
    29 const uint32_t kPesOptPts = 0x80;
    30 const uint32_t kPesOptDts = 0x40;
    31 const uint32_t kPesOptAlign = 0x04;
    32 const uint32_t kPsmStreamId = 0xBC;
    33 const uint32_t kPaddingStreamId = 0xBE;
    34 const uint32_t kIndexMagic = 0x49444d69;
    35 const uint32_t kIndexStreamId = 0xBF; // private_stream_2
    36 const uint32_t kIndexVersion4HeaderSize = 12;
    37 const uint32_t kEcmStreamId = 0xF0;
    38 const uint32_t kV2MetadataStreamId = 0xF1; // EMM_stream
    39 const uint32_t kScramblingBitsMask = 0x30;
    40 const uint32_t kStartCode1 = 0x00;
    41 const uint32_t kStartCode2 = 0x00;
    42 const uint32_t kStartCode3 = 0x01;
    43 const uint32_t kStartCode4Pack = 0xBA;
    44 const uint32_t kStartCode4System = 0xBB;
    45 const uint32_t kStartCode4ProgramEnd = 0xB9;
    46 const uint32_t kPesStreamIdVideoMask = 0xF0;
    47 const uint32_t kPesStreamIdVideo = 0xE0;
    48 const uint32_t kPesStreamIdAudioMask = 0xE0;
    49 const uint32_t kPesStreamIdAudio = 0xC0;
    50 const uint32_t kVersion4 = 4;
    51 const uint8_t kAacSampleSizeBits = 16;
    52 // Applies to all video streams.
    53 const uint8_t kNaluLengthSize = 4; // unit is bytes.
    54 // Placeholder sampling frequency for all audio streams, which
    55 // will be overwritten after filter parsing.
    56 const uint32_t kDefaultSamplingFrequency = 100;
    57 const uint16_t kEcmSizeBytes = 80;
    58 const uint32_t kInitializationVectorSizeBytes = 16;
    59 // ECM fields for processing.
    60 const uint32_t kEcmContentKeySizeBytes = 16;
    61 const uint32_t kEcmDCPFlagsSizeBytes = 3;
    62 const uint32_t kEcmCCIFlagsSizeBytes = 1;
    63 const uint32_t kEcmFlagsSizeBytes =
    64  kEcmCCIFlagsSizeBytes + kEcmDCPFlagsSizeBytes;
    65 const uint32_t kEcmPaddingSizeBytes = 12;
    66 const uint32_t kAssetKeySizeBytes = 16;
    67 // Default audio and video PES stream IDs.
    68 const uint8_t kDefaultAudioStreamId = kPesStreamIdAudio;
    69 const uint8_t kDefaultVideoStreamId = kPesStreamIdVideo;
    70 
    71 enum Type {
    72  Type_void = 0,
    73  Type_uint8 = 1,
    74  Type_int8 = 2,
    75  Type_uint16 = 3,
    76  Type_int16 = 4,
    77  Type_uint32 = 5,
    78  Type_int32 = 6,
    79  Type_uint64 = 7,
    80  Type_int64 = 8,
    81  Type_string = 9,
    82  Type_BinaryData = 10
    83 };
    84 } // namespace
    85 
    86 namespace shaka {
    87 namespace media {
    88 namespace wvm {
    89 
    90 WvmMediaParser::WvmMediaParser()
    91  : is_initialized_(false),
    92  parse_state_(StartCode1),
    93  skip_bytes_(0),
    94  metadata_is_complete_(false),
    95  current_program_id_(0),
    96  pes_stream_id_(0),
    97  prev_pes_stream_id_(0),
    98  pes_packet_bytes_(0),
    99  pes_flags_1_(0),
    100  pes_flags_2_(0),
    101  prev_pes_flags_1_(0),
    102  pes_header_data_bytes_(0),
    103  timestamp_(0),
    104  pts_(0),
    105  dts_(0),
    106  index_program_id_(0),
    107  media_sample_(NULL),
    108  crypto_unit_start_pos_(0),
    109  stream_id_count_(0),
    110  decryption_key_source_(NULL) {}
    111 
    112 WvmMediaParser::~WvmMediaParser() {}
    113 
    114 void WvmMediaParser::Init(const InitCB& init_cb,
    115  const NewSampleCB& new_sample_cb,
    116  KeySource* decryption_key_source) {
    117  DCHECK(!is_initialized_);
    118  DCHECK(!init_cb.is_null());
    119  DCHECK(!new_sample_cb.is_null());
    120  decryption_key_source_ = decryption_key_source;
    121  init_cb_ = init_cb;
    122  new_sample_cb_ = new_sample_cb;
    123 }
    124 
    125 bool WvmMediaParser::Parse(const uint8_t* buf, int size) {
    126  size_t num_bytes = 0;
    127  size_t prev_size = 0;
    128  const uint8_t* read_ptr = buf;
    129  const uint8_t* end = read_ptr + size;
    130 
    131  while (read_ptr < end) {
    132  switch (parse_state_) {
    133  case StartCode1:
    134  if (*read_ptr == kStartCode1) {
    135  parse_state_ = StartCode2;
    136  }
    137  break;
    138  case StartCode2:
    139  if (*read_ptr == kStartCode2) {
    140  parse_state_ = StartCode3;
    141  } else {
    142  parse_state_ = StartCode1;
    143  }
    144  break;
    145  case StartCode3:
    146  if (*read_ptr == kStartCode3) {
    147  parse_state_ = StartCode4;
    148  } else {
    149  parse_state_ = StartCode1;
    150  }
    151  break;
    152  case StartCode4:
    153  switch (*read_ptr) {
    154  case kStartCode4Pack:
    155  parse_state_ = PackHeader1;
    156  break;
    157  case kStartCode4System:
    158  parse_state_ = SystemHeader1;
    159  break;
    160  case kStartCode4ProgramEnd:
    161  parse_state_ = ProgramEnd;
    162  continue;
    163  default:
    164  parse_state_ = PesStreamId;
    165  continue;
    166  }
    167  break;
    168  case PackHeader1:
    169  parse_state_ = PackHeader2;
    170  break;
    171  case PackHeader2:
    172  parse_state_ = PackHeader3;
    173  break;
    174  case PackHeader3:
    175  parse_state_ = PackHeader4;
    176  break;
    177  case PackHeader4:
    178  parse_state_ = PackHeader5;
    179  break;
    180  case PackHeader5:
    181  parse_state_ = PackHeader6;
    182  break;
    183  case PackHeader6:
    184  parse_state_ = PackHeader7;
    185  break;
    186  case PackHeader7:
    187  parse_state_ = PackHeader8;
    188  break;
    189  case PackHeader8:
    190  parse_state_ = PackHeader9;
    191  break;
    192  case PackHeader9:
    193  parse_state_ = PackHeader10;
    194  break;
    195  case PackHeader10:
    196  skip_bytes_ = *read_ptr & 0x07;
    197  parse_state_ = PackHeaderStuffingSkip;
    198  break;
    199  case SystemHeader1:
    200  skip_bytes_ = *read_ptr;
    201  skip_bytes_ <<= 8;
    202  parse_state_ = SystemHeader2;
    203  break;
    204  case SystemHeader2:
    205  skip_bytes_ |= *read_ptr;
    206  parse_state_ = SystemHeaderSkip;
    207  break;
    208  case PackHeaderStuffingSkip:
    209  if (end >= skip_bytes_ + read_ptr) {
    210  read_ptr += skip_bytes_;
    211  skip_bytes_ = 0;
    212  parse_state_ = StartCode1;
    213  } else {
    214  skip_bytes_ -= (end - read_ptr);
    215  read_ptr = end;
    216  }
    217  continue;
    218  case SystemHeaderSkip:
    219  if (end >= skip_bytes_ + read_ptr) {
    220  read_ptr += skip_bytes_;
    221  skip_bytes_ = 0;
    222  parse_state_ = StartCode1;
    223  } else {
    224  uint32_t remaining_size = end - read_ptr;
    225  skip_bytes_ -= remaining_size;
    226  read_ptr = end;
    227  }
    228  continue;
    229  case PesStreamId:
    230  pes_stream_id_ = *read_ptr;
    231  if (!metadata_is_complete_ &&
    232  (pes_stream_id_ != kPsmStreamId) &&
    233  (pes_stream_id_ != kIndexStreamId) &&
    234  (pes_stream_id_ != kEcmStreamId) &&
    235  (pes_stream_id_ != kV2MetadataStreamId) &&
    236  (pes_stream_id_ != kPaddingStreamId)) {
    237  metadata_is_complete_ = true;
    238  }
    239  parse_state_ = PesPacketLength1;
    240  break;
    241  case PesPacketLength1:
    242  pes_packet_bytes_ = *read_ptr;
    243  pes_packet_bytes_ <<= 8;
    244  parse_state_ = PesPacketLength2;
    245  break;
    246  case PesPacketLength2:
    247  pes_packet_bytes_ |= *read_ptr;
    248  if (HAS_HEADER_EXTENSION(pes_stream_id_)) {
    249  parse_state_ = PesExtension1;
    250  } else {
    251  prev_pes_flags_1_ = pes_flags_1_;
    252  pes_flags_1_ = pes_flags_2_ = 0;
    253  pes_header_data_bytes_ = 0;
    254  parse_state_ = PesPayload;
    255  }
    256  break;
    257  case PesExtension1:
    258  prev_pes_flags_1_ = pes_flags_1_;
    259  pes_flags_1_ = *read_ptr;
    260  --pes_packet_bytes_;
    261  parse_state_ = PesExtension2;
    262  break;
    263  case PesExtension2:
    264  pes_flags_2_ = *read_ptr;
    265  --pes_packet_bytes_;
    266  parse_state_ = PesExtension3;
    267  break;
    268  case PesExtension3:
    269  pes_header_data_bytes_ = *read_ptr;
    270  --pes_packet_bytes_;
    271  if (pes_flags_2_ & kPesOptPts) {
    272  parse_state_ = Pts1;
    273  } else {
    274  parse_state_ = PesHeaderData;
    275  }
    276  break;
    277  case Pts1:
    278  timestamp_ = (*read_ptr & 0x0E);
    279  --pes_header_data_bytes_;
    280  --pes_packet_bytes_;
    281  parse_state_ = Pts2;
    282  break;
    283  case Pts2:
    284  timestamp_ <<= 7;
    285  timestamp_ |= *read_ptr;
    286  --pes_header_data_bytes_;
    287  --pes_packet_bytes_;
    288  parse_state_ = Pts3;
    289  break;
    290  case Pts3:
    291  timestamp_ <<= 7;
    292  timestamp_ |= *read_ptr >> 1;
    293  --pes_header_data_bytes_;
    294  --pes_packet_bytes_;
    295  parse_state_ = Pts4;
    296  break;
    297  case Pts4:
    298  timestamp_ <<= 8;
    299  timestamp_ |= *read_ptr;
    300  --pes_header_data_bytes_;
    301  --pes_packet_bytes_;
    302  parse_state_ = Pts5;
    303  break;
    304  case Pts5:
    305  timestamp_ <<= 7;
    306  timestamp_ |= *read_ptr >> 1;
    307  pts_ = timestamp_;
    308  --pes_header_data_bytes_;
    309  --pes_packet_bytes_;
    310  if (pes_flags_2_ & kPesOptDts) {
    311  parse_state_ = Dts1;
    312  } else {
    313  dts_ = pts_;
    314  parse_state_ = PesHeaderData;
    315  }
    316  break;
    317  case Dts1:
    318  timestamp_ = (*read_ptr & 0x0E);
    319  --pes_header_data_bytes_;
    320  --pes_packet_bytes_;
    321  parse_state_ = Dts2;
    322  break;
    323  case Dts2:
    324  timestamp_ <<= 7;
    325  timestamp_ |= *read_ptr;
    326  --pes_header_data_bytes_;
    327  --pes_packet_bytes_;
    328  parse_state_ = Dts3;
    329  break;
    330  case Dts3:
    331  timestamp_ <<= 7;
    332  timestamp_ |= *read_ptr >> 1;
    333  --pes_header_data_bytes_;
    334  --pes_packet_bytes_;
    335  parse_state_ = Dts4;
    336  break;
    337  case Dts4:
    338  timestamp_ <<= 8;
    339  timestamp_ |= *read_ptr;
    340  --pes_header_data_bytes_;
    341  --pes_packet_bytes_;
    342  parse_state_ = Dts5;
    343  break;
    344  case Dts5:
    345  timestamp_ <<= 7;
    346  timestamp_ |= *read_ptr >> 1;
    347  dts_ = timestamp_;
    348  --pes_header_data_bytes_;
    349  --pes_packet_bytes_;
    350  parse_state_ = PesHeaderData;
    351  break;
    352  case PesHeaderData:
    353  num_bytes = end - read_ptr;
    354  if (num_bytes >= pes_header_data_bytes_) {
    355  num_bytes = pes_header_data_bytes_;
    356  parse_state_ = PesPayload;
    357  }
    358  pes_header_data_bytes_ -= num_bytes;
    359  pes_packet_bytes_ -= num_bytes;
    360  read_ptr += num_bytes;
    361  continue;
    362  case PesPayload:
    363  switch (pes_stream_id_) {
    364  case kPsmStreamId:
    365  psm_data_.clear();
    366  parse_state_ = PsmPayload;
    367  continue;
    368  case kPaddingStreamId:
    369  parse_state_ = Padding;
    370  continue;
    371  case kEcmStreamId:
    372  ecm_.clear();
    373  parse_state_ = EcmPayload;
    374  continue;
    375  case kIndexStreamId:
    376  parse_state_ = IndexPayload;
    377  continue;
    378  default:
    379  if (!DemuxNextPes(false)) {
    380  return false;
    381  }
    382  parse_state_ = EsPayload;
    383  }
    384  continue;
    385  case PsmPayload:
    386  num_bytes = end - read_ptr;
    387  if (num_bytes >= pes_packet_bytes_) {
    388  num_bytes = pes_packet_bytes_;
    389  parse_state_ = StartCode1;
    390  }
    391  if (num_bytes > 0) {
    392  pes_packet_bytes_ -= num_bytes;
    393  prev_size = psm_data_.size();
    394  psm_data_.resize(prev_size + num_bytes);
    395  memcpy(&psm_data_[prev_size], read_ptr, num_bytes);
    396  }
    397  read_ptr += num_bytes;
    398  continue;
    399  case EcmPayload:
    400  num_bytes = end - read_ptr;
    401  if (num_bytes >= pes_packet_bytes_) {
    402  num_bytes = pes_packet_bytes_;
    403  parse_state_ = StartCode1;
    404  }
    405  if (num_bytes > 0) {
    406  pes_packet_bytes_ -= num_bytes;
    407  prev_size = ecm_.size();
    408  ecm_.resize(prev_size + num_bytes);
    409  memcpy(&ecm_[prev_size], read_ptr, num_bytes);
    410  }
    411  if ((pes_packet_bytes_ == 0) && !ecm_.empty()) {
    412  if (!ProcessEcm()) {
    413  return(false);
    414  }
    415  }
    416  read_ptr += num_bytes;
    417  continue;
    418  case IndexPayload:
    419  num_bytes = end - read_ptr;
    420  if (num_bytes >= pes_packet_bytes_) {
    421  num_bytes = pes_packet_bytes_;
    422  parse_state_ = StartCode1;
    423  }
    424  if (num_bytes > 0) {
    425  pes_packet_bytes_ -= num_bytes;
    426  prev_size = index_data_.size();
    427  index_data_.resize(prev_size + num_bytes);
    428  memcpy(&index_data_[prev_size], read_ptr, num_bytes);
    429  }
    430  if (pes_packet_bytes_ == 0 && !index_data_.empty()) {
    431  if (!metadata_is_complete_) {
    432  if (!ParseIndexEntry()) {
    433  return false;
    434  }
    435  }
    436  }
    437  read_ptr += num_bytes;
    438  continue;
    439  case EsPayload:
    440  num_bytes = end - read_ptr;
    441  if (num_bytes >= pes_packet_bytes_) {
    442  num_bytes = pes_packet_bytes_;
    443  parse_state_ = StartCode1;
    444  }
    445  pes_packet_bytes_ -= num_bytes;
    446  if (pes_stream_id_ != kV2MetadataStreamId) {
    447  sample_data_.resize(sample_data_.size() + num_bytes);
    448  memcpy(&sample_data_[sample_data_.size() - num_bytes], read_ptr,
    449  num_bytes);
    450  }
    451  prev_pes_stream_id_ = pes_stream_id_;
    452  read_ptr += num_bytes;
    453  continue;
    454  case Padding:
    455  num_bytes = end - read_ptr;
    456  if (num_bytes >= pes_packet_bytes_) {
    457  num_bytes = pes_packet_bytes_;
    458  parse_state_ = StartCode1;
    459  }
    460  pes_packet_bytes_ -= num_bytes;
    461  read_ptr += num_bytes;
    462  continue;
    463  case ProgramEnd:
    464  parse_state_ = StartCode1;
    465  metadata_is_complete_ = true;
    466  if (!DemuxNextPes(true)) {
    467  return false;
    468  }
    469  if (!Flush()) {
    470  return false;
    471  }
    472  // Reset.
    473  dts_ = pts_ = 0;
    474  parse_state_ = StartCode1;
    475  prev_media_sample_data_.Reset();
    476  current_program_id_++;
    477  ecm_.clear();
    478  index_data_.clear();
    479  psm_data_.clear();
    480  break;
    481  default:
    482  break;
    483  }
    484  ++read_ptr;
    485  }
    486  return true;
    487 }
    488 
    489 bool WvmMediaParser::EmitLastSample(
    490  uint32_t stream_id,
    491  const std::shared_ptr<MediaSample>& new_sample) {
    492  std::string key = base::UintToString(current_program_id_)
    493  .append(":")
    494  .append(base::UintToString(stream_id));
    495  std::map<std::string, uint32_t>::iterator it =
    496  program_demux_stream_map_.find(key);
    497  if (it == program_demux_stream_map_.end())
    498  return false;
    499  return EmitSample(stream_id, (*it).second, new_sample, true);
    500 }
    501 
    502 bool WvmMediaParser::EmitPendingSamples() {
    503  // Emit queued samples which were built when not initialized.
    504  while (!media_sample_queue_.empty()) {
    505  DemuxStreamIdMediaSample& demux_stream_media_sample =
    506  media_sample_queue_.front();
    507  if (!EmitSample(demux_stream_media_sample.parsed_audio_or_video_stream_id,
    508  demux_stream_media_sample.demux_stream_id,
    509  demux_stream_media_sample.media_sample,
    510  false)) {
    511  return false;
    512  }
    513  media_sample_queue_.pop_front();
    514  }
    515  return true;
    516 }
    517 
    518 bool WvmMediaParser::Flush() {
    519  // Flush the last audio and video sample for current program.
    520  // Reset the streamID when successfully emitted.
    521  if (prev_media_sample_data_.audio_sample != NULL) {
    522  if (!EmitLastSample(prev_pes_stream_id_,
    523  prev_media_sample_data_.audio_sample)) {
    524  LOG(ERROR) << "Did not emit last sample for audio stream with ID = "
    525  << prev_pes_stream_id_;
    526  return false;
    527  }
    528  }
    529  if (prev_media_sample_data_.video_sample != NULL) {
    530  if (!EmitLastSample(prev_pes_stream_id_,
    531  prev_media_sample_data_.video_sample)) {
    532  LOG(ERROR) << "Did not emit last sample for video stream with ID = "
    533  << prev_pes_stream_id_;
    534  return false;
    535  }
    536  }
    537  return true;
    538 }
    539 
    540 bool WvmMediaParser::ParseIndexEntry() {
    541  // Do not parse index entry at the beginning of any track *after* the first
    542  // track.
    543  if (current_program_id_ > 0) {
    544  return true;
    545  }
    546  uint32_t index_size = 0;
    547  if (index_data_.size() < kIndexVersion4HeaderSize) {
    548  return false;
    549  }
    550 
    551  const uint8_t* read_ptr = index_data_.data();
    552  if (ntohlFromBuffer(read_ptr) != kIndexMagic) {
    553  index_data_.clear();
    554  return false;
    555  }
    556  read_ptr += 4;
    557 
    558  uint32_t version = ntohlFromBuffer(read_ptr);
    559  read_ptr += 4;
    560  if (version == kVersion4) {
    561  index_size = kIndexVersion4HeaderSize + ntohlFromBuffer(read_ptr);
    562  if (index_data_.size() < index_size) {
    563  // We do not yet have the full index. Keep accumulating index data.
    564  return true;
    565  }
    566  read_ptr += sizeof(uint32_t);
    567 
    568  // Index metadata
    569  uint32_t index_metadata_max_size = index_size - kIndexVersion4HeaderSize;
    570  if (index_metadata_max_size < sizeof(uint8_t)) {
    571  index_data_.clear();
    572  return false;
    573  }
    574 
    575  uint64_t track_duration = 0;
    576  uint32_t trick_play_factor = 0;
    577  uint32_t sampling_frequency = kDefaultSamplingFrequency;
    578  uint32_t time_scale = kMpeg2ClockRate;
    579  uint16_t video_width = 0;
    580  uint16_t video_height = 0;
    581  uint32_t pixel_width = 0;
    582  uint32_t pixel_height = 0;
    583  uint8_t nalu_length_size = kNaluLengthSize;
    584  uint8_t num_channels = 0;
    585  int audio_pes_stream_id = 0;
    586  int video_pes_stream_id = 0;
    587  bool has_video = false;
    588  bool has_audio = false;
    589  std::vector<uint8_t> audio_codec_config;
    590  std::vector<uint8_t> video_codec_config;
    591  uint8_t num_index_entries = *read_ptr;
    592  ++read_ptr;
    593  --index_metadata_max_size;
    594 
    595  for (uint8_t idx = 0; idx < num_index_entries; ++idx) {
    596  if (index_metadata_max_size < (2 * sizeof(uint8_t)) + sizeof(uint32_t)) {
    597  return false;
    598  }
    599  uint8_t tag = *read_ptr;
    600  ++read_ptr;
    601  uint8_t type = *read_ptr;
    602  ++read_ptr;
    603  uint32_t length = ntohlFromBuffer(read_ptr);
    604  read_ptr += sizeof(uint32_t);
    605  index_metadata_max_size -= (2 * sizeof(uint8_t)) + sizeof(uint32_t);
    606  if (index_metadata_max_size < length) {
    607  return false;
    608  }
    609  int64_t value = 0;
    610  Tag tagtype = Unset;
    611  std::vector<uint8_t> binary_data;
    612  switch (Type(type)) {
    613  case Type_uint8:
    614  if (length == sizeof(uint8_t)) {
    615  tagtype = GetTag(tag, length, read_ptr, &value);
    616  } else {
    617  return false;
    618  }
    619  break;
    620  case Type_int8:
    621  if (length == sizeof(int8_t)) {
    622  tagtype = GetTag(tag, length, read_ptr, &value);
    623  } else {
    624  return false;
    625  }
    626  break;
    627  case Type_uint16:
    628  if (length == sizeof(uint16_t)) {
    629  tagtype = GetTag(tag, length, read_ptr, &value);
    630  } else {
    631  return false;
    632  }
    633  break;
    634  case Type_int16:
    635  if (length == sizeof(int16_t)) {
    636  tagtype = GetTag(tag, length, read_ptr, &value);
    637  } else {
    638  return false;
    639  }
    640  break;
    641  case Type_uint32:
    642  if (length == sizeof(uint32_t)) {
    643  tagtype = GetTag(tag, length, read_ptr, &value);
    644  } else {
    645  return false;
    646  }
    647  break;
    648  case Type_int32:
    649  if (length == sizeof(int32_t)) {
    650  tagtype = GetTag(tag, length, read_ptr, &value);
    651  } else {
    652  return false;
    653  }
    654  break;
    655  case Type_uint64:
    656  if (length == sizeof(uint64_t)) {
    657  tagtype = GetTag(tag, length, read_ptr, &value);
    658  } else {
    659  return false;
    660  }
    661  break;
    662  case Type_int64:
    663  if (length == sizeof(int64_t)) {
    664  tagtype = GetTag(tag, length, read_ptr, &value);
    665  } else {
    666  return false;
    667  }
    668  break;
    669  case Type_string:
    670  case Type_BinaryData:
    671  binary_data.assign(read_ptr, read_ptr + length);
    672  tagtype = Tag(tag);
    673  break;
    674  default:
    675  break;
    676  }
    677 
    678  switch (tagtype) {
    679  case TrackDuration:
    680  track_duration = value;
    681  break;
    682  case TrackTrickPlayFactor:
    683  trick_play_factor = value;
    684  break;
    685  case VideoStreamId:
    686  video_pes_stream_id = value;
    687  break;
    688  case AudioStreamId:
    689  audio_pes_stream_id = value;
    690  break;
    691  case VideoWidth:
    692  video_width = (uint16_t)value;
    693  break;
    694  case VideoHeight:
    695  video_height = (uint16_t)value;
    696  break;
    697  case AudioNumChannels:
    698  num_channels = (uint8_t)value;
    699  break;
    700  case VideoType:
    701  has_video = true;
    702  break;
    703  case AudioType:
    704  has_audio = true;
    705  break;
    706  case VideoPixelWidth:
    707  pixel_width = static_cast<uint32_t>(value);
    708  break;
    709  case VideoPixelHeight:
    710  pixel_height = static_cast<uint32_t>(value);
    711  break;
    712  case Audio_EsDescriptor: {
    713  ESDescriptor descriptor;
    714  if (!descriptor.Parse(binary_data)) {
    715  LOG(ERROR) <<
    716  "Could not extract AudioSpecificConfig from ES_Descriptor";
    717  return false;
    718  }
    719  audio_codec_config = descriptor.decoder_config_descriptor()
    720  .decoder_specific_info_descriptor()
    721  .data();
    722  break;
    723  }
    724  case Audio_EC3SpecificData:
    725  case Audio_DtsSpecificData:
    726  case Audio_AC3SpecificData:
    727  LOG(ERROR) << "Audio type not supported.";
    728  return false;
    729  case Video_AVCDecoderConfigurationRecord:
    730  video_codec_config = binary_data;
    731  break;
    732  default:
    733  break;
    734  }
    735 
    736  read_ptr += length;
    737  index_metadata_max_size -= length;
    738  }
    739  // End Index metadata
    740  index_size = read_ptr - index_data_.data();
    741 
    742  if (has_video) {
    743  stream_infos_.emplace_back(new VideoStreamInfo(
    744  stream_id_count_, time_scale, track_duration, kCodecH264,
    745  byte_to_unit_stream_converter_.stream_format(), std::string(),
    746  video_codec_config.data(), video_codec_config.size(), video_width,
    747  video_height, pixel_width, pixel_height,
    748  0 /* transfer_characteristics */, trick_play_factor, nalu_length_size,
    749  std::string(), decryption_key_source_ ? false : true));
    750  program_demux_stream_map_[base::UintToString(index_program_id_) + ":" +
    751  base::UintToString(
    752  video_pes_stream_id
    753  ? video_pes_stream_id
    754  : kDefaultVideoStreamId)] =
    755  stream_id_count_++;
    756  }
    757  if (has_audio) {
    758  const Codec audio_codec = kCodecAAC;
    759  // TODO(beil): Pass in max and average bitrate in wvm container.
    760  stream_infos_.emplace_back(new AudioStreamInfo(
    761  stream_id_count_, time_scale, track_duration, audio_codec,
    762  std::string(), audio_codec_config.data(), audio_codec_config.size(),
    763  kAacSampleSizeBits, num_channels, sampling_frequency,
    764  0 /* seek preroll */, 0 /* codec delay */, 0 /* max bitrate */,
    765  0 /* avg bitrate */, std::string(),
    766  decryption_key_source_ ? false : true));
    767  program_demux_stream_map_[base::UintToString(index_program_id_) + ":" +
    768  base::UintToString(
    769  audio_pes_stream_id
    770  ? audio_pes_stream_id
    771  : kDefaultAudioStreamId)] =
    772  stream_id_count_++;
    773  }
    774  }
    775 
    776  index_program_id_++;
    777  index_data_.clear();
    778  return true;
    779 }
    780 
    781 bool WvmMediaParser::DemuxNextPes(bool is_program_end) {
    782  bool output_encrypted_sample = false;
    783  if (!sample_data_.empty() && (prev_pes_flags_1_ & kScramblingBitsMask)) {
    784  // Decrypt crypto unit.
    785  if (!content_decryptor_) {
    786  output_encrypted_sample = true;
    787  } else {
    788  content_decryptor_->Crypt(&sample_data_[crypto_unit_start_pos_],
    789  sample_data_.size() - crypto_unit_start_pos_,
    790  &sample_data_[crypto_unit_start_pos_]);
    791  }
    792  }
    793  // Demux media sample if we are at program end or if we are not at a
    794  // continuation PES.
    795  if ((pes_flags_2_ & kPesOptPts) || is_program_end) {
    796  if (!sample_data_.empty()) {
    797  if (!Output(output_encrypted_sample)) {
    798  return false;
    799  }
    800  }
    801  StartMediaSampleDemux();
    802  }
    803 
    804  crypto_unit_start_pos_ = sample_data_.size();
    805  return true;
    806 }
    807 
    808 void WvmMediaParser::StartMediaSampleDemux() {
    809  bool is_key_frame = ((pes_flags_1_ & kPesOptAlign) != 0);
    810  media_sample_ = MediaSample::CreateEmptyMediaSample();
    811  media_sample_->set_dts(dts_);
    812  media_sample_->set_pts(pts_);
    813  media_sample_->set_is_key_frame(is_key_frame);
    814 
    815  sample_data_.clear();
    816 }
    817 
    818 bool WvmMediaParser::Output(bool output_encrypted_sample) {
    819  if (output_encrypted_sample) {
    820  media_sample_->SetData(sample_data_.data(), sample_data_.size());
    821  media_sample_->set_is_encrypted(true);
    822  } else {
    823  if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
    824  // Convert video stream to unit stream and get config.
    825  std::vector<uint8_t> nal_unit_stream;
    826  if (!byte_to_unit_stream_converter_.ConvertByteStreamToNalUnitStream(
    827  sample_data_.data(), sample_data_.size(), &nal_unit_stream)) {
    828  LOG(ERROR) << "Could not convert h.264 byte stream sample";
    829  return false;
    830  }
    831  media_sample_->SetData(nal_unit_stream.data(), nal_unit_stream.size());
    832  if (!is_initialized_) {
    833  // Set extra data for video stream from AVC Decoder Config Record.
    834  // Also, set codec string from the AVC Decoder Config Record.
    835  std::vector<uint8_t> decoder_config_record;
    836  byte_to_unit_stream_converter_.GetDecoderConfigurationRecord(
    837  &decoder_config_record);
    838  for (uint32_t i = 0; i < stream_infos_.size(); i++) {
    839  if (stream_infos_[i]->stream_type() == kStreamVideo &&
    840  stream_infos_[i]->codec_string().empty()) {
    841  const std::vector<uint8_t>* stream_config;
    842  if (stream_infos_[i]->codec_config().empty()) {
    843  // Decoder config record not available for stream. Use the one
    844  // computed from the first video stream.
    845  stream_infos_[i]->set_codec_config(decoder_config_record);
    846  stream_config = &decoder_config_record;
    847  } else {
    848  // Use stream-specific config record.
    849  stream_config = &stream_infos_[i]->codec_config();
    850  }
    851  DCHECK(stream_config);
    852 
    853  VideoStreamInfo* video_stream_info =
    854  reinterpret_cast<VideoStreamInfo*>(stream_infos_[i].get());
    856  if (!avc_config.Parse(*stream_config)) {
    857  LOG(WARNING) << "Failed to parse AVCDecoderConfigurationRecord. "
    858  "Using computed configuration record instead.";
    859  video_stream_info->set_codec_config(decoder_config_record);
    860  if (!avc_config.Parse(decoder_config_record)) {
    861  LOG(ERROR) << "Failed to parse AVCDecoderConfigurationRecord.";
    862  return false;
    863  }
    864  }
    865  const FourCC codec_fourcc =
    866  byte_to_unit_stream_converter_.stream_format() ==
    867  H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    868  ? FOURCC_avc3
    869  : FOURCC_avc1;
    870  video_stream_info->set_codec_string(
    871  avc_config.GetCodecString(codec_fourcc));
    872 
    873  if (avc_config.pixel_width() != video_stream_info->pixel_width() ||
    874  avc_config.pixel_height() !=
    875  video_stream_info->pixel_height()) {
    876  LOG_IF(WARNING, video_stream_info->pixel_width() != 0 ||
    877  video_stream_info->pixel_height() != 0)
    878  << "Pixel aspect ratio in WVM metadata ("
    879  << video_stream_info->pixel_width() << ","
    880  << video_stream_info->pixel_height()
    881  << ") does not match with SAR in "
    882  "AVCDecoderConfigurationRecord ("
    883  << avc_config.pixel_width() << ","
    884  << avc_config.pixel_height()
    885  << "). Use AVCDecoderConfigurationRecord.";
    886  video_stream_info->set_pixel_width(avc_config.pixel_width());
    887  video_stream_info->set_pixel_height(avc_config.pixel_height());
    888  }
    889  if (avc_config.coded_width() != video_stream_info->width() ||
    890  avc_config.coded_height() != video_stream_info->height()) {
    891  LOG(WARNING) << "Resolution in WVM metadata ("
    892  << video_stream_info->width() << ","
    893  << video_stream_info->height()
    894  << ") does not match with resolution in "
    895  "AVCDecoderConfigurationRecord ("
    896  << avc_config.coded_width() << ","
    897  << avc_config.coded_height()
    898  << "). Use AVCDecoderConfigurationRecord.";
    899  video_stream_info->set_width(avc_config.coded_width());
    900  video_stream_info->set_height(avc_config.coded_height());
    901  }
    902  }
    903  }
    904  }
    905  } else if ((prev_pes_stream_id_ & kPesStreamIdAudioMask) ==
    906  kPesStreamIdAudio) {
    907  // Set data on the audio stream.
    908  mp2t::AdtsHeader adts_header;
    909  const uint8_t* frame_ptr = sample_data_.data();
    910  if (!adts_header.Parse(frame_ptr, sample_data_.size())) {
    911  LOG(ERROR) << "Could not parse ADTS header";
    912  return false;
    913  }
    914  media_sample_->SetData(
    915  frame_ptr + adts_header.GetHeaderSize(),
    916  adts_header.GetFrameSize() - adts_header.GetHeaderSize());
    917  if (!is_initialized_) {
    918  for (uint32_t i = 0; i < stream_infos_.size(); i++) {
    919  if (stream_infos_[i]->stream_type() == kStreamAudio &&
    920  stream_infos_[i]->codec_string().empty()) {
    921  AudioStreamInfo* audio_stream_info =
    922  reinterpret_cast<AudioStreamInfo*>(stream_infos_[i].get());
    923  if (audio_stream_info->codec_config().empty()) {
    924  // Set AudioStreamInfo fields using information from the ADTS
    925  // header.
    926  audio_stream_info->set_sampling_frequency(
    927  adts_header.GetSamplingFrequency());
    928  std::vector<uint8_t> audio_specific_config;
    929  adts_header.GetAudioSpecificConfig(&audio_specific_config);
    930  audio_stream_info->set_codec_config(audio_specific_config);
    931  audio_stream_info->set_codec_string(
    933  kCodecAAC, adts_header.GetObjectType()));
    934  } else {
    935  // Set AudioStreamInfo fields using information from the
    936  // AACAudioSpecificConfig record.
    937  AACAudioSpecificConfig aac_config;
    938  if (!aac_config.Parse(stream_infos_[i]->codec_config())) {
    939  LOG(ERROR) << "Could not parse AACAudioSpecificconfig";
    940  return false;
    941  }
    942  audio_stream_info->set_sampling_frequency(
    943  aac_config.GetSamplesPerSecond());
    944  audio_stream_info->set_codec_string(
    946  kCodecAAC, aac_config.GetAudioObjectType()));
    947  }
    948  }
    949  }
    950  }
    951  }
    952  }
    953 
    954  if (!is_initialized_) {
    955  bool all_streams_have_config = true;
    956  // Check if all collected stream infos have codec_config set.
    957  for (uint32_t i = 0; i < stream_infos_.size(); i++) {
    958  if (stream_infos_[i]->codec_string().empty()) {
    959  all_streams_have_config = false;
    960  break;
    961  }
    962  }
    963  if (all_streams_have_config) {
    964  init_cb_.Run(stream_infos_);
    965  is_initialized_ = true;
    966  }
    967  }
    968 
    969  DCHECK_GT(media_sample_->data_size(), 0UL);
    970  std::string key = base::UintToString(current_program_id_).append(":")
    971  .append(base::UintToString(prev_pes_stream_id_));
    972  std::map<std::string, uint32_t>::iterator it =
    973  program_demux_stream_map_.find(key);
    974  if (it == program_demux_stream_map_.end()) {
    975  // TODO(ramjic): Log error message here and in other error cases through
    976  // this method.
    977  return false;
    978  }
    979  DemuxStreamIdMediaSample demux_stream_media_sample;
    980  demux_stream_media_sample.parsed_audio_or_video_stream_id =
    981  prev_pes_stream_id_;
    982  demux_stream_media_sample.demux_stream_id = (*it).second;
    983  demux_stream_media_sample.media_sample = media_sample_;
    984  // Check if sample can be emitted.
    985  if (!is_initialized_) {
    986  media_sample_queue_.push_back(demux_stream_media_sample);
    987  } else {
    988  // flush the sample queue and emit all queued samples.
    989  while (!media_sample_queue_.empty()) {
    990  if (!EmitPendingSamples())
    991  return false;
    992  }
    993  // Emit current sample.
    994  if (!EmitSample(prev_pes_stream_id_, (*it).second, media_sample_, false))
    995  return false;
    996  }
    997  return true;
    998 }
    999 
    1000 bool WvmMediaParser::EmitSample(uint32_t parsed_audio_or_video_stream_id,
    1001  uint32_t stream_id,
    1002  const std::shared_ptr<MediaSample>& new_sample,
    1003  bool isLastSample) {
    1004  DCHECK(new_sample);
    1005  if (isLastSample) {
    1006  if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
    1007  kPesStreamIdVideo) {
    1008  new_sample->set_duration(prev_media_sample_data_.video_sample_duration);
    1009  } else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
    1010  kPesStreamIdAudio) {
    1011  new_sample->set_duration(prev_media_sample_data_.audio_sample_duration);
    1012  }
    1013  if (!new_sample_cb_.Run(stream_id, new_sample)) {
    1014  LOG(ERROR) << "Failed to process the last sample.";
    1015  return false;
    1016  }
    1017  return true;
    1018  }
    1019 
    1020  // Cannot emit current sample. Compute duration first and then,
    1021  // emit previous sample.
    1022  if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
    1023  kPesStreamIdVideo) {
    1024  if (prev_media_sample_data_.video_sample == NULL) {
    1025  prev_media_sample_data_.video_sample = new_sample;
    1026  prev_media_sample_data_.video_stream_id = stream_id;
    1027  return true;
    1028  }
    1029  prev_media_sample_data_.video_sample->set_duration(
    1030  new_sample->dts() - prev_media_sample_data_.video_sample->dts());
    1031  prev_media_sample_data_.video_sample_duration =
    1032  prev_media_sample_data_.video_sample->duration();
    1033  if (!new_sample_cb_.Run(prev_media_sample_data_.video_stream_id,
    1034  prev_media_sample_data_.video_sample)) {
    1035  LOG(ERROR) << "Failed to process the video sample.";
    1036  return false;
    1037  }
    1038  prev_media_sample_data_.video_sample = new_sample;
    1039  prev_media_sample_data_.video_stream_id = stream_id;
    1040  } else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
    1041  kPesStreamIdAudio) {
    1042  if (prev_media_sample_data_.audio_sample == NULL) {
    1043  prev_media_sample_data_.audio_sample = new_sample;
    1044  prev_media_sample_data_.audio_stream_id = stream_id;
    1045  return true;
    1046  }
    1047  prev_media_sample_data_.audio_sample->set_duration(
    1048  new_sample->dts() - prev_media_sample_data_.audio_sample->dts());
    1049  prev_media_sample_data_.audio_sample_duration =
    1050  prev_media_sample_data_.audio_sample->duration();
    1051  if (!new_sample_cb_.Run(prev_media_sample_data_.audio_stream_id,
    1052  prev_media_sample_data_.audio_sample)) {
    1053  LOG(ERROR) << "Failed to process the audio sample.";
    1054  return false;
    1055  }
    1056  prev_media_sample_data_.audio_sample = new_sample;
    1057  prev_media_sample_data_.audio_stream_id = stream_id;
    1058  }
    1059  return true;
    1060 }
    1061 
    1062 bool WvmMediaParser::GetAssetKey(const uint8_t* asset_id,
    1063  EncryptionKey* encryption_key) {
    1064  DCHECK(decryption_key_source_);
    1065  Status status = decryption_key_source_->FetchKeys(
    1066  EmeInitDataType::WIDEVINE_CLASSIC,
    1067  std::vector<uint8_t>(asset_id, asset_id + sizeof(uint32_t)));
    1068  if (!status.ok()) {
    1069  LOG(ERROR) << "Fetch Key(s) failed for AssetID = "
    1070  << ntohlFromBuffer(asset_id) << ", error = " << status;
    1071  return false;
    1072  }
    1073 
    1074  const char kHdStreamLabel[] = "HD";
    1075  status = decryption_key_source_->GetKey(kHdStreamLabel, encryption_key);
    1076  if (!status.ok()) {
    1077  LOG(ERROR) << "Fetch Key(s) failed for AssetID = "
    1078  << ntohlFromBuffer(asset_id) << ", error = " << status;
    1079  return false;
    1080  }
    1081 
    1082  return true;
    1083 }
    1084 
    1085 bool WvmMediaParser::ProcessEcm() {
    1086  // An error will be returned later if the samples need to be decrypted.
    1087  if (!decryption_key_source_)
    1088  return true;
    1089 
    1090  if (current_program_id_ > 0) {
    1091  return true;
    1092  }
    1093  if (ecm_.size() != kEcmSizeBytes) {
    1094  LOG(ERROR) << "Unexpected ECM size = " << ecm_.size()
    1095  << ", expected size = " << kEcmSizeBytes;
    1096  return false;
    1097  }
    1098  const uint8_t* ecm_data = ecm_.data();
    1099  DCHECK(ecm_data);
    1100  ecm_data += sizeof(uint32_t); // old version field - skip.
    1101  ecm_data += sizeof(uint32_t); // clear lead - skip.
    1102  ecm_data += sizeof(uint32_t); // system id(includes ECM version) - skip.
    1103  EncryptionKey encryption_key;
    1104  if (!GetAssetKey(ecm_data, &encryption_key)) {
    1105  return false;
    1106  }
    1107  if (encryption_key.key.size() < kAssetKeySizeBytes) {
    1108  LOG(ERROR) << "Asset Key size of " << encryption_key.key.size()
    1109  << " for AssetID = " << ntohlFromBuffer(ecm_data)
    1110  << " is less than minimum asset key size.";
    1111  return false;
    1112  }
    1113  ecm_data += sizeof(uint32_t); // asset_id.
    1114  // Legacy WVM content may have asset keys > 16 bytes.
    1115  // Use only the first 16 bytes of the asset key to get
    1116  // the content key.
    1117  std::vector<uint8_t> asset_key(
    1118  encryption_key.key.begin(),
    1119  encryption_key.key.begin() + kAssetKeySizeBytes);
    1120  // WVM format always uses all zero IV.
    1121  std::vector<uint8_t> zero_iv(kInitializationVectorSizeBytes, 0);
    1122  AesCbcDecryptor asset_decryptor(kCtsPadding, AesCryptor::kUseConstantIv);
    1123  if (!asset_decryptor.InitializeWithIv(asset_key, zero_iv)) {
    1124  LOG(ERROR) << "Failed to initialize asset_decryptor.";
    1125  return false;
    1126  }
    1127 
    1128  const size_t content_key_buffer_size =
    1129  kEcmFlagsSizeBytes + kEcmContentKeySizeBytes +
    1130  kEcmPaddingSizeBytes; // flags + contentKey + padding.
    1131  std::vector<uint8_t> content_key_buffer(content_key_buffer_size);
    1132  CHECK(asset_decryptor.Crypt(ecm_data, content_key_buffer_size,
    1133  content_key_buffer.data()));
    1134 
    1135  std::vector<uint8_t> decrypted_content_key_vec(
    1136  content_key_buffer.begin() + 4,
    1137  content_key_buffer.begin() + 20);
    1138  std::unique_ptr<AesCbcDecryptor> content_decryptor(
    1139  new AesCbcDecryptor(kCtsPadding, AesCryptor::kUseConstantIv));
    1140  if (!content_decryptor->InitializeWithIv(decrypted_content_key_vec,
    1141  zero_iv)) {
    1142  LOG(ERROR) << "Failed to initialize content decryptor.";
    1143  return false;
    1144  }
    1145 
    1146  content_decryptor_ = std::move(content_decryptor);
    1147  return true;
    1148 }
    1149 
    1150 DemuxStreamIdMediaSample::DemuxStreamIdMediaSample() :
    1151  demux_stream_id(0),
    1152  parsed_audio_or_video_stream_id(0) {}
    1153 
    1154 DemuxStreamIdMediaSample::~DemuxStreamIdMediaSample() {}
    1155 
    1156 PrevSampleData::PrevSampleData() {
    1157  Reset();
    1158 }
    1159 
    1160 PrevSampleData::~PrevSampleData() {}
    1161 
    1162 void PrevSampleData::Reset() {
    1163  audio_sample = NULL;
    1164  video_sample = NULL;
    1165  audio_stream_id = 0;
    1166  video_stream_id = 0;
    1167  audio_sample_duration = 0;
    1168  video_sample_duration = 0;
    1169 }
    1170 
    1171 } // namespace wvm
    1172 } // namespace media
    1173 } // namespace shaka
    - - -
    size_t GetHeaderSize() const override
    Definition: adts_header.cc:82
    -
    Class which implements AES-CBC (Cipher block chaining) decryption.
    Definition: aes_decryptor.h:25
    -
    virtual bool Parse(const std::vector< uint8_t > &data)
    -
    static std::shared_ptr< MediaSample > CreateEmptyMediaSample()
    Create a MediaSample object with default members.
    Definition: media_sample.cc:71
    -
    uint8_t GetObjectType() const override
    Definition: adts_header.cc:108
    -
    All the methods that are virtual are virtual for mocking.
    - -
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    -
    uint32_t GetSamplingFrequency() const override
    Definition: adts_header.cc:112
    -
    bool Parse(const std::vector< uint8_t > &data)
    - -
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: adts_header.cc:98
    -
    std::string GetCodecString(FourCC codec_fourcc) const
    - - -
    static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
    -
    bool Parse(const std::vector< uint8_t > &data)
    -
    Class for parsing AVC decoder configuration record.
    -
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: adts_header.cc:46
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    - - -
    Holds video stream information.
    -
    Holds audio stream information.
    - -
    size_t GetFrameSize() const override
    Definition: adts_header.cc:87
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/wvm/wvm_media_parser.h"
    +
    6 
    +
    7 #include <map>
    +
    8 #include <sstream>
    +
    9 #include <vector>
    +
    10 
    +
    11 #include "packager/base/strings/string_number_conversions.h"
    +
    12 #include "packager/media/base/aes_decryptor.h"
    +
    13 #include "packager/media/base/audio_stream_info.h"
    +
    14 #include "packager/media/base/key_source.h"
    +
    15 #include "packager/media/base/media_sample.h"
    +
    16 #include "packager/media/base/video_stream_info.h"
    +
    17 #include "packager/media/codecs/aac_audio_specific_config.h"
    +
    18 #include "packager/media/codecs/avc_decoder_configuration_record.h"
    +
    19 #include "packager/media/codecs/es_descriptor.h"
    +
    20 #include "packager/media/formats/mp2t/adts_header.h"
    +
    21 #include "packager/status.h"
    +
    22 
    +
    23 #define HAS_HEADER_EXTENSION(x) ((x != 0xBC) && (x != 0xBE) && (x != 0xBF) \
    +
    24  && (x != 0xF0) && (x != 0xF2) && (x != 0xF8) \
    +
    25  && (x != 0xFF))
    +
    26 
    +
    27 namespace {
    +
    28 const uint32_t kMpeg2ClockRate = 90000;
    +
    29 const uint32_t kPesOptPts = 0x80;
    +
    30 const uint32_t kPesOptDts = 0x40;
    +
    31 const uint32_t kPesOptAlign = 0x04;
    +
    32 const uint32_t kPsmStreamId = 0xBC;
    +
    33 const uint32_t kPaddingStreamId = 0xBE;
    +
    34 const uint32_t kIndexMagic = 0x49444d69;
    +
    35 const uint32_t kIndexStreamId = 0xBF; // private_stream_2
    +
    36 const uint32_t kIndexVersion4HeaderSize = 12;
    +
    37 const uint32_t kEcmStreamId = 0xF0;
    +
    38 const uint32_t kV2MetadataStreamId = 0xF1; // EMM_stream
    +
    39 const uint32_t kScramblingBitsMask = 0x30;
    +
    40 const uint32_t kStartCode1 = 0x00;
    +
    41 const uint32_t kStartCode2 = 0x00;
    +
    42 const uint32_t kStartCode3 = 0x01;
    +
    43 const uint32_t kStartCode4Pack = 0xBA;
    +
    44 const uint32_t kStartCode4System = 0xBB;
    +
    45 const uint32_t kStartCode4ProgramEnd = 0xB9;
    +
    46 const uint32_t kPesStreamIdVideoMask = 0xF0;
    +
    47 const uint32_t kPesStreamIdVideo = 0xE0;
    +
    48 const uint32_t kPesStreamIdAudioMask = 0xE0;
    +
    49 const uint32_t kPesStreamIdAudio = 0xC0;
    +
    50 const uint32_t kVersion4 = 4;
    +
    51 const uint8_t kAacSampleSizeBits = 16;
    +
    52 // Applies to all video streams.
    +
    53 const uint8_t kNaluLengthSize = 4; // unit is bytes.
    +
    54 // Placeholder sampling frequency for all audio streams, which
    +
    55 // will be overwritten after filter parsing.
    +
    56 const uint32_t kDefaultSamplingFrequency = 100;
    +
    57 const uint16_t kEcmSizeBytes = 80;
    +
    58 const uint32_t kInitializationVectorSizeBytes = 16;
    +
    59 // ECM fields for processing.
    +
    60 const uint32_t kEcmContentKeySizeBytes = 16;
    +
    61 const uint32_t kEcmDCPFlagsSizeBytes = 3;
    +
    62 const uint32_t kEcmCCIFlagsSizeBytes = 1;
    +
    63 const uint32_t kEcmFlagsSizeBytes =
    +
    64  kEcmCCIFlagsSizeBytes + kEcmDCPFlagsSizeBytes;
    +
    65 const uint32_t kEcmPaddingSizeBytes = 12;
    +
    66 const uint32_t kAssetKeySizeBytes = 16;
    +
    67 // Default audio and video PES stream IDs.
    +
    68 const uint8_t kDefaultAudioStreamId = kPesStreamIdAudio;
    +
    69 const uint8_t kDefaultVideoStreamId = kPesStreamIdVideo;
    +
    70 
    +
    71 enum Type {
    +
    72  Type_void = 0,
    +
    73  Type_uint8 = 1,
    +
    74  Type_int8 = 2,
    +
    75  Type_uint16 = 3,
    +
    76  Type_int16 = 4,
    +
    77  Type_uint32 = 5,
    +
    78  Type_int32 = 6,
    +
    79  Type_uint64 = 7,
    +
    80  Type_int64 = 8,
    +
    81  Type_string = 9,
    +
    82  Type_BinaryData = 10
    +
    83 };
    +
    84 } // namespace
    +
    85 
    +
    86 namespace shaka {
    +
    87 namespace media {
    +
    88 namespace wvm {
    +
    89 
    +
    90 WvmMediaParser::WvmMediaParser()
    +
    91  : is_initialized_(false),
    +
    92  parse_state_(StartCode1),
    +
    93  skip_bytes_(0),
    +
    94  metadata_is_complete_(false),
    +
    95  current_program_id_(0),
    +
    96  pes_stream_id_(0),
    +
    97  prev_pes_stream_id_(0),
    +
    98  pes_packet_bytes_(0),
    +
    99  pes_flags_1_(0),
    +
    100  pes_flags_2_(0),
    +
    101  prev_pes_flags_1_(0),
    +
    102  pes_header_data_bytes_(0),
    +
    103  timestamp_(0),
    +
    104  pts_(0),
    +
    105  dts_(0),
    +
    106  index_program_id_(0),
    +
    107  media_sample_(NULL),
    +
    108  crypto_unit_start_pos_(0),
    +
    109  stream_id_count_(0),
    +
    110  decryption_key_source_(NULL) {}
    +
    111 
    +
    112 WvmMediaParser::~WvmMediaParser() {}
    +
    113 
    +
    114 void WvmMediaParser::Init(const InitCB& init_cb,
    +
    115  const NewMediaSampleCB& new_media_sample_cb,
    +
    116  const NewTextSampleCB& new_text_sample_cb,
    +
    117  KeySource* decryption_key_source) {
    +
    118  DCHECK(!is_initialized_);
    +
    119  DCHECK(!init_cb.is_null());
    +
    120  DCHECK(!new_media_sample_cb.is_null());
    +
    121  decryption_key_source_ = decryption_key_source;
    +
    122  init_cb_ = init_cb;
    +
    123  new_sample_cb_ = new_media_sample_cb;
    +
    124 }
    +
    125 
    +
    126 bool WvmMediaParser::Parse(const uint8_t* buf, int size) {
    +
    127  size_t num_bytes = 0;
    +
    128  size_t prev_size = 0;
    +
    129  const uint8_t* read_ptr = buf;
    +
    130  const uint8_t* end = read_ptr + size;
    +
    131 
    +
    132  while (read_ptr < end) {
    +
    133  switch (parse_state_) {
    +
    134  case StartCode1:
    +
    135  if (*read_ptr == kStartCode1) {
    +
    136  parse_state_ = StartCode2;
    +
    137  }
    +
    138  break;
    +
    139  case StartCode2:
    +
    140  if (*read_ptr == kStartCode2) {
    +
    141  parse_state_ = StartCode3;
    +
    142  } else {
    +
    143  parse_state_ = StartCode1;
    +
    144  }
    +
    145  break;
    +
    146  case StartCode3:
    +
    147  if (*read_ptr == kStartCode3) {
    +
    148  parse_state_ = StartCode4;
    +
    149  } else {
    +
    150  parse_state_ = StartCode1;
    +
    151  }
    +
    152  break;
    +
    153  case StartCode4:
    +
    154  switch (*read_ptr) {
    +
    155  case kStartCode4Pack:
    +
    156  parse_state_ = PackHeader1;
    +
    157  break;
    +
    158  case kStartCode4System:
    +
    159  parse_state_ = SystemHeader1;
    +
    160  break;
    +
    161  case kStartCode4ProgramEnd:
    +
    162  parse_state_ = ProgramEnd;
    +
    163  continue;
    +
    164  default:
    +
    165  parse_state_ = PesStreamId;
    +
    166  continue;
    +
    167  }
    +
    168  break;
    +
    169  case PackHeader1:
    +
    170  parse_state_ = PackHeader2;
    +
    171  break;
    +
    172  case PackHeader2:
    +
    173  parse_state_ = PackHeader3;
    +
    174  break;
    +
    175  case PackHeader3:
    +
    176  parse_state_ = PackHeader4;
    +
    177  break;
    +
    178  case PackHeader4:
    +
    179  parse_state_ = PackHeader5;
    +
    180  break;
    +
    181  case PackHeader5:
    +
    182  parse_state_ = PackHeader6;
    +
    183  break;
    +
    184  case PackHeader6:
    +
    185  parse_state_ = PackHeader7;
    +
    186  break;
    +
    187  case PackHeader7:
    +
    188  parse_state_ = PackHeader8;
    +
    189  break;
    +
    190  case PackHeader8:
    +
    191  parse_state_ = PackHeader9;
    +
    192  break;
    +
    193  case PackHeader9:
    +
    194  parse_state_ = PackHeader10;
    +
    195  break;
    +
    196  case PackHeader10:
    +
    197  skip_bytes_ = *read_ptr & 0x07;
    +
    198  parse_state_ = PackHeaderStuffingSkip;
    +
    199  break;
    +
    200  case SystemHeader1:
    +
    201  skip_bytes_ = *read_ptr;
    +
    202  skip_bytes_ <<= 8;
    +
    203  parse_state_ = SystemHeader2;
    +
    204  break;
    +
    205  case SystemHeader2:
    +
    206  skip_bytes_ |= *read_ptr;
    +
    207  parse_state_ = SystemHeaderSkip;
    +
    208  break;
    +
    209  case PackHeaderStuffingSkip:
    +
    210  if (end >= skip_bytes_ + read_ptr) {
    +
    211  read_ptr += skip_bytes_;
    +
    212  skip_bytes_ = 0;
    +
    213  parse_state_ = StartCode1;
    +
    214  } else {
    +
    215  skip_bytes_ -= (end - read_ptr);
    +
    216  read_ptr = end;
    +
    217  }
    +
    218  continue;
    +
    219  case SystemHeaderSkip:
    +
    220  if (end >= skip_bytes_ + read_ptr) {
    +
    221  read_ptr += skip_bytes_;
    +
    222  skip_bytes_ = 0;
    +
    223  parse_state_ = StartCode1;
    +
    224  } else {
    +
    225  uint32_t remaining_size = end - read_ptr;
    +
    226  skip_bytes_ -= remaining_size;
    +
    227  read_ptr = end;
    +
    228  }
    +
    229  continue;
    +
    230  case PesStreamId:
    +
    231  pes_stream_id_ = *read_ptr;
    +
    232  if (!metadata_is_complete_ &&
    +
    233  (pes_stream_id_ != kPsmStreamId) &&
    +
    234  (pes_stream_id_ != kIndexStreamId) &&
    +
    235  (pes_stream_id_ != kEcmStreamId) &&
    +
    236  (pes_stream_id_ != kV2MetadataStreamId) &&
    +
    237  (pes_stream_id_ != kPaddingStreamId)) {
    +
    238  metadata_is_complete_ = true;
    +
    239  }
    +
    240  parse_state_ = PesPacketLength1;
    +
    241  break;
    +
    242  case PesPacketLength1:
    +
    243  pes_packet_bytes_ = *read_ptr;
    +
    244  pes_packet_bytes_ <<= 8;
    +
    245  parse_state_ = PesPacketLength2;
    +
    246  break;
    +
    247  case PesPacketLength2:
    +
    248  pes_packet_bytes_ |= *read_ptr;
    +
    249  if (HAS_HEADER_EXTENSION(pes_stream_id_)) {
    +
    250  parse_state_ = PesExtension1;
    +
    251  } else {
    +
    252  prev_pes_flags_1_ = pes_flags_1_;
    +
    253  pes_flags_1_ = pes_flags_2_ = 0;
    +
    254  pes_header_data_bytes_ = 0;
    +
    255  parse_state_ = PesPayload;
    +
    256  }
    +
    257  break;
    +
    258  case PesExtension1:
    +
    259  prev_pes_flags_1_ = pes_flags_1_;
    +
    260  pes_flags_1_ = *read_ptr;
    +
    261  --pes_packet_bytes_;
    +
    262  parse_state_ = PesExtension2;
    +
    263  break;
    +
    264  case PesExtension2:
    +
    265  pes_flags_2_ = *read_ptr;
    +
    266  --pes_packet_bytes_;
    +
    267  parse_state_ = PesExtension3;
    +
    268  break;
    +
    269  case PesExtension3:
    +
    270  pes_header_data_bytes_ = *read_ptr;
    +
    271  --pes_packet_bytes_;
    +
    272  if (pes_flags_2_ & kPesOptPts) {
    +
    273  parse_state_ = Pts1;
    +
    274  } else {
    +
    275  parse_state_ = PesHeaderData;
    +
    276  }
    +
    277  break;
    +
    278  case Pts1:
    +
    279  timestamp_ = (*read_ptr & 0x0E);
    +
    280  --pes_header_data_bytes_;
    +
    281  --pes_packet_bytes_;
    +
    282  parse_state_ = Pts2;
    +
    283  break;
    +
    284  case Pts2:
    +
    285  timestamp_ <<= 7;
    +
    286  timestamp_ |= *read_ptr;
    +
    287  --pes_header_data_bytes_;
    +
    288  --pes_packet_bytes_;
    +
    289  parse_state_ = Pts3;
    +
    290  break;
    +
    291  case Pts3:
    +
    292  timestamp_ <<= 7;
    +
    293  timestamp_ |= *read_ptr >> 1;
    +
    294  --pes_header_data_bytes_;
    +
    295  --pes_packet_bytes_;
    +
    296  parse_state_ = Pts4;
    +
    297  break;
    +
    298  case Pts4:
    +
    299  timestamp_ <<= 8;
    +
    300  timestamp_ |= *read_ptr;
    +
    301  --pes_header_data_bytes_;
    +
    302  --pes_packet_bytes_;
    +
    303  parse_state_ = Pts5;
    +
    304  break;
    +
    305  case Pts5:
    +
    306  timestamp_ <<= 7;
    +
    307  timestamp_ |= *read_ptr >> 1;
    +
    308  pts_ = timestamp_;
    +
    309  --pes_header_data_bytes_;
    +
    310  --pes_packet_bytes_;
    +
    311  if (pes_flags_2_ & kPesOptDts) {
    +
    312  parse_state_ = Dts1;
    +
    313  } else {
    +
    314  dts_ = pts_;
    +
    315  parse_state_ = PesHeaderData;
    +
    316  }
    +
    317  break;
    +
    318  case Dts1:
    +
    319  timestamp_ = (*read_ptr & 0x0E);
    +
    320  --pes_header_data_bytes_;
    +
    321  --pes_packet_bytes_;
    +
    322  parse_state_ = Dts2;
    +
    323  break;
    +
    324  case Dts2:
    +
    325  timestamp_ <<= 7;
    +
    326  timestamp_ |= *read_ptr;
    +
    327  --pes_header_data_bytes_;
    +
    328  --pes_packet_bytes_;
    +
    329  parse_state_ = Dts3;
    +
    330  break;
    +
    331  case Dts3:
    +
    332  timestamp_ <<= 7;
    +
    333  timestamp_ |= *read_ptr >> 1;
    +
    334  --pes_header_data_bytes_;
    +
    335  --pes_packet_bytes_;
    +
    336  parse_state_ = Dts4;
    +
    337  break;
    +
    338  case Dts4:
    +
    339  timestamp_ <<= 8;
    +
    340  timestamp_ |= *read_ptr;
    +
    341  --pes_header_data_bytes_;
    +
    342  --pes_packet_bytes_;
    +
    343  parse_state_ = Dts5;
    +
    344  break;
    +
    345  case Dts5:
    +
    346  timestamp_ <<= 7;
    +
    347  timestamp_ |= *read_ptr >> 1;
    +
    348  dts_ = timestamp_;
    +
    349  --pes_header_data_bytes_;
    +
    350  --pes_packet_bytes_;
    +
    351  parse_state_ = PesHeaderData;
    +
    352  break;
    +
    353  case PesHeaderData:
    +
    354  num_bytes = end - read_ptr;
    +
    355  if (num_bytes >= pes_header_data_bytes_) {
    +
    356  num_bytes = pes_header_data_bytes_;
    +
    357  parse_state_ = PesPayload;
    +
    358  }
    +
    359  pes_header_data_bytes_ -= num_bytes;
    +
    360  pes_packet_bytes_ -= num_bytes;
    +
    361  read_ptr += num_bytes;
    +
    362  continue;
    +
    363  case PesPayload:
    +
    364  switch (pes_stream_id_) {
    +
    365  case kPsmStreamId:
    +
    366  psm_data_.clear();
    +
    367  parse_state_ = PsmPayload;
    +
    368  continue;
    +
    369  case kPaddingStreamId:
    +
    370  parse_state_ = Padding;
    +
    371  continue;
    +
    372  case kEcmStreamId:
    +
    373  ecm_.clear();
    +
    374  parse_state_ = EcmPayload;
    +
    375  continue;
    +
    376  case kIndexStreamId:
    +
    377  parse_state_ = IndexPayload;
    +
    378  continue;
    +
    379  default:
    +
    380  if (!DemuxNextPes(false)) {
    +
    381  return false;
    +
    382  }
    +
    383  parse_state_ = EsPayload;
    +
    384  }
    +
    385  continue;
    +
    386  case PsmPayload:
    +
    387  num_bytes = end - read_ptr;
    +
    388  if (num_bytes >= pes_packet_bytes_) {
    +
    389  num_bytes = pes_packet_bytes_;
    +
    390  parse_state_ = StartCode1;
    +
    391  }
    +
    392  if (num_bytes > 0) {
    +
    393  pes_packet_bytes_ -= num_bytes;
    +
    394  prev_size = psm_data_.size();
    +
    395  psm_data_.resize(prev_size + num_bytes);
    +
    396  memcpy(&psm_data_[prev_size], read_ptr, num_bytes);
    +
    397  }
    +
    398  read_ptr += num_bytes;
    +
    399  continue;
    +
    400  case EcmPayload:
    +
    401  num_bytes = end - read_ptr;
    +
    402  if (num_bytes >= pes_packet_bytes_) {
    +
    403  num_bytes = pes_packet_bytes_;
    +
    404  parse_state_ = StartCode1;
    +
    405  }
    +
    406  if (num_bytes > 0) {
    +
    407  pes_packet_bytes_ -= num_bytes;
    +
    408  prev_size = ecm_.size();
    +
    409  ecm_.resize(prev_size + num_bytes);
    +
    410  memcpy(&ecm_[prev_size], read_ptr, num_bytes);
    +
    411  }
    +
    412  if ((pes_packet_bytes_ == 0) && !ecm_.empty()) {
    +
    413  if (!ProcessEcm()) {
    +
    414  return(false);
    +
    415  }
    +
    416  }
    +
    417  read_ptr += num_bytes;
    +
    418  continue;
    +
    419  case IndexPayload:
    +
    420  num_bytes = end - read_ptr;
    +
    421  if (num_bytes >= pes_packet_bytes_) {
    +
    422  num_bytes = pes_packet_bytes_;
    +
    423  parse_state_ = StartCode1;
    +
    424  }
    +
    425  if (num_bytes > 0) {
    +
    426  pes_packet_bytes_ -= num_bytes;
    +
    427  prev_size = index_data_.size();
    +
    428  index_data_.resize(prev_size + num_bytes);
    +
    429  memcpy(&index_data_[prev_size], read_ptr, num_bytes);
    +
    430  }
    +
    431  if (pes_packet_bytes_ == 0 && !index_data_.empty()) {
    +
    432  if (!metadata_is_complete_) {
    +
    433  if (!ParseIndexEntry()) {
    +
    434  return false;
    +
    435  }
    +
    436  }
    +
    437  }
    +
    438  read_ptr += num_bytes;
    +
    439  continue;
    +
    440  case EsPayload:
    +
    441  num_bytes = end - read_ptr;
    +
    442  if (num_bytes >= pes_packet_bytes_) {
    +
    443  num_bytes = pes_packet_bytes_;
    +
    444  parse_state_ = StartCode1;
    +
    445  }
    +
    446  pes_packet_bytes_ -= num_bytes;
    +
    447  if (pes_stream_id_ != kV2MetadataStreamId) {
    +
    448  sample_data_.resize(sample_data_.size() + num_bytes);
    +
    449  memcpy(&sample_data_[sample_data_.size() - num_bytes], read_ptr,
    +
    450  num_bytes);
    +
    451  }
    +
    452  prev_pes_stream_id_ = pes_stream_id_;
    +
    453  read_ptr += num_bytes;
    +
    454  continue;
    +
    455  case Padding:
    +
    456  num_bytes = end - read_ptr;
    +
    457  if (num_bytes >= pes_packet_bytes_) {
    +
    458  num_bytes = pes_packet_bytes_;
    +
    459  parse_state_ = StartCode1;
    +
    460  }
    +
    461  pes_packet_bytes_ -= num_bytes;
    +
    462  read_ptr += num_bytes;
    +
    463  continue;
    +
    464  case ProgramEnd:
    +
    465  parse_state_ = StartCode1;
    +
    466  metadata_is_complete_ = true;
    +
    467  if (!DemuxNextPes(true)) {
    +
    468  return false;
    +
    469  }
    +
    470  if (!Flush()) {
    +
    471  return false;
    +
    472  }
    +
    473  // Reset.
    +
    474  dts_ = pts_ = 0;
    +
    475  parse_state_ = StartCode1;
    +
    476  prev_media_sample_data_.Reset();
    +
    477  current_program_id_++;
    +
    478  ecm_.clear();
    +
    479  index_data_.clear();
    +
    480  psm_data_.clear();
    +
    481  break;
    +
    482  default:
    +
    483  break;
    +
    484  }
    +
    485  ++read_ptr;
    +
    486  }
    +
    487  return true;
    +
    488 }
    +
    489 
    +
    490 bool WvmMediaParser::EmitLastSample(
    +
    491  uint32_t stream_id,
    +
    492  const std::shared_ptr<MediaSample>& new_sample) {
    +
    493  std::string key = base::UintToString(current_program_id_)
    +
    494  .append(":")
    +
    495  .append(base::UintToString(stream_id));
    +
    496  std::map<std::string, uint32_t>::iterator it =
    +
    497  program_demux_stream_map_.find(key);
    +
    498  if (it == program_demux_stream_map_.end())
    +
    499  return false;
    +
    500  return EmitSample(stream_id, (*it).second, new_sample, true);
    +
    501 }
    +
    502 
    +
    503 bool WvmMediaParser::EmitPendingSamples() {
    +
    504  // Emit queued samples which were built when not initialized.
    +
    505  while (!media_sample_queue_.empty()) {
    +
    506  DemuxStreamIdMediaSample& demux_stream_media_sample =
    +
    507  media_sample_queue_.front();
    +
    508  if (!EmitSample(demux_stream_media_sample.parsed_audio_or_video_stream_id,
    +
    509  demux_stream_media_sample.demux_stream_id,
    +
    510  demux_stream_media_sample.media_sample,
    +
    511  false)) {
    +
    512  return false;
    +
    513  }
    +
    514  media_sample_queue_.pop_front();
    +
    515  }
    +
    516  return true;
    +
    517 }
    +
    518 
    +
    519 bool WvmMediaParser::Flush() {
    +
    520  // Flush the last audio and video sample for current program.
    +
    521  // Reset the streamID when successfully emitted.
    +
    522  if (prev_media_sample_data_.audio_sample != NULL) {
    +
    523  if (!EmitLastSample(prev_pes_stream_id_,
    +
    524  prev_media_sample_data_.audio_sample)) {
    +
    525  LOG(ERROR) << "Did not emit last sample for audio stream with ID = "
    +
    526  << prev_pes_stream_id_;
    +
    527  return false;
    +
    528  }
    +
    529  }
    +
    530  if (prev_media_sample_data_.video_sample != NULL) {
    +
    531  if (!EmitLastSample(prev_pes_stream_id_,
    +
    532  prev_media_sample_data_.video_sample)) {
    +
    533  LOG(ERROR) << "Did not emit last sample for video stream with ID = "
    +
    534  << prev_pes_stream_id_;
    +
    535  return false;
    +
    536  }
    +
    537  }
    +
    538  return true;
    +
    539 }
    +
    540 
    +
    541 bool WvmMediaParser::ParseIndexEntry() {
    +
    542  // Do not parse index entry at the beginning of any track *after* the first
    +
    543  // track.
    +
    544  if (current_program_id_ > 0) {
    +
    545  return true;
    +
    546  }
    +
    547  uint32_t index_size = 0;
    +
    548  if (index_data_.size() < kIndexVersion4HeaderSize) {
    +
    549  return false;
    +
    550  }
    +
    551 
    +
    552  const uint8_t* read_ptr = index_data_.data();
    +
    553  if (ntohlFromBuffer(read_ptr) != kIndexMagic) {
    +
    554  index_data_.clear();
    +
    555  return false;
    +
    556  }
    +
    557  read_ptr += 4;
    +
    558 
    +
    559  uint32_t version = ntohlFromBuffer(read_ptr);
    +
    560  read_ptr += 4;
    +
    561  if (version == kVersion4) {
    +
    562  index_size = kIndexVersion4HeaderSize + ntohlFromBuffer(read_ptr);
    +
    563  if (index_data_.size() < index_size) {
    +
    564  // We do not yet have the full index. Keep accumulating index data.
    +
    565  return true;
    +
    566  }
    +
    567  read_ptr += sizeof(uint32_t);
    +
    568 
    +
    569  // Index metadata
    +
    570  uint32_t index_metadata_max_size = index_size - kIndexVersion4HeaderSize;
    +
    571  if (index_metadata_max_size < sizeof(uint8_t)) {
    +
    572  index_data_.clear();
    +
    573  return false;
    +
    574  }
    +
    575 
    +
    576  uint64_t track_duration = 0;
    +
    577  uint32_t trick_play_factor = 0;
    +
    578  uint32_t sampling_frequency = kDefaultSamplingFrequency;
    +
    579  uint32_t time_scale = kMpeg2ClockRate;
    +
    580  uint16_t video_width = 0;
    +
    581  uint16_t video_height = 0;
    +
    582  uint32_t pixel_width = 0;
    +
    583  uint32_t pixel_height = 0;
    +
    584  uint8_t nalu_length_size = kNaluLengthSize;
    +
    585  uint8_t num_channels = 0;
    +
    586  int audio_pes_stream_id = 0;
    +
    587  int video_pes_stream_id = 0;
    +
    588  bool has_video = false;
    +
    589  bool has_audio = false;
    +
    590  std::vector<uint8_t> audio_codec_config;
    +
    591  std::vector<uint8_t> video_codec_config;
    +
    592  uint8_t num_index_entries = *read_ptr;
    +
    593  ++read_ptr;
    +
    594  --index_metadata_max_size;
    +
    595 
    +
    596  for (uint8_t idx = 0; idx < num_index_entries; ++idx) {
    +
    597  if (index_metadata_max_size < (2 * sizeof(uint8_t)) + sizeof(uint32_t)) {
    +
    598  return false;
    +
    599  }
    +
    600  uint8_t tag = *read_ptr;
    +
    601  ++read_ptr;
    +
    602  uint8_t type = *read_ptr;
    +
    603  ++read_ptr;
    +
    604  uint32_t length = ntohlFromBuffer(read_ptr);
    +
    605  read_ptr += sizeof(uint32_t);
    +
    606  index_metadata_max_size -= (2 * sizeof(uint8_t)) + sizeof(uint32_t);
    +
    607  if (index_metadata_max_size < length) {
    +
    608  return false;
    +
    609  }
    +
    610  int64_t value = 0;
    +
    611  Tag tagtype = Unset;
    +
    612  std::vector<uint8_t> binary_data;
    +
    613  switch (Type(type)) {
    +
    614  case Type_uint8:
    +
    615  if (length == sizeof(uint8_t)) {
    +
    616  tagtype = GetTag(tag, length, read_ptr, &value);
    +
    617  } else {
    +
    618  return false;
    +
    619  }
    +
    620  break;
    +
    621  case Type_int8:
    +
    622  if (length == sizeof(int8_t)) {
    +
    623  tagtype = GetTag(tag, length, read_ptr, &value);
    +
    624  } else {
    +
    625  return false;
    +
    626  }
    +
    627  break;
    +
    628  case Type_uint16:
    +
    629  if (length == sizeof(uint16_t)) {
    +
    630  tagtype = GetTag(tag, length, read_ptr, &value);
    +
    631  } else {
    +
    632  return false;
    +
    633  }
    +
    634  break;
    +
    635  case Type_int16:
    +
    636  if (length == sizeof(int16_t)) {
    +
    637  tagtype = GetTag(tag, length, read_ptr, &value);
    +
    638  } else {
    +
    639  return false;
    +
    640  }
    +
    641  break;
    +
    642  case Type_uint32:
    +
    643  if (length == sizeof(uint32_t)) {
    +
    644  tagtype = GetTag(tag, length, read_ptr, &value);
    +
    645  } else {
    +
    646  return false;
    +
    647  }
    +
    648  break;
    +
    649  case Type_int32:
    +
    650  if (length == sizeof(int32_t)) {
    +
    651  tagtype = GetTag(tag, length, read_ptr, &value);
    +
    652  } else {
    +
    653  return false;
    +
    654  }
    +
    655  break;
    +
    656  case Type_uint64:
    +
    657  if (length == sizeof(uint64_t)) {
    +
    658  tagtype = GetTag(tag, length, read_ptr, &value);
    +
    659  } else {
    +
    660  return false;
    +
    661  }
    +
    662  break;
    +
    663  case Type_int64:
    +
    664  if (length == sizeof(int64_t)) {
    +
    665  tagtype = GetTag(tag, length, read_ptr, &value);
    +
    666  } else {
    +
    667  return false;
    +
    668  }
    +
    669  break;
    +
    670  case Type_string:
    +
    671  case Type_BinaryData:
    +
    672  binary_data.assign(read_ptr, read_ptr + length);
    +
    673  tagtype = Tag(tag);
    +
    674  break;
    +
    675  default:
    +
    676  break;
    +
    677  }
    +
    678 
    +
    679  switch (tagtype) {
    +
    680  case TrackDuration:
    +
    681  track_duration = value;
    +
    682  break;
    +
    683  case TrackTrickPlayFactor:
    +
    684  trick_play_factor = value;
    +
    685  break;
    +
    686  case VideoStreamId:
    +
    687  video_pes_stream_id = value;
    +
    688  break;
    +
    689  case AudioStreamId:
    +
    690  audio_pes_stream_id = value;
    +
    691  break;
    +
    692  case VideoWidth:
    +
    693  video_width = (uint16_t)value;
    +
    694  break;
    +
    695  case VideoHeight:
    +
    696  video_height = (uint16_t)value;
    +
    697  break;
    +
    698  case AudioNumChannels:
    +
    699  num_channels = (uint8_t)value;
    +
    700  break;
    +
    701  case VideoType:
    +
    702  has_video = true;
    +
    703  break;
    +
    704  case AudioType:
    +
    705  has_audio = true;
    +
    706  break;
    +
    707  case VideoPixelWidth:
    +
    708  pixel_width = static_cast<uint32_t>(value);
    +
    709  break;
    +
    710  case VideoPixelHeight:
    +
    711  pixel_height = static_cast<uint32_t>(value);
    +
    712  break;
    +
    713  case Audio_EsDescriptor: {
    +
    714  ESDescriptor descriptor;
    +
    715  if (!descriptor.Parse(binary_data)) {
    +
    716  LOG(ERROR) <<
    +
    717  "Could not extract AudioSpecificConfig from ES_Descriptor";
    +
    718  return false;
    +
    719  }
    +
    720  audio_codec_config = descriptor.decoder_config_descriptor()
    +
    721  .decoder_specific_info_descriptor()
    +
    722  .data();
    +
    723  break;
    +
    724  }
    +
    725  case Audio_EC3SpecificData:
    +
    726  case Audio_DtsSpecificData:
    +
    727  case Audio_AC3SpecificData:
    +
    728  LOG(ERROR) << "Audio type not supported.";
    +
    729  return false;
    +
    730  case Video_AVCDecoderConfigurationRecord:
    +
    731  video_codec_config = binary_data;
    +
    732  break;
    +
    733  default:
    +
    734  break;
    +
    735  }
    +
    736 
    +
    737  read_ptr += length;
    +
    738  index_metadata_max_size -= length;
    +
    739  }
    +
    740  // End Index metadata
    +
    741  index_size = read_ptr - index_data_.data();
    +
    742 
    +
    743  if (has_video) {
    +
    744  stream_infos_.emplace_back(new VideoStreamInfo(
    +
    745  stream_id_count_, time_scale, track_duration, kCodecH264,
    +
    746  byte_to_unit_stream_converter_.stream_format(), std::string(),
    +
    747  video_codec_config.data(), video_codec_config.size(), video_width,
    +
    748  video_height, pixel_width, pixel_height,
    +
    749  0 /* transfer_characteristics */, trick_play_factor, nalu_length_size,
    +
    750  std::string(), decryption_key_source_ ? false : true));
    +
    751  program_demux_stream_map_[base::UintToString(index_program_id_) + ":" +
    +
    752  base::UintToString(
    +
    753  video_pes_stream_id
    +
    754  ? video_pes_stream_id
    +
    755  : kDefaultVideoStreamId)] =
    +
    756  stream_id_count_++;
    +
    757  }
    +
    758  if (has_audio) {
    +
    759  const Codec audio_codec = kCodecAAC;
    +
    760  // TODO(beil): Pass in max and average bitrate in wvm container.
    +
    761  stream_infos_.emplace_back(new AudioStreamInfo(
    +
    762  stream_id_count_, time_scale, track_duration, audio_codec,
    +
    763  std::string(), audio_codec_config.data(), audio_codec_config.size(),
    +
    764  kAacSampleSizeBits, num_channels, sampling_frequency,
    +
    765  0 /* seek preroll */, 0 /* codec delay */, 0 /* max bitrate */,
    +
    766  0 /* avg bitrate */, std::string(),
    +
    767  decryption_key_source_ ? false : true));
    +
    768  program_demux_stream_map_[base::UintToString(index_program_id_) + ":" +
    +
    769  base::UintToString(
    +
    770  audio_pes_stream_id
    +
    771  ? audio_pes_stream_id
    +
    772  : kDefaultAudioStreamId)] =
    +
    773  stream_id_count_++;
    +
    774  }
    +
    775  }
    +
    776 
    +
    777  index_program_id_++;
    +
    778  index_data_.clear();
    +
    779  return true;
    +
    780 }
    +
    781 
    +
    782 bool WvmMediaParser::DemuxNextPes(bool is_program_end) {
    +
    783  bool output_encrypted_sample = false;
    +
    784  if (!sample_data_.empty() && (prev_pes_flags_1_ & kScramblingBitsMask)) {
    +
    785  // Decrypt crypto unit.
    +
    786  if (!content_decryptor_) {
    +
    787  output_encrypted_sample = true;
    +
    788  } else {
    +
    789  content_decryptor_->Crypt(&sample_data_[crypto_unit_start_pos_],
    +
    790  sample_data_.size() - crypto_unit_start_pos_,
    +
    791  &sample_data_[crypto_unit_start_pos_]);
    +
    792  }
    +
    793  }
    +
    794  // Demux media sample if we are at program end or if we are not at a
    +
    795  // continuation PES.
    +
    796  if ((pes_flags_2_ & kPesOptPts) || is_program_end) {
    +
    797  if (!sample_data_.empty()) {
    +
    798  if (!Output(output_encrypted_sample)) {
    +
    799  return false;
    +
    800  }
    +
    801  }
    +
    802  StartMediaSampleDemux();
    +
    803  }
    +
    804 
    +
    805  crypto_unit_start_pos_ = sample_data_.size();
    +
    806  return true;
    +
    807 }
    +
    808 
    +
    809 void WvmMediaParser::StartMediaSampleDemux() {
    +
    810  bool is_key_frame = ((pes_flags_1_ & kPesOptAlign) != 0);
    +
    811  media_sample_ = MediaSample::CreateEmptyMediaSample();
    +
    812  media_sample_->set_dts(dts_);
    +
    813  media_sample_->set_pts(pts_);
    +
    814  media_sample_->set_is_key_frame(is_key_frame);
    +
    815 
    +
    816  sample_data_.clear();
    +
    817 }
    +
    818 
    +
    819 bool WvmMediaParser::Output(bool output_encrypted_sample) {
    +
    820  if (output_encrypted_sample) {
    +
    821  media_sample_->SetData(sample_data_.data(), sample_data_.size());
    +
    822  media_sample_->set_is_encrypted(true);
    +
    823  } else {
    +
    824  if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
    +
    825  // Convert video stream to unit stream and get config.
    +
    826  std::vector<uint8_t> nal_unit_stream;
    +
    827  if (!byte_to_unit_stream_converter_.ConvertByteStreamToNalUnitStream(
    +
    828  sample_data_.data(), sample_data_.size(), &nal_unit_stream)) {
    +
    829  LOG(ERROR) << "Could not convert h.264 byte stream sample";
    +
    830  return false;
    +
    831  }
    +
    832  media_sample_->SetData(nal_unit_stream.data(), nal_unit_stream.size());
    +
    833  if (!is_initialized_) {
    +
    834  // Set extra data for video stream from AVC Decoder Config Record.
    +
    835  // Also, set codec string from the AVC Decoder Config Record.
    +
    836  std::vector<uint8_t> decoder_config_record;
    +
    837  byte_to_unit_stream_converter_.GetDecoderConfigurationRecord(
    +
    838  &decoder_config_record);
    +
    839  for (uint32_t i = 0; i < stream_infos_.size(); i++) {
    +
    840  if (stream_infos_[i]->stream_type() == kStreamVideo &&
    +
    841  stream_infos_[i]->codec_string().empty()) {
    +
    842  const std::vector<uint8_t>* stream_config;
    +
    843  if (stream_infos_[i]->codec_config().empty()) {
    +
    844  // Decoder config record not available for stream. Use the one
    +
    845  // computed from the first video stream.
    +
    846  stream_infos_[i]->set_codec_config(decoder_config_record);
    +
    847  stream_config = &decoder_config_record;
    +
    848  } else {
    +
    849  // Use stream-specific config record.
    +
    850  stream_config = &stream_infos_[i]->codec_config();
    +
    851  }
    +
    852  DCHECK(stream_config);
    +
    853 
    +
    854  VideoStreamInfo* video_stream_info =
    +
    855  reinterpret_cast<VideoStreamInfo*>(stream_infos_[i].get());
    +
    856  AVCDecoderConfigurationRecord avc_config;
    +
    857  if (!avc_config.Parse(*stream_config)) {
    +
    858  LOG(WARNING) << "Failed to parse AVCDecoderConfigurationRecord. "
    +
    859  "Using computed configuration record instead.";
    +
    860  video_stream_info->set_codec_config(decoder_config_record);
    +
    861  if (!avc_config.Parse(decoder_config_record)) {
    +
    862  LOG(ERROR) << "Failed to parse AVCDecoderConfigurationRecord.";
    +
    863  return false;
    +
    864  }
    +
    865  }
    +
    866  const FourCC codec_fourcc =
    +
    867  byte_to_unit_stream_converter_.stream_format() ==
    +
    868  H26xStreamFormat::kNalUnitStreamWithParameterSetNalus
    +
    869  ? FOURCC_avc3
    +
    870  : FOURCC_avc1;
    +
    871  video_stream_info->set_codec_string(
    +
    872  avc_config.GetCodecString(codec_fourcc));
    +
    873 
    +
    874  if (avc_config.pixel_width() != video_stream_info->pixel_width() ||
    +
    875  avc_config.pixel_height() !=
    +
    876  video_stream_info->pixel_height()) {
    +
    877  LOG_IF(WARNING, video_stream_info->pixel_width() != 0 ||
    +
    878  video_stream_info->pixel_height() != 0)
    +
    879  << "Pixel aspect ratio in WVM metadata ("
    +
    880  << video_stream_info->pixel_width() << ","
    +
    881  << video_stream_info->pixel_height()
    +
    882  << ") does not match with SAR in "
    +
    883  "AVCDecoderConfigurationRecord ("
    +
    884  << avc_config.pixel_width() << ","
    +
    885  << avc_config.pixel_height()
    +
    886  << "). Use AVCDecoderConfigurationRecord.";
    +
    887  video_stream_info->set_pixel_width(avc_config.pixel_width());
    +
    888  video_stream_info->set_pixel_height(avc_config.pixel_height());
    +
    889  }
    +
    890  if (avc_config.coded_width() != video_stream_info->width() ||
    +
    891  avc_config.coded_height() != video_stream_info->height()) {
    +
    892  LOG(WARNING) << "Resolution in WVM metadata ("
    +
    893  << video_stream_info->width() << ","
    +
    894  << video_stream_info->height()
    +
    895  << ") does not match with resolution in "
    +
    896  "AVCDecoderConfigurationRecord ("
    +
    897  << avc_config.coded_width() << ","
    +
    898  << avc_config.coded_height()
    +
    899  << "). Use AVCDecoderConfigurationRecord.";
    +
    900  video_stream_info->set_width(avc_config.coded_width());
    +
    901  video_stream_info->set_height(avc_config.coded_height());
    +
    902  }
    +
    903  }
    +
    904  }
    +
    905  }
    +
    906  } else if ((prev_pes_stream_id_ & kPesStreamIdAudioMask) ==
    +
    907  kPesStreamIdAudio) {
    +
    908  // Set data on the audio stream.
    +
    909  mp2t::AdtsHeader adts_header;
    +
    910  const uint8_t* frame_ptr = sample_data_.data();
    +
    911  if (!adts_header.Parse(frame_ptr, sample_data_.size())) {
    +
    912  LOG(ERROR) << "Could not parse ADTS header";
    +
    913  return false;
    +
    914  }
    +
    915  media_sample_->SetData(
    +
    916  frame_ptr + adts_header.GetHeaderSize(),
    +
    917  adts_header.GetFrameSize() - adts_header.GetHeaderSize());
    +
    918  if (!is_initialized_) {
    +
    919  for (uint32_t i = 0; i < stream_infos_.size(); i++) {
    +
    920  if (stream_infos_[i]->stream_type() == kStreamAudio &&
    +
    921  stream_infos_[i]->codec_string().empty()) {
    +
    922  AudioStreamInfo* audio_stream_info =
    +
    923  reinterpret_cast<AudioStreamInfo*>(stream_infos_[i].get());
    +
    924  if (audio_stream_info->codec_config().empty()) {
    +
    925  // Set AudioStreamInfo fields using information from the ADTS
    +
    926  // header.
    +
    927  audio_stream_info->set_sampling_frequency(
    +
    928  adts_header.GetSamplingFrequency());
    +
    929  std::vector<uint8_t> audio_specific_config;
    +
    930  adts_header.GetAudioSpecificConfig(&audio_specific_config);
    +
    931  audio_stream_info->set_codec_config(audio_specific_config);
    +
    932  audio_stream_info->set_codec_string(
    +
    933  AudioStreamInfo::GetCodecString(
    +
    934  kCodecAAC, adts_header.GetObjectType()));
    +
    935  } else {
    +
    936  // Set AudioStreamInfo fields using information from the
    +
    937  // AACAudioSpecificConfig record.
    +
    938  AACAudioSpecificConfig aac_config;
    +
    939  if (!aac_config.Parse(stream_infos_[i]->codec_config())) {
    +
    940  LOG(ERROR) << "Could not parse AACAudioSpecificconfig";
    +
    941  return false;
    +
    942  }
    +
    943  audio_stream_info->set_sampling_frequency(
    +
    944  aac_config.GetSamplesPerSecond());
    +
    945  audio_stream_info->set_codec_string(
    +
    946  AudioStreamInfo::GetCodecString(
    +
    947  kCodecAAC, aac_config.GetAudioObjectType()));
    +
    948  }
    +
    949  }
    +
    950  }
    +
    951  }
    +
    952  }
    +
    953  }
    +
    954 
    +
    955  if (!is_initialized_) {
    +
    956  bool all_streams_have_config = true;
    +
    957  // Check if all collected stream infos have codec_config set.
    +
    958  for (uint32_t i = 0; i < stream_infos_.size(); i++) {
    +
    959  if (stream_infos_[i]->codec_string().empty()) {
    +
    960  all_streams_have_config = false;
    +
    961  break;
    +
    962  }
    +
    963  }
    +
    964  if (all_streams_have_config) {
    +
    965  init_cb_.Run(stream_infos_);
    +
    966  is_initialized_ = true;
    +
    967  }
    +
    968  }
    +
    969 
    +
    970  DCHECK_GT(media_sample_->data_size(), 0UL);
    +
    971  std::string key = base::UintToString(current_program_id_).append(":")
    +
    972  .append(base::UintToString(prev_pes_stream_id_));
    +
    973  std::map<std::string, uint32_t>::iterator it =
    +
    974  program_demux_stream_map_.find(key);
    +
    975  if (it == program_demux_stream_map_.end()) {
    +
    976  // TODO(ramjic): Log error message here and in other error cases through
    +
    977  // this method.
    +
    978  return false;
    +
    979  }
    +
    980  DemuxStreamIdMediaSample demux_stream_media_sample;
    +
    981  demux_stream_media_sample.parsed_audio_or_video_stream_id =
    +
    982  prev_pes_stream_id_;
    +
    983  demux_stream_media_sample.demux_stream_id = (*it).second;
    +
    984  demux_stream_media_sample.media_sample = media_sample_;
    +
    985  // Check if sample can be emitted.
    +
    986  if (!is_initialized_) {
    +
    987  media_sample_queue_.push_back(demux_stream_media_sample);
    +
    988  } else {
    +
    989  // flush the sample queue and emit all queued samples.
    +
    990  while (!media_sample_queue_.empty()) {
    +
    991  if (!EmitPendingSamples())
    +
    992  return false;
    +
    993  }
    +
    994  // Emit current sample.
    +
    995  if (!EmitSample(prev_pes_stream_id_, (*it).second, media_sample_, false))
    +
    996  return false;
    +
    997  }
    +
    998  return true;
    +
    999 }
    +
    1000 
    +
    1001 bool WvmMediaParser::EmitSample(uint32_t parsed_audio_or_video_stream_id,
    +
    1002  uint32_t stream_id,
    +
    1003  const std::shared_ptr<MediaSample>& new_sample,
    +
    1004  bool isLastSample) {
    +
    1005  DCHECK(new_sample);
    +
    1006  if (isLastSample) {
    +
    1007  if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
    +
    1008  kPesStreamIdVideo) {
    +
    1009  new_sample->set_duration(prev_media_sample_data_.video_sample_duration);
    +
    1010  } else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
    +
    1011  kPesStreamIdAudio) {
    +
    1012  new_sample->set_duration(prev_media_sample_data_.audio_sample_duration);
    +
    1013  }
    +
    1014  if (!new_sample_cb_.Run(stream_id, new_sample)) {
    +
    1015  LOG(ERROR) << "Failed to process the last sample.";
    +
    1016  return false;
    +
    1017  }
    +
    1018  return true;
    +
    1019  }
    +
    1020 
    +
    1021  // Cannot emit current sample. Compute duration first and then,
    +
    1022  // emit previous sample.
    +
    1023  if ((parsed_audio_or_video_stream_id & kPesStreamIdVideoMask) ==
    +
    1024  kPesStreamIdVideo) {
    +
    1025  if (prev_media_sample_data_.video_sample == NULL) {
    +
    1026  prev_media_sample_data_.video_sample = new_sample;
    +
    1027  prev_media_sample_data_.video_stream_id = stream_id;
    +
    1028  return true;
    +
    1029  }
    +
    1030  prev_media_sample_data_.video_sample->set_duration(
    +
    1031  new_sample->dts() - prev_media_sample_data_.video_sample->dts());
    +
    1032  prev_media_sample_data_.video_sample_duration =
    +
    1033  prev_media_sample_data_.video_sample->duration();
    +
    1034  if (!new_sample_cb_.Run(prev_media_sample_data_.video_stream_id,
    +
    1035  prev_media_sample_data_.video_sample)) {
    +
    1036  LOG(ERROR) << "Failed to process the video sample.";
    +
    1037  return false;
    +
    1038  }
    +
    1039  prev_media_sample_data_.video_sample = new_sample;
    +
    1040  prev_media_sample_data_.video_stream_id = stream_id;
    +
    1041  } else if ((parsed_audio_or_video_stream_id & kPesStreamIdAudioMask) ==
    +
    1042  kPesStreamIdAudio) {
    +
    1043  if (prev_media_sample_data_.audio_sample == NULL) {
    +
    1044  prev_media_sample_data_.audio_sample = new_sample;
    +
    1045  prev_media_sample_data_.audio_stream_id = stream_id;
    +
    1046  return true;
    +
    1047  }
    +
    1048  prev_media_sample_data_.audio_sample->set_duration(
    +
    1049  new_sample->dts() - prev_media_sample_data_.audio_sample->dts());
    +
    1050  prev_media_sample_data_.audio_sample_duration =
    +
    1051  prev_media_sample_data_.audio_sample->duration();
    +
    1052  if (!new_sample_cb_.Run(prev_media_sample_data_.audio_stream_id,
    +
    1053  prev_media_sample_data_.audio_sample)) {
    +
    1054  LOG(ERROR) << "Failed to process the audio sample.";
    +
    1055  return false;
    +
    1056  }
    +
    1057  prev_media_sample_data_.audio_sample = new_sample;
    +
    1058  prev_media_sample_data_.audio_stream_id = stream_id;
    +
    1059  }
    +
    1060  return true;
    +
    1061 }
    +
    1062 
    +
    1063 bool WvmMediaParser::GetAssetKey(const uint8_t* asset_id,
    +
    1064  EncryptionKey* encryption_key) {
    +
    1065  DCHECK(decryption_key_source_);
    +
    1066  Status status = decryption_key_source_->FetchKeys(
    +
    1067  EmeInitDataType::WIDEVINE_CLASSIC,
    +
    1068  std::vector<uint8_t>(asset_id, asset_id + sizeof(uint32_t)));
    +
    1069  if (!status.ok()) {
    +
    1070  LOG(ERROR) << "Fetch Key(s) failed for AssetID = "
    +
    1071  << ntohlFromBuffer(asset_id) << ", error = " << status;
    +
    1072  return false;
    +
    1073  }
    +
    1074 
    +
    1075  const char kHdStreamLabel[] = "HD";
    +
    1076  status = decryption_key_source_->GetKey(kHdStreamLabel, encryption_key);
    +
    1077  if (!status.ok()) {
    +
    1078  LOG(ERROR) << "Fetch Key(s) failed for AssetID = "
    +
    1079  << ntohlFromBuffer(asset_id) << ", error = " << status;
    +
    1080  return false;
    +
    1081  }
    +
    1082 
    +
    1083  return true;
    +
    1084 }
    +
    1085 
    +
    1086 bool WvmMediaParser::ProcessEcm() {
    +
    1087  // An error will be returned later if the samples need to be decrypted.
    +
    1088  if (!decryption_key_source_)
    +
    1089  return true;
    +
    1090 
    +
    1091  if (current_program_id_ > 0) {
    +
    1092  return true;
    +
    1093  }
    +
    1094  if (ecm_.size() != kEcmSizeBytes) {
    +
    1095  LOG(ERROR) << "Unexpected ECM size = " << ecm_.size()
    +
    1096  << ", expected size = " << kEcmSizeBytes;
    +
    1097  return false;
    +
    1098  }
    +
    1099  const uint8_t* ecm_data = ecm_.data();
    +
    1100  DCHECK(ecm_data);
    +
    1101  ecm_data += sizeof(uint32_t); // old version field - skip.
    +
    1102  ecm_data += sizeof(uint32_t); // clear lead - skip.
    +
    1103  ecm_data += sizeof(uint32_t); // system id(includes ECM version) - skip.
    +
    1104  EncryptionKey encryption_key;
    +
    1105  if (!GetAssetKey(ecm_data, &encryption_key)) {
    +
    1106  return false;
    +
    1107  }
    +
    1108  if (encryption_key.key.size() < kAssetKeySizeBytes) {
    +
    1109  LOG(ERROR) << "Asset Key size of " << encryption_key.key.size()
    +
    1110  << " for AssetID = " << ntohlFromBuffer(ecm_data)
    +
    1111  << " is less than minimum asset key size.";
    +
    1112  return false;
    +
    1113  }
    +
    1114  ecm_data += sizeof(uint32_t); // asset_id.
    +
    1115  // Legacy WVM content may have asset keys > 16 bytes.
    +
    1116  // Use only the first 16 bytes of the asset key to get
    +
    1117  // the content key.
    +
    1118  std::vector<uint8_t> asset_key(
    +
    1119  encryption_key.key.begin(),
    +
    1120  encryption_key.key.begin() + kAssetKeySizeBytes);
    +
    1121  // WVM format always uses all zero IV.
    +
    1122  std::vector<uint8_t> zero_iv(kInitializationVectorSizeBytes, 0);
    +
    1123  AesCbcDecryptor asset_decryptor(kCtsPadding, AesCryptor::kUseConstantIv);
    +
    1124  if (!asset_decryptor.InitializeWithIv(asset_key, zero_iv)) {
    +
    1125  LOG(ERROR) << "Failed to initialize asset_decryptor.";
    +
    1126  return false;
    +
    1127  }
    +
    1128 
    +
    1129  const size_t content_key_buffer_size =
    +
    1130  kEcmFlagsSizeBytes + kEcmContentKeySizeBytes +
    +
    1131  kEcmPaddingSizeBytes; // flags + contentKey + padding.
    +
    1132  std::vector<uint8_t> content_key_buffer(content_key_buffer_size);
    +
    1133  CHECK(asset_decryptor.Crypt(ecm_data, content_key_buffer_size,
    +
    1134  content_key_buffer.data()));
    +
    1135 
    +
    1136  std::vector<uint8_t> decrypted_content_key_vec(
    +
    1137  content_key_buffer.begin() + 4,
    +
    1138  content_key_buffer.begin() + 20);
    +
    1139  std::unique_ptr<AesCbcDecryptor> content_decryptor(
    +
    1140  new AesCbcDecryptor(kCtsPadding, AesCryptor::kUseConstantIv));
    +
    1141  if (!content_decryptor->InitializeWithIv(decrypted_content_key_vec,
    +
    1142  zero_iv)) {
    +
    1143  LOG(ERROR) << "Failed to initialize content decryptor.";
    +
    1144  return false;
    +
    1145  }
    +
    1146 
    +
    1147  content_decryptor_ = std::move(content_decryptor);
    +
    1148  return true;
    +
    1149 }
    +
    1150 
    +
    1151 DemuxStreamIdMediaSample::DemuxStreamIdMediaSample() :
    +
    1152  demux_stream_id(0),
    +
    1153  parsed_audio_or_video_stream_id(0) {}
    +
    1154 
    +
    1155 DemuxStreamIdMediaSample::~DemuxStreamIdMediaSample() {}
    +
    1156 
    +
    1157 PrevSampleData::PrevSampleData() {
    +
    1158  Reset();
    +
    1159 }
    +
    1160 
    +
    1161 PrevSampleData::~PrevSampleData() {}
    +
    1162 
    +
    1163 void PrevSampleData::Reset() {
    +
    1164  audio_sample = NULL;
    +
    1165  video_sample = NULL;
    +
    1166  audio_stream_id = 0;
    +
    1167  video_stream_id = 0;
    +
    1168  audio_sample_duration = 0;
    +
    1169  video_sample_duration = 0;
    +
    1170 }
    +
    1171 
    +
    1172 } // namespace wvm
    +
    1173 } // namespace media
    +
    1174 } // namespace shaka
    +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
    Definition: media_parser.h:53
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d3a/gflags__hex__bytes_8h_source.html b/docs/dd/d3a/gflags__hex__bytes_8h_source.html index 59421109de..a09c95c8b0 100644 --- a/docs/dd/d3a/gflags__hex__bytes_8h_source.html +++ b/docs/dd/d3a/gflags__hex__bytes_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/gflags_hex_bytes.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    gflags_hex_bytes.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Extends gflags to support hex formatted bytes.
    8 
    9 #ifndef PACKAGER_APP_GFLAGS_HEX_BYTES_H_
    10 #define PACKAGER_APP_GFLAGS_HEX_BYTES_H_
    11 
    12 #include <gflags/gflags.h>
    13 
    14 #include <string>
    15 #include <vector>
    16 
    17 namespace shaka {
    18 bool ValidateHexString(const char* flagname,
    19  const std::string& value,
    20  std::vector<uint8_t>* value_bytes);
    21 } // namespace shaka
    22 
    23 // The raw bytes will be available in FLAGS_##name##_bytes.
    24 // The original gflag variable FLAGS_##name is defined in shaka_gflags_extension
    25 // and not exposed directly.
    26 #define DECLARE_hex_bytes(name) \
    27  namespace shaka_gflags_extension { \
    28  DECLARE_string(name); \
    29  } \
    30  namespace shaka_gflags_extension { \
    31  extern std::vector<uint8_t> FLAGS_##name##_bytes; \
    32  } \
    33  using shaka_gflags_extension::FLAGS_##name##_bytes
    34 
    35 #define DEFINE_hex_bytes(name, val, txt) \
    36  namespace shaka_gflags_extension { \
    37  DEFINE_string(name, val, txt); \
    38  } \
    39  namespace shaka_gflags_extension { \
    40  std::vector<uint8_t> FLAGS_##name##_bytes; \
    41  static bool hex_validator_##name = gflags::RegisterFlagValidator( \
    42  &FLAGS_##name, \
    43  [](const char* flagname, const std::string& value) { \
    44  return shaka::ValidateHexString(flagname, value, \
    45  &FLAGS_##name##_bytes); \
    46  }); \
    47  } \
    48  using shaka_gflags_extension::FLAGS_##name##_bytes
    49 
    50 #endif // PACKAGER_APP_GFLAGS_HEX_BYTES_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Extends gflags to support hex formatted bytes.
    +
    8 
    +
    9 #ifndef PACKAGER_APP_GFLAGS_HEX_BYTES_H_
    +
    10 #define PACKAGER_APP_GFLAGS_HEX_BYTES_H_
    +
    11 
    +
    12 #include <gflags/gflags.h>
    +
    13 
    +
    14 #include <string>
    +
    15 #include <vector>
    +
    16 
    +
    17 namespace shaka {
    +
    18 bool ValidateHexString(const char* flagname,
    +
    19  const std::string& value,
    +
    20  std::vector<uint8_t>* value_bytes);
    +
    21 } // namespace shaka
    +
    22 
    +
    23 // The raw bytes will be available in FLAGS_##name##_bytes.
    +
    24 // The original gflag variable FLAGS_##name is defined in shaka_gflags_extension
    +
    25 // and not exposed directly.
    +
    26 #define DECLARE_hex_bytes(name) \
    +
    27  namespace shaka_gflags_extension { \
    +
    28  DECLARE_string(name); \
    +
    29  } \
    +
    30  namespace shaka_gflags_extension { \
    +
    31  extern std::vector<uint8_t> FLAGS_##name##_bytes; \
    +
    32  } \
    +
    33  using shaka_gflags_extension::FLAGS_##name##_bytes
    +
    34 
    +
    35 #define DEFINE_hex_bytes(name, val, txt) \
    +
    36  namespace shaka_gflags_extension { \
    +
    37  DEFINE_string(name, val, txt); \
    +
    38  } \
    +
    39  namespace shaka_gflags_extension { \
    +
    40  std::vector<uint8_t> FLAGS_##name##_bytes; \
    +
    41  static bool hex_validator_##name = gflags::RegisterFlagValidator( \
    +
    42  &FLAGS_##name, \
    +
    43  [](const char* flagname, const std::string& value) { \
    +
    44  return shaka::ValidateHexString(flagname, value, \
    +
    45  &FLAGS_##name##_bytes); \
    +
    46  }); \
    +
    47  } \
    +
    48  using shaka_gflags_extension::FLAGS_##name##_bytes
    +
    49 
    +
    50 #endif // PACKAGER_APP_GFLAGS_HEX_BYTES_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d3b/mp4_2segmenter_8h_source.html b/docs/dd/d3b/mp4_2segmenter_8h_source.html index 7144a05397..f023052606 100644 --- a/docs/dd/d3b/mp4_2segmenter_8h_source.html +++ b/docs/dd/d3b/mp4_2segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/segmenter.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    segmenter.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_SEGMENTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_SEGMENTER_H_
    9 
    10 #include <map>
    11 #include <memory>
    12 #include <vector>
    13 
    14 #include "packager/base/optional.h"
    15 #include "packager/media/base/fourccs.h"
    16 #include "packager/media/base/range.h"
    17 #include "packager/media/formats/mp4/box_definitions.h"
    18 #include "packager/status.h"
    19 
    20 namespace shaka {
    21 namespace media {
    22 
    23 struct EncryptionConfig;
    24 struct MuxerOptions;
    25 struct SegmentInfo;
    26 
    27 class BufferWriter;
    28 class MediaSample;
    29 class MuxerListener;
    30 class ProgressListener;
    31 class StreamInfo;
    32 
    33 namespace mp4 {
    34 
    35 class Fragmenter;
    36 struct KeyFrameInfo;
    37 
    44 class Segmenter {
    45  public:
    46  Segmenter(const MuxerOptions& options,
    47  std::unique_ptr<FileType> ftyp,
    48  std::unique_ptr<Movie> moov);
    49  virtual ~Segmenter();
    50 
    59  const std::vector<std::shared_ptr<const StreamInfo>>& streams,
    60  MuxerListener* muxer_listener,
    61  ProgressListener* progress_listener);
    62 
    65  Status Finalize();
    66 
    71  Status AddSample(size_t stream_id, const MediaSample& sample);
    72 
    77  Status FinalizeSegment(size_t stream_id, const SegmentInfo& segment_info);
    78 
    79  // TODO(rkuroiwa): Change these Get*Range() methods to return
    80  // base::Optional<Range> as well.
    83  virtual bool GetInitRange(size_t* offset, size_t* size) = 0;
    84 
    87  virtual bool GetIndexRange(size_t* offset, size_t* size) = 0;
    88 
    89  // Returns an empty vector if there are no specific ranges for the segments,
    90  // e.g. the media is in multiple files.
    91  // Otherwise, a vector of ranges for the media segments are returned.
    92  virtual std::vector<Range> GetSegmentRanges() = 0;
    93 
    94  uint32_t GetReferenceTimeScale() const;
    95 
    97  double GetDuration() const;
    98 
    101  uint32_t sample_duration() const { return sample_duration_; }
    102 
    103  protected:
    105  void UpdateProgress(uint64_t progress);
    107  void SetComplete();
    108 
    109  const MuxerOptions& options() const { return options_; }
    110  FileType* ftyp() { return ftyp_.get(); }
    111  Movie* moov() { return moov_.get(); }
    112  BufferWriter* fragment_buffer() { return fragment_buffer_.get(); }
    113  SegmentIndex* sidx() { return sidx_.get(); }
    114  MuxerListener* muxer_listener() { return muxer_listener_; }
    115  uint64_t progress_target() { return progress_target_; }
    116  const std::vector<KeyFrameInfo>& key_frame_infos() const {
    117  return key_frame_infos_;
    118  }
    119 
    120  void set_progress_target(uint64_t progress_target) {
    121  progress_target_ = progress_target;
    122  }
    123 
    124  private:
    125  virtual Status DoInitialize() = 0;
    126  virtual Status DoFinalize() = 0;
    127  virtual Status DoFinalizeSegment() = 0;
    128 
    129  uint32_t GetReferenceStreamId();
    130 
    131  void FinalizeFragmentForKeyRotation(
    132  size_t stream_id,
    133  bool fragment_encrypted,
    134  const EncryptionConfig& encryption_config);
    135 
    136  const MuxerOptions& options_;
    137  std::unique_ptr<FileType> ftyp_;
    138  std::unique_ptr<Movie> moov_;
    139  std::unique_ptr<MovieFragment> moof_;
    140  std::unique_ptr<BufferWriter> fragment_buffer_;
    141  std::unique_ptr<SegmentIndex> sidx_;
    142  std::vector<std::unique_ptr<Fragmenter>> fragmenters_;
    143  MuxerListener* muxer_listener_ = nullptr;
    144  ProgressListener* progress_listener_ = nullptr;
    145  uint64_t progress_target_ = 0u;
    146  uint64_t accumulated_progress_ = 0u;
    147  uint32_t sample_duration_ = 0u;
    148  std::vector<uint64_t> stream_durations_;
    149  std::vector<KeyFrameInfo> key_frame_infos_;
    150 
    151  DISALLOW_COPY_AND_ASSIGN(Segmenter);
    152 };
    153 
    154 } // namespace mp4
    155 } // namespace media
    156 } // namespace shaka
    157 
    158 #endif // PACKAGER_MEDIA_FORMATS_MP4_SEGMENTER_H_
    Status Initialize(const std::vector< std::shared_ptr< const StreamInfo >> &streams, MuxerListener *muxer_listener, ProgressListener *progress_listener)
    Definition: segmenter.cc:51
    -
    void UpdateProgress(uint64_t progress)
    Update segmentation progress using ProgressListener.
    Definition: segmenter.cc:250
    -
    void SetComplete()
    Set progress to 100%.
    Definition: segmenter.cc:266
    - - -
    virtual bool GetInitRange(size_t *offset, size_t *size)=0
    -
    Status AddSample(size_t stream_id, const MediaSample &sample)
    Definition: segmenter.cc:123
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - - -
    This class listens to progress updates events.
    - - - - -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - -
    double GetDuration() const
    Definition: segmenter.cc:241
    -
    Status FinalizeSegment(size_t stream_id, const SegmentInfo &segment_info)
    Definition: segmenter.cc:147
    -
    uint32_t sample_duration() const
    Definition: segmenter.h:101
    -
    virtual bool GetIndexRange(size_t *offset, size_t *size)=0
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_SEGMENTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_SEGMENTER_H_
    +
    9 
    +
    10 #include <map>
    +
    11 #include <memory>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/optional.h"
    +
    15 #include "packager/media/base/fourccs.h"
    +
    16 #include "packager/media/base/range.h"
    +
    17 #include "packager/media/formats/mp4/box_definitions.h"
    +
    18 #include "packager/status.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 namespace media {
    +
    22 
    +
    23 struct EncryptionConfig;
    +
    24 struct MuxerOptions;
    +
    25 struct SegmentInfo;
    +
    26 
    +
    27 class BufferWriter;
    +
    28 class MediaSample;
    +
    29 class MuxerListener;
    +
    30 class ProgressListener;
    +
    31 class StreamInfo;
    +
    32 
    +
    33 namespace mp4 {
    +
    34 
    +
    35 class Fragmenter;
    +
    36 struct KeyFrameInfo;
    +
    37 
    +
    44 class Segmenter {
    +
    45  public:
    +
    46  Segmenter(const MuxerOptions& options,
    +
    47  std::unique_ptr<FileType> ftyp,
    +
    48  std::unique_ptr<Movie> moov);
    +
    49  virtual ~Segmenter();
    +
    50 
    + +
    59  const std::vector<std::shared_ptr<const StreamInfo>>& streams,
    +
    60  MuxerListener* muxer_listener,
    +
    61  ProgressListener* progress_listener);
    +
    62 
    +
    65  Status Finalize();
    +
    66 
    +
    71  Status AddSample(size_t stream_id, const MediaSample& sample);
    +
    72 
    +
    77  Status FinalizeSegment(size_t stream_id, const SegmentInfo& segment_info);
    +
    78 
    +
    79  // TODO(rkuroiwa): Change these Get*Range() methods to return
    +
    80  // base::Optional<Range> as well.
    +
    83  virtual bool GetInitRange(size_t* offset, size_t* size) = 0;
    +
    84 
    +
    87  virtual bool GetIndexRange(size_t* offset, size_t* size) = 0;
    +
    88 
    +
    89  // Returns an empty vector if there are no specific ranges for the segments,
    +
    90  // e.g. the media is in multiple files.
    +
    91  // Otherwise, a vector of ranges for the media segments are returned.
    +
    92  virtual std::vector<Range> GetSegmentRanges() = 0;
    +
    93 
    +
    94  uint32_t GetReferenceTimeScale() const;
    +
    95 
    +
    97  double GetDuration() const;
    +
    98 
    +
    101  uint32_t sample_duration() const { return sample_duration_; }
    +
    102 
    +
    103  protected:
    +
    105  void UpdateProgress(uint64_t progress);
    +
    107  void SetComplete();
    +
    108 
    +
    109  const MuxerOptions& options() const { return options_; }
    +
    110  FileType* ftyp() { return ftyp_.get(); }
    +
    111  Movie* moov() { return moov_.get(); }
    +
    112  BufferWriter* fragment_buffer() { return fragment_buffer_.get(); }
    +
    113  SegmentIndex* sidx() { return sidx_.get(); }
    +
    114  MuxerListener* muxer_listener() { return muxer_listener_; }
    +
    115  uint64_t progress_target() { return progress_target_; }
    +
    116  const std::vector<KeyFrameInfo>& key_frame_infos() const {
    +
    117  return key_frame_infos_;
    +
    118  }
    +
    119 
    +
    120  void set_progress_target(uint64_t progress_target) {
    +
    121  progress_target_ = progress_target;
    +
    122  }
    +
    123 
    +
    124  private:
    +
    125  virtual Status DoInitialize() = 0;
    +
    126  virtual Status DoFinalize() = 0;
    +
    127  virtual Status DoFinalizeSegment() = 0;
    +
    128 
    +
    129  uint32_t GetReferenceStreamId();
    +
    130 
    +
    131  void FinalizeFragmentForKeyRotation(
    +
    132  size_t stream_id,
    +
    133  bool fragment_encrypted,
    +
    134  const EncryptionConfig& encryption_config);
    +
    135 
    +
    136  const MuxerOptions& options_;
    +
    137  std::unique_ptr<FileType> ftyp_;
    +
    138  std::unique_ptr<Movie> moov_;
    +
    139  std::unique_ptr<MovieFragment> moof_;
    +
    140  std::unique_ptr<BufferWriter> fragment_buffer_;
    +
    141  std::unique_ptr<SegmentIndex> sidx_;
    +
    142  std::vector<std::unique_ptr<Fragmenter>> fragmenters_;
    +
    143  MuxerListener* muxer_listener_ = nullptr;
    +
    144  ProgressListener* progress_listener_ = nullptr;
    +
    145  uint64_t progress_target_ = 0u;
    +
    146  uint64_t accumulated_progress_ = 0u;
    +
    147  uint32_t sample_duration_ = 0u;
    +
    148  std::vector<uint64_t> stream_durations_;
    +
    149  std::vector<KeyFrameInfo> key_frame_infos_;
    +
    150 
    +
    151  DISALLOW_COPY_AND_ASSIGN(Segmenter);
    +
    152 };
    +
    153 
    +
    154 } // namespace mp4
    +
    155 } // namespace media
    +
    156 } // namespace shaka
    +
    157 
    +
    158 #endif // PACKAGER_MEDIA_FORMATS_MP4_SEGMENTER_H_
    + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    + +
    This class listens to progress updates events.
    + +
    virtual bool GetInitRange(size_t *offset, size_t *size)=0
    + +
    double GetDuration() const
    Definition: segmenter.cc:241
    +
    Status AddSample(size_t stream_id, const MediaSample &sample)
    Definition: segmenter.cc:123
    +
    virtual bool GetIndexRange(size_t *offset, size_t *size)=0
    +
    Status Initialize(const std::vector< std::shared_ptr< const StreamInfo >> &streams, MuxerListener *muxer_listener, ProgressListener *progress_listener)
    Definition: segmenter.cc:51
    +
    uint32_t sample_duration() const
    Definition: segmenter.h:101
    +
    void SetComplete()
    Set progress to 100%.
    Definition: segmenter.cc:266
    +
    Status FinalizeSegment(size_t stream_id, const SegmentInfo &segment_info)
    Definition: segmenter.cc:147
    +
    void UpdateProgress(uint64_t progress)
    Update segmentation progress using ProgressListener.
    Definition: segmenter.cc:250
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    diff --git a/docs/dd/d3e/callback__file_8cc_source.html b/docs/dd/d3e/callback__file_8cc_source.html index 14cac8fd75..29a6dcbe25 100644 --- a/docs/dd/d3e/callback__file_8cc_source.html +++ b/docs/dd/d3e/callback__file_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/callback_file.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    callback_file.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/file/callback_file.h"
    8 
    9 #include "packager/base/logging.h"
    10 
    11 namespace shaka {
    12 
    13 CallbackFile::CallbackFile(const char* file_name, const char* mode)
    14  : File(file_name), file_mode_(mode) {}
    15 
    16 CallbackFile::~CallbackFile() {}
    17 
    19  delete this;
    20  return true;
    21 }
    22 
    23 int64_t CallbackFile::Read(void* buffer, uint64_t length) {
    24  if (!callback_params_->read_func) {
    25  LOG(ERROR) << "Read function not defined.";
    26  return -1;
    27  }
    28  return callback_params_->read_func(name_, buffer, length);
    29 }
    30 
    31 int64_t CallbackFile::Write(const void* buffer, uint64_t length) {
    32  if (!callback_params_->write_func) {
    33  LOG(ERROR) << "Write function not defined.";
    34  return -1;
    35  }
    36  return callback_params_->write_func(name_, buffer, length);
    37 }
    38 
    39 int64_t CallbackFile::Size() {
    40  LOG(INFO) << "CallbackFile does not support Size().";
    41  return -1;
    42 }
    43 
    45  // Do nothing on Flush.
    46  return true;
    47 }
    48 
    49 bool CallbackFile::Seek(uint64_t position) {
    50  VLOG(1) << "CallbackFile does not support Seek().";
    51  return false;
    52 }
    53 
    54 bool CallbackFile::Tell(uint64_t* position) {
    55  VLOG(1) << "CallbackFile does not support Tell().";
    56  return false;
    57 }
    58 
    60  if (file_mode_ != "r" && file_mode_ != "w" && file_mode_ != "rb" &&
    61  file_mode_ != "wb") {
    62  LOG(ERROR) << "CallbackFile does not support file mode " << file_mode_;
    63  return false;
    64  }
    65  return ParseCallbackFileName(file_name(), &callback_params_, &name_);
    66 }
    67 
    68 } // namespace shaka
    bool Close() override
    -
    std::function< int64_t(const std::string &name, void *buffer, uint64_t size)> read_func
    -
    Define an abstract file interface.
    Definition: file.h:26
    -
    const std::string & file_name() const
    Definition: file.h:94
    -
    int64_t Write(const void *buffer, uint64_t length) override
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool Tell(uint64_t *position) override
    -
    bool Flush() override
    -
    bool Seek(uint64_t position) override
    -
    std::function< int64_t(const std::string &name, const void *buffer, uint64_t size)> write_func
    -
    static bool ParseCallbackFileName(const std::string &callback_file_name, const BufferCallbackParams **callback_params, std::string *name)
    Definition: file.cc:389
    -
    bool Open() override
    Internal open. Should not be used directly.
    -
    int64_t Read(void *buffer, uint64_t length) override
    -
    CallbackFile(const char *file_name, const char *mode)
    -
    int64_t Size() override
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/file/callback_file.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 
    +
    13 CallbackFile::CallbackFile(const char* file_name, const char* mode)
    +
    14  : File(file_name), file_mode_(mode) {}
    +
    15 
    +
    16 CallbackFile::~CallbackFile() {}
    +
    17 
    + +
    19  delete this;
    +
    20  return true;
    +
    21 }
    +
    22 
    +
    23 int64_t CallbackFile::Read(void* buffer, uint64_t length) {
    +
    24  if (!callback_params_->read_func) {
    +
    25  LOG(ERROR) << "Read function not defined.";
    +
    26  return -1;
    +
    27  }
    +
    28  return callback_params_->read_func(name_, buffer, length);
    +
    29 }
    +
    30 
    +
    31 int64_t CallbackFile::Write(const void* buffer, uint64_t length) {
    +
    32  if (!callback_params_->write_func) {
    +
    33  LOG(ERROR) << "Write function not defined.";
    +
    34  return -1;
    +
    35  }
    +
    36  return callback_params_->write_func(name_, buffer, length);
    +
    37 }
    +
    38 
    +
    39 int64_t CallbackFile::Size() {
    +
    40  LOG(INFO) << "CallbackFile does not support Size().";
    +
    41  return -1;
    +
    42 }
    +
    43 
    + +
    45  // Do nothing on Flush.
    +
    46  return true;
    +
    47 }
    +
    48 
    +
    49 bool CallbackFile::Seek(uint64_t position) {
    +
    50  VLOG(1) << "CallbackFile does not support Seek().";
    +
    51  return false;
    +
    52 }
    +
    53 
    +
    54 bool CallbackFile::Tell(uint64_t* position) {
    +
    55  VLOG(1) << "CallbackFile does not support Tell().";
    +
    56  return false;
    +
    57 }
    +
    58 
    + +
    60  if (file_mode_ != "r" && file_mode_ != "w" && file_mode_ != "rb" &&
    +
    61  file_mode_ != "wb") {
    +
    62  LOG(ERROR) << "CallbackFile does not support file mode " << file_mode_;
    +
    63  return false;
    +
    64  }
    +
    65  return ParseCallbackFileName(file_name(), &callback_params_, &name_);
    +
    66 }
    +
    67 
    +
    68 } // namespace shaka
    +
    CallbackFile(const char *file_name, const char *mode)
    +
    bool Seek(uint64_t position) override
    +
    int64_t Read(void *buffer, uint64_t length) override
    +
    int64_t Write(const void *buffer, uint64_t length) override
    +
    bool Close() override
    +
    int64_t Size() override
    +
    bool Open() override
    Internal open. Should not be used directly.
    +
    bool Tell(uint64_t *position) override
    +
    bool Flush() override
    +
    Define an abstract file interface.
    Definition: file.h:27
    +
    const std::string & file_name() const
    Definition: file.h:95
    +
    static bool ParseCallbackFileName(const std::string &callback_file_name, const BufferCallbackParams **callback_params, std::string *name)
    Definition: file.cc:409
    +
    All the methods that are virtual are virtual for mocking.
    +
    std::function< int64_t(const std::string &name, void *buffer, uint64_t size)> read_func
    +
    std::function< int64_t(const std::string &name, const void *buffer, uint64_t size)> write_func
    diff --git a/docs/dd/d3f/structshaka_1_1media_1_1mp4_1_1SyncSample.html b/docs/dd/d3f/structshaka_1_1media_1_1mp4_1_1SyncSample.html index 7422bd7d85..0dc32ce11d 100644 --- a/docs/dd/d3f/structshaka_1_1media_1_1mp4_1_1SyncSample.html +++ b/docs/dd/d3f/structshaka_1_1media_1_1mp4_1_1SyncSample.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SyncSample Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 490 of file box_definitions.h.

    +

    Definition at line 503 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 935 of file box_definitions.cc.

    +

    Definition at line 948 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/dd/d40/classshaka_1_1CallbackFile.html b/docs/dd/d40/classshaka_1_1CallbackFile.html index d756e5eabd..fc7b8400ed 100644 --- a/docs/dd/d40/classshaka_1_1CallbackFile.html +++ b/docs/dd/d40/classshaka_1_1CallbackFile.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::CallbackFile Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::File - -
    +shaka::File + + @@ -213,7 +216,7 @@ Additional Inherited Members

    Public Member Functions

    -

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.
    +

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.

    Implements shaka::File.

    @@ -243,7 +246,7 @@ Additional Inherited Members
    -

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.
    +

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.

    Implements shaka::File.

    @@ -458,9 +461,7 @@ Additional Inherited Members
    diff --git a/docs/dd/d42/encryptor_8h_source.html b/docs/dd/d42/encryptor_8h_source.html index 1205de0065..8f0a3730e0 100644 --- a/docs/dd/d42/encryptor_8h_source.html +++ b/docs/dd/d42/encryptor_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/encryptor.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    encryptor.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_ENCRYPTOR_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_ENCRYPTOR_H_
    9 
    10 #include <vector>
    11 
    12 #include "packager/status.h"
    13 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    18 class MediaSample;
    19 
    20 namespace webm {
    21 
    24 Status UpdateTrackForEncryption(const std::vector<uint8_t>& key_id,
    25  mkvmuxer::Track* track);
    26 
    29 void UpdateFrameForEncryption(MediaSample* sample);
    30 
    31 } // namespace webm
    32 } // namespace media
    33 } // namespace shaka
    34 
    35 #endif // PACKAGER_MEDIA_FORMATS_WEBM_ENCRYPTOR_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_ENCRYPTOR_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_ENCRYPTOR_H_
    +
    9 
    +
    10 #include <vector>
    +
    11 
    +
    12 #include "packager/status.h"
    +
    13 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    18 class MediaSample;
    +
    19 
    +
    20 namespace webm {
    +
    21 
    +
    24 Status UpdateTrackForEncryption(const std::vector<uint8_t>& key_id,
    +
    25  mkvmuxer::Track* track);
    +
    26 
    +
    29 void UpdateFrameForEncryption(MediaSample* sample);
    +
    30 
    +
    31 } // namespace webm
    +
    32 } // namespace media
    +
    33 } // namespace shaka
    +
    34 
    +
    35 #endif // PACKAGER_MEDIA_FORMATS_WEBM_ENCRYPTOR_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d46/webm__parser_8h_source.html b/docs/dd/d46/webm__parser_8h_source.html index d6115460c7..7c3e4ded08 100644 --- a/docs/dd/d46/webm__parser_8h_source.html +++ b/docs/dd/d46/webm__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_parser.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    webm_parser.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
    7 
    8 #include <stdint.h>
    9 
    10 #include <string>
    11 #include <vector>
    12 
    13 #include "packager/base/macros.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    31  public:
    32  virtual ~WebMParserClient();
    33 
    34  virtual WebMParserClient* OnListStart(int id);
    35  virtual bool OnListEnd(int id);
    36  virtual bool OnUInt(int id, int64_t val);
    37  virtual bool OnFloat(int id, double val);
    38  virtual bool OnBinary(int id, const uint8_t* data, int size);
    39  virtual bool OnString(int id, const std::string& str);
    40 
    41  protected:
    43 
    44  DISALLOW_COPY_AND_ASSIGN(WebMParserClient);
    45 };
    46 
    47 struct ListElementInfo;
    48 
    55  public:
    58  WebMListParser(int id, WebMParserClient* client);
    59  ~WebMListParser();
    60 
    62  void Reset();
    63 
    68  int Parse(const uint8_t* buf, int size);
    69 
    71  bool IsParsingComplete() const;
    72 
    73  private:
    74  enum State {
    75  NEED_LIST_HEADER,
    76  INSIDE_LIST,
    77  DONE_PARSING_LIST,
    78  PARSE_ERROR,
    79  };
    80 
    81  struct ListState {
    82  int id_;
    83  int64_t size_;
    84  int64_t bytes_parsed_;
    85  const ListElementInfo* element_info_;
    86  WebMParserClient* client_;
    87  };
    88 
    89  void ChangeState(State new_state);
    90 
    91  // Parses a single element in the current list.
    92  //
    93  // |header_size| - The size of the element header
    94  // |id| - The ID of the element being parsed.
    95  // |element_size| - The size of the element body.
    96  // |data| - Pointer to the element contents.
    97  // |size| - Number of bytes in |data|
    98  // |client| - Client to pass the parsed data to.
    99  //
    100  // Returns < 0 if the parse fails.
    101  // Returns 0 if more data is needed.
    102  // Returning > 0 indicates success & the number of bytes parsed.
    103  int ParseListElement(int header_size,
    104  int id,
    105  int64_t element_size,
    106  const uint8_t* data,
    107  int size);
    108 
    109  // Called when starting to parse a new list.
    110  //
    111  // |id| - The ID of the new list.
    112  // |size| - The size of the new list.
    113  // |client| - The client object to notify that a new list is being parsed.
    114  //
    115  // Returns true if this list can be started in the current context. False
    116  // if starting this list causes some sort of parse error.
    117  bool OnListStart(int id, int64_t size);
    118 
    119  // Called when the end of the current list has been reached. This may also
    120  // signal the end of the current list's ancestors if the current list happens
    121  // to be at the end of its parent.
    122  //
    123  // Returns true if no errors occurred while ending this list(s).
    124  bool OnListEnd();
    125 
    126  // Checks to see if |id_b| is a sibling or ancestor of |id_a|.
    127  bool IsSiblingOrAncestor(int id_a, int id_b) const;
    128 
    129  State state_;
    130 
    131  // Element ID passed to the constructor.
    132  const int root_id_;
    133 
    134  // Element level for |root_id_|. Used to verify that elements appear at
    135  // the correct level.
    136  const int root_level_;
    137 
    138  // WebMParserClient to handle the root list.
    139  WebMParserClient* const root_client_;
    140 
    141  // Stack of state for all the lists currently being parsed. Lists are
    142  // added and removed from this stack as they are parsed.
    143  std::vector<ListState> list_state_stack_;
    144 
    145  DISALLOW_COPY_AND_ASSIGN(WebMListParser);
    146 };
    147 
    155 int WebMParseElementHeader(const uint8_t* buf,
    156  int size,
    157  int* id,
    158  int64_t* element_size);
    159 
    160 } // namespace media
    161 } // namespace shaka
    162 
    163 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
    -
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 
    +
    10 #include <string>
    +
    11 #include <vector>
    +
    12 
    +
    13 #include "packager/base/macros.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    + +
    31  public:
    +
    32  virtual ~WebMParserClient();
    +
    33 
    +
    34  virtual WebMParserClient* OnListStart(int id);
    +
    35  virtual bool OnListEnd(int id);
    +
    36  virtual bool OnUInt(int id, int64_t val);
    +
    37  virtual bool OnFloat(int id, double val);
    +
    38  virtual bool OnBinary(int id, const uint8_t* data, int size);
    +
    39  virtual bool OnString(int id, const std::string& str);
    +
    40 
    +
    41  protected:
    + +
    43 
    +
    44  DISALLOW_COPY_AND_ASSIGN(WebMParserClient);
    +
    45 };
    +
    46 
    +
    47 struct ListElementInfo;
    +
    48 
    + +
    55  public:
    +
    58  WebMListParser(int id, WebMParserClient* client);
    +
    59  ~WebMListParser();
    +
    60 
    +
    62  void Reset();
    +
    63 
    +
    68  int Parse(const uint8_t* buf, int size);
    +
    69 
    +
    71  bool IsParsingComplete() const;
    +
    72 
    +
    73  private:
    +
    74  enum State {
    +
    75  NEED_LIST_HEADER,
    +
    76  INSIDE_LIST,
    +
    77  DONE_PARSING_LIST,
    +
    78  PARSE_ERROR,
    +
    79  };
    +
    80 
    +
    81  struct ListState {
    +
    82  int id_;
    +
    83  int64_t size_;
    +
    84  int64_t bytes_parsed_;
    +
    85  const ListElementInfo* element_info_;
    +
    86  WebMParserClient* client_;
    +
    87  };
    +
    88 
    +
    89  void ChangeState(State new_state);
    +
    90 
    +
    91  // Parses a single element in the current list.
    +
    92  //
    +
    93  // |header_size| - The size of the element header
    +
    94  // |id| - The ID of the element being parsed.
    +
    95  // |element_size| - The size of the element body.
    +
    96  // |data| - Pointer to the element contents.
    +
    97  // |size| - Number of bytes in |data|
    +
    98  // |client| - Client to pass the parsed data to.
    +
    99  //
    +
    100  // Returns < 0 if the parse fails.
    +
    101  // Returns 0 if more data is needed.
    +
    102  // Returning > 0 indicates success & the number of bytes parsed.
    +
    103  int ParseListElement(int header_size,
    +
    104  int id,
    +
    105  int64_t element_size,
    +
    106  const uint8_t* data,
    +
    107  int size);
    +
    108 
    +
    109  // Called when starting to parse a new list.
    +
    110  //
    +
    111  // |id| - The ID of the new list.
    +
    112  // |size| - The size of the new list.
    +
    113  // |client| - The client object to notify that a new list is being parsed.
    +
    114  //
    +
    115  // Returns true if this list can be started in the current context. False
    +
    116  // if starting this list causes some sort of parse error.
    +
    117  bool OnListStart(int id, int64_t size);
    +
    118 
    +
    119  // Called when the end of the current list has been reached. This may also
    +
    120  // signal the end of the current list's ancestors if the current list happens
    +
    121  // to be at the end of its parent.
    +
    122  //
    +
    123  // Returns true if no errors occurred while ending this list(s).
    +
    124  bool OnListEnd();
    +
    125 
    +
    126  // Checks to see if |id_b| is a sibling or ancestor of |id_a|.
    +
    127  bool IsSiblingOrAncestor(int id_a, int id_b) const;
    +
    128 
    +
    129  State state_;
    +
    130 
    +
    131  // Element ID passed to the constructor.
    +
    132  const int root_id_;
    +
    133 
    +
    134  // Element level for |root_id_|. Used to verify that elements appear at
    +
    135  // the correct level.
    +
    136  const int root_level_;
    +
    137 
    +
    138  // WebMParserClient to handle the root list.
    +
    139  WebMParserClient* const root_client_;
    +
    140 
    +
    141  // Stack of state for all the lists currently being parsed. Lists are
    +
    142  // added and removed from this stack as they are parsed.
    +
    143  std::vector<ListState> list_state_stack_;
    +
    144 
    +
    145  DISALLOW_COPY_AND_ASSIGN(WebMListParser);
    +
    146 };
    +
    147 
    +
    155 int WebMParseElementHeader(const uint8_t* buf,
    +
    156  int size,
    +
    157  int* id,
    +
    158  int64_t* element_size);
    +
    159 
    +
    160 } // namespace media
    +
    161 } // namespace shaka
    +
    162 
    +
    163 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
    + +
    void Reset()
    Resets the state of the parser so it can start parsing a new list.
    Definition: webm_parser.cc:733
    +
    WebMListParser(int id, WebMParserClient *client)
    Definition: webm_parser.cc:722
    +
    int Parse(const uint8_t *buf, int size)
    Definition: webm_parser.cc:738
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d4b/classshaka_1_1media_1_1SLConfigDescriptor-members.html b/docs/dd/d4b/classshaka_1_1media_1_1SLConfigDescriptor-members.html index 9ad825e958..e511ef4257 100644 --- a/docs/dd/d4b/classshaka_1_1media_1_1SLConfigDescriptor-members.html +++ b/docs/dd/d4b/classshaka_1_1media_1_1SLConfigDescriptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/d4b/event__info_8h_source.html b/docs/dd/d4b/event__info_8h_source.html index cc7181d552..7274c52ec4 100644 --- a/docs/dd/d4b/event__info_8h_source.html +++ b/docs/dd/d4b/event__info_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/event_info.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    event_info.h
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Defines EventInfo structure used internally by muxer listeners for VOD.
    8 
    9 #ifndef PACKAGER_MEDIA_EVENT_EVENT_INFO_H_
    10 #define PACKAGER_MEDIA_EVENT_EVENT_INFO_H_
    11 
    12 #include <cstdint>
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 // This stores data passed into OnNewSegment() for VOD.
    19  int64_t start_time;
    20  // The below two fields are only useful for Segment.
    21  int64_t duration;
    22  uint64_t segment_file_size;
    23 };
    24 
    25 struct KeyFrameEvent {
    26  int64_t timestamp;
    27  // In segment for multi-segment, in subsegment for single-segment.
    28  uint64_t start_offset_in_segment;
    29  uint64_t size;
    30 };
    31 
    32 // This stores data passed into OnCueEvent() for VOD.
    33 struct CueEventInfo {
    34  int64_t timestamp;
    35 };
    36 
    37 enum class EventInfoType {
    38  kSegment,
    39  kKeyFrame,
    40  kCue,
    41 };
    42 
    43 // This stores data for lazy event callback for VOD.
    44 struct EventInfo {
    45  EventInfoType type;
    46  union {
    47  SegmentEventInfo segment_info;
    48  KeyFrameEvent key_frame;
    49  CueEventInfo cue_event_info;
    50  };
    51 };
    52 
    53 } // namespace media
    54 } // namespace shaka
    55 
    56 #endif // PACKAGER_MEDIA_EVENT_EVENT_INFO_H_
    - - -
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Defines EventInfo structure used internally by muxer listeners for VOD.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_EVENT_EVENT_INFO_H_
    +
    10 #define PACKAGER_MEDIA_EVENT_EVENT_INFO_H_
    +
    11 
    +
    12 #include <cstdint>
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 // This stores data passed into OnNewSegment() for VOD.
    + +
    19  int64_t start_time;
    +
    20  // The below two fields are only useful for Segment.
    +
    21  int64_t duration;
    +
    22  uint64_t segment_file_size;
    +
    23 };
    +
    24 
    +
    25 struct KeyFrameEvent {
    +
    26  int64_t timestamp;
    +
    27  // In segment for multi-segment, in subsegment for single-segment.
    +
    28  uint64_t start_offset_in_segment;
    +
    29  uint64_t size;
    +
    30 };
    +
    31 
    +
    32 // This stores data passed into OnCueEvent() for VOD.
    +
    33 struct CueEventInfo {
    +
    34  int64_t timestamp;
    +
    35 };
    +
    36 
    +
    37 enum class EventInfoType {
    +
    38  kSegment,
    +
    39  kKeyFrame,
    +
    40  kCue,
    +
    41 };
    +
    42 
    +
    43 // This stores data for lazy event callback for VOD.
    +
    44 struct EventInfo {
    +
    45  EventInfoType type;
    +
    46  union {
    +
    47  SegmentEventInfo segment_info;
    +
    48  KeyFrameEvent key_frame;
    +
    49  CueEventInfo cue_event_info;
    +
    50  };
    +
    51 };
    +
    52 
    +
    53 } // namespace media
    +
    54 } // namespace shaka
    +
    55 
    +
    56 #endif // PACKAGER_MEDIA_EVENT_EVENT_INFO_H_
    +
    All the methods that are virtual are virtual for mocking.
    + + + +
    diff --git a/docs/dd/d4d/structshaka_1_1media_1_1mp4_1_1MovieFragment-members.html b/docs/dd/d4d/structshaka_1_1media_1_1mp4_1_1MovieFragment-members.html index 868601b389..86d60db163 100644 --- a/docs/dd/d4d/structshaka_1_1media_1_1mp4_1_1MovieFragment-members.html +++ b/docs/dd/d4d/structshaka_1_1media_1_1mp4_1_1MovieFragment-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/d4e/classshaka_1_1Period-members.html b/docs/dd/d4e/classshaka_1_1Period-members.html index 6504b2494e..39daddb9c5 100644 --- a/docs/dd/d4e/classshaka_1_1Period-members.html +++ b/docs/dd/d4e/classshaka_1_1Period-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    duration_seconds() constshaka::Periodinline GetAdaptationSets() constshaka::Period GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)shaka::Periodvirtual - GetXml(bool output_period_duration)shaka::Period + GetXml(bool output_period_duration)shaka::Period MpdBuilder (defined in shaka::Period)shaka::Periodfriend Period(uint32_t period_id, double start_time_in_seconds, const MpdOptions &mpd_options, uint32_t *representation_counter)shaka::Periodprotected PeriodTest (defined in shaka::Period)shaka::Periodfriend set_duration_seconds(double duration_seconds)shaka::Periodinline start_time_in_seconds() constshaka::Periodinline - ~Period()=default (defined in shaka::Period)shaka::Periodvirtual + trickplay_cache() constshaka::Periodinline + ~Period() (defined in shaka::Period)shaka::Periodvirtual
    diff --git a/docs/dd/d4f/classshaka_1_1hls_1_1SimpleHlsNotifier-members.html b/docs/dd/d4f/classshaka_1_1hls_1_1SimpleHlsNotifier-members.html index 8d1c3b667b..22989ab778 100644 --- a/docs/dd/d4f/classshaka_1_1hls_1_1SimpleHlsNotifier-members.html +++ b/docs/dd/d4f/classshaka_1_1hls_1_1SimpleHlsNotifier-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/d51/structshaka_1_1PlayReadyEncryptionParams-members.html b/docs/dd/d51/structshaka_1_1PlayReadyEncryptionParams-members.html index e7d76de944..885a930df9 100644 --- a/docs/dd/d51/structshaka_1_1PlayReadyEncryptionParams-members.html +++ b/docs/dd/d51/structshaka_1_1PlayReadyEncryptionParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/d53/dovi__decoder__configuration__record_8cc_source.html b/docs/dd/d53/dovi__decoder__configuration__record_8cc_source.html index 826eefa8d0..d7fabdd3fa 100644 --- a/docs/dd/d53/dovi__decoder__configuration__record_8cc_source.html +++ b/docs/dd/d53/dovi__decoder__configuration__record_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/dovi_decoder_configuration_record.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    dovi_decoder_configuration_record.cc
    -
    1 // Copyright 2019 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/dovi_decoder_configuration_record.h"
    8 
    9 #include "packager/base/strings/stringprintf.h"
    10 #include "packager/media/base/bit_reader.h"
    11 #include "packager/media/base/rcheck.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 bool DOVIDecoderConfigurationRecord::Parse(const std::vector<uint8_t>& data) {
    17  BitReader reader(data.data(), data.size());
    18 
    19  // Dolby Vision Streams Within the ISO Base Media File Format Version 2.0:
    20  // https://www.dolby.com/us/en/technologies/dolby-vision/dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.0.pdf
    21  uint8_t major_version = 0;
    22  uint8_t minor_version = 0;
    23  RCHECK(reader.ReadBits(8, &major_version) && major_version == 1 &&
    24  reader.ReadBits(8, &minor_version) && minor_version == 0 &&
    25  reader.ReadBits(7, &profile_) && reader.ReadBits(6, &level_));
    26  return true;
    27 }
    28 
    30  FourCC codec_fourcc) const {
    31  // Dolby Vision Streams within the HTTP Live Streaming format Version 2.0:
    32  // https://www.dolby.com/us/en/technologies/dolby-vision/dolby-vision-streams-within-the-http-live-streaming-format-v2.0.pdf
    33  return base::StringPrintf(
    34  "%s.%02d.%02d", FourCCToString(codec_fourcc).c_str(), profile_, level_);
    35 }
    36 
    37 } // namespace media
    38 } // namespace shaka
    -
    A class to read bit streams.
    Definition: bit_reader.h:17
    -
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2019 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/dovi_decoder_configuration_record.h"
    +
    8 
    +
    9 #include "packager/base/strings/stringprintf.h"
    +
    10 #include "packager/media/base/bit_reader.h"
    +
    11 #include "packager/media/base/rcheck.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 bool DOVIDecoderConfigurationRecord::Parse(const std::vector<uint8_t>& data) {
    +
    17  BitReader reader(data.data(), data.size());
    +
    18 
    +
    19  // Dolby Vision Streams Within the ISO Base Media File Format Version 2.0:
    +
    20  // https://www.dolby.com/us/en/technologies/dolby-vision/dolby-vision-bitstreams-within-the-iso-base-media-file-format-v2.0.pdf
    +
    21  uint8_t major_version = 0;
    +
    22  uint8_t minor_version = 0;
    +
    23  RCHECK(reader.ReadBits(8, &major_version) && major_version == 1 &&
    +
    24  reader.ReadBits(8, &minor_version) && minor_version == 0 &&
    +
    25  reader.ReadBits(7, &profile_) && reader.ReadBits(6, &level_));
    +
    26  return true;
    +
    27 }
    +
    28 
    + +
    30  FourCC codec_fourcc) const {
    +
    31  // Dolby Vision Streams within the HTTP Live Streaming format Version 2.0:
    +
    32  // https://www.dolby.com/us/en/technologies/dolby-vision/dolby-vision-streams-within-the-http-live-streaming-format-v2.0.pdf
    +
    33  return base::StringPrintf(
    +
    34  "%s.%02d.%02d", FourCCToString(codec_fourcc).c_str(), profile_, level_);
    +
    35 }
    +
    36 
    +
    37 } // namespace media
    +
    38 } // namespace shaka
    +
    A class to read bit streams.
    Definition: bit_reader.h:17
    +
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d53/structshaka_1_1media_1_1wvm_1_1DemuxStreamIdMediaSample-members.html b/docs/dd/d53/structshaka_1_1media_1_1wvm_1_1DemuxStreamIdMediaSample-members.html index eba26eb267..d40bfad9a0 100644 --- a/docs/dd/d53/structshaka_1_1media_1_1wvm_1_1DemuxStreamIdMediaSample-members.html +++ b/docs/dd/d53/structshaka_1_1media_1_1wvm_1_1DemuxStreamIdMediaSample-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/d54/widevine__encryption__flags_8h_source.html b/docs/dd/d54/widevine__encryption__flags_8h_source.html index 9421d6f66d..96bf7da8c0 100644 --- a/docs/dd/d54/widevine__encryption__flags_8h_source.html +++ b/docs/dd/d54/widevine__encryption__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/widevine_encryption_flags.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    widevine_encryption_flags.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Defines command line flags for widevine_encryption.
    8 
    9 #ifndef APP_WIDEVINE_ENCRYPTION_FLAGS_H_
    10 #define APP_WIDEVINE_ENCRYPTION_FLAGS_H_
    11 
    12 #include <gflags/gflags.h>
    13 
    14 #include "packager/app/gflags_hex_bytes.h"
    15 
    16 DECLARE_bool(enable_widevine_encryption);
    17 DECLARE_bool(enable_widevine_decryption);
    18 DECLARE_string(key_server_url);
    19 DECLARE_hex_bytes(content_id);
    20 DECLARE_string(policy);
    21 DECLARE_int32(max_sd_pixels);
    22 DECLARE_int32(max_hd_pixels);
    23 DECLARE_int32(max_uhd1_pixels);
    24 DECLARE_string(signer);
    25 DECLARE_hex_bytes(aes_signing_key);
    26 DECLARE_hex_bytes(aes_signing_iv);
    27 DECLARE_string(rsa_signing_key_path);
    28 DECLARE_int32(crypto_period_duration);
    29 DECLARE_hex_bytes(group_id);
    30 DECLARE_bool(enable_entitlement_license);
    31 
    32 namespace shaka {
    33 
    37 
    38 } // namespace shaka
    39 
    40 #endif // APP_WIDEVINE_ENCRYPTION_FLAGS_H_
    bool ValidateWidevineCryptoFlags()
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Defines command line flags for widevine_encryption.
    +
    8 
    +
    9 #ifndef APP_WIDEVINE_ENCRYPTION_FLAGS_H_
    +
    10 #define APP_WIDEVINE_ENCRYPTION_FLAGS_H_
    +
    11 
    +
    12 #include <gflags/gflags.h>
    +
    13 
    +
    14 #include "packager/app/gflags_hex_bytes.h"
    +
    15 
    +
    16 DECLARE_bool(enable_widevine_encryption);
    +
    17 DECLARE_bool(enable_widevine_decryption);
    +
    18 DECLARE_string(key_server_url);
    +
    19 DECLARE_hex_bytes(content_id);
    +
    20 DECLARE_string(policy);
    +
    21 DECLARE_int32(max_sd_pixels);
    +
    22 DECLARE_int32(max_hd_pixels);
    +
    23 DECLARE_int32(max_uhd1_pixels);
    +
    24 DECLARE_string(signer);
    +
    25 DECLARE_hex_bytes(aes_signing_key);
    +
    26 DECLARE_hex_bytes(aes_signing_iv);
    +
    27 DECLARE_string(rsa_signing_key_path);
    +
    28 DECLARE_int32(crypto_period_duration);
    +
    29 DECLARE_hex_bytes(group_id);
    +
    30 DECLARE_bool(enable_entitlement_license);
    +
    31 
    +
    32 namespace shaka {
    +
    33 
    + +
    37 
    +
    38 } // namespace shaka
    +
    39 
    +
    40 #endif // APP_WIDEVINE_ENCRYPTION_FLAGS_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    bool ValidateWidevineCryptoFlags()
    diff --git a/docs/dd/d58/bit__writer_8cc_source.html b/docs/dd/d58/bit__writer_8cc_source.html index a378de5714..3f5ae444ff 100644 --- a/docs/dd/d58/bit__writer_8cc_source.html +++ b/docs/dd/d58/bit__writer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/bit_writer.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    bit_writer.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/bit_writer.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 
    12 BitWriter::BitWriter(std::vector<uint8_t>* storage)
    13  : storage_(storage), initial_storage_size_(storage_->size()) {}
    14 
    15 void BitWriter::WriteBits(uint32_t bits, size_t number_of_bits) {
    16  DCHECK_NE(number_of_bits, 0u);
    17  DCHECK_LE(number_of_bits, 32u);
    18  DCHECK_LT(bits, 1ULL << number_of_bits);
    19 
    20  num_bits_ += number_of_bits;
    21  DCHECK_LE(num_bits_, 64);
    22  bits_ |= static_cast<uint64_t>(bits) << (64 - num_bits_);
    23 
    24  while (num_bits_ >= 8) {
    25  storage_->push_back(bits_ >> 56);
    26  bits_ <<= 8;
    27  num_bits_ -= 8;
    28  }
    29 }
    30 
    32  while (num_bits_ > 0) {
    33  storage_->push_back(bits_ >> 56);
    34  bits_ <<= 8;
    35  num_bits_ -= 8;
    36  }
    37  bits_ = 0;
    38  num_bits_ = 0;
    39 }
    40 
    41 } // namespace media
    42 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    -
    void WriteBits(uint32_t bits, size_t number_of_bits)
    Definition: bit_writer.cc:15
    -
    BitWriter(std::vector< uint8_t > *storage)
    Definition: bit_writer.cc:12
    -
    void Flush()
    Write pending bits, and align bitstream with extra zero bits.
    Definition: bit_writer.cc:31
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/bit_writer.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 
    +
    12 BitWriter::BitWriter(std::vector<uint8_t>* storage)
    +
    13  : storage_(storage), initial_storage_size_(storage_->size()) {}
    +
    14 
    +
    15 void BitWriter::WriteBits(uint32_t bits, size_t number_of_bits) {
    +
    16  DCHECK_NE(number_of_bits, 0u);
    +
    17  DCHECK_LE(number_of_bits, 32u);
    +
    18  DCHECK_LT(bits, 1ULL << number_of_bits);
    +
    19 
    +
    20  num_bits_ += number_of_bits;
    +
    21  DCHECK_LE(num_bits_, 64);
    +
    22  bits_ |= static_cast<uint64_t>(bits) << (64 - num_bits_);
    +
    23 
    +
    24  while (num_bits_ >= 8) {
    +
    25  storage_->push_back(bits_ >> 56);
    +
    26  bits_ <<= 8;
    +
    27  num_bits_ -= 8;
    +
    28  }
    +
    29 }
    +
    30 
    + +
    32  while (num_bits_ > 0) {
    +
    33  storage_->push_back(bits_ >> 56);
    +
    34  bits_ <<= 8;
    +
    35  num_bits_ -= 8;
    +
    36  }
    +
    37  bits_ = 0;
    +
    38  num_bits_ = 0;
    +
    39 }
    +
    40 
    +
    41 } // namespace media
    +
    42 } // namespace shaka
    +
    BitWriter(std::vector< uint8_t > *storage)
    Definition: bit_writer.cc:12
    +
    void Flush()
    Write pending bits, and align bitstream with extra zero bits.
    Definition: bit_writer.cc:31
    +
    void WriteBits(uint32_t bits, size_t number_of_bits)
    Definition: bit_writer.cc:15
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d58/crypto__params_8h_source.html b/docs/dd/d58/crypto__params_8h_source.html index bfc2e16cfe..0c480fb472 100644 --- a/docs/dd/d58/crypto__params_8h_source.html +++ b/docs/dd/d58/crypto__params_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/public/crypto_params.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    crypto_params.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_PUBLIC_CRYPTO_PARAMS_H_
    8 #define PACKAGER_MEDIA_PUBLIC_CRYPTO_PARAMS_H_
    9 
    10 #include <functional>
    11 #include <map>
    12 #include <string>
    13 #include <vector>
    14 
    15 namespace shaka {
    16 
    18 enum class KeyProvider {
    19  kNone = 0,
    20  kWidevine = 1,
    21  kPlayReady = 2,
    22  kRawKey = 3,
    23 };
    24 
    28  std::string signer_name;
    29 
    30  enum class SigningKeyType {
    31  kNone,
    32  kAes,
    33  kRsa,
    34  };
    37  SigningKeyType signing_key_type = SigningKeyType::kNone;
    38  struct {
    40  std::vector<uint8_t> key;
    42  std::vector<uint8_t> iv;
    43  } aes;
    44  struct {
    46  std::string key;
    47  } rsa;
    48 };
    49 
    53  std::string key_server_url;
    55  std::vector<uint8_t> content_id;
    57  std::string policy;
    61  std::vector<uint8_t> group_id;
    64 };
    65 
    71  std::string key_server_url;
    73  std::string program_identifier;
    76  std::string ca_file;
    78  std::string client_cert_file;
    83 };
    84 
    86 struct RawKeyParams {
    90  std::vector<uint8_t> iv;
    94  std::vector<uint8_t> pssh;
    95 
    96  using StreamLabel = std::string;
    97  struct KeyInfo {
    98  std::vector<uint8_t> key_id;
    99  std::vector<uint8_t> key;
    100  };
    104  std::map<StreamLabel, KeyInfo> key_map;
    105 };
    106 
    112  KeyProvider key_provider = KeyProvider::kNone;
    113  // Only one of the three fields is valid.
    114  WidevineEncryptionParams widevine;
    115  PlayReadyEncryptionParams playready;
    116  RawKeyParams raw_key;
    117 
    119  enum class ProtectionSystem {
    120  kCommonSystem,
    121  kFairPlay,
    122  kMarlin,
    123  kPlayReady,
    124  kWidevine,
    125  };
    127  std::vector<ProtectionSystem> protection_systems;
    128 
    130  double clear_lead_in_seconds = 0;
    132  static constexpr uint32_t kProtectionSchemeCenc = 0x63656E63;
    133  static constexpr uint32_t kProtectionSchemeCbc1 = 0x63626331;
    134  static constexpr uint32_t kProtectionSchemeCens = 0x63656E73;
    135  static constexpr uint32_t kProtectionSchemeCbcs = 0x63626373;
    136  uint32_t protection_scheme = kProtectionSchemeCenc;
    139  static constexpr double kNoKeyRotation = 0;
    140  double crypto_period_duration_in_seconds = kNoKeyRotation;
    142  bool vp9_subsample_encryption = true;
    143 
    146  enum StreamType {
    147  kUnknown,
    148  kVideo,
    149  kAudio,
    150  };
    151 
    152  StreamType stream_type = kUnknown;
    153  union OneOf {
    154  OneOf() {}
    155 
    156  struct {
    157  int width = 0;
    158  int height = 0;
    159  float frame_rate = 0;
    160  int bit_depth = 0;
    161  } video;
    162 
    163  struct {
    164  int number_of_channels = 0;
    165  } audio;
    166  } oneof;
    167  };
    173  std::function<std::string(const EncryptedStreamAttributes& stream_attributes)>
    175 };
    176 
    180  std::string key_server_url;
    183 };
    184 
    190  KeyProvider key_provider = KeyProvider::kNone;
    191  // Only one of the two fields is valid.
    192  WidevineDecryptionParams widevine;
    193  RawKeyParams raw_key;
    194 };
    195 
    196 } // namespace shaka
    197 
    198 #endif // PACKAGER_MEDIA_PUBLIC_CRYPTO_PARAMS_H_
    std::string key_server_url
    Widevine license / key server URL.
    Definition: crypto_params.h:53
    -
    std::string key_server_url
    PlayReady license / key server URL.
    Definition: crypto_params.h:71
    -
    std::string client_cert_private_key_password
    Password to the private key file.
    Definition: crypto_params.h:82
    -
    KeyProvider
    Encryption / decryption key providers.
    Definition: crypto_params.h:18
    -
    Widevine decryption parameters.
    -
    std::function< std::string(const EncryptedStreamAttributes &stream_attributes)> stream_label_func
    -
    WidevineSigner signer
    Signer credential for Widevine license / key server.
    Definition: crypto_params.h:59
    -
    std::vector< uint8_t > content_id
    Content identifier.
    Definition: crypto_params.h:55
    -
    std::string program_identifier
    PlayReady program identifier.
    Definition: crypto_params.h:73
    -
    WidevineSigner signer
    Signer credential for Widevine license / key server.
    -
    All the methods that are virtual are virtual for mocking.
    -
    ProtectionSystem
    Supported protection systems.
    - -
    std::string key_server_url
    Widevine license / key server URL.
    -
    bool enable_entitlement_license
    Enables entitlement license when set to true.
    Definition: crypto_params.h:63
    -
    Raw key encryption/decryption parameters, i.e. with key parameters provided.
    Definition: crypto_params.h:86
    - -
    std::string signer_name
    Name of the signer / content provider.
    Definition: crypto_params.h:28
    -
    std::map< StreamLabel, KeyInfo > key_map
    - -
    std::vector< uint8_t > iv
    Definition: crypto_params.h:90
    -
    Widevine encryption parameters.
    Definition: crypto_params.h:51
    -
    std::vector< ProtectionSystem > protection_systems
    Protection systems to be generated.
    -
    Decryption parameters.
    - -
    Encryption parameters.
    -
    Encrypted stream information that is used to determine stream label.
    -
    std::vector< uint8_t > key
    AES signing key.
    Definition: crypto_params.h:40
    -
    std::string policy
    The name of a stored policy, which specifies DRM content rights.
    Definition: crypto_params.h:57
    -
    std::string client_cert_file
    Absolute path to client certificate file.
    Definition: crypto_params.h:78
    -
    std::string key
    RSA signing private key.
    Definition: crypto_params.h:46
    -
    std::vector< uint8_t > pssh
    Definition: crypto_params.h:94
    -
    Signer credential for Widevine license server.
    Definition: crypto_params.h:26
    -
    std::vector< uint8_t > group_id
    Group identifier, if present licenses will belong to this group.
    Definition: crypto_params.h:61
    -
    std::string client_cert_private_key_file
    Absolute path to the private key file.
    Definition: crypto_params.h:80
    -
    std::vector< uint8_t > iv
    AES signing IV.
    Definition: crypto_params.h:42
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_PUBLIC_CRYPTO_PARAMS_H_
    +
    8 #define PACKAGER_MEDIA_PUBLIC_CRYPTO_PARAMS_H_
    +
    9 
    +
    10 #include <functional>
    +
    11 #include <map>
    +
    12 #include <string>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/status.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 
    +
    21 enum class KeyProvider {
    +
    22  kNone,
    +
    23  kRawKey,
    +
    24  kWidevine,
    +
    25  kPlayReady,
    +
    26 };
    +
    27 
    +
    31 enum class ProtectionSystem : uint16_t {
    +
    32  kNone = 0,
    +
    34  kCommon = (1 << 0),
    +
    35  kWidevine = (1 << 1),
    +
    36  kPlayReady = (1 << 2),
    +
    37  kFairPlay = (1 << 3),
    +
    38  kMarlin = (1 << 4),
    +
    39 };
    +
    40 
    +
    41 inline ProtectionSystem operator|(ProtectionSystem a, ProtectionSystem b) {
    +
    42  return static_cast<ProtectionSystem>(static_cast<uint16_t>(a) |
    +
    43  static_cast<uint16_t>(b));
    +
    44 }
    +
    45 inline ProtectionSystem& operator|=(ProtectionSystem& a, ProtectionSystem b) {
    +
    46  return a = a | b;
    +
    47 }
    +
    48 inline ProtectionSystem operator&(ProtectionSystem a, ProtectionSystem b) {
    +
    49  return static_cast<ProtectionSystem>(static_cast<uint16_t>(a) &
    +
    50  static_cast<uint16_t>(b));
    +
    51 }
    +
    52 inline ProtectionSystem& operator&=(ProtectionSystem& a, ProtectionSystem b) {
    +
    53  return a = a & b;
    +
    54 }
    +
    55 inline ProtectionSystem operator~(ProtectionSystem a) {
    +
    56  return static_cast<ProtectionSystem>(~static_cast<uint16_t>(a));
    +
    57 }
    +
    58 inline bool has_flag(ProtectionSystem value, ProtectionSystem flag) {
    +
    59  return (value & flag) == flag;
    +
    60 }
    +
    61 
    + +
    65  std::string signer_name;
    +
    66 
    +
    67  enum class SigningKeyType {
    +
    68  kNone,
    +
    69  kAes,
    +
    70  kRsa,
    +
    71  };
    +
    74  SigningKeyType signing_key_type = SigningKeyType::kNone;
    +
    75  struct {
    +
    77  std::vector<uint8_t> key;
    +
    79  std::vector<uint8_t> iv;
    +
    80  } aes;
    +
    81  struct {
    +
    83  std::string key;
    +
    84  } rsa;
    +
    85 };
    +
    86 
    + +
    90  std::string key_server_url;
    +
    92  std::vector<uint8_t> content_id;
    +
    94  std::string policy;
    + +
    98  std::vector<uint8_t> group_id;
    + +
    101 };
    +
    102 
    + +
    108  std::string key_server_url;
    +
    110  std::string program_identifier;
    +
    113  std::string ca_file;
    +
    115  std::string client_cert_file;
    + + +
    120 };
    +
    121 
    +
    123 struct RawKeyParams {
    +
    127  std::vector<uint8_t> iv;
    +
    131  std::vector<uint8_t> pssh;
    +
    132 
    +
    133  using StreamLabel = std::string;
    +
    134  struct KeyInfo {
    +
    135  std::vector<uint8_t> key_id;
    +
    136  std::vector<uint8_t> key;
    +
    137  std::vector<uint8_t> iv;
    +
    138  };
    +
    142  std::map<StreamLabel, KeyInfo> key_map;
    +
    143 };
    +
    144 
    + +
    150  KeyProvider key_provider = KeyProvider::kNone;
    +
    151  // Only one of the three fields is valid.
    +
    152  WidevineEncryptionParams widevine;
    +
    153  PlayReadyEncryptionParams playready;
    +
    154  RawKeyParams raw_key;
    +
    155 
    + + +
    160 
    + +
    164  static constexpr uint32_t kProtectionSchemeCenc = 0x63656E63;
    +
    165  static constexpr uint32_t kProtectionSchemeCbc1 = 0x63626331;
    +
    166  static constexpr uint32_t kProtectionSchemeCens = 0x63656E73;
    +
    167  static constexpr uint32_t kProtectionSchemeCbcs = 0x63626373;
    +
    168  uint32_t protection_scheme = kProtectionSchemeCenc;
    +
    174  uint8_t crypt_byte_block = 1;
    +
    178  uint8_t skip_byte_block = 9;
    +
    181  static constexpr double kNoKeyRotation = 0;
    +
    182  double crypto_period_duration_in_seconds = kNoKeyRotation;
    + +
    185 
    + +
    188  enum StreamType {
    +
    189  kUnknown,
    +
    190  kVideo,
    +
    191  kAudio,
    +
    192  };
    +
    193 
    +
    194  StreamType stream_type = kUnknown;
    +
    195  union OneOf {
    +
    196  OneOf() {}
    +
    197 
    +
    198  struct {
    +
    199  int width = 0;
    +
    200  int height = 0;
    +
    201  float frame_rate = 0;
    +
    202  int bit_depth = 0;
    +
    203  } video;
    +
    204 
    +
    205  struct {
    +
    206  int number_of_channels = 0;
    +
    207  } audio;
    +
    208  } oneof;
    +
    209  };
    +
    215  std::function<std::string(const EncryptedStreamAttributes& stream_attributes)>
    + +
    217 };
    +
    218 
    + +
    222  std::string key_server_url;
    + +
    225 };
    +
    226 
    + +
    232  KeyProvider key_provider = KeyProvider::kNone;
    +
    233  // Only one of the two fields is valid.
    +
    234  WidevineDecryptionParams widevine;
    +
    235  RawKeyParams raw_key;
    +
    236 };
    +
    237 
    +
    238 } // namespace shaka
    +
    239 
    +
    240 #endif // PACKAGER_MEDIA_PUBLIC_CRYPTO_PARAMS_H_
    +
    All the methods that are virtual are virtual for mocking.
    + +
    ProtectionSystem
    Definition: crypto_params.h:31
    +
    @ kCommon
    The common key system from EME: https://goo.gl/s8RIhr.
    +
    Decryption parameters.
    + +
    Encrypted stream information that is used to determine stream label.
    +
    Encryption parameters.
    +
    double clear_lead_in_seconds
    Clear lead duration in seconds.
    +
    static constexpr uint32_t kProtectionSchemeCenc
    The protection scheme: "cenc", "cens", "cbc1", "cbcs".
    +
    bool vp9_subsample_encryption
    Enable/disable subsample encryption for VP9.
    +
    std::string playready_extra_header_data
    Extra XML data to add to PlayReady data.
    +
    std::function< std::string(const EncryptedStreamAttributes &stream_attributes)> stream_label_func
    + +
    ProtectionSystem protection_systems
    The protection systems to generate, multiple can be OR'd together.
    +
    static constexpr double kNoKeyRotation
    + + + +
    std::string client_cert_private_key_file
    Absolute path to the private key file.
    +
    std::string client_cert_private_key_password
    Password to the private key file.
    +
    std::string program_identifier
    PlayReady program identifier.
    +
    std::string client_cert_file
    Absolute path to client certificate file.
    +
    std::string key_server_url
    PlayReady license / key server URL.
    + + +
    Raw key encryption/decryption parameters, i.e. with key parameters provided.
    +
    std::map< StreamLabel, KeyInfo > key_map
    +
    std::vector< uint8_t > pssh
    +
    std::vector< uint8_t > iv
    +
    Widevine decryption parameters.
    +
    WidevineSigner signer
    Signer credential for Widevine license / key server.
    +
    std::string key_server_url
    Widevine license / key server URL.
    +
    Widevine encryption parameters.
    Definition: crypto_params.h:88
    +
    WidevineSigner signer
    Signer credential for Widevine license / key server.
    Definition: crypto_params.h:96
    +
    std::string policy
    The name of a stored policy, which specifies DRM content rights.
    Definition: crypto_params.h:94
    +
    bool enable_entitlement_license
    Enables entitlement license when set to true.
    +
    std::vector< uint8_t > content_id
    Content identifier.
    Definition: crypto_params.h:92
    +
    std::vector< uint8_t > group_id
    Group identifier, if present licenses will belong to this group.
    Definition: crypto_params.h:98
    +
    std::string key_server_url
    Widevine license / key server URL.
    Definition: crypto_params.h:90
    +
    Signer credential for Widevine license server.
    Definition: crypto_params.h:63
    +
    std::string key
    RSA signing private key.
    Definition: crypto_params.h:83
    +
    SigningKeyType signing_key_type
    Definition: crypto_params.h:74
    +
    std::string signer_name
    Name of the signer / content provider.
    Definition: crypto_params.h:65
    +
    std::vector< uint8_t > iv
    AES signing IV.
    Definition: crypto_params.h:79
    +
    std::vector< uint8_t > key
    AES signing key.
    Definition: crypto_params.h:77
    +
    diff --git a/docs/dd/d59/classshaka_1_1media_1_1mp2t_1_1EsParserH265-members.html b/docs/dd/d59/classshaka_1_1media_1_1mp2t_1_1EsParserH265-members.html index 5ec7263fae..83526cdfc3 100644 --- a/docs/dd/d59/classshaka_1_1media_1_1mp2t_1_1EsParserH265-members.html +++ b/docs/dd/d59/classshaka_1_1media_1_1mp2t_1_1EsParserH265-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::mp2t::EsParserH265, including all inherited members.

    - - - - - - - - - - - - + + + + + + + + + + + + +
    EmitSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    EsParserH265(uint32_t pid, const NewStreamInfoCB &new_stream_info_cb, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH265)shaka::media::mp2t::EsParserH265
    EsParserH26x(Nalu::CodecType type, std::unique_ptr< H26xByteToUnitStreamConverter > stream_converter, uint32_t pid, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
    Flush() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
    NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
    pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    Reset() override (defined in shaka::media::mp2t::EsParserH265)shaka::media::mp2t::EsParserH265virtual
    stream_converter() const (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xinlineprotected
    ~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
    ~EsParserH265() override (defined in shaka::media::mp2t::EsParserH265)shaka::media::mp2t::EsParserH265
    ~EsParserH26x() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
    EmitTextSampleCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    EsParser(uint32_t pid) (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    EsParserH265(uint32_t pid, const NewStreamInfoCB &new_stream_info_cb, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH265)shaka::media::mp2t::EsParserH265
    EsParserH26x(Nalu::CodecType type, std::unique_ptr< H26xByteToUnitStreamConverter > stream_converter, uint32_t pid, const EmitSampleCB &emit_sample_cb) (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
    Flush() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
    NewStreamInfoCB typedef (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParser
    Parse(const uint8_t *buf, int size, int64_t pts, int64_t dts) override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xvirtual
    pid() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinline
    Reset() override (defined in shaka::media::mp2t::EsParserH265)shaka::media::mp2t::EsParserH265virtual
    stream_converter() const (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26xinlineprotected
    ~EsParser() (defined in shaka::media::mp2t::EsParser)shaka::media::mp2t::EsParserinlinevirtual
    ~EsParserH265() override (defined in shaka::media::mp2t::EsParserH265)shaka::media::mp2t::EsParserH265
    ~EsParserH26x() override (defined in shaka::media::mp2t::EsParserH26x)shaka::media::mp2t::EsParserH26x
    diff --git a/docs/dd/d59/structshaka_1_1media_1_1mp4_1_1SchemeInfo-members.html b/docs/dd/d59/structshaka_1_1media_1_1mp4_1_1SchemeInfo-members.html index b6d2dd3e18..7711fe32d4 100644 --- a/docs/dd/d59/structshaka_1_1media_1_1mp4_1_1SchemeInfo-members.html +++ b/docs/dd/d59/structshaka_1_1media_1_1mp4_1_1SchemeInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/d5e/structshaka_1_1media_1_1TextSettings.html b/docs/dd/d5e/structshaka_1_1media_1_1TextSettings.html new file mode 100644 index 0000000000..31222b2169 --- /dev/null +++ b/docs/dd/d5e/structshaka_1_1media_1_1TextSettings.html @@ -0,0 +1,195 @@ + + + + + + + +Shaka Packager SDK: shaka::media::TextSettings Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::TextSettings Struct Reference
    +
    +
    + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    base::Optional< TextNumberline
     
    base::Optional< TextNumberposition
     
    base::Optional< TextNumberwidth
     
    base::Optional< TextNumberheight
     
    +std::string region
     The region to draw the cue in.
     
    WritingDirection writing_direction = WritingDirection::kHorizontal
     
    +TextAlignment text_alignment = TextAlignment::kCenter
     How to align the text within the cue box.
     
    +

    Detailed Description

    +
    +

    Definition at line 55 of file text_sample.h.

    +

    Member Data Documentation

    + +

    ◆ height

    + +
    +
    + + + + +
    base::Optional<TextNumber> shaka::media::TextSettings::height
    +
    +

    For horizontal cues, this is the height of the area to draw cues. For vertical cues, this is the width. Percent units are relative to the window.

    + +

    Definition at line 69 of file text_sample.h.

    + +
    +
    + +

    ◆ line

    + +
    +
    + + + + +
    base::Optional<TextNumber> shaka::media::TextSettings::line
    +
    +

    The line offset of the cue. For horizontal cues, this is the vertical offset. Percent units are relative to the window.

    + +

    Definition at line 58 of file text_sample.h.

    + +
    +
    + +

    ◆ position

    + +
    +
    + + + + +
    base::Optional<TextNumber> shaka::media::TextSettings::position
    +
    +

    The position offset of the cue. For horizontal cues, this is the horizontal offset. Percent units are relative to the window.

    + +

    Definition at line 61 of file text_sample.h.

    + +
    +
    + +

    ◆ width

    + +
    +
    + + + + +
    base::Optional<TextNumber> shaka::media::TextSettings::width
    +
    +

    For horizontal cues, this is the width of the area to draw cues. For vertical cues, this is the height. Percent units are relative to the window.

    + +

    Definition at line 65 of file text_sample.h.

    + +
    +
    + +

    ◆ writing_direction

    + +
    +
    + + + + +
    WritingDirection shaka::media::TextSettings::writing_direction = WritingDirection::kHorizontal
    +
    +

    The direction to draw text. This is also used to determine how cues are positioned within the region.

    + +

    Definition at line 76 of file text_sample.h.

    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/docs/dd/d60/raw__key__source_8h_source.html b/docs/dd/d60/raw__key__source_8h_source.html index 8462196b8e..2ea3fb9e20 100644 --- a/docs/dd/d60/raw__key__source_8h_source.html +++ b/docs/dd/d60/raw__key__source_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/raw_key_source.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    raw_key_source.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_RAW_KEY_SOURCE_H_
    8 #define PACKAGER_MEDIA_BASE_RAW_KEY_SOURCE_H_
    9 
    10 #include <memory>
    11 #include <string>
    12 #include <vector>
    13 
    14 #include "packager/media/base/key_source.h"
    15 #include "packager/media/public/crypto_params.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    21 class RawKeySource : public KeySource {
    22  public:
    23  ~RawKeySource() override;
    24 
    27  Status FetchKeys(EmeInitDataType init_data_type,
    28  const std::vector<uint8_t>& init_data) override;
    29  Status GetKey(const std::string& stream_label, EncryptionKey* key) override;
    30  Status GetKey(const std::vector<uint8_t>& key_id,
    31  EncryptionKey* key) override;
    32  Status GetCryptoPeriodKey(uint32_t crypto_period_index,
    33  uint32_t crypto_period_duration_in_seconds,
    34  const std::string& stream_label,
    35  EncryptionKey* key) override;
    37 
    46  static std::unique_ptr<RawKeySource> Create(const RawKeyParams& raw_key,
    47  int protection_system_flags,
    48  FourCC protection_scheme);
    49 
    50  protected:
    51  // Allow default constructor for mock key sources.
    52  RawKeySource();
    53 
    54  private:
    55  RawKeySource(EncryptionKeyMap&& encryption_key_map,
    56  int protection_systems_flags,
    57  FourCC protection_scheme);
    58  RawKeySource(const RawKeySource&) = delete;
    59  RawKeySource& operator=(const RawKeySource&) = delete;
    60 
    61  EncryptionKeyMap encryption_key_map_;
    62 };
    63 
    64 } // namespace media
    65 } // namespace shaka
    66 
    67 #endif // PACKAGER_MEDIA_BASE_RAW_KEY_SOURCE_H_
    static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key, int protection_system_flags, FourCC protection_scheme)
    -
    All the methods that are virtual are virtual for mocking.
    - -
    Raw key encryption/decryption parameters, i.e. with key parameters provided.
    Definition: crypto_params.h:86
    - -
    A key source that uses raw keys for encryption.
    -
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    -
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_RAW_KEY_SOURCE_H_
    +
    8 #define PACKAGER_MEDIA_BASE_RAW_KEY_SOURCE_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <string>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/media/base/key_source.h"
    +
    15 #include "packager/media/public/crypto_params.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    +
    21 class RawKeySource : public KeySource {
    +
    22  public:
    +
    23  ~RawKeySource() override;
    +
    24 
    +
    27  Status FetchKeys(EmeInitDataType init_data_type,
    +
    28  const std::vector<uint8_t>& init_data) override;
    +
    29  Status GetKey(const std::string& stream_label, EncryptionKey* key) override;
    +
    30  Status GetKey(const std::vector<uint8_t>& key_id,
    +
    31  EncryptionKey* key) override;
    +
    32  Status GetCryptoPeriodKey(uint32_t crypto_period_index,
    +
    33  uint32_t crypto_period_duration_in_seconds,
    +
    34  const std::string& stream_label,
    +
    35  EncryptionKey* key) override;
    +
    37 
    +
    41  static std::unique_ptr<RawKeySource> Create(const RawKeyParams& raw_key);
    +
    42 
    +
    43  protected:
    +
    44  // Allow default constructor for mock key sources.
    +
    45  RawKeySource();
    +
    46 
    +
    47  private:
    +
    48  RawKeySource(EncryptionKeyMap&& encryption_key_map);
    +
    49  RawKeySource(const RawKeySource&) = delete;
    +
    50  RawKeySource& operator=(const RawKeySource&) = delete;
    +
    51 
    +
    52  EncryptionKeyMap encryption_key_map_;
    +
    53 };
    +
    54 
    +
    55 } // namespace media
    +
    56 } // namespace shaka
    +
    57 
    +
    58 #endif // PACKAGER_MEDIA_BASE_RAW_KEY_SOURCE_H_
    + +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    +
    A key source that uses raw keys for encryption.
    +
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    +
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    +
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    +
    static std::unique_ptr< RawKeySource > Create(const RawKeyParams &raw_key)
    +
    All the methods that are virtual are virtual for mocking.
    +
    Raw key encryption/decryption parameters, i.e. with key parameters provided.
    +
    diff --git a/docs/dd/d64/structshaka_1_1media_1_1mp4_1_1SyncSample-members.html b/docs/dd/d64/structshaka_1_1media_1_1mp4_1_1SyncSample-members.html index b9b5c04823..25edf1d4bd 100644 --- a/docs/dd/d64/structshaka_1_1media_1_1mp4_1_1SyncSample-members.html +++ b/docs/dd/d64/structshaka_1_1media_1_1mp4_1_1SyncSample-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/d65/vp8__parser_8h_source.html b/docs/dd/d65/vp8__parser_8h_source.html index f969c39969..ea1ea6ee85 100644 --- a/docs/dd/d65/vp8__parser_8h_source.html +++ b/docs/dd/d65/vp8__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/vp8_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    vp8_parser.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_VP8_PARSER_H_
    8 #define PACKAGER_MEDIA_CODECS_VP8_PARSER_H_
    9 
    10 #include <stdint.h>
    11 #include <stdlib.h>
    12 
    13 #include "packager/base/macros.h"
    14 #include "packager/media/codecs/vpx_parser.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    21 class VP8Parser : public VPxParser {
    22  public:
    23  VP8Parser();
    24  ~VP8Parser() override;
    25 
    32  bool Parse(const uint8_t* data,
    33  size_t data_size,
    34  std::vector<VPxFrameInfo>* vpx_frames) override;
    35 
    41  static bool IsKeyframe(const uint8_t* data, size_t data_size);
    42 
    43  private:
    44  // Keep track of the current width and height. Note that they may change from
    45  // frame to frame.
    46  uint32_t width_;
    47  uint32_t height_;
    48 
    49  DISALLOW_COPY_AND_ASSIGN(VP8Parser);
    50 };
    51 
    52 } // namespace media
    53 } // namespace shaka
    54 
    55 #endif // PACKAGER_MEDIA_CODECS_VP8_PARSER_H_
    -
    bool Parse(const uint8_t *data, size_t data_size, std::vector< VPxFrameInfo > *vpx_frames) override
    Definition: vp8_parser.cc:100
    -
    All the methods that are virtual are virtual for mocking.
    - -
    static bool IsKeyframe(const uint8_t *data, size_t data_size)
    Definition: vp8_parser.cc:179
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_VP8_PARSER_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_VP8_PARSER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <stdlib.h>
    +
    12 
    +
    13 #include "packager/base/macros.h"
    +
    14 #include "packager/media/codecs/vpx_parser.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    21 class VP8Parser : public VPxParser {
    +
    22  public:
    +
    23  VP8Parser();
    +
    24  ~VP8Parser() override;
    +
    25 
    +
    32  bool Parse(const uint8_t* data,
    +
    33  size_t data_size,
    +
    34  std::vector<VPxFrameInfo>* vpx_frames) override;
    +
    35 
    +
    41  static bool IsKeyframe(const uint8_t* data, size_t data_size);
    +
    42 
    +
    43  private:
    +
    44  // Keep track of the current width and height. Note that they may change from
    +
    45  // frame to frame.
    +
    46  uint32_t width_;
    +
    47  uint32_t height_;
    +
    48 
    +
    49  DISALLOW_COPY_AND_ASSIGN(VP8Parser);
    +
    50 };
    +
    51 
    +
    52 } // namespace media
    +
    53 } // namespace shaka
    +
    54 
    +
    55 #endif // PACKAGER_MEDIA_CODECS_VP8_PARSER_H_
    + +
    bool Parse(const uint8_t *data, size_t data_size, std::vector< VPxFrameInfo > *vpx_frames) override
    Definition: vp8_parser.cc:100
    +
    static bool IsKeyframe(const uint8_t *data, size_t data_size)
    Definition: vp8_parser.cc:179
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d67/h264__byte__to__unit__stream__converter_8cc_source.html b/docs/dd/d67/h264__byte__to__unit__stream__converter_8cc_source.html index 4d4bd5b80b..7164e0c8c8 100644 --- a/docs/dd/d67/h264__byte__to__unit__stream__converter_8cc_source.html +++ b/docs/dd/d67/h264__byte__to__unit__stream__converter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h264_byte_to_unit_stream_converter.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    h264_byte_to_unit_stream_converter.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/h264_byte_to_unit_stream_converter.h"
    8 
    9 #include <limits>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/media/base/buffer_writer.h"
    13 #include "packager/media/codecs/h264_parser.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    20 
    22  H26xStreamFormat stream_format)
    23  : H26xByteToUnitStreamConverter(Nalu::kH264, stream_format) {}
    24 
    25 H264ByteToUnitStreamConverter::~H264ByteToUnitStreamConverter() {}
    26 
    28  std::vector<uint8_t>* decoder_config) const {
    29  DCHECK(decoder_config);
    30 
    31  if ((last_sps_.size() < 4) || last_pps_.empty()) {
    32  // No data available to construct AVCDecoderConfigurationRecord.
    33  return false;
    34  }
    35 
    36  // Construct an AVCDecoderConfigurationRecord containing a single SPS and a
    37  // single PPS NALU. Please refer to ISO/IEC 14496-15 for format specifics.
    38  BufferWriter buffer(last_sps_.size() + last_pps_.size() + 11);
    39  uint8_t version(1);
    40  buffer.AppendInt(version);
    41  buffer.AppendInt(last_sps_[1]);
    42  buffer.AppendInt(last_sps_[2]);
    43  buffer.AppendInt(last_sps_[3]);
    44  uint8_t reserved_and_length_size_minus_one(0xff);
    45  buffer.AppendInt(reserved_and_length_size_minus_one);
    46  uint8_t reserved_and_num_sps(0xe1);
    47  buffer.AppendInt(reserved_and_num_sps);
    48  buffer.AppendInt(static_cast<uint16_t>(last_sps_.size()));
    49  buffer.AppendVector(last_sps_);
    50  uint8_t num_pps(1);
    51  buffer.AppendInt(num_pps);
    52  buffer.AppendInt(static_cast<uint16_t>(last_pps_.size()));
    53  buffer.AppendVector(last_pps_);
    54 
    55  buffer.SwapBuffer(decoder_config);
    56  return true;
    57 }
    58 
    59 bool H264ByteToUnitStreamConverter::ProcessNalu(const Nalu& nalu) {
    60  DCHECK(nalu.data());
    61 
    62  // Skip the start code, but keep the 1-byte NALU type.
    63  const uint8_t* nalu_ptr = nalu.data();
    64  const uint64_t nalu_size = nalu.payload_size() + nalu.header_size();
    65 
    66  switch (nalu.type()) {
    67  case Nalu::H264_SPS:
    68  if (strip_parameter_set_nalus())
    69  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_sps_);
    70  // Grab SPS NALU.
    71  last_sps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    72  return strip_parameter_set_nalus();
    73  case Nalu::H264_PPS:
    74  if (strip_parameter_set_nalus())
    75  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_pps_);
    76  // Grab PPS NALU.
    77  last_pps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    78  return strip_parameter_set_nalus();
    79  case Nalu::H264_AUD:
    80  // Ignore AUD NALU.
    81  return true;
    82  default:
    83  // Have the base class handle other NALU types.
    84  return false;
    85  }
    86 }
    87 
    88 } // namespace media
    89 } // namespace shaka
    -
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    -
    All the methods that are virtual are virtual for mocking.
    -
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    - -
    bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const override
    -
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    - -
    int type() const
    Definition: nalu_reader.h:113
    -
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/h264_byte_to_unit_stream_converter.h"
    +
    8 
    +
    9 #include <limits>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/buffer_writer.h"
    +
    13 #include "packager/media/codecs/h264_parser.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    18 namespace {
    +
    19 // utility helper function to get an sps
    +
    20 const H264Sps* ParseSpsFromBytes(const std::vector<uint8_t> sps,
    +
    21  H264Parser* parser) {
    +
    22  Nalu nalu;
    +
    23  if (!nalu.Initialize(Nalu::kH264, sps.data(), sps.size()))
    +
    24  return nullptr;
    +
    25 
    +
    26  int sps_id = 0;
    +
    27  if (parser->ParseSps(nalu, &sps_id) != H264Parser::kOk)
    +
    28  return nullptr;
    +
    29  return parser->GetSps(sps_id);
    +
    30 }
    +
    31 } // namespace
    +
    32 
    + + +
    35 
    + +
    37  H26xStreamFormat stream_format)
    +
    38  : H26xByteToUnitStreamConverter(Nalu::kH264, stream_format) {}
    +
    39 
    +
    40 H264ByteToUnitStreamConverter::~H264ByteToUnitStreamConverter() {}
    +
    41 
    + +
    43  std::vector<uint8_t>* decoder_config) const {
    +
    44  DCHECK(decoder_config);
    +
    45  if ((last_sps_.size() < 4) || last_pps_.empty()) {
    +
    46  // No data available to construct AVCDecoderConfigurationRecord.
    +
    47  return false;
    +
    48  }
    +
    49  // Construct an AVCDecoderConfigurationRecord containing a single SPS, a
    +
    50  // single PPS, and if available, a single SPS Extension NALU.
    +
    51  // Please refer to ISO/IEC 14496-15 for format specifics.
    +
    52  BufferWriter buffer;
    +
    53  uint8_t version(1);
    +
    54  buffer.AppendInt(version);
    +
    55  buffer.AppendInt(last_sps_[1]);
    +
    56  buffer.AppendInt(last_sps_[2]);
    +
    57  buffer.AppendInt(last_sps_[3]);
    +
    58  uint8_t reserved_and_length_size_minus_one(0xff);
    +
    59  buffer.AppendInt(reserved_and_length_size_minus_one);
    +
    60  uint8_t reserved_and_num_sps(0xe1);
    +
    61  buffer.AppendInt(reserved_and_num_sps);
    +
    62  buffer.AppendInt(static_cast<uint16_t>(last_sps_.size()));
    +
    63  buffer.AppendVector(last_sps_);
    +
    64  uint8_t num_pps(1);
    +
    65  buffer.AppendInt(num_pps);
    +
    66  buffer.AppendInt(static_cast<uint16_t>(last_pps_.size()));
    +
    67  buffer.AppendVector(last_pps_);
    +
    68  // handle profile special cases, refer to ISO/IEC 14496-15 Section 5.3.3.1.2
    +
    69  uint8_t profile_indication = last_sps_[1];
    +
    70  if (profile_indication == 100 || profile_indication == 110 ||
    +
    71  profile_indication == 122 || profile_indication == 144) {
    +
    72 
    +
    73  H264Parser parser;
    +
    74  const H264Sps* sps = ParseSpsFromBytes(last_sps_, &parser);
    +
    75  if (sps == nullptr)
    +
    76  return false;
    +
    77 
    +
    78  uint8_t reserved_chroma_format = 0xfc | (sps->chroma_format_idc);
    +
    79  buffer.AppendInt(reserved_chroma_format);
    +
    80  uint8_t reserved_bit_depth_luma_minus8 = 0xf8 | sps->bit_depth_luma_minus8;
    +
    81  buffer.AppendInt(reserved_bit_depth_luma_minus8);
    +
    82  uint8_t reserved_bit_depth_chroma_minus8 = 0xf8 | sps->bit_depth_chroma_minus8;
    +
    83  buffer.AppendInt(reserved_bit_depth_chroma_minus8);
    +
    84 
    +
    85  if (last_sps_ext_.empty()) {
    +
    86  uint8_t num_sps_ext(0);
    +
    87  buffer.AppendInt(num_sps_ext);
    +
    88  } else {
    +
    89  uint8_t num_sps_ext(1);
    +
    90  buffer.AppendInt(num_sps_ext);
    +
    91  buffer.AppendVector(last_sps_ext_);
    +
    92  }
    +
    93  }
    +
    94 
    +
    95  buffer.SwapBuffer(decoder_config);
    +
    96  return true;
    +
    97 }
    +
    98 
    +
    99 bool H264ByteToUnitStreamConverter::ProcessNalu(const Nalu& nalu) {
    +
    100  DCHECK(nalu.data());
    +
    101 
    +
    102  // Skip the start code, but keep the 1-byte NALU type.
    +
    103  const uint8_t* nalu_ptr = nalu.data();
    +
    104  const uint64_t nalu_size = nalu.payload_size() + nalu.header_size();
    +
    105 
    +
    106  switch (nalu.type()) {
    +
    107  case Nalu::H264_SPS:
    +
    108  if (strip_parameter_set_nalus())
    +
    109  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_sps_);
    +
    110  // Grab SPS NALU.
    +
    111  last_sps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    +
    112  return strip_parameter_set_nalus();
    +
    113  case Nalu::H264_SPSExtension:
    +
    114  if (strip_parameter_set_nalus())
    +
    115  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_sps_ext_);
    +
    116  // Grab SPSExtension NALU.
    +
    117  last_sps_ext_.assign(nalu_ptr, nalu_ptr + nalu_size);
    +
    118  return strip_parameter_set_nalus();
    +
    119  case Nalu::H264_PPS:
    +
    120  if (strip_parameter_set_nalus())
    +
    121  WarnIfNotMatch(nalu.type(), nalu_ptr, nalu_size, last_pps_);
    +
    122  // Grab PPS NALU.
    +
    123  last_pps_.assign(nalu_ptr, nalu_ptr + nalu_size);
    +
    124  return strip_parameter_set_nalus();
    +
    125  case Nalu::H264_AUD:
    +
    126  // Ignore AUD NALU.
    +
    127  return true;
    +
    128  default:
    +
    129  // Have the base class handle other NALU types.
    +
    130  return false;
    +
    131  }
    +
    132 }
    +
    133 
    +
    134 } // namespace media
    +
    135 } // namespace shaka
    + + + +
    bool GetDecoderConfigurationRecord(std::vector< uint8_t > *decoder_config) const override
    + +
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    + +
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    +
    int type() const
    Definition: nalu_reader.h:113
    +
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    +
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/dd/d6e/classshaka_1_1media_1_1H265VideoSliceHeaderParser-members.html b/docs/dd/d6e/classshaka_1_1media_1_1H265VideoSliceHeaderParser-members.html index 75dfb12472..68e9d66a69 100644 --- a/docs/dd/d6e/classshaka_1_1media_1_1H265VideoSliceHeaderParser-members.html +++ b/docs/dd/d6e/classshaka_1_1media_1_1H265VideoSliceHeaderParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/d71/structshaka_1_1media_1_1mp4_1_1PixelAspectRatio.html b/docs/dd/d71/structshaka_1_1media_1_1mp4_1_1PixelAspectRatio.html index 50c519d1da..2b9b06ae67 100644 --- a/docs/dd/d71/structshaka_1_1media_1_1mp4_1_1PixelAspectRatio.html +++ b/docs/dd/d71/structshaka_1_1media_1_1mp4_1_1PixelAspectRatio.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::PixelAspectRatio Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -115,7 +118,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 270 of file box_definitions.h.

    +

    Definition at line 271 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -143,7 +146,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1442 of file box_definitions.cc.

    +

    Definition at line 1468 of file box_definitions.cc.

    @@ -154,9 +157,7 @@ Additional Inherited Members diff --git a/docs/dd/d74/classshaka_1_1media_1_1MediaHandlerGraphTestBase-members.html b/docs/dd/d74/classshaka_1_1media_1_1MediaHandlerGraphTestBase-members.html index 170a48cf14..3b94d0de63 100644 --- a/docs/dd/d74/classshaka_1_1media_1_1MediaHandlerGraphTestBase-members.html +++ b/docs/dd/d74/classshaka_1_1media_1_1MediaHandlerGraphTestBase-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/d79/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header.html b/docs/dd/d79/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header.html new file mode 100644 index 0000000000..6e24f66cb1 --- /dev/null +++ b/docs/dd/d79/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header.html @@ -0,0 +1,501 @@ + + + + + + + +Shaka Packager SDK: shaka::media::mp2t::Mpeg1Header Class Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::mp2t::Mpeg1Header Class Reference
    +
    +
    + +

    #include <mpeg1_header.h>

    +
    +Inheritance diagram for shaka::media::mp2t::Mpeg1Header:
    +
    +
    + + +shaka::media::mp2t::AudioHeader + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Public Member Functions

    AudioHeader implementation overrides.
    bool IsSyncWord (const uint8_t *buf) const override
     
    size_t GetMinFrameSize () const override
     
    size_t GetSamplesPerFrame () const override
     
    bool Parse (const uint8_t *mpeg1_frame, size_t mpeg1_frame_size) override
     
    size_t GetHeaderSize () const override
     
    size_t GetFrameSize () const override
     
    size_t GetFrameSizeWithoutParsing (const uint8_t *data, size_t num_bytes) const override
     
    void GetAudioSpecificConfig (std::vector< uint8_t > *buffer) const override
     
    uint8_t GetObjectType () const override
     
    uint32_t GetSamplingFrequency () const override
     
    uint8_t GetNumChannels () const override
     
    +

    Detailed Description

    +

    Class which parses Mpeg1 audio frame (header / metadata) and synthesizes AudioSpecificConfig from audio frame content.

    +

    See https://www.datavoyage.com/mpgscript/mpeghdr.htm

    + +

    Definition at line 17 of file mpeg1_header.h.

    +

    Member Function Documentation

    + +

    ◆ GetAudioSpecificConfig()

    + +
    +
    + + + + + +
    + + + + + + + + +
    void shaka::media::mp2t::Mpeg1Header::GetAudioSpecificConfig (std::vector< uint8_t > * buffer) const
    +
    +overridevirtual
    +
    +

    Synthesize an AudioSpecificConfig record from the fields within the audio header. Should only be called after a successful Parse.

    Parameters
    + + +
    [out]bufferis a pointer to a vector to contain the AudioSpecificConfig.
    +
    +
    +
    Returns
    true if successful, false otherwise.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 182 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ GetFrameSize()

    + +
    +
    + + + + + +
    + + + + + + + +
    size_t shaka::media::mp2t::Mpeg1Header::GetFrameSize () const
    +
    +overridevirtual
    +
    +

    Should only be called after a successful Parse.

    Returns
    the size of frame (header + payload).
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 160 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ GetFrameSizeWithoutParsing()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + +
    size_t shaka::media::mp2t::Mpeg1Header::GetFrameSizeWithoutParsing (const uint8_t * data,
    size_t num_bytes 
    ) const
    +
    +overridevirtual
    +
    +

    Obtain the size of the frame from the header data without doing a full Parse.

    Returns
    the size of the frame (header + payload).
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 164 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ GetHeaderSize()

    + +
    +
    + + + + + +
    + + + + + + + +
    size_t shaka::media::mp2t::Mpeg1Header::GetHeaderSize () const
    +
    +overridevirtual
    +
    +

    Should only be called after a successful Parse.

    Returns
    The size of audio header.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 154 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ GetMinFrameSize()

    + +
    +
    + + + + + +
    + + + + + + + +
    size_t shaka::media::mp2t::Mpeg1Header::GetMinFrameSize () const
    +
    +overridevirtual
    +
    +
    Returns
    The minium frame size.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 103 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ GetNumChannels()

    + +
    +
    + + + + + +
    + + + + + + + +
    uint8_t shaka::media::mp2t::Mpeg1Header::GetNumChannels () const
    +
    +overridevirtual
    +
    +

    Should only be called after a successful Parse.

    Returns
    Number of channels for this frame.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 235 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ GetObjectType()

    + +
    +
    + + + + + +
    + + + + + + + +
    uint8_t shaka::media::mp2t::Mpeg1Header::GetObjectType () const
    +
    +overridevirtual
    +
    +

    Should only be called after a successful Parse.

    Returns
    The audio profile for this frame. Only meaningful for AAC.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 218 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ GetSamplesPerFrame()

    + +
    +
    + + + + + +
    + + + + + + + +
    size_t shaka::media::mp2t::Mpeg1Header::GetSamplesPerFrame () const
    +
    +overridevirtual
    +
    +
    Returns
    Number of audio samples per frame.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 107 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ GetSamplingFrequency()

    + +
    +
    + + + + + +
    + + + + + + + +
    uint32_t shaka::media::mp2t::Mpeg1Header::GetSamplingFrequency () const
    +
    +overridevirtual
    +
    +

    Should only be called after a successful Parse.

    Returns
    The sampling frequency for this frame.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 231 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ IsSyncWord()

    + +
    +
    + + + + + +
    + + + + + + + + +
    bool shaka::media::mp2t::Mpeg1Header::IsSyncWord (const uint8_t * buf) const
    +
    +overridevirtual
    +
    +

    Check if the leading word (2 bytes) is sync signal.

    Parameters
    + + +
    bufpoints to the buffer to be checked. Must be at least 2 bytes.
    +
    +
    +
    Returns
    true if corresponds to a syncword.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 94 of file mpeg1_header.cc.

    + +
    +
    + +

    ◆ Parse()

    + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + + + + +
    bool shaka::media::mp2t::Mpeg1Header::Parse (const uint8_t * audio_frame,
    size_t audio_frame_size 
    )
    +
    +overridevirtual
    +
    +

    Parse a partial audio frame, extracting the fields within. Only audio frame header / metadata is parsed. The audio_frame_size must contain the full header / metadata.

    Parameters
    + + + +
    audio_frameis an input parameter pointing to an audio frame.
    audio_frame_sizeis the size, in bytes of the input data. It can be smaller than the actual frame size, but it should not be smaller than the header size.
    +
    +
    +
    Returns
    true if successful, false otherwise.
    + +

    Implements shaka::media::mp2t::AudioHeader.

    + +

    Definition at line 113 of file mpeg1_header.cc.

    + +
    +
    +
    The documentation for this class was generated from the following files: +
    + + + + diff --git a/docs/dd/d79/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header.png b/docs/dd/d79/classshaka_1_1media_1_1mp2t_1_1Mpeg1Header.png new file mode 100644 index 0000000000000000000000000000000000000000..89d8c8ac72164c9be57929304d184851c12eeae3 GIT binary patch literal 821 zcmeAS@N?(olHy`uVBq!ia0vp^r-3+tgBeIRv=lZ1DTx4|5ZC|z{{xvX-h3_XKQsZz z0^S-*@Hz|0kJ3 zV$yS#zTM)~5%@l3_YIjh6T+vZMzRTZcbpKIrK6L7EK+?ey{24xn`u@R9-vHraMD7WVhqe(&G`)>)I;gPIE67yZmvfs6|5H!^bCb zuB!WI>*78|F`SoXe&NyzLeLZ>ShSt>mE7UWCrW&&Al>R^d@VHK@?c$3| zf*1cSzaRNFjq!}i-E)>Y@n8R}Xq_YXdB*G91C{Y}E`(3s(tB^p`$?*i_bTJ_zD2C` z+P6XBp53(@kL;#d1=*TQ-`HELP+2@IWM0tdc-Wsq=T-e@ED_yEt5PcD*dX)4op_A`E2agyo6d^K)|`dK;*z@TIJ zvYe2>o+ScK5-uzaiYAc^zb>aRzVH|AX5HQSb4#q%^;ox?mrj1%@%H4u8>W`#|2tV9 z_y{i9a3oTW_wL2}X`S5S%}anGt@ZR-__V9_Y2J*FS9)%f&p9Qrex-NaD&LtFKa+mg zewW*$lbqF4Q{B5r?N#r_Z85yRZ5pc%%ZlyYWR>Z%>Q$1^G7jH*VU7K-3et>=PiL-n zE&TJbI_~`Gs?dkI{ZA)}P5ZlO-V)ECV=@~;=Faz8tQ0bN-7BHy+e=<9`~1$jJ7h6X z>$2i=r^^o}J*u=#+b*zmvWX7++~VX(+aAvTB)f6S)xSS#cfQ#eG_@wtaZl} cLCZe|^DwRLRmTGqfN7k;)78&qol`;+0F>Z^Y5)KL literal 0 HcmV?d00001 diff --git a/docs/dd/d7a/classshaka_1_1media_1_1DOVIDecoderConfigurationRecord-members.html b/docs/dd/d7a/classshaka_1_1media_1_1DOVIDecoderConfigurationRecord-members.html index e823bac813..fc7f15eb0f 100644 --- a/docs/dd/d7a/classshaka_1_1media_1_1DOVIDecoderConfigurationRecord-members.html +++ b/docs/dd/d7a/classshaka_1_1media_1_1DOVIDecoderConfigurationRecord-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/d7a/classshaka_1_1media_1_1MuxerListener.html b/docs/dd/d7a/classshaka_1_1media_1_1MuxerListener.html index a1dc2dfa21..b2b6c80a27 100644 --- a/docs/dd/d7a/classshaka_1_1media_1_1MuxerListener.html +++ b/docs/dd/d7a/classshaka_1_1media_1_1MuxerListener.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MuxerListener Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::CombinedMuxerListener -shaka::media::HlsNotifyMuxerListener +shaka::media::HlsNotifyMuxerListener shaka::media::MockMuxerListener shaka::media::MpdNotifyMuxerListener shaka::media::VodMediaInfoDumpMuxerListener - -
    +shaka::media::MultiCodecMuxerListener + + @@ -95,13 +99,13 @@ Classes @@ -171,7 +175,7 @@ Public Member Functions -

    Implemented in shaka::media::HlsNotifyMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, and shaka::media::CombinedMuxerListener.

    +

    Implemented in shaka::media::VodMediaInfoDumpMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::HlsNotifyMuxerListener, and shaka::media::CombinedMuxerListener.

    @@ -236,7 +240,7 @@ Public Member Functions -

    Implemented in shaka::media::HlsNotifyMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, and shaka::media::CombinedMuxerListener.

    +

    Implemented in shaka::media::MpdNotifyMuxerListener, shaka::media::HlsNotifyMuxerListener, shaka::media::CombinedMuxerListener, and shaka::media::VodMediaInfoDumpMuxerListener.

    @@ -264,7 +268,7 @@ Public Member Functions

    Called when the muxer starts encrypting the segments. Further segments notified via OnNewSegment() are encrypted. This may be called more than once e.g. per segment, but the semantics does not change.

    -

    Implemented in shaka::media::HlsNotifyMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, and shaka::media::CombinedMuxerListener.

    +

    Implemented in shaka::media::VodMediaInfoDumpMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::HlsNotifyMuxerListener, and shaka::media::CombinedMuxerListener.

    @@ -316,7 +320,7 @@ Public Member Functions -

    Implemented in shaka::media::HlsNotifyMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, and shaka::media::CombinedMuxerListener.

    +

    Implemented in shaka::media::VodMediaInfoDumpMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::HlsNotifyMuxerListener, and shaka::media::CombinedMuxerListener.

    @@ -361,7 +365,7 @@ Public Member Functions -

    Implemented in shaka::media::HlsNotifyMuxerListener, shaka::media::MockMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, and shaka::media::CombinedMuxerListener.

    +

    Implemented in shaka::media::MockMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::HlsNotifyMuxerListener, and shaka::media::CombinedMuxerListener.

    @@ -410,7 +414,7 @@ Public Member Functions

    Classes

    Public Types

    enum  ContainerType {
    -  kContainerUnknown = 0, -kContainerMp4, -kContainerMpeg2ts, -kContainerWebM, -
    -  kContainerText, -kContainerPackedAudio +  kContainerUnknown = 0 +, kContainerMp4 +, kContainerMpeg2ts +, kContainerWebM +,
    +  kContainerText +, kContainerPackedAudio
    }
     
    -

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    +

    Called when muxing starts. For MPEG DASH Live profile, the initialization segment information is available from StreamInfo.

    Parameters
    @@ -420,7 +424,7 @@ Public Member Functions -

    Implemented in shaka::media::HlsNotifyMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, and shaka::media::CombinedMuxerListener.

    +

    Implemented in shaka::media::VodMediaInfoDumpMuxerListener, shaka::media::MultiCodecMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::HlsNotifyMuxerListener, and shaka::media::CombinedMuxerListener.

    @@ -479,7 +483,7 @@ Public Member Functions -

    Implemented in shaka::media::HlsNotifyMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, and shaka::media::CombinedMuxerListener.

    +

    Implemented in shaka::media::VodMediaInfoDumpMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::HlsNotifyMuxerListener, and shaka::media::CombinedMuxerListener.

    @@ -513,7 +517,7 @@ Public Member Functions -

    Implemented in shaka::media::HlsNotifyMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::VodMediaInfoDumpMuxerListener, and shaka::media::CombinedMuxerListener.

    +

    Implemented in shaka::media::VodMediaInfoDumpMuxerListener, shaka::media::MpdNotifyMuxerListener, shaka::media::HlsNotifyMuxerListener, and shaka::media::CombinedMuxerListener.

    @@ -523,9 +527,7 @@ Public Member Functions diff --git a/docs/dd/d7a/classshaka_1_1media_1_1MuxerListener.png b/docs/dd/d7a/classshaka_1_1media_1_1MuxerListener.png index 1e2163e308783f5db8335f93100ca5a560bdc1dd..466fe689abd19a40c164bb78612bbffc72414d56 100644 GIT binary patch literal 3272 zcmdT{YgAKL7N*NmEiKxvw#uVI)hM?#-q zg#iS#6jE-20b+3k zxB^;C=wmOqR*f{)8m4h05VfKJfhcO7=Muy{WN@r}>nb8ksTCFsfnm2W>OJ6bzp zSnufAz4U|L$rB%oSkqk&OM6Fm57ubE&&qQ7sw|Ma6TI9uf@8qX{@oqhZ6FKzFIv1! zcG#wNr;tqhMu&7ShuTx=3p=Jd>=-C(OG``5ARVYbSLWRlNocK%lP`DS1KC+wS-MR6 z)iInr1uN*A{uTd}baB?t*@+e>)Q{SorHQ!>MPIRcn#-F5*{n0{d9Cxj@ALP<_(4HI zbrngIg>C&PUH!mNrb6@+{lbg&W;b_xY-m*yoC)YXj)cgMKcb=pZ7a(Np$69zp?oHe zwzAARn--7q_3>#Xa7Oo1MC>~f7TU8riuqIIVQB#n^*Ag<-scxBjWH)w+F?g2f%7yc z6ka7%)JPNA&0>|a4%)}6I zxjwBI?m*?<9N#-u(i{nGre()dwb9svjULy~ZpM`ROevRF z8Gj3wIlZQEUo6y5pH^e|_;k;Vtm#iz`l_J1{u41&+twr7vg$E!AM0MW!_CeH=l^AY zuK8_1-aG9jALhEPGrtY4ykK%Py&ZV=e-nO|np=%6Sw6WdpfBa)?h_@|SgLJ6-}XGW zN^D7WJ!U&-WA^3m%db)?5YP>C4R)-1Bci?JV16zGD2NSaBJ*?IDq*%be}rp)ZhkBk zRR$|<#)F3K`pzTU_T|?@A+=)I;4?|VAF;*|lv8JQV#OP=V93A>MSX2bALg*WvzqxW zX&o{Nj%YaT$!wCIEPHxgus>7kTrl-i(8!}4ReO}TB!5M}k;0P-K2q!V%rUSD)VlX2 zs|r+s{_xVSgz*cFz4Y8DJyv~yyjjE>D|smU`2k@&r-CMig`R^mU$#4z&*pcN*Q%FN zc6LrM4)Q7E4vj*Z)17FPQz)z4TRovo+Cbj}Jv2IM6rnqxpwFior%-bGUmBN-UTU8w z5?~x8O0HRt6u@6h|0?y`MZAWqkLcm(?s=Y6jBc+u+jL*^RC`E}I!_{&p6%2~Tevl| z>s=N`ZZ{l}eneEX=r8GZA7HvCDl_esLbxGvuCQalX|Wa{B!tmu(mqbHKUt3+cvpyBD89mKq~;$*SF%eyJ{piP7@`CPuwZ$s?vB0kfh1XiRDD_;pJVQ z7q^`5(lG?+A*y)QhWdki;;ZcF+j=rUuu(60iLVAiic}k~aMcS-XP+gmK67v4^gtZt zJiA9eSVSU*W~yE>GorS*+TVb!BS!kdKj@R>4R;~Eqh(%F+`D)(5MACcej0+(&30yP zt&H9~t(e_yZeIegmPUQ4bwSHl{7qQ{5EMBPggEE?^= zg!8h~b*vH1cib(`qKKYoVYKdDOb4>RiM>@*$hzE2&Ad02>h3+FTY-|}j)f7Dg@#z= z56W~dTb5z$R7HQ=?WT&6HN`HN#o(F^9^3YUv9xvC}OxHLTY6= zWfp^YWrUu8h*op802x~n55nH@Mmz|FkX7|(0DPw-8PW||S(PVD+;Q~=PXZDBMvp6I zvgr&DW>SoVUBE6A~g{LKtV1H{1Lp?t(j+Wu9%FH~bQj;Uo+`twwAjtbGRI5)cnp*In| zLY4y%Xb=0URwIilm3ocGUBz?885gsx8yf!Fz$UuP$*q)?q>Fqlt|fX;Br?(kpFVS5 zC}Yg~zAkp#Z87N(D`k=$MT_*Xf35Kr7^=Dl?bqE!!h7k-lRplUE*4A`8#jM$hJ?b? zcsNVvc=;`x5K!yss{!W9FrMLVF+=rpHv_W-q)AgJz~rb;IJyx)JsA_pFIq!KN2~}> zQ{M#^W)pf^MugLAxd3NWBd*50k$we=E#`-Z_u#gI%8$#zf2v4B;o+X;@QRFzms8au z+=k9-QzdZ`{Mo3-pDP6g07sjYF(A4$e6#iwhoo`6{&=sJa%@b@OC+X;AR2C&^s#M- zJR^E+Si)XSyPoEC1U;eoZhxM$h#Dr{G0}gQSwsJ1eh(S;o*=wwjH`1?{~us3UF=qwtKO)CL9!RBxN=g#KCXbs6i#S7vW Yq;H4H*T$uQe>*G?eu3ZI{yHY>?|(jQtN;K2 literal 2370 zcmdT`eN<9;8g|BPN-NLKI!$^sb|&_ux#}iniK94U4dDm5K$`i1jpoOgRuCW`!lq}e z)}#?X6TwWSff>=XBo;-RN;5ImCDSr7GsHlpL{u`iz;eSG6cTL%I9ZRu2N+)f8bIv-7L)VI%;-4oYDC?E@t(-CMMm#fyE7(a zx)PlBd00(&u2jw8+u7sTZ)NV`dfjqZe>+PM~Pq})1J{`3? z3V@3KFC$_;MvL0b* zV)P@P%W4`p&*j&lSBp}k<1@Xx?lq?BM|Ys^XI`*Ydo|$+A%GB!6VJ|hXNQhE_zkZ1vP6^zqsR{P4aK5#%l78;`q_X!h;Gs6 zY5PB4|Hxdv{rd3x0)c~~zhFP7aBxO>o2&w+JvM@|a8LBjO^+hJv>gwBpD(rev4`1! zk2L6tvIOd{3I*Bc8mofkFvp|UOq7}a`oa%VN)EE;9^OnyEmOQ8Y@XTG>xk-rX0kQs zN`h6l-&gQ8^mlp&1vvN}Y*y^wC}A7XUMVtGIEnIrN^D9cJA}uru)W?JZx} z0)_W6w{9fWq zKVoGrsJe&g4HozZZFFOSJe zi9mC}k~2ndZzVL0wVO~1PS&_1y8Q+bE#Vc1SQkIiRi;MghT*7-$vO@CrF-qi{UP%OtDs7{28(u9g%ykjurh0ZCXz#rF(l9=2M%G-uke@1@n7SD) zv>i+L2*SF@~g{Jg$C0B)Tlv=hh$$S>lt~vu(Q_k9?z^4Tx!Spo$dbkeUA0jmtks zwR&N8&YoWLbFlLpku&8d9=avRt3o?E0ZN(*u?>y#9VKel+(VkA)8zK2mc!OGw z)nmgAkUi!V^3OBXII3If6q`@iTzwjDAaFoQlYM-;xD4GwQ*bdqoG~E8{0gA(KX!f7@eWkvQ>m&~z(b`4CTDFiglxnm`tcoQ>F;Uy^bc zn>J-vCHzbXfi2OzhVEZ-HX#Ky*_rw&HpX)6vJcesiRTdP}SrRK}2 zWsCsSQLNR;2F=;%cJKL}=v-KK+RNk8{s~z7<^G{8*0lboO+g6?bIWk-bks@cbjmaoifoaXqu7{ASF9&9dVo#Z$Cl{ zPyD_gg7qQC7LiDns~A{}!c@4tP(F%m=ZF#mVQE&vrHzuq_!08ofe}&4%8YjiqI6}7 z$ILzo?u;;l_N;WkSV$b*o*O_LX;y22S(UuBfX41evEI5f*q6ZM^%hngI3Q1SYTjsv zyN@z;wlEVtnt;zLVWn1u$MD%2u+i2MEw~gL7D-@T%n+2MR4~$vuF)DE6tU6;E7Rnc zqX79xuF`;?G&p}CACLa_&fUA_1Eq2Mb8jUONqjYj_^;CZkFLftO-2>ZH&Suq*mWA9 taSs56D_B)HG+f~qnXCbnFhgdsQTKb+A2{zZ3H + - + Shaka Packager SDK: packager/media/base/media_sample.h Source File @@ -29,18 +29,21 @@
    muxer_optionsis the options for Muxer.
    stream_infois the information of this media.
    - + +/* @license-end */
    media_sample.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_MEDIA_SAMPLE_H_
    8 #define PACKAGER_MEDIA_BASE_MEDIA_SAMPLE_H_
    9 
    10 #include <deque>
    11 #include <memory>
    12 #include <string>
    13 #include <vector>
    14 
    15 #include "packager/base/logging.h"
    16 #include "packager/media/base/decrypt_config.h"
    17 
    18 namespace shaka {
    19 namespace media {
    20 
    22 class MediaSample {
    23  public:
    29  static std::shared_ptr<MediaSample> CopyFrom(const uint8_t* data,
    30  size_t size,
    31  bool is_key_frame);
    32 
    42  static std::shared_ptr<MediaSample> CopyFrom(const uint8_t* data,
    43  size_t size,
    44  const uint8_t* side_data,
    45  size_t side_data_size,
    46  bool is_key_frame);
    47 
    54  static std::shared_ptr<MediaSample> FromMetadata(const uint8_t* metadata,
    55  size_t metadata_size);
    56 
    58  static std::shared_ptr<MediaSample> CreateEmptyMediaSample();
    59 
    63  static std::shared_ptr<MediaSample> CreateEOSBuffer();
    64 
    65  virtual ~MediaSample();
    66 
    68  std::shared_ptr<MediaSample> Clone() const;
    69 
    73  void TransferData(std::shared_ptr<uint8_t> data, size_t data_size);
    74 
    79  void SetData(const uint8_t* data, size_t data_size);
    80 
    82  std::string ToString() const;
    83 
    84  int64_t dts() const {
    85  DCHECK(!end_of_stream());
    86  return dts_;
    87  }
    88 
    89  void set_dts(int64_t dts) { dts_ = dts; }
    90 
    91  int64_t pts() const {
    92  DCHECK(!end_of_stream());
    93  return pts_;
    94  }
    95 
    96  void set_pts(int64_t pts) { pts_ = pts; }
    97 
    98  int64_t duration() const {
    99  DCHECK(!end_of_stream());
    100  return duration_;
    101  }
    102 
    103  void set_duration(int64_t duration) {
    104  DCHECK(!end_of_stream());
    105  duration_ = duration;
    106  }
    107 
    108  bool is_key_frame() const {
    109  DCHECK(!end_of_stream());
    110  return is_key_frame_;
    111  }
    112 
    113  bool is_encrypted() const {
    114  DCHECK(!end_of_stream());
    115  return is_encrypted_;
    116  }
    117  const uint8_t* data() const {
    118  DCHECK(!end_of_stream());
    119  return data_.get();
    120  }
    121 
    122  size_t data_size() const {
    123  DCHECK(!end_of_stream());
    124  return data_size_;
    125  }
    126 
    127  const uint8_t* side_data() const { return side_data_.get(); }
    128 
    129  size_t side_data_size() const { return side_data_size_; }
    130 
    131  const DecryptConfig* decrypt_config() const { return decrypt_config_.get(); }
    132 
    133  void set_is_key_frame(bool value) {
    134  is_key_frame_ = value;
    135  }
    136 
    137  void set_is_encrypted(bool value) {
    138  is_encrypted_ = value;
    139  }
    140 
    141  void set_decrypt_config(std::unique_ptr<DecryptConfig> decrypt_config) {
    142  decrypt_config_ = std::move(decrypt_config);
    143  }
    144 
    145  // If there's no data in this buffer, it represents end of stream.
    146  bool end_of_stream() const { return data_size_ == 0; }
    147 
    148  const std::string& config_id() const { return config_id_; }
    149  void set_config_id(const std::string& config_id) {
    150  config_id_ = config_id;
    151  }
    152 
    153  protected:
    154  // Made it protected to disallow the constructor to be called directly.
    155  // Create a MediaSample. Buffer will be padded and aligned as necessary.
    156  // |data|,|side_data| can be nullptr, which indicates an empty sample.
    157  MediaSample(const uint8_t* data,
    158  size_t data_size,
    159  const uint8_t* side_data,
    160  size_t side_data_size,
    161  bool is_key_frame);
    162  MediaSample();
    163 
    164  private:
    165  // Decoding time stamp.
    166  int64_t dts_ = 0;
    167  // Presentation time stamp.
    168  int64_t pts_ = 0;
    169  int64_t duration_ = 0;
    170  bool is_key_frame_ = false;
    171  // is sample encrypted ?
    172  bool is_encrypted_ = false;
    173 
    174  // Main buffer data.
    175  std::shared_ptr<const uint8_t> data_;
    176  size_t data_size_ = 0;
    177  // Contain additional buffers to complete the main one. Needed by WebM
    178  // http://www.matroska.org/technical/specs/index.html BlockAdditional[A5].
    179  // Not used by mp4 and other containers.
    180  std::shared_ptr<const uint8_t> side_data_;
    181  size_t side_data_size_ = 0;
    182 
    183  // Text specific fields.
    184  // For now this is the cue identifier for WebVTT.
    185  std::string config_id_;
    186 
    187  // Decrypt configuration.
    188  std::unique_ptr<DecryptConfig> decrypt_config_;
    189 
    190  DISALLOW_COPY_AND_ASSIGN(MediaSample);
    191 };
    192 
    193 typedef std::deque<std::shared_ptr<MediaSample>> BufferQueue;
    194 
    195 } // namespace media
    196 } // namespace shaka
    197 
    198 #endif // PACKAGER_MEDIA_BASE_MEDIA_SAMPLE_H_
    std::shared_ptr< MediaSample > Clone() const
    Clone the object and return a new MediaSample.
    Definition: media_sample.cc:81
    - -
    static std::shared_ptr< MediaSample > CreateEOSBuffer()
    Definition: media_sample.cc:76
    -
    std::string ToString() const
    -
    static std::shared_ptr< MediaSample > CreateEmptyMediaSample()
    Create a MediaSample object with default members.
    Definition: media_sample.cc:71
    -
    All the methods that are virtual are virtual for mocking.
    -
    void SetData(const uint8_t *data, size_t data_size)
    -
    static std::shared_ptr< MediaSample > FromMetadata(const uint8_t *metadata, size_t metadata_size)
    Definition: media_sample.cc:64
    -
    void TransferData(std::shared_ptr< uint8_t > data, size_t data_size)
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    -
    static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
    Definition: media_sample.cc:42
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_MEDIA_SAMPLE_H_
    +
    8 #define PACKAGER_MEDIA_BASE_MEDIA_SAMPLE_H_
    +
    9 
    +
    10 #include <deque>
    +
    11 #include <memory>
    +
    12 #include <string>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/base/logging.h"
    +
    16 #include "packager/media/base/decrypt_config.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    +
    22 class MediaSample {
    +
    23  public:
    +
    29  static std::shared_ptr<MediaSample> CopyFrom(const uint8_t* data,
    +
    30  size_t size,
    +
    31  bool is_key_frame);
    +
    32 
    +
    42  static std::shared_ptr<MediaSample> CopyFrom(const uint8_t* data,
    +
    43  size_t size,
    +
    44  const uint8_t* side_data,
    +
    45  size_t side_data_size,
    +
    46  bool is_key_frame);
    +
    47 
    +
    54  static std::shared_ptr<MediaSample> FromMetadata(const uint8_t* metadata,
    +
    55  size_t metadata_size);
    +
    56 
    +
    58  static std::shared_ptr<MediaSample> CreateEmptyMediaSample();
    +
    59 
    +
    63  static std::shared_ptr<MediaSample> CreateEOSBuffer();
    +
    64 
    +
    65  virtual ~MediaSample();
    +
    66 
    +
    68  std::shared_ptr<MediaSample> Clone() const;
    +
    69 
    +
    73  void TransferData(std::shared_ptr<uint8_t> data, size_t data_size);
    +
    74 
    +
    79  void SetData(const uint8_t* data, size_t data_size);
    +
    80 
    +
    82  std::string ToString() const;
    +
    83 
    +
    84  int64_t dts() const {
    +
    85  DCHECK(!end_of_stream());
    +
    86  return dts_;
    +
    87  }
    +
    88 
    +
    89  void set_dts(int64_t dts) { dts_ = dts; }
    +
    90 
    +
    91  int64_t pts() const {
    +
    92  DCHECK(!end_of_stream());
    +
    93  return pts_;
    +
    94  }
    +
    95 
    +
    96  void set_pts(int64_t pts) { pts_ = pts; }
    +
    97 
    +
    98  int64_t duration() const {
    +
    99  DCHECK(!end_of_stream());
    +
    100  return duration_;
    +
    101  }
    +
    102 
    +
    103  void set_duration(int64_t duration) {
    +
    104  DCHECK(!end_of_stream());
    +
    105  duration_ = duration;
    +
    106  }
    +
    107 
    +
    108  bool is_key_frame() const {
    +
    109  DCHECK(!end_of_stream());
    +
    110  return is_key_frame_;
    +
    111  }
    +
    112 
    +
    113  bool is_encrypted() const {
    +
    114  DCHECK(!end_of_stream());
    +
    115  return is_encrypted_;
    +
    116  }
    +
    117  const uint8_t* data() const {
    +
    118  DCHECK(!end_of_stream());
    +
    119  return data_.get();
    +
    120  }
    +
    121 
    +
    122  size_t data_size() const {
    +
    123  DCHECK(!end_of_stream());
    +
    124  return data_size_;
    +
    125  }
    +
    126 
    +
    127  const uint8_t* side_data() const { return side_data_.get(); }
    +
    128 
    +
    129  size_t side_data_size() const { return side_data_size_; }
    +
    130 
    +
    131  const DecryptConfig* decrypt_config() const { return decrypt_config_.get(); }
    +
    132 
    +
    133  void set_is_key_frame(bool value) {
    +
    134  is_key_frame_ = value;
    +
    135  }
    +
    136 
    +
    137  void set_is_encrypted(bool value) {
    +
    138  is_encrypted_ = value;
    +
    139  }
    +
    140 
    +
    141  void set_decrypt_config(std::unique_ptr<DecryptConfig> decrypt_config) {
    +
    142  decrypt_config_ = std::move(decrypt_config);
    +
    143  }
    +
    144 
    +
    145  // If there's no data in this buffer, it represents end of stream.
    +
    146  bool end_of_stream() const { return data_size_ == 0; }
    +
    147 
    +
    148  const std::string& config_id() const { return config_id_; }
    +
    149  void set_config_id(const std::string& config_id) {
    +
    150  config_id_ = config_id;
    +
    151  }
    +
    152 
    +
    153  protected:
    +
    154  // Made it protected to disallow the constructor to be called directly.
    +
    155  // Create a MediaSample. Buffer will be padded and aligned as necessary.
    +
    156  // |data|,|side_data| can be nullptr, which indicates an empty sample.
    +
    157  MediaSample(const uint8_t* data,
    +
    158  size_t data_size,
    +
    159  const uint8_t* side_data,
    +
    160  size_t side_data_size,
    +
    161  bool is_key_frame);
    +
    162  MediaSample();
    +
    163 
    +
    164  private:
    +
    165  // Decoding time stamp.
    +
    166  int64_t dts_ = 0;
    +
    167  // Presentation time stamp.
    +
    168  int64_t pts_ = 0;
    +
    169  int64_t duration_ = 0;
    +
    170  bool is_key_frame_ = false;
    +
    171  // is sample encrypted ?
    +
    172  bool is_encrypted_ = false;
    +
    173 
    +
    174  // Main buffer data.
    +
    175  std::shared_ptr<const uint8_t> data_;
    +
    176  size_t data_size_ = 0;
    +
    177  // Contain additional buffers to complete the main one. Needed by WebM
    +
    178  // http://www.matroska.org/technical/specs/index.html BlockAdditional[A5].
    +
    179  // Not used by mp4 and other containers.
    +
    180  std::shared_ptr<const uint8_t> side_data_;
    +
    181  size_t side_data_size_ = 0;
    +
    182 
    +
    183  // Text specific fields.
    +
    184  // For now this is the cue identifier for WebVTT.
    +
    185  std::string config_id_;
    +
    186 
    +
    187  // Decrypt configuration.
    +
    188  std::unique_ptr<DecryptConfig> decrypt_config_;
    +
    189 
    +
    190  DISALLOW_COPY_AND_ASSIGN(MediaSample);
    +
    191 };
    +
    192 
    +
    193 typedef std::deque<std::shared_ptr<MediaSample>> BufferQueue;
    +
    194 
    +
    195 } // namespace media
    +
    196 } // namespace shaka
    +
    197 
    +
    198 #endif // PACKAGER_MEDIA_BASE_MEDIA_SAMPLE_H_
    + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    static std::shared_ptr< MediaSample > CreateEOSBuffer()
    Definition: media_sample.cc:76
    +
    static std::shared_ptr< MediaSample > CreateEmptyMediaSample()
    Create a MediaSample object with default members.
    Definition: media_sample.cc:71
    +
    void TransferData(std::shared_ptr< uint8_t > data, size_t data_size)
    +
    std::shared_ptr< MediaSample > Clone() const
    Clone the object and return a new MediaSample.
    Definition: media_sample.cc:81
    +
    static std::shared_ptr< MediaSample > FromMetadata(const uint8_t *metadata, size_t metadata_size)
    Definition: media_sample.cc:64
    +
    void SetData(const uint8_t *data, size_t data_size)
    +
    std::string ToString() const
    +
    static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
    Definition: media_sample.cc:42
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d87/memory__file_8cc_source.html b/docs/dd/d87/memory__file_8cc_source.html index 3c0521b166..fcf62eb52a 100644 --- a/docs/dd/d87/memory__file_8cc_source.html +++ b/docs/dd/d87/memory__file_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/memory_file.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    memory_file.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/file/memory_file.h"
    8 
    9 #include <string.h> // for memcpy
    10 
    11 #include <algorithm>
    12 #include <map>
    13 #include <memory>
    14 #include <set>
    15 
    16 #include "packager/base/logging.h"
    17 #include "packager/base/synchronization/lock.h"
    18 
    19 namespace shaka {
    20 namespace {
    21 
    22 // A helper filesystem object. This holds the data for the memory files.
    23 class FileSystem {
    24  public:
    25  ~FileSystem() {}
    26 
    27  static FileSystem* Instance() {
    28  static FileSystem instance;
    29  return &instance;
    30  }
    31 
    32  void Delete(const std::string& file_name) {
    33  base::AutoLock auto_lock(lock_);
    34 
    35  if (open_files_.find(file_name) != open_files_.end()) {
    36  LOG(ERROR) << "File '" << file_name
    37  << "' is still open. Deleting an open MemoryFile is not "
    38  "allowed. Exit without deleting the file.";
    39  return;
    40  }
    41 
    42  files_.erase(file_name);
    43  }
    44 
    45  void DeleteAll() {
    46  base::AutoLock auto_lock(lock_);
    47  if (!open_files_.empty()) {
    48  LOG(ERROR) << "There are still files open. Deleting an open MemoryFile "
    49  "is not allowed. Exit without deleting the file.";
    50  return;
    51  }
    52  files_.clear();
    53  }
    54 
    55  std::vector<uint8_t>* Open(const std::string& file_name,
    56  const std::string& mode) {
    57  base::AutoLock auto_lock(lock_);
    58 
    59  if (open_files_.find(file_name) != open_files_.end()) {
    60  NOTIMPLEMENTED() << "File '" << file_name
    61  << "' is already open. MemoryFile does not support "
    62  "open the same file before it is closed.";
    63  return nullptr;
    64  }
    65 
    66  auto iter = files_.find(file_name);
    67  if (mode == "r") {
    68  if (iter == files_.end())
    69  return nullptr;
    70  } else if (mode == "w") {
    71  if (iter != files_.end())
    72  iter->second.clear();
    73  } else {
    74  NOTIMPLEMENTED() << "File mode '" << mode
    75  << "' not supported by MemoryFile";
    76  return nullptr;
    77  }
    78 
    79  open_files_[file_name] = mode;
    80  return &files_[file_name];
    81  }
    82 
    83  bool Close(const std::string& file_name) {
    84  base::AutoLock auto_lock(lock_);
    85 
    86  auto iter = open_files_.find(file_name);
    87  if (iter == open_files_.end()) {
    88  LOG(ERROR) << "Cannot close file '" << file_name
    89  << "' which is not open.";
    90  return false;
    91  }
    92 
    93  open_files_.erase(iter);
    94  return true;
    95  }
    96 
    97  private:
    98  FileSystem(const FileSystem&) = delete;
    99  FileSystem& operator=(const FileSystem&) = delete;
    100 
    101  FileSystem() = default;
    102 
    103  // Filename to file data map.
    104  std::map<std::string, std::vector<uint8_t>> files_;
    105  // Filename to file open modes map.
    106  std::map<std::string, std::string> open_files_;
    107 
    108  base::Lock lock_;
    109 };
    110 
    111 } // namespace
    112 
    113 MemoryFile::MemoryFile(const std::string& file_name, const std::string& mode)
    114  : File(file_name), mode_(mode), file_(NULL), position_(0) {}
    115 
    116 MemoryFile::~MemoryFile() {}
    117 
    119  if (!FileSystem::Instance()->Close(file_name()))
    120  return false;
    121  delete this;
    122  return true;
    123 }
    124 
    125 int64_t MemoryFile::Read(void* buffer, uint64_t length) {
    126  const uint64_t size = Size();
    127  DCHECK_LE(position_, size);
    128  if (position_ >= size)
    129  return 0;
    130 
    131  const uint64_t bytes_to_read = std::min(length, size - position_);
    132  memcpy(buffer, &(*file_)[position_], bytes_to_read);
    133  position_ += bytes_to_read;
    134  return bytes_to_read;
    135 }
    136 
    137 int64_t MemoryFile::Write(const void* buffer, uint64_t length) {
    138  // If length is zero, we won't resize the buffer and it is possible for
    139  // |position| to equal the length of the buffer. This will cause a segfault
    140  // when indexing into the buffer for the memcpy.
    141  if (length == 0) {
    142  return 0;
    143  }
    144 
    145  const uint64_t size = Size();
    146  if (size < position_ + length) {
    147  file_->resize(position_ + length);
    148  }
    149 
    150  memcpy(&(*file_)[position_], buffer, length);
    151  position_ += length;
    152  return length;
    153 }
    154 
    155 int64_t MemoryFile::Size() {
    156  DCHECK(file_);
    157  return file_->size();
    158 }
    159 
    161  return true;
    162 }
    163 
    164 bool MemoryFile::Seek(uint64_t position) {
    165  if (Size() < static_cast<int64_t>(position))
    166  return false;
    167 
    168  position_ = position;
    169  return true;
    170 }
    171 
    172 bool MemoryFile::Tell(uint64_t* position) {
    173  *position = position_;
    174  return true;
    175 }
    176 
    178  file_ = FileSystem::Instance()->Open(file_name(), mode_);
    179  if (!file_)
    180  return false;
    181 
    182  position_ = 0;
    183  return true;
    184 }
    185 
    187  FileSystem::Instance()->DeleteAll();
    188 }
    189 
    190 void MemoryFile::Delete(const std::string& file_name) {
    191  FileSystem::Instance()->Delete(file_name);
    192 }
    193 
    194 } // namespace shaka
    static void Delete(const std::string &file_name)
    Definition: memory_file.cc:190
    -
    bool Close() override
    Definition: local_file.cc:104
    -
    static void DeleteAll()
    Definition: memory_file.cc:186
    -
    bool Open() override
    Internal open. Should not be used directly.
    Definition: memory_file.cc:177
    -
    bool Close() override
    Definition: memory_file.cc:118
    -
    bool Seek(uint64_t position) override
    Definition: memory_file.cc:164
    -
    const std::string & file_name() const
    Definition: file.h:94
    -
    All the methods that are virtual are virtual for mocking.
    -
    int64_t Write(const void *buffer, uint64_t length) override
    Definition: memory_file.cc:137
    -
    int64_t Size() override
    Definition: local_file.cc:138
    -
    int64_t Size() override
    Definition: memory_file.cc:155
    -
    bool Tell(uint64_t *position) override
    Definition: memory_file.cc:172
    -
    bool Flush() override
    Definition: memory_file.cc:160
    -
    int64_t Read(void *buffer, uint64_t length) override
    Definition: memory_file.cc:125
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/file/memory_file.h"
    +
    8 
    +
    9 #include <string.h> // for memcpy
    +
    10 
    +
    11 #include <algorithm>
    +
    12 #include <map>
    +
    13 #include <memory>
    +
    14 #include <set>
    +
    15 
    +
    16 #include "packager/base/logging.h"
    +
    17 #include "packager/base/synchronization/lock.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace {
    +
    21 
    +
    22 // A helper filesystem object. This holds the data for the memory files.
    +
    23 class FileSystem {
    +
    24  public:
    +
    25  ~FileSystem() {}
    +
    26 
    +
    27  static FileSystem* Instance() {
    +
    28  static FileSystem instance;
    +
    29  return &instance;
    +
    30  }
    +
    31 
    +
    32  void Delete(const std::string& file_name) {
    +
    33  base::AutoLock auto_lock(lock_);
    +
    34 
    +
    35  if (open_files_.find(file_name) != open_files_.end()) {
    +
    36  LOG(ERROR) << "File '" << file_name
    +
    37  << "' is still open. Deleting an open MemoryFile is not "
    +
    38  "allowed. Exit without deleting the file.";
    +
    39  return;
    +
    40  }
    +
    41 
    +
    42  files_.erase(file_name);
    +
    43  }
    +
    44 
    +
    45  void DeleteAll() {
    +
    46  base::AutoLock auto_lock(lock_);
    +
    47  if (!open_files_.empty()) {
    +
    48  LOG(ERROR) << "There are still files open. Deleting an open MemoryFile "
    +
    49  "is not allowed. Exit without deleting the file.";
    +
    50  return;
    +
    51  }
    +
    52  files_.clear();
    +
    53  }
    +
    54 
    +
    55  std::vector<uint8_t>* Open(const std::string& file_name,
    +
    56  const std::string& mode) {
    +
    57  base::AutoLock auto_lock(lock_);
    +
    58 
    +
    59  if (open_files_.find(file_name) != open_files_.end()) {
    +
    60  NOTIMPLEMENTED() << "File '" << file_name
    +
    61  << "' is already open. MemoryFile does not support "
    +
    62  "open the same file before it is closed.";
    +
    63  return nullptr;
    +
    64  }
    +
    65 
    +
    66  auto iter = files_.find(file_name);
    +
    67  if (mode == "r") {
    +
    68  if (iter == files_.end())
    +
    69  return nullptr;
    +
    70  } else if (mode == "w") {
    +
    71  if (iter != files_.end())
    +
    72  iter->second.clear();
    +
    73  } else {
    +
    74  NOTIMPLEMENTED() << "File mode '" << mode
    +
    75  << "' not supported by MemoryFile";
    +
    76  return nullptr;
    +
    77  }
    +
    78 
    +
    79  open_files_[file_name] = mode;
    +
    80  return &files_[file_name];
    +
    81  }
    +
    82 
    +
    83  bool Close(const std::string& file_name) {
    +
    84  base::AutoLock auto_lock(lock_);
    +
    85 
    +
    86  auto iter = open_files_.find(file_name);
    +
    87  if (iter == open_files_.end()) {
    +
    88  LOG(ERROR) << "Cannot close file '" << file_name
    +
    89  << "' which is not open.";
    +
    90  return false;
    +
    91  }
    +
    92 
    +
    93  open_files_.erase(iter);
    +
    94  return true;
    +
    95  }
    +
    96 
    +
    97  private:
    +
    98  FileSystem(const FileSystem&) = delete;
    +
    99  FileSystem& operator=(const FileSystem&) = delete;
    +
    100 
    +
    101  FileSystem() = default;
    +
    102 
    +
    103  // Filename to file data map.
    +
    104  std::map<std::string, std::vector<uint8_t>> files_;
    +
    105  // Filename to file open modes map.
    +
    106  std::map<std::string, std::string> open_files_;
    +
    107 
    +
    108  base::Lock lock_;
    +
    109 };
    +
    110 
    +
    111 } // namespace
    +
    112 
    +
    113 MemoryFile::MemoryFile(const std::string& file_name, const std::string& mode)
    +
    114  : File(file_name), mode_(mode), file_(NULL), position_(0) {}
    +
    115 
    +
    116 MemoryFile::~MemoryFile() {}
    +
    117 
    +
    118 bool MemoryFile::Close() {
    +
    119  if (!FileSystem::Instance()->Close(file_name()))
    +
    120  return false;
    +
    121  delete this;
    +
    122  return true;
    +
    123 }
    +
    124 
    +
    125 int64_t MemoryFile::Read(void* buffer, uint64_t length) {
    +
    126  const uint64_t size = Size();
    +
    127  DCHECK_LE(position_, size);
    +
    128  if (position_ >= size)
    +
    129  return 0;
    +
    130 
    +
    131  const uint64_t bytes_to_read = std::min(length, size - position_);
    +
    132  memcpy(buffer, &(*file_)[position_], bytes_to_read);
    +
    133  position_ += bytes_to_read;
    +
    134  return bytes_to_read;
    +
    135 }
    +
    136 
    +
    137 int64_t MemoryFile::Write(const void* buffer, uint64_t length) {
    +
    138  // If length is zero, we won't resize the buffer and it is possible for
    +
    139  // |position| to equal the length of the buffer. This will cause a segfault
    +
    140  // when indexing into the buffer for the memcpy.
    +
    141  if (length == 0) {
    +
    142  return 0;
    +
    143  }
    +
    144 
    +
    145  const uint64_t size = Size();
    +
    146  if (size < position_ + length) {
    +
    147  file_->resize(position_ + length);
    +
    148  }
    +
    149 
    +
    150  memcpy(&(*file_)[position_], buffer, length);
    +
    151  position_ += length;
    +
    152  return length;
    +
    153 }
    +
    154 
    +
    155 int64_t MemoryFile::Size() {
    +
    156  DCHECK(file_);
    +
    157  return file_->size();
    +
    158 }
    +
    159 
    +
    160 bool MemoryFile::Flush() {
    +
    161  return true;
    +
    162 }
    +
    163 
    +
    164 bool MemoryFile::Seek(uint64_t position) {
    +
    165  if (Size() < static_cast<int64_t>(position))
    +
    166  return false;
    +
    167 
    +
    168  position_ = position;
    +
    169  return true;
    +
    170 }
    +
    171 
    +
    172 bool MemoryFile::Tell(uint64_t* position) {
    +
    173  *position = position_;
    +
    174  return true;
    +
    175 }
    +
    176 
    +
    177 bool MemoryFile::Open() {
    +
    178  file_ = FileSystem::Instance()->Open(file_name(), mode_);
    +
    179  if (!file_)
    +
    180  return false;
    +
    181 
    +
    182  position_ = 0;
    +
    183  return true;
    +
    184 }
    +
    185 
    +
    186 void MemoryFile::DeleteAll() {
    +
    187  FileSystem::Instance()->DeleteAll();
    +
    188 }
    +
    189 
    +
    190 void MemoryFile::Delete(const std::string& file_name) {
    +
    191  FileSystem::Instance()->Delete(file_name);
    +
    192 }
    +
    193 
    +
    194 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d88/pes__packet__generator_8h_source.html b/docs/dd/d88/pes__packet__generator_8h_source.html index f2a473c515..76fb8131d0 100644 --- a/docs/dd/d88/pes__packet__generator_8h_source.html +++ b/docs/dd/d88/pes__packet__generator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/pes_packet_generator.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    pes_packet_generator.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_GENERATOR_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_GENERATOR_H_
    9 
    10 #include <list>
    11 #include <memory>
    12 
    13 #include "packager/media/base/media_sample.h"
    14 #include "packager/media/base/stream_info.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 class AACAudioSpecificConfig;
    20 class NalUnitToByteStreamConverter;
    21 class StreamInfo;
    22 
    23 namespace mp2t {
    24 
    25 class PesPacket;
    26 
    30  public:
    34  explicit PesPacketGenerator(uint32_t transport_stream_timestamp_offset);
    35  virtual ~PesPacketGenerator();
    36 
    42  virtual bool Initialize(const StreamInfo& stream);
    43 
    48  virtual bool PushSample(const MediaSample& sample);
    49 
    51  virtual size_t NumberOfReadyPesPackets();
    52 
    56  virtual std::unique_ptr<PesPacket> GetNextPesPacket();
    57 
    61  virtual bool Flush();
    62 
    63  private:
    64  friend class PesPacketGeneratorTest;
    65 
    66  StreamType stream_type_;
    67 
    68  const uint32_t transport_stream_timestamp_offset_ = 0;
    69  // Calculated by 90000 / input stream's timescale. This is used to scale the
    70  // timestamps.
    71  double timescale_scale_ = 0.0;
    72 
    73  std::unique_ptr<NalUnitToByteStreamConverter> converter_;
    74  std::unique_ptr<AACAudioSpecificConfig> adts_converter_;
    75 
    76  // This is the PES packet that this object is currently working on.
    77  // This can be used to create a PES from multiple audio samples.
    78  std::unique_ptr<PesPacket> current_processing_pes_;
    79 
    80  // Audio stream id PES packet is codec dependent.
    81  uint8_t audio_stream_id_ = 0;
    82  std::list<std::unique_ptr<PesPacket>> pes_packets_;
    83 
    84  DISALLOW_COPY_AND_ASSIGN(PesPacketGenerator);
    85 };
    86 
    87 } // namespace mp2t
    88 } // namespace media
    89 } // namespace shaka
    90 
    91 #endif // PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_GENERATOR_H_
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    virtual bool PushSample(const MediaSample &sample)
    -
    virtual std::unique_ptr< PesPacket > GetNextPesPacket()
    - -
    All the methods that are virtual are virtual for mocking.
    - -
    virtual bool Initialize(const StreamInfo &stream)
    -
    PesPacketGenerator(uint32_t transport_stream_timestamp_offset)
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_GENERATOR_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_GENERATOR_H_
    +
    9 
    +
    10 #include <list>
    +
    11 #include <memory>
    +
    12 
    +
    13 #include "packager/media/base/media_sample.h"
    +
    14 #include "packager/media/base/stream_info.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 class AACAudioSpecificConfig;
    +
    20 class NalUnitToByteStreamConverter;
    +
    21 class StreamInfo;
    +
    22 
    +
    23 namespace mp2t {
    +
    24 
    +
    25 class PesPacket;
    +
    26 
    + +
    30  public:
    +
    34  explicit PesPacketGenerator(uint32_t transport_stream_timestamp_offset);
    +
    35  virtual ~PesPacketGenerator();
    +
    36 
    +
    42  virtual bool Initialize(const StreamInfo& stream);
    +
    43 
    +
    48  virtual bool PushSample(const MediaSample& sample);
    +
    49 
    +
    51  virtual size_t NumberOfReadyPesPackets();
    +
    52 
    +
    56  virtual std::unique_ptr<PesPacket> GetNextPesPacket();
    +
    57 
    +
    61  virtual bool Flush();
    +
    62 
    +
    63  private:
    +
    64  friend class PesPacketGeneratorTest;
    +
    65 
    +
    66  StreamType stream_type_;
    +
    67 
    +
    68  const uint32_t transport_stream_timestamp_offset_ = 0;
    +
    69  // Calculated by 90000 / input stream's timescale. This is used to scale the
    +
    70  // timestamps.
    +
    71  double timescale_scale_ = 0.0;
    +
    72 
    +
    73  std::unique_ptr<NalUnitToByteStreamConverter> converter_;
    +
    74  std::unique_ptr<AACAudioSpecificConfig> adts_converter_;
    +
    75 
    +
    76  // This is the PES packet that this object is currently working on.
    +
    77  // This can be used to create a PES from multiple audio samples.
    +
    78  std::unique_ptr<PesPacket> current_processing_pes_;
    +
    79 
    +
    80  // Audio stream id PES packet is codec dependent.
    +
    81  uint8_t audio_stream_id_ = 0;
    +
    82  std::list<std::unique_ptr<PesPacket>> pes_packets_;
    +
    83 
    +
    84  DISALLOW_COPY_AND_ASSIGN(PesPacketGenerator);
    +
    85 };
    +
    86 
    +
    87 } // namespace mp2t
    +
    88 } // namespace media
    +
    89 } // namespace shaka
    +
    90 
    +
    91 #endif // PACKAGER_MEDIA_FORMATS_MP2T_PES_PACKET_GENERATOR_H_
    +
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    + + + +
    virtual bool PushSample(const MediaSample &sample)
    +
    PesPacketGenerator(uint32_t transport_stream_timestamp_offset)
    +
    virtual bool Initialize(const StreamInfo &stream)
    +
    virtual std::unique_ptr< PesPacket > GetNextPesPacket()
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d8c/file__test__util_8h_source.html b/docs/dd/d8c/file__test__util_8h_source.html index 4218f2d180..4b456d454f 100644 --- a/docs/dd/d8c/file__test__util_8h_source.html +++ b/docs/dd/d8c/file__test__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/file_test_util.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    file_test_util.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef MEDIA_FILE_FILE_TEST_UTIL_H_
    8 #define MEDIA_FILE_FILE_TEST_UTIL_H_
    9 
    10 #include <gmock/gmock.h>
    11 #include <gtest/gtest.h>
    12 
    13 #include <string>
    14 
    15 #include "packager/file/file.h"
    16 
    17 namespace shaka {
    18 
    19 #define ASSERT_FILE_EQ(file_name, array) \
    20  do { \
    21  std::string temp_data; \
    22  ASSERT_TRUE(File::ReadFileToString((file_name), &temp_data)); \
    23  const char* array_ptr = reinterpret_cast<const char*>(array); \
    24  ASSERT_EQ(std::string(array_ptr, arraysize(array)), temp_data); \
    25  } while (false)
    26 
    27 #define ASSERT_FILE_STREQ(file_name, str) \
    28  do { \
    29  std::string temp_data; \
    30  ASSERT_TRUE(File::ReadFileToString((file_name), &temp_data)); \
    31  ASSERT_EQ(str, temp_data); \
    32  } while (false)
    33 
    34 #define ASSERT_FILE_ENDS_WITH(file_name, array) \
    35  do { \
    36  std::string temp_data; \
    37  ASSERT_TRUE(File::ReadFileToString((file_name), &temp_data)); \
    38  EXPECT_THAT(temp_data, \
    39  ::testing::EndsWith(std::string( \
    40  reinterpret_cast<const char*>(array), sizeof(array)))); \
    41  } while (false)
    42 
    43 } // namespace shaka
    44 
    45 #endif // MEDIA_FILE_FILE_TEST_UTIL_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef MEDIA_FILE_FILE_TEST_UTIL_H_
    +
    8 #define MEDIA_FILE_FILE_TEST_UTIL_H_
    +
    9 
    +
    10 #include <gmock/gmock.h>
    +
    11 #include <gtest/gtest.h>
    +
    12 
    +
    13 #include <string>
    +
    14 
    +
    15 #include "packager/file/file.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 
    +
    19 #define ASSERT_FILE_EQ(file_name, array) \
    +
    20  do { \
    +
    21  std::string temp_data; \
    +
    22  ASSERT_TRUE(File::ReadFileToString((file_name), &temp_data)); \
    +
    23  const char* array_ptr = reinterpret_cast<const char*>(array); \
    +
    24  ASSERT_EQ(std::string(array_ptr, arraysize(array)), temp_data); \
    +
    25  } while (false)
    +
    26 
    +
    27 #define ASSERT_FILE_STREQ(file_name, str) \
    +
    28  do { \
    +
    29  std::string temp_data; \
    +
    30  ASSERT_TRUE(File::ReadFileToString((file_name), &temp_data)); \
    +
    31  ASSERT_EQ(str, temp_data); \
    +
    32  } while (false)
    +
    33 
    +
    34 #define ASSERT_FILE_ENDS_WITH(file_name, array) \
    +
    35  do { \
    +
    36  std::string temp_data; \
    +
    37  ASSERT_TRUE(File::ReadFileToString((file_name), &temp_data)); \
    +
    38  EXPECT_THAT(temp_data, \
    +
    39  ::testing::EndsWith(std::string( \
    +
    40  reinterpret_cast<const char*>(array), sizeof(array)))); \
    +
    41  } while (false)
    +
    42 
    +
    43 } // namespace shaka
    +
    44 
    +
    45 #endif // MEDIA_FILE_FILE_TEST_UTIL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d8d/structshaka_1_1media_1_1mp4_1_1SegmentIndex-members.html b/docs/dd/d8d/structshaka_1_1media_1_1mp4_1_1SegmentIndex-members.html index 7e8b0a8a72..f6e13284f9 100644 --- a/docs/dd/d8d/structshaka_1_1media_1_1mp4_1_1SegmentIndex-members.html +++ b/docs/dd/d8d/structshaka_1_1media_1_1mp4_1_1SegmentIndex-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/d95/classshaka_1_1ThreadedIoFile-members.html b/docs/dd/d95/classshaka_1_1ThreadedIoFile-members.html index bb20c547a1..e48b6bbfd9 100644 --- a/docs/dd/d95/classshaka_1_1ThreadedIoFile-members.html +++ b/docs/dd/d95/classshaka_1_1ThreadedIoFile-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/d98/ts__packet__writer__util_8h_source.html b/docs/dd/d98/ts__packet__writer__util_8h_source.html index 97e9945cce..4597921cfa 100644 --- a/docs/dd/d98/ts__packet__writer__util_8h_source.html +++ b/docs/dd/d98/ts__packet__writer__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_packet_writer_util.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    ts_packet_writer_util.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 // This file contains utility functions that help write TS packets to buffer.
    8 
    9 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_UTIL_H_
    10 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_UTIL_H_
    11 
    12 #include <stddef.h>
    13 #include <stdint.h>
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    18 class BufferWriter;
    19 
    20 namespace mp2t {
    21 
    22 class ContinuityCounter;
    23 
    34 void WritePayloadToBufferWriter(const uint8_t* payload,
    35  size_t payload_size,
    36  bool payload_unit_start_indicator,
    37  int pid,
    38  bool has_pcr,
    39  uint64_t pcr_base,
    40  ContinuityCounter* continuity_counter,
    41  BufferWriter* output);
    42 
    43 } // namespace mp2t
    44 } // namespace media
    45 } // namespace shaka
    46 
    47 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_UTIL_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 // This file contains utility functions that help write TS packets to buffer.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_UTIL_H_
    +
    10 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_UTIL_H_
    +
    11 
    +
    12 #include <stddef.h>
    +
    13 #include <stdint.h>
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    18 class BufferWriter;
    +
    19 
    +
    20 namespace mp2t {
    +
    21 
    +
    22 class ContinuityCounter;
    +
    23 
    +
    34 void WritePayloadToBufferWriter(const uint8_t* payload,
    +
    35  size_t payload_size,
    +
    36  bool payload_unit_start_indicator,
    +
    37  int pid,
    +
    38  bool has_pcr,
    +
    39  uint64_t pcr_base,
    +
    40  ContinuityCounter* continuity_counter,
    +
    41  BufferWriter* output);
    +
    42 
    +
    43 } // namespace mp2t
    +
    44 } // namespace media
    +
    45 } // namespace shaka
    +
    46 
    +
    47 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_WRITER_UTIL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d9a/audio__timestamp__helper_8h_source.html b/docs/dd/d9a/audio__timestamp__helper_8h_source.html index 99851f4062..42150a351b 100644 --- a/docs/dd/d9a/audio__timestamp__helper_8h_source.html +++ b/docs/dd/d9a/audio__timestamp__helper_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/audio_timestamp_helper.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    audio_timestamp_helper.h
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_BASE_AUDIO_TIMESTAMP_HELPER_H_
    6 #define PACKAGER_MEDIA_BASE_AUDIO_TIMESTAMP_HELPER_H_
    7 
    8 #include <stdint.h>
    9 
    10 #include "packager/base/macros.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    15 // Generates timestamps for a sequence of audio sample frames. This class should
    16 // be used any place timestamps need to be calculated for a sequence of audio
    17 // samples. It helps avoid timestamps inaccuracies caused by rounding/truncation
    18 // in repeated sample count to timestamp conversions.
    19 //
    20 // The class is constructed with samples_per_second information so that it can
    21 // convert audio sample frame counts into timestamps. After the object is
    22 // constructed, SetBaseTimestamp() must be called to specify the starting
    23 // timestamp of the audio sequence. As audio samples are received, their frame
    24 // counts are added using AddFrames(). These frame counts are accumulated by
    25 // this class so GetTimestamp() can be used to determine the timestamp for the
    26 // samples that have been added. GetDuration() calculates the proper duration
    27 // values for samples added to the current timestamp. GetFramesToTarget()
    28 // determines the number of frames that need to be added/removed from the
    29 // accumulated frames to reach a target timestamp.
    31  public:
    32  explicit AudioTimestampHelper(uint32_t timescale,
    33  uint32_t samples_per_second);
    34 
    35  // Sets the base timestamp to |base_timestamp| and the sets count to 0.
    36  void SetBaseTimestamp(int64_t base_timestamp);
    37 
    38  int64_t base_timestamp() const;
    39  int64_t frame_count() const { return frame_count_; }
    40 
    41  // Adds |frame_count| to the frame counter.
    42  // Note: SetBaseTimestamp() must be called with a value other than
    43  // kNoTimestamp() before this method can be called.
    44  void AddFrames(int64_t frame_count);
    45 
    46  // Get the current timestamp. This value is computed from the base_timestamp()
    47  // and the number of sample frames that have been added so far.
    48  int64_t GetTimestamp() const;
    49 
    50  // Gets the duration if |frame_count| frames were added to the current
    51  // timestamp reported by GetTimestamp(). This method ensures that
    52  // (GetTimestamp() + GetFrameDuration(n)) will equal the timestamp that
    53  // GetTimestamp() will return if AddFrames(n) is called.
    54  int64_t GetFrameDuration(int64_t frame_count) const;
    55 
    56  // Returns the number of frames needed to reach the target timestamp.
    57  // Note: |target| must be >= |base_timestamp_|.
    58  int64_t GetFramesToTarget(int64_t target) const;
    59 
    60  private:
    61  int64_t ComputeTimestamp(int64_t frame_count) const;
    62 
    63  double ticks_per_frame_;
    64 
    65  int64_t base_timestamp_;
    66 
    67  // Number of frames accumulated by AddFrames() calls.
    68  int64_t frame_count_;
    69 
    70  DISALLOW_IMPLICIT_CONSTRUCTORS(AudioTimestampHelper);
    71 };
    72 
    73 } // namespace media
    74 } // namespace shaka
    75 
    76 #endif
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_BASE_AUDIO_TIMESTAMP_HELPER_H_
    +
    6 #define PACKAGER_MEDIA_BASE_AUDIO_TIMESTAMP_HELPER_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 
    +
    10 #include "packager/base/macros.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    15 // Generates timestamps for a sequence of audio sample frames. This class should
    +
    16 // be used any place timestamps need to be calculated for a sequence of audio
    +
    17 // samples. It helps avoid timestamps inaccuracies caused by rounding/truncation
    +
    18 // in repeated sample count to timestamp conversions.
    +
    19 //
    +
    20 // The class is constructed with samples_per_second information so that it can
    +
    21 // convert audio sample frame counts into timestamps. After the object is
    +
    22 // constructed, SetBaseTimestamp() must be called to specify the starting
    +
    23 // timestamp of the audio sequence. As audio samples are received, their frame
    +
    24 // counts are added using AddFrames(). These frame counts are accumulated by
    +
    25 // this class so GetTimestamp() can be used to determine the timestamp for the
    +
    26 // samples that have been added. GetDuration() calculates the proper duration
    +
    27 // values for samples added to the current timestamp. GetFramesToTarget()
    +
    28 // determines the number of frames that need to be added/removed from the
    +
    29 // accumulated frames to reach a target timestamp.
    + +
    31  public:
    +
    32  explicit AudioTimestampHelper(uint32_t timescale,
    +
    33  uint32_t samples_per_second);
    +
    34 
    +
    35  // Sets the base timestamp to |base_timestamp| and the sets count to 0.
    +
    36  void SetBaseTimestamp(int64_t base_timestamp);
    +
    37 
    +
    38  int64_t base_timestamp() const;
    +
    39  int64_t frame_count() const { return frame_count_; }
    +
    40 
    +
    41  // Adds |frame_count| to the frame counter.
    +
    42  // Note: SetBaseTimestamp() must be called with a value other than
    +
    43  // kNoTimestamp() before this method can be called.
    +
    44  void AddFrames(int64_t frame_count);
    +
    45 
    +
    46  // Get the current timestamp. This value is computed from the base_timestamp()
    +
    47  // and the number of sample frames that have been added so far.
    +
    48  int64_t GetTimestamp() const;
    +
    49 
    +
    50  // Gets the duration if |frame_count| frames were added to the current
    +
    51  // timestamp reported by GetTimestamp(). This method ensures that
    +
    52  // (GetTimestamp() + GetFrameDuration(n)) will equal the timestamp that
    +
    53  // GetTimestamp() will return if AddFrames(n) is called.
    +
    54  int64_t GetFrameDuration(int64_t frame_count) const;
    +
    55 
    +
    56  // Returns the number of frames needed to reach the target timestamp.
    +
    57  // Note: |target| must be >= |base_timestamp_|.
    +
    58  int64_t GetFramesToTarget(int64_t target) const;
    +
    59 
    +
    60  private:
    +
    61  int64_t ComputeTimestamp(int64_t frame_count) const;
    +
    62 
    +
    63  double ticks_per_frame_;
    +
    64 
    +
    65  int64_t base_timestamp_;
    +
    66 
    +
    67  // Number of frames accumulated by AddFrames() calls.
    +
    68  int64_t frame_count_;
    +
    69 
    +
    70  DISALLOW_IMPLICIT_CONSTRUCTORS(AudioTimestampHelper);
    +
    71 };
    +
    72 
    +
    73 } // namespace media
    +
    74 } // namespace shaka
    +
    75 
    +
    76 #endif
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/d9b/structshaka_1_1media_1_1mp4_1_1SegmentReference.html b/docs/dd/d9b/structshaka_1_1media_1_1mp4_1_1SegmentReference.html index d1ecd73d6d..1576349c9e 100644 --- a/docs/dd/d9b/structshaka_1_1media_1_1mp4_1_1SegmentReference.html +++ b/docs/dd/d9b/structshaka_1_1media_1_1mp4_1_1SegmentReference.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::SegmentReference Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Public Types

    enum  SAPType {
    -  TypeUnknown = 0, -Type1 = 1, -Type2 = 2, -Type3 = 3, -
    -  Type4 = 4, -Type5 = 5, -Type6 = 6 +  TypeUnknown = 0 +, Type1 = 1 +, Type2 = 2 +, Type3 = 3 +,
    +  Type4 = 4 +, Type5 = 5 +, Type6 = 6
    }   @@ -112,16 +115,14 @@ uint64_t earliest_presenta

    Detailed Description

    -

    Definition at line 761 of file box_definitions.h.

    +

    Definition at line 779 of file box_definitions.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/dd/d9d/classshaka_1_1MpdNotifier-members.html b/docs/dd/d9d/classshaka_1_1MpdNotifier-members.html index e7733e0046..e870db754d 100644 --- a/docs/dd/d9d/classshaka_1_1MpdNotifier-members.html +++ b/docs/dd/d9d/classshaka_1_1MpdNotifier-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    dash_profile() constshaka::MpdNotifierinline Flush()=0shaka::MpdNotifierpure virtual - Init()=0shaka::MpdNotifierpure virtual - mpd_type() constshaka::MpdNotifierinline - MpdNotifier(const MpdOptions &mpd_options) (defined in shaka::MpdNotifier)shaka::MpdNotifierinlineexplicit - NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0shaka::MpdNotifierpure virtual - NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0shaka::MpdNotifierpure virtual - NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0shaka::MpdNotifierpure virtual - NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0shaka::MpdNotifierpure virtual - NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0shaka::MpdNotifierpure virtual - NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0shaka::MpdNotifierpure virtual - ~MpdNotifier() (defined in shaka::MpdNotifier)shaka::MpdNotifierinlinevirtual + include_mspr_pro() constshaka::MpdNotifierinline + Init()=0shaka::MpdNotifierpure virtual + mpd_type() constshaka::MpdNotifierinline + MpdNotifier(const MpdOptions &mpd_options) (defined in shaka::MpdNotifier)shaka::MpdNotifierinlineexplicit + NotifyCueEvent(uint32_t container_id, uint64_t timestamp)=0shaka::MpdNotifierpure virtual + NotifyEncryptionUpdate(uint32_t container_id, const std::string &drm_uuid, const std::vector< uint8_t > &new_key_id, const std::vector< uint8_t > &new_pssh)=0shaka::MpdNotifierpure virtual + NotifyMediaInfoUpdate(uint32_t container_id, const MediaInfo &media_info)=0shaka::MpdNotifierpure virtual + NotifyNewContainer(const MediaInfo &media_info, uint32_t *container_id)=0shaka::MpdNotifierpure virtual + NotifyNewSegment(uint32_t container_id, uint64_t start_time, uint64_t duration, uint64_t size)=0shaka::MpdNotifierpure virtual + NotifySampleDuration(uint32_t container_id, uint32_t sample_duration)=0shaka::MpdNotifierpure virtual + ~MpdNotifier() (defined in shaka::MpdNotifier)shaka::MpdNotifierinlinevirtual
    diff --git a/docs/dd/da4/structshaka_1_1xml_1_1XmlDeleter.html b/docs/dd/da4/structshaka_1_1xml_1_1XmlDeleter.html index 632f825219..c241d33af0 100644 --- a/docs/dd/da4/structshaka_1_1xml_1_1XmlDeleter.html +++ b/docs/dd/da4/structshaka_1_1xml_1_1XmlDeleter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::xml::XmlDeleter Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    operator() (xmlSc void operator() (xmlSchemaValidCtxtPtr ptr) const   + +void operator() (xmlOutputBufferPtr ptr) const +  void operator() (xmlSchemaPtr ptr) const   @@ -103,9 +109,7 @@ void operator() (xmlCh
    diff --git a/docs/dd/da5/classshaka_1_1media_1_1webm_1_1TwoPassSingleSegmentSegmenter.html b/docs/dd/da5/classshaka_1_1media_1_1webm_1_1TwoPassSingleSegmentSegmenter.html index b10c3c2e44..6a766a14be 100644 --- a/docs/dd/da5/classshaka_1_1media_1_1webm_1_1TwoPassSingleSegmentSegmenter.html +++ b/docs/dd/da5/classshaka_1_1media_1_1webm_1_1TwoPassSingleSegmentSegmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::webm::TwoPassSingleSegmentSegmenter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::webm::SingleSegmentSegmenter shaka::media::webm::Segmenter - -
    + + @@ -161,7 +164,7 @@ uint64_t  - + @@ -202,9 +205,7 @@ uint64_t 

    Public Member Functions

     
    void UpdateProgress (uint64_t progress)
     Update segmentation progress using ProgressListener.
     Update segmentation progress using ProgressListener.
     
    void set_progress_target (uint64_t target)
    duration () c diff --git a/docs/dd/daa/vod__media__info__dump__muxer__listener_8h_source.html b/docs/dd/daa/vod__media__info__dump__muxer__listener_8h_source.html index 9722ccde9b..eaa375300f 100644 --- a/docs/dd/daa/vod__media__info__dump__muxer__listener_8h_source.html +++ b/docs/dd/daa/vod__media__info__dump__muxer__listener_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/vod_media_info_dump_muxer_listener.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    vod_media_info_dump_muxer_listener.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Implementation of MuxerListener that converts the info to a MediaInfo
    8 // protobuf and dumps it to a file.
    9 // This is specifically for VOD.
    10 
    11 #ifndef PACKAGER_MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_
    12 #define PACKAGER_MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_
    13 
    14 #include <memory>
    15 #include <string>
    16 #include <vector>
    17 
    18 #include "packager/base/macros.h"
    19 #include "packager/media/base/muxer_options.h"
    20 #include "packager/media/event/muxer_listener.h"
    21 
    22 namespace shaka {
    23 
    24 class MediaInfo;
    25 
    26 namespace media {
    27 
    29  public:
    30  VodMediaInfoDumpMuxerListener(const std::string& output_file_name);
    32 
    35  void OnEncryptionInfoReady(bool is_initial_encryption_info,
    36  FourCC protection_scheme,
    37  const std::vector<uint8_t>& default_key_id,
    38  const std::vector<uint8_t>& iv,
    39  const std::vector<ProtectionSystemSpecificInfo>&
    40  key_system_info) override;
    41  void OnEncryptionStart() override;
    42  void OnMediaStart(const MuxerOptions& muxer_options,
    43  const StreamInfo& stream_info,
    44  uint32_t time_scale,
    45  ContainerType container_type) override;
    46  void OnSampleDurationReady(uint32_t sample_duration) override;
    47  void OnMediaEnd(const MediaRanges& media_ranges,
    48  float duration_seconds) override;
    49  void OnNewSegment(const std::string& file_name,
    50  int64_t start_time,
    51  int64_t duration,
    52  uint64_t segment_file_size) override;
    53  void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size);
    54  void OnCueEvent(int64_t timestamp, const std::string& cue_data) override;
    56 
    61  // TODO(rkuroiwa): Move this to muxer_listener_internal and rename
    62  // muxer_listener_internal to muxer_listener_util.
    63  static bool WriteMediaInfoToFile(const MediaInfo& media_info,
    64  const std::string& output_file_path);
    65 
    66  private:
    67  std::string output_file_name_;
    68  std::unique_ptr<MediaInfo> media_info_;
    69  uint64_t max_bitrate_ = 0;
    70 
    71  bool is_encrypted_ = false;
    72  // Storage for values passed to OnEncryptionInfoReady().
    73  FourCC protection_scheme_;
    74  std::vector<uint8_t> default_key_id_;
    75  std::vector<ProtectionSystemSpecificInfo> key_system_info_;
    76 
    77  DISALLOW_COPY_AND_ASSIGN(VodMediaInfoDumpMuxerListener);
    78 };
    79 
    80 } // namespace media
    81 } // namespace shaka
    82 
    83 #endif // PACKAGER_MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    void OnSampleDurationReady(uint32_t sample_duration) override
    -
    void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
    - -
    All the methods that are virtual are virtual for mocking.
    - -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    -
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    -
    static bool WriteMediaInfoToFile(const MediaInfo &media_info, const std::string &output_file_path)
    - -
    void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    -
    void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
    -
    void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
    -
    void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &default_key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Implementation of MuxerListener that converts the info to a MediaInfo
    +
    8 // protobuf and dumps it to a file.
    +
    9 // This is specifically for VOD.
    +
    10 
    +
    11 #ifndef PACKAGER_MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_
    +
    12 #define PACKAGER_MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_
    +
    13 
    +
    14 #include <memory>
    +
    15 #include <string>
    +
    16 #include <vector>
    +
    17 
    +
    18 #include "packager/base/macros.h"
    +
    19 #include "packager/media/base/muxer_options.h"
    +
    20 #include "packager/media/event/muxer_listener.h"
    +
    21 
    +
    22 namespace shaka {
    +
    23 
    +
    24 class MediaInfo;
    +
    25 
    +
    26 namespace media {
    +
    27 
    + +
    29  public:
    +
    30  VodMediaInfoDumpMuxerListener(const std::string& output_file_name);
    + +
    32 
    +
    35  void OnEncryptionInfoReady(bool is_initial_encryption_info,
    +
    36  FourCC protection_scheme,
    +
    37  const std::vector<uint8_t>& default_key_id,
    +
    38  const std::vector<uint8_t>& iv,
    +
    39  const std::vector<ProtectionSystemSpecificInfo>&
    +
    40  key_system_info) override;
    +
    41  void OnEncryptionStart() override;
    +
    42  void OnMediaStart(const MuxerOptions& muxer_options,
    +
    43  const StreamInfo& stream_info,
    +
    44  uint32_t time_scale,
    +
    45  ContainerType container_type) override;
    +
    46  void OnSampleDurationReady(uint32_t sample_duration) override;
    +
    47  void OnMediaEnd(const MediaRanges& media_ranges,
    +
    48  float duration_seconds) override;
    +
    49  void OnNewSegment(const std::string& file_name,
    +
    50  int64_t start_time,
    +
    51  int64_t duration,
    +
    52  uint64_t segment_file_size) override;
    +
    53  void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size);
    +
    54  void OnCueEvent(int64_t timestamp, const std::string& cue_data) override;
    +
    56 
    +
    61  // TODO(rkuroiwa): Move this to muxer_listener_internal and rename
    +
    62  // muxer_listener_internal to muxer_listener_util.
    +
    63  static bool WriteMediaInfoToFile(const MediaInfo& media_info,
    +
    64  const std::string& output_file_path);
    +
    65 
    +
    66  private:
    +
    67  std::string output_file_name_;
    +
    68  std::unique_ptr<MediaInfo> media_info_;
    +
    69  uint64_t max_bitrate_ = 0;
    +
    70 
    +
    71  bool is_encrypted_ = false;
    +
    72  // Storage for values passed to OnEncryptionInfoReady().
    +
    73  FourCC protection_scheme_;
    +
    74  std::vector<uint8_t> default_key_id_;
    +
    75  std::vector<ProtectionSystemSpecificInfo> key_system_info_;
    +
    76 
    +
    77  DISALLOW_COPY_AND_ASSIGN(VodMediaInfoDumpMuxerListener);
    +
    78 };
    +
    79 
    +
    80 } // namespace media
    +
    81 } // namespace shaka
    +
    82 
    +
    83 #endif // PACKAGER_MEDIA_EVENT_VOD_MEDIA_INFO_DUMP_MUXER_LISTENER_H_
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    + +
    void OnSampleDurationReady(uint32_t sample_duration) override
    +
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    +
    void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &default_key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
    +
    void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
    +
    void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
    +
    static bool WriteMediaInfoToFile(const MediaInfo &media_info, const std::string &output_file_path)
    + +
    void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
    +
    void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    +
    All the methods that are virtual are virtual for mocking.
    + +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/dd/dab/webm__muxer_8h_source.html b/docs/dd/dab/webm__muxer_8h_source.html index fd8aaa9134..931549b756 100644 --- a/docs/dd/dab/webm__muxer_8h_source.html +++ b/docs/dd/dab/webm__muxer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_muxer.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    webm_muxer.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MUXER_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MUXER_H_
    9 
    10 #include "packager/media/base/muxer.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 namespace webm {
    15 
    16 class Segmenter;
    17 
    19 class WebMMuxer : public Muxer {
    20  public:
    22  explicit WebMMuxer(const MuxerOptions& options);
    23  ~WebMMuxer() override;
    24 
    25  private:
    26  // Muxer implementation overrides.
    27  Status InitializeMuxer() override;
    28  Status Finalize() override;
    29  Status AddSample(size_t stream_id, const MediaSample& sample) override;
    30  Status FinalizeSegment(size_t stream_id,
    31  const SegmentInfo& segment_info) override;
    32 
    33  void FireOnMediaStartEvent();
    34  void FireOnMediaEndEvent();
    35 
    36  std::unique_ptr<Segmenter> segmenter_;
    37 
    38  DISALLOW_COPY_AND_ASSIGN(WebMMuxer);
    39 };
    40 
    41 } // namespace webm
    42 } // namespace media
    43 } // namespace shaka
    44 
    45 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MUXER_H_
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    Implements WebM Muxer.
    Definition: webm_muxer.h:19
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - -
    WebMMuxer(const MuxerOptions &options)
    Create a WebMMuxer object from MuxerOptions.
    Definition: webm_muxer.cc:21
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MUXER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MUXER_H_
    +
    9 
    +
    10 #include "packager/media/base/muxer.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 namespace webm {
    +
    15 
    +
    16 class Segmenter;
    +
    17 
    +
    19 class WebMMuxer : public Muxer {
    +
    20  public:
    +
    22  explicit WebMMuxer(const MuxerOptions& options);
    +
    23  ~WebMMuxer() override;
    +
    24 
    +
    25  private:
    +
    26  // Muxer implementation overrides.
    +
    27  Status InitializeMuxer() override;
    +
    28  Status Finalize() override;
    +
    29  Status AddMediaSample(size_t stream_id, const MediaSample& sample) override;
    +
    30  Status FinalizeSegment(size_t stream_id,
    +
    31  const SegmentInfo& segment_info) override;
    +
    32 
    +
    33  void FireOnMediaStartEvent();
    +
    34  void FireOnMediaEndEvent();
    +
    35 
    +
    36  std::unique_ptr<Segmenter> segmenter_;
    +
    37 
    +
    38  DISALLOW_COPY_AND_ASSIGN(WebMMuxer);
    +
    39 };
    +
    40 
    +
    41 } // namespace webm
    +
    42 } // namespace media
    +
    43 } // namespace shaka
    +
    44 
    +
    45 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_MUXER_H_
    + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    + +
    Implements WebM Muxer.
    Definition: webm_muxer.h:19
    +
    WebMMuxer(const MuxerOptions &options)
    Create a WebMMuxer object from MuxerOptions.
    Definition: webm_muxer.cc:21
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    diff --git a/docs/dd/dae/structshaka_1_1media_1_1mp4_1_1WebVTTSourceLabelBox-members.html b/docs/dd/dae/structshaka_1_1media_1_1mp4_1_1WebVTTSourceLabelBox-members.html index b92f93757a..d5f4beb82e 100644 --- a/docs/dd/dae/structshaka_1_1media_1_1mp4_1_1WebVTTSourceLabelBox-members.html +++ b/docs/dd/dae/structshaka_1_1media_1_1mp4_1_1WebVTTSourceLabelBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/db0/classshaka_1_1media_1_1WebMAudioClient-members.html b/docs/dd/db0/classshaka_1_1media_1_1WebMAudioClient-members.html index c4f445bbeb..f8ab3ff1f5 100644 --- a/docs/dd/db0/classshaka_1_1media_1_1WebMAudioClient-members.html +++ b/docs/dd/db0/classshaka_1_1media_1_1WebMAudioClient-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/db3/structshaka_1_1media_1_1mp4_1_1SampleTable-members.html b/docs/dd/db3/structshaka_1_1media_1_1mp4_1_1SampleTable-members.html index 3be412ef81..321e02ba2e 100644 --- a/docs/dd/db3/structshaka_1_1media_1_1mp4_1_1SampleTable-members.html +++ b/docs/dd/db3/structshaka_1_1media_1_1mp4_1_1SampleTable-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/db5/packager_8h_source.html b/docs/dd/db5/packager_8h_source.html index 529cb9740b..0c80ce9032 100644 --- a/docs/dd/db5/packager_8h_source.html +++ b/docs/dd/db5/packager_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/packager.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    packager.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_PACKAGER_H_
    8 #define PACKAGER_PACKAGER_H_
    9 
    10 #include <memory>
    11 #include <string>
    12 #include <vector>
    13 
    14 #include "packager/file/public/buffer_callback_params.h"
    15 #include "packager/hls/public/hls_params.h"
    16 #include "packager/media/public/ad_cue_generator_params.h"
    17 #include "packager/media/public/chunking_params.h"
    18 #include "packager/media/public/crypto_params.h"
    19 #include "packager/media/public/mp4_output_params.h"
    20 #include "packager/mpd/public/mpd_params.h"
    21 #include "packager/status.h"
    22 
    23 namespace shaka {
    24 
    26 struct TestParams {
    28  bool dump_stream_info = false;
    31  bool inject_fake_clock = false;
    35 };
    36 
    40  std::string temp_dir;
    46  uint32_t transport_stream_timestamp_offset_ms = 0;
    49 
    52 
    55  bool output_media_info = false;
    60 
    63  DecryptionParams decryption_params;
    64 
    67 
    68  // Parameters for testing. Do not use in production.
    69  TestParams test_params;
    70 };
    71 
    75  std::string input;
    76 
    79  std::string stream_selector;
    80 
    83  std::string output;
    85  std::string segment_template;
    86 
    89  std::string output_format;
    92  bool skip_encryption = false;
    97  std::string drm_label;
    101  uint32_t trick_play_factor = 0;
    105  uint32_t bandwidth = 0;
    108  std::string language;
    109 
    113  std::string hls_name;
    116  std::string hls_group_id;
    119  std::string hls_playlist_name;
    125  std::vector<std::string> hls_characteristics;
    126 
    128  std::vector<std::string> dash_accessiblities;
    130  std::vector<std::string> dash_roles;
    131 };
    132 
    133 class SHAKA_EXPORT Packager {
    134  public:
    135  Packager();
    136  ~Packager();
    137 
    142  Status Initialize(
    143  const PackagingParams& packaging_params,
    144  const std::vector<StreamDescriptor>& stream_descriptors);
    145 
    149  Status Run();
    150 
    152  void Cancel();
    153 
    155  static std::string GetLibraryVersion();
    156 
    176  static std::string DefaultStreamLabelFunction(
    177  int max_sd_pixels,
    178  int max_hd_pixels,
    179  int max_uhd1_pixels,
    180  const EncryptionParams::EncryptedStreamAttributes& stream_attributes);
    181 
    182  private:
    183  Packager(const Packager&) = delete;
    184  Packager& operator=(const Packager&) = delete;
    185 
    186  struct PackagerInternal;
    187  std::unique_ptr<PackagerInternal> internal_;
    188 };
    189 
    190 } // namespace shaka
    191 
    192 #endif // PACKAGER_PACKAGER_H_
    std::string stream_selector
    Definition: packager.h:79
    -
    BufferCallbackParams buffer_callback_params
    Buffer callback params.
    Definition: packager.h:66
    -
    DASH MPD related parameters.
    Definition: mpd_params.h:16
    -
    Defines a single input/output stream.
    Definition: packager.h:73
    -
    std::string input
    Input/source media file path or network stream URL. Required.
    Definition: packager.h:75
    -
    HlsParams hls_params
    HLS related parameters.
    Definition: packager.h:59
    -
    ChunkingParams chunking_params
    Chunking (segmentation) related parameters.
    Definition: packager.h:48
    -
    std::string hls_playlist_name
    Definition: packager.h:119
    -
    HLS related parameters.
    Definition: hls_params.h:23
    -
    std::string hls_name
    Definition: packager.h:113
    -
    std::string segment_template
    Specifies segment template. Can be empty.
    Definition: packager.h:85
    -
    bool inject_fake_clock
    Definition: packager.h:31
    -
    Parameters used for testing.
    Definition: packager.h:26
    -
    std::string output_format
    Definition: packager.h:89
    -
    bool dump_stream_info
    Whether to dump input stream info.
    Definition: packager.h:28
    -
    All the methods that are virtual are virtual for mocking.
    - -
    std::string injected_library_version
    Definition: packager.h:34
    -
    MpdParams mpd_params
    DASH MPD related parameters.
    Definition: packager.h:57
    -
    std::string drm_label
    Definition: packager.h:97
    -
    MP4 (ISO-BMFF) output related parameters.
    - -
    AdCueGeneratorParams ad_cue_generator_params
    Out of band cuepoint parameters.
    Definition: packager.h:51
    -
    std::string temp_dir
    Specify temporary directory for intermediate temporary files.
    Definition: packager.h:40
    -
    Cuepoint generator related parameters.
    -
    Mp4OutputParams mp4_output_params
    MP4 (ISO-BMFF) output related parameters.
    Definition: packager.h:42
    -
    EncryptionParams encryption_params
    Encryption and Decryption Parameters.
    Definition: packager.h:62
    -
    Chunking (segmentation) related parameters.
    -
    std::string output
    Definition: packager.h:83
    -
    Decryption parameters.
    -
    Encryption parameters.
    -
    std::vector< std::string > hls_characteristics
    Definition: packager.h:125
    -
    Encrypted stream information that is used to determine stream label.
    -
    std::string hls_iframe_playlist_name
    Definition: packager.h:122
    -
    std::vector< std::string > dash_accessiblities
    Optional for DASH output. It defines Accessibility elements of the stream.
    Definition: packager.h:128
    -
    Packaging parameters.
    Definition: packager.h:38
    -
    Buffer callback params.
    -
    std::vector< std::string > dash_roles
    Optional for DASH output. It defines Role elements of the stream.
    Definition: packager.h:130
    -
    std::string language
    Definition: packager.h:108
    -
    std::string hls_group_id
    Definition: packager.h:116
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_PACKAGER_H_
    +
    8 #define PACKAGER_PACKAGER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <string>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/file/public/buffer_callback_params.h"
    +
    15 #include "packager/hls/public/hls_params.h"
    +
    16 #include "packager/media/public/ad_cue_generator_params.h"
    +
    17 #include "packager/media/public/chunking_params.h"
    +
    18 #include "packager/media/public/crypto_params.h"
    +
    19 #include "packager/media/public/mp4_output_params.h"
    +
    20 #include "packager/mpd/public/mpd_params.h"
    +
    21 #include "packager/status.h"
    +
    22 
    +
    23 namespace shaka {
    +
    24 
    +
    26 struct TestParams {
    +
    28  bool dump_stream_info = false;
    +
    31  bool inject_fake_clock = false;
    + +
    35 };
    +
    36 
    + +
    40  std::string temp_dir;
    + + + +
    49 
    + +
    52 
    +
    55  bool output_media_info = false;
    +
    58  bool single_threaded = false;
    + + +
    63 
    + +
    66  DecryptionParams decryption_params;
    +
    67 
    + +
    70 
    +
    71  // Parameters for testing. Do not use in production.
    +
    72  TestParams test_params;
    +
    73 };
    +
    74 
    + +
    78  std::string input;
    +
    79 
    +
    82  std::string stream_selector;
    +
    83 
    +
    86  std::string output;
    +
    88  std::string segment_template;
    +
    89 
    +
    92  std::string output_format;
    +
    95  bool skip_encryption = false;
    +
    100  std::string drm_label;
    +
    104  uint32_t trick_play_factor = 0;
    +
    108  uint32_t bandwidth = 0;
    +
    111  std::string language;
    +
    115  int32_t cc_index = -1;
    +
    116 
    +
    120  std::string hls_name;
    +
    123  std::string hls_group_id;
    +
    126  std::string hls_playlist_name;
    + +
    132  std::vector<std::string> hls_characteristics;
    +
    133 
    +
    135  std::vector<std::string> dash_accessiblities;
    +
    137  std::vector<std::string> dash_roles;
    +
    138 
    +
    140  bool dash_only = false;
    +
    142  bool hls_only = false;
    +
    143 };
    +
    144 
    +
    145 class SHAKA_EXPORT Packager {
    +
    146  public:
    +
    147  Packager();
    +
    148  ~Packager();
    +
    149 
    +
    154  Status Initialize(
    +
    155  const PackagingParams& packaging_params,
    +
    156  const std::vector<StreamDescriptor>& stream_descriptors);
    +
    157 
    +
    161  Status Run();
    +
    162 
    +
    164  void Cancel();
    +
    165 
    +
    167  static std::string GetLibraryVersion();
    +
    168 
    +
    188  static std::string DefaultStreamLabelFunction(
    +
    189  int max_sd_pixels,
    +
    190  int max_hd_pixels,
    +
    191  int max_uhd1_pixels,
    +
    192  const EncryptionParams::EncryptedStreamAttributes& stream_attributes);
    +
    193 
    +
    194  private:
    +
    195  Packager(const Packager&) = delete;
    +
    196  Packager& operator=(const Packager&) = delete;
    +
    197 
    +
    198  struct PackagerInternal;
    +
    199  std::unique_ptr<PackagerInternal> internal_;
    +
    200 };
    +
    201 
    +
    202 } // namespace shaka
    +
    203 
    +
    204 #endif // PACKAGER_PACKAGER_H_
    + + +
    All the methods that are virtual are virtual for mocking.
    +
    Cuepoint generator related parameters.
    + +
    Chunking (segmentation) related parameters.
    +
    Decryption parameters.
    +
    Encrypted stream information that is used to determine stream label.
    +
    Encryption parameters.
    +
    HLS related parameters.
    Definition: hls_params.h:23
    +
    MP4 (ISO-BMFF) output related parameters.
    +
    DASH MPD related parameters.
    Definition: mpd_params.h:16
    +
    Packaging parameters.
    Definition: packager.h:38
    +
    EncryptionParams encryption_params
    Encryption and Decryption Parameters.
    Definition: packager.h:65
    +
    Mp4OutputParams mp4_output_params
    MP4 (ISO-BMFF) output related parameters.
    Definition: packager.h:42
    +
    HlsParams hls_params
    HLS related parameters.
    Definition: packager.h:62
    + +
    uint32_t transport_stream_timestamp_offset_ms
    Definition: packager.h:46
    +
    AdCueGeneratorParams ad_cue_generator_params
    Out of band cuepoint parameters.
    Definition: packager.h:51
    +
    BufferCallbackParams buffer_callback_params
    Buffer callback params.
    Definition: packager.h:69
    +
    ChunkingParams chunking_params
    Chunking (segmentation) related parameters.
    Definition: packager.h:48
    +
    MpdParams mpd_params
    DASH MPD related parameters.
    Definition: packager.h:60
    +
    std::string temp_dir
    Specify temporary directory for intermediate temporary files.
    Definition: packager.h:40
    + +
    Defines a single input/output stream.
    Definition: packager.h:76
    +
    std::string output_format
    Definition: packager.h:92
    +
    std::vector< std::string > dash_accessiblities
    Optional for DASH output. It defines Accessibility elements of the stream.
    Definition: packager.h:135
    +
    std::string hls_iframe_playlist_name
    Definition: packager.h:129
    +
    std::string output
    Definition: packager.h:86
    +
    std::vector< std::string > dash_roles
    Optional for DASH output. It defines Role elements of the stream.
    Definition: packager.h:137
    +
    std::string hls_group_id
    Definition: packager.h:123
    +
    bool dash_only
    Set to true to indicate that the stream is for dash only.
    Definition: packager.h:140
    +
    std::string stream_selector
    Definition: packager.h:82
    + +
    uint32_t trick_play_factor
    Definition: packager.h:104
    +
    bool hls_only
    Set to true to indicate that the stream is for hls only.
    Definition: packager.h:142
    +
    std::string drm_label
    Definition: packager.h:100
    +
    std::string hls_name
    Definition: packager.h:120
    + +
    std::string hls_playlist_name
    Definition: packager.h:126
    + +
    std::vector< std::string > hls_characteristics
    Definition: packager.h:132
    +
    std::string input
    Input/source media file path or network stream URL. Required.
    Definition: packager.h:78
    +
    std::string language
    Definition: packager.h:111
    +
    std::string segment_template
    Specifies segment template. Can be empty.
    Definition: packager.h:88
    +
    Parameters used for testing.
    Definition: packager.h:26
    +
    bool dump_stream_info
    Whether to dump input stream info.
    Definition: packager.h:28
    +
    bool inject_fake_clock
    Definition: packager.h:31
    +
    std::string injected_library_version
    Definition: packager.h:34
    diff --git a/docs/dd/db9/classshaka_1_1xml_1_1RepresentationBaseXmlNode.html b/docs/dd/db9/classshaka_1_1xml_1_1RepresentationBaseXmlNode.html index 208800d0ec..4abf0bbd23 100644 --- a/docs/dd/db9/classshaka_1_1xml_1_1RepresentationBaseXmlNode.html +++ b/docs/dd/db9/classshaka_1_1xml_1_1RepresentationBaseXmlNode.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::xml::RepresentationBaseXmlNode Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::xml::XmlNode -shaka::xml::AdaptationSetXmlNode -shaka::xml::RepresentationXmlNode - -
    +shaka::xml::AdaptationSetXmlNode +shaka::xml::RepresentationXmlNode + + - - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + +

    Public Member Functions

    -bool AddContentProtectionElements (const std::list< ContentProtectionElement > &content_protection_elements)
     
    void AddSupplementalProperty (const std::string &scheme_id_uri, const std::string &value)
     
    void AddEssentialProperty (const std::string &scheme_id_uri, const std::string &value)
     
    +bool AddContentProtectionElements (const std::list< ContentProtectionElement > &content_protection_elements) WARN_UNUSED_RESULT
     
    bool AddSupplementalProperty (const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
     
    bool AddEssentialProperty (const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
     
    - Public Member Functions inherited from shaka::xml::XmlNode
     XmlNode (const char *name)
     
    bool AddChild (scoped_xml_ptr< xmlNode > child)
     
    -bool AddElements (const std::vector< Element > &elements)
     Adds Elements to this node using the Element struct.
     
    void SetStringAttribute (const char *attribute_name, const std::string &attribute)
     
    void SetIntegerAttribute (const char *attribute_name, uint64_t number)
     
    void SetFloatingPointAttribute (const char *attribute_name, double number)
     
    void SetId (uint32_t id)
     
     XmlNode (const std::string &name)
     
    XmlNode (XmlNode &&)
     
    +XmlNodeoperator= (XmlNode &&)
     
    bool AddChild (XmlNode child) WARN_UNUSED_RESULT
     
    +bool AddElements (const std::vector< Element > &elements) WARN_UNUSED_RESULT
     Adds Elements to this node using the Element struct.
     
    bool SetStringAttribute (const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
     
    bool SetIntegerAttribute (const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULT
     
    bool SetFloatingPointAttribute (const std::string &attribute_name, double number) WARN_UNUSED_RESULT
     
    bool SetId (uint32_t id) WARN_UNUSED_RESULT
     
    +void AddContent (const std::string &content)
     Similar to SetContent, but appends to the end of existing content.
     
    void SetContent (const std::string &content)
     
    std::set< std::string > ExtractReferencedNamespaces ()
     
    scoped_xml_ptr< xmlNode > PassScopedPtr ()
     
    xmlNodePtr Release ()
     
    xmlNodePtr GetRawPtr ()
     
    std::set< std::string > ExtractReferencedNamespaces () const
     
    std::string ToString (const std::string &comment) const
     
    bool GetAttribute (const std::string &name, std::string *value) const
     
    - - - - + + + +

    Protected Member Functions

    RepresentationBaseXmlNode (const char *name)
     
    bool AddDescriptor (const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value)
     
    RepresentationBaseXmlNode (const std::string &name)
     
    bool AddDescriptor (const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
     

    Detailed Description

    This corresponds to RepresentationBaseType in MPD. RepresentationBaseType is not a concrete element type so this should not get instantiated on its own. AdaptationSet and Representation are subtypes of this.

    -

    Definition at line 101 of file xml_node.h.

    +

    Definition at line 125 of file xml_node.h.

    Member Function Documentation

    - -

    ◆ AddDescriptor()

    + +

    ◆ AddDescriptor()

    @@ -182,18 +193,18 @@ Protected Member Functions -

    Definition at line 249 of file xml_node.cc.

    +

    Definition at line 286 of file xml_node.cc.

    - -

    ◆ AddEssentialProperty()

    + +

    ◆ AddEssentialProperty()

    - + @@ -219,18 +230,18 @@ Protected Member Functions -

    Definition at line 243 of file xml_node.cc.

    +

    Definition at line 280 of file xml_node.cc.

    - -

    ◆ AddSupplementalProperty()

    + +

    ◆ AddSupplementalProperty()

    void shaka::xml::RepresentationBaseXmlNode::AddEssentialProperty bool shaka::xml::RepresentationBaseXmlNode::AddEssentialProperty ( const std::string &  scheme_id_uri,
    - + @@ -256,7 +267,7 @@ Protected Member Functions -

    Definition at line 237 of file xml_node.cc.

    +

    Definition at line 274 of file xml_node.cc.

    @@ -267,9 +278,7 @@ Protected Member Functions diff --git a/docs/dd/dbc/buffer__reader_8cc_source.html b/docs/dd/dbc/buffer__reader_8cc_source.html index 5aef10aac7..ccf06a1012 100644 --- a/docs/dd/dbc/buffer__reader_8cc_source.html +++ b/docs/dd/dbc/buffer__reader_8cc_source.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: packager/media/base/buffer_reader.cc Source File @@ -29,18 +29,21 @@
    void shaka::xml::RepresentationBaseXmlNode::AddSupplementalProperty bool shaka::xml::RepresentationBaseXmlNode::AddSupplementalProperty ( const std::string &  scheme_id_uri,
    - + +/* @license-end */
    buffer_reader.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/buffer_reader.h"
    8 
    9 #include "packager/base/logging.h"
    10 
    11 namespace shaka {
    12 namespace media {
    13 
    14 bool BufferReader::Read1(uint8_t* v) {
    15  DCHECK(v != NULL);
    16  if (!HasBytes(1))
    17  return false;
    18  *v = buf_[pos_++];
    19  return true;
    20 }
    21 
    22 bool BufferReader::Read2(uint16_t* v) {
    23  return Read(v);
    24 }
    25 bool BufferReader::Read2s(int16_t* v) {
    26  return Read(v);
    27 }
    28 bool BufferReader::Read4(uint32_t* v) {
    29  return Read(v);
    30 }
    31 bool BufferReader::Read4s(int32_t* v) {
    32  return Read(v);
    33 }
    34 bool BufferReader::Read8(uint64_t* v) {
    35  return Read(v);
    36 }
    37 bool BufferReader::Read8s(int64_t* v) {
    38  return Read(v);
    39 }
    40 bool BufferReader::ReadNBytesInto8(uint64_t* v, size_t num_bytes) {
    41  return ReadNBytes(v, num_bytes);
    42 }
    43 bool BufferReader::ReadNBytesInto8s(int64_t* v, size_t num_bytes) {
    44  return ReadNBytes(v, num_bytes);
    45 }
    46 
    47 bool BufferReader::ReadToVector(std::vector<uint8_t>* vec, size_t count) {
    48  DCHECK(vec != NULL);
    49  if (!HasBytes(count))
    50  return false;
    51  vec->assign(buf_ + pos_, buf_ + pos_ + count);
    52  pos_ += count;
    53  return true;
    54 }
    55 
    56 bool BufferReader::ReadToString(std::string* str, size_t size) {
    57  DCHECK(str);
    58  if (!HasBytes(size))
    59  return false;
    60  str->assign(buf_ + pos_, buf_ + pos_ + size);
    61  pos_ += size;
    62  return true;
    63 }
    64 
    65 bool BufferReader::SkipBytes(size_t num_bytes) {
    66  if (!HasBytes(num_bytes))
    67  return false;
    68  pos_ += num_bytes;
    69  return true;
    70 }
    71 
    72 template <typename T>
    73 bool BufferReader::Read(T* v) {
    74  return ReadNBytes(v, sizeof(*v));
    75 }
    76 
    77 template <typename T>
    78 bool BufferReader::ReadNBytes(T* v, size_t num_bytes) {
    79  DCHECK(v != NULL);
    80  DCHECK_LE(num_bytes, sizeof(*v));
    81  if (!HasBytes(num_bytes))
    82  return false;
    83 
    84  // Sign extension is required only if
    85  // |num_bytes| is less than size of T, and
    86  // T is a signed type.
    87  const bool sign_extension_required =
    88  num_bytes < sizeof(*v) && static_cast<T>(-1) < 0;
    89  // Perform sign extension by casting the byte value to int8_t, which will be
    90  // sign extended automatically when it is implicitly converted to T.
    91  T tmp = sign_extension_required ? static_cast<int8_t>(buf_[pos_++])
    92  : buf_[pos_++];
    93  for (size_t i = 1; i < num_bytes; ++i) {
    94  tmp <<= 8;
    95  tmp |= buf_[pos_++];
    96  }
    97  *v = tmp;
    98  return true;
    99 }
    100 
    101 } // namespace media
    102 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    -
    bool ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULT
    -
    bool HasBytes(size_t count)
    Definition: buffer_reader.h:32
    -
    bool Read1(uint8_t *v) WARN_UNUSED_RESULT
    -
    bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/buffer_reader.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 namespace media {
    +
    13 
    +
    14 bool BufferReader::Read1(uint8_t* v) {
    +
    15  DCHECK(v != NULL);
    +
    16  if (!HasBytes(1))
    +
    17  return false;
    +
    18  *v = buf_[pos_++];
    +
    19  return true;
    +
    20 }
    +
    21 
    +
    22 bool BufferReader::Read2(uint16_t* v) {
    +
    23  return Read(v);
    +
    24 }
    +
    25 bool BufferReader::Read2s(int16_t* v) {
    +
    26  return Read(v);
    +
    27 }
    +
    28 bool BufferReader::Read4(uint32_t* v) {
    +
    29  return Read(v);
    +
    30 }
    +
    31 bool BufferReader::Read4s(int32_t* v) {
    +
    32  return Read(v);
    +
    33 }
    +
    34 bool BufferReader::Read8(uint64_t* v) {
    +
    35  return Read(v);
    +
    36 }
    +
    37 bool BufferReader::Read8s(int64_t* v) {
    +
    38  return Read(v);
    +
    39 }
    +
    40 bool BufferReader::ReadNBytesInto8(uint64_t* v, size_t num_bytes) {
    +
    41  return ReadNBytes(v, num_bytes);
    +
    42 }
    +
    43 bool BufferReader::ReadNBytesInto8s(int64_t* v, size_t num_bytes) {
    +
    44  return ReadNBytes(v, num_bytes);
    +
    45 }
    +
    46 
    +
    47 bool BufferReader::ReadToVector(std::vector<uint8_t>* vec, size_t count) {
    +
    48  DCHECK(vec != NULL);
    +
    49  if (!HasBytes(count))
    +
    50  return false;
    +
    51  vec->assign(buf_ + pos_, buf_ + pos_ + count);
    +
    52  pos_ += count;
    +
    53  return true;
    +
    54 }
    +
    55 
    +
    56 bool BufferReader::ReadToString(std::string* str, size_t size) {
    +
    57  DCHECK(str);
    +
    58  if (!HasBytes(size))
    +
    59  return false;
    +
    60  str->assign(buf_ + pos_, buf_ + pos_ + size);
    +
    61  pos_ += size;
    +
    62  return true;
    +
    63 }
    +
    64 
    +
    65 bool BufferReader::ReadCString(std::string* str) {
    +
    66  DCHECK(str);
    +
    67  for (size_t count = 0; pos_ + count < size_; count++) {
    +
    68  if (buf_[pos_ + count] == 0) {
    +
    69  str->assign(buf_ + pos_, buf_ + pos_ + count);
    +
    70  pos_ += count + 1;
    +
    71  return true;
    +
    72  }
    +
    73  }
    +
    74  return false; // EOF
    +
    75 }
    +
    76 
    +
    77 bool BufferReader::SkipBytes(size_t num_bytes) {
    +
    78  if (!HasBytes(num_bytes))
    +
    79  return false;
    +
    80  pos_ += num_bytes;
    +
    81  return true;
    +
    82 }
    +
    83 
    +
    84 template <typename T>
    +
    85 bool BufferReader::Read(T* v) {
    +
    86  return ReadNBytes(v, sizeof(*v));
    +
    87 }
    +
    88 
    +
    89 template <typename T>
    +
    90 bool BufferReader::ReadNBytes(T* v, size_t num_bytes) {
    +
    91  DCHECK(v != NULL);
    +
    92  DCHECK_LE(num_bytes, sizeof(*v));
    +
    93  if (!HasBytes(num_bytes))
    +
    94  return false;
    +
    95 
    +
    96  // Sign extension is required only if
    +
    97  // |num_bytes| is less than size of T, and
    +
    98  // T is a signed type.
    +
    99  const bool sign_extension_required =
    +
    100  num_bytes < sizeof(*v) && static_cast<T>(-1) < 0;
    +
    101  // Perform sign extension by casting the byte value to int8_t, which will be
    +
    102  // sign extended automatically when it is implicitly converted to T.
    +
    103  T tmp = sign_extension_required ? static_cast<int8_t>(buf_[pos_++])
    +
    104  : buf_[pos_++];
    +
    105  for (size_t i = 1; i < num_bytes; ++i) {
    +
    106  tmp <<= 8;
    +
    107  tmp |= buf_[pos_++];
    +
    108  }
    +
    109  *v = tmp;
    +
    110  return true;
    +
    111 }
    +
    112 
    +
    113 } // namespace media
    +
    114 } // namespace shaka
    +
    bool HasBytes(size_t count)
    Definition: buffer_reader.h:32
    +
    bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
    +
    bool Read1(uint8_t *v) WARN_UNUSED_RESULT
    +
    bool ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULT
    +
    bool ReadCString(std::string *str) WARN_UNUSED_RESULT
    Reads a null-terminated string.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/dbc/encryption__handler_8h_source.html b/docs/dd/dbc/encryption__handler_8h_source.html index b47c8cf46a..a92d4e0720 100644 --- a/docs/dd/dbc/encryption__handler_8h_source.html +++ b/docs/dd/dbc/encryption__handler_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto/encryption_handler.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    encryption_handler.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CRYPTO_ENCRYPTION_HANDLER_H_
    8 #define PACKAGER_MEDIA_CRYPTO_ENCRYPTION_HANDLER_H_
    9 
    10 #include "packager/media/base/key_source.h"
    11 #include "packager/media/base/media_handler.h"
    12 #include "packager/media/public/crypto_params.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 class AesCryptor;
    18 class AesEncryptorFactory;
    19 class SubsampleGenerator;
    20 struct EncryptionKey;
    21 
    23  public:
    24  EncryptionHandler(const EncryptionParams& encryption_params,
    25  KeySource* key_source);
    26 
    27  ~EncryptionHandler() override;
    28 
    29  protected:
    32  Status InitializeInternal() override;
    33  Status Process(std::unique_ptr<StreamData> stream_data) override;
    35 
    36  private:
    37  friend class EncryptionHandlerTest;
    38 
    39  EncryptionHandler(const EncryptionHandler&) = delete;
    40  EncryptionHandler& operator=(const EncryptionHandler&) = delete;
    41 
    42  // Processes |stream_info| and sets up stream specific variables.
    43  Status ProcessStreamInfo(const StreamInfo& stream_info);
    44  // Processes media sample and encrypts it if needed.
    45  Status ProcessMediaSample(std::shared_ptr<const MediaSample> clear_sample);
    46 
    47  void SetupProtectionPattern(StreamType stream_type);
    48  bool CreateEncryptor(const EncryptionKey& encryption_key);
    49  // Encrypt an E-AC3 frame with size |source_size| according to SAMPLE-AES
    50  // specification. |dest| should have at least |source_size| bytes.
    51  bool SampleAesEncryptEac3Frame(const uint8_t* source,
    52  size_t source_size,
    53  uint8_t* dest);
    54  // Encrypt an array with size |source_size|. |dest| should have at
    55  // least |source_size| bytes.
    56  void EncryptBytes(const uint8_t* source, size_t source_size, uint8_t* dest);
    57 
    58  // An E-AC3 frame comprises of one or more syncframes. This function extracts
    59  // the syncframe sizes from the source bytes.
    60  // Returns false if the frame is not well formed.
    61  bool ExtractEac3SyncframeSizes(const uint8_t* source,
    62  size_t source_size,
    63  std::vector<size_t>* syncframe_sizes);
    64 
    65  // Testing injections.
    66  void InjectSubsampleGeneratorForTesting(
    67  std::unique_ptr<SubsampleGenerator> generator);
    68  void InjectEncryptorFactoryForTesting(
    69  std::unique_ptr<AesEncryptorFactory> encryptor_factory);
    70 
    71  const EncryptionParams encryption_params_;
    72  const FourCC protection_scheme_ = FOURCC_NULL;
    73  KeySource* key_source_ = nullptr;
    74  std::string stream_label_;
    75  // Current encryption config and encryptor.
    76  std::shared_ptr<EncryptionConfig> encryption_config_;
    77  std::unique_ptr<AesCryptor> encryptor_;
    78  Codec codec_ = kUnknownCodec;
    79  // Remaining clear lead in the stream's time scale.
    80  int64_t remaining_clear_lead_ = 0;
    81  // Crypto period duration in the stream's time scale.
    82  uint64_t crypto_period_duration_ = 0;
    83  // Previous crypto period index if key rotation is enabled.
    84  int64_t prev_crypto_period_index_ = -1;
    85  bool check_new_crypto_period_ = false;
    86 
    87  std::unique_ptr<SubsampleGenerator> subsample_generator_;
    88  std::unique_ptr<AesEncryptorFactory> encryptor_factory_;
    89  // Number of encrypted blocks (16-byte-block) in pattern based encryption.
    90  uint8_t crypt_byte_block_ = 0;
    92  uint8_t skip_byte_block_ = 0;
    93 };
    94 
    95 } // namespace media
    96 } // namespace shaka
    97 
    98 #endif // PACKAGER_MEDIA_CRYPTO_ENCRYPTION_HANDLER_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    - - -
    All the methods that are virtual are virtual for mocking.
    - - -
    Status Process(std::unique_ptr< StreamData > stream_data) override
    - -
    Encryption parameters.
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CRYPTO_ENCRYPTION_HANDLER_H_
    +
    8 #define PACKAGER_MEDIA_CRYPTO_ENCRYPTION_HANDLER_H_
    +
    9 
    +
    10 #include "packager/media/base/key_source.h"
    +
    11 #include "packager/media/base/media_handler.h"
    +
    12 #include "packager/media/public/crypto_params.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 class AesCryptor;
    +
    18 class AesEncryptorFactory;
    +
    19 class SubsampleGenerator;
    +
    20 struct EncryptionKey;
    +
    21 
    + +
    23  public:
    +
    24  EncryptionHandler(const EncryptionParams& encryption_params,
    +
    25  KeySource* key_source);
    +
    26 
    +
    27  ~EncryptionHandler() override;
    +
    28 
    +
    29  protected:
    +
    32  Status InitializeInternal() override;
    +
    33  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    35 
    +
    36  private:
    +
    37  friend class EncryptionHandlerTest;
    +
    38 
    +
    39  EncryptionHandler(const EncryptionHandler&) = delete;
    +
    40  EncryptionHandler& operator=(const EncryptionHandler&) = delete;
    +
    41 
    +
    42  // Processes |stream_info| and sets up stream specific variables.
    +
    43  Status ProcessStreamInfo(const StreamInfo& stream_info);
    +
    44  // Processes media sample and encrypts it if needed.
    +
    45  Status ProcessMediaSample(std::shared_ptr<const MediaSample> clear_sample);
    +
    46 
    +
    47  void SetupProtectionPattern(StreamType stream_type);
    +
    48  bool CreateEncryptor(const EncryptionKey& encryption_key);
    +
    49  // Encrypt an E-AC3 frame with size |source_size| according to SAMPLE-AES
    +
    50  // specification. |dest| should have at least |source_size| bytes.
    +
    51  bool SampleAesEncryptEac3Frame(const uint8_t* source,
    +
    52  size_t source_size,
    +
    53  uint8_t* dest);
    +
    54  // Encrypt an array with size |source_size|. |dest| should have at
    +
    55  // least |source_size| bytes.
    +
    56  void EncryptBytes(const uint8_t* source, size_t source_size, uint8_t* dest);
    +
    57 
    +
    58  // An E-AC3 frame comprises of one or more syncframes. This function extracts
    +
    59  // the syncframe sizes from the source bytes.
    +
    60  // Returns false if the frame is not well formed.
    +
    61  bool ExtractEac3SyncframeSizes(const uint8_t* source,
    +
    62  size_t source_size,
    +
    63  std::vector<size_t>* syncframe_sizes);
    +
    64 
    +
    65  // Testing injections.
    +
    66  void InjectSubsampleGeneratorForTesting(
    +
    67  std::unique_ptr<SubsampleGenerator> generator);
    +
    68  void InjectEncryptorFactoryForTesting(
    +
    69  std::unique_ptr<AesEncryptorFactory> encryptor_factory);
    +
    70 
    +
    71  const EncryptionParams encryption_params_;
    +
    72  const FourCC protection_scheme_ = FOURCC_NULL;
    +
    73  KeySource* key_source_ = nullptr;
    +
    74  std::string stream_label_;
    +
    75  // Current encryption config and encryptor.
    +
    76  std::shared_ptr<EncryptionConfig> encryption_config_;
    +
    77  std::unique_ptr<AesCryptor> encryptor_;
    +
    78  Codec codec_ = kUnknownCodec;
    +
    79  // Remaining clear lead in the stream's time scale.
    +
    80  int64_t remaining_clear_lead_ = 0;
    +
    81  // Crypto period duration in the stream's time scale.
    +
    82  uint64_t crypto_period_duration_ = 0;
    +
    83  // Previous crypto period index if key rotation is enabled.
    +
    84  int64_t prev_crypto_period_index_ = -1;
    +
    85  bool check_new_crypto_period_ = false;
    +
    86 
    +
    87  std::unique_ptr<SubsampleGenerator> subsample_generator_;
    +
    88  std::unique_ptr<AesEncryptorFactory> encryptor_factory_;
    +
    89  // Number of encrypted blocks (16-byte-block) in pattern based encryption.
    +
    90  uint8_t crypt_byte_block_ = 0;
    +
    92  uint8_t skip_byte_block_ = 0;
    +
    93 };
    +
    94 
    +
    95 } // namespace media
    +
    96 } // namespace shaka
    +
    97 
    +
    98 #endif // PACKAGER_MEDIA_CRYPTO_ENCRYPTION_HANDLER_H_
    + + + +
    Status Process(std::unique_ptr< StreamData > stream_data) override
    +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    +
    Encryption parameters.
    +
    diff --git a/docs/dd/dbd/structshaka_1_1media_1_1EncryptionKey.html b/docs/dd/dbd/structshaka_1_1media_1_1EncryptionKey.html index 655440cfc6..8868d28382 100644 --- a/docs/dd/dbd/structshaka_1_1media_1_1EncryptionKey.html +++ b/docs/dd/dbd/structshaka_1_1media_1_1EncryptionKey.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::EncryptionKey Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    std::vector< ProtectionSystemSpecificInfokey_system_info   -std::vector< uint8_t > key_id +std::vector< uint8_t > key_id + The ID of this key.
      + +std::vector< std::vector< uint8_t > > key_ids + The IDs of the other keys to include in PSSH info.
    std::vector< uint8_t > key   @@ -94,9 +102,7 @@ std::vector< uint8_t > 
    diff --git a/docs/dd/dbd/structshaka_1_1media_1_1mp4_1_1TrackEncryption-members.html b/docs/dd/dbd/structshaka_1_1media_1_1mp4_1_1TrackEncryption-members.html index dd2beb300e..9873f3cd37 100644 --- a/docs/dd/dbd/structshaka_1_1media_1_1mp4_1_1TrackEncryption-members.html +++ b/docs/dd/dbd/structshaka_1_1media_1_1mp4_1_1TrackEncryption-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/dbf/webm__webvtt__parser_8h_source.html b/docs/dd/dbf/webm__webvtt__parser_8h_source.html index 7a2d6ca79e..8a26e17137 100644 --- a/docs/dd/dbf/webm__webvtt__parser_8h_source.html +++ b/docs/dd/dbf/webm__webvtt__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_webvtt_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webm_webvtt_parser.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_WEBVTT_PARSER_H_
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_WEBVTT_PARSER_H_
    7 
    8 #include <stdint.h>
    9 
    10 #include <string>
    11 
    12 #include "packager/base/macros.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    18  public:
    20  static void Parse(const uint8_t* payload,
    21  int payload_size,
    22  std::string* id,
    23  std::string* settings,
    24  std::string* content);
    25 
    26  private:
    27  // The payload is the embedded WebVTT cue, stored in a WebM block.
    28  // The parser treats this as a UTF-8 byte stream.
    29  WebMWebVTTParser(const uint8_t* payload, int payload_size);
    30 
    31  // Parse the cue identifier, settings, and content from the stream.
    32  void Parse(std::string* id, std::string* settings, std::string* content);
    33  // Remove a byte from the stream, advancing the stream pointer.
    34  // Returns true if a character was returned; false means "end of stream".
    35  bool GetByte(uint8_t* byte);
    36 
    37  // Backup the stream pointer.
    38  void UngetByte();
    39 
    40  // Parse a line of text from the stream.
    41  void ParseLine(std::string* line);
    42 
    43  // Represents the portion of the stream that has not been consumed yet.
    44  const uint8_t* ptr_;
    45  const uint8_t* const ptr_end_;
    46 
    47  DISALLOW_COPY_AND_ASSIGN(WebMWebVTTParser);
    48 };
    49 
    50 } // namespace media
    51 } // namespace shaka
    52 
    53 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_WEBVTT_PARSER_H_
    All the methods that are virtual are virtual for mocking.
    -
    static void Parse(const uint8_t *payload, int payload_size, std::string *id, std::string *settings, std::string *content)
    Utility function to parse the WebVTT cue from a byte stream.
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_WEBVTT_PARSER_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_WEBVTT_PARSER_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 #include "packager/base/macros.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    + +
    18  public:
    +
    20  static void Parse(const uint8_t* payload,
    +
    21  int payload_size,
    +
    22  std::string* id,
    +
    23  std::string* settings,
    +
    24  std::string* content);
    +
    25 
    +
    26  private:
    +
    27  // The payload is the embedded WebVTT cue, stored in a WebM block.
    +
    28  // The parser treats this as a UTF-8 byte stream.
    +
    29  WebMWebVTTParser(const uint8_t* payload, int payload_size);
    +
    30 
    +
    31  // Parse the cue identifier, settings, and content from the stream.
    +
    32  void Parse(std::string* id, std::string* settings, std::string* content);
    +
    33  // Remove a byte from the stream, advancing the stream pointer.
    +
    34  // Returns true if a character was returned; false means "end of stream".
    +
    35  bool GetByte(uint8_t* byte);
    +
    36 
    +
    37  // Backup the stream pointer.
    +
    38  void UngetByte();
    +
    39 
    +
    40  // Parse a line of text from the stream.
    +
    41  void ParseLine(std::string* line);
    +
    42 
    +
    43  // Represents the portion of the stream that has not been consumed yet.
    +
    44  const uint8_t* ptr_;
    +
    45  const uint8_t* const ptr_end_;
    +
    46 
    +
    47  DISALLOW_COPY_AND_ASSIGN(WebMWebVTTParser);
    +
    48 };
    +
    49 
    +
    50 } // namespace media
    +
    51 } // namespace shaka
    +
    52 
    +
    53 #endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_WEBVTT_PARSER_H_
    + +
    static void Parse(const uint8_t *payload, int payload_size, std::string *id, std::string *settings, std::string *content)
    Utility function to parse the WebVTT cue from a byte stream.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/dc1/structshaka_1_1media_1_1mp4_1_1FullBox.html b/docs/dd/dc1/structshaka_1_1media_1_1mp4_1_1FullBox.html index 98939d4e12..1d10acaeed 100644 --- a/docs/dd/dc1/structshaka_1_1media_1_1mp4_1_1FullBox.html +++ b/docs/dd/dc1/structshaka_1_1media_1_1mp4_1_1FullBox.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::FullBox Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::ElementaryStreamDescriptor shaka::media::mp4::FlacSpecific shaka::media::mp4::HandlerReference -shaka::media::mp4::ID3v2 +shaka::media::mp4::ID3v2 shaka::media::mp4::MediaHeader shaka::media::mp4::Metadata shaka::media::mp4::MovieExtendsHeader shaka::media::mp4::MovieFragmentHeader shaka::media::mp4::MovieHeader -shaka::media::mp4::ProtectionSystemSpecificHeader -shaka::media::mp4::SampleAuxiliaryInformationOffset -shaka::media::mp4::SampleAuxiliaryInformationSize -shaka::media::mp4::SampleDescription -shaka::media::mp4::SampleEncryption -shaka::media::mp4::SampleGroupDescription -shaka::media::mp4::SampleSize -shaka::media::mp4::SampleToChunk -shaka::media::mp4::SampleToGroup -shaka::media::mp4::SchemeType -shaka::media::mp4::SegmentIndex -shaka::media::mp4::SoundMediaHeader -shaka::media::mp4::SubtitleMediaHeader -shaka::media::mp4::SyncSample -shaka::media::mp4::TrackEncryption -shaka::media::mp4::TrackExtends -shaka::media::mp4::TrackFragmentDecodeTime -shaka::media::mp4::TrackFragmentHeader -shaka::media::mp4::TrackFragmentRun -shaka::media::mp4::TrackHeader -shaka::media::mp4::VideoMediaHeader - -
    +shaka::media::mp4::NullMediaHeader +shaka::media::mp4::ProtectionSystemSpecificHeader +shaka::media::mp4::SampleAuxiliaryInformationOffset +shaka::media::mp4::SampleAuxiliaryInformationSize +shaka::media::mp4::SampleDescription +shaka::media::mp4::SampleEncryption +shaka::media::mp4::SampleGroupDescription +shaka::media::mp4::SampleSize +shaka::media::mp4::SampleToChunk +shaka::media::mp4::SampleToGroup +shaka::media::mp4::SchemeType +shaka::media::mp4::SegmentIndex +shaka::media::mp4::SoundMediaHeader +shaka::media::mp4::SubtitleMediaHeader +shaka::media::mp4::SyncSample +shaka::media::mp4::TrackEncryption +shaka::media::mp4::TrackExtends +shaka::media::mp4::TrackFragmentDecodeTime +shaka::media::mp4::TrackFragmentHeader +shaka::media::mp4::TrackFragmentRun +shaka::media::mp4::TrackHeader +shaka::media::mp4::VideoMediaHeader + + @@ -225,9 +229,7 @@ Protected Member Functions diff --git a/docs/dd/dc1/structshaka_1_1media_1_1mp4_1_1FullBox.png b/docs/dd/dc1/structshaka_1_1media_1_1mp4_1_1FullBox.png index ce72d75b36f6d371bfebea88e466a7aefe1005f4..6df91dfa4396f6f437e3a3f9e4a9b010a942df10 100644 GIT binary patch literal 26301 zcmd_T4P4Uq+CRRBQ=P3f@6I;eX6eqNTq~urBp*53PI<`Ebt+9!S>;2eV2X;Uz{)kx z=F){rGE}y?X=Q3^iikqi)C`f8DJdYP0xIGIhzRoV|9pMu!FAu~{{3F}{d@gi8?VuoMuh08>U+?REUHj@&U+-0~zWeG6FTAh{^^d>*^Mw~)!oBdqpTGa}%iwP+21850 zf8PFd@4;Obiv>I#8r3Fb-TD?hoBQYH&6~@<65E46{yF}iz6V|aFM=MOcMooR;f093 zsK0-7FzH2=L>bq!hkf?mqbnauE$d@i*1%4m`gU~cmbAcW_tEbY4&STlHAh`4x>9uF zQo*uiEB2!PiBjjumwWGE!n%K8HSXs-q7skeP94PiP}g3vUDGM1hNXiqo0Q^SYFoLM z4eOq&82##khRQ@DQQQ88Pb&-s->UC<|GGfBT-zn?yG*$#inNMRZ1x>cc+})n4IOLz znZ~;dr-k^{=HX~audEs77(#PA`!X)JUmyv`uY&pZuD2mmYr8E$=5%zH1=IKD;r-otw<|0l&^4~vVSde zWZ?xP45PBt&oH>&E61}UE>u0O$Kz)V&NC;#olL$W?u$}##-dEd35NAOaK#vA;q2%m zRbJDH`+1uVXZ;xUF6{!wiCu8YRboxSpxN?i;w8#z47kQ*^O02C349oBch{lR>8jv3 zLR)foo+SBO&$}w}JH{`dFvzy(;KY1}Ui&T&gHs0mG}&3%6hEuMOD9Ke%j7GO--FP$ z9CvOQJC4UG{sZUc1`kxRvf|JOjZFRxR-;m{r!<_)t=>DqDHMg-`7#AA`X@Iw_tHf3SRZ>YzpYS-Lsx$qS(S z&M0&0-_T0t!Vqc10bS3SB7@P+;K#Gh$`rKawe{_*0;V6Lf|A0Rr$$NM<$Kc zus#=~B%msXk9EJXiRRPmMYhYgOg(aT@W>w&z#UfL8d#0GRqc)_PR-~ejnMnN7hNQS z1)$^s__QO_io^m$@#eA)g{FMhhxRL-{0x<9UbyfLrFcM?`ULv6h7_u}TLS`YOuA9Tw#8oyieb9~C6Omelz=Pqx3 zMs}P1W?!>-tRQUiB<|FM^WrYs4*hWNs-I?C>XK)yXjorn>46YJtM+PoKyb`u{;J*X z^|_&lW>;nhU6k4GUFk5vP<&cpW^@r6J&19u`=$`!)iQB(7F}@%Ef;p} zPG%E&iy!je+&ycKaLdY7(i5T-A>(TPbR{xdh5Jr|J+E=~*GweeS4OaEClWNFF-3}U zMc^fvAHetrW-)b8p(@yhQa`j}l(8DEX6)Or)o6#-Ea=l(`s3N7KcdtF02j3%f}0q# z1;93RH#>^t%hLhs6T7^z^EX!g6S8{Yi+Hc7DDd4+A_9JA)vILg{~PG~w-`CGGLBw! z;_8V@MUjnBhE=TfsP(P*r}Er?k_M~YnM{}_%H)J{A#F}MDvN6swfIpz1_Zatg>a4= zJk>CW@-GL6dlhdkT4fqxWOnT@#w3%GU-pJWYbp4Ws#WD-?Hd@J{tK~Yv)zz(65~&1 zjV9j`ec*KaIDWFf97zebdKikt7%L~@#j1VlTQMM`ob<*OJIv@mhYQr=J8ODRG`@eG zf2@lq- zFXPlz$ohJ`^hX~h9KhnX+&v9aCjz8S-Ou!5QfOrl-d!y8#@_J z;t8?`W1fVopXg#B;fK!&!&rwu_0*&?0l*T9Io0enmk=D?6K!rQ%Uttx~8!+>D>4O!8FAcf!m z_Yefa;8M|vWb67O%(u308p;1_DfQpRL>8x&XZW>XKCWXI zYV_rnS1=(X)12%uC^cr`-D83@y$M9BhORlY>oYopuUR^BWPNIURT8O4wm;*Ic9ukZ zuRrU+UJC2Mhj(FtC&1gHu^jF08;{2mZ4hJFF_2^SlE^i1@4@NiBt$~?pnoxdK3POv zb-wB6LSD{nQg>WHz3Nff>2q&#Sh;4?KP7t~Ngr0^wpXbP5vG5&y9;G>RXAmXNc90- zC+WZtG86|e_bzG5t@H!T+l-|PRreD)-6;v^@3q4IE+d(?Ejtk}kDXONBh&PwGg<3HBfZL?Gy zKVj}q9nw}RvUeb61gQvS$AE`tpI#sOZY|kZT(-yp9J!bqsT$D^Q`9fY7#d@J>k*LV z45!8N8&0mljA1p6{Wp2KrL(ehI5B0S#lt=8hOE)H1Kc;tP_avg(g~qROva1uk=~~B za79nDK>LsiZsp~P9QV!-2jHPG>hnCUCuj*o+iGNp!h@{C62y_C=Jbw z!c8y?iF3gf(v($D#A@`LVYI94AAs`gxQB@`*XQueg^#fao(3E)1|=67La5P(!_&Xq zCANwf3Jqz+Z-0}@rHBJu8kW+UcfSH!k-LeTX;M{6!> zD_z+#T}Dm}nN3Qmo|zfDIM4t^G8%y1m@zn}rrPx~dyBa;I;u`$XWV+Z?7)}{lbvNF zjK*#0)gd~R5iW{ETwhV4hT2&$`vEiIFD3l=gbB4e1771*fJcWSP>DpDxK}EbVuGn_ zs<&3 zYXOs##k0*s&ldSR3VPu7cta}5isl@OGq}lI#s;T-v%{dMG+z?wU%}W-8G{uF#j=c> zE?Gcxv7c7Y?&8@}LfUIRB-@zul*7i@uTQk=&AvJ5>s!}>LzTRN*|d)BbyegzG@a{c zo=eM#lnKdd^nMAU>Mk}`8q=x<1@0HcAV?FPA^e+tK`>tcby+2~W4&4`#7?yOR;*Tf z{k%vG-VJY)V%iKI{nSCYOGMYU#@S39p$AIIFG|0;%g#-TuH#1@ZokXslTz9@w7#4V z$bmC`xXW63E4CprF!vA+l&VPxl}Y0&Sbi*kegYD81c(k|O^Eaw+WlOKV7#lPemx}oIL>+q z>Xa1}a$t135J?>@h9tq3xu6>O&qGLd#G^e0xG}-EO)ds$(U&@64{^&g7c_@F_&zOo9L{3hvtnL zO5=<%>cU;wM~uag!nINL-;1gWGTqMI)Xy|IhWHn}9xT;p?<%9NnR!kM5$99tHSn`f zZen(P;x-;DT#-V=39~E@s#AZoofCop1;pJ#N9Oy*?~5?anp)7sJ+&3u(;}Na)C+(m zc;3PKD%IbYS*GUnM&CSmj$@HXA&7X@N>CS{{|nPz;aDPUZuQUBPET7$?x{?I5@QLd zxGin0{9duwuTk4F_*0->Q23Ln+IY1X!iH8goe`5Q6NE zvAqcJ5tP)Ki^#D=D_;bb-x)rVKX_IusvlHoB9-5FC{S_Z0vmg&7ts%;hB^eMmN}xi zHiXP}AJe44+oum)0aZ!nxMI5dcFWXGPmPAH*&A3C_l}Rk&+lc$BT&ZBIuP}e~WO(pjAQyc$QUK;ZL(mDorOM{`UP9iinozCb)#T|w++WSn`QlHm^ z>2*fgM=L340GSkWmrY%Mg-8)f`4-j!g=!0^V-j~L63Yf2lTEEhUH9IYmxA)*wK7ZL zBFRkcXl@JIkR-jQ@|`_ZNBRh@CPKdqV!jSG&bSILkaH{QPUR<=jCTDXf?Mh8qL`80>)7J48TAJKXnD4j&yc~+&aRpF+ z#y_<|R-!kw+B`?ND+f_l{}Z^pORCDHMdwqc!x{1SeY&XsjZVscnSY;OrE}k7KH4YP5g zJv&fj&{-->ghEZ^n$huhSENyvq(6KL)i*Dq<9wOCaJ#$_!E6+c!N|8doTr(7lgFhF zLd~2Wx@h<#ir0Og4;1O1P-%1d=#$ch=5UxXl00FUB4A=9x6NB0g1h!I%due4_#ZLT z*ID1NUj^mOR*5gNM5VzEiytK1?#2_E%lh$rikQ}P4l`bDP>7BXTJHTny6#9@vq?G+$o71 zxwfOJrG(yt>;tg}RAHE&m_A(%dk3iJOH~@}``~uXVY>9kh z474Z|Q*xtDU((5j=~sgYN^XG4n~Y2+qFFz1)T@I#1jLj57T7|SUDU?Pklg{{_?2uv z9DDaN!;6JKr@ZS&Er!quGnkkxr}SK8n6I37t?yWr7rRS23|`$A4Zd4YWQfX|L4K8t zitqC81TL#GE8)BXI?nPFDCpBoJdldFwnM2nF@8b&zMSOF2icw7=2!JRYq|YgV1mZbIxDU{+mX!+au)- zwwcsjW7!o4E`z~gu2K%rfQ}i|lUh;`8+L&&Qy?z<#}WYjmI{EuWH$SuipsC@A|61g zZJ;X$he%+xiS`f+yh-q)Q=P>fIquY+_# zatBG1SHzb`} zR;j4=wOV-lHb15&P^fgW-_ROco+p|Gj|?B`_`{1X1bkTMeEtlH=p^B++ADkZ2CU3U ztL#{1UMB^?@4{T5cIcX_%Y){Rv+$xIA^%OY53+u~(v|c)&E{0(*U6+D(X!&V6m&Pr z#rcd*pNqAK)hM;#Ips#^Hqg&I1g`8-bXpRVzc;q#wv?@@MJ5Lfr2r=F1P3yp6%?}5 zHUAo#QmV6Ini5vyCPSmxi(wYIo?&X(f)(Us{40G=>CCj%j&ZXd$ISzAoLSH~TQOI^ z#JS5R^{Mb5@@#W&yE`8KQw?#>z|cRdbSO#dQlPVEr*T_iX z)LHE%81bLr;x&VA2!=kuGSNxJ2RoaxNuj(_tDOl`a1QbTa zHuBDPMY_T{!9xN9LPrR#zpG02QSKlhzJ*yqX|WsB0kfJ$Cp$~s*(XWSk;5fdj*iNi zvJgH4UVeRMWcp#}B~}|uPY1V0HCM?RaW2xri`o#?6KJOB55BsWIk%5R=F8=V#@JJqR9LZf9sEKE9s0&WkZ$TAIKIUk| z_U5Tt`YHtap((hhU8VljQXop+>%|c#TaoG`VvAsUwlAQkEfI##@UvIv`)rlzP1#(P zT-~xe!75Qg{|onU2mj6Ho%Ok8F150qmvrr#BNIi}p`EO}r5W;|X)PIA-8-qhqI z_3j!+bm((@nX!S+x;z*K>Sq?uX)sd8W|FERC76`7_`+^Sv=+peg&FxjO+#iiq!txCy|Q0CCdX$jhv+LLz;~zyR~1G z+^eqblYOkL3btYR-rzhiyzUz?qnXVUX+Lj@6%qtDAgbdK=k9r1;J{2WDy@B=sCzSJ zLu+LfT`J!ma;rBkS!z!VM5t1)c-u}EVr%FdUyBQK4#A${#cm(ZSKPL?7dy^6ciZtBn*!x> zTw*;hA~`c+;Po;D>y9BgCS#xs&;luxE^+}iR(NVpWe>U{Q|n;e55U#3d?haEeIujFsByT3fpLUhgdMdALQ=SBQ$4eYkKPZR4JDT5;Va2j7#GVitF?XSK(7=f-g zSG;;s^JQJ`Ey{R0qN8&;bB(vAm*^Ee*(ibBVfWSq=Y`{NtbJupcsH%Ss2!rEP(;nC zdz?UE!F7HP9i+86qCyXWOXE%T+2S&vSN(e3G0T$sYmkx*O_WgriomO;5b0)l&(~f0#9b&I7Qa!-}Z}f z%F=F&d2CAvAUgVSE{M|b0#=C4=B^Ow+T&1RvLcSo&{wAMJ_+4j@vqMoYZ5w(ujK61 zsZJ}Qsw9j7B55rTlA#ZlTjBJ)kQasj!3j=e61}oT2C@BsQXr6E%gk;!%3T1e09_=Z zDrhXGWXwqurtec6bIAw_xW1!F-Vc7HhooH?RL)Ml2y<_U!;OOn+zFK^y10q(#<9i1 zr09MX%X6phq;rVl;Y@)q;_cywz!-CG(HK)n4Y#5df*;<*3SePNLI32o>6ZvMK@IRE zzFQot)k_Q)nPHQ4d#knA>ef)1ZRMRZrhvrmyV0LoqOi&iD~3J}pxfl$^N|c#8lW>v z^^#BrkcXB%hiWd#+Q195=$%>_mv%;4{=e#${_lkyWPdcC5kGY*KEeGrt@ow)CDLB6 z*$4~djQL(C-aq#;0^U%KW0?m;O)3v_jKpvqsw1+|)Ku)G5lLaY4za$j;XFKC%Nm1Q zE&zR=1@t`6R3nCx?5`jw0RxR3>Jt1TeBSH&BpIy5-+g5>r=xpPIK1&l8x1*tL&0C z=b8Nunqq_!=T~p+o5JhtxtuBOG%!siuyaG17hIV>Yn7S)S;xI1oSB`Ppk1s>>xIr< z?O4yhmLF5a4Zg3GJzygzC6;xXIv&NyPv`!1-giSN{VXa%V&al!4~~D?k%$wXo<4*t ziLr10)wS>3Iw4ytA2Pkq6j^?vC%a4fQmlc%Ghp(W&+@V&ola~QoZ`+@txd@l4ZI;; zR?RA-Z#4dtP9N^i4ehhJTu4!OOUR zJf`~LvsL=hIs0uinp9me7SB?>am|Sev%)g^lOrkSI?vmBEQl{M3}UVQ-6Zq$%=a=x zj7Vu`mx@0RBlb-aEymdMVPw#3De{3%gGX-%Qm>Z`OGy{*hHrk{m&RQ<#k!lUQU@z; zm+|DC8HXrdmtu7BIhrf9mHr5`B8%A6e^)_ppjmv%(!o8<1fvC!)k!%thx$}1Bf-(| z&@G}N+V@2F_zw2DY7Gn5upUva9JZ6R*MBz9Ok-Yu7$Wp82TkFLwRoIz-=OhL(8X?E zci8iCI?q3)L)!){71{)x@SPi+{@X4!+*Ckr8-8#>%)EmDU{1d@=X?Bg!S|T)HSI-= zUo1_e4;FHncr=Br7y4%?OUSt*{nr|bGGoDPk+V!})|6Y|TwplA8m&kijwm>7E9#LC zCErjd{;8Cp9CReqxR|)InyqYb0xlDsB?g6M;RGl&5C39b`O|X ztVV=K&t4m=33Y_&J0Ki<*Eq5O_2;m_|SZzZ1#?`^+)5=ZkrKtwgGcbu;2_JfvN2e zR;`hq^<6YknOO{2ca7oXG0AY8$l-7Z3}x5j(WGy-v+D+AgfZttPcksLo?gfGe9?4W z`U+_PhRBbC=aH+(VOhk8pn}2yG=0m=<@~voQB95E8{bl^vMXbMvR;Cz-b0j$AE zpVJV^;`nz1ieK|zaDiZ>*#z%4-6@l*E~8hG=ta)eVBHi-F|MfCrxbppH(w#C?^s2? z^&zC6F-7~S9+itBuV+K$0bJ(t<6M)%O6D@xtyl$yYRrV^sJ2T;`0val;+FHQNu**> zHQ<1%;bTmJI&H2^6oVsybwhei1w_29C8-e97u#&e#Ym$-KM66~zF<1K5?AmxZ?&eP zkJ=b6qw&fd>PwFkFKB!8!Nq4Y@bH*1O|4*^rQW3JR^R0AZGy3&0ksBJzMWo?&Gs*?#35b@=)fjq<>Mwke*I~il0wCnEt!5f7<8CMFB(Y0 zSp#J!l?kq)^g43UM|_ufe6vFv@Dalo#vV(4DqSN2HYr&X)2lXaaIBU{$F&4_;f@L$Tc(K2rFrBIkX?}2YIqsVxHfm-Uj&4gTwl&&39$K4gxjW~s zOal11Q#3GoNrbLU-GO*}d=~hMk-%4MHT{hBqe9iYcB}OEFjJdJY8X7(oL_>5MkgG|_YG;3AR9#+dnf+Q~0oHkr3JCwx z6N&Bp+qbn3eCCSuvJNhooJY)Hzg*?<9w?trr)q>HO(i_|xJ7ea*@I*_3QV*sz~)g~ zj(7J|3tB2uf8r@pLKhA1KZkSiFkMuDBFM16&GZ>iyD154__wZ`tl;gzQrRIHu(tfSyvlGNMkq zd2zrOmp1!8lkHR1+{u5-=16ZUy*^yl_!=m^%16cXMkR9CGit^H#g&s%UmuWvt!Tir zrqqmB5`_P6nzd)XuR7qm4}ItQS+m00Y%Mvv#~Yc*w%SRGUE;aPm2d%c^mo6GzJJx;iyYjyCTRbm;{=>P~x}0 z3j)&ZpJOZT?^~V01#YDat@D_fElQ9(;h-^}VTT2z?7f3i@0_0{7u^Yqy>L!!tqAI3 z8a+^%$&Z_{snX`QI@^sUF7y6&=WOledJ!41;Sv89BR3iZ;acR4Tpad1Wq7Dk<`tTF zF49+a1c!Fles~jCG=Z6QSQx-?&3k$P!=*;TUMEkfb-FlyWRgft^QQIdn8eRFA}geGE3S z+nJiao#C--*D)xi|73ZLKX#Vvvf@ovS0ob4Gz{erHNnhO!gbJW@Lt=dnyNK>u;u~| z+4i^_3uWt?8x@IO!v3uAeF&TSdUrP|0Ja1VroJ`QfPU?}gbO9hD|UZ`^Dfi3xS7Loy~}FDz4?J;>s-Ji?(6cuwxO9(3oRl zF$oOnY67$FvQ-59U&ii~g5DG%b#bjhnMY`%Dy;0$5uA<|EU!rr52)N0&P>ld;`KG`~YPscl=myR84-wi}5cp$AJMZ2#yLDbMo%?V^OXL zpqxCrkdxyp*I;a;XbLwA(UeM@CQhd2!nz@1v;xY+NGp|LLU69_QNH!&mqZ>5T2%GV zkQQZ4x#lve|0x5%rXU6UcDDkNF$`|v)IB$4i>jzVA( zgDVoYxGfefAD;DQVIN$ty}KJn!%O^_7R)oTXFs;McqLbme6SbGrDsoAQg9PJnK29N z3?OD$>ZbRZi@Zd;e-T(A@>BS|#TK3}Z_Pfzl2WK)V$ zEXhPn+R$nTy?u}-jrE?Z*Ss!Ar-N?CH9!@go@fl+1k6oPb8E3CS&~*4I}N`#bJK?3 zMxG!$KwlMK?Y1yIBbxJJhIvugL^{mMn9+5~HuW|Wzp$C*`@EK}xVqHMwNr6{dKvJa zGYxgY;UqqNWm^K7ToFu%r9%gw4Ju_dqc~}m?3on>qd)?3uS1&UFCkc^T^k+`(H18U z#}s^mIOL?P%PcIXm8xrB6Lj|N>Fp{%C-$c-4BKA$t=H*%OWnQBR|0G<;?cf6vTEw! z=T9bhbkS|s!q4ay8l;hS%KfZ_uS-|9;Ry{D4y{aRAp!FGGdcE{?_fl*XLW99oT%1+ z-ivMzyy(O@QkCzc`p!kbTUDWSArkoKR&Gx3)5c4sbA#I|NUSvdQo}6x3Z;GnqNUsd zkt#C}CWYF7mPv7r`$=jlw7VvBJBYk}f4sM+u87d0>(q;iJib7 zaJsiZpM8GBwppOx50AX}RB3#^Rm-FwxF$$-Qwzq6;Wj>gn-UMvVFc*Hmx_G_puSL$>^%~_gQ(ppegI#KygO!u@_2uX^!nCaPYv0UK!K5Vz{8w` z&jGupEX@Q&M>(Rhg*^ylr+sbVoAGSVCJY!Jn+WmEhP6O`kI02lGKTr-<`MRosKK*o zq)nIsM|(B6mmY^ol~5?d7PLJ|p&y;k4Pe;jq>V522y`XT#Ui5LK57N@{A&P!Jg~%N z>D0qwy|K_S{k?5zK|VL?DtA7Ttm50}kwqT&vJnNaP2f1bOIwUS%-X5qtN6VbF_3L+ zDmO6&4zr2mo5hoOyA8a+sfxb)yamb7)`wS;=U?tydq>rHK`t&^X{{_9pPn-_d9v~g z1{vP*t7Kp)*#xjNWs&Ba_Mr6LsKM~k%9UKseZ!xa${gVyDi_+1(=L|3)aBlD@;%2; zLYA2qt~_^2GTDW(WtEmsZRMDaV#(AIAE>w2r;^TUlX2R(BhAfQ1~3 z_L@>|;&-T0W!gGkI#3{=z@f%2^P=}Li~eBy#Az~LWr8%IXa&z=1SrN`_6F?UwIhq=;sQ#*oe z28KV#FB>wa(P(dE4Q%NPXpZ4J%<_o&co9Aw_z!e*c4Y?YfsRt#>#NC=umSj z+YeI3cAoqcobl>ipE0&-$M zI*)KnqCSICBf$CS$rc6Ql&ubB+y~1pT0CPu2dnqSPb)JuIU?b0aTjg&Z48AxHkPUt z7LXt(02|c9?b{({D7rVYQP2`CubI4qSaILf3NQ7n69a<@4Krsj5j^qPd7LQxoIQDc zWWGXiS_i_E+m4L|V~b3%lwgBAd1OPY&<*q;J?X;(FL8R;bAxO4_IojTuaSIkp@@`6 zg}l-*K8xI8%tMOY{$E2_XuJkmrB4EqervqLFlK&qD(S=@10A+pJo#7<6@c#Vv6UQaA5J z${#B-hiqxr%$w`Dec>`ggcl8CGuKJcoQ0QUFPP?3#-9{mbmOYRrOe(!y!Dtfj*@Bn z@Wcm(Ga2LMy6cB^Ih!%OP3v2|K-jwF&Cg~Gpv`e;;nDX<)nG@9qm96QtmTGb&0!^8 z`V#|~+QKiODgnY2a+psD?p9O!}=*ZOB-F+8Qtv#xJ?Cs>XN-WqUo*#hCPJ#7#ypZY@JE?rnY zWx5s=Q$&jrx8IWS#cSd@BA-;kCp%FEPz9d`C1`i+zfnD|gC+|3WAIkZ#dx;#V)kGP z6x!T8(a~eRR0bqG(7+al(B~{UU96TDi|MCKZNCSrCysQ|mGz%llewk>YBh_gfU_5_VGFNUU}Rk(g4OTP7@PIR>g@FhdK*Ves zl=w#FgoslzYjQ;;LMtP!z!;&dEh_$- zp(4cGK!yZH9mG6mDMmvWxV%@vCsZ@nHz4O4O3~_3t5C@&X91s(_?;n6t+RIEsdO|a5ipn*% z4Cf;ig91Z&4p`qedBZPb48Ak#ht4w{0ZJaj7nyani6k~x*R}ZM5iG8#I7nxrZ3snvL@M&sIN_&jlsnz;W}K`HbyK-y@P>GN(VT4Qs02+5J9~u30~~l;OW zn@JapOqN00`$~svdS8Xx7~kGbJ6{_#0bmPVEUhnO%Xq^zUKpwv3L6aAHSi@Mk3@sg zdtn$iadr#My+;e;v?QDI`Ec|B|#drXY_7Xhz`DU zuNZ|m@V300A8)q<48f)2dvlzm(Qq)fF(z;0M|6HS5HgD8-4-v!$bQn8(a!gZYE8&Gy&6zTl}-eZs@f6dzu96d(k z6EnS)>3%a~m(C_n(RZ?OxI`=SE4Dy$Me*Xvdp}Pk8!mSb@)YYY^2IpD)cbS5yAaUCy8Q8D4SitH z!`S&`6V@wF#d5ehI_tiy8z-pT+H8j*gVCeo(CCp8#3w$>P`5BB_eD9Ly>B?NF*Sb$ zqRvEV(^`X(4=y3vIp3QPIO-7wfx|w|>{xtNZfIGBI2mCLxjqtZ>Um8KQagfa z3(5>_o)m!Ht;lhff)1nTvK4!%=@6E1zZGfRk5E$&Kvcn@NJIqP9SXGWU@iwL|8T8D zx9|Q9NH?^=TK9m9^(9b0FzD)up?~4Q=4;;inV7lt_+VG*yv1T;yI-uU3ux!qsTSHf zKc8wH*?s{B-zjKZ#Ab^^=Ytb=j20w-1JMJ#yeNT{QGM#E-ECED`o|iA&PIIr)T>Il zTJu&+Tna87SZd#xR=5-=5aTmktIE`zY_5~&5>8n<5!aY?B;lQ}N|ph4ae}QW;crfy ze^4VK8NUxqCB3Z>JNZ#0_ZBQ^s@s@B7e+)owt95h&B}>eH){bc`}ysHqw1#K8p*=i zm*$EjgK~eJhe#FZ()@6MC$-qXTC1Sq-9#Uj+i4T#E%Z_EiaJ#HmLaU$0Hzl*p|ys0 zfI>=q5G=iBKTTAyQ>z+A1!3&9e`nH%W$*Gz3CBL_-NyA_k;ko1y*Io(O$C%oa&NnL z0nExY$f6EH8-dNtIQK23)G#oa=xxf{$JF$Ky8a*F3!&=(z^?zp0j%jC&o;Z2RAz@C zRqRHpH97-F`QTbGObOj@B)FEGni1u_)qIs@A27n#=U46A$Iv_s%KR~FnIfHRo*EF$ zQHBp?e|azmtavnu$a$cZ5JZrMi2%$Ja0H4u!5lu;Cs>EMaU)@Fvi+#Yb49h=Nm3*I zKp8xt%xQt@3ZP-7+H${mJr5hA`I{lG8?0(^DjX;~4UCcL6TTX{HYcfO6B!@ItolYJXfnNxlJ#j^M(>xCVr9XL%s$;=C_p92{um zxM)ADl?#$v4JD<;C&)6=5EuzDpcIdkB=HREKF2{ziW%u9c`6|&J1lU5!ZB?vam%H{XjjKTPeL{ zt4B??@Xjc7 X-+D6u{J&;iK<)DVd)ddIo%#O&gEpL{ literal 25666 zcmd_T4Or6m`aiy%R_&~nzq1G1nWfvJTuotRNv6Wt*_vaPp4NIWR4P*|1q&1(kuA5i z&83A)QdHVpTKTjzMIMyQnGqrtDJdY90x2RYqVgd8-XGNUu=f3)|Nr+rzw38xTvyjD z%;3%ae%<%|x?it*-~1~mVDSsDzwpd6&n(7#^uZ_3Jo6XAGtWGK@cDV*PqyH$62X67 z``4CFH{0!Y@a2OcV?y@Tli(}IuPaxs%>PF227dc|{3k)%p8?+lJvwfDy6%~0B5q+m zc<*!_W94JhQ_Zdi{KybKbx@oR!xsBCcorD$)WtB z`STZU!F+-lD^M>8*ua8y{lIS8Ci29P4-$@iN(!Vc&v#kYA*UTU4xXOY%6n*SRYoqX zYdpH^<##kI-(_XH_Oyo-ToWh9dPd)3&ZmdN z-$93w{qGSuVYaD__m$VA^4{}Qx@@3{$+Xwj8W8lj-~`V--J7BsV%rI(>FK{=#+=q8 zHx4q@-lYix_wt*@=rWFTLt0(zT7}K#0k1prEoQ73ygs8IDbac(HRQ^^l41j`qsa0$ zYjaDc=rX(M9m{bxzP&v1*yM7>@MWh`SpY-3txNPuxE!t6!m7KD*u;rtXVb$XQr0Wr zdRo6`19Icx-l$FDIxQn1ru3+BRAD~DIxx!FQX9#XMj+ODBa?jW@m^bL%n5y+0A|`l z$|%mq(uQt=H>1vl`9d#Ps>+4g&;9r3xmB{hWBpc1&Dmb6!1t9`tXR?F7i ztYh{Y?x0OlEOT5CXbqY8;G-#q0pV_oS~Gfs(7rGg4gBCS`XPar->G4nN7z>FP#&e3VS_d*XS)V zQJ`3>jUoh=S>57~N+zpya$TiX;R8G#uCw< zVC61<-u;yK@q~A~?|~Rw+s-cRk(1-YtGh{Vs=D(@(F9EnoWwxzz`u$6*}Mr;WVpd@ z;Dbj!tm{xjRE2vhJ^;(TOD1TZFS>yzc{MPwE&#l`V96hrx-3gL;HBt(i~r!kx-3@& z*ZD||KcQ$vTpkYVGN9{8X6{FBe@$m$4ERM=#&uQ{CN>C>GNCP~j=PP_+T5<$Eo#329~6QX0P;*$>J6A60-eTDFF^NF-(__W3SsDrP;6&Pbk&)w z1lci!BX`RBb7B0ZJ2OZZ%m7!eQ%>s-p&kZLLb<|yx&p#}kUfeF+pyrQKz=!#UosFf zlArz_;a?+`4gZ4x^?!ndxRbK=Tek!F^sHsOt6dRTChOH1TyczC$gIGL?|R;JZt z;+%`JxD6LzrhkH0K<+1}9CLG;8uJjJXuDVF?C}?wA4rq%2-Ea_CJ)E+n0`sJRI3?u zeh+~PrbUA!bQni4%xehxn)`XY<+G(!%B9!{PQ{`Iu6giUZbpoyKl4lJ)>?Mc+Y7xV z+Me|qau1zQG?6SgET()fGhd+Q$9YIxh2~tQyI@zi4{H)UmeOItvNIux zFYh;=kIPKns6Z8&)#ux=JF7(BB>#P9wiF==1qskMo&$o*TT-#mwmE?AIXPM#vnbQu z{w}i>Ioe{5{6Y8(H}C4(%C0S%E;6Mio%2|(-SIbRM%)YeXcTTzerNym;7f+BxTS5# zhABTx(JjX*t`vx6#-Aq%lvJs^K=VkEGKVa73V@7Ea1y`wY0hSA5TG-4P}RWF{sr^- zxc_Kc{r97GYCe0eKIq*r{gs^d6RqFpDM2~=Hs;=?c@2vNGsH~8G2YWq23FBnXf$T* z3yC0Zm)*ZfNs=>FVDSz(bm-^ z2zc$c>o7Z^mvxAcd3-&(oAG)46%IrU$kmpVo!rrMWkXgVZGmsYGtro6p zvSbk)0qi<36Trs29-2z49q?vSecoarA8;=)V607w-t)moNri4GGYgI#?u!(Ljn*CK zF7WE)>qW4Zz%xM?mO_&wCD| z{$Nnc6zDt!);;_{+E!|=|0QDh*u)9qZFo=Pl`IGDM{?WX2cm2x2M~ zJdR?<{9U}X!}lsTaTJH#f>^>k9D!~$Dn)wNUM26XoxbvD)%p4@Q9L%dQaxd(coi~7 zA1ODn)k$F`-PK~@d0)46xW1^&#zRIT=pXENSWs@C)U8P$UoTpme$^gNu%E3{FE~Dp z&`cnptbI2Vgj3ap|GrL>tlzp}t7P0GX)FH?yj2fBi|j(>>XNKl`g zhKUdTwsW0J3bT#voy5n>&H|9hr;~>n?)o<{S>UhVp`OOl(g@qyTjMe_T+HVp01$f(Dj1WPU3xQ$dL>8tH&gf(wBR7#QPtxMYQ8hUH6}(?+`LV!;ly<^n*s_ zLCI-;s=&83AF4-!7CC>8cdZHcj%HcYZ;grKSaDU(Zp!5(9t+f>ly_Jy&4o;@sLp#~ z!qRI?g>@w|T@!UdN5Tz-nmjprKVP)?n#C5CqG(gg+ZW5@=Ss_<{k3_OOTxp`M_W2u zNd%#Gl>q(_>59FhIvq%t*nM20Tk#EJo2erzg`_gd75V2e)mTtk8Y@KcF`3pMi-ozC zq^{ab#z0-qG9)n-gmD9bHUt5=n|vlu6Ljki?gXnRau1|eC|3$f(88kKK8R$CB?sn&FBt7Ri$1P!OEN{7P?$P@lM+A z^o_*}K~CNW>=}c0_&_Sx^7CF8R;U?*?PGv>VD+tqfX22 zH!5i=fWglP$CXHRQSG{M^~AG9^zsRL0K39%q(GLI6~PXJC+Elp`TJI|RE4Vqxx3nR z)8NsvQn2)~IPH5@`P~g}UQ#Sa6urCs23JH$ZC@prR|u|@7h|B)*)&^IYWo`U2$?7K z2u{K`(MSm(d+ZBW3UZ;=PB~jy?$s=SD`OEB->zYGZ^E50@gg+@X7yeb{?(qBcqxVI&!2zGz}CiwNPalX6A%Y&6E{))e8`Pt)yA}G#9*6 zpY@~U80iH~u-$6vs@DFMF2NraWJgl7L$|Q_0Up7*FeO9}GTU{$b0S~a>MsJH&77Zk z#XCC$!KlHeQycoPMRCHvhoOIjn$$N~J{6l^WX(I2*KDpr)(L-BI1h9f@0fNm z1`;9)NWKkh-2?Bug~Hq%U5R2LTa-wHq1C5JbE&w-5q}~P!N0*(P0li~<)E;OF)e&F z+D<5ro|2^v9rnT#Mn1NgeupO1ge3Y;=n1iLW6ukMA5*|kb zVEEOa4h*w@lY}W&zoR!Z=9d=pH(Aq8!IJkL4Zw_j107%*#Q(Gu^Q~k+EC=%|jny8Q zMv$0rU2QtQwLu}Fn$}ia*{5(Pvvq)pMq>fbe9a@ziQ}&wI4^m=AR8yY9jO|)V)VyV z@fxoU@`s3xxB+Rvd_V@pOx$^)gCG|SPR z>J)rI?1qrIxVWPwGxQNkwx!A7*tzMWO(yGqMZh(>0g`I?lftRnvMp6*TxC%C*&O# zqLyOSs%nq-%|dA&gW_-j!rvTZ~q{%)jI6AJ@-QBwc93%hCK{uXM9l#N4{w>0ro(dOBmoDvf-ur|{^} z-u($QK-vLdy^askzSL~|0ZvW6d3DzePj3Dv%ZqH0Yn^EQ_0Xle3u?_uP-`YUtTl@Q zkc@$?|H#a#Y_w9pp9{~p?lU36=k&faZA|u&;SW_4N7B}>^Hub2w*K;H7n9$rj+fo_ z*0(3^8c*4|O7JXzL$gT~Uxb$;wVjWJqxP^fV?gy1fK8u+ws=L?{!dmp(9@g_f$5Tj z(G}cCS{j7^PaZ$Sg#;e{vqfEk$K%XTvS5HEdVe_BI58P*L}6^7gOBtCI4TtD`T-mP zdtsFz80u(;L8vA9Mjy?8TXUSh3_*1ceW||O8sBC7f+5in^A?txEjBQQiPp?>*6{pW z#;Rb+(9CN>O-{M#mOcK`4bwg`#7JJe3o(+=;OaU%p99JG{S|PZ3F_un4Wq*4ACfZmWf4jY?>DNwS(oy0r7O$) zC$|x_8h-Z{Bnj(Y*EU>vg}dFu877cCWFsxHekRpCzWxEZl(JEg+ZP+*rN}3gt*-U2 z?<`J=xxPwJ193R>7y}vZ_K;aF@;Mg?KB62yd}cBR-L)kyZsiQI7#CM!h~+khu*k3P za#L1hCkHxL2|wj74^O1CeLA)hG~#wCFP$@$l(5~h5cJr^WWdj$^*0-HVa;H|HOIou zu`=N>aK9fNp*{h8a}!q3TYm~#Z1FMa_#$G)F=f^Ny+Pl9360ic@<)iJ_X+>*pqTsQ zpqMJPPy00Z*eSNdMmQ!Nn*D_%X0R`?h-$AtBOXVjK;eiM=w=3jt4YKAeTX)X`d^44 zrU6hQ#+AsbCEDBmC)@=RsEI*)$ApMjyF0hIl1 zmXSavsG|DIkA>KcE!CP58Tta4Q|z-7y&4GL&CoQ3Gi{3Jnx1xDb(f9N9lmLf>_*3d z*$k3n(Tzl<__yhnX($B4{7%d&fp{Q3qu6%qQFtSN?@7egS`o(qb=Uk=Y>D9t`^i|s zx~CPArF?{Jg8vcJDBGbBNwyyjUnwv=CAIM122bms5?W6To&RVw_BT&P5M4P8Cvy)N z%7c48rKLfWD|;kV6tXr4YR;h8yGa@J36UICWRv+EV;Q*F$5T^C$#?0i<89+&CexE! zbi{|_%=X_XERZEM?N=BTlig6fO@b)W@v}!?zhOGs4&m7CSsWXkHs%DkS6`<@DA*jB z58w*7DceEP94oKNCYgj`OQn9OFtV4KK*BOr;wiI*l=yxbzmZ!7fn7A1syKUV$SEY* ztu@C@XGHQ&eCPtXdvso@%v7#TpgZOC*FWri6Jxh9xIWc`GYAH+8AP!bMu*@_%H|8- z>l#>KKLub3%aAQy9#$uB73S(Z*0A|E`{Z?<30_~?Z#z95vzQr7ri$EjsKr#$?zT#B z6w0(wQ0i<9`G98idP*NcZ}Y^2?*LcxiP(A))gFO_Kf+iKG?|Zc%|w&VmLo<7)AXQ- za7;a!sn`$V%?V)IX98v0tJ8Z4ZozilvL=~H(K-*^z<%yXUgX1G_HUj<%f^GYK4POq zoYTJ$>V`E$U)AVn8sdinm%L_Q&)v_}B|BP-`xdQxSw^P@OD%$-p`b?R%L+Qr@wKFI z8q(G{ENV@PZ=tu8`O8#K|-)a^uN%Y4MrJxmpEiueOxsgNs^N7t~lo)uEL;vY0W zXfz*90)Upikeg)HIzK`KcYJH*o{Ck$3fenJi*gjCx&8|2qH(x=(?iQ<)U8 zyRl;G>DFi=;X~z8HpS|pmNxU@F-s%yo|JSP9$bbV5PqIOJ;Sta4JZrnbF0adnUiq~ z&9;K+wuOZ+;D`3 zpt-*`@f5AAI82cv7KUWkXV zuPFTnX6&V>gsS~0c$y2Y>XTsi1Q!0m@@&ecCz}Qpi<{vbh)M^-4k_cV-(l&6e3!Il zv>0j}zSdZ^00l(FV9=Jdij`ezCujAp-_xFb#3$P3u@TKPlu~WhSkOC^-KwqcRsB<2 z6S|Zcbh+`4c}dW&DT}2*X8f$>s5DW08DjU`LGEqNc4z%gsH)e;fl2a0!)AH}LF+8; z030#&IffEQd+4ooudUOrLAnm?nu*ov>5!t)N{#4z`*DSJSGg^P;0V_&5UwsFc9`ol zr??}hFuSV_KYeDY@BK7ULbSF$4q@zFq8=bOo;Ds69>K(2{+H~!E<(w> z*H4M!Ynwb|=VGcX*) zEO~(jR-8I`Zt6)bI|x8ii5ookY-$~c3ZU?AB*~Iwj?+Bf)2>Ik4iAV_`*2ZR zCJCCFUI$St5BBtv8*Z9CNCc_SqmoRSY?y#fxIrEiY|%&Xz9OamIos9O8}%m zB6j)4K2($!E5U{SEbE2nt}Y^{P|RuURyD(Xh9C0N%UvXDLRR_QsJJ}kEfymrH8D?h zb|^l>ew~GUG#HByZxe{>lBOeGy`x?X6^T8dNc=t6B!Y3JI)2cwwGh39)(5>`kwcVF z^EJ#A4SqY9rRS13A`fKsi+{ST{#5a^2QJb5uHV45&l&WdJ*-f>M%JS9v&AXQKSQ-# z4m7_TwW8CxJ`dR6)-~SUUC$oQwBG>KsC)wuNZYJ9YRXPcq9)|$Evj{7Xo%MW4e@%i zatw4$vl{Kp7rXm2Rm5+FdSn0`p3;zMtO#$f<@EWmIyl1Tc|2|b5OHmzgZS*VzEN2b z<~Fqd*G4#3i6Dkh(h`ddj2Jhe+-TZw z)7$`F+5sjU3nnmVz@AVpa?9Ghrnb2oN|9PZFwfdMPMUP%H;x-8z?>|Bn-|VH?ZXOO zuFcw+eGm%Z4#S?!?EIBdFBHh_Z&pRQ&+}dyY^qyEDuwreQ3Z{U=5WAQ4jm6WG}|Jxgs9C6-OB zh0>mOd}?dBdSdFA#P{%(+Nc-M1NWjhNhNfoR+IV|d*c!zT|OE=a{oJxle(;Yaw_?) zitJE@EV8^kI<$i0V-its51=EG7XqQF9;ACKFS%r;AUk>Zvc3O4bXQNa{gXSv1WScf zPYhugF1+ud$*eUFK=mAf^W+_w6B_)ni0#@Nk3;UIew{d&7K^3SUK);P>s~I0)4(vB zc|RqZYUlVjoA6MJ0P!30`&|_4#MD_8GESy-bxk9I;ZE;pvfXy{)PeL3$f=S*Xr!IY zE2WMZxDvi)&1vE8jdQx4`W;tQYqYgOQlS$U&e(<6IX!)_Q6ULwFAaz9R!k|;>Q^)0 zVJZtlZ3wn2XkmPT@|M|gKP0?pWDJvjr}jaF_KdOG=UgOTI^^BiuHhJS<-E$$)OcUR zu@f%1o~!#4!`vD+{lsocY-3j-PZ_q?FaO9Td#~}VD;%raD)r*86iPMhu;`oSZ=Ga! zZDV=%Z;fAd%X_2cu_aRcVaK5RyRel za`P#>{SCK`{wVEhuku$<`A?O!*LDgO~o>orL zKY%4eFkuTIy6l8lEgO>Pvdi%W9#qWe5&%C>@b6FFg+G{fh(d_NsHNsGTCBNd=$q4- zzyy;{J0Ke@JCRT-#54CMfY?50ctzuqnsfk)f4C$52dGcR|6Z*HK>)PU(K30v9mlM$ zx8ZD~(*N&~k6Wc2d=5ZYOrFdX;#ma9cLcLPAS@GAmj#C9+xJYQiU<+9v`TE8K%`CK z1hBjick4%0p7Nf%gD~*-w5wPx^YWQjb^qW{{$;@7Jg_Ie(dGduht?pk^g2js;lANk zus`9B`o8G}Z3e?7P1*_OLM31>@tn{-Q+jO$*Mdtko~hZOiuH_ zL2?h#qk$jeXDCiRBilJY6QL=$0V38v(d$d*$N<3o&j9Y1#=pL+^u?X6yp;|IMl3fm zpl$NVw2qV6qamZx^9=Y+8m*jAQW{u+xZG2yQSc-{7PkiCFj%r}G{5S(kayU6Y;>Xv zBx7&39Vfbc0)4Rn2+ZuhPbrC>xB-7KI)AzFsj$!Bo4LaVFGMGb!o^fW^@YM)iR-v7S7`XcNY;fn%hzVp)r>2o|ruKn1-(O@=)UNgLK_sXl4eXkq4&+ z=2oe8#F$fS6iF>#Y3!S|2Vnas|uOFPt>^+t9)}g%WDc8|15N9+)^KO!<`X1rhnzT@rjk zb|GQppG#s(u-N`tl6H9FN-$A&F)GAr{wLjOMi_Na*)yw2y7-vdeHNbEQ#FyR+LvN^ z?5th`in|e%kpJL1=Ioju^o#p_16B&2<~G|5gf>d(^q&aAKR66GJw6~<8rWmA!UT1u zGQJjtWgC{z`hNf|%Hnp%z*F7FYF()C*g~sHV?hJ$6gju5T&D^Z@@2f6MW}f#B*clntDs`tgL#Oy;0Uw*5(@9SoJ)UseY% z)r7iL+dLdb$~&jz>c7CJMYHkP2jcPKXEPY$&q^_ z%|Xa1#ImkOeU4svi;@6-Zj|*63Wv0RW=W>j9HY1 z{=?S_%dn7p?ff)EPRI=M$qm(SBQT9X@VCuwU@L}iV#bz3)iO?uzx2MlU=rdfc0l^L zKVNKmJ+A+N=Q@l+cwrR^mmEIQ@@?T{m%P_vbIh+czv9OCM;+`^(M#rpZA(~>FE11)q&Awg9rrs_^hx{Cy9qj_I9FrazXnX7 zh7IzdY-`^o54V9aQ_-BhGw4v4ewkppyMyg)M|cGP%o)6o0SJXiQ(f@YKYEt1kLo@1Ywufaj-2kbg~7kuA(yV8m63 z02YhrIaw!n@ou62XM)c5HwCg&& z>lEA->eMrnqdwm;-YJ@FSKSs;uNg%NA2XW^#R_?^oB1s$&Ex!T0e6hJo0@nZoU?S+ z*gVH<*fF4_#s2w*t?Z{`spZSyo`4w}r^8L<@OS&89t?bmA#Ryz?F`Ex_vIQlYQ-n) zw(4K$U)HOhRn_6XOl|dueo_;Ra><-Am`{H|C=IYp9twA}u}}H%B*!-IWwe&lMXNn6 z4N%K}?8p%mDKld`O{DfZKxbQ+ap2!)=khrL%a9U{Rd;0=bA9 zRh__TO0?d5beR9TxZnn8vdDuwK2vPD$DauHmL%7ODa%P4Pn2crJD;dB!`@Xk-=BNw zA3?K*i94g)u|T2(P5Gb5&Bm($M74i9{=iuA^gz?@qS7mN7Af(rmi~rSf)miE?+#8# z9gupaW)-_jNJ5aA7O3PrhcFiaC8lmCXEgG&cV8GMq~cU9-u~c0DXi5GF3n zgy#EA01LJH94^XAT48AR`*reqyIL6&=mIKFPuuR!cv6#)TWo;p!B!H3IdqQS@{f>R z?8AG5?$tzUDWhYrtD?^}PC9#M z?#$|pmuPguW1@*_evU4ERaka|&;G{aLR5N}h|V?h9@y+BVO`LmAiz;FmVQ>u-A7A% z)V@0F9CIkMmqPQG-?5U-O}rlZxp605Ua_YCMjrVeSv>Gx>XD!g2fa)Cy&uY@TtJ2K zu|skG-wf^su}@FR(kdGqTVb`{wF#3|0C_YV|tmlW<^(;l`Ax~nNeCG;S>Via8#$m^61wdxO27N z4Sexe5a@9WwCS8_`;EEc@J&!0nvVRc%S@XAyn-+6O0eyKoHlDHcMMwx`!nUk2sTht z|1Uj}+jdXApm_Qzfk$2v&T?eh`k_9$!fKujy>B)fMz%OEMZ$V0#iqWsaakK{378h| z29fxv_^n|lINSSwy7qZ`%TpMmBHj(x=-!tKYcWJ1e=2Td$OhiDQ@)k{tNl@vcsrp> zUt4VHi-RA@ksZd*=zra=Bv;1+VY)+&>5^RT5>|L5;d39B>Zh>qcQ8wmewCc0iLbToS(T)`r3>Iow8mGyw)zbPMD>|kC;N^h*D=%m& z<^YfIbr?&)jUj~Y^?9zU)M5(<^y|-Y4(+9TU4wDU78(=Uz+yMb35oqM6J!9I&eqh) zx8?L(pacF9WRsXbog~;e@2QvQxiBnq@wj zk|`hbpvuEs(|cPOsVarkCkKdt&3;Ae#RMFUWkA?+Tk>sK$0|V~IBZ~Elo))`*J5Hc zIJmN?X!6H%6_D3^D0e!%23v4{qAgBfmw;bI@*tE|$bBWgfo)6KYF{bR`3EvFt? z^W&!7X6k(<8{JcI4l3S86{2y&iJ?(Akdnr{O!_-8xCM`@qBc1-3J=lx&p_caG?QkH z67&=09jkPAp($lFQdpW;`l@KL%~vUeyp1_NX>r@P&>Z(Skc8D;#jJA_#oBmZ{RPar zo!~}>uVulKAwp_S4?LGzpUAvmZOWXZSjQjXwWvV*TxQA+WXM5%T^`7VH8n zIS9P3-+3Ez?{Y%(n9Gs9du&4Ej&Ths7#aRb?G(hv7d;TT1UsxKC%{pnSkDjjvBXQv z*bbkPV8VHJ)1t1^veq1mFS-{*p;OLdQOI)%6qXh2tO}~Xu4_82mRBxv)>i5#9D)+C zT%)L884$l%Wj*h(+h$V?(CCL7$tSHg;Di}fS~UN*`8k$0SNbun3S{WR(V)rDF2`>; z>0HGPun$xlKdc{4(pH_2ckVKKHQH=)#rR+q#c~+D>nsqAx})2oM-l$3L_`K7OF zT+q}rFfnw!DxoQkE~OhY#(WCsHT(nQ;nY8!)~P#BhNYQm)9EmV%_DWcYQI3nWO5Nf z(IJJ}F_|Jv0q^2ja}t@*UWp@j&VnN(WnMw0b2A5DZ@Y%LL_FV_B;cCvS*%j zxyF-Kb(~#+n2b)Fo@R3m9k|qq4)F7JJzJ`LB{TWDtkj{;yS75P?4wC{{^f}WL_@qU zF1=xRY#+@}^RO@e>BL`#uQgws(TQ@uJKOT2)sNK@g5t{$11H59E!cv=)B>&hL~Kd+ zqNy}GaEGk>#v+G%jeD|_6+>TU!&x`*F=1c>kqS!P(CV}$PZHe3q2#500qdC7iL5$A zBDdG(CtCbr5(+99eO=>e*2$-og?7k`TlS}mQ}Yi`?UGA^`Dqim4&!l_Iopx7UpG(b zZoS7$2W;Z}v^h$9RU6p2*D3;(Hf(m|-do=bqMs z6h-^l`o@()uosIy5&?X+{Cvn~>)AU?#T1`poT{^>A6?|a_C$OSJI*5#^x%PjV;aH2 zE6~1k~T;J0w{S5Y6oxbs@=iIKF@y$UmQL%vkt%v{eQ61felR?fAVuJs5b1!#2)Z z6(RmqevugvPyk{t+WJ8Zm>u5(LU_lvm92Ec`0lKH^rH4`)2|NPizfniQkN=lBh^HT zmz%IE)0RFyX)s--cVMc6p@ga;r{6ZrL;H7-T%_4{)Vz{ zXa0>w7FZ8-&Cx4o4b$$1*A>KK*`m@s5_Yn7biy7y7m!&~2jXPI41q6C>t^ddL zXe_>Dl8qnMgV`R=hnGjdpTfn@=;bG>{S~fZM^X#IfQ31?3NVo;+`6}D-XnrVR#!EJ z`Z<26k+xwl1X7*vo*rG#Wt`o*&I0!{8`3?Ww zbD^mJ!1qLrB~u=@Zl>K4&-O9ak+@B>iV19cIYX|Nw6PUEx3AUOq)5r^ay8|spr=kT z(?N%6I@E8673qMmEu8C`jUoO6>Y#PN=*>6Js^MyLbpsO*j!EyaD7z*tB-#*U0&oL^ z=4~WO4ME2}w(qUO(BOQ_<`)#%f+&9B4(*dM*Yg;6r;}o@h)` z1RzXz{P_kV>mOIeYiTS=FipORGBss^b&X9fY4lSMFDT+cHb$F+Fx;`o5rHsn=rQ~F z^=QHy7y`uqZG&WOCY)_t4)n%FLSk%M+ZQb~zIJ9ofdu8r;rIG|wR2Grt^z^bH0^iM zdGe@5I_Qcx+B2pJUCnuY1fuNfGIxp_&KV(Skku4NIyW8;?zB$Me|;aZka zdjCMCoX}2(K?`?`8^KNt(>^%?Ro2S2fn6)*e#JcM1trhTbs}LF-jX!hUJZZL3l# z+(UQ|jkpX{m#l8i1b&>Il&{^!@ssI7yj$-Ahx?1&qBpI3IV%NULCJkI%Dgw*Tt2gM zsQL>riAx>V&Nn2u5=t1+Ja!Hc&$rcp!SrEhFsG=Z9;%VoF4mr?u0pABeX=A>ZNX&Beq&!+WbAWSV}Q>wdG3i!|s z!EI8w#*r~&2&f5+1$CzIPZ#CD_48Oilpv4|xMK)~s5C2u7R&Bwa*y6hbBE3c>KEBN z(Aim2Kjp!aL4%%|1fLa9ln70$;Q^r9)Myfaby^y4BJkF*cxqGfl1k@-#yvP&yqV7z zvn$$@P{Zco3l35Jr(g+@KYB#i{KyibcEZ{(;SBZIdE}uWnq7p>p5YKq9`)r zJO4)O1X6gb8;q`GMq-Kb63`C5jt z8KqC7$JNoN3u6=e)KOjyp%H8&!2^8sFMjqqz>&A0ntROd( z4Xn_zHe@uk&g?4r%0aHzjy(991QxmqS5Czlp%oYnY|8iux&8k7)$PGYeY}Cw+^>6P z8EgH=_h=o5)+oY{6lIjnFRkjNqYG_%JzZW|+U2hW2VLtmQ!A+Mwa0-jes-x_BJxYM zei%`IsrQvmkxKJUPyd8`iBjI{J|u>G!w;NEQDG{II}R?(Cul21h)w9`!F4a~nh9I8 z_Onp1^2Wj5G=bS7SRWi#WaG@Sp0eZo>v)u?Kz6uGm*5(jo-k=A&1ovTR5=ZJ?ySr6 z>xj{DX>ojVovbGIyGyNfz8&!qEgB5Bw^@)9k^i7!W{0J8eO;-n803#L0MkE=tLg%q zt@L2?!g=6VM-Lg=6HQU6T}lDj_iF-F!scT2*N*Wb(<_#2q$Znwlq_B#V?aXr!fZc` zs~HMW$ILcPMc%t-rN9*mS2qSh)8LD-odUPE;X?o*fq%Y6{?zZaR%2qAP@0qYJq!m? zO;o_ArV%=%#VhhH)TcsR-^ot%W|r0JVL>f5502gMP5_q@6mvU}oPXV6o`W=`JiI0pyT z^2A5_`bT1s`(2q1DgYFqc&#}@18o%3WP40taeX2_HNI(Kq694DZwdxBb}0N<7KSkPvO8%z6uBgTii3y)z4UcVfVOM?lM~pTNIAc)RrZ z@WYyLE`ZN8%=sUU=g9nf85Wa4KXok_AwE`kh;qMY`MF#lkkg zyLZj-?!1TDdx=wNTk)j?t^@_T`EBDHS(X|~dR|8q$H!xr#2eE%aTU}sGHxD07dG3| zV@obwNpgByR8J{S?lO zaB~7m+;N(D!8H3*<|Ko!LUKq*)BNv6X1RSH^^5QT@`9g{;D7k>3}$oC2bKTad+dJ$ Dp_D#! diff --git a/docs/dd/dc4/classshaka_1_1media_1_1ProducerConsumerQueue-members.html b/docs/dd/dc4/classshaka_1_1media_1_1ProducerConsumerQueue-members.html index 92171203da..786714d243 100644 --- a/docs/dd/dc4/classshaka_1_1media_1_1ProducerConsumerQueue-members.html +++ b/docs/dd/dc4/classshaka_1_1media_1_1ProducerConsumerQueue-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    diff --git a/docs/dd/dc5/classshaka_1_1media_1_1webm_1_1Segmenter.html b/docs/dd/dc5/classshaka_1_1media_1_1webm_1_1Segmenter.html index 1d456925fe..0e78fc1861 100644 --- a/docs/dd/dc5/classshaka_1_1media_1_1webm_1_1Segmenter.html +++ b/docs/dd/dc5/classshaka_1_1media_1_1webm_1_1Segmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::webm::Segmenter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::webm::MultiSegmentSegmenter shaka::media::webm::SingleSegmentSegmenter shaka::media::webm::TwoPassSingleSegmentSegmenter - -
    + + @@ -127,7 +130,7 @@ uint64_t  - + @@ -190,7 +193,7 @@ virtual Status&#
    Returns
    OK on success, an error status otherwise.
    -

    Definition at line 159 of file segmenter.cc.

    +

    Definition at line 161 of file segmenter.cc.

    @@ -230,7 +233,7 @@ virtual Status&#
    Returns
    The total length, in seconds, of segmented media files.
    -

    Definition at line 205 of file segmenter.cc.

    +

    Definition at line 207 of file segmenter.cc.

    @@ -363,9 +366,7 @@ virtual Status&# diff --git a/docs/dd/dc7/classshaka_1_1media_1_1DvbSubParser-members.html b/docs/dd/dc7/classshaka_1_1media_1_1DvbSubParser-members.html new file mode 100644 index 0000000000..901fd70234 --- /dev/null +++ b/docs/dd/dc7/classshaka_1_1media_1_1DvbSubParser-members.html @@ -0,0 +1,88 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    +

    Public Member Functions

     
    void UpdateProgress (uint64_t progress)
     Update segmentation progress using ProgressListener.
     Update segmentation progress using ProgressListener.
     
    void set_progress_target (uint64_t target)
    + + + + + +
    +
    Shaka Packager SDK +
    +
    + + + + + + + + + +
    +
    + + +
    + +
    + + + +
    +
    +
    shaka::media::DvbSubParser Member List
    +
    +
    + +

    This is the complete list of members for shaka::media::DvbSubParser, including all inherited members.

    + + + + + + + + +
    DvbSubParser() (defined in shaka::media::DvbSubParser)shaka::media::DvbSubParser
    DvbSubParser(const DvbSubParser &)=delete (defined in shaka::media::DvbSubParser)shaka::media::DvbSubParser
    DvbSubParserTest (defined in shaka::media::DvbSubParser)shaka::media::DvbSubParserfriend
    Flush(std::vector< std::shared_ptr< TextSample >> *samples) (defined in shaka::media::DvbSubParser)shaka::media::DvbSubParser
    operator=(const DvbSubParser &)=delete (defined in shaka::media::DvbSubParser)shaka::media::DvbSubParser
    Parse(DvbSubSegmentType segment_type, int64_t pts, const uint8_t *payload, size_t size, std::vector< std::shared_ptr< TextSample >> *samples) (defined in shaka::media::DvbSubParser)shaka::media::DvbSubParser
    ~DvbSubParser() (defined in shaka::media::DvbSubParser)shaka::media::DvbSubParser
    + + + + diff --git a/docs/dd/dca/structshaka_1_1media_1_1mp4_1_1OriginalFormat-members.html b/docs/dd/dca/structshaka_1_1media_1_1mp4_1_1OriginalFormat-members.html index 6308925567..3557b2e4e3 100644 --- a/docs/dd/dca/structshaka_1_1media_1_1mp4_1_1OriginalFormat-members.html +++ b/docs/dd/dca/structshaka_1_1media_1_1mp4_1_1OriginalFormat-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/dd2/buffer__writer_8h_source.html b/docs/dd/dd2/buffer__writer_8h_source.html index 369a2a51d1..c5ebfc1ad9 100644 --- a/docs/dd/dd2/buffer__writer_8h_source.html +++ b/docs/dd/dd2/buffer__writer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/buffer_writer.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    buffer_writer.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_BUFFER_WRITER_H_
    8 #define PACKAGER_MEDIA_BASE_BUFFER_WRITER_H_
    9 
    10 #include <vector>
    11 
    12 #include "packager/base/macros.h"
    13 #include "packager/status.h"
    14 
    15 namespace shaka {
    16 
    17 class File;
    18 
    19 namespace media {
    20 
    23 class BufferWriter {
    24  public:
    25  BufferWriter();
    30  explicit BufferWriter(size_t reserved_size_in_bytes);
    31  ~BufferWriter();
    32 
    36  void AppendInt(uint8_t v);
    37  void AppendInt(uint16_t v);
    38  void AppendInt(uint32_t v);
    39  void AppendInt(uint64_t v);
    40  void AppendInt(int16_t v);
    41  void AppendInt(int32_t v);
    42  void AppendInt(int64_t v);
    44 
    48  void AppendNBytes(uint64_t v, size_t num_bytes);
    49 
    50  void AppendVector(const std::vector<uint8_t>& v);
    51  void AppendString(const std::string& s);
    52  void AppendArray(const uint8_t* buf, size_t size);
    53  void AppendBuffer(const BufferWriter& buffer);
    54 
    55  void Swap(BufferWriter* buffer) { buf_.swap(buffer->buf_); }
    56  void SwapBuffer(std::vector<uint8_t>* buffer) { buf_.swap(*buffer); }
    57 
    58  void Clear() { buf_.clear(); }
    59  size_t Size() const { return buf_.size(); }
    61  const uint8_t* Buffer() const { return buf_.data(); }
    62 
    67  Status WriteToFile(File* file);
    68 
    69  private:
    70  // Internal implementation of multi-byte write.
    71  template <typename T>
    72  void AppendInternal(T v);
    73 
    74  std::vector<uint8_t> buf_;
    75 
    76  DISALLOW_COPY_AND_ASSIGN(BufferWriter);
    77 };
    78 
    79 } // namespace media
    80 } // namespace shaka
    81 
    82 #endif // PACKAGER_MEDIA_BASE_BUFFER_WRITER_H_
    const uint8_t * Buffer() const
    Definition: buffer_writer.h:61
    -
    Define an abstract file interface.
    Definition: file.h:26
    -
    All the methods that are virtual are virtual for mocking.
    - - - -
    void AppendNBytes(uint64_t v, size_t num_bytes)
    -
    Status WriteToFile(File *file)
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_BUFFER_WRITER_H_
    +
    8 #define PACKAGER_MEDIA_BASE_BUFFER_WRITER_H_
    +
    9 
    +
    10 #include <vector>
    +
    11 
    +
    12 #include "packager/base/macros.h"
    +
    13 #include "packager/status.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 
    +
    17 class File;
    +
    18 
    +
    19 namespace media {
    +
    20 
    +
    23 class BufferWriter {
    +
    24  public:
    +
    25  BufferWriter();
    +
    30  explicit BufferWriter(size_t reserved_size_in_bytes);
    +
    31  ~BufferWriter();
    +
    32 
    +
    36  void AppendInt(uint8_t v);
    +
    37  void AppendInt(uint16_t v);
    +
    38  void AppendInt(uint32_t v);
    +
    39  void AppendInt(uint64_t v);
    +
    40  void AppendInt(int16_t v);
    +
    41  void AppendInt(int32_t v);
    +
    42  void AppendInt(int64_t v);
    +
    44 
    +
    48  void AppendNBytes(uint64_t v, size_t num_bytes);
    +
    49 
    +
    50  void AppendVector(const std::vector<uint8_t>& v);
    +
    51  void AppendString(const std::string& s);
    +
    52  void AppendArray(const uint8_t* buf, size_t size);
    +
    53  void AppendBuffer(const BufferWriter& buffer);
    +
    54 
    +
    55  void Swap(BufferWriter* buffer) { buf_.swap(buffer->buf_); }
    +
    56  void SwapBuffer(std::vector<uint8_t>* buffer) { buf_.swap(*buffer); }
    +
    57 
    +
    58  void Clear() { buf_.clear(); }
    +
    59  size_t Size() const { return buf_.size(); }
    +
    61  const uint8_t* Buffer() const { return buf_.data(); }
    +
    62 
    +
    67  Status WriteToFile(File* file);
    +
    68 
    +
    69  private:
    +
    70  // Internal implementation of multi-byte write.
    +
    71  template <typename T>
    +
    72  void AppendInternal(T v);
    +
    73 
    +
    74  std::vector<uint8_t> buf_;
    +
    75 
    +
    76  DISALLOW_COPY_AND_ASSIGN(BufferWriter);
    +
    77 };
    +
    78 
    +
    79 } // namespace media
    +
    80 } // namespace shaka
    +
    81 
    +
    82 #endif // PACKAGER_MEDIA_BASE_BUFFER_WRITER_H_
    +
    Define an abstract file interface.
    Definition: file.h:27
    + + +
    Status WriteToFile(File *file)
    + +
    const uint8_t * Buffer() const
    Definition: buffer_writer.h:61
    +
    void AppendNBytes(uint64_t v, size_t num_bytes)
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/dd3/buffer__writer_8cc_source.html b/docs/dd/dd3/buffer__writer_8cc_source.html index 2e3913e67e..36af80e714 100644 --- a/docs/dd/dd3/buffer__writer_8cc_source.html +++ b/docs/dd/dd3/buffer__writer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/buffer_writer.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    buffer_writer.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/buffer_writer.h"
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/base/sys_byteorder.h"
    11 #include "packager/file/file.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 BufferWriter::BufferWriter() {
    17  const size_t kDefaultReservedCapacity = 0x40000; // 256KB.
    18  buf_.reserve(kDefaultReservedCapacity);
    19 }
    20 BufferWriter::BufferWriter(size_t reserved_size_in_bytes) {
    21  buf_.reserve(reserved_size_in_bytes);
    22 }
    23 BufferWriter::~BufferWriter() {}
    24 
    25 void BufferWriter::AppendInt(uint8_t v) {
    26  buf_.push_back(v);
    27 }
    28 void BufferWriter::AppendInt(uint16_t v) {
    29  AppendInternal(base::HostToNet16(v));
    30 }
    31 void BufferWriter::AppendInt(uint32_t v) {
    32  AppendInternal(base::HostToNet32(v));
    33 }
    34 void BufferWriter::AppendInt(uint64_t v) {
    35  AppendInternal(base::HostToNet64(v));
    36 }
    37 void BufferWriter::AppendInt(int16_t v) {
    38  AppendInternal(base::HostToNet16(v));
    39 }
    40 void BufferWriter::AppendInt(int32_t v) {
    41  AppendInternal(base::HostToNet32(v));
    42 }
    43 void BufferWriter::AppendInt(int64_t v) {
    44  AppendInternal(base::HostToNet64(v));
    45 }
    46 
    47 void BufferWriter::AppendNBytes(uint64_t v, size_t num_bytes) {
    48  DCHECK_GE(sizeof(v), num_bytes);
    49  v = base::HostToNet64(v);
    50  const uint8_t* data = reinterpret_cast<uint8_t*>(&v);
    51  AppendArray(&data[sizeof(v) - num_bytes], num_bytes);
    52 }
    53 
    54 void BufferWriter::AppendVector(const std::vector<uint8_t>& v) {
    55  buf_.insert(buf_.end(), v.begin(), v.end());
    56 }
    57 
    58 void BufferWriter::AppendString(const std::string& s) {
    59  buf_.insert(buf_.end(), s.begin(), s.end());
    60 }
    61 
    62 void BufferWriter::AppendArray(const uint8_t* buf, size_t size) {
    63  buf_.insert(buf_.end(), buf, buf + size);
    64 }
    65 
    66 void BufferWriter::AppendBuffer(const BufferWriter& buffer) {
    67  buf_.insert(buf_.end(), buffer.buf_.begin(), buffer.buf_.end());
    68 }
    69 
    71  DCHECK(file);
    72  DCHECK(!buf_.empty());
    73 
    74  size_t remaining_size = buf_.size();
    75  const uint8_t* buf = &buf_[0];
    76  while (remaining_size > 0) {
    77  int64_t size_written = file->Write(buf, remaining_size);
    78  if (size_written <= 0) {
    79  return Status(error::FILE_FAILURE,
    80  "Fail to write to file in BufferWriter");
    81  }
    82  remaining_size -= size_written;
    83  buf += size_written;
    84  }
    85  buf_.clear();
    86  return Status::OK;
    87 }
    88 
    89 template <typename T>
    90 void BufferWriter::AppendInternal(T v) {
    91  AppendArray(reinterpret_cast<uint8_t*>(&v), sizeof(T));
    92 }
    93 
    94 } // namespace media
    95 } // namespace shaka
    virtual int64_t Write(const void *buffer, uint64_t length)=0
    -
    Define an abstract file interface.
    Definition: file.h:26
    -
    All the methods that are virtual are virtual for mocking.
    - - - -
    void AppendNBytes(uint64_t v, size_t num_bytes)
    -
    Status WriteToFile(File *file)
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/buffer_writer.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/base/sys_byteorder.h"
    +
    11 #include "packager/file/file.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 BufferWriter::BufferWriter() {
    +
    17  const size_t kDefaultReservedCapacity = 0x40000; // 256KB.
    +
    18  buf_.reserve(kDefaultReservedCapacity);
    +
    19 }
    +
    20 BufferWriter::BufferWriter(size_t reserved_size_in_bytes) {
    +
    21  buf_.reserve(reserved_size_in_bytes);
    +
    22 }
    +
    23 BufferWriter::~BufferWriter() {}
    +
    24 
    +
    25 void BufferWriter::AppendInt(uint8_t v) {
    +
    26  buf_.push_back(v);
    +
    27 }
    +
    28 void BufferWriter::AppendInt(uint16_t v) {
    +
    29  AppendInternal(base::HostToNet16(v));
    +
    30 }
    +
    31 void BufferWriter::AppendInt(uint32_t v) {
    +
    32  AppendInternal(base::HostToNet32(v));
    +
    33 }
    +
    34 void BufferWriter::AppendInt(uint64_t v) {
    +
    35  AppendInternal(base::HostToNet64(v));
    +
    36 }
    +
    37 void BufferWriter::AppendInt(int16_t v) {
    +
    38  AppendInternal(base::HostToNet16(v));
    +
    39 }
    +
    40 void BufferWriter::AppendInt(int32_t v) {
    +
    41  AppendInternal(base::HostToNet32(v));
    +
    42 }
    +
    43 void BufferWriter::AppendInt(int64_t v) {
    +
    44  AppendInternal(base::HostToNet64(v));
    +
    45 }
    +
    46 
    +
    47 void BufferWriter::AppendNBytes(uint64_t v, size_t num_bytes) {
    +
    48  DCHECK_GE(sizeof(v), num_bytes);
    +
    49  v = base::HostToNet64(v);
    +
    50  const uint8_t* data = reinterpret_cast<uint8_t*>(&v);
    +
    51  AppendArray(&data[sizeof(v) - num_bytes], num_bytes);
    +
    52 }
    +
    53 
    +
    54 void BufferWriter::AppendVector(const std::vector<uint8_t>& v) {
    +
    55  buf_.insert(buf_.end(), v.begin(), v.end());
    +
    56 }
    +
    57 
    +
    58 void BufferWriter::AppendString(const std::string& s) {
    +
    59  buf_.insert(buf_.end(), s.begin(), s.end());
    +
    60 }
    +
    61 
    +
    62 void BufferWriter::AppendArray(const uint8_t* buf, size_t size) {
    +
    63  buf_.insert(buf_.end(), buf, buf + size);
    +
    64 }
    +
    65 
    +
    66 void BufferWriter::AppendBuffer(const BufferWriter& buffer) {
    +
    67  buf_.insert(buf_.end(), buffer.buf_.begin(), buffer.buf_.end());
    +
    68 }
    +
    69 
    + +
    71  DCHECK(file);
    +
    72  DCHECK(!buf_.empty());
    +
    73 
    +
    74  size_t remaining_size = buf_.size();
    +
    75  const uint8_t* buf = &buf_[0];
    +
    76  while (remaining_size > 0) {
    +
    77  int64_t size_written = file->Write(buf, remaining_size);
    +
    78  if (size_written <= 0) {
    +
    79  return Status(error::FILE_FAILURE,
    +
    80  "Fail to write to file in BufferWriter");
    +
    81  }
    +
    82  remaining_size -= size_written;
    +
    83  buf += size_written;
    +
    84  }
    +
    85  buf_.clear();
    +
    86  return Status::OK;
    +
    87 }
    +
    88 
    +
    89 template <typename T>
    +
    90 void BufferWriter::AppendInternal(T v) {
    +
    91  AppendArray(reinterpret_cast<uint8_t*>(&v), sizeof(T));
    +
    92 }
    +
    93 
    +
    94 } // namespace media
    +
    95 } // namespace shaka
    +
    Define an abstract file interface.
    Definition: file.h:27
    +
    virtual int64_t Write(const void *buffer, uint64_t length)=0
    + +
    Status WriteToFile(File *file)
    + +
    void AppendNBytes(uint64_t v, size_t num_bytes)
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/dd6/classshaka_1_1media_1_1WebMVideoClient-members.html b/docs/dd/dd6/classshaka_1_1media_1_1WebMVideoClient-members.html index 06427bdaaa..22fea2d60f 100644 --- a/docs/dd/dd6/classshaka_1_1media_1_1WebMVideoClient-members.html +++ b/docs/dd/dd6/classshaka_1_1media_1_1WebMVideoClient-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/dd8/mock__muxer__listener_8cc_source.html b/docs/dd/dd8/mock__muxer__listener_8cc_source.html index 7933e9e8db..20a4114666 100644 --- a/docs/dd/dd8/mock__muxer__listener_8cc_source.html +++ b/docs/dd/dd8/mock__muxer__listener_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/mock_muxer_listener.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    mock_muxer_listener.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/event/mock_muxer_listener.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 
    12 MockMuxerListener::MockMuxerListener() {}
    13 MockMuxerListener::~MockMuxerListener() {}
    14 
    16  float duration_seconds) {
    17  const bool has_init_range = static_cast<bool>(range.init_range);
    18  Range init_range = {};
    19  if (has_init_range) {
    20  init_range = range.init_range.value();
    21  }
    22  const bool has_index_range = static_cast<bool>(range.index_range);
    23  Range index_range = {};
    24  if (has_index_range) {
    25  index_range = range.index_range.value();
    26  }
    27 
    28  OnMediaEndMock(has_init_range, init_range.start, init_range.end,
    29  has_index_range, index_range.start, index_range.end,
    30  !range.subsegment_ranges.empty(), range.subsegment_ranges,
    31  duration_seconds);
    32 }
    33 
    34 } // namespace media
    35 } // namespace shaka
    base::Optional< Range > init_range
    Range of the initialization section of a segment.
    -
    base::Optional< Range > index_range
    Range of the index section of a segment.
    - -
    All the methods that are virtual are virtual for mocking.
    - - -
    void OnMediaEnd(const MediaRanges &range, float duration_seconds) override
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/event/mock_muxer_listener.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 
    +
    12 MockMuxerListener::MockMuxerListener() {}
    +
    13 MockMuxerListener::~MockMuxerListener() {}
    +
    14 
    + +
    16  float duration_seconds) {
    +
    17  const bool has_init_range = static_cast<bool>(range.init_range);
    +
    18  Range init_range = {};
    +
    19  if (has_init_range) {
    +
    20  init_range = range.init_range.value();
    +
    21  }
    +
    22  const bool has_index_range = static_cast<bool>(range.index_range);
    +
    23  Range index_range = {};
    +
    24  if (has_index_range) {
    +
    25  index_range = range.index_range.value();
    +
    26  }
    +
    27 
    +
    28  OnMediaEndMock(has_init_range, init_range.start, init_range.end,
    +
    29  has_index_range, index_range.start, index_range.end,
    +
    30  !range.subsegment_ranges.empty(), range.subsegment_ranges,
    +
    31  duration_seconds);
    +
    32 }
    +
    33 
    +
    34 } // namespace media
    +
    35 } // namespace shaka
    +
    void OnMediaEnd(const MediaRanges &range, float duration_seconds) override
    +
    All the methods that are virtual are virtual for mocking.
    + +
    base::Optional< Range > init_range
    Range of the initialization section of a segment.
    + +
    base::Optional< Range > index_range
    Range of the index section of a segment.
    +
    diff --git a/docs/dd/dd9/structshaka_1_1media_1_1mp4_1_1Box-members.html b/docs/dd/dd9/structshaka_1_1media_1_1mp4_1_1Box-members.html index 94260a8c8d..cb8d2d1746 100644 --- a/docs/dd/dd9/structshaka_1_1media_1_1mp4_1_1Box-members.html +++ b/docs/dd/dd9/structshaka_1_1media_1_1mp4_1_1Box-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/ddb/structshaka_1_1media_1_1TextSubStreamInfo.html b/docs/dd/ddb/structshaka_1_1media_1_1TextSubStreamInfo.html new file mode 100644 index 0000000000..c34539b1f9 --- /dev/null +++ b/docs/dd/ddb/structshaka_1_1media_1_1TextSubStreamInfo.html @@ -0,0 +1,97 @@ + + + + + + + +Shaka Packager SDK: shaka::media::TextSubStreamInfo Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::TextSubStreamInfo Struct Reference
    +
    +
    + +

    #include <text_stream_info.h>

    + + + + +

    +Public Attributes

    +std::string language
     
    +

    Detailed Description

    +

    Contains info about a sub-stream within a text stream. Depending on the format, some info may not be available. This info doesn't affect output.

    + +

    Definition at line 45 of file text_stream_info.h.

    +

    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/docs/dd/ddc/trick__play__handler_8h_source.html b/docs/dd/ddc/trick__play__handler_8h_source.html index aec0c63f60..a5c031c535 100644 --- a/docs/dd/ddc/trick__play__handler_8h_source.html +++ b/docs/dd/ddc/trick__play__handler_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/trick_play/trick_play_handler.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    trick_play_handler.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_TRICK_PLAY_HANDLER_H_
    8 #define PACKAGER_MEDIA_BASE_TRICK_PLAY_HANDLER_H_
    9 
    10 #include <list>
    11 
    12 #include "packager/media/base/media_handler.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 class VideoStreamInfo;
    18 
    22 // The stream data in trick play streams are not simple duplicates. Some
    23 // information get changed (e.g. VideoStreamInfo.trick_play_factor).
    25  public:
    26  explicit TrickPlayHandler(uint32_t factor);
    27 
    28  private:
    29  TrickPlayHandler(const TrickPlayHandler&) = delete;
    30  TrickPlayHandler& operator=(const TrickPlayHandler&) = delete;
    31 
    32  Status InitializeInternal() override;
    33  Status Process(std::unique_ptr<StreamData> stream_data) override;
    34  Status OnFlushRequest(size_t input_stream_index) override;
    35 
    36  Status OnStreamInfo(const StreamInfo& info);
    37  Status OnSegmentInfo(std::shared_ptr<const SegmentInfo> info);
    38  Status OnMediaSample(const MediaSample& sample);
    39  Status OnTrickFrame(const MediaSample& sample);
    40 
    41  const uint32_t factor_;
    42 
    43  uint64_t total_frames_ = 0;
    44  uint64_t total_key_frames_ = 0;
    45  uint64_t total_trick_frames_ = 0;
    46 
    47  // We cannot just send video info through as we need to calculate the play
    48  // rate using the first two trick play frames. This reference should only be
    49  // used to update the play back rate before video info is sent downstream.
    50  // After getting sent downstream, this should never be used.
    51  std::shared_ptr<VideoStreamInfo> video_info_;
    52 
    53  // We need to track the segment that most recently finished so that we can
    54  // extend its duration if there are empty segments.
    55  std::shared_ptr<SegmentInfo> previous_segment_;
    56 
    57  // Since we are dropping frames, the time that those frames would have been
    58  // on screen need to be added to the frame before them. Keep a reference to
    59  // the most recent trick play frame so that we can grow its duration as we
    60  // drop other frames.
    61  std::shared_ptr<MediaSample> previous_trick_frame_;
    62 
    63  // Since we cannot send messages downstream right away, keep a queue of
    64  // messages that need to be sent down. At the start, we use this to queue
    65  // messages until we can send out |video_info_|. To ensure messages are
    66  // kept in order, messages are only dispatched through this queue and never
    67  // directly.
    68  std::list<std::unique_ptr<StreamData>> delayed_messages_;
    69 };
    70 
    71 } // namespace media
    72 } // namespace shaka
    73 
    74 #endif // PACKAGER_MEDIA_BASE_TRICK_PLAY_HANDLER_H_
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    - -
    All the methods that are virtual are virtual for mocking.
    - -
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_TRICK_PLAY_HANDLER_H_
    +
    8 #define PACKAGER_MEDIA_BASE_TRICK_PLAY_HANDLER_H_
    +
    9 
    +
    10 #include <list>
    +
    11 
    +
    12 #include "packager/media/base/media_handler.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 class VideoStreamInfo;
    +
    18 
    +
    22 // The stream data in trick play streams are not simple duplicates. Some
    +
    23 // information get changed (e.g. VideoStreamInfo.trick_play_factor).
    + +
    25  public:
    +
    26  explicit TrickPlayHandler(uint32_t factor);
    +
    27 
    +
    28  private:
    +
    29  TrickPlayHandler(const TrickPlayHandler&) = delete;
    +
    30  TrickPlayHandler& operator=(const TrickPlayHandler&) = delete;
    +
    31 
    +
    32  Status InitializeInternal() override;
    +
    33  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    34  Status OnFlushRequest(size_t input_stream_index) override;
    +
    35 
    +
    36  Status OnStreamInfo(const StreamInfo& info);
    +
    37  Status OnSegmentInfo(std::shared_ptr<const SegmentInfo> info);
    +
    38  Status OnMediaSample(const MediaSample& sample);
    +
    39  Status OnTrickFrame(const MediaSample& sample);
    +
    40 
    +
    41  const uint32_t factor_;
    +
    42 
    +
    43  uint64_t total_frames_ = 0;
    +
    44  uint64_t total_key_frames_ = 0;
    +
    45  uint64_t total_trick_frames_ = 0;
    +
    46 
    +
    47  // We cannot just send video info through as we need to calculate the play
    +
    48  // rate using the first two trick play frames. This reference should only be
    +
    49  // used to update the play back rate before video info is sent downstream.
    +
    50  // After getting sent downstream, this should never be used.
    +
    51  std::shared_ptr<VideoStreamInfo> video_info_;
    +
    52 
    +
    53  // We need to track the segment that most recently finished so that we can
    +
    54  // extend its duration if there are empty segments.
    +
    55  std::shared_ptr<SegmentInfo> previous_segment_;
    +
    56 
    +
    57  // Since we are dropping frames, the time that those frames would have been
    +
    58  // on screen need to be added to the frame before them. Keep a reference to
    +
    59  // the most recent trick play frame so that we can grow its duration as we
    +
    60  // drop other frames.
    +
    61  std::shared_ptr<MediaSample> previous_trick_frame_;
    +
    62 
    +
    63  // Since we cannot send messages downstream right away, keep a queue of
    +
    64  // messages that need to be sent down. At the start, we use this to queue
    +
    65  // messages until we can send out |video_info_|. To ensure messages are
    +
    66  // kept in order, messages are only dispatched through this queue and never
    +
    67  // directly.
    +
    68  std::list<std::unique_ptr<StreamData>> delayed_messages_;
    +
    69 };
    +
    70 
    +
    71 } // namespace media
    +
    72 } // namespace shaka
    +
    73 
    +
    74 #endif // PACKAGER_MEDIA_BASE_TRICK_PLAY_HANDLER_H_
    + + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/dd/de1/period_8cc_source.html b/docs/dd/de1/period_8cc_source.html index fde0f96a45..c72a0ccfa8 100644 --- a/docs/dd/de1/period_8cc_source.html +++ b/docs/dd/de1/period_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/period.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    period.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/mpd/base/period.h"
    8 
    9 #include "packager/base/stl_util.h"
    10 #include "packager/mpd/base/adaptation_set.h"
    11 #include "packager/mpd/base/mpd_options.h"
    12 #include "packager/mpd/base/mpd_utils.h"
    13 #include "packager/mpd/base/xml/xml_node.h"
    14 
    15 namespace shaka {
    16 namespace {
    17 
    18 // The easiest way to check whether two protobufs are equal, is to compare the
    19 // serialized version.
    20 bool ProtectedContentEq(
    21  const MediaInfo::ProtectedContent& content_protection1,
    22  const MediaInfo::ProtectedContent& content_protection2) {
    23  return content_protection1.SerializeAsString() ==
    24  content_protection2.SerializeAsString();
    25 }
    26 
    27 std::set<std::string> GetUUIDs(
    28  const MediaInfo::ProtectedContent& protected_content) {
    29  std::set<std::string> uuids;
    30  for (const auto& entry : protected_content.content_protection_entry())
    31  uuids.insert(entry.uuid());
    32  return uuids;
    33 }
    34 
    35 const std::string& GetDefaultAudioLanguage(const MpdOptions& mpd_options) {
    36  return mpd_options.mpd_params.default_language;
    37 }
    38 
    39 const std::string& GetDefaultTextLanguage(const MpdOptions& mpd_options) {
    40  return mpd_options.mpd_params.default_text_language.empty()
    41  ? mpd_options.mpd_params.default_language
    42  : mpd_options.mpd_params.default_text_language;
    43 }
    44 
    45 AdaptationSet::Role RoleFromString(const std::string& role_str) {
    46  if (role_str == "caption")
    47  return AdaptationSet::Role::kRoleCaption;
    48  if (role_str == "subtitle")
    49  return AdaptationSet::Role::kRoleSubtitle;
    50  if (role_str == "main")
    51  return AdaptationSet::Role::kRoleMain;
    52  if (role_str == "alternate")
    53  return AdaptationSet::Role::kRoleAlternate;
    54  if (role_str == "supplementary")
    55  return AdaptationSet::Role::kRoleSupplementary;
    56  if (role_str == "commentary")
    57  return AdaptationSet::Role::kRoleCommentary;
    58  if (role_str == "dub")
    59  return AdaptationSet::Role::kRoleDub;
    60  return AdaptationSet::Role::kRoleUnknown;
    61 }
    62 
    63 } // namespace
    64 
    65 Period::Period(uint32_t period_id,
    66  double start_time_in_seconds,
    67  const MpdOptions& mpd_options,
    68  uint32_t* representation_counter)
    69  : id_(period_id),
    70  start_time_in_seconds_(start_time_in_seconds),
    71  mpd_options_(mpd_options),
    72  representation_counter_(representation_counter) {}
    73 
    75  const MediaInfo& media_info,
    76  bool content_protection_in_adaptation_set) {
    77  // Set duration if it is not set. It may be updated later from duration
    78  // calculated from segments.
    79  if (duration_seconds_ == 0)
    80  duration_seconds_ = media_info.media_duration_seconds();
    81 
    82  // AdaptationSets with the same key should only differ in ContentProtection,
    83  // which also means that if |content_protection_in_adaptation_set| is false,
    84  // there should be at most one entry in |adaptation_sets|.
    85  const std::string key = GetAdaptationSetKey(media_info);
    86  std::list<AdaptationSet*>& adaptation_sets = adaptation_set_list_map_[key];
    87  if (content_protection_in_adaptation_set) {
    88  for (AdaptationSet* adaptation_set : adaptation_sets) {
    89  if (protected_adaptation_set_map_.Match(*adaptation_set, media_info))
    90  return adaptation_set;
    91  }
    92  } else {
    93  if (!adaptation_sets.empty()) {
    94  DCHECK_EQ(adaptation_sets.size(), 1u);
    95  return adaptation_sets.front();
    96  }
    97  }
    98  // None of the adaptation sets match with the new content protection.
    99  // Need a new one.
    100  const std::string language = GetLanguage(media_info);
    101  std::unique_ptr<AdaptationSet> new_adaptation_set =
    102  NewAdaptationSet(language, mpd_options_, representation_counter_);
    103  if (!SetNewAdaptationSetAttributes(language, media_info, adaptation_sets,
    104  new_adaptation_set.get())) {
    105  return nullptr;
    106  }
    107 
    108  if (content_protection_in_adaptation_set &&
    109  media_info.has_protected_content()) {
    110  protected_adaptation_set_map_.Register(*new_adaptation_set, media_info);
    111  AddContentProtectionElements(media_info, new_adaptation_set.get());
    112 
    113  for (AdaptationSet* adaptation_set : adaptation_sets) {
    114  if (protected_adaptation_set_map_.Switchable(*adaptation_set,
    115  *new_adaptation_set)) {
    116  adaptation_set->AddAdaptationSetSwitching(new_adaptation_set.get());
    117  new_adaptation_set->AddAdaptationSetSwitching(adaptation_set);
    118  }
    119  }
    120  }
    121  AdaptationSet* adaptation_set_ptr = new_adaptation_set.get();
    122  adaptation_sets.push_back(adaptation_set_ptr);
    123  adaptation_sets_.emplace_back(std::move(new_adaptation_set));
    124  return adaptation_set_ptr;
    125 }
    126 
    127 xml::scoped_xml_ptr<xmlNode> Period::GetXml(bool output_period_duration) {
    128  adaptation_sets_.sort(
    129  [](const std::unique_ptr<AdaptationSet>& adaptation_set_a,
    130  const std::unique_ptr<AdaptationSet>& adaptation_set_b) {
    131  if (!adaptation_set_a->has_id())
    132  return false;
    133  if (!adaptation_set_b->has_id())
    134  return true;
    135  return adaptation_set_a->id() < adaptation_set_b->id();
    136  });
    137 
    138  xml::XmlNode period("Period");
    139 
    140  // Required for 'dynamic' MPDs.
    141  period.SetId(id_);
    142  // Iterate thru AdaptationSets and add them to one big Period element.
    143  for (const auto& adaptation_set : adaptation_sets_) {
    144  xml::scoped_xml_ptr<xmlNode> child(adaptation_set->GetXml());
    145  if (!child || !period.AddChild(std::move(child)))
    146  return nullptr;
    147  }
    148 
    149  if (output_period_duration) {
    150  period.SetStringAttribute("duration",
    151  SecondsToXmlDuration(duration_seconds_));
    152  } else if (mpd_options_.mpd_type == MpdType::kDynamic) {
    153  period.SetStringAttribute("start",
    154  SecondsToXmlDuration(start_time_in_seconds_));
    155  }
    156  return period.PassScopedPtr();
    157 }
    158 
    159 const std::list<AdaptationSet*> Period::GetAdaptationSets() const {
    160  std::list<AdaptationSet*> adaptation_sets;
    161  for (const auto& adaptation_set : adaptation_sets_) {
    162  adaptation_sets.push_back(adaptation_set.get());
    163  }
    164  return adaptation_sets;
    165 }
    166 
    167 std::unique_ptr<AdaptationSet> Period::NewAdaptationSet(
    168  const std::string& language,
    169  const MpdOptions& options,
    170  uint32_t* representation_counter) {
    171  return std::unique_ptr<AdaptationSet>(
    172  new AdaptationSet(language, options, representation_counter));
    173 }
    174 
    175 bool Period::SetNewAdaptationSetAttributes(
    176  const std::string& language,
    177  const MediaInfo& media_info,
    178  const std::list<AdaptationSet*>& adaptation_sets,
    179  AdaptationSet* new_adaptation_set) {
    180  if (!media_info.dash_roles().empty()) {
    181  for (const std::string& role_str : media_info.dash_roles()) {
    182  AdaptationSet::Role role = RoleFromString(role_str);
    183  if (role == AdaptationSet::kRoleUnknown) {
    184  LOG(ERROR) << "Unrecognized role '" << role_str << "'.";
    185  return false;
    186  }
    187  new_adaptation_set->AddRole(role);
    188  }
    189  } else if (!language.empty()) {
    190  const bool is_main_role =
    191  language == (media_info.has_audio_info()
    192  ? GetDefaultAudioLanguage(mpd_options_)
    193  : GetDefaultTextLanguage(mpd_options_));
    194  if (is_main_role)
    195  new_adaptation_set->AddRole(AdaptationSet::kRoleMain);
    196  }
    197  for (const std::string& accessibility : media_info.dash_accessibilities()) {
    198  size_t pos = accessibility.find('=');
    199  if (pos == std::string::npos) {
    200  LOG(ERROR)
    201  << "Accessibility should be in scheme=value format, but seeing "
    202  << accessibility;
    203  return false;
    204  }
    205  new_adaptation_set->AddAccessibility(accessibility.substr(0, pos),
    206  accessibility.substr(pos + 1));
    207  }
    208 
    209  if (media_info.has_video_info()) {
    210  // Because 'language' is ignored for videos, |adaptation_sets| must have
    211  // all the video AdaptationSets.
    212  if (adaptation_sets.size() > 1) {
    213  new_adaptation_set->AddRole(AdaptationSet::kRoleMain);
    214  } else if (adaptation_sets.size() == 1) {
    215  (*adaptation_sets.begin())->AddRole(AdaptationSet::kRoleMain);
    216  new_adaptation_set->AddRole(AdaptationSet::kRoleMain);
    217  }
    218 
    219  if (media_info.video_info().has_playback_rate()) {
    220  const AdaptationSet* trick_play_reference_adaptation_set =
    221  FindOriginalAdaptationSetForTrickPlay(media_info);
    222  if (!trick_play_reference_adaptation_set) {
    223  LOG(ERROR) << "Failed to find original AdaptationSet for trick play.";
    224  return false;
    225  }
    226  new_adaptation_set->AddTrickPlayReference(
    227  trick_play_reference_adaptation_set);
    228  }
    229  } else if (media_info.has_text_info()) {
    230  // IOP requires all AdaptationSets to have (sub)segmentAlignment set to
    231  // true, so carelessly set it to true.
    232  // In practice it doesn't really make sense to adapt between text tracks.
    233  new_adaptation_set->ForceSetSegmentAlignment(true);
    234  }
    235  return true;
    236 }
    237 
    238 const AdaptationSet* Period::FindOriginalAdaptationSetForTrickPlay(
    239  const MediaInfo& media_info) {
    240  MediaInfo media_info_no_trickplay = media_info;
    241  media_info_no_trickplay.mutable_video_info()->clear_playback_rate();
    242 
    243  std::string key = GetAdaptationSetKey(media_info_no_trickplay);
    244  const std::list<AdaptationSet*>& adaptation_sets =
    245  adaptation_set_list_map_[key];
    246  for (AdaptationSet* adaptation_set : adaptation_sets) {
    247  if (protected_adaptation_set_map_.Match(*adaptation_set, media_info)) {
    248  return adaptation_set;
    249  }
    250  }
    251  return nullptr;
    252 }
    253 
    254 void Period::ProtectedAdaptationSetMap::Register(
    255  const AdaptationSet& adaptation_set,
    256  const MediaInfo& media_info) {
    257  DCHECK(!ContainsKey(protected_content_map_, &adaptation_set));
    258  protected_content_map_[&adaptation_set] = media_info.protected_content();
    259 }
    260 
    261 bool Period::ProtectedAdaptationSetMap::Match(
    262  const AdaptationSet& adaptation_set,
    263  const MediaInfo& media_info) {
    264  const auto protected_content_it =
    265  protected_content_map_.find(&adaptation_set);
    266  // If the AdaptationSet ID is not registered in the map, then it is clear
    267  // content.
    268  if (protected_content_it == protected_content_map_.end())
    269  return !media_info.has_protected_content();
    270  if (!media_info.has_protected_content())
    271  return false;
    272  return ProtectedContentEq(protected_content_it->second,
    273  media_info.protected_content());
    274 }
    275 
    276 bool Period::ProtectedAdaptationSetMap::Switchable(
    277  const AdaptationSet& adaptation_set_a,
    278  const AdaptationSet& adaptation_set_b) {
    279  const auto protected_content_it_a =
    280  protected_content_map_.find(&adaptation_set_a);
    281  const auto protected_content_it_b =
    282  protected_content_map_.find(&adaptation_set_b);
    283 
    284  if (protected_content_it_a == protected_content_map_.end())
    285  return protected_content_it_b == protected_content_map_.end();
    286  if (protected_content_it_b == protected_content_map_.end())
    287  return false;
    288  // Get all the UUIDs of the AdaptationSet. If another AdaptationSet has the
    289  // same UUIDs then those are switchable.
    290  return GetUUIDs(protected_content_it_a->second) ==
    291  GetUUIDs(protected_content_it_b->second);
    292 }
    293 
    294 } // namespace shaka
    virtual AdaptationSet * GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)
    Definition: period.cc:74
    - - -
    scoped_xml_ptr< xmlNode > PassScopedPtr()
    Definition: xml_node.cc:204
    -
    All the methods that are virtual are virtual for mocking.
    -
    void SetStringAttribute(const char *attribute_name, const std::string &attribute)
    Definition: xml_node.cc:166
    -
    bool AddChild(scoped_xml_ptr< xmlNode > child)
    Definition: xml_node.cc:121
    -
    virtual void AddRole(Role role)
    -
    xml::scoped_xml_ptr< xmlNode > GetXml(bool output_period_duration)
    Definition: period.cc:127
    -
    void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
    Definition: mpd_utils.cc:436
    -
    void SetId(uint32_t id)
    Definition: xml_node.cc:189
    -
    virtual void ForceSetSegmentAlignment(bool segment_alignment)
    -
    Period(uint32_t period_id, double start_time_in_seconds, const MpdOptions &mpd_options, uint32_t *representation_counter)
    Definition: period.cc:65
    -
    virtual void AddAccessibility(const std::string &scheme, const std::string &value)
    -
    const std::list< AdaptationSet * > GetAdaptationSets() const
    Definition: period.cc:159
    -
    Defines Mpd Options.
    Definition: mpd_options.h:25
    -
    virtual void AddTrickPlayReference(const AdaptationSet *adaptation_set)
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/mpd/base/period.h"
    +
    8 
    +
    9 #include "packager/base/stl_util.h"
    +
    10 #include "packager/mpd/base/adaptation_set.h"
    +
    11 #include "packager/mpd/base/mpd_options.h"
    +
    12 #include "packager/mpd/base/mpd_utils.h"
    +
    13 #include "packager/mpd/base/xml/xml_node.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace {
    +
    17 
    +
    18 // The easiest way to check whether two protobufs are equal, is to compare the
    +
    19 // serialized version.
    +
    20 bool ProtectedContentEq(
    +
    21  const MediaInfo::ProtectedContent& content_protection1,
    +
    22  const MediaInfo::ProtectedContent& content_protection2) {
    +
    23  return content_protection1.SerializeAsString() ==
    +
    24  content_protection2.SerializeAsString();
    +
    25 }
    +
    26 
    +
    27 std::set<std::string> GetUUIDs(
    +
    28  const MediaInfo::ProtectedContent& protected_content) {
    +
    29  std::set<std::string> uuids;
    +
    30  for (const auto& entry : protected_content.content_protection_entry())
    +
    31  uuids.insert(entry.uuid());
    +
    32  return uuids;
    +
    33 }
    +
    34 
    +
    35 const std::string& GetDefaultAudioLanguage(const MpdOptions& mpd_options) {
    +
    36  return mpd_options.mpd_params.default_language;
    +
    37 }
    +
    38 
    +
    39 const std::string& GetDefaultTextLanguage(const MpdOptions& mpd_options) {
    +
    40  return mpd_options.mpd_params.default_text_language.empty()
    +
    41  ? mpd_options.mpd_params.default_language
    +
    42  : mpd_options.mpd_params.default_text_language;
    +
    43 }
    +
    44 
    +
    45 AdaptationSet::Role RoleFromString(const std::string& role_str) {
    +
    46  if (role_str == "caption")
    +
    47  return AdaptationSet::Role::kRoleCaption;
    +
    48  if (role_str == "subtitle")
    +
    49  return AdaptationSet::Role::kRoleSubtitle;
    +
    50  if (role_str == "main")
    +
    51  return AdaptationSet::Role::kRoleMain;
    +
    52  if (role_str == "alternate")
    +
    53  return AdaptationSet::Role::kRoleAlternate;
    +
    54  if (role_str == "supplementary")
    +
    55  return AdaptationSet::Role::kRoleSupplementary;
    +
    56  if (role_str == "commentary")
    +
    57  return AdaptationSet::Role::kRoleCommentary;
    +
    58  if (role_str == "dub")
    +
    59  return AdaptationSet::Role::kRoleDub;
    +
    60  return AdaptationSet::Role::kRoleUnknown;
    +
    61 }
    +
    62 
    +
    63 } // namespace
    +
    64 
    +
    65 Period::Period(uint32_t period_id,
    +
    66  double start_time_in_seconds,
    +
    67  const MpdOptions& mpd_options,
    +
    68  uint32_t* representation_counter)
    +
    69  : id_(period_id),
    +
    70  start_time_in_seconds_(start_time_in_seconds),
    +
    71  mpd_options_(mpd_options),
    +
    72  representation_counter_(representation_counter) {}
    +
    73 
    + +
    75  const MediaInfo& media_info,
    +
    76  bool content_protection_in_adaptation_set) {
    +
    77  // Set duration if it is not set. It may be updated later from duration
    +
    78  // calculated from segments.
    +
    79  if (duration_seconds_ == 0)
    +
    80  duration_seconds_ = media_info.media_duration_seconds();
    +
    81 
    +
    82  const std::string key = GetAdaptationSetKey(
    +
    83  media_info, mpd_options_.mpd_params.allow_codec_switching);
    +
    84 
    +
    85  std::list<AdaptationSet*>& adaptation_sets = adaptation_set_list_map_[key];
    +
    86 
    +
    87  for (AdaptationSet* adaptation_set : adaptation_sets) {
    +
    88  if (protected_adaptation_set_map_.Match(
    +
    89  *adaptation_set, media_info, content_protection_in_adaptation_set))
    +
    90  return adaptation_set;
    +
    91  }
    +
    92 
    +
    93  // None of the adaptation sets match with the new content protection.
    +
    94  // Need a new one.
    +
    95  const std::string language = GetLanguage(media_info);
    +
    96  std::unique_ptr<AdaptationSet> new_adaptation_set =
    +
    97  NewAdaptationSet(language, mpd_options_, representation_counter_);
    +
    98  if (!SetNewAdaptationSetAttributes(language, media_info, adaptation_sets,
    +
    99  content_protection_in_adaptation_set,
    +
    100  new_adaptation_set.get())) {
    +
    101  return nullptr;
    +
    102  }
    +
    103 
    +
    104  if (content_protection_in_adaptation_set &&
    +
    105  media_info.has_protected_content()) {
    +
    106  protected_adaptation_set_map_.Register(*new_adaptation_set, media_info);
    +
    107  AddContentProtectionElements(media_info, new_adaptation_set.get());
    +
    108  }
    +
    109  for (AdaptationSet* adaptation_set : adaptation_sets) {
    +
    110  if (protected_adaptation_set_map_.Switchable(*adaptation_set,
    +
    111  *new_adaptation_set)) {
    +
    112  adaptation_set->AddAdaptationSetSwitching(new_adaptation_set.get());
    +
    113  new_adaptation_set->AddAdaptationSetSwitching(adaptation_set);
    +
    114  }
    +
    115  }
    +
    116 
    +
    117  AdaptationSet* adaptation_set_ptr = new_adaptation_set.get();
    +
    118  adaptation_sets.push_back(adaptation_set_ptr);
    +
    119  adaptation_sets_.emplace_back(std::move(new_adaptation_set));
    +
    120  return adaptation_set_ptr;
    +
    121 }
    +
    122 
    +
    123 base::Optional<xml::XmlNode> Period::GetXml(bool output_period_duration) {
    +
    124  adaptation_sets_.sort(
    +
    125  [](const std::unique_ptr<AdaptationSet>& adaptation_set_a,
    +
    126  const std::unique_ptr<AdaptationSet>& adaptation_set_b) {
    +
    127  if (!adaptation_set_a->has_id())
    +
    128  return false;
    +
    129  if (!adaptation_set_b->has_id())
    +
    130  return true;
    +
    131  return adaptation_set_a->id() < adaptation_set_b->id();
    +
    132  });
    +
    133 
    +
    134  xml::XmlNode period("Period");
    +
    135 
    +
    136  // Required for 'dynamic' MPDs.
    +
    137  if (!period.SetId(id_))
    +
    138  return base::nullopt;
    +
    139  // Iterate thru AdaptationSets and add them to one big Period element.
    +
    140  for (const auto& adaptation_set : adaptation_sets_) {
    +
    141  auto child = adaptation_set->GetXml();
    +
    142  if (!child || !period.AddChild(std::move(*child)))
    +
    143  return base::nullopt;
    +
    144  }
    +
    145 
    +
    146  if (output_period_duration) {
    +
    147  if (!period.SetStringAttribute("duration",
    +
    148  SecondsToXmlDuration(duration_seconds_))) {
    +
    149  return base::nullopt;
    +
    150  }
    +
    151  } else if (mpd_options_.mpd_type == MpdType::kDynamic) {
    +
    152  if (!period.SetStringAttribute(
    +
    153  "start", SecondsToXmlDuration(start_time_in_seconds_))) {
    +
    154  return base::nullopt;
    +
    155  }
    +
    156  }
    +
    157  return period;
    +
    158 }
    +
    159 
    +
    160 const std::list<AdaptationSet*> Period::GetAdaptationSets() const {
    +
    161  std::list<AdaptationSet*> adaptation_sets;
    +
    162  for (const auto& adaptation_set : adaptation_sets_) {
    +
    163  adaptation_sets.push_back(adaptation_set.get());
    +
    164  }
    +
    165  return adaptation_sets;
    +
    166 }
    +
    167 
    +
    168 std::unique_ptr<AdaptationSet> Period::NewAdaptationSet(
    +
    169  const std::string& language,
    +
    170  const MpdOptions& options,
    +
    171  uint32_t* representation_counter) {
    +
    172  return std::unique_ptr<AdaptationSet>(
    +
    173  new AdaptationSet(language, options, representation_counter));
    +
    174 }
    +
    175 
    +
    176 bool Period::SetNewAdaptationSetAttributes(
    +
    177  const std::string& language,
    +
    178  const MediaInfo& media_info,
    +
    179  const std::list<AdaptationSet*>& adaptation_sets,
    +
    180  bool content_protection_in_adaptation_set,
    +
    181  AdaptationSet* new_adaptation_set) {
    +
    182  if (!media_info.dash_roles().empty()) {
    +
    183  for (const std::string& role_str : media_info.dash_roles()) {
    +
    184  AdaptationSet::Role role = RoleFromString(role_str);
    +
    185  if (role == AdaptationSet::kRoleUnknown) {
    +
    186  LOG(ERROR) << "Unrecognized role '" << role_str << "'.";
    +
    187  return false;
    +
    188  }
    +
    189  new_adaptation_set->AddRole(role);
    +
    190  }
    +
    191  } else if (!language.empty()) {
    +
    192  const bool is_main_role =
    +
    193  language == (media_info.has_audio_info()
    +
    194  ? GetDefaultAudioLanguage(mpd_options_)
    +
    195  : GetDefaultTextLanguage(mpd_options_));
    +
    196  if (is_main_role)
    +
    197  new_adaptation_set->AddRole(AdaptationSet::kRoleMain);
    +
    198  }
    +
    199  for (const std::string& accessibility : media_info.dash_accessibilities()) {
    +
    200  size_t pos = accessibility.find('=');
    +
    201  if (pos == std::string::npos) {
    +
    202  LOG(ERROR)
    +
    203  << "Accessibility should be in scheme=value format, but seeing "
    +
    204  << accessibility;
    +
    205  return false;
    +
    206  }
    +
    207  new_adaptation_set->AddAccessibility(accessibility.substr(0, pos),
    +
    208  accessibility.substr(pos + 1));
    +
    209  }
    +
    210 
    +
    211  new_adaptation_set->set_codec(GetBaseCodec(media_info));
    +
    212 
    +
    213  if (media_info.has_video_info()) {
    +
    214  // Because 'language' is ignored for videos, |adaptation_sets| must have
    +
    215  // all the video AdaptationSets.
    +
    216  if (adaptation_sets.size() > 1) {
    +
    217  new_adaptation_set->AddRole(AdaptationSet::kRoleMain);
    +
    218  } else if (adaptation_sets.size() == 1) {
    +
    219  (*adaptation_sets.begin())->AddRole(AdaptationSet::kRoleMain);
    +
    220  new_adaptation_set->AddRole(AdaptationSet::kRoleMain);
    +
    221  }
    +
    222 
    +
    223  if (media_info.video_info().has_playback_rate()) {
    +
    224  std::string trick_play_reference_adaptation_set_key;
    +
    225  AdaptationSet* trick_play_reference_adaptation_set =
    +
    226  FindMatchingAdaptationSetForTrickPlay(
    +
    227  media_info, content_protection_in_adaptation_set,
    +
    228  &trick_play_reference_adaptation_set_key);
    +
    229  if (trick_play_reference_adaptation_set) {
    +
    230  new_adaptation_set->AddTrickPlayReference(
    +
    231  trick_play_reference_adaptation_set);
    +
    232  } else {
    +
    233  trickplay_cache_[trick_play_reference_adaptation_set_key].push_back(
    +
    234  new_adaptation_set);
    +
    235  }
    +
    236  } else {
    +
    237  std::string trick_play_adaptation_set_key;
    +
    238  AdaptationSet* trickplay_adaptation_set =
    +
    239  FindMatchingAdaptationSetForTrickPlay(
    +
    240  media_info, content_protection_in_adaptation_set,
    +
    241  &trick_play_adaptation_set_key);
    +
    242  if (trickplay_adaptation_set) {
    +
    243  trickplay_adaptation_set->AddTrickPlayReference(new_adaptation_set);
    +
    244  trickplay_cache_.erase(trick_play_adaptation_set_key);
    +
    245  }
    +
    246  }
    +
    247 
    +
    248  } else if (media_info.has_text_info()) {
    +
    249  // IOP requires all AdaptationSets to have (sub)segmentAlignment set to
    +
    250  // true, so carelessly set it to true.
    +
    251  // In practice it doesn't really make sense to adapt between text tracks.
    +
    252  new_adaptation_set->ForceSetSegmentAlignment(true);
    +
    253  }
    +
    254  return true;
    +
    255 }
    +
    256 
    +
    257 AdaptationSet* Period::FindMatchingAdaptationSetForTrickPlay(
    +
    258  const MediaInfo& media_info,
    +
    259  bool content_protection_in_adaptation_set,
    +
    260  std::string* adaptation_set_key) {
    +
    261  std::list<AdaptationSet*>* adaptation_sets = nullptr;
    +
    262  const bool is_trickplay_adaptation_set =
    +
    263  media_info.video_info().has_playback_rate();
    +
    264  if (is_trickplay_adaptation_set) {
    +
    265  *adaptation_set_key = GetAdaptationSetKeyForTrickPlay(media_info);
    +
    266  if (adaptation_set_list_map_.find(*adaptation_set_key) ==
    +
    267  adaptation_set_list_map_.end())
    +
    268  return nullptr;
    +
    269  adaptation_sets = &adaptation_set_list_map_[*adaptation_set_key];
    +
    270  } else {
    +
    271  *adaptation_set_key = GetAdaptationSetKey(
    +
    272  media_info, mpd_options_.mpd_params.allow_codec_switching);
    +
    273  if (trickplay_cache_.find(*adaptation_set_key) == trickplay_cache_.end())
    +
    274  return nullptr;
    +
    275  adaptation_sets = &trickplay_cache_[*adaptation_set_key];
    +
    276  }
    +
    277  for (AdaptationSet* adaptation_set : *adaptation_sets) {
    +
    278  if (protected_adaptation_set_map_.Match(
    +
    279  *adaptation_set, media_info,
    +
    280  content_protection_in_adaptation_set)) {
    +
    281  return adaptation_set;
    +
    282  }
    +
    283  }
    +
    284 
    +
    285  return nullptr;
    +
    286 }
    +
    287 
    +
    288 std::string Period::GetAdaptationSetKeyForTrickPlay(
    +
    289  const MediaInfo& media_info) {
    +
    290  MediaInfo media_info_no_trickplay = media_info;
    +
    291  media_info_no_trickplay.mutable_video_info()->clear_playback_rate();
    +
    292  return GetAdaptationSetKey(media_info_no_trickplay,
    +
    293  mpd_options_.mpd_params.allow_codec_switching);
    +
    294 }
    +
    295 
    +
    296 void Period::ProtectedAdaptationSetMap::Register(
    +
    297  const AdaptationSet& adaptation_set,
    +
    298  const MediaInfo& media_info) {
    +
    299  DCHECK(!ContainsKey(protected_content_map_, &adaptation_set));
    +
    300  protected_content_map_[&adaptation_set] = media_info.protected_content();
    +
    301 }
    +
    302 
    +
    303 bool Period::ProtectedAdaptationSetMap::Match(
    +
    304  const AdaptationSet& adaptation_set,
    +
    305  const MediaInfo& media_info,
    +
    306  bool content_protection_in_adaptation_set) {
    +
    307  if (adaptation_set.codec() != GetBaseCodec(media_info))
    +
    308  return false;
    +
    309 
    +
    310  if (!content_protection_in_adaptation_set)
    +
    311  return true;
    +
    312 
    +
    313  const auto protected_content_it =
    +
    314  protected_content_map_.find(&adaptation_set);
    +
    315  // If the AdaptationSet ID is not registered in the map, then it is clear
    +
    316  // content.
    +
    317  if (protected_content_it == protected_content_map_.end())
    +
    318  return !media_info.has_protected_content();
    +
    319  if (!media_info.has_protected_content())
    +
    320  return false;
    +
    321 
    +
    322  return ProtectedContentEq(protected_content_it->second,
    +
    323  media_info.protected_content());
    +
    324 }
    +
    325 
    +
    326 bool Period::ProtectedAdaptationSetMap::Switchable(
    +
    327  const AdaptationSet& adaptation_set_a,
    +
    328  const AdaptationSet& adaptation_set_b) {
    +
    329  const auto protected_content_it_a =
    +
    330  protected_content_map_.find(&adaptation_set_a);
    +
    331  const auto protected_content_it_b =
    +
    332  protected_content_map_.find(&adaptation_set_b);
    +
    333 
    +
    334  if (protected_content_it_a == protected_content_map_.end())
    +
    335  return protected_content_it_b == protected_content_map_.end();
    +
    336  if (protected_content_it_b == protected_content_map_.end())
    +
    337  return false;
    +
    338  // Get all the UUIDs of the AdaptationSet. If another AdaptationSet has the
    +
    339  // same UUIDs then those are switchable.
    +
    340  return GetUUIDs(protected_content_it_a->second) ==
    +
    341  GetUUIDs(protected_content_it_b->second);
    +
    342 }
    +
    343 
    +
    344 Period::~Period() {
    +
    345  if (!trickplay_cache_.empty()) {
    +
    346  LOG(WARNING) << "Trickplay adaptation set did not get a valid adaptation "
    +
    347  "set match. Please check the command line options.";
    +
    348  }
    +
    349 }
    +
    350 
    +
    351 } // namespace shaka
    + +
    virtual AdaptationSet * GetOrCreateAdaptationSet(const MediaInfo &media_info, bool content_protection_in_adaptation_set)
    Definition: period.cc:74
    +
    Period(uint32_t period_id, double start_time_in_seconds, const MpdOptions &mpd_options, uint32_t *representation_counter)
    Definition: period.cc:65
    +
    base::Optional< xml::XmlNode > GetXml(bool output_period_duration)
    Definition: period.cc:123
    +
    const std::list< AdaptationSet * > GetAdaptationSets() const
    Definition: period.cc:160
    + +
    bool AddChild(XmlNode child) WARN_UNUSED_RESULT
    Definition: xml_node.cc:140
    +
    bool SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
    Definition: xml_node.cc:183
    +
    bool SetId(uint32_t id) WARN_UNUSED_RESULT
    Definition: xml_node.cc:204
    +
    All the methods that are virtual are virtual for mocking.
    +
    void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
    Definition: mpd_utils.cc:473
    +
    Defines Mpd Options.
    Definition: mpd_options.h:25
    +
    bool allow_codec_switching
    Definition: mpd_params.h:85
    diff --git a/docs/dd/de4/classshaka_1_1media_1_1VideoSliceHeaderParser.html b/docs/dd/de4/classshaka_1_1media_1_1VideoSliceHeaderParser.html index 8a4bb8d624..4a3c335fcc 100644 --- a/docs/dd/de4/classshaka_1_1media_1_1VideoSliceHeaderParser.html +++ b/docs/dd/de4/classshaka_1_1media_1_1VideoSliceHeaderParser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::VideoSliceHeaderParser Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::H264VideoSliceHeaderParser shaka::media::H265VideoSliceHeaderParser - -
    + + @@ -159,9 +162,7 @@ virtual int64_t 

    Public Member Functions

    diff --git a/docs/dd/de7/structshaka_1_1media_1_1H265Pps-members.html b/docs/dd/de7/structshaka_1_1media_1_1H265Pps-members.html index c37ba785c4..8e478ff9a4 100644 --- a/docs/dd/de7/structshaka_1_1media_1_1H265Pps-members.html +++ b/docs/dd/de7/structshaka_1_1media_1_1H265Pps-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/de7/xml__node_8h_source.html b/docs/dd/de7/xml__node_8h_source.html index f43aa4f1de..0121c581a8 100644 --- a/docs/dd/de7/xml__node_8h_source.html +++ b/docs/dd/de7/xml__node_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/xml/xml_node.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    xml_node.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Classes to wrap XML operations. XmlNode is a generic wrapper class for
    8 // XmlNode in libxml2. There are also MPD XML specific classes as well.
    9 
    10 #ifndef MPD_BASE_XML_XML_NODE_H_
    11 #define MPD_BASE_XML_XML_NODE_H_
    12 
    13 #include <libxml/tree.h>
    14 #include <stdint.h>
    15 
    16 #include <list>
    17 #include <set>
    18 
    19 #include "packager/base/macros.h"
    20 #include "packager/mpd/base/content_protection_element.h"
    21 #include "packager/mpd/base/media_info.pb.h"
    22 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
    23 
    24 namespace shaka {
    25 
    26 struct SegmentInfo;
    27 
    28 namespace xml {
    29 
    33 class XmlNode {
    34  public:
    37  explicit XmlNode(const char* name);
    38  virtual ~XmlNode();
    39 
    44  bool AddChild(scoped_xml_ptr<xmlNode> child);
    45 
    47  bool AddElements(const std::vector<Element>& elements);
    48 
    52  void SetStringAttribute(const char* attribute_name,
    53  const std::string& attribute);
    54 
    58  void SetIntegerAttribute(const char* attribute_name, uint64_t number);
    59 
    63  void SetFloatingPointAttribute(const char* attribute_name, double number);
    64 
    67  void SetId(uint32_t id);
    68 
    75  void SetContent(const std::string& content);
    76 
    78  std::set<std::string> ExtractReferencedNamespaces();
    79 
    83  scoped_xml_ptr<xmlNode> PassScopedPtr();
    84 
    87  xmlNodePtr Release();
    88 
    90  xmlNodePtr GetRawPtr();
    91 
    92  private:
    93  scoped_xml_ptr<xmlNode> node_;
    94 
    95  DISALLOW_COPY_AND_ASSIGN(XmlNode);
    96 };
    97 
    102  public:
    103  ~RepresentationBaseXmlNode() override;
    105  const std::list<ContentProtectionElement>& content_protection_elements);
    106 
    109  void AddSupplementalProperty(const std::string& scheme_id_uri,
    110  const std::string& value);
    111 
    114  void AddEssentialProperty(const std::string& scheme_id_uri,
    115  const std::string& value);
    116 
    117  protected:
    118  explicit RepresentationBaseXmlNode(const char* name);
    119 
    124  bool AddDescriptor(const std::string& descriptor_name,
    125  const std::string& scheme_id_uri,
    126  const std::string& value);
    127 
    128  private:
    129  bool AddContentProtectionElement(
    130  const ContentProtectionElement& content_protection_element);
    131 
    132  DISALLOW_COPY_AND_ASSIGN(RepresentationBaseXmlNode);
    133 };
    134 
    137  public:
    139  ~AdaptationSetXmlNode() override;
    140 
    143  void AddAccessibilityElement(const std::string& scheme_id_uri,
    144  const std::string& value);
    145 
    148  void AddRoleElement(const std::string& scheme_id_uri,
    149  const std::string& value);
    150 
    151  private:
    152  DISALLOW_COPY_AND_ASSIGN(AdaptationSetXmlNode);
    153 };
    154 
    157  public:
    159  ~RepresentationXmlNode() override;
    160 
    168  bool AddVideoInfo(const MediaInfo::VideoInfo& video_info,
    169  bool set_width,
    170  bool set_height,
    171  bool set_frame_rate);
    172 
    177  bool AddAudioInfo(const MediaInfo::AudioInfo& audio_info);
    178 
    183  bool AddVODOnlyInfo(const MediaInfo& media_info);
    184 
    187  bool AddLiveOnlyInfo(const MediaInfo& media_info,
    188  const std::list<SegmentInfo>& segment_infos,
    189  uint32_t start_number);
    190 
    191  private:
    192  // Add AudioChannelConfiguration element. Note that it is a required element
    193  // for audio Representations.
    194  bool AddAudioChannelInfo(const MediaInfo::AudioInfo& audio_info);
    195 
    196  // Add audioSamplingRate attribute to this element, if present.
    197  void AddAudioSamplingRateInfo(const MediaInfo::AudioInfo& audio_info);
    198 
    199  DISALLOW_COPY_AND_ASSIGN(RepresentationXmlNode);
    200 };
    201 
    202 } // namespace xml
    203 } // namespace shaka
    204 #endif // MPD_BASE_XML_XML_NODE_H_
    RepresentationType in MPD.
    Definition: xml_node.h:156
    - -
    std::set< std::string > ExtractReferencedNamespaces()
    Definition: xml_node.cc:198
    -
    void SetFloatingPointAttribute(const char *attribute_name, double number)
    Definition: xml_node.cc:181
    -
    AdaptationSetType specified in MPD.
    Definition: xml_node.h:136
    - -
    scoped_xml_ptr< xmlNode > PassScopedPtr()
    Definition: xml_node.cc:204
    -
    XmlNode(const char *name)
    Definition: xml_node.cc:114
    -
    All the methods that are virtual are virtual for mocking.
    -
    void SetStringAttribute(const char *attribute_name, const std::string &attribute)
    Definition: xml_node.cc:166
    - -
    bool AddChild(scoped_xml_ptr< xmlNode > child)
    Definition: xml_node.cc:121
    -
    xmlNodePtr Release()
    Definition: xml_node.cc:210
    -
    void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
    Definition: mpd_utils.cc:436
    -
    void SetId(uint32_t id)
    Definition: xml_node.cc:189
    -
    bool AddElements(const std::vector< Element > &elements)
    Adds Elements to this node using the Element struct.
    Definition: xml_node.cc:133
    -
    void SetIntegerAttribute(const char *attribute_name, uint64_t number)
    Definition: xml_node.cc:173
    -
    void SetContent(const std::string &content)
    Definition: xml_node.cc:193
    -
    xmlNodePtr GetRawPtr()
    Definition: xml_node.cc:216
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Classes to wrap XML operations. XmlNode is a generic wrapper class for
    +
    8 // XmlNode in libxml2. There are also MPD XML specific classes as well.
    +
    9 
    +
    10 #ifndef MPD_BASE_XML_XML_NODE_H_
    +
    11 #define MPD_BASE_XML_XML_NODE_H_
    +
    12 
    +
    13 #include <stdint.h>
    +
    14 
    +
    15 #include <list>
    +
    16 #include <set>
    +
    17 #include <string>
    +
    18 #include <vector>
    +
    19 
    +
    20 #include "packager/base/compiler_specific.h"
    +
    21 #include "packager/base/macros.h"
    +
    22 #include "packager/mpd/base/content_protection_element.h"
    +
    23 #include "packager/mpd/base/media_info.pb.h"
    +
    24 
    +
    25 typedef struct _xmlNode xmlNode;
    +
    26 
    +
    27 namespace shaka {
    +
    28 
    +
    29 class MpdBuilder;
    +
    30 struct SegmentInfo;
    +
    31 
    +
    32 namespace xml {
    +
    33 class XmlNode;
    +
    34 } // namespace xml
    +
    35 
    +
    36 // Defined in tests under mpd/test/xml_compare.h
    +
    37 bool XmlEqual(const std::string& xml1, const xml::XmlNode& xml2);
    +
    38 
    +
    39 namespace xml {
    +
    40 
    +
    44 class XmlNode {
    +
    45  public:
    +
    48  explicit XmlNode(const std::string& name);
    +
    49  XmlNode(XmlNode&&);
    +
    50  virtual ~XmlNode();
    +
    51 
    +
    52  XmlNode& operator=(XmlNode&&);
    +
    53 
    +
    57  bool AddChild(XmlNode child) WARN_UNUSED_RESULT;
    +
    58 
    +
    60  bool AddElements(const std::vector<Element>& elements) WARN_UNUSED_RESULT;
    +
    61 
    +
    65  bool SetStringAttribute(const std::string& attribute_name,
    +
    66  const std::string& attribute) WARN_UNUSED_RESULT;
    +
    67 
    +
    71  bool SetIntegerAttribute(const std::string& attribute_name,
    +
    72  uint64_t number) WARN_UNUSED_RESULT;
    +
    73 
    +
    77  bool SetFloatingPointAttribute(const std::string& attribute_name,
    +
    78  double number) WARN_UNUSED_RESULT;
    +
    79 
    +
    82  bool SetId(uint32_t id) WARN_UNUSED_RESULT;
    +
    83 
    +
    85  void AddContent(const std::string& content);
    +
    86 
    +
    93  void SetContent(const std::string& content);
    +
    94 
    +
    96  std::set<std::string> ExtractReferencedNamespaces() const;
    +
    97 
    +
    100  std::string ToString(const std::string& comment) const;
    +
    101 
    +
    106  bool GetAttribute(const std::string& name, std::string* value) const;
    +
    107 
    +
    108  private:
    +
    109  friend bool shaka::XmlEqual(const std::string& xml1,
    +
    110  const xml::XmlNode& xml2);
    +
    111  xmlNode* GetRawPtr() const;
    +
    112 
    +
    113  // Don't use xmlNode directly so we don't have to forward-declare a bunch of
    +
    114  // libxml types to define the scoped_xml_ptr type. This allows us to only
    +
    115  // include libxml headers in a few source files.
    +
    116  class Impl;
    +
    117  std::unique_ptr<Impl> impl_;
    +
    118 
    +
    119  DISALLOW_COPY_AND_ASSIGN(XmlNode);
    +
    120 };
    +
    121 
    + +
    126  public:
    +
    127  ~RepresentationBaseXmlNode() override;
    +
    128  bool AddContentProtectionElements(
    +
    129  const std::list<ContentProtectionElement>& content_protection_elements)
    +
    130  WARN_UNUSED_RESULT;
    +
    131 
    +
    134  bool AddSupplementalProperty(const std::string& scheme_id_uri,
    +
    135  const std::string& value) WARN_UNUSED_RESULT;
    +
    136 
    +
    139  bool AddEssentialProperty(const std::string& scheme_id_uri,
    +
    140  const std::string& value) WARN_UNUSED_RESULT;
    +
    141 
    +
    142  protected:
    +
    143  explicit RepresentationBaseXmlNode(const std::string& name);
    +
    144 
    +
    149  bool AddDescriptor(const std::string& descriptor_name,
    +
    150  const std::string& scheme_id_uri,
    +
    151  const std::string& value) WARN_UNUSED_RESULT;
    +
    152 
    +
    153  private:
    +
    154  bool AddContentProtectionElement(
    +
    155  const ContentProtectionElement& content_protection_element)
    +
    156  WARN_UNUSED_RESULT;
    +
    157 
    +
    158  DISALLOW_COPY_AND_ASSIGN(RepresentationBaseXmlNode);
    +
    159 };
    +
    160 
    + +
    163  public:
    + +
    165  ~AdaptationSetXmlNode() override;
    +
    166 
    +
    169  bool AddAccessibilityElement(const std::string& scheme_id_uri,
    +
    170  const std::string& value) WARN_UNUSED_RESULT;
    +
    171 
    +
    174  bool AddRoleElement(const std::string& scheme_id_uri,
    +
    175  const std::string& value) WARN_UNUSED_RESULT;
    +
    176 
    +
    177  private:
    +
    178  DISALLOW_COPY_AND_ASSIGN(AdaptationSetXmlNode);
    +
    179 };
    +
    180 
    + +
    183  public:
    + +
    185  ~RepresentationXmlNode() override;
    +
    186 
    +
    194  bool AddVideoInfo(const MediaInfo::VideoInfo& video_info,
    +
    195  bool set_width,
    +
    196  bool set_height,
    +
    197  bool set_frame_rate) WARN_UNUSED_RESULT;
    +
    198 
    +
    203  bool AddAudioInfo(const MediaInfo::AudioInfo& audio_info) WARN_UNUSED_RESULT;
    +
    204 
    +
    209  bool AddVODOnlyInfo(const MediaInfo& media_info) WARN_UNUSED_RESULT;
    +
    210 
    +
    213  bool AddLiveOnlyInfo(const MediaInfo& media_info,
    +
    214  const std::list<SegmentInfo>& segment_infos,
    +
    215  uint32_t start_number) WARN_UNUSED_RESULT;
    +
    216 
    +
    217  private:
    +
    218  // Add AudioChannelConfiguration element. Note that it is a required element
    +
    219  // for audio Representations.
    +
    220  bool AddAudioChannelInfo(const MediaInfo::AudioInfo& audio_info)
    +
    221  WARN_UNUSED_RESULT;
    +
    222 
    +
    223  // Add audioSamplingRate attribute to this element, if present.
    +
    224  bool AddAudioSamplingRateInfo(const MediaInfo::AudioInfo& audio_info)
    +
    225  WARN_UNUSED_RESULT;
    +
    226 
    +
    227  DISALLOW_COPY_AND_ASSIGN(RepresentationXmlNode);
    +
    228 };
    +
    229 
    +
    230 } // namespace xml
    +
    231 } // namespace shaka
    +
    232 #endif // MPD_BASE_XML_XML_NODE_H_
    +
    AdaptationSetType specified in MPD.
    Definition: xml_node.h:162
    +
    bool AddRoleElement(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:328
    +
    bool AddAccessibilityElement(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:322
    + +
    bool AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:286
    +
    bool AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:274
    +
    bool AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:280
    +
    RepresentationType in MPD.
    Definition: xml_node.h:182
    +
    bool AddVideoInfo(const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate) WARN_UNUSED_RESULT
    Definition: xml_node.cc:337
    +
    bool AddVODOnlyInfo(const MediaInfo &media_info) WARN_UNUSED_RESULT
    Definition: xml_node.cc:379
    +
    bool AddLiveOnlyInfo(const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number) WARN_UNUSED_RESULT
    Definition: xml_node.cc:433
    +
    bool AddAudioInfo(const MediaInfo::AudioInfo &audio_info) WARN_UNUSED_RESULT
    Definition: xml_node.cc:374
    + +
    bool AddChild(XmlNode child) WARN_UNUSED_RESULT
    Definition: xml_node.cc:140
    +
    std::set< std::string > ExtractReferencedNamespaces() const
    Definition: xml_node.cc:218
    +
    void AddContent(const std::string &content)
    Similar to SetContent, but appends to the end of existing content.
    Definition: xml_node.cc:208
    +
    void SetContent(const std::string &content)
    Definition: xml_node.cc:213
    +
    bool SetFloatingPointAttribute(const std::string &attribute_name, double number) WARN_UNUSED_RESULT
    Definition: xml_node.cc:197
    +
    bool SetIntegerAttribute(const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULT
    Definition: xml_node.cc:190
    +
    XmlNode(const std::string &name)
    Definition: xml_node.cc:129
    +
    bool SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
    Definition: xml_node.cc:183
    +
    bool GetAttribute(const std::string &name, std::string *value) const
    Definition: xml_node.cc:248
    +
    bool SetId(uint32_t id) WARN_UNUSED_RESULT
    Definition: xml_node.cc:204
    +
    bool AddElements(const std::vector< Element > &elements) WARN_UNUSED_RESULT
    Adds Elements to this node using the Element struct.
    Definition: xml_node.cc:151
    +
    std::string ToString(const std::string &comment) const
    Definition: xml_node.cc:224
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/dd/de9/classshaka_1_1media_1_1MediaHandler-members.html b/docs/dd/de9/classshaka_1_1media_1_1MediaHandler-members.html index ddd31e3173..64f44bb337 100644 --- a/docs/dd/de9/classshaka_1_1media_1_1MediaHandler-members.html +++ b/docs/dd/de9/classshaka_1_1media_1_1MediaHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::MediaHandler, including all inherited members.

    - + @@ -96,9 +99,7 @@ $(function() {
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
    Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
    diff --git a/docs/dd/de9/structshaka_1_1ChunkingParams-members.html b/docs/dd/de9/structshaka_1_1ChunkingParams-members.html index ab5353e5a9..64c78c438e 100644 --- a/docs/dd/de9/structshaka_1_1ChunkingParams-members.html +++ b/docs/dd/de9/structshaka_1_1ChunkingParams-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dd/dee/box__definitions_8cc_source.html b/docs/dd/dee/box__definitions_8cc_source.html index 8af8fed9df..3d04ed2e5a 100644 --- a/docs/dd/dee/box__definitions_8cc_source.html +++ b/docs/dd/dee/box__definitions_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/box_definitions.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    box_definitions.cc
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/mp4/box_definitions.h"
    6 
    7 #include <limits>
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/media/base/bit_reader.h"
    11 #include "packager/media/base/macros.h"
    12 #include "packager/media/base/rcheck.h"
    13 #include "packager/media/formats/mp4/box_buffer.h"
    14 
    15 namespace {
    16 const uint32_t kFourCCSize = 4;
    17 
    18 // Key Id size as defined in CENC spec.
    19 const uint32_t kCencKeyIdSize = 16;
    20 
    21 // 9 uint32_t in big endian formatted array.
    22 const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    23  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
    24  0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
    25 
    26 // Default entries for HandlerReference box.
    27 const char kVideoHandlerName[] = "VideoHandler";
    28 const char kAudioHandlerName[] = "SoundHandler";
    29 const char kTextHandlerName[] = "TextHandler";
    30 
    31 // Default values for VideoSampleEntry box.
    32 const uint32_t kVideoResolution = 0x00480000; // 72 dpi.
    33 const uint16_t kVideoFrameCount = 1;
    34 const uint16_t kVideoDepth = 0x0018;
    35 
    36 const uint32_t kCompressorNameSize = 32u;
    37 const char kAv1CompressorName[] = "\012AOM Coding";
    38 const char kAvcCompressorName[] = "\012AVC Coding";
    39 const char kDolbyVisionCompressorName[] = "\013DOVI Coding";
    40 const char kHevcCompressorName[] = "\013HEVC Coding";
    41 const char kVpcCompressorName[] = "\012VPC Coding";
    42 
    43 // According to ISO/IEC FDIS 23001-7: CENC spec, IV should be either
    44 // 64-bit (8-byte) or 128-bit (16-byte).
    45 // |per_sample_iv_size| of 0 means constant_iv is used.
    46 bool IsIvSizeValid(uint8_t per_sample_iv_size) {
    47  return per_sample_iv_size == 0 || per_sample_iv_size == 8 ||
    48  per_sample_iv_size == 16;
    49 }
    50 
    51 // Default values to construct the following fields in ddts box. Values are set
    52 // according to FFMPEG.
    53 // bit(2) FrameDuration; // 3 = 4096
    54 // bit(5) StreamConstruction; // 18
    55 // bit(1) CoreLFEPresent; // 0 = none
    56 // bit(6) CoreLayout; // 31 = ignore core layout
    57 // bit(14) CoreSize; // 0
    58 // bit(1) StereoDownmix // 0 = none
    59 // bit(3) RepresentationType; // 4
    60 // bit(16) ChannelLayout; // 0xf = 5.1 channel layout.
    61 // bit(1) MultiAssetFlag // 0 = single asset
    62 // bit(1) LBRDurationMod // 0 = ignore
    63 // bit(1) ReservedBoxPresent // 0 = none
    64 // bit(5) Reserved // 0
    65 const uint8_t kDdtsExtraData[] = {0xe4, 0x7c, 0, 4, 0, 0x0f, 0};
    66 
    67 // Utility functions to check if the 64bit integers can fit in 32bit integer.
    68 bool IsFitIn32Bits(uint64_t a) {
    69  return a <= std::numeric_limits<uint32_t>::max();
    70 }
    71 
    72 bool IsFitIn32Bits(int64_t a) {
    73  return a <= std::numeric_limits<int32_t>::max() &&
    74  a >= std::numeric_limits<int32_t>::min();
    75 }
    76 
    77 template <typename T1, typename T2>
    78 bool IsFitIn32Bits(T1 a1, T2 a2) {
    79  return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
    80 }
    81 
    82 template <typename T1, typename T2, typename T3>
    83 bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
    84  return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
    85 }
    86 
    87 } // namespace
    88 
    89 namespace shaka {
    90 namespace media {
    91 namespace mp4 {
    92 
    93 namespace {
    94 
    95 TrackType FourCCToTrackType(FourCC fourcc) {
    96  switch (fourcc) {
    97  case FOURCC_vide:
    98  return kVideo;
    99  case FOURCC_soun:
    100  return kAudio;
    101  case FOURCC_text:
    102  return kText;
    103  default:
    104  return kInvalid;
    105  }
    106 }
    107 
    108 FourCC TrackTypeToFourCC(TrackType track_type) {
    109  switch (track_type) {
    110  case kVideo:
    111  return FOURCC_vide;
    112  case kAudio:
    113  return FOURCC_soun;
    114  case kText:
    115  return FOURCC_text;
    116  default:
    117  return FOURCC_NULL;
    118  }
    119 }
    120 
    121 bool IsProtectionSchemeSupported(FourCC scheme) {
    122  return scheme == FOURCC_cenc || scheme == FOURCC_cens ||
    123  scheme == FOURCC_cbc1 || scheme == FOURCC_cbcs;
    124 }
    125 
    126 } // namespace
    127 
    128 FileType::FileType() = default;
    129 FileType::~FileType() = default;
    130 
    131 FourCC FileType::BoxType() const {
    132  return FOURCC_ftyp;
    133 }
    134 
    135 bool FileType::ReadWriteInternal(BoxBuffer* buffer) {
    136  RCHECK(ReadWriteHeaderInternal(buffer) &&
    137  buffer->ReadWriteFourCC(&major_brand) &&
    138  buffer->ReadWriteUInt32(&minor_version));
    139  size_t num_brands;
    140  if (buffer->Reading()) {
    141  RCHECK(buffer->BytesLeft() % sizeof(FourCC) == 0);
    142  num_brands = buffer->BytesLeft() / sizeof(FourCC);
    143  compatible_brands.resize(num_brands);
    144  } else {
    145  num_brands = compatible_brands.size();
    146  }
    147  for (size_t i = 0; i < num_brands; ++i)
    148  RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
    149  return true;
    150 }
    151 
    152 size_t FileType::ComputeSizeInternal() {
    153  return HeaderSize() + kFourCCSize + sizeof(minor_version) +
    154  kFourCCSize * compatible_brands.size();
    155 }
    156 
    157 FourCC SegmentType::BoxType() const {
    158  return FOURCC_styp;
    159 }
    160 
    161 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() = default;
    162 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() = default;
    163 
    165  return FOURCC_pssh;
    166 }
    167 
    168 bool ProtectionSystemSpecificHeader::ReadWriteInternal(BoxBuffer* buffer) {
    169  if (buffer->Reading()) {
    170  BoxReader* reader = buffer->reader();
    171  DCHECK(reader);
    172  raw_box.assign(reader->data(), reader->data() + reader->size());
    173  } else {
    174  DCHECK(!raw_box.empty());
    175  buffer->writer()->AppendVector(raw_box);
    176  }
    177 
    178  return true;
    179 }
    180 
    181 size_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
    182  return raw_box.size();
    183 }
    184 
    185 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() = default;
    186 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() = default;
    187 
    189  return FOURCC_saio;
    190 }
    191 
    192 bool SampleAuxiliaryInformationOffset::ReadWriteInternal(BoxBuffer* buffer) {
    193  RCHECK(ReadWriteHeaderInternal(buffer));
    194  if (flags & 1)
    195  RCHECK(buffer->IgnoreBytes(8)); // aux_info_type and parameter.
    196 
    197  uint32_t count = static_cast<uint32_t>(offsets.size());
    198  RCHECK(buffer->ReadWriteUInt32(&count));
    199  offsets.resize(count);
    200 
    201  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    202  for (uint32_t i = 0; i < count; ++i)
    203  RCHECK(buffer->ReadWriteUInt64NBytes(&offsets[i], num_bytes));
    204  return true;
    205 }
    206 
    207 size_t SampleAuxiliaryInformationOffset::ComputeSizeInternal() {
    208  // This box is optional. Skip it if it is empty.
    209  if (offsets.size() == 0)
    210  return 0;
    211  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    212  return HeaderSize() + sizeof(uint32_t) + num_bytes * offsets.size();
    213 }
    214 
    215 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize() = default;
    216 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() = default;
    217 
    219  return FOURCC_saiz;
    220 }
    221 
    222 bool SampleAuxiliaryInformationSize::ReadWriteInternal(BoxBuffer* buffer) {
    223  RCHECK(ReadWriteHeaderInternal(buffer));
    224  if (flags & 1)
    225  RCHECK(buffer->IgnoreBytes(8));
    226 
    227  RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
    228  buffer->ReadWriteUInt32(&sample_count));
    229  if (default_sample_info_size == 0)
    230  RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
    231  return true;
    232 }
    233 
    234 size_t SampleAuxiliaryInformationSize::ComputeSizeInternal() {
    235  // This box is optional. Skip it if it is empty.
    236  if (sample_count == 0)
    237  return 0;
    238  return HeaderSize() + sizeof(default_sample_info_size) +
    239  sizeof(sample_count) +
    240  (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
    241 }
    242 
    243 bool SampleEncryptionEntry::ReadWrite(uint8_t iv_size,
    244  bool has_subsamples,
    245  BoxBuffer* buffer) {
    246  DCHECK(IsIvSizeValid(iv_size));
    247  DCHECK(buffer);
    248 
    249  RCHECK(buffer->ReadWriteVector(&initialization_vector, iv_size));
    250 
    251  if (!has_subsamples) {
    252  subsamples.clear();
    253  return true;
    254  }
    255 
    256  uint16_t subsample_count = static_cast<uint16_t>(subsamples.size());
    257  RCHECK(buffer->ReadWriteUInt16(&subsample_count));
    258  RCHECK(subsample_count > 0);
    259  subsamples.resize(subsample_count);
    260  for (auto& subsample : subsamples) {
    261  RCHECK(buffer->ReadWriteUInt16(&subsample.clear_bytes) &&
    262  buffer->ReadWriteUInt32(&subsample.cipher_bytes));
    263  }
    264  return true;
    265 }
    266 
    268  bool has_subsamples,
    269  BufferReader* reader) {
    270  DCHECK(IsIvSizeValid(iv_size));
    271  DCHECK(reader);
    272 
    273  initialization_vector.resize(iv_size);
    274  RCHECK(reader->ReadToVector(&initialization_vector, iv_size));
    275 
    276  if (!has_subsamples) {
    277  subsamples.clear();
    278  return true;
    279  }
    280 
    281  uint16_t subsample_count;
    282  RCHECK(reader->Read2(&subsample_count));
    283  RCHECK(subsample_count > 0);
    284  subsamples.resize(subsample_count);
    285  for (auto& subsample : subsamples) {
    286  RCHECK(reader->Read2(&subsample.clear_bytes) &&
    287  reader->Read4(&subsample.cipher_bytes));
    288  }
    289  return true;
    290 }
    291 
    293  const uint32_t subsample_entry_size = sizeof(uint16_t) + sizeof(uint32_t);
    294  const uint16_t subsample_count = static_cast<uint16_t>(subsamples.size());
    295  return static_cast<uint32_t>(
    296  initialization_vector.size() +
    297  (subsample_count > 0
    298  ? (sizeof(subsample_count) + subsample_entry_size * subsample_count)
    299  : 0));
    300 }
    301 
    303  uint32_t size = 0;
    304  for (uint32_t i = 0; i < subsamples.size(); ++i)
    305  size += subsamples[i].clear_bytes + subsamples[i].cipher_bytes;
    306  return size;
    307 }
    308 
    309 SampleEncryption::SampleEncryption() = default;
    310 SampleEncryption::~SampleEncryption() = default;
    311 
    313  return FOURCC_senc;
    314 }
    315 
    316 bool SampleEncryption::ReadWriteInternal(BoxBuffer* buffer) {
    317  RCHECK(ReadWriteHeaderInternal(buffer));
    318 
    319  // If we don't know |iv_size|, store sample encryption data to parse later
    320  // after we know iv_size.
    321  if (buffer->Reading() && iv_size == SampleEncryption::kInvalidIvSize) {
    322  RCHECK(
    323  buffer->ReadWriteVector(&sample_encryption_data, buffer->BytesLeft()));
    324  return true;
    325  }
    326 
    327  if (!IsIvSizeValid(iv_size)) {
    328  LOG(ERROR)
    329  << "IV_size can only be 8 or 16 or 0 for constant iv, but seeing "
    330  << iv_size;
    331  return false;
    332  }
    333 
    334  uint32_t sample_count =
    335  static_cast<uint32_t>(sample_encryption_entries.size());
    336  RCHECK(buffer->ReadWriteUInt32(&sample_count));
    337 
    338  sample_encryption_entries.resize(sample_count);
    339  for (auto& sample_encryption_entry : sample_encryption_entries) {
    340  RCHECK(sample_encryption_entry.ReadWrite(
    341  iv_size, (flags & kUseSubsampleEncryption) != 0, buffer) != 0);
    342  }
    343  return true;
    344 }
    345 
    346 size_t SampleEncryption::ComputeSizeInternal() {
    347  const uint32_t sample_count =
    348  static_cast<uint32_t>(sample_encryption_entries.size());
    349  if (sample_count == 0) {
    350  // Sample encryption box is optional. Skip it if it is empty.
    351  return 0;
    352  }
    353 
    354  DCHECK(IsIvSizeValid(iv_size));
    355  size_t box_size = HeaderSize() + sizeof(sample_count);
    356  if (flags & kUseSubsampleEncryption) {
    357  for (const SampleEncryptionEntry& sample_encryption_entry :
    358  sample_encryption_entries) {
    359  box_size += sample_encryption_entry.ComputeSize();
    360  }
    361  } else {
    362  box_size += sample_count * iv_size;
    363  }
    364  return box_size;
    365 }
    366 
    368  uint8_t iv_size,
    369  std::vector<SampleEncryptionEntry>* sample_encryption_entries) const {
    370  DCHECK(IsIvSizeValid(iv_size));
    371 
    372  BufferReader reader(sample_encryption_data.data(),
    373  sample_encryption_data.size());
    374  uint32_t sample_count = 0;
    375  RCHECK(reader.Read4(&sample_count));
    376 
    377  sample_encryption_entries->resize(sample_count);
    378  for (auto& sample_encryption_entry : *sample_encryption_entries) {
    379  RCHECK(sample_encryption_entry.ParseFromBuffer(
    380  iv_size, (flags & kUseSubsampleEncryption) != 0, &reader) != 0);
    381  }
    382  return true;
    383 }
    384 
    385 OriginalFormat::OriginalFormat() = default;
    386 OriginalFormat::~OriginalFormat() = default;
    387 
    388 FourCC OriginalFormat::BoxType() const {
    389  return FOURCC_frma;
    390 }
    391 
    392 bool OriginalFormat::ReadWriteInternal(BoxBuffer* buffer) {
    393  return ReadWriteHeaderInternal(buffer) && buffer->ReadWriteFourCC(&format);
    394 }
    395 
    396 size_t OriginalFormat::ComputeSizeInternal() {
    397  return HeaderSize() + kFourCCSize;
    398 }
    399 
    400 SchemeType::SchemeType() = default;
    401 SchemeType::~SchemeType() = default;
    402 
    403 FourCC SchemeType::BoxType() const {
    404  return FOURCC_schm;
    405 }
    406 
    407 bool SchemeType::ReadWriteInternal(BoxBuffer* buffer) {
    408  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteFourCC(&type) &&
    409  buffer->ReadWriteUInt32(&version));
    410  return true;
    411 }
    412 
    413 size_t SchemeType::ComputeSizeInternal() {
    414  return HeaderSize() + kFourCCSize + sizeof(version);
    415 }
    416 
    417 TrackEncryption::TrackEncryption() = default;
    418 TrackEncryption::~TrackEncryption() = default;
    419 
    420 FourCC TrackEncryption::BoxType() const {
    421  return FOURCC_tenc;
    422 }
    423 
    424 bool TrackEncryption::ReadWriteInternal(BoxBuffer* buffer) {
    425  if (!buffer->Reading()) {
    426  if (default_kid.size() != kCencKeyIdSize) {
    427  LOG(WARNING) << "CENC defines key id length of " << kCencKeyIdSize
    428  << " bytes; got " << default_kid.size()
    429  << ". Resized accordingly.";
    430  default_kid.resize(kCencKeyIdSize);
    431  }
    432  RCHECK(default_crypt_byte_block < 16 && default_skip_byte_block < 16);
    433  if (default_crypt_byte_block != 0 && default_skip_byte_block != 0) {
    434  // Version 1 box is needed for pattern-based encryption.
    435  version = 1;
    436  }
    437  }
    438 
    439  RCHECK(ReadWriteHeaderInternal(buffer) &&
    440  buffer->IgnoreBytes(1)); // reserved.
    441 
    442  uint8_t pattern = default_crypt_byte_block << 4 | default_skip_byte_block;
    443  RCHECK(buffer->ReadWriteUInt8(&pattern));
    444  default_crypt_byte_block = pattern >> 4;
    445  default_skip_byte_block = pattern & 0x0F;
    446 
    447  RCHECK(buffer->ReadWriteUInt8(&default_is_protected) &&
    448  buffer->ReadWriteUInt8(&default_per_sample_iv_size) &&
    449  buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
    450 
    451  if (default_is_protected == 1) {
    452  if (default_per_sample_iv_size == 0) { // For constant iv.
    453  uint8_t default_constant_iv_size =
    454  static_cast<uint8_t>(default_constant_iv.size());
    455  RCHECK(buffer->ReadWriteUInt8(&default_constant_iv_size));
    456  RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
    457  RCHECK(buffer->ReadWriteVector(&default_constant_iv,
    458  default_constant_iv_size));
    459  } else {
    460  RCHECK(default_per_sample_iv_size == 8 ||
    461  default_per_sample_iv_size == 16);
    462  RCHECK(default_constant_iv.empty());
    463  }
    464  } else {
    465  // Expect |default_is_protected| to be 0, i.e. not protected. Other values
    466  // of |default_is_protected| is not supported.
    467  RCHECK(default_is_protected == 0);
    468  RCHECK(default_per_sample_iv_size == 0);
    469  RCHECK(default_constant_iv.empty());
    470  }
    471  return true;
    472 }
    473 
    474 size_t TrackEncryption::ComputeSizeInternal() {
    475  return HeaderSize() + sizeof(uint32_t) + kCencKeyIdSize +
    476  (default_constant_iv.empty()
    477  ? 0
    478  : (sizeof(uint8_t) + default_constant_iv.size()));
    479 }
    480 
    481 SchemeInfo::SchemeInfo() = default;
    482 SchemeInfo::~SchemeInfo() = default;
    483 
    484 FourCC SchemeInfo::BoxType() const {
    485  return FOURCC_schi;
    486 }
    487 
    488 bool SchemeInfo::ReadWriteInternal(BoxBuffer* buffer) {
    489  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    490  buffer->ReadWriteChild(&track_encryption));
    491  return true;
    492 }
    493 
    494 size_t SchemeInfo::ComputeSizeInternal() {
    495  return HeaderSize() + track_encryption.ComputeSize();
    496 }
    497 
    498 ProtectionSchemeInfo::ProtectionSchemeInfo() = default;
    499 ProtectionSchemeInfo::~ProtectionSchemeInfo() = default;
    500 
    502  return FOURCC_sinf;
    503 }
    504 
    505 bool ProtectionSchemeInfo::ReadWriteInternal(BoxBuffer* buffer) {
    506  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    507  buffer->ReadWriteChild(&format) && buffer->ReadWriteChild(&type));
    508  if (IsProtectionSchemeSupported(type.type)) {
    509  RCHECK(buffer->ReadWriteChild(&info));
    510  } else {
    511  DLOG(WARNING) << "Ignore unsupported protection scheme: "
    512  << FourCCToString(type.type);
    513  }
    514  // Other protection schemes are silently ignored. Since the protection scheme
    515  // type can't be determined until this box is opened, we return 'true' for
    516  // non-CENC protection scheme types. It is the parent box's responsibility to
    517  // ensure that this scheme type is a supported one.
    518  return true;
    519 }
    520 
    521 size_t ProtectionSchemeInfo::ComputeSizeInternal() {
    522  // Skip sinf box if it is not initialized.
    523  if (format.format == FOURCC_NULL)
    524  return 0;
    525  return HeaderSize() + format.ComputeSize() + type.ComputeSize() +
    526  info.ComputeSize();
    527 }
    528 
    529 MovieHeader::MovieHeader() = default;
    530 MovieHeader::~MovieHeader() = default;
    531 
    532 FourCC MovieHeader::BoxType() const {
    533  return FOURCC_mvhd;
    534 }
    535 
    536 bool MovieHeader::ReadWriteInternal(BoxBuffer* buffer) {
    537  RCHECK(ReadWriteHeaderInternal(buffer));
    538 
    539  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    540  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
    541  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
    542  buffer->ReadWriteUInt32(&timescale) &&
    543  buffer->ReadWriteUInt64NBytes(&duration, num_bytes));
    544 
    545  std::vector<uint8_t> matrix(kUnityMatrix,
    546  kUnityMatrix + arraysize(kUnityMatrix));
    547  RCHECK(buffer->ReadWriteInt32(&rate) && buffer->ReadWriteInt16(&volume) &&
    548  buffer->IgnoreBytes(10) && // reserved
    549  buffer->ReadWriteVector(&matrix, matrix.size()) &&
    550  buffer->IgnoreBytes(24) && // predefined zero
    551  buffer->ReadWriteUInt32(&next_track_id));
    552  return true;
    553 }
    554 
    555 size_t MovieHeader::ComputeSizeInternal() {
    556  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
    557  return HeaderSize() + sizeof(uint32_t) * (1 + version) * 3 +
    558  sizeof(timescale) + sizeof(rate) + sizeof(volume) +
    559  sizeof(next_track_id) + sizeof(kUnityMatrix) + 10 +
    560  24; // 10 bytes reserved, 24 bytes predefined.
    561 }
    562 
    563 TrackHeader::TrackHeader() {
    564  flags = kTrackEnabled | kTrackInMovie | kTrackInPreview;
    565 }
    566 
    567 TrackHeader::~TrackHeader() = default;
    568 
    569 FourCC TrackHeader::BoxType() const {
    570  return FOURCC_tkhd;
    571 }
    572 
    573 bool TrackHeader::ReadWriteInternal(BoxBuffer* buffer) {
    574  RCHECK(ReadWriteHeaderInternal(buffer));
    575 
    576  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    577  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
    578  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
    579  buffer->ReadWriteUInt32(&track_id) &&
    580  buffer->IgnoreBytes(4) && // reserved
    581  buffer->ReadWriteUInt64NBytes(&duration, num_bytes));
    582 
    583  if (!buffer->Reading()) {
    584  // Set default value for volume, if track is audio, 0x100 else 0.
    585  if (volume == -1)
    586  volume = (width != 0 && height != 0) ? 0 : 0x100;
    587  }
    588  std::vector<uint8_t> matrix(kUnityMatrix,
    589  kUnityMatrix + arraysize(kUnityMatrix));
    590  RCHECK(buffer->IgnoreBytes(8) && // reserved
    591  buffer->ReadWriteInt16(&layer) &&
    592  buffer->ReadWriteInt16(&alternate_group) &&
    593  buffer->ReadWriteInt16(&volume) &&
    594  buffer->IgnoreBytes(2) && // reserved
    595  buffer->ReadWriteVector(&matrix, matrix.size()) &&
    596  buffer->ReadWriteUInt32(&width) && buffer->ReadWriteUInt32(&height));
    597  return true;
    598 }
    599 
    600 size_t TrackHeader::ComputeSizeInternal() {
    601  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
    602  return HeaderSize() + sizeof(track_id) +
    603  sizeof(uint32_t) * (1 + version) * 3 + sizeof(layer) +
    604  sizeof(alternate_group) + sizeof(volume) + sizeof(width) +
    605  sizeof(height) + sizeof(kUnityMatrix) + 14; // 14 bytes reserved.
    606 }
    607 
    608 SampleDescription::SampleDescription() = default;
    609 SampleDescription::~SampleDescription() = default;
    610 
    612  return FOURCC_stsd;
    613 }
    614 
    615 bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
    616  uint32_t count = 0;
    617  switch (type) {
    618  case kVideo:
    619  count = static_cast<uint32_t>(video_entries.size());
    620  break;
    621  case kAudio:
    622  count = static_cast<uint32_t>(audio_entries.size());
    623  break;
    624  case kText:
    625  count = static_cast<uint32_t>(text_entries.size());
    626  break;
    627  default:
    628  NOTIMPLEMENTED() << "SampleDecryption type " << type
    629  << " is not handled. Skipping.";
    630  }
    631  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    632 
    633  if (buffer->Reading()) {
    634  BoxReader* reader = buffer->reader();
    635  DCHECK(reader);
    636  video_entries.clear();
    637  audio_entries.clear();
    638  // Note: this value is preset before scanning begins. See comments in the
    639  // Parse(Media*) function.
    640  if (type == kVideo) {
    641  RCHECK(reader->ReadAllChildren(&video_entries));
    642  RCHECK(video_entries.size() == count);
    643  } else if (type == kAudio) {
    644  RCHECK(reader->ReadAllChildren(&audio_entries));
    645  RCHECK(audio_entries.size() == count);
    646  } else if (type == kText) {
    647  RCHECK(reader->ReadAllChildren(&text_entries));
    648  RCHECK(text_entries.size() == count);
    649  }
    650  } else {
    651  DCHECK_LT(0u, count);
    652  if (type == kVideo) {
    653  for (uint32_t i = 0; i < count; ++i)
    654  RCHECK(buffer->ReadWriteChild(&video_entries[i]));
    655  } else if (type == kAudio) {
    656  for (uint32_t i = 0; i < count; ++i)
    657  RCHECK(buffer->ReadWriteChild(&audio_entries[i]));
    658  } else if (type == kText) {
    659  for (uint32_t i = 0; i < count; ++i)
    660  RCHECK(buffer->ReadWriteChild(&text_entries[i]));
    661  } else {
    662  NOTIMPLEMENTED();
    663  }
    664  }
    665  return true;
    666 }
    667 
    668 size_t SampleDescription::ComputeSizeInternal() {
    669  size_t box_size = HeaderSize() + sizeof(uint32_t);
    670  if (type == kVideo) {
    671  for (uint32_t i = 0; i < video_entries.size(); ++i)
    672  box_size += video_entries[i].ComputeSize();
    673  } else if (type == kAudio) {
    674  for (uint32_t i = 0; i < audio_entries.size(); ++i)
    675  box_size += audio_entries[i].ComputeSize();
    676  } else if (type == kText) {
    677  for (uint32_t i = 0; i < text_entries.size(); ++i)
    678  box_size += text_entries[i].ComputeSize();
    679  }
    680  return box_size;
    681 }
    682 
    683 DecodingTimeToSample::DecodingTimeToSample() = default;
    684 DecodingTimeToSample::~DecodingTimeToSample() = default;
    685 
    687  return FOURCC_stts;
    688 }
    689 
    690 bool DecodingTimeToSample::ReadWriteInternal(BoxBuffer* buffer) {
    691  uint32_t count = static_cast<uint32_t>(decoding_time.size());
    692  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    693 
    694  decoding_time.resize(count);
    695  for (uint32_t i = 0; i < count; ++i) {
    696  RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
    697  buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
    698  }
    699  return true;
    700 }
    701 
    702 size_t DecodingTimeToSample::ComputeSizeInternal() {
    703  return HeaderSize() + sizeof(uint32_t) +
    704  sizeof(DecodingTime) * decoding_time.size();
    705 }
    706 
    707 CompositionTimeToSample::CompositionTimeToSample() = default;
    708 CompositionTimeToSample::~CompositionTimeToSample() = default;
    709 
    711  return FOURCC_ctts;
    712 }
    713 
    714 bool CompositionTimeToSample::ReadWriteInternal(BoxBuffer* buffer) {
    715  uint32_t count = static_cast<uint32_t>(composition_offset.size());
    716  if (!buffer->Reading()) {
    717  // Determine whether version 0 or version 1 should be used.
    718  // Use version 0 if possible, use version 1 if there is a negative
    719  // sample_offset value.
    720  version = 0;
    721  for (uint32_t i = 0; i < count; ++i) {
    722  if (composition_offset[i].sample_offset < 0) {
    723  version = 1;
    724  break;
    725  }
    726  }
    727  }
    728 
    729  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    730 
    731  composition_offset.resize(count);
    732  for (uint32_t i = 0; i < count; ++i) {
    733  RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
    734 
    735  if (version == 0) {
    736  uint32_t sample_offset = composition_offset[i].sample_offset;
    737  RCHECK(buffer->ReadWriteUInt32(&sample_offset));
    738  composition_offset[i].sample_offset = sample_offset;
    739  } else {
    740  int32_t sample_offset = composition_offset[i].sample_offset;
    741  RCHECK(buffer->ReadWriteInt32(&sample_offset));
    742  composition_offset[i].sample_offset = sample_offset;
    743  }
    744  }
    745  return true;
    746 }
    747 
    748 size_t CompositionTimeToSample::ComputeSizeInternal() {
    749  // This box is optional. Skip it if it is empty.
    750  if (composition_offset.empty())
    751  return 0;
    752  // Structure CompositionOffset contains |sample_offset| (uint32_t) and
    753  // |sample_offset| (int64_t). The actual size of |sample_offset| is
    754  // 4 bytes (uint32_t for version 0 and int32_t for version 1).
    755  const size_t kCompositionOffsetSize = sizeof(uint32_t) * 2;
    756  return HeaderSize() + sizeof(uint32_t) +
    757  kCompositionOffsetSize * composition_offset.size();
    758 }
    759 
    760 SampleToChunk::SampleToChunk() = default;
    761 SampleToChunk::~SampleToChunk() = default;
    762 
    763 FourCC SampleToChunk::BoxType() const {
    764  return FOURCC_stsc;
    765 }
    766 
    767 bool SampleToChunk::ReadWriteInternal(BoxBuffer* buffer) {
    768  uint32_t count = static_cast<uint32_t>(chunk_info.size());
    769  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    770 
    771  chunk_info.resize(count);
    772  for (uint32_t i = 0; i < count; ++i) {
    773  RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
    774  buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
    775  buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
    776  // first_chunk values are always increasing.
    777  RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
    778  : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
    779  }
    780  return true;
    781 }
    782 
    783 size_t SampleToChunk::ComputeSizeInternal() {
    784  return HeaderSize() + sizeof(uint32_t) +
    785  sizeof(ChunkInfo) * chunk_info.size();
    786 }
    787 
    788 SampleSize::SampleSize() = default;
    789 SampleSize::~SampleSize() = default;
    790 
    791 FourCC SampleSize::BoxType() const {
    792  return FOURCC_stsz;
    793 }
    794 
    795 bool SampleSize::ReadWriteInternal(BoxBuffer* buffer) {
    796  RCHECK(ReadWriteHeaderInternal(buffer) &&
    797  buffer->ReadWriteUInt32(&sample_size) &&
    798  buffer->ReadWriteUInt32(&sample_count));
    799 
    800  if (sample_size == 0) {
    801  if (buffer->Reading())
    802  sizes.resize(sample_count);
    803  else
    804  DCHECK(sample_count == sizes.size());
    805  for (uint32_t i = 0; i < sample_count; ++i)
    806  RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
    807  }
    808  return true;
    809 }
    810 
    811 size_t SampleSize::ComputeSizeInternal() {
    812  return HeaderSize() + sizeof(sample_size) + sizeof(sample_count) +
    813  (sample_size == 0 ? sizeof(uint32_t) * sizes.size() : 0);
    814 }
    815 
    816 CompactSampleSize::CompactSampleSize() = default;
    817 CompactSampleSize::~CompactSampleSize() = default;
    818 
    820  return FOURCC_stz2;
    821 }
    822 
    823 bool CompactSampleSize::ReadWriteInternal(BoxBuffer* buffer) {
    824  uint32_t sample_count = static_cast<uint32_t>(sizes.size());
    825  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->IgnoreBytes(3) &&
    826  buffer->ReadWriteUInt8(&field_size) &&
    827  buffer->ReadWriteUInt32(&sample_count));
    828 
    829  // Reserve one more entry if field size is 4 bits.
    830  sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
    831  switch (field_size) {
    832  case 4:
    833  for (uint32_t i = 0; i < sample_count; i += 2) {
    834  if (buffer->Reading()) {
    835  uint8_t size = 0;
    836  RCHECK(buffer->ReadWriteUInt8(&size));
    837  sizes[i] = size >> 4;
    838  sizes[i + 1] = size & 0x0F;
    839  } else {
    840  DCHECK_LT(sizes[i], 16u);
    841  DCHECK_LT(sizes[i + 1], 16u);
    842  uint8_t size = (sizes[i] << 4) | sizes[i + 1];
    843  RCHECK(buffer->ReadWriteUInt8(&size));
    844  }
    845  }
    846  break;
    847  case 8:
    848  for (uint32_t i = 0; i < sample_count; ++i) {
    849  uint8_t size = sizes[i];
    850  RCHECK(buffer->ReadWriteUInt8(&size));
    851  sizes[i] = size;
    852  }
    853  break;
    854  case 16:
    855  for (uint32_t i = 0; i < sample_count; ++i) {
    856  uint16_t size = sizes[i];
    857  RCHECK(buffer->ReadWriteUInt16(&size));
    858  sizes[i] = size;
    859  }
    860  break;
    861  default:
    862  RCHECK(false);
    863  }
    864  sizes.resize(sample_count);
    865  return true;
    866 }
    867 
    868 size_t CompactSampleSize::ComputeSizeInternal() {
    869  return HeaderSize() + sizeof(uint32_t) + sizeof(uint32_t) +
    870  (field_size * sizes.size() + 7) / 8;
    871 }
    872 
    873 ChunkOffset::ChunkOffset() = default;
    874 ChunkOffset::~ChunkOffset() = default;
    875 
    876 FourCC ChunkOffset::BoxType() const {
    877  return FOURCC_stco;
    878 }
    879 
    880 bool ChunkOffset::ReadWriteInternal(BoxBuffer* buffer) {
    881  uint32_t count = static_cast<uint32_t>(offsets.size());
    882  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    883 
    884  offsets.resize(count);
    885  for (uint32_t i = 0; i < count; ++i)
    886  RCHECK(buffer->ReadWriteUInt64NBytes(&offsets[i], sizeof(uint32_t)));
    887  return true;
    888 }
    889 
    890 size_t ChunkOffset::ComputeSizeInternal() {
    891  return HeaderSize() + sizeof(uint32_t) + sizeof(uint32_t) * offsets.size();
    892 }
    893 
    894 ChunkLargeOffset::ChunkLargeOffset() = default;
    895 ChunkLargeOffset::~ChunkLargeOffset() = default;
    896 
    898  return FOURCC_co64;
    899 }
    900 
    901 bool ChunkLargeOffset::ReadWriteInternal(BoxBuffer* buffer) {
    902  uint32_t count = static_cast<uint32_t>(offsets.size());
    903 
    904  if (!buffer->Reading()) {
    905  // Switch to ChunkOffset box if it is able to fit in 32 bits offset.
    906  if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
    907  ChunkOffset stco;
    908  stco.offsets.swap(offsets);
    909  DCHECK(buffer->writer());
    910  stco.Write(buffer->writer());
    911  stco.offsets.swap(offsets);
    912  return true;
    913  }
    914  }
    915 
    916  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    917 
    918  offsets.resize(count);
    919  for (uint32_t i = 0; i < count; ++i)
    920  RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
    921  return true;
    922 }
    923 
    924 size_t ChunkLargeOffset::ComputeSizeInternal() {
    925  uint32_t count = static_cast<uint32_t>(offsets.size());
    926  int use_large_offset =
    927  (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
    928  return HeaderSize() + sizeof(count) +
    929  sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
    930 }
    931 
    932 SyncSample::SyncSample() = default;
    933 SyncSample::~SyncSample() = default;
    934 
    935 FourCC SyncSample::BoxType() const {
    936  return FOURCC_stss;
    937 }
    938 
    939 bool SyncSample::ReadWriteInternal(BoxBuffer* buffer) {
    940  uint32_t count = static_cast<uint32_t>(sample_number.size());
    941  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    942 
    943  sample_number.resize(count);
    944  for (uint32_t i = 0; i < count; ++i)
    945  RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
    946  return true;
    947 }
    948 
    949 size_t SyncSample::ComputeSizeInternal() {
    950  // Sync sample box is optional. Skip it if it is empty.
    951  if (sample_number.empty())
    952  return 0;
    953  return HeaderSize() + sizeof(uint32_t) +
    954  sizeof(uint32_t) * sample_number.size();
    955 }
    956 
    957 bool CencSampleEncryptionInfoEntry::ReadWrite(BoxBuffer* buffer) {
    958  if (!buffer->Reading()) {
    959  if (key_id.size() != kCencKeyIdSize) {
    960  LOG(WARNING) << "CENC defines key id length of " << kCencKeyIdSize
    961  << " bytes; got " << key_id.size()
    962  << ". Resized accordingly.";
    963  key_id.resize(kCencKeyIdSize);
    964  }
    965  RCHECK(crypt_byte_block < 16 && skip_byte_block < 16);
    966  }
    967 
    968  RCHECK(buffer->IgnoreBytes(1)); // reserved.
    969 
    970  uint8_t pattern = crypt_byte_block << 4 | skip_byte_block;
    971  RCHECK(buffer->ReadWriteUInt8(&pattern));
    972  crypt_byte_block = pattern >> 4;
    973  skip_byte_block = pattern & 0x0F;
    974 
    975  RCHECK(buffer->ReadWriteUInt8(&is_protected) &&
    976  buffer->ReadWriteUInt8(&per_sample_iv_size) &&
    977  buffer->ReadWriteVector(&key_id, kCencKeyIdSize));
    978 
    979  if (is_protected == 1) {
    980  if (per_sample_iv_size == 0) { // For constant iv.
    981  uint8_t constant_iv_size = static_cast<uint8_t>(constant_iv.size());
    982  RCHECK(buffer->ReadWriteUInt8(&constant_iv_size));
    983  RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
    984  RCHECK(buffer->ReadWriteVector(&constant_iv, constant_iv_size));
    985  } else {
    986  RCHECK(per_sample_iv_size == 8 || per_sample_iv_size == 16);
    987  DCHECK(constant_iv.empty());
    988  }
    989  } else {
    990  // Expect |is_protected| to be 0, i.e. not protected. Other values of
    991  // |is_protected| is not supported.
    992  RCHECK(is_protected == 0);
    993  RCHECK(per_sample_iv_size == 0);
    994  }
    995  return true;
    996 }
    997 
    998 uint32_t CencSampleEncryptionInfoEntry::ComputeSize() const {
    999  return static_cast<uint32_t>(
    1000  sizeof(uint32_t) + kCencKeyIdSize +
    1001  (constant_iv.empty() ? 0 : (sizeof(uint8_t) + constant_iv.size())));
    1002 }
    1003 
    1004 bool AudioRollRecoveryEntry::ReadWrite(BoxBuffer* buffer) {
    1005  RCHECK(buffer->ReadWriteInt16(&roll_distance));
    1006  return true;
    1007 }
    1008 
    1009 uint32_t AudioRollRecoveryEntry::ComputeSize() const {
    1010  return sizeof(roll_distance);
    1011 }
    1012 
    1013 SampleGroupDescription::SampleGroupDescription() = default;
    1014 SampleGroupDescription::~SampleGroupDescription() = default;
    1015 
    1017  return FOURCC_sgpd;
    1018 }
    1019 
    1020 bool SampleGroupDescription::ReadWriteInternal(BoxBuffer* buffer) {
    1021  RCHECK(ReadWriteHeaderInternal(buffer) &&
    1022  buffer->ReadWriteUInt32(&grouping_type));
    1023 
    1024  switch (grouping_type) {
    1025  case FOURCC_seig:
    1026  return ReadWriteEntries(buffer, &cenc_sample_encryption_info_entries);
    1027  case FOURCC_roll:
    1028  return ReadWriteEntries(buffer, &audio_roll_recovery_entries);
    1029  default:
    1030  DCHECK(buffer->Reading());
    1031  DLOG(WARNING) << "Ignore unsupported sample group: "
    1032  << FourCCToString(static_cast<FourCC>(grouping_type));
    1033  return true;
    1034  }
    1035 }
    1036 
    1037 template <typename T>
    1038 bool SampleGroupDescription::ReadWriteEntries(BoxBuffer* buffer,
    1039  std::vector<T>* entries) {
    1040  uint32_t default_length = 0;
    1041  if (!buffer->Reading()) {
    1042  DCHECK(!entries->empty());
    1043  default_length = (*entries)[0].ComputeSize();
    1044  DCHECK_NE(default_length, 0u);
    1045  }
    1046  if (version == 1)
    1047  RCHECK(buffer->ReadWriteUInt32(&default_length));
    1048  if (version >= 2) {
    1049  NOTIMPLEMENTED() << "Unsupported SampleGroupDescriptionBox 'sgpd' version "
    1050  << static_cast<int>(version);
    1051  return false;
    1052  }
    1053 
    1054  uint32_t count = static_cast<uint32_t>(entries->size());
    1055  RCHECK(buffer->ReadWriteUInt32(&count));
    1056  RCHECK(count != 0);
    1057  entries->resize(count);
    1058 
    1059  for (T& entry : *entries) {
    1060  if (version == 1) {
    1061  uint32_t description_length = default_length;
    1062  if (buffer->Reading() && default_length == 0)
    1063  RCHECK(buffer->ReadWriteUInt32(&description_length));
    1064  RCHECK(entry.ReadWrite(buffer));
    1065  RCHECK(entry.ComputeSize() == description_length);
    1066  } else {
    1067  RCHECK(entry.ReadWrite(buffer));
    1068  }
    1069  }
    1070  return true;
    1071 }
    1072 
    1073 size_t SampleGroupDescription::ComputeSizeInternal() {
    1074  // Version 0 is obsoleted, so always generate version 1 box.
    1075  version = 1;
    1076  size_t entries_size = 0;
    1077  switch (grouping_type) {
    1078  case FOURCC_seig:
    1079  for (const auto& entry : cenc_sample_encryption_info_entries)
    1080  entries_size += entry.ComputeSize();
    1081  break;
    1082  case FOURCC_roll:
    1083  for (const auto& entry : audio_roll_recovery_entries)
    1084  entries_size += entry.ComputeSize();
    1085  break;
    1086  }
    1087  // This box is optional. Skip it if it is not used.
    1088  if (entries_size == 0)
    1089  return 0;
    1090  return HeaderSize() + sizeof(grouping_type) +
    1091  (version == 1 ? sizeof(uint32_t) : 0) + sizeof(uint32_t) +
    1092  entries_size;
    1093 }
    1094 
    1095 SampleToGroup::SampleToGroup() = default;
    1096 SampleToGroup::~SampleToGroup() = default;
    1097 
    1098 FourCC SampleToGroup::BoxType() const {
    1099  return FOURCC_sbgp;
    1100 }
    1101 
    1102 bool SampleToGroup::ReadWriteInternal(BoxBuffer* buffer) {
    1103  RCHECK(ReadWriteHeaderInternal(buffer) &&
    1104  buffer->ReadWriteUInt32(&grouping_type));
    1105  if (version == 1)
    1106  RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
    1107 
    1108  if (grouping_type != FOURCC_seig && grouping_type != FOURCC_roll) {
    1109  DCHECK(buffer->Reading());
    1110  DLOG(WARNING) << "Ignore unsupported sample group: "
    1111  << FourCCToString(static_cast<FourCC>(grouping_type));
    1112  return true;
    1113  }
    1114 
    1115  uint32_t count = static_cast<uint32_t>(entries.size());
    1116  RCHECK(buffer->ReadWriteUInt32(&count));
    1117  entries.resize(count);
    1118  for (uint32_t i = 0; i < count; ++i) {
    1119  RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
    1120  buffer->ReadWriteUInt32(&entries[i].group_description_index));
    1121  }
    1122  return true;
    1123 }
    1124 
    1125 size_t SampleToGroup::ComputeSizeInternal() {
    1126  // This box is optional. Skip it if it is not used.
    1127  if (entries.empty())
    1128  return 0;
    1129  return HeaderSize() + sizeof(grouping_type) +
    1130  (version == 1 ? sizeof(grouping_type_parameter) : 0) +
    1131  sizeof(uint32_t) + entries.size() * sizeof(entries[0]);
    1132 }
    1133 
    1134 SampleTable::SampleTable() = default;
    1135 SampleTable::~SampleTable() = default;
    1136 
    1137 FourCC SampleTable::BoxType() const {
    1138  return FOURCC_stbl;
    1139 }
    1140 
    1141 bool SampleTable::ReadWriteInternal(BoxBuffer* buffer) {
    1142  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    1143  buffer->ReadWriteChild(&description) &&
    1144  buffer->ReadWriteChild(&decoding_time_to_sample) &&
    1145  buffer->TryReadWriteChild(&composition_time_to_sample) &&
    1146  buffer->ReadWriteChild(&sample_to_chunk));
    1147 
    1148  if (buffer->Reading()) {
    1149  BoxReader* reader = buffer->reader();
    1150  DCHECK(reader);
    1151 
    1152  // Either SampleSize or CompactSampleSize must present.
    1153  if (reader->ChildExist(&sample_size)) {
    1154  RCHECK(reader->ReadChild(&sample_size));
    1155  } else {
    1156  CompactSampleSize compact_sample_size;
    1157  RCHECK(reader->ReadChild(&compact_sample_size));
    1158  sample_size.sample_size = 0;
    1159  sample_size.sample_count =
    1160  static_cast<uint32_t>(compact_sample_size.sizes.size());
    1161  sample_size.sizes.swap(compact_sample_size.sizes);
    1162  }
    1163 
    1164  // Either ChunkOffset or ChunkLargeOffset must present.
    1165  if (reader->ChildExist(&chunk_large_offset)) {
    1166  RCHECK(reader->ReadChild(&chunk_large_offset));
    1167  } else {
    1168  ChunkOffset chunk_offset;
    1169  RCHECK(reader->ReadChild(&chunk_offset));
    1170  chunk_large_offset.offsets.swap(chunk_offset.offsets);
    1171  }
    1172  } else {
    1173  RCHECK(buffer->ReadWriteChild(&sample_size) &&
    1174  buffer->ReadWriteChild(&chunk_large_offset));
    1175  }
    1176  RCHECK(buffer->TryReadWriteChild(&sync_sample));
    1177  if (buffer->Reading()) {
    1178  RCHECK(buffer->reader()->TryReadChildren(&sample_group_descriptions) &&
    1179  buffer->reader()->TryReadChildren(&sample_to_groups));
    1180  } else {
    1181  for (auto& sample_group_description : sample_group_descriptions)
    1182  RCHECK(buffer->ReadWriteChild(&sample_group_description));
    1183  for (auto& sample_to_group : sample_to_groups)
    1184  RCHECK(buffer->ReadWriteChild(&sample_to_group));
    1185  }
    1186  return true;
    1187 }
    1188 
    1189 size_t SampleTable::ComputeSizeInternal() {
    1190  size_t box_size = HeaderSize() + description.ComputeSize() +
    1191  decoding_time_to_sample.ComputeSize() +
    1192  composition_time_to_sample.ComputeSize() +
    1193  sample_to_chunk.ComputeSize() + sample_size.ComputeSize() +
    1194  chunk_large_offset.ComputeSize() +
    1195  sync_sample.ComputeSize();
    1196  for (auto& sample_group_description : sample_group_descriptions)
    1197  box_size += sample_group_description.ComputeSize();
    1198  for (auto& sample_to_group : sample_to_groups)
    1199  box_size += sample_to_group.ComputeSize();
    1200  return box_size;
    1201 }
    1202 
    1203 EditList::EditList() = default;
    1204 EditList::~EditList() = default;
    1205 
    1206 FourCC EditList::BoxType() const {
    1207  return FOURCC_elst;
    1208 }
    1209 
    1210 bool EditList::ReadWriteInternal(BoxBuffer* buffer) {
    1211  uint32_t count = static_cast<uint32_t>(edits.size());
    1212  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    1213  edits.resize(count);
    1214 
    1215  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    1216  for (uint32_t i = 0; i < count; ++i) {
    1217  RCHECK(
    1218  buffer->ReadWriteUInt64NBytes(&edits[i].segment_duration, num_bytes) &&
    1219  buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
    1220  buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
    1221  buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
    1222  }
    1223  return true;
    1224 }
    1225 
    1226 size_t EditList::ComputeSizeInternal() {
    1227  // EditList box is optional. Skip it if it is empty.
    1228  if (edits.empty())
    1229  return 0;
    1230 
    1231  version = 0;
    1232  for (uint32_t i = 0; i < edits.size(); ++i) {
    1233  if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
    1234  version = 1;
    1235  break;
    1236  }
    1237  }
    1238  return HeaderSize() + sizeof(uint32_t) +
    1239  (sizeof(uint32_t) * (1 + version) * 2 + sizeof(int16_t) * 2) *
    1240  edits.size();
    1241 }
    1242 
    1243 Edit::Edit() = default;
    1244 Edit::~Edit() = default;
    1245 
    1246 FourCC Edit::BoxType() const {
    1247  return FOURCC_edts;
    1248 }
    1249 
    1250 bool Edit::ReadWriteInternal(BoxBuffer* buffer) {
    1251  return ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    1252  buffer->ReadWriteChild(&list);
    1253 }
    1254 
    1255 size_t Edit::ComputeSizeInternal() {
    1256  // Edit box is optional. Skip it if it is empty.
    1257  if (list.edits.empty())
    1258  return 0;
    1259  return HeaderSize() + list.ComputeSize();
    1260 }
    1261 
    1262 HandlerReference::HandlerReference() = default;
    1263 HandlerReference::~HandlerReference() = default;
    1264 
    1266  return FOURCC_hdlr;
    1267 }
    1268 
    1269 bool HandlerReference::ReadWriteInternal(BoxBuffer* buffer) {
    1270  std::vector<uint8_t> handler_name;
    1271  if (!buffer->Reading()) {
    1272  switch (handler_type) {
    1273  case FOURCC_vide:
    1274  handler_name.assign(kVideoHandlerName,
    1275  kVideoHandlerName + arraysize(kVideoHandlerName));
    1276  break;
    1277  case FOURCC_soun:
    1278  handler_name.assign(kAudioHandlerName,
    1279  kAudioHandlerName + arraysize(kAudioHandlerName));
    1280  break;
    1281  case FOURCC_text:
    1282  handler_name.assign(kTextHandlerName,
    1283  kTextHandlerName + arraysize(kTextHandlerName));
    1284  break;
    1285  case FOURCC_ID32:
    1286  break;
    1287  default:
    1288  NOTIMPLEMENTED();
    1289  return false;
    1290  }
    1291  }
    1292  RCHECK(ReadWriteHeaderInternal(buffer) &&
    1293  buffer->IgnoreBytes(4) && // predefined.
    1294  buffer->ReadWriteFourCC(&handler_type));
    1295  if (!buffer->Reading()) {
    1296  RCHECK(buffer->IgnoreBytes(12) && // reserved.
    1297  buffer->ReadWriteVector(&handler_name, handler_name.size()));
    1298  }
    1299  return true;
    1300 }
    1301 
    1302 size_t HandlerReference::ComputeSizeInternal() {
    1303  size_t box_size = HeaderSize() + kFourCCSize + 16; // 16 bytes Reserved
    1304  switch (handler_type) {
    1305  case FOURCC_vide:
    1306  box_size += sizeof(kVideoHandlerName);
    1307  break;
    1308  case FOURCC_soun:
    1309  box_size += sizeof(kAudioHandlerName);
    1310  break;
    1311  case FOURCC_text:
    1312  box_size += sizeof(kTextHandlerName);
    1313  break;
    1314  case FOURCC_ID32:
    1315  break;
    1316  default:
    1317  NOTIMPLEMENTED();
    1318  }
    1319  return box_size;
    1320 }
    1321 
    1322 bool Language::ReadWrite(BoxBuffer* buffer) {
    1323  if (buffer->Reading()) {
    1324  // Read language codes into temp first then use BitReader to read the
    1325  // values. ISO-639-2/T language code: unsigned int(5)[3] language (2 bytes).
    1326  std::vector<uint8_t> temp;
    1327  RCHECK(buffer->ReadWriteVector(&temp, 2));
    1328 
    1329  BitReader bit_reader(&temp[0], 2);
    1330  bit_reader.SkipBits(1);
    1331  char language[3];
    1332  for (int i = 0; i < 3; ++i) {
    1333  CHECK(bit_reader.ReadBits(5, &language[i]));
    1334  language[i] += 0x60;
    1335  }
    1336  code.assign(language, 3);
    1337  } else {
    1338  // Set up default language if it is not set.
    1339  const char kUndefinedLanguage[] = "und";
    1340  if (code.empty())
    1341  code = kUndefinedLanguage;
    1342  DCHECK_EQ(code.size(), 3u);
    1343 
    1344  // Lang format: bit(1) pad, unsigned int(5)[3] language.
    1345  uint16_t lang = 0;
    1346  for (int i = 0; i < 3; ++i)
    1347  lang |= (code[i] - 0x60) << ((2 - i) * 5);
    1348  RCHECK(buffer->ReadWriteUInt16(&lang));
    1349  }
    1350  return true;
    1351 }
    1352 
    1353 uint32_t Language::ComputeSize() const {
    1354  // ISO-639-2/T language code: unsigned int(5)[3] language (2 bytes).
    1355  return 2;
    1356 }
    1357 
    1358 ID3v2::ID3v2() = default;
    1359 ID3v2::~ID3v2() = default;
    1360 
    1361 FourCC ID3v2::BoxType() const {
    1362  return FOURCC_ID32;
    1363 }
    1364 
    1365 bool ID3v2::ReadWriteInternal(BoxBuffer* buffer) {
    1366  RCHECK(ReadWriteHeaderInternal(buffer) && language.ReadWrite(buffer) &&
    1367  buffer->ReadWriteVector(&id3v2_data, buffer->Reading()
    1368  ? buffer->BytesLeft()
    1369  : id3v2_data.size()));
    1370  return true;
    1371 }
    1372 
    1373 size_t ID3v2::ComputeSizeInternal() {
    1374  // Skip ID3v2 box generation if there is no id3 data.
    1375  return id3v2_data.size() == 0
    1376  ? 0
    1377  : HeaderSize() + language.ComputeSize() + id3v2_data.size();
    1378 }
    1379 
    1380 Metadata::Metadata() = default;
    1381 Metadata::~Metadata() = default;
    1382 
    1383 FourCC Metadata::BoxType() const {
    1384  return FOURCC_meta;
    1385 }
    1386 
    1387 bool Metadata::ReadWriteInternal(BoxBuffer* buffer) {
    1388  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    1389  buffer->ReadWriteChild(&handler) && buffer->TryReadWriteChild(&id3v2));
    1390  return true;
    1391 }
    1392 
    1393 size_t Metadata::ComputeSizeInternal() {
    1394  size_t id3v2_size = id3v2.ComputeSize();
    1395  // Skip metadata box generation if there is no metadata box.
    1396  return id3v2_size == 0 ? 0
    1397  : HeaderSize() + handler.ComputeSize() + id3v2_size;
    1398 }
    1399 
    1400 CodecConfiguration::CodecConfiguration() = default;
    1401 CodecConfiguration::~CodecConfiguration() = default;
    1402 
    1404  // CodecConfiguration box should be parsed according to format recovered in
    1405  // VideoSampleEntry. |box_type| is determined dynamically there.
    1406  return box_type;
    1407 }
    1408 
    1409 bool CodecConfiguration::ReadWriteInternal(BoxBuffer* buffer) {
    1410  DCHECK_NE(box_type, FOURCC_NULL);
    1411  RCHECK(ReadWriteHeaderInternal(buffer));
    1412 
    1413  // VPCodecConfiguration box inherits from FullBox instead of Box. The extra 4
    1414  // bytes are handled here.
    1415  if (box_type == FOURCC_vpcC) {
    1416  // Only version 1 box is supported.
    1417  uint8_t vpcc_version = 1;
    1418  uint32_t version_flags = vpcc_version << 24;
    1419  RCHECK(buffer->ReadWriteUInt32(&version_flags));
    1420  vpcc_version = version_flags >> 24;
    1421  RCHECK(vpcc_version == 1);
    1422  }
    1423 
    1424  if (buffer->Reading()) {
    1425  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
    1426  } else {
    1427  RCHECK(buffer->ReadWriteVector(&data, data.size()));
    1428  }
    1429  return true;
    1430 }
    1431 
    1432 size_t CodecConfiguration::ComputeSizeInternal() {
    1433  if (data.empty())
    1434  return 0;
    1435  DCHECK_NE(box_type, FOURCC_NULL);
    1436  return HeaderSize() + (box_type == FOURCC_vpcC ? 4 : 0) + data.size();
    1437 }
    1438 
    1439 PixelAspectRatio::PixelAspectRatio() = default;
    1440 PixelAspectRatio::~PixelAspectRatio() = default;
    1441 
    1443  return FOURCC_pasp;
    1444 }
    1445 
    1446 bool PixelAspectRatio::ReadWriteInternal(BoxBuffer* buffer) {
    1447  RCHECK(ReadWriteHeaderInternal(buffer) &&
    1448  buffer->ReadWriteUInt32(&h_spacing) &&
    1449  buffer->ReadWriteUInt32(&v_spacing));
    1450  return true;
    1451 }
    1452 
    1453 size_t PixelAspectRatio::ComputeSizeInternal() {
    1454  // This box is optional. Skip it if it is not initialized.
    1455  if (h_spacing == 0 && v_spacing == 0)
    1456  return 0;
    1457  // Both values must be positive.
    1458  DCHECK(h_spacing != 0 && v_spacing != 0);
    1459  return HeaderSize() + sizeof(h_spacing) + sizeof(v_spacing);
    1460 }
    1461 
    1462 VideoSampleEntry::VideoSampleEntry() = default;
    1463 VideoSampleEntry::~VideoSampleEntry() = default;
    1464 
    1466  if (format == FOURCC_NULL) {
    1467  LOG(ERROR) << "VideoSampleEntry should be parsed according to the "
    1468  << "handler type recovered in its Media ancestor.";
    1469  }
    1470  return format;
    1471 }
    1472 
    1473 bool VideoSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
    1474  std::vector<uint8_t> compressor_name;
    1475  if (buffer->Reading()) {
    1476  DCHECK(buffer->reader());
    1477  format = buffer->reader()->type();
    1478  } else {
    1479  RCHECK(ReadWriteHeaderInternal(buffer));
    1480 
    1481  const FourCC actual_format = GetActualFormat();
    1482  switch (actual_format) {
    1483  case FOURCC_av01:
    1484  compressor_name.assign(std::begin(kAv1CompressorName),
    1485  std::end(kAv1CompressorName));
    1486  break;
    1487  case FOURCC_avc1:
    1488  case FOURCC_avc3:
    1489  compressor_name.assign(std::begin(kAvcCompressorName),
    1490  std::end(kAvcCompressorName));
    1491  break;
    1492  case FOURCC_dvh1:
    1493  case FOURCC_dvhe:
    1494  compressor_name.assign(std::begin(kDolbyVisionCompressorName),
    1495  std::end(kDolbyVisionCompressorName));
    1496  break;
    1497  case FOURCC_hev1:
    1498  case FOURCC_hvc1:
    1499  compressor_name.assign(std::begin(kHevcCompressorName),
    1500  std::end(kHevcCompressorName));
    1501  break;
    1502  case FOURCC_vp08:
    1503  case FOURCC_vp09:
    1504  compressor_name.assign(std::begin(kVpcCompressorName),
    1505  std::end(kVpcCompressorName));
    1506  break;
    1507  default:
    1508  LOG(ERROR) << FourCCToString(actual_format) << " is not supported.";
    1509  return false;
    1510  }
    1511  compressor_name.resize(kCompressorNameSize);
    1512  }
    1513 
    1514  uint32_t video_resolution = kVideoResolution;
    1515  uint16_t video_frame_count = kVideoFrameCount;
    1516  uint16_t video_depth = kVideoDepth;
    1517  int16_t predefined = -1;
    1518  RCHECK(buffer->IgnoreBytes(6) && // reserved.
    1519  buffer->ReadWriteUInt16(&data_reference_index) &&
    1520  buffer->IgnoreBytes(16) && // predefined 0.
    1521  buffer->ReadWriteUInt16(&width) && buffer->ReadWriteUInt16(&height) &&
    1522  buffer->ReadWriteUInt32(&video_resolution) &&
    1523  buffer->ReadWriteUInt32(&video_resolution) &&
    1524  buffer->IgnoreBytes(4) && // reserved.
    1525  buffer->ReadWriteUInt16(&video_frame_count) &&
    1526  buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
    1527  buffer->ReadWriteUInt16(&video_depth) &&
    1528  buffer->ReadWriteInt16(&predefined));
    1529 
    1530  RCHECK(buffer->PrepareChildren());
    1531 
    1532  // This has to happen before reading codec configuration box as the actual
    1533  // format is read from sinf.format.format, which is needed to parse the codec
    1534  // configuration box.
    1535  if (format == FOURCC_encv && buffer->Reading()) {
    1536  // Continue scanning until a supported protection scheme is found, or
    1537  // until we run out of protection schemes.
    1538  while (!IsProtectionSchemeSupported(sinf.type.type))
    1539  RCHECK(buffer->ReadWriteChild(&sinf));
    1540  }
    1541 
    1542  const FourCC actual_format = GetActualFormat();
    1543  if (buffer->Reading()) {
    1544  codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
    1545  } else {
    1546  DCHECK_EQ(codec_configuration.box_type,
    1547  GetCodecConfigurationBoxType(actual_format));
    1548  }
    1549  if (codec_configuration.box_type == FOURCC_NULL)
    1550  return false;
    1551 
    1552  RCHECK(buffer->ReadWriteChild(&codec_configuration));
    1553 
    1554  if (buffer->Reading()) {
    1555  extra_codec_configs.clear();
    1556  // Handle Dolby Vision boxes.
    1557  const bool is_hevc =
    1558  actual_format == FOURCC_dvhe || actual_format == FOURCC_dvh1 ||
    1559  actual_format == FOURCC_hev1 || actual_format == FOURCC_hvc1;
    1560  if (is_hevc) {
    1561  for (FourCC fourcc : {FOURCC_dvcC, FOURCC_dvvC, FOURCC_hvcE}) {
    1562  CodecConfiguration dv_box;
    1563  dv_box.box_type = fourcc;
    1564  RCHECK(buffer->TryReadWriteChild(&dv_box));
    1565  if (!dv_box.data.empty())
    1566  extra_codec_configs.push_back(std::move(dv_box));
    1567  }
    1568  }
    1569  } else {
    1570  for (CodecConfiguration& extra_codec_config : extra_codec_configs)
    1571  RCHECK(buffer->ReadWriteChild(&extra_codec_config));
    1572  }
    1573 
    1574  RCHECK(buffer->TryReadWriteChild(&pixel_aspect));
    1575 
    1576  // Somehow Edge does not support having sinf box before codec_configuration,
    1577  // box, so just do it in the end of VideoSampleEntry. See
    1578  // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12658991/
    1579  if (format == FOURCC_encv && !buffer->Reading()) {
    1580  DCHECK(IsProtectionSchemeSupported(sinf.type.type));
    1581  RCHECK(buffer->ReadWriteChild(&sinf));
    1582  }
    1583  return true;
    1584 }
    1585 
    1586 size_t VideoSampleEntry::ComputeSizeInternal() {
    1587  const FourCC actual_format = GetActualFormat();
    1588  if (actual_format == FOURCC_NULL)
    1589  return 0;
    1590  codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
    1591  DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
    1592  size_t size = HeaderSize() + sizeof(data_reference_index) + sizeof(width) +
    1593  sizeof(height) + sizeof(kVideoResolution) * 2 +
    1594  sizeof(kVideoFrameCount) + sizeof(kVideoDepth) +
    1595  pixel_aspect.ComputeSize() + sinf.ComputeSize() +
    1596  codec_configuration.ComputeSize() + kCompressorNameSize + 6 +
    1597  4 + 16 + 2; // 6 + 4 bytes reserved, 16 + 2 bytes predefined.
    1598  for (CodecConfiguration& codec_config : extra_codec_configs)
    1599  size += codec_config.ComputeSize();
    1600  return size;
    1601 }
    1602 
    1603 FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC format) const {
    1604  switch (format) {
    1605  case FOURCC_av01:
    1606  return FOURCC_av1C;
    1607  case FOURCC_avc1:
    1608  case FOURCC_avc3:
    1609  return FOURCC_avcC;
    1610  case FOURCC_dvh1:
    1611  case FOURCC_dvhe:
    1612  case FOURCC_hev1:
    1613  case FOURCC_hvc1:
    1614  return FOURCC_hvcC;
    1615  case FOURCC_vp08:
    1616  case FOURCC_vp09:
    1617  return FOURCC_vpcC;
    1618  default:
    1619  LOG(ERROR) << FourCCToString(format) << " is not supported.";
    1620  return FOURCC_NULL;
    1621  }
    1622 }
    1623 
    1624 std::vector<uint8_t> VideoSampleEntry::ExtraCodecConfigsAsVector() const {
    1625  BufferWriter buffer;
    1626  for (CodecConfiguration codec_config : extra_codec_configs)
    1627  codec_config.Write(&buffer);
    1628  return std::vector<uint8_t>(buffer.Buffer(), buffer.Buffer() + buffer.Size());
    1629 }
    1630 
    1631 bool VideoSampleEntry::ParseExtraCodecConfigsVector(
    1632  const std::vector<uint8_t>& data) {
    1633  extra_codec_configs.clear();
    1634  size_t pos = 0;
    1635  while (pos < data.size()) {
    1636  bool err = false;
    1637  std::unique_ptr<BoxReader> box_reader(
    1638  BoxReader::ReadBox(data.data() + pos, data.size() - pos, &err));
    1639  RCHECK(!err && box_reader);
    1640 
    1641  CodecConfiguration codec_config;
    1642  codec_config.box_type = box_reader->type();
    1643  RCHECK(codec_config.Parse(box_reader.get()));
    1644  extra_codec_configs.push_back(std::move(codec_config));
    1645 
    1646  pos += box_reader->pos();
    1647  }
    1648  return true;
    1649 }
    1650 
    1651 ElementaryStreamDescriptor::ElementaryStreamDescriptor() = default;
    1652 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() = default;
    1653 
    1655  return FOURCC_esds;
    1656 }
    1657 
    1658 bool ElementaryStreamDescriptor::ReadWriteInternal(BoxBuffer* buffer) {
    1659  RCHECK(ReadWriteHeaderInternal(buffer));
    1660  if (buffer->Reading()) {
    1661  std::vector<uint8_t> data;
    1662  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
    1663  RCHECK(es_descriptor.Parse(data));
    1664  if (es_descriptor.decoder_config_descriptor().IsAAC()) {
    1665  RCHECK(aac_audio_specific_config.Parse(
    1666  es_descriptor.decoder_config_descriptor()
    1667  .decoder_specific_info_descriptor()
    1668  .data()));
    1669  }
    1670  } else {
    1671  DCHECK(buffer->writer());
    1672  es_descriptor.Write(buffer->writer());
    1673  }
    1674  return true;
    1675 }
    1676 
    1677 size_t ElementaryStreamDescriptor::ComputeSizeInternal() {
    1678  // This box is optional. Skip it if not initialized.
    1679  if (es_descriptor.decoder_config_descriptor().object_type() ==
    1680  ObjectType::kForbidden) {
    1681  return 0;
    1682  }
    1683  return HeaderSize() + es_descriptor.ComputeSize();
    1684 }
    1685 
    1686 DTSSpecific::DTSSpecific() = default;
    1687 DTSSpecific::~DTSSpecific() = default;
    1688 ;
    1689 
    1690 FourCC DTSSpecific::BoxType() const {
    1691  return FOURCC_ddts;
    1692 }
    1693 
    1694 bool DTSSpecific::ReadWriteInternal(BoxBuffer* buffer) {
    1695  RCHECK(ReadWriteHeaderInternal(buffer) &&
    1696  buffer->ReadWriteUInt32(&sampling_frequency) &&
    1697  buffer->ReadWriteUInt32(&max_bitrate) &&
    1698  buffer->ReadWriteUInt32(&avg_bitrate) &&
    1699  buffer->ReadWriteUInt8(&pcm_sample_depth));
    1700 
    1701  if (buffer->Reading()) {
    1702  RCHECK(buffer->ReadWriteVector(&extra_data, buffer->BytesLeft()));
    1703  } else {
    1704  if (extra_data.empty()) {
    1705  extra_data.assign(kDdtsExtraData,
    1706  kDdtsExtraData + sizeof(kDdtsExtraData));
    1707  }
    1708  RCHECK(buffer->ReadWriteVector(&extra_data, extra_data.size()));
    1709  }
    1710  return true;
    1711 }
    1712 
    1713 size_t DTSSpecific::ComputeSizeInternal() {
    1714  // This box is optional. Skip it if not initialized.
    1715  if (sampling_frequency == 0)
    1716  return 0;
    1717  return HeaderSize() + sizeof(sampling_frequency) + sizeof(max_bitrate) +
    1718  sizeof(avg_bitrate) + sizeof(pcm_sample_depth) +
    1719  sizeof(kDdtsExtraData);
    1720 }
    1721 
    1722 AC3Specific::AC3Specific() = default;
    1723 AC3Specific::~AC3Specific() = default;
    1724 
    1725 FourCC AC3Specific::BoxType() const {
    1726  return FOURCC_dac3;
    1727 }
    1728 
    1729 bool AC3Specific::ReadWriteInternal(BoxBuffer* buffer) {
    1730  RCHECK(ReadWriteHeaderInternal(buffer) &&
    1731  buffer->ReadWriteVector(
    1732  &data, buffer->Reading() ? buffer->BytesLeft() : data.size()));
    1733  return true;
    1734 }
    1735 
    1736 size_t AC3Specific::ComputeSizeInternal() {
    1737  // This box is optional. Skip it if not initialized.
    1738  if (data.empty())
    1739  return 0;
    1740  return HeaderSize() + data.size();
    1741 }
    1742 
    1743 EC3Specific::EC3Specific() = default;
    1744 EC3Specific::~EC3Specific() = default;
    1745 
    1746 FourCC EC3Specific::BoxType() const {
    1747  return FOURCC_dec3;
    1748 }
    1749 
    1750 bool EC3Specific::ReadWriteInternal(BoxBuffer* buffer) {
    1751  RCHECK(ReadWriteHeaderInternal(buffer));
    1752  size_t size = buffer->Reading() ? buffer->BytesLeft() : data.size();
    1753  RCHECK(buffer->ReadWriteVector(&data, size));
    1754  return true;
    1755 }
    1756 
    1757 size_t EC3Specific::ComputeSizeInternal() {
    1758  // This box is optional. Skip it if not initialized.
    1759  if (data.empty())
    1760  return 0;
    1761  return HeaderSize() + data.size();
    1762 }
    1763 
    1764 OpusSpecific::OpusSpecific() = default;
    1765 OpusSpecific::~OpusSpecific() = default;
    1766 
    1767 FourCC OpusSpecific::BoxType() const {
    1768  return FOURCC_dOps;
    1769 }
    1770 
    1771 bool OpusSpecific::ReadWriteInternal(BoxBuffer* buffer) {
    1772  RCHECK(ReadWriteHeaderInternal(buffer));
    1773  if (buffer->Reading()) {
    1774  std::vector<uint8_t> data;
    1775  const int kMinOpusSpecificBoxDataSize = 11;
    1776  RCHECK(buffer->BytesLeft() >= kMinOpusSpecificBoxDataSize);
    1777  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
    1778  preskip = data[2] + (data[3] << 8);
    1779 
    1780  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
    1781  BufferWriter writer;
    1782  writer.AppendInt(FOURCC_Opus);
    1783  writer.AppendInt(FOURCC_Head);
    1784  // The version must always be 1.
    1785  const uint8_t kOpusIdentificationHeaderVersion = 1;
    1786  data[0] = kOpusIdentificationHeaderVersion;
    1787  writer.AppendVector(data);
    1788  writer.SwapBuffer(&opus_identification_header);
    1789  } else {
    1790  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
    1791  // The first 8 bytes is "magic signature".
    1792  const size_t kOpusMagicSignatureSize = 8u;
    1793  DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
    1794  // https://www.opus-codec.org/docs/opus_in_isobmff.html
    1795  // The version field shall be set to 0.
    1796  const uint8_t kOpusSpecificBoxVersion = 0;
    1797  buffer->writer()->AppendInt(kOpusSpecificBoxVersion);
    1798  buffer->writer()->AppendArray(
    1799  &opus_identification_header[kOpusMagicSignatureSize + 1],
    1800  opus_identification_header.size() - kOpusMagicSignatureSize - 1);
    1801  }
    1802  return true;
    1803 }
    1804 
    1805 size_t OpusSpecific::ComputeSizeInternal() {
    1806  // This box is optional. Skip it if not initialized.
    1807  if (opus_identification_header.empty())
    1808  return 0;
    1809  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
    1810  // The first 8 bytes is "magic signature".
    1811  const size_t kOpusMagicSignatureSize = 8u;
    1812  DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
    1813  return HeaderSize() + opus_identification_header.size() -
    1814  kOpusMagicSignatureSize;
    1815 }
    1816 
    1817 FlacSpecific::FlacSpecific() = default;
    1818 FlacSpecific::~FlacSpecific() = default;
    1819 
    1820 FourCC FlacSpecific::BoxType() const {
    1821  return FOURCC_dfLa;
    1822 }
    1823 
    1824 bool FlacSpecific::ReadWriteInternal(BoxBuffer* buffer) {
    1825  RCHECK(ReadWriteHeaderInternal(buffer));
    1826  size_t size = buffer->Reading() ? buffer->BytesLeft() : data.size();
    1827  RCHECK(buffer->ReadWriteVector(&data, size));
    1828  return true;
    1829 }
    1830 
    1831 size_t FlacSpecific::ComputeSizeInternal() {
    1832  // This box is optional. Skip it if not initialized.
    1833  if (data.empty())
    1834  return 0;
    1835  return HeaderSize() + data.size();
    1836 }
    1837 
    1838 AudioSampleEntry::AudioSampleEntry() = default;
    1839 AudioSampleEntry::~AudioSampleEntry() = default;
    1840 
    1842  if (format == FOURCC_NULL) {
    1843  LOG(ERROR) << "AudioSampleEntry should be parsed according to the "
    1844  << "handler type recovered in its Media ancestor.";
    1845  }
    1846  return format;
    1847 }
    1848 
    1849 bool AudioSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
    1850  if (buffer->Reading()) {
    1851  DCHECK(buffer->reader());
    1852  format = buffer->reader()->type();
    1853  } else {
    1854  RCHECK(ReadWriteHeaderInternal(buffer));
    1855  }
    1856 
    1857  // Convert from integer to 16.16 fixed point for writing.
    1858  samplerate <<= 16;
    1859  RCHECK(buffer->IgnoreBytes(6) && // reserved.
    1860  buffer->ReadWriteUInt16(&data_reference_index) &&
    1861  buffer->IgnoreBytes(8) && // reserved.
    1862  buffer->ReadWriteUInt16(&channelcount) &&
    1863  buffer->ReadWriteUInt16(&samplesize) &&
    1864  buffer->IgnoreBytes(4) && // predefined.
    1865  buffer->ReadWriteUInt32(&samplerate));
    1866  // Convert from 16.16 fixed point to integer.
    1867  samplerate >>= 16;
    1868 
    1869  RCHECK(buffer->PrepareChildren());
    1870 
    1871  RCHECK(buffer->TryReadWriteChild(&esds));
    1872  RCHECK(buffer->TryReadWriteChild(&ddts));
    1873  RCHECK(buffer->TryReadWriteChild(&dac3));
    1874  RCHECK(buffer->TryReadWriteChild(&dec3));
    1875  RCHECK(buffer->TryReadWriteChild(&dops));
    1876  RCHECK(buffer->TryReadWriteChild(&dfla));
    1877 
    1878  // Somehow Edge does not support having sinf box before codec_configuration,
    1879  // box, so just do it in the end of AudioSampleEntry. See
    1880  // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12658991/
    1881  if (format == FOURCC_enca) {
    1882  if (buffer->Reading()) {
    1883  // Continue scanning until a supported protection scheme is found, or
    1884  // until we run out of protection schemes.
    1885  while (!IsProtectionSchemeSupported(sinf.type.type))
    1886  RCHECK(buffer->ReadWriteChild(&sinf));
    1887  } else {
    1888  DCHECK(IsProtectionSchemeSupported(sinf.type.type));
    1889  RCHECK(buffer->ReadWriteChild(&sinf));
    1890  }
    1891  }
    1892  return true;
    1893 }
    1894 
    1895 size_t AudioSampleEntry::ComputeSizeInternal() {
    1896  if (GetActualFormat() == FOURCC_NULL)
    1897  return 0;
    1898  return HeaderSize() + sizeof(data_reference_index) + sizeof(channelcount) +
    1899  sizeof(samplesize) + sizeof(samplerate) + sinf.ComputeSize() +
    1900  esds.ComputeSize() + ddts.ComputeSize() + dac3.ComputeSize() +
    1901  dec3.ComputeSize() + dops.ComputeSize() + dfla.ComputeSize() +
    1902  // Reserved and predefined bytes.
    1903  6 + 8 + // 6 + 8 bytes reserved.
    1904  4; // 4 bytes predefined.
    1905 }
    1906 
    1907 WebVTTConfigurationBox::WebVTTConfigurationBox() = default;
    1908 WebVTTConfigurationBox::~WebVTTConfigurationBox() = default;
    1909 
    1911  return FOURCC_vttC;
    1912 }
    1913 
    1914 bool WebVTTConfigurationBox::ReadWriteInternal(BoxBuffer* buffer) {
    1915  RCHECK(ReadWriteHeaderInternal(buffer));
    1916  return buffer->ReadWriteString(
    1917  &config, buffer->Reading() ? buffer->BytesLeft() : config.size());
    1918 }
    1919 
    1920 size_t WebVTTConfigurationBox::ComputeSizeInternal() {
    1921  return HeaderSize() + config.size();
    1922 }
    1923 
    1924 WebVTTSourceLabelBox::WebVTTSourceLabelBox() = default;
    1925 WebVTTSourceLabelBox::~WebVTTSourceLabelBox() = default;
    1926 
    1928  return FOURCC_vlab;
    1929 }
    1930 
    1931 bool WebVTTSourceLabelBox::ReadWriteInternal(BoxBuffer* buffer) {
    1932  RCHECK(ReadWriteHeaderInternal(buffer));
    1933  return buffer->ReadWriteString(&source_label, buffer->Reading()
    1934  ? buffer->BytesLeft()
    1935  : source_label.size());
    1936 }
    1937 
    1938 size_t WebVTTSourceLabelBox::ComputeSizeInternal() {
    1939  if (source_label.empty())
    1940  return 0;
    1941  return HeaderSize() + source_label.size();
    1942 }
    1943 
    1944 TextSampleEntry::TextSampleEntry() = default;
    1945 TextSampleEntry::~TextSampleEntry() = default;
    1946 
    1948  if (format == FOURCC_NULL) {
    1949  LOG(ERROR) << "TextSampleEntry should be parsed according to the "
    1950  << "handler type recovered in its Media ancestor.";
    1951  }
    1952  return format;
    1953 }
    1954 
    1955 bool TextSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
    1956  if (buffer->Reading()) {
    1957  DCHECK(buffer->reader());
    1958  format = buffer->reader()->type();
    1959  } else {
    1960  RCHECK(ReadWriteHeaderInternal(buffer));
    1961  }
    1962  RCHECK(buffer->IgnoreBytes(6) && // reserved for SampleEntry.
    1963  buffer->ReadWriteUInt16(&data_reference_index));
    1964 
    1965  if (format == FOURCC_wvtt) {
    1966  // TODO(rkuroiwa): Handle the optional MPEG4BitRateBox.
    1967  RCHECK(buffer->PrepareChildren() && buffer->ReadWriteChild(&config) &&
    1968  buffer->ReadWriteChild(&label));
    1969  }
    1970  return true;
    1971 }
    1972 
    1973 size_t TextSampleEntry::ComputeSizeInternal() {
    1974  // 6 for the (anonymous) reserved bytes for SampleEntry class.
    1975  return HeaderSize() + 6 + sizeof(data_reference_index) +
    1976  config.ComputeSize() + label.ComputeSize();
    1977 }
    1978 
    1979 MediaHeader::MediaHeader() = default;
    1980 MediaHeader::~MediaHeader() = default;
    1981 
    1982 FourCC MediaHeader::BoxType() const {
    1983  return FOURCC_mdhd;
    1984 }
    1985 
    1986 bool MediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    1987  RCHECK(ReadWriteHeaderInternal(buffer));
    1988 
    1989  uint8_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    1990  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
    1991  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
    1992  buffer->ReadWriteUInt32(&timescale) &&
    1993  buffer->ReadWriteUInt64NBytes(&duration, num_bytes) &&
    1994  language.ReadWrite(buffer) &&
    1995  // predefined.
    1996  buffer->IgnoreBytes(2));
    1997  return true;
    1998 }
    1999 
    2000 size_t MediaHeader::ComputeSizeInternal() {
    2001  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
    2002  return HeaderSize() + sizeof(timescale) +
    2003  sizeof(uint32_t) * (1 + version) * 3 + language.ComputeSize() +
    2004  2; // 2 bytes predefined.
    2005 }
    2006 
    2007 VideoMediaHeader::VideoMediaHeader() {
    2008  const uint32_t kVideoMediaHeaderFlags = 1;
    2009  flags = kVideoMediaHeaderFlags;
    2010 }
    2011 
    2012 VideoMediaHeader::~VideoMediaHeader() = default;
    2013 
    2015  return FOURCC_vmhd;
    2016 }
    2017 bool VideoMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    2018  RCHECK(ReadWriteHeaderInternal(buffer) &&
    2019  buffer->ReadWriteUInt16(&graphicsmode) &&
    2020  buffer->ReadWriteUInt16(&opcolor_red) &&
    2021  buffer->ReadWriteUInt16(&opcolor_green) &&
    2022  buffer->ReadWriteUInt16(&opcolor_blue));
    2023  return true;
    2024 }
    2025 
    2026 size_t VideoMediaHeader::ComputeSizeInternal() {
    2027  return HeaderSize() + sizeof(graphicsmode) + sizeof(opcolor_red) +
    2028  sizeof(opcolor_green) + sizeof(opcolor_blue);
    2029 }
    2030 
    2031 SoundMediaHeader::SoundMediaHeader() = default;
    2032 SoundMediaHeader::~SoundMediaHeader() = default;
    2033 
    2035  return FOURCC_smhd;
    2036 }
    2037 
    2038 bool SoundMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    2039  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt16(&balance) &&
    2040  buffer->IgnoreBytes(2)); // reserved.
    2041  return true;
    2042 }
    2043 
    2044 size_t SoundMediaHeader::ComputeSizeInternal() {
    2045  return HeaderSize() + sizeof(balance) + sizeof(uint16_t);
    2046 }
    2047 
    2048 SubtitleMediaHeader::SubtitleMediaHeader() = default;
    2049 SubtitleMediaHeader::~SubtitleMediaHeader() = default;
    2050 
    2052  return FOURCC_sthd;
    2053 }
    2054 
    2055 bool SubtitleMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    2056  return ReadWriteHeaderInternal(buffer);
    2057 }
    2058 
    2059 size_t SubtitleMediaHeader::ComputeSizeInternal() {
    2060  return HeaderSize();
    2061 }
    2062 
    2063 DataEntryUrl::DataEntryUrl() {
    2064  const uint32_t kDataEntryUrlFlags = 1;
    2065  flags = kDataEntryUrlFlags;
    2066 }
    2067 
    2068 DataEntryUrl::~DataEntryUrl() = default;
    2069 
    2070 FourCC DataEntryUrl::BoxType() const {
    2071  return FOURCC_url;
    2072 }
    2073 bool DataEntryUrl::ReadWriteInternal(BoxBuffer* buffer) {
    2074  RCHECK(ReadWriteHeaderInternal(buffer));
    2075  if (buffer->Reading()) {
    2076  RCHECK(buffer->ReadWriteVector(&location, buffer->BytesLeft()));
    2077  } else {
    2078  RCHECK(buffer->ReadWriteVector(&location, location.size()));
    2079  }
    2080  return true;
    2081 }
    2082 
    2083 size_t DataEntryUrl::ComputeSizeInternal() {
    2084  return HeaderSize() + location.size();
    2085 }
    2086 
    2087 DataReference::DataReference() = default;
    2088 DataReference::~DataReference() = default;
    2089 
    2090 FourCC DataReference::BoxType() const {
    2091  return FOURCC_dref;
    2092 }
    2093 bool DataReference::ReadWriteInternal(BoxBuffer* buffer) {
    2094  uint32_t entry_count = static_cast<uint32_t>(data_entry.size());
    2095  RCHECK(ReadWriteHeaderInternal(buffer) &&
    2096  buffer->ReadWriteUInt32(&entry_count));
    2097  data_entry.resize(entry_count);
    2098  RCHECK(buffer->PrepareChildren());
    2099  for (uint32_t i = 0; i < entry_count; ++i)
    2100  RCHECK(buffer->ReadWriteChild(&data_entry[i]));
    2101  return true;
    2102 }
    2103 
    2104 size_t DataReference::ComputeSizeInternal() {
    2105  uint32_t count = static_cast<uint32_t>(data_entry.size());
    2106  size_t box_size = HeaderSize() + sizeof(count);
    2107  for (uint32_t i = 0; i < count; ++i)
    2108  box_size += data_entry[i].ComputeSize();
    2109  return box_size;
    2110 }
    2111 
    2112 DataInformation::DataInformation() = default;
    2113 DataInformation::~DataInformation() = default;
    2114 
    2116  return FOURCC_dinf;
    2117 }
    2118 
    2119 bool DataInformation::ReadWriteInternal(BoxBuffer* buffer) {
    2120  return ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2121  buffer->ReadWriteChild(&dref);
    2122 }
    2123 
    2124 size_t DataInformation::ComputeSizeInternal() {
    2125  return HeaderSize() + dref.ComputeSize();
    2126 }
    2127 
    2128 MediaInformation::MediaInformation() = default;
    2129 MediaInformation::~MediaInformation() = default;
    2130 
    2132  return FOURCC_minf;
    2133 }
    2134 
    2135 bool MediaInformation::ReadWriteInternal(BoxBuffer* buffer) {
    2136  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2137  buffer->ReadWriteChild(&dinf) &&
    2138  buffer->ReadWriteChild(&sample_table));
    2139  switch (sample_table.description.type) {
    2140  case kVideo:
    2141  RCHECK(buffer->ReadWriteChild(&vmhd));
    2142  break;
    2143  case kAudio:
    2144  RCHECK(buffer->ReadWriteChild(&smhd));
    2145  break;
    2146  case kText:
    2147  RCHECK(buffer->TryReadWriteChild(&sthd));
    2148  break;
    2149  default:
    2150  NOTIMPLEMENTED();
    2151  }
    2152  // Hint is not supported for now.
    2153  return true;
    2154 }
    2155 
    2156 size_t MediaInformation::ComputeSizeInternal() {
    2157  size_t box_size =
    2158  HeaderSize() + dinf.ComputeSize() + sample_table.ComputeSize();
    2159  switch (sample_table.description.type) {
    2160  case kVideo:
    2161  box_size += vmhd.ComputeSize();
    2162  break;
    2163  case kAudio:
    2164  box_size += smhd.ComputeSize();
    2165  break;
    2166  case kText:
    2167  box_size += sthd.ComputeSize();
    2168  break;
    2169  default:
    2170  NOTIMPLEMENTED();
    2171  }
    2172  return box_size;
    2173 }
    2174 
    2175 Media::Media() = default;
    2176 Media::~Media() = default;
    2177 
    2178 FourCC Media::BoxType() const {
    2179  return FOURCC_mdia;
    2180 }
    2181 
    2182 bool Media::ReadWriteInternal(BoxBuffer* buffer) {
    2183  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2184  buffer->ReadWriteChild(&header));
    2185  if (buffer->Reading()) {
    2186  RCHECK(buffer->ReadWriteChild(&handler));
    2187  // Maddeningly, the HandlerReference box specifies how to parse the
    2188  // SampleDescription box, making the latter the only box (of those that we
    2189  // support) which cannot be parsed correctly on its own (or even with
    2190  // information from its strict ancestor tree). We thus copy the handler type
    2191  // to the sample description box *before* parsing it to provide this
    2192  // information while parsing.
    2193  information.sample_table.description.type =
    2194  FourCCToTrackType(handler.handler_type);
    2195  } else {
    2196  handler.handler_type =
    2197  TrackTypeToFourCC(information.sample_table.description.type);
    2198  RCHECK(handler.handler_type != FOURCC_NULL);
    2199  RCHECK(buffer->ReadWriteChild(&handler));
    2200  }
    2201  RCHECK(buffer->ReadWriteChild(&information));
    2202  return true;
    2203 }
    2204 
    2205 size_t Media::ComputeSizeInternal() {
    2206  handler.handler_type =
    2207  TrackTypeToFourCC(information.sample_table.description.type);
    2208  return HeaderSize() + header.ComputeSize() + handler.ComputeSize() +
    2209  information.ComputeSize();
    2210 }
    2211 
    2212 Track::Track() = default;
    2213 Track::~Track() = default;
    2214 
    2215 FourCC Track::BoxType() const {
    2216  return FOURCC_trak;
    2217 }
    2218 
    2219 bool Track::ReadWriteInternal(BoxBuffer* buffer) {
    2220  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2221  buffer->ReadWriteChild(&header) && buffer->ReadWriteChild(&media) &&
    2222  buffer->TryReadWriteChild(&edit) &&
    2223  buffer->TryReadWriteChild(&sample_encryption));
    2224  return true;
    2225 }
    2226 
    2227 size_t Track::ComputeSizeInternal() {
    2228  return HeaderSize() + header.ComputeSize() + media.ComputeSize() +
    2229  edit.ComputeSize();
    2230 }
    2231 
    2232 MovieExtendsHeader::MovieExtendsHeader() = default;
    2233 MovieExtendsHeader::~MovieExtendsHeader() = default;
    2234 
    2236  return FOURCC_mehd;
    2237 }
    2238 
    2239 bool MovieExtendsHeader::ReadWriteInternal(BoxBuffer* buffer) {
    2240  RCHECK(ReadWriteHeaderInternal(buffer));
    2241  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    2242  RCHECK(buffer->ReadWriteUInt64NBytes(&fragment_duration, num_bytes));
    2243  return true;
    2244 }
    2245 
    2246 size_t MovieExtendsHeader::ComputeSizeInternal() {
    2247  // This box is optional. Skip it if it is not used.
    2248  if (fragment_duration == 0)
    2249  return 0;
    2250  version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
    2251  return HeaderSize() + sizeof(uint32_t) * (1 + version);
    2252 }
    2253 
    2254 TrackExtends::TrackExtends() = default;
    2255 TrackExtends::~TrackExtends() = default;
    2256 
    2257 FourCC TrackExtends::BoxType() const {
    2258  return FOURCC_trex;
    2259 }
    2260 
    2261 bool TrackExtends::ReadWriteInternal(BoxBuffer* buffer) {
    2262  RCHECK(ReadWriteHeaderInternal(buffer) &&
    2263  buffer->ReadWriteUInt32(&track_id) &&
    2264  buffer->ReadWriteUInt32(&default_sample_description_index) &&
    2265  buffer->ReadWriteUInt32(&default_sample_duration) &&
    2266  buffer->ReadWriteUInt32(&default_sample_size) &&
    2267  buffer->ReadWriteUInt32(&default_sample_flags));
    2268  return true;
    2269 }
    2270 
    2271 size_t TrackExtends::ComputeSizeInternal() {
    2272  return HeaderSize() + sizeof(track_id) +
    2273  sizeof(default_sample_description_index) +
    2274  sizeof(default_sample_duration) + sizeof(default_sample_size) +
    2275  sizeof(default_sample_flags);
    2276 }
    2277 
    2278 MovieExtends::MovieExtends() = default;
    2279 MovieExtends::~MovieExtends() = default;
    2280 
    2281 FourCC MovieExtends::BoxType() const {
    2282  return FOURCC_mvex;
    2283 }
    2284 
    2285 bool MovieExtends::ReadWriteInternal(BoxBuffer* buffer) {
    2286  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2287  buffer->TryReadWriteChild(&header));
    2288  if (buffer->Reading()) {
    2289  DCHECK(buffer->reader());
    2290  RCHECK(buffer->reader()->ReadChildren(&tracks));
    2291  } else {
    2292  for (uint32_t i = 0; i < tracks.size(); ++i)
    2293  RCHECK(buffer->ReadWriteChild(&tracks[i]));
    2294  }
    2295  return true;
    2296 }
    2297 
    2298 size_t MovieExtends::ComputeSizeInternal() {
    2299  // This box is optional. Skip it if it does not contain any track.
    2300  if (tracks.size() == 0)
    2301  return 0;
    2302  size_t box_size = HeaderSize() + header.ComputeSize();
    2303  for (uint32_t i = 0; i < tracks.size(); ++i)
    2304  box_size += tracks[i].ComputeSize();
    2305  return box_size;
    2306 }
    2307 
    2308 Movie::Movie() = default;
    2309 Movie::~Movie() = default;
    2310 
    2311 FourCC Movie::BoxType() const {
    2312  return FOURCC_moov;
    2313 }
    2314 
    2315 bool Movie::ReadWriteInternal(BoxBuffer* buffer) {
    2316  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2317  buffer->ReadWriteChild(&header));
    2318  if (buffer->Reading()) {
    2319  BoxReader* reader = buffer->reader();
    2320  DCHECK(reader);
    2321  RCHECK(reader->ReadChildren(&tracks) && reader->TryReadChild(&extends) &&
    2322  reader->TryReadChildren(&pssh));
    2323  } else {
    2324  // The 'meta' box is not well formed in the video captured by Android's
    2325  // default camera app: spec indicates that it is a FullBox but it is written
    2326  // as a Box. This results in the box failed to be parsed. See
    2327  // https://github.com/google/shaka-packager/issues/319 for details.
    2328  // We do not care the content of metadata box in the source content, so just
    2329  // skip reading the box.
    2330  RCHECK(buffer->TryReadWriteChild(&metadata));
    2331  for (uint32_t i = 0; i < tracks.size(); ++i)
    2332  RCHECK(buffer->ReadWriteChild(&tracks[i]));
    2333  RCHECK(buffer->TryReadWriteChild(&extends));
    2334  for (uint32_t i = 0; i < pssh.size(); ++i)
    2335  RCHECK(buffer->ReadWriteChild(&pssh[i]));
    2336  }
    2337  return true;
    2338 }
    2339 
    2340 size_t Movie::ComputeSizeInternal() {
    2341  size_t box_size = HeaderSize() + header.ComputeSize() +
    2342  metadata.ComputeSize() + extends.ComputeSize();
    2343  for (uint32_t i = 0; i < tracks.size(); ++i)
    2344  box_size += tracks[i].ComputeSize();
    2345  for (uint32_t i = 0; i < pssh.size(); ++i)
    2346  box_size += pssh[i].ComputeSize();
    2347  return box_size;
    2348 }
    2349 
    2350 TrackFragmentDecodeTime::TrackFragmentDecodeTime() = default;
    2351 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() = default;
    2352 
    2354  return FOURCC_tfdt;
    2355 }
    2356 
    2357 bool TrackFragmentDecodeTime::ReadWriteInternal(BoxBuffer* buffer) {
    2358  RCHECK(ReadWriteHeaderInternal(buffer));
    2359  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    2360  RCHECK(buffer->ReadWriteUInt64NBytes(&decode_time, num_bytes));
    2361  return true;
    2362 }
    2363 
    2364 size_t TrackFragmentDecodeTime::ComputeSizeInternal() {
    2365  version = IsFitIn32Bits(decode_time) ? 0 : 1;
    2366  return HeaderSize() + sizeof(uint32_t) * (1 + version);
    2367 }
    2368 
    2369 MovieFragmentHeader::MovieFragmentHeader() = default;
    2370 MovieFragmentHeader::~MovieFragmentHeader() = default;
    2371 
    2373  return FOURCC_mfhd;
    2374 }
    2375 
    2376 bool MovieFragmentHeader::ReadWriteInternal(BoxBuffer* buffer) {
    2377  return ReadWriteHeaderInternal(buffer) &&
    2378  buffer->ReadWriteUInt32(&sequence_number);
    2379 }
    2380 
    2381 size_t MovieFragmentHeader::ComputeSizeInternal() {
    2382  return HeaderSize() + sizeof(sequence_number);
    2383 }
    2384 
    2385 TrackFragmentHeader::TrackFragmentHeader() = default;
    2386 TrackFragmentHeader::~TrackFragmentHeader() = default;
    2387 
    2389  return FOURCC_tfhd;
    2390 }
    2391 
    2392 bool TrackFragmentHeader::ReadWriteInternal(BoxBuffer* buffer) {
    2393  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&track_id));
    2394 
    2395  if (flags & kBaseDataOffsetPresentMask) {
    2396  // MSE requires 'default-base-is-moof' to be set and
    2397  // 'base-data-offset-present' not to be set. We omit these checks as some
    2398  // valid files in the wild don't follow these rules, though they use moof as
    2399  // base.
    2400  uint64_t base_data_offset;
    2401  RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
    2402  DLOG(WARNING) << "base-data-offset-present is not expected. Assumes "
    2403  "default-base-is-moof.";
    2404  }
    2405 
    2406  if (flags & kSampleDescriptionIndexPresentMask) {
    2407  RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
    2408  } else if (buffer->Reading()) {
    2409  sample_description_index = 0;
    2410  }
    2411 
    2412  if (flags & kDefaultSampleDurationPresentMask) {
    2413  RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
    2414  } else if (buffer->Reading()) {
    2415  default_sample_duration = 0;
    2416  }
    2417 
    2418  if (flags & kDefaultSampleSizePresentMask) {
    2419  RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
    2420  } else if (buffer->Reading()) {
    2421  default_sample_size = 0;
    2422  }
    2423 
    2424  if (flags & kDefaultSampleFlagsPresentMask)
    2425  RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
    2426  return true;
    2427 }
    2428 
    2429 size_t TrackFragmentHeader::ComputeSizeInternal() {
    2430  size_t box_size = HeaderSize() + sizeof(track_id);
    2431  if (flags & kSampleDescriptionIndexPresentMask)
    2432  box_size += sizeof(sample_description_index);
    2433  if (flags & kDefaultSampleDurationPresentMask)
    2434  box_size += sizeof(default_sample_duration);
    2435  if (flags & kDefaultSampleSizePresentMask)
    2436  box_size += sizeof(default_sample_size);
    2437  if (flags & kDefaultSampleFlagsPresentMask)
    2438  box_size += sizeof(default_sample_flags);
    2439  return box_size;
    2440 }
    2441 
    2442 TrackFragmentRun::TrackFragmentRun() = default;
    2443 TrackFragmentRun::~TrackFragmentRun() = default;
    2444 
    2446  return FOURCC_trun;
    2447 }
    2448 
    2449 bool TrackFragmentRun::ReadWriteInternal(BoxBuffer* buffer) {
    2450  if (!buffer->Reading()) {
    2451  // Determine whether version 0 or version 1 should be used.
    2452  // Use version 0 if possible, use version 1 if there is a negative
    2453  // sample_offset value.
    2454  version = 0;
    2455  if (flags & kSampleCompTimeOffsetsPresentMask) {
    2456  for (uint32_t i = 0; i < sample_count; ++i) {
    2457  if (sample_composition_time_offsets[i] < 0) {
    2458  version = 1;
    2459  break;
    2460  }
    2461  }
    2462  }
    2463  }
    2464 
    2465  RCHECK(ReadWriteHeaderInternal(buffer) &&
    2466  buffer->ReadWriteUInt32(&sample_count));
    2467 
    2468  bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
    2469  bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
    2470  bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
    2471  bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
    2472  bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
    2473  bool sample_composition_time_offsets_present =
    2474  (flags & kSampleCompTimeOffsetsPresentMask) != 0;
    2475 
    2476  if (data_offset_present) {
    2477  RCHECK(buffer->ReadWriteUInt32(&data_offset));
    2478  } else {
    2479  // NOTE: If the data-offset is not present, then the data for this run
    2480  // starts immediately after the data of the previous run, or at the
    2481  // base-data-offset defined by the track fragment header if this is the
    2482  // first run in a track fragment. If the data-offset is present, it is
    2483  // relative to the base-data-offset established in the track fragment
    2484  // header.
    2485  NOTIMPLEMENTED();
    2486  }
    2487 
    2488  uint32_t first_sample_flags(0);
    2489 
    2490  if (buffer->Reading()) {
    2491  if (first_sample_flags_present)
    2492  RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
    2493 
    2494  if (sample_duration_present)
    2495  sample_durations.resize(sample_count);
    2496  if (sample_size_present)
    2497  sample_sizes.resize(sample_count);
    2498  if (sample_flags_present)
    2499  sample_flags.resize(sample_count);
    2500  if (sample_composition_time_offsets_present)
    2501  sample_composition_time_offsets.resize(sample_count);
    2502  } else {
    2503  if (first_sample_flags_present) {
    2504  first_sample_flags = sample_flags[0];
    2505  DCHECK(sample_flags.size() == 1);
    2506  RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
    2507  }
    2508 
    2509  if (sample_duration_present)
    2510  DCHECK(sample_durations.size() == sample_count);
    2511  if (sample_size_present)
    2512  DCHECK(sample_sizes.size() == sample_count);
    2513  if (sample_flags_present)
    2514  DCHECK(sample_flags.size() == sample_count);
    2515  if (sample_composition_time_offsets_present)
    2516  DCHECK(sample_composition_time_offsets.size() == sample_count);
    2517  }
    2518 
    2519  for (uint32_t i = 0; i < sample_count; ++i) {
    2520  if (sample_duration_present)
    2521  RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
    2522  if (sample_size_present)
    2523  RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
    2524  if (sample_flags_present)
    2525  RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
    2526 
    2527  if (sample_composition_time_offsets_present) {
    2528  if (version == 0) {
    2529  uint32_t sample_offset = sample_composition_time_offsets[i];
    2530  RCHECK(buffer->ReadWriteUInt32(&sample_offset));
    2531  sample_composition_time_offsets[i] = sample_offset;
    2532  } else {
    2533  int32_t sample_offset = sample_composition_time_offsets[i];
    2534  RCHECK(buffer->ReadWriteInt32(&sample_offset));
    2535  sample_composition_time_offsets[i] = sample_offset;
    2536  }
    2537  }
    2538  }
    2539 
    2540  if (buffer->Reading()) {
    2541  if (first_sample_flags_present) {
    2542  if (sample_flags.size() == 0) {
    2543  sample_flags.push_back(first_sample_flags);
    2544  } else {
    2545  sample_flags[0] = first_sample_flags;
    2546  }
    2547  }
    2548  }
    2549  return true;
    2550 }
    2551 
    2552 size_t TrackFragmentRun::ComputeSizeInternal() {
    2553  size_t box_size = HeaderSize() + sizeof(sample_count);
    2554  if (flags & kDataOffsetPresentMask)
    2555  box_size += sizeof(data_offset);
    2556  if (flags & kFirstSampleFlagsPresentMask)
    2557  box_size += sizeof(uint32_t);
    2558  uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
    2559  (flags & kSampleSizePresentMask ? 1 : 0) +
    2560  (flags & kSampleFlagsPresentMask ? 1 : 0) +
    2561  (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
    2562  box_size += fields * sizeof(uint32_t) * sample_count;
    2563  return box_size;
    2564 }
    2565 
    2566 TrackFragment::TrackFragment() = default;
    2567 TrackFragment::~TrackFragment() = default;
    2568 
    2569 FourCC TrackFragment::BoxType() const {
    2570  return FOURCC_traf;
    2571 }
    2572 
    2573 bool TrackFragment::ReadWriteInternal(BoxBuffer* buffer) {
    2574  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2575  buffer->ReadWriteChild(&header));
    2576  if (buffer->Reading()) {
    2577  DCHECK(buffer->reader());
    2578  decode_time_absent = !buffer->reader()->ChildExist(&decode_time);
    2579  if (!decode_time_absent)
    2580  RCHECK(buffer->ReadWriteChild(&decode_time));
    2581  RCHECK(buffer->reader()->TryReadChildren(&runs) &&
    2582  buffer->reader()->TryReadChildren(&sample_group_descriptions) &&
    2583  buffer->reader()->TryReadChildren(&sample_to_groups));
    2584  } else {
    2585  if (!decode_time_absent)
    2586  RCHECK(buffer->ReadWriteChild(&decode_time));
    2587  for (uint32_t i = 0; i < runs.size(); ++i)
    2588  RCHECK(buffer->ReadWriteChild(&runs[i]));
    2589  for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
    2590  RCHECK(buffer->ReadWriteChild(&sample_to_groups[i]));
    2591  for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
    2592  RCHECK(buffer->ReadWriteChild(&sample_group_descriptions[i]));
    2593  }
    2594  return buffer->TryReadWriteChild(&auxiliary_size) &&
    2595  buffer->TryReadWriteChild(&auxiliary_offset) &&
    2596  buffer->TryReadWriteChild(&sample_encryption);
    2597 }
    2598 
    2599 size_t TrackFragment::ComputeSizeInternal() {
    2600  size_t box_size = HeaderSize() + header.ComputeSize() +
    2601  decode_time.ComputeSize() + auxiliary_size.ComputeSize() +
    2602  auxiliary_offset.ComputeSize() +
    2603  sample_encryption.ComputeSize();
    2604  for (uint32_t i = 0; i < runs.size(); ++i)
    2605  box_size += runs[i].ComputeSize();
    2606  for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
    2607  box_size += sample_group_descriptions[i].ComputeSize();
    2608  for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
    2609  box_size += sample_to_groups[i].ComputeSize();
    2610  return box_size;
    2611 }
    2612 
    2613 MovieFragment::MovieFragment() = default;
    2614 MovieFragment::~MovieFragment() = default;
    2615 
    2616 FourCC MovieFragment::BoxType() const {
    2617  return FOURCC_moof;
    2618 }
    2619 
    2620 bool MovieFragment::ReadWriteInternal(BoxBuffer* buffer) {
    2621  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2622  buffer->ReadWriteChild(&header));
    2623  if (buffer->Reading()) {
    2624  BoxReader* reader = buffer->reader();
    2625  DCHECK(reader);
    2626  RCHECK(reader->ReadChildren(&tracks) && reader->TryReadChildren(&pssh));
    2627  } else {
    2628  for (uint32_t i = 0; i < tracks.size(); ++i)
    2629  RCHECK(buffer->ReadWriteChild(&tracks[i]));
    2630  for (uint32_t i = 0; i < pssh.size(); ++i)
    2631  RCHECK(buffer->ReadWriteChild(&pssh[i]));
    2632  }
    2633  return true;
    2634 }
    2635 
    2636 size_t MovieFragment::ComputeSizeInternal() {
    2637  size_t box_size = HeaderSize() + header.ComputeSize();
    2638  for (uint32_t i = 0; i < tracks.size(); ++i)
    2639  box_size += tracks[i].ComputeSize();
    2640  for (uint32_t i = 0; i < pssh.size(); ++i)
    2641  box_size += pssh[i].ComputeSize();
    2642  return box_size;
    2643 }
    2644 
    2645 SegmentIndex::SegmentIndex() = default;
    2646 SegmentIndex::~SegmentIndex() = default;
    2647 
    2648 FourCC SegmentIndex::BoxType() const {
    2649  return FOURCC_sidx;
    2650 }
    2651 
    2652 bool SegmentIndex::ReadWriteInternal(BoxBuffer* buffer) {
    2653  RCHECK(ReadWriteHeaderInternal(buffer) &&
    2654  buffer->ReadWriteUInt32(&reference_id) &&
    2655  buffer->ReadWriteUInt32(&timescale));
    2656 
    2657  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    2658  RCHECK(
    2659  buffer->ReadWriteUInt64NBytes(&earliest_presentation_time, num_bytes) &&
    2660  buffer->ReadWriteUInt64NBytes(&first_offset, num_bytes));
    2661 
    2662  uint16_t reference_count = static_cast<uint16_t>(references.size());
    2663  RCHECK(buffer->IgnoreBytes(2) && // reserved.
    2664  buffer->ReadWriteUInt16(&reference_count));
    2665  references.resize(reference_count);
    2666 
    2667  uint32_t reference_type_size;
    2668  uint32_t sap;
    2669  for (uint32_t i = 0; i < reference_count; ++i) {
    2670  if (!buffer->Reading()) {
    2671  reference_type_size = references[i].referenced_size;
    2672  if (references[i].reference_type)
    2673  reference_type_size |= (1 << 31);
    2674  sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
    2675  if (references[i].starts_with_sap)
    2676  sap |= (1 << 31);
    2677  }
    2678  RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
    2679  buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
    2680  buffer->ReadWriteUInt32(&sap));
    2681  if (buffer->Reading()) {
    2682  references[i].reference_type = (reference_type_size >> 31) ? true : false;
    2683  references[i].referenced_size = reference_type_size & ~(1 << 31);
    2684  references[i].starts_with_sap = (sap >> 31) ? true : false;
    2685  references[i].sap_type =
    2686  static_cast<SegmentReference::SAPType>((sap >> 28) & 0x07);
    2687  references[i].sap_delta_time = sap & ~(0xF << 28);
    2688  }
    2689  }
    2690  return true;
    2691 }
    2692 
    2693 size_t SegmentIndex::ComputeSizeInternal() {
    2694  version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
    2695  return HeaderSize() + sizeof(reference_id) + sizeof(timescale) +
    2696  sizeof(uint32_t) * (1 + version) * 2 + 2 * sizeof(uint16_t) +
    2697  3 * sizeof(uint32_t) * references.size();
    2698 }
    2699 
    2700 MediaData::MediaData() = default;
    2701 MediaData::~MediaData() = default;
    2702 
    2703 FourCC MediaData::BoxType() const {
    2704  return FOURCC_mdat;
    2705 }
    2706 
    2707 bool MediaData::ReadWriteInternal(BoxBuffer* buffer) {
    2708  NOTIMPLEMENTED() << "Actual data is parsed and written separately.";
    2709  return false;
    2710 }
    2711 
    2712 size_t MediaData::ComputeSizeInternal() {
    2713  return HeaderSize() + data_size;
    2714 }
    2715 
    2716 CueSourceIDBox::CueSourceIDBox() = default;
    2717 CueSourceIDBox::~CueSourceIDBox() = default;
    2718 
    2719 FourCC CueSourceIDBox::BoxType() const {
    2720  return FOURCC_vsid;
    2721 }
    2722 
    2723 bool CueSourceIDBox::ReadWriteInternal(BoxBuffer* buffer) {
    2724  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteInt32(&source_id));
    2725  return true;
    2726 }
    2727 
    2728 size_t CueSourceIDBox::ComputeSizeInternal() {
    2729  if (source_id == kCueSourceIdNotSet)
    2730  return 0;
    2731  return HeaderSize() + sizeof(source_id);
    2732 }
    2733 
    2734 CueTimeBox::CueTimeBox() = default;
    2735 CueTimeBox::~CueTimeBox() = default;
    2736 
    2737 FourCC CueTimeBox::BoxType() const {
    2738  return FOURCC_ctim;
    2739 }
    2740 
    2741 bool CueTimeBox::ReadWriteInternal(BoxBuffer* buffer) {
    2742  RCHECK(ReadWriteHeaderInternal(buffer));
    2743  return buffer->ReadWriteString(
    2744  &cue_current_time,
    2745  buffer->Reading() ? buffer->BytesLeft() : cue_current_time.size());
    2746 }
    2747 
    2748 size_t CueTimeBox::ComputeSizeInternal() {
    2749  if (cue_current_time.empty())
    2750  return 0;
    2751  return HeaderSize() + cue_current_time.size();
    2752 }
    2753 
    2754 CueIDBox::CueIDBox() = default;
    2755 CueIDBox::~CueIDBox() = default;
    2756 
    2757 FourCC CueIDBox::BoxType() const {
    2758  return FOURCC_iden;
    2759 }
    2760 
    2761 bool CueIDBox::ReadWriteInternal(BoxBuffer* buffer) {
    2762  RCHECK(ReadWriteHeaderInternal(buffer));
    2763  return buffer->ReadWriteString(
    2764  &cue_id, buffer->Reading() ? buffer->BytesLeft() : cue_id.size());
    2765 }
    2766 
    2767 size_t CueIDBox::ComputeSizeInternal() {
    2768  if (cue_id.empty())
    2769  return 0;
    2770  return HeaderSize() + cue_id.size();
    2771 }
    2772 
    2773 CueSettingsBox::CueSettingsBox() = default;
    2774 CueSettingsBox::~CueSettingsBox() = default;
    2775 
    2776 FourCC CueSettingsBox::BoxType() const {
    2777  return FOURCC_sttg;
    2778 }
    2779 
    2780 bool CueSettingsBox::ReadWriteInternal(BoxBuffer* buffer) {
    2781  RCHECK(ReadWriteHeaderInternal(buffer));
    2782  return buffer->ReadWriteString(
    2783  &settings, buffer->Reading() ? buffer->BytesLeft() : settings.size());
    2784 }
    2785 
    2786 size_t CueSettingsBox::ComputeSizeInternal() {
    2787  if (settings.empty())
    2788  return 0;
    2789  return HeaderSize() + settings.size();
    2790 }
    2791 
    2792 CuePayloadBox::CuePayloadBox() = default;
    2793 CuePayloadBox::~CuePayloadBox() = default;
    2794 
    2795 FourCC CuePayloadBox::BoxType() const {
    2796  return FOURCC_payl;
    2797 }
    2798 
    2799 bool CuePayloadBox::ReadWriteInternal(BoxBuffer* buffer) {
    2800  RCHECK(ReadWriteHeaderInternal(buffer));
    2801  return buffer->ReadWriteString(
    2802  &cue_text, buffer->Reading() ? buffer->BytesLeft() : cue_text.size());
    2803 }
    2804 
    2805 size_t CuePayloadBox::ComputeSizeInternal() {
    2806  return HeaderSize() + cue_text.size();
    2807 }
    2808 
    2809 VTTEmptyCueBox::VTTEmptyCueBox() = default;
    2810 VTTEmptyCueBox::~VTTEmptyCueBox() = default;
    2811 
    2812 FourCC VTTEmptyCueBox::BoxType() const {
    2813  return FOURCC_vtte;
    2814 }
    2815 
    2816 bool VTTEmptyCueBox::ReadWriteInternal(BoxBuffer* buffer) {
    2817  return ReadWriteHeaderInternal(buffer);
    2818 }
    2819 
    2820 size_t VTTEmptyCueBox::ComputeSizeInternal() {
    2821  return HeaderSize();
    2822 }
    2823 
    2824 VTTAdditionalTextBox::VTTAdditionalTextBox() = default;
    2825 VTTAdditionalTextBox::~VTTAdditionalTextBox() = default;
    2826 
    2828  return FOURCC_vtta;
    2829 }
    2830 
    2831 bool VTTAdditionalTextBox::ReadWriteInternal(BoxBuffer* buffer) {
    2832  RCHECK(ReadWriteHeaderInternal(buffer));
    2833  return buffer->ReadWriteString(
    2834  &cue_additional_text,
    2835  buffer->Reading() ? buffer->BytesLeft() : cue_additional_text.size());
    2836 }
    2837 
    2838 size_t VTTAdditionalTextBox::ComputeSizeInternal() {
    2839  return HeaderSize() + cue_additional_text.size();
    2840 }
    2841 
    2842 VTTCueBox::VTTCueBox() = default;
    2843 VTTCueBox::~VTTCueBox() = default;
    2844 
    2845 FourCC VTTCueBox::BoxType() const {
    2846  return FOURCC_vttc;
    2847 }
    2848 
    2849 bool VTTCueBox::ReadWriteInternal(BoxBuffer* buffer) {
    2850  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    2851  buffer->TryReadWriteChild(&cue_source_id) &&
    2852  buffer->TryReadWriteChild(&cue_id) &&
    2853  buffer->TryReadWriteChild(&cue_time) &&
    2854  buffer->TryReadWriteChild(&cue_settings) &&
    2855  buffer->ReadWriteChild(&cue_payload));
    2856  return true;
    2857 }
    2858 
    2859 size_t VTTCueBox::ComputeSizeInternal() {
    2860  return HeaderSize() + cue_source_id.ComputeSize() + cue_id.ComputeSize() +
    2861  cue_time.ComputeSize() + cue_settings.ComputeSize() +
    2862  cue_payload.ComputeSize();
    2863 }
    2864 
    2865 } // namespace mp4
    2866 } // namespace media
    2867 } // namespace shaka
    FourCC BoxType() const override
    - - - - -
    FourCC BoxType() const override
    - - -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    - - -
    bool ParseFromBuffer(uint8_t iv_size, bool has_subsamples, BufferReader *reader)
    - - -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    - - - -
    FourCC BoxType() const override
    -
    A class to read bit streams.
    Definition: bit_reader.h:17
    -
    const uint8_t * Buffer() const
    Definition: buffer_writer.h:61
    -
    FourCC BoxType() const override
    - -
    FourCC BoxType() const override
    -
    bool TryReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
    Definition: box_reader.h:134
    - -
    bool TryReadWriteChild(Box *box)
    Definition: box_buffer.h:177
    - - -
    FourCC BoxType() const override
    -
    bool ReadAllChildren(std::vector< T > *children) WARN_UNUSED_RESULT
    Definition: box_reader.h:157
    -
    FourCC BoxType() const override
    - - - -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    - -
    size_t BytesLeft() const
    Definition: box_buffer.h:62
    -
    FourCC BoxType() const override
    - - -
    FourCC BoxType() const override
    - -
    virtual bool ReadWriteHeaderInternal(BoxBuffer *buffer)
    Definition: box.cc:61
    -
    FourCC BoxType() const override
    -
    All the methods that are virtual are virtual for mocking.
    - -
    FourCC BoxType() const override
    - - -
    bool ParseFromSampleEncryptionData(uint8_t iv_size, std::vector< SampleEncryptionEntry > *sample_encryption_entries) const
    - - -
    FourCC BoxType() const override
    - - -
    uint32_t ComputeSize()
    Definition: box.cc:50
    -
    bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer *buffer)
    - -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    - - -
    FourCC BoxType() const override
    -
    bool ReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
    Definition: box_reader.h:128
    - -
    FourCC BoxType() const override
    - - - -
    FourCC BoxType() const override
    -
    uint32_t box_size()
    Definition: box.h:55
    - -
    FourCC BoxType() const override
    -
    BufferWriter * writer()
    Definition: box_buffer.h:200
    -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    - -
    bool IgnoreBytes(size_t num_bytes)
    Definition: box_buffer.h:189
    - -
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    -
    bool ReadWriteString(std::string *str, size_t size)
    Definition: box_buffer.h:139
    -
    FourCC BoxType() const override
    -
    bool ReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:90
    -
    virtual uint32_t HeaderSize() const
    Definition: box.cc:55
    -
    FourCC BoxType() const override
    - -
    FourCC BoxType() const override
    - - -
    bool ReadWriteUInt64NBytes(uint64_t *v, size_t num_bytes)
    Definition: box_buffer.h:117
    -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    - - - -
    FourCC BoxType() const override
    - - - -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    -
    bool Parse(BoxReader *reader)
    Definition: box.cc:19
    -
    void Write(BufferWriter *writer)
    Definition: box.cc:25
    -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    -
    bool TryReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:106
    -
    FourCC BoxType() const override
    -
    FourCC BoxType() const override
    -
    bool ChildExist(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:102
    -
    bool ReadWriteChild(Box *box)
    Definition: box_buffer.h:166
    -
    static BoxReader * ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)
    Definition: box_reader.cc:36
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/mp4/box_definitions.h"
    +
    6 
    +
    7 #include <gflags/gflags.h>
    +
    8 #include <algorithm>
    +
    9 #include <limits>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/bit_reader.h"
    +
    13 #include "packager/media/base/macros.h"
    +
    14 #include "packager/media/base/rcheck.h"
    +
    15 #include "packager/media/formats/mp4/box_buffer.h"
    +
    16 
    +
    17 DEFINE_bool(mvex_before_trak,
    +
    18  false,
    +
    19  "Android MediaExtractor requires mvex to be written before trak. "
    +
    20  "Set the flag to true to comply with the requirement.");
    +
    21 
    +
    22 namespace {
    +
    23 const uint32_t kFourCCSize = 4;
    +
    24 
    +
    25 // Key Id size as defined in CENC spec.
    +
    26 const uint32_t kCencKeyIdSize = 16;
    +
    27 
    +
    28 // 9 uint32_t in big endian formatted array.
    +
    29 const uint8_t kUnityMatrix[] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    +
    30  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
    +
    31  0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
    +
    32 
    +
    33 // Default entries for HandlerReference box.
    +
    34 const char kVideoHandlerName[] = "VideoHandler";
    +
    35 const char kAudioHandlerName[] = "SoundHandler";
    +
    36 const char kTextHandlerName[] = "TextHandler";
    +
    37 const char kSubtitleHandlerName[] = "SubtitleHandler";
    +
    38 
    +
    39 // Default values for VideoSampleEntry box.
    +
    40 const uint32_t kVideoResolution = 0x00480000; // 72 dpi.
    +
    41 const uint16_t kVideoFrameCount = 1;
    +
    42 const uint16_t kVideoDepth = 0x0018;
    +
    43 
    +
    44 const uint32_t kCompressorNameSize = 32u;
    +
    45 const char kAv1CompressorName[] = "\012AOM Coding";
    +
    46 const char kAvcCompressorName[] = "\012AVC Coding";
    +
    47 const char kDolbyVisionCompressorName[] = "\013DOVI Coding";
    +
    48 const char kHevcCompressorName[] = "\013HEVC Coding";
    +
    49 const char kVpcCompressorName[] = "\012VPC Coding";
    +
    50 
    +
    51 // According to ISO/IEC FDIS 23001-7: CENC spec, IV should be either
    +
    52 // 64-bit (8-byte) or 128-bit (16-byte).
    +
    53 // |per_sample_iv_size| of 0 means constant_iv is used.
    +
    54 bool IsIvSizeValid(uint8_t per_sample_iv_size) {
    +
    55  return per_sample_iv_size == 0 || per_sample_iv_size == 8 ||
    +
    56  per_sample_iv_size == 16;
    +
    57 }
    +
    58 
    +
    59 // Default values to construct the following fields in ddts box. Values are set
    +
    60 // according to FFMPEG.
    +
    61 // bit(2) FrameDuration; // 3 = 4096
    +
    62 // bit(5) StreamConstruction; // 18
    +
    63 // bit(1) CoreLFEPresent; // 0 = none
    +
    64 // bit(6) CoreLayout; // 31 = ignore core layout
    +
    65 // bit(14) CoreSize; // 0
    +
    66 // bit(1) StereoDownmix // 0 = none
    +
    67 // bit(3) RepresentationType; // 4
    +
    68 // bit(16) ChannelLayout; // 0xf = 5.1 channel layout.
    +
    69 // bit(1) MultiAssetFlag // 0 = single asset
    +
    70 // bit(1) LBRDurationMod // 0 = ignore
    +
    71 // bit(1) ReservedBoxPresent // 0 = none
    +
    72 // bit(5) Reserved // 0
    +
    73 const uint8_t kDdtsExtraData[] = {0xe4, 0x7c, 0, 4, 0, 0x0f, 0};
    +
    74 
    +
    75 // Utility functions to check if the 64bit integers can fit in 32bit integer.
    +
    76 bool IsFitIn32Bits(uint64_t a) {
    +
    77  return a <= std::numeric_limits<uint32_t>::max();
    +
    78 }
    +
    79 
    +
    80 bool IsFitIn32Bits(int64_t a) {
    +
    81  return a <= std::numeric_limits<int32_t>::max() &&
    +
    82  a >= std::numeric_limits<int32_t>::min();
    +
    83 }
    +
    84 
    +
    85 template <typename T1, typename T2>
    +
    86 bool IsFitIn32Bits(T1 a1, T2 a2) {
    +
    87  return IsFitIn32Bits(a1) && IsFitIn32Bits(a2);
    +
    88 }
    +
    89 
    +
    90 template <typename T1, typename T2, typename T3>
    +
    91 bool IsFitIn32Bits(T1 a1, T2 a2, T3 a3) {
    +
    92  return IsFitIn32Bits(a1) && IsFitIn32Bits(a2) && IsFitIn32Bits(a3);
    +
    93 }
    +
    94 
    +
    95 } // namespace
    +
    96 
    +
    97 namespace shaka {
    +
    98 namespace media {
    +
    99 namespace mp4 {
    +
    100 
    +
    101 namespace {
    +
    102 
    +
    103 TrackType FourCCToTrackType(FourCC fourcc) {
    +
    104  switch (fourcc) {
    +
    105  case FOURCC_vide:
    +
    106  return kVideo;
    +
    107  case FOURCC_soun:
    +
    108  return kAudio;
    +
    109  case FOURCC_text:
    +
    110  return kText;
    +
    111  case FOURCC_subt:
    +
    112  return kSubtitle;
    +
    113  default:
    +
    114  return kInvalid;
    +
    115  }
    +
    116 }
    +
    117 
    +
    118 FourCC TrackTypeToFourCC(TrackType track_type) {
    +
    119  switch (track_type) {
    +
    120  case kVideo:
    +
    121  return FOURCC_vide;
    +
    122  case kAudio:
    +
    123  return FOURCC_soun;
    +
    124  case kText:
    +
    125  return FOURCC_text;
    +
    126  case kSubtitle:
    +
    127  return FOURCC_subt;
    +
    128  default:
    +
    129  return FOURCC_NULL;
    +
    130  }
    +
    131 }
    +
    132 
    +
    133 bool IsProtectionSchemeSupported(FourCC scheme) {
    +
    134  return scheme == FOURCC_cenc || scheme == FOURCC_cens ||
    +
    135  scheme == FOURCC_cbc1 || scheme == FOURCC_cbcs;
    +
    136 }
    +
    137 
    +
    138 } // namespace
    +
    139 
    +
    140 FileType::FileType() = default;
    +
    141 FileType::~FileType() = default;
    +
    142 
    +
    143 FourCC FileType::BoxType() const {
    +
    144  return FOURCC_ftyp;
    +
    145 }
    +
    146 
    +
    147 bool FileType::ReadWriteInternal(BoxBuffer* buffer) {
    +
    148  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    149  buffer->ReadWriteFourCC(&major_brand) &&
    +
    150  buffer->ReadWriteUInt32(&minor_version));
    +
    151  size_t num_brands;
    +
    152  if (buffer->Reading()) {
    +
    153  RCHECK(buffer->BytesLeft() % sizeof(FourCC) == 0);
    +
    154  num_brands = buffer->BytesLeft() / sizeof(FourCC);
    +
    155  compatible_brands.resize(num_brands);
    +
    156  } else {
    +
    157  num_brands = compatible_brands.size();
    +
    158  }
    +
    159  for (size_t i = 0; i < num_brands; ++i)
    +
    160  RCHECK(buffer->ReadWriteFourCC(&compatible_brands[i]));
    +
    161  return true;
    +
    162 }
    +
    163 
    +
    164 size_t FileType::ComputeSizeInternal() {
    +
    165  return HeaderSize() + kFourCCSize + sizeof(minor_version) +
    +
    166  kFourCCSize * compatible_brands.size();
    +
    167 }
    +
    168 
    +
    169 FourCC SegmentType::BoxType() const {
    +
    170  return FOURCC_styp;
    +
    171 }
    +
    172 
    +
    173 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() = default;
    +
    174 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() = default;
    +
    175 
    + +
    177  return FOURCC_pssh;
    +
    178 }
    +
    179 
    +
    180 bool ProtectionSystemSpecificHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    181  if (buffer->Reading()) {
    +
    182  BoxReader* reader = buffer->reader();
    +
    183  DCHECK(reader);
    +
    184  raw_box.assign(reader->data(), reader->data() + reader->size());
    +
    185  } else {
    +
    186  DCHECK(!raw_box.empty());
    +
    187  buffer->writer()->AppendVector(raw_box);
    +
    188  }
    +
    189 
    +
    190  return true;
    +
    191 }
    +
    192 
    +
    193 size_t ProtectionSystemSpecificHeader::ComputeSizeInternal() {
    +
    194  return raw_box.size();
    +
    195 }
    +
    196 
    +
    197 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() = default;
    +
    198 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() = default;
    +
    199 
    + +
    201  return FOURCC_saio;
    +
    202 }
    +
    203 
    +
    204 bool SampleAuxiliaryInformationOffset::ReadWriteInternal(BoxBuffer* buffer) {
    +
    205  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    206  if (flags & 1)
    +
    207  RCHECK(buffer->IgnoreBytes(8)); // aux_info_type and parameter.
    +
    208 
    +
    209  uint32_t count = static_cast<uint32_t>(offsets.size());
    +
    210  RCHECK(buffer->ReadWriteUInt32(&count));
    +
    211  offsets.resize(count);
    +
    212 
    +
    213  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    214  for (uint32_t i = 0; i < count; ++i)
    +
    215  RCHECK(buffer->ReadWriteUInt64NBytes(&offsets[i], num_bytes));
    +
    216  return true;
    +
    217 }
    +
    218 
    +
    219 size_t SampleAuxiliaryInformationOffset::ComputeSizeInternal() {
    +
    220  // This box is optional. Skip it if it is empty.
    +
    221  if (offsets.size() == 0)
    +
    222  return 0;
    +
    223  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    224  return HeaderSize() + sizeof(uint32_t) + num_bytes * offsets.size();
    +
    225 }
    +
    226 
    +
    227 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize() = default;
    +
    228 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() = default;
    +
    229 
    + +
    231  return FOURCC_saiz;
    +
    232 }
    +
    233 
    +
    234 bool SampleAuxiliaryInformationSize::ReadWriteInternal(BoxBuffer* buffer) {
    +
    235  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    236  if (flags & 1)
    +
    237  RCHECK(buffer->IgnoreBytes(8));
    +
    238 
    +
    239  RCHECK(buffer->ReadWriteUInt8(&default_sample_info_size) &&
    +
    240  buffer->ReadWriteUInt32(&sample_count));
    +
    241  if (default_sample_info_size == 0)
    +
    242  RCHECK(buffer->ReadWriteVector(&sample_info_sizes, sample_count));
    +
    243  return true;
    +
    244 }
    +
    245 
    +
    246 size_t SampleAuxiliaryInformationSize::ComputeSizeInternal() {
    +
    247  // This box is optional. Skip it if it is empty.
    +
    248  if (sample_count == 0)
    +
    249  return 0;
    +
    250  return HeaderSize() + sizeof(default_sample_info_size) +
    +
    251  sizeof(sample_count) +
    +
    252  (default_sample_info_size == 0 ? sample_info_sizes.size() : 0);
    +
    253 }
    +
    254 
    +
    255 bool SampleEncryptionEntry::ReadWrite(uint8_t iv_size,
    +
    256  bool has_subsamples,
    +
    257  BoxBuffer* buffer) {
    +
    258  DCHECK(IsIvSizeValid(iv_size));
    +
    259  DCHECK(buffer);
    +
    260 
    +
    261  RCHECK(buffer->ReadWriteVector(&initialization_vector, iv_size));
    +
    262 
    +
    263  if (!has_subsamples) {
    +
    264  subsamples.clear();
    +
    265  return true;
    +
    266  }
    +
    267 
    +
    268  uint16_t subsample_count = static_cast<uint16_t>(subsamples.size());
    +
    269  RCHECK(buffer->ReadWriteUInt16(&subsample_count));
    +
    270  RCHECK(subsample_count > 0);
    +
    271  subsamples.resize(subsample_count);
    +
    272  for (auto& subsample : subsamples) {
    +
    273  RCHECK(buffer->ReadWriteUInt16(&subsample.clear_bytes) &&
    +
    274  buffer->ReadWriteUInt32(&subsample.cipher_bytes));
    +
    275  }
    +
    276  return true;
    +
    277 }
    +
    278 
    + +
    280  bool has_subsamples,
    +
    281  BufferReader* reader) {
    +
    282  DCHECK(IsIvSizeValid(iv_size));
    +
    283  DCHECK(reader);
    +
    284 
    +
    285  initialization_vector.resize(iv_size);
    +
    286  RCHECK(reader->ReadToVector(&initialization_vector, iv_size));
    +
    287 
    +
    288  if (!has_subsamples) {
    +
    289  subsamples.clear();
    +
    290  return true;
    +
    291  }
    +
    292 
    +
    293  uint16_t subsample_count;
    +
    294  RCHECK(reader->Read2(&subsample_count));
    +
    295  RCHECK(subsample_count > 0);
    +
    296  subsamples.resize(subsample_count);
    +
    297  for (auto& subsample : subsamples) {
    +
    298  RCHECK(reader->Read2(&subsample.clear_bytes) &&
    +
    299  reader->Read4(&subsample.cipher_bytes));
    +
    300  }
    +
    301  return true;
    +
    302 }
    +
    303 
    + +
    305  const uint32_t subsample_entry_size = sizeof(uint16_t) + sizeof(uint32_t);
    +
    306  const uint16_t subsample_count = static_cast<uint16_t>(subsamples.size());
    +
    307  return static_cast<uint32_t>(
    +
    308  initialization_vector.size() +
    +
    309  (subsample_count > 0
    +
    310  ? (sizeof(subsample_count) + subsample_entry_size * subsample_count)
    +
    311  : 0));
    +
    312 }
    +
    313 
    + +
    315  uint32_t size = 0;
    +
    316  for (uint32_t i = 0; i < subsamples.size(); ++i)
    +
    317  size += subsamples[i].clear_bytes + subsamples[i].cipher_bytes;
    +
    318  return size;
    +
    319 }
    +
    320 
    +
    321 SampleEncryption::SampleEncryption() = default;
    +
    322 SampleEncryption::~SampleEncryption() = default;
    +
    323 
    + +
    325  return FOURCC_senc;
    +
    326 }
    +
    327 
    +
    328 bool SampleEncryption::ReadWriteInternal(BoxBuffer* buffer) {
    +
    329  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    330 
    +
    331  // If we don't know |iv_size|, store sample encryption data to parse later
    +
    332  // after we know iv_size.
    +
    333  if (buffer->Reading() && iv_size == SampleEncryption::kInvalidIvSize) {
    +
    334  RCHECK(
    +
    335  buffer->ReadWriteVector(&sample_encryption_data, buffer->BytesLeft()));
    +
    336  return true;
    +
    337  }
    +
    338 
    +
    339  if (!IsIvSizeValid(iv_size)) {
    +
    340  LOG(ERROR)
    +
    341  << "IV_size can only be 8 or 16 or 0 for constant iv, but seeing "
    +
    342  << iv_size;
    +
    343  return false;
    +
    344  }
    +
    345 
    +
    346  uint32_t sample_count =
    +
    347  static_cast<uint32_t>(sample_encryption_entries.size());
    +
    348  RCHECK(buffer->ReadWriteUInt32(&sample_count));
    +
    349 
    +
    350  sample_encryption_entries.resize(sample_count);
    +
    351  for (auto& sample_encryption_entry : sample_encryption_entries) {
    +
    352  RCHECK(sample_encryption_entry.ReadWrite(
    +
    353  iv_size, (flags & kUseSubsampleEncryption) != 0, buffer) != 0);
    +
    354  }
    +
    355  return true;
    +
    356 }
    +
    357 
    +
    358 size_t SampleEncryption::ComputeSizeInternal() {
    +
    359  const uint32_t sample_count =
    +
    360  static_cast<uint32_t>(sample_encryption_entries.size());
    +
    361  if (sample_count == 0) {
    +
    362  // Sample encryption box is optional. Skip it if it is empty.
    +
    363  return 0;
    +
    364  }
    +
    365 
    +
    366  DCHECK(IsIvSizeValid(iv_size));
    +
    367  size_t box_size = HeaderSize() + sizeof(sample_count);
    +
    368  if (flags & kUseSubsampleEncryption) {
    +
    369  for (const SampleEncryptionEntry& sample_encryption_entry :
    +
    370  sample_encryption_entries) {
    +
    371  box_size += sample_encryption_entry.ComputeSize();
    +
    372  }
    +
    373  } else {
    +
    374  box_size += sample_count * iv_size;
    +
    375  }
    +
    376  return box_size;
    +
    377 }
    +
    378 
    + +
    380  uint8_t iv_size,
    +
    381  std::vector<SampleEncryptionEntry>* sample_encryption_entries) const {
    +
    382  DCHECK(IsIvSizeValid(iv_size));
    +
    383 
    +
    384  BufferReader reader(sample_encryption_data.data(),
    +
    385  sample_encryption_data.size());
    +
    386  uint32_t sample_count = 0;
    +
    387  RCHECK(reader.Read4(&sample_count));
    +
    388 
    +
    389  sample_encryption_entries->resize(sample_count);
    +
    390  for (auto& sample_encryption_entry : *sample_encryption_entries) {
    +
    391  RCHECK(sample_encryption_entry.ParseFromBuffer(
    +
    392  iv_size, (flags & kUseSubsampleEncryption) != 0, &reader) != 0);
    +
    393  }
    +
    394  return true;
    +
    395 }
    +
    396 
    +
    397 OriginalFormat::OriginalFormat() = default;
    +
    398 OriginalFormat::~OriginalFormat() = default;
    +
    399 
    +
    400 FourCC OriginalFormat::BoxType() const {
    +
    401  return FOURCC_frma;
    +
    402 }
    +
    403 
    +
    404 bool OriginalFormat::ReadWriteInternal(BoxBuffer* buffer) {
    +
    405  return ReadWriteHeaderInternal(buffer) && buffer->ReadWriteFourCC(&format);
    +
    406 }
    +
    407 
    +
    408 size_t OriginalFormat::ComputeSizeInternal() {
    +
    409  return HeaderSize() + kFourCCSize;
    +
    410 }
    +
    411 
    +
    412 SchemeType::SchemeType() = default;
    +
    413 SchemeType::~SchemeType() = default;
    +
    414 
    +
    415 FourCC SchemeType::BoxType() const {
    +
    416  return FOURCC_schm;
    +
    417 }
    +
    418 
    +
    419 bool SchemeType::ReadWriteInternal(BoxBuffer* buffer) {
    +
    420  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteFourCC(&type) &&
    +
    421  buffer->ReadWriteUInt32(&version));
    +
    422  return true;
    +
    423 }
    +
    424 
    +
    425 size_t SchemeType::ComputeSizeInternal() {
    +
    426  return HeaderSize() + kFourCCSize + sizeof(version);
    +
    427 }
    +
    428 
    +
    429 TrackEncryption::TrackEncryption() = default;
    +
    430 TrackEncryption::~TrackEncryption() = default;
    +
    431 
    +
    432 FourCC TrackEncryption::BoxType() const {
    +
    433  return FOURCC_tenc;
    +
    434 }
    +
    435 
    +
    436 bool TrackEncryption::ReadWriteInternal(BoxBuffer* buffer) {
    +
    437  if (!buffer->Reading()) {
    +
    438  if (default_kid.size() != kCencKeyIdSize) {
    +
    439  LOG(WARNING) << "CENC defines key id length of " << kCencKeyIdSize
    +
    440  << " bytes; got " << default_kid.size()
    +
    441  << ". Resized accordingly.";
    +
    442  default_kid.resize(kCencKeyIdSize);
    +
    443  }
    +
    444  RCHECK(default_crypt_byte_block < 16 && default_skip_byte_block < 16);
    +
    445  if (default_crypt_byte_block != 0 && default_skip_byte_block != 0) {
    +
    446  // Version 1 box is needed for pattern-based encryption.
    +
    447  version = 1;
    +
    448  }
    +
    449  }
    +
    450 
    +
    451  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    452  buffer->IgnoreBytes(1)); // reserved.
    +
    453 
    +
    454  uint8_t pattern = default_crypt_byte_block << 4 | default_skip_byte_block;
    +
    455  RCHECK(buffer->ReadWriteUInt8(&pattern));
    +
    456  default_crypt_byte_block = pattern >> 4;
    +
    457  default_skip_byte_block = pattern & 0x0F;
    +
    458 
    +
    459  RCHECK(buffer->ReadWriteUInt8(&default_is_protected) &&
    +
    460  buffer->ReadWriteUInt8(&default_per_sample_iv_size) &&
    +
    461  buffer->ReadWriteVector(&default_kid, kCencKeyIdSize));
    +
    462 
    +
    463  if (default_is_protected == 1) {
    +
    464  if (default_per_sample_iv_size == 0) { // For constant iv.
    +
    465  uint8_t default_constant_iv_size =
    +
    466  static_cast<uint8_t>(default_constant_iv.size());
    +
    467  RCHECK(buffer->ReadWriteUInt8(&default_constant_iv_size));
    +
    468  RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
    +
    469  RCHECK(buffer->ReadWriteVector(&default_constant_iv,
    +
    470  default_constant_iv_size));
    +
    471  } else {
    +
    472  RCHECK(default_per_sample_iv_size == 8 ||
    +
    473  default_per_sample_iv_size == 16);
    +
    474  RCHECK(default_constant_iv.empty());
    +
    475  }
    +
    476  } else {
    +
    477  // Expect |default_is_protected| to be 0, i.e. not protected. Other values
    +
    478  // of |default_is_protected| is not supported.
    +
    479  RCHECK(default_is_protected == 0);
    +
    480  RCHECK(default_per_sample_iv_size == 0);
    +
    481  RCHECK(default_constant_iv.empty());
    +
    482  }
    +
    483  return true;
    +
    484 }
    +
    485 
    +
    486 size_t TrackEncryption::ComputeSizeInternal() {
    +
    487  return HeaderSize() + sizeof(uint32_t) + kCencKeyIdSize +
    +
    488  (default_constant_iv.empty()
    +
    489  ? 0
    +
    490  : (sizeof(uint8_t) + default_constant_iv.size()));
    +
    491 }
    +
    492 
    +
    493 SchemeInfo::SchemeInfo() = default;
    +
    494 SchemeInfo::~SchemeInfo() = default;
    +
    495 
    +
    496 FourCC SchemeInfo::BoxType() const {
    +
    497  return FOURCC_schi;
    +
    498 }
    +
    499 
    +
    500 bool SchemeInfo::ReadWriteInternal(BoxBuffer* buffer) {
    +
    501  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    502  buffer->ReadWriteChild(&track_encryption));
    +
    503  return true;
    +
    504 }
    +
    505 
    +
    506 size_t SchemeInfo::ComputeSizeInternal() {
    +
    507  return HeaderSize() + track_encryption.ComputeSize();
    +
    508 }
    +
    509 
    +
    510 ProtectionSchemeInfo::ProtectionSchemeInfo() = default;
    +
    511 ProtectionSchemeInfo::~ProtectionSchemeInfo() = default;
    +
    512 
    + +
    514  return FOURCC_sinf;
    +
    515 }
    +
    516 
    +
    517 bool ProtectionSchemeInfo::ReadWriteInternal(BoxBuffer* buffer) {
    +
    518  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    519  buffer->ReadWriteChild(&format) && buffer->ReadWriteChild(&type));
    +
    520  if (IsProtectionSchemeSupported(type.type)) {
    +
    521  RCHECK(buffer->ReadWriteChild(&info));
    +
    522  } else {
    +
    523  DLOG(WARNING) << "Ignore unsupported protection scheme: "
    +
    524  << FourCCToString(type.type);
    +
    525  }
    +
    526  // Other protection schemes are silently ignored. Since the protection scheme
    +
    527  // type can't be determined until this box is opened, we return 'true' for
    +
    528  // non-CENC protection scheme types. It is the parent box's responsibility to
    +
    529  // ensure that this scheme type is a supported one.
    +
    530  return true;
    +
    531 }
    +
    532 
    +
    533 size_t ProtectionSchemeInfo::ComputeSizeInternal() {
    +
    534  // Skip sinf box if it is not initialized.
    +
    535  if (format.format == FOURCC_NULL)
    +
    536  return 0;
    +
    537  return HeaderSize() + format.ComputeSize() + type.ComputeSize() +
    +
    538  info.ComputeSize();
    +
    539 }
    +
    540 
    +
    541 MovieHeader::MovieHeader() = default;
    +
    542 MovieHeader::~MovieHeader() = default;
    +
    543 
    +
    544 FourCC MovieHeader::BoxType() const {
    +
    545  return FOURCC_mvhd;
    +
    546 }
    +
    547 
    +
    548 bool MovieHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    549  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    550 
    +
    551  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    552  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
    +
    553  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
    +
    554  buffer->ReadWriteUInt32(&timescale) &&
    +
    555  buffer->ReadWriteUInt64NBytes(&duration, num_bytes));
    +
    556 
    +
    557  std::vector<uint8_t> matrix(kUnityMatrix,
    +
    558  kUnityMatrix + arraysize(kUnityMatrix));
    +
    559  RCHECK(buffer->ReadWriteInt32(&rate) && buffer->ReadWriteInt16(&volume) &&
    +
    560  buffer->IgnoreBytes(10) && // reserved
    +
    561  buffer->ReadWriteVector(&matrix, matrix.size()) &&
    +
    562  buffer->IgnoreBytes(24) && // predefined zero
    +
    563  buffer->ReadWriteUInt32(&next_track_id));
    +
    564  return true;
    +
    565 }
    +
    566 
    +
    567 size_t MovieHeader::ComputeSizeInternal() {
    +
    568  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
    +
    569  return HeaderSize() + sizeof(uint32_t) * (1 + version) * 3 +
    +
    570  sizeof(timescale) + sizeof(rate) + sizeof(volume) +
    +
    571  sizeof(next_track_id) + sizeof(kUnityMatrix) + 10 +
    +
    572  24; // 10 bytes reserved, 24 bytes predefined.
    +
    573 }
    +
    574 
    +
    575 TrackHeader::TrackHeader() {
    +
    576  flags = kTrackEnabled | kTrackInMovie | kTrackInPreview;
    +
    577 }
    +
    578 
    +
    579 TrackHeader::~TrackHeader() = default;
    +
    580 
    +
    581 FourCC TrackHeader::BoxType() const {
    +
    582  return FOURCC_tkhd;
    +
    583 }
    +
    584 
    +
    585 bool TrackHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    586  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    587 
    +
    588  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    589  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
    +
    590  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
    +
    591  buffer->ReadWriteUInt32(&track_id) &&
    +
    592  buffer->IgnoreBytes(4) && // reserved
    +
    593  buffer->ReadWriteUInt64NBytes(&duration, num_bytes));
    +
    594 
    +
    595  if (!buffer->Reading()) {
    +
    596  // Set default value for volume, if track is audio, 0x100 else 0.
    +
    597  if (volume == -1)
    +
    598  volume = (width != 0 && height != 0) ? 0 : 0x100;
    +
    599  }
    +
    600  std::vector<uint8_t> matrix(kUnityMatrix,
    +
    601  kUnityMatrix + arraysize(kUnityMatrix));
    +
    602  RCHECK(buffer->IgnoreBytes(8) && // reserved
    +
    603  buffer->ReadWriteInt16(&layer) &&
    +
    604  buffer->ReadWriteInt16(&alternate_group) &&
    +
    605  buffer->ReadWriteInt16(&volume) &&
    +
    606  buffer->IgnoreBytes(2) && // reserved
    +
    607  buffer->ReadWriteVector(&matrix, matrix.size()) &&
    +
    608  buffer->ReadWriteUInt32(&width) && buffer->ReadWriteUInt32(&height));
    +
    609  return true;
    +
    610 }
    +
    611 
    +
    612 size_t TrackHeader::ComputeSizeInternal() {
    +
    613  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
    +
    614  return HeaderSize() + sizeof(track_id) +
    +
    615  sizeof(uint32_t) * (1 + version) * 3 + sizeof(layer) +
    +
    616  sizeof(alternate_group) + sizeof(volume) + sizeof(width) +
    +
    617  sizeof(height) + sizeof(kUnityMatrix) + 14; // 14 bytes reserved.
    +
    618 }
    +
    619 
    +
    620 SampleDescription::SampleDescription() = default;
    +
    621 SampleDescription::~SampleDescription() = default;
    +
    622 
    + +
    624  return FOURCC_stsd;
    +
    625 }
    +
    626 
    +
    627 bool SampleDescription::ReadWriteInternal(BoxBuffer* buffer) {
    +
    628  uint32_t count = 0;
    +
    629  switch (type) {
    +
    630  case kVideo:
    +
    631  count = static_cast<uint32_t>(video_entries.size());
    +
    632  break;
    +
    633  case kAudio:
    +
    634  count = static_cast<uint32_t>(audio_entries.size());
    +
    635  break;
    +
    636  case kText:
    +
    637  case kSubtitle:
    +
    638  count = static_cast<uint32_t>(text_entries.size());
    +
    639  break;
    +
    640  default:
    +
    641  NOTIMPLEMENTED() << "SampleDecryption type " << type
    +
    642  << " is not handled. Skipping.";
    +
    643  }
    +
    644  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    +
    645 
    +
    646  if (buffer->Reading()) {
    +
    647  BoxReader* reader = buffer->reader();
    +
    648  DCHECK(reader);
    +
    649  video_entries.clear();
    +
    650  audio_entries.clear();
    +
    651  // Note: this value is preset before scanning begins. See comments in the
    +
    652  // Parse(Media*) function.
    +
    653  if (type == kVideo) {
    +
    654  RCHECK(reader->ReadAllChildren(&video_entries));
    +
    655  RCHECK(video_entries.size() == count);
    +
    656  } else if (type == kAudio) {
    +
    657  RCHECK(reader->ReadAllChildren(&audio_entries));
    +
    658  RCHECK(audio_entries.size() == count);
    +
    659  } else if (type == kText || type == kSubtitle) {
    +
    660  RCHECK(reader->ReadAllChildren(&text_entries));
    +
    661  RCHECK(text_entries.size() == count);
    +
    662  }
    +
    663  } else {
    +
    664  DCHECK_LT(0u, count);
    +
    665  if (type == kVideo) {
    +
    666  for (uint32_t i = 0; i < count; ++i)
    +
    667  RCHECK(buffer->ReadWriteChild(&video_entries[i]));
    +
    668  } else if (type == kAudio) {
    +
    669  for (uint32_t i = 0; i < count; ++i)
    +
    670  RCHECK(buffer->ReadWriteChild(&audio_entries[i]));
    +
    671  } else if (type == kText || type == kSubtitle) {
    +
    672  for (uint32_t i = 0; i < count; ++i)
    +
    673  RCHECK(buffer->ReadWriteChild(&text_entries[i]));
    +
    674  } else {
    +
    675  NOTIMPLEMENTED();
    +
    676  }
    +
    677  }
    +
    678  return true;
    +
    679 }
    +
    680 
    +
    681 size_t SampleDescription::ComputeSizeInternal() {
    +
    682  size_t box_size = HeaderSize() + sizeof(uint32_t);
    +
    683  if (type == kVideo) {
    +
    684  for (uint32_t i = 0; i < video_entries.size(); ++i)
    +
    685  box_size += video_entries[i].ComputeSize();
    +
    686  } else if (type == kAudio) {
    +
    687  for (uint32_t i = 0; i < audio_entries.size(); ++i)
    +
    688  box_size += audio_entries[i].ComputeSize();
    +
    689  } else if (type == kText || type == kSubtitle) {
    +
    690  for (uint32_t i = 0; i < text_entries.size(); ++i)
    +
    691  box_size += text_entries[i].ComputeSize();
    +
    692  }
    +
    693  return box_size;
    +
    694 }
    +
    695 
    +
    696 DecodingTimeToSample::DecodingTimeToSample() = default;
    +
    697 DecodingTimeToSample::~DecodingTimeToSample() = default;
    +
    698 
    + +
    700  return FOURCC_stts;
    +
    701 }
    +
    702 
    +
    703 bool DecodingTimeToSample::ReadWriteInternal(BoxBuffer* buffer) {
    +
    704  uint32_t count = static_cast<uint32_t>(decoding_time.size());
    +
    705  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    +
    706 
    +
    707  decoding_time.resize(count);
    +
    708  for (uint32_t i = 0; i < count; ++i) {
    +
    709  RCHECK(buffer->ReadWriteUInt32(&decoding_time[i].sample_count) &&
    +
    710  buffer->ReadWriteUInt32(&decoding_time[i].sample_delta));
    +
    711  }
    +
    712  return true;
    +
    713 }
    +
    714 
    +
    715 size_t DecodingTimeToSample::ComputeSizeInternal() {
    +
    716  return HeaderSize() + sizeof(uint32_t) +
    +
    717  sizeof(DecodingTime) * decoding_time.size();
    +
    718 }
    +
    719 
    +
    720 CompositionTimeToSample::CompositionTimeToSample() = default;
    +
    721 CompositionTimeToSample::~CompositionTimeToSample() = default;
    +
    722 
    + +
    724  return FOURCC_ctts;
    +
    725 }
    +
    726 
    +
    727 bool CompositionTimeToSample::ReadWriteInternal(BoxBuffer* buffer) {
    +
    728  uint32_t count = static_cast<uint32_t>(composition_offset.size());
    +
    729  if (!buffer->Reading()) {
    +
    730  // Determine whether version 0 or version 1 should be used.
    +
    731  // Use version 0 if possible, use version 1 if there is a negative
    +
    732  // sample_offset value.
    +
    733  version = 0;
    +
    734  for (uint32_t i = 0; i < count; ++i) {
    +
    735  if (composition_offset[i].sample_offset < 0) {
    +
    736  version = 1;
    +
    737  break;
    +
    738  }
    +
    739  }
    +
    740  }
    +
    741 
    +
    742  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    +
    743 
    +
    744  composition_offset.resize(count);
    +
    745  for (uint32_t i = 0; i < count; ++i) {
    +
    746  RCHECK(buffer->ReadWriteUInt32(&composition_offset[i].sample_count));
    +
    747 
    +
    748  if (version == 0) {
    +
    749  uint32_t sample_offset = composition_offset[i].sample_offset;
    +
    750  RCHECK(buffer->ReadWriteUInt32(&sample_offset));
    +
    751  composition_offset[i].sample_offset = sample_offset;
    +
    752  } else {
    +
    753  int32_t sample_offset = composition_offset[i].sample_offset;
    +
    754  RCHECK(buffer->ReadWriteInt32(&sample_offset));
    +
    755  composition_offset[i].sample_offset = sample_offset;
    +
    756  }
    +
    757  }
    +
    758  return true;
    +
    759 }
    +
    760 
    +
    761 size_t CompositionTimeToSample::ComputeSizeInternal() {
    +
    762  // This box is optional. Skip it if it is empty.
    +
    763  if (composition_offset.empty())
    +
    764  return 0;
    +
    765  // Structure CompositionOffset contains |sample_offset| (uint32_t) and
    +
    766  // |sample_offset| (int64_t). The actual size of |sample_offset| is
    +
    767  // 4 bytes (uint32_t for version 0 and int32_t for version 1).
    +
    768  const size_t kCompositionOffsetSize = sizeof(uint32_t) * 2;
    +
    769  return HeaderSize() + sizeof(uint32_t) +
    +
    770  kCompositionOffsetSize * composition_offset.size();
    +
    771 }
    +
    772 
    +
    773 SampleToChunk::SampleToChunk() = default;
    +
    774 SampleToChunk::~SampleToChunk() = default;
    +
    775 
    +
    776 FourCC SampleToChunk::BoxType() const {
    +
    777  return FOURCC_stsc;
    +
    778 }
    +
    779 
    +
    780 bool SampleToChunk::ReadWriteInternal(BoxBuffer* buffer) {
    +
    781  uint32_t count = static_cast<uint32_t>(chunk_info.size());
    +
    782  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    +
    783 
    +
    784  chunk_info.resize(count);
    +
    785  for (uint32_t i = 0; i < count; ++i) {
    +
    786  RCHECK(buffer->ReadWriteUInt32(&chunk_info[i].first_chunk) &&
    +
    787  buffer->ReadWriteUInt32(&chunk_info[i].samples_per_chunk) &&
    +
    788  buffer->ReadWriteUInt32(&chunk_info[i].sample_description_index));
    +
    789  // first_chunk values are always increasing.
    +
    790  RCHECK(i == 0 ? chunk_info[i].first_chunk == 1
    +
    791  : chunk_info[i].first_chunk > chunk_info[i - 1].first_chunk);
    +
    792  }
    +
    793  return true;
    +
    794 }
    +
    795 
    +
    796 size_t SampleToChunk::ComputeSizeInternal() {
    +
    797  return HeaderSize() + sizeof(uint32_t) +
    +
    798  sizeof(ChunkInfo) * chunk_info.size();
    +
    799 }
    +
    800 
    +
    801 SampleSize::SampleSize() = default;
    +
    802 SampleSize::~SampleSize() = default;
    +
    803 
    +
    804 FourCC SampleSize::BoxType() const {
    +
    805  return FOURCC_stsz;
    +
    806 }
    +
    807 
    +
    808 bool SampleSize::ReadWriteInternal(BoxBuffer* buffer) {
    +
    809  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    810  buffer->ReadWriteUInt32(&sample_size) &&
    +
    811  buffer->ReadWriteUInt32(&sample_count));
    +
    812 
    +
    813  if (sample_size == 0) {
    +
    814  if (buffer->Reading())
    +
    815  sizes.resize(sample_count);
    +
    816  else
    +
    817  DCHECK(sample_count == sizes.size());
    +
    818  for (uint32_t i = 0; i < sample_count; ++i)
    +
    819  RCHECK(buffer->ReadWriteUInt32(&sizes[i]));
    +
    820  }
    +
    821  return true;
    +
    822 }
    +
    823 
    +
    824 size_t SampleSize::ComputeSizeInternal() {
    +
    825  return HeaderSize() + sizeof(sample_size) + sizeof(sample_count) +
    +
    826  (sample_size == 0 ? sizeof(uint32_t) * sizes.size() : 0);
    +
    827 }
    +
    828 
    +
    829 CompactSampleSize::CompactSampleSize() = default;
    +
    830 CompactSampleSize::~CompactSampleSize() = default;
    +
    831 
    + +
    833  return FOURCC_stz2;
    +
    834 }
    +
    835 
    +
    836 bool CompactSampleSize::ReadWriteInternal(BoxBuffer* buffer) {
    +
    837  uint32_t sample_count = static_cast<uint32_t>(sizes.size());
    +
    838  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->IgnoreBytes(3) &&
    +
    839  buffer->ReadWriteUInt8(&field_size) &&
    +
    840  buffer->ReadWriteUInt32(&sample_count));
    +
    841 
    +
    842  // Reserve one more entry if field size is 4 bits.
    +
    843  sizes.resize(sample_count + (field_size == 4 ? 1 : 0), 0);
    +
    844  switch (field_size) {
    +
    845  case 4:
    +
    846  for (uint32_t i = 0; i < sample_count; i += 2) {
    +
    847  if (buffer->Reading()) {
    +
    848  uint8_t size = 0;
    +
    849  RCHECK(buffer->ReadWriteUInt8(&size));
    +
    850  sizes[i] = size >> 4;
    +
    851  sizes[i + 1] = size & 0x0F;
    +
    852  } else {
    +
    853  DCHECK_LT(sizes[i], 16u);
    +
    854  DCHECK_LT(sizes[i + 1], 16u);
    +
    855  uint8_t size = (sizes[i] << 4) | sizes[i + 1];
    +
    856  RCHECK(buffer->ReadWriteUInt8(&size));
    +
    857  }
    +
    858  }
    +
    859  break;
    +
    860  case 8:
    +
    861  for (uint32_t i = 0; i < sample_count; ++i) {
    +
    862  uint8_t size = sizes[i];
    +
    863  RCHECK(buffer->ReadWriteUInt8(&size));
    +
    864  sizes[i] = size;
    +
    865  }
    +
    866  break;
    +
    867  case 16:
    +
    868  for (uint32_t i = 0; i < sample_count; ++i) {
    +
    869  uint16_t size = sizes[i];
    +
    870  RCHECK(buffer->ReadWriteUInt16(&size));
    +
    871  sizes[i] = size;
    +
    872  }
    +
    873  break;
    +
    874  default:
    +
    875  RCHECK(false);
    +
    876  }
    +
    877  sizes.resize(sample_count);
    +
    878  return true;
    +
    879 }
    +
    880 
    +
    881 size_t CompactSampleSize::ComputeSizeInternal() {
    +
    882  return HeaderSize() + sizeof(uint32_t) + sizeof(uint32_t) +
    +
    883  (field_size * sizes.size() + 7) / 8;
    +
    884 }
    +
    885 
    +
    886 ChunkOffset::ChunkOffset() = default;
    +
    887 ChunkOffset::~ChunkOffset() = default;
    +
    888 
    +
    889 FourCC ChunkOffset::BoxType() const {
    +
    890  return FOURCC_stco;
    +
    891 }
    +
    892 
    +
    893 bool ChunkOffset::ReadWriteInternal(BoxBuffer* buffer) {
    +
    894  uint32_t count = static_cast<uint32_t>(offsets.size());
    +
    895  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    +
    896 
    +
    897  offsets.resize(count);
    +
    898  for (uint32_t i = 0; i < count; ++i)
    +
    899  RCHECK(buffer->ReadWriteUInt64NBytes(&offsets[i], sizeof(uint32_t)));
    +
    900  return true;
    +
    901 }
    +
    902 
    +
    903 size_t ChunkOffset::ComputeSizeInternal() {
    +
    904  return HeaderSize() + sizeof(uint32_t) + sizeof(uint32_t) * offsets.size();
    +
    905 }
    +
    906 
    +
    907 ChunkLargeOffset::ChunkLargeOffset() = default;
    +
    908 ChunkLargeOffset::~ChunkLargeOffset() = default;
    +
    909 
    + +
    911  return FOURCC_co64;
    +
    912 }
    +
    913 
    +
    914 bool ChunkLargeOffset::ReadWriteInternal(BoxBuffer* buffer) {
    +
    915  uint32_t count = static_cast<uint32_t>(offsets.size());
    +
    916 
    +
    917  if (!buffer->Reading()) {
    +
    918  // Switch to ChunkOffset box if it is able to fit in 32 bits offset.
    +
    919  if (count == 0 || IsFitIn32Bits(offsets[count - 1])) {
    +
    920  ChunkOffset stco;
    +
    921  stco.offsets.swap(offsets);
    +
    922  DCHECK(buffer->writer());
    +
    923  stco.Write(buffer->writer());
    +
    924  stco.offsets.swap(offsets);
    +
    925  return true;
    +
    926  }
    +
    927  }
    +
    928 
    +
    929  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    +
    930 
    +
    931  offsets.resize(count);
    +
    932  for (uint32_t i = 0; i < count; ++i)
    +
    933  RCHECK(buffer->ReadWriteUInt64(&offsets[i]));
    +
    934  return true;
    +
    935 }
    +
    936 
    +
    937 size_t ChunkLargeOffset::ComputeSizeInternal() {
    +
    938  uint32_t count = static_cast<uint32_t>(offsets.size());
    +
    939  int use_large_offset =
    +
    940  (count > 0 && !IsFitIn32Bits(offsets[count - 1])) ? 1 : 0;
    +
    941  return HeaderSize() + sizeof(count) +
    +
    942  sizeof(uint32_t) * (1 + use_large_offset) * offsets.size();
    +
    943 }
    +
    944 
    +
    945 SyncSample::SyncSample() = default;
    +
    946 SyncSample::~SyncSample() = default;
    +
    947 
    +
    948 FourCC SyncSample::BoxType() const {
    +
    949  return FOURCC_stss;
    +
    950 }
    +
    951 
    +
    952 bool SyncSample::ReadWriteInternal(BoxBuffer* buffer) {
    +
    953  uint32_t count = static_cast<uint32_t>(sample_number.size());
    +
    954  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    +
    955 
    +
    956  sample_number.resize(count);
    +
    957  for (uint32_t i = 0; i < count; ++i)
    +
    958  RCHECK(buffer->ReadWriteUInt32(&sample_number[i]));
    +
    959  return true;
    +
    960 }
    +
    961 
    +
    962 size_t SyncSample::ComputeSizeInternal() {
    +
    963  // Sync sample box is optional. Skip it if it is empty.
    +
    964  if (sample_number.empty())
    +
    965  return 0;
    +
    966  return HeaderSize() + sizeof(uint32_t) +
    +
    967  sizeof(uint32_t) * sample_number.size();
    +
    968 }
    +
    969 
    +
    970 bool CencSampleEncryptionInfoEntry::ReadWrite(BoxBuffer* buffer) {
    +
    971  if (!buffer->Reading()) {
    +
    972  if (key_id.size() != kCencKeyIdSize) {
    +
    973  LOG(WARNING) << "CENC defines key id length of " << kCencKeyIdSize
    +
    974  << " bytes; got " << key_id.size()
    +
    975  << ". Resized accordingly.";
    +
    976  key_id.resize(kCencKeyIdSize);
    +
    977  }
    +
    978  RCHECK(crypt_byte_block < 16 && skip_byte_block < 16);
    +
    979  }
    +
    980 
    +
    981  RCHECK(buffer->IgnoreBytes(1)); // reserved.
    +
    982 
    +
    983  uint8_t pattern = crypt_byte_block << 4 | skip_byte_block;
    +
    984  RCHECK(buffer->ReadWriteUInt8(&pattern));
    +
    985  crypt_byte_block = pattern >> 4;
    +
    986  skip_byte_block = pattern & 0x0F;
    +
    987 
    +
    988  RCHECK(buffer->ReadWriteUInt8(&is_protected) &&
    +
    989  buffer->ReadWriteUInt8(&per_sample_iv_size) &&
    +
    990  buffer->ReadWriteVector(&key_id, kCencKeyIdSize));
    +
    991 
    +
    992  if (is_protected == 1) {
    +
    993  if (per_sample_iv_size == 0) { // For constant iv.
    +
    994  uint8_t constant_iv_size = static_cast<uint8_t>(constant_iv.size());
    +
    995  RCHECK(buffer->ReadWriteUInt8(&constant_iv_size));
    +
    996  RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
    +
    997  RCHECK(buffer->ReadWriteVector(&constant_iv, constant_iv_size));
    +
    998  } else {
    +
    999  RCHECK(per_sample_iv_size == 8 || per_sample_iv_size == 16);
    +
    1000  DCHECK(constant_iv.empty());
    +
    1001  }
    +
    1002  } else {
    +
    1003  // Expect |is_protected| to be 0, i.e. not protected. Other values of
    +
    1004  // |is_protected| is not supported.
    +
    1005  RCHECK(is_protected == 0);
    +
    1006  RCHECK(per_sample_iv_size == 0);
    +
    1007  }
    +
    1008  return true;
    +
    1009 }
    +
    1010 
    +
    1011 uint32_t CencSampleEncryptionInfoEntry::ComputeSize() const {
    +
    1012  return static_cast<uint32_t>(
    +
    1013  sizeof(uint32_t) + kCencKeyIdSize +
    +
    1014  (constant_iv.empty() ? 0 : (sizeof(uint8_t) + constant_iv.size())));
    +
    1015 }
    +
    1016 
    +
    1017 bool AudioRollRecoveryEntry::ReadWrite(BoxBuffer* buffer) {
    +
    1018  RCHECK(buffer->ReadWriteInt16(&roll_distance));
    +
    1019  return true;
    +
    1020 }
    +
    1021 
    +
    1022 uint32_t AudioRollRecoveryEntry::ComputeSize() const {
    +
    1023  return sizeof(roll_distance);
    +
    1024 }
    +
    1025 
    +
    1026 SampleGroupDescription::SampleGroupDescription() = default;
    +
    1027 SampleGroupDescription::~SampleGroupDescription() = default;
    +
    1028 
    + +
    1030  return FOURCC_sgpd;
    +
    1031 }
    +
    1032 
    +
    1033 bool SampleGroupDescription::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1034  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    1035  buffer->ReadWriteUInt32(&grouping_type));
    +
    1036 
    +
    1037  switch (grouping_type) {
    +
    1038  case FOURCC_seig:
    +
    1039  return ReadWriteEntries(buffer, &cenc_sample_encryption_info_entries);
    +
    1040  case FOURCC_roll:
    +
    1041  return ReadWriteEntries(buffer, &audio_roll_recovery_entries);
    +
    1042  default:
    +
    1043  DCHECK(buffer->Reading());
    +
    1044  DLOG(WARNING) << "Ignore unsupported sample group: "
    +
    1045  << FourCCToString(static_cast<FourCC>(grouping_type));
    +
    1046  return true;
    +
    1047  }
    +
    1048 }
    +
    1049 
    +
    1050 template <typename T>
    +
    1051 bool SampleGroupDescription::ReadWriteEntries(BoxBuffer* buffer,
    +
    1052  std::vector<T>* entries) {
    +
    1053  uint32_t default_length = 0;
    +
    1054  if (!buffer->Reading()) {
    +
    1055  DCHECK(!entries->empty());
    +
    1056  default_length = (*entries)[0].ComputeSize();
    +
    1057  DCHECK_NE(default_length, 0u);
    +
    1058  }
    +
    1059  if (version == 1)
    +
    1060  RCHECK(buffer->ReadWriteUInt32(&default_length));
    +
    1061  if (version >= 2) {
    +
    1062  NOTIMPLEMENTED() << "Unsupported SampleGroupDescriptionBox 'sgpd' version "
    +
    1063  << static_cast<int>(version);
    +
    1064  return false;
    +
    1065  }
    +
    1066 
    +
    1067  uint32_t count = static_cast<uint32_t>(entries->size());
    +
    1068  RCHECK(buffer->ReadWriteUInt32(&count));
    +
    1069  if (buffer->Reading()) {
    +
    1070  if (count == 0)
    +
    1071  return true;
    +
    1072  } else {
    +
    1073  RCHECK(count != 0);
    +
    1074  }
    +
    1075  entries->resize(count);
    +
    1076 
    +
    1077  for (T& entry : *entries) {
    +
    1078  if (version == 1) {
    +
    1079  uint32_t description_length = default_length;
    +
    1080  if (buffer->Reading() && default_length == 0)
    +
    1081  RCHECK(buffer->ReadWriteUInt32(&description_length));
    +
    1082  RCHECK(entry.ReadWrite(buffer));
    +
    1083  RCHECK(entry.ComputeSize() == description_length);
    +
    1084  } else {
    +
    1085  RCHECK(entry.ReadWrite(buffer));
    +
    1086  }
    +
    1087  }
    +
    1088  return true;
    +
    1089 }
    +
    1090 
    +
    1091 size_t SampleGroupDescription::ComputeSizeInternal() {
    +
    1092  // Version 0 is obsoleted, so always generate version 1 box.
    +
    1093  version = 1;
    +
    1094  size_t entries_size = 0;
    +
    1095  switch (grouping_type) {
    +
    1096  case FOURCC_seig:
    +
    1097  for (const auto& entry : cenc_sample_encryption_info_entries)
    +
    1098  entries_size += entry.ComputeSize();
    +
    1099  break;
    +
    1100  case FOURCC_roll:
    +
    1101  for (const auto& entry : audio_roll_recovery_entries)
    +
    1102  entries_size += entry.ComputeSize();
    +
    1103  break;
    +
    1104  }
    +
    1105  // This box is optional. Skip it if it is not used.
    +
    1106  if (entries_size == 0)
    +
    1107  return 0;
    +
    1108  return HeaderSize() + sizeof(grouping_type) +
    +
    1109  (version == 1 ? sizeof(uint32_t) : 0) + sizeof(uint32_t) +
    +
    1110  entries_size;
    +
    1111 }
    +
    1112 
    +
    1113 SampleToGroup::SampleToGroup() = default;
    +
    1114 SampleToGroup::~SampleToGroup() = default;
    +
    1115 
    +
    1116 FourCC SampleToGroup::BoxType() const {
    +
    1117  return FOURCC_sbgp;
    +
    1118 }
    +
    1119 
    +
    1120 bool SampleToGroup::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1121  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    1122  buffer->ReadWriteUInt32(&grouping_type));
    +
    1123  if (version == 1)
    +
    1124  RCHECK(buffer->ReadWriteUInt32(&grouping_type_parameter));
    +
    1125 
    +
    1126  if (grouping_type != FOURCC_seig && grouping_type != FOURCC_roll) {
    +
    1127  DCHECK(buffer->Reading());
    +
    1128  DLOG(WARNING) << "Ignore unsupported sample group: "
    +
    1129  << FourCCToString(static_cast<FourCC>(grouping_type));
    +
    1130  return true;
    +
    1131  }
    +
    1132 
    +
    1133  uint32_t count = static_cast<uint32_t>(entries.size());
    +
    1134  RCHECK(buffer->ReadWriteUInt32(&count));
    +
    1135  entries.resize(count);
    +
    1136  for (uint32_t i = 0; i < count; ++i) {
    +
    1137  RCHECK(buffer->ReadWriteUInt32(&entries[i].sample_count) &&
    +
    1138  buffer->ReadWriteUInt32(&entries[i].group_description_index));
    +
    1139  }
    +
    1140  return true;
    +
    1141 }
    +
    1142 
    +
    1143 size_t SampleToGroup::ComputeSizeInternal() {
    +
    1144  // This box is optional. Skip it if it is not used.
    +
    1145  if (entries.empty())
    +
    1146  return 0;
    +
    1147  return HeaderSize() + sizeof(grouping_type) +
    +
    1148  (version == 1 ? sizeof(grouping_type_parameter) : 0) +
    +
    1149  sizeof(uint32_t) + entries.size() * sizeof(entries[0]);
    +
    1150 }
    +
    1151 
    +
    1152 SampleTable::SampleTable() = default;
    +
    1153 SampleTable::~SampleTable() = default;
    +
    1154 
    +
    1155 FourCC SampleTable::BoxType() const {
    +
    1156  return FOURCC_stbl;
    +
    1157 }
    +
    1158 
    +
    1159 bool SampleTable::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1160  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    1161  buffer->ReadWriteChild(&description) &&
    +
    1162  buffer->ReadWriteChild(&decoding_time_to_sample) &&
    +
    1163  buffer->TryReadWriteChild(&composition_time_to_sample) &&
    +
    1164  buffer->ReadWriteChild(&sample_to_chunk));
    +
    1165 
    +
    1166  if (buffer->Reading()) {
    +
    1167  BoxReader* reader = buffer->reader();
    +
    1168  DCHECK(reader);
    +
    1169 
    +
    1170  // Either SampleSize or CompactSampleSize must present.
    +
    1171  if (reader->ChildExist(&sample_size)) {
    +
    1172  RCHECK(reader->ReadChild(&sample_size));
    +
    1173  } else {
    +
    1174  CompactSampleSize compact_sample_size;
    +
    1175  RCHECK(reader->ReadChild(&compact_sample_size));
    +
    1176  sample_size.sample_size = 0;
    +
    1177  sample_size.sample_count =
    +
    1178  static_cast<uint32_t>(compact_sample_size.sizes.size());
    +
    1179  sample_size.sizes.swap(compact_sample_size.sizes);
    +
    1180  }
    +
    1181 
    +
    1182  // Either ChunkOffset or ChunkLargeOffset must present.
    +
    1183  if (reader->ChildExist(&chunk_large_offset)) {
    +
    1184  RCHECK(reader->ReadChild(&chunk_large_offset));
    +
    1185  } else {
    +
    1186  ChunkOffset chunk_offset;
    +
    1187  RCHECK(reader->ReadChild(&chunk_offset));
    +
    1188  chunk_large_offset.offsets.swap(chunk_offset.offsets);
    +
    1189  }
    +
    1190  } else {
    +
    1191  RCHECK(buffer->ReadWriteChild(&sample_size) &&
    +
    1192  buffer->ReadWriteChild(&chunk_large_offset));
    +
    1193  }
    +
    1194  RCHECK(buffer->TryReadWriteChild(&sync_sample));
    +
    1195  if (buffer->Reading()) {
    +
    1196  RCHECK(buffer->reader()->TryReadChildren(&sample_group_descriptions) &&
    +
    1197  buffer->reader()->TryReadChildren(&sample_to_groups));
    +
    1198  } else {
    +
    1199  for (auto& sample_group_description : sample_group_descriptions)
    +
    1200  RCHECK(buffer->ReadWriteChild(&sample_group_description));
    +
    1201  for (auto& sample_to_group : sample_to_groups)
    +
    1202  RCHECK(buffer->ReadWriteChild(&sample_to_group));
    +
    1203  }
    +
    1204  return true;
    +
    1205 }
    +
    1206 
    +
    1207 size_t SampleTable::ComputeSizeInternal() {
    +
    1208  size_t box_size = HeaderSize() + description.ComputeSize() +
    +
    1209  decoding_time_to_sample.ComputeSize() +
    +
    1210  composition_time_to_sample.ComputeSize() +
    +
    1211  sample_to_chunk.ComputeSize() + sample_size.ComputeSize() +
    +
    1212  chunk_large_offset.ComputeSize() +
    +
    1213  sync_sample.ComputeSize();
    +
    1214  for (auto& sample_group_description : sample_group_descriptions)
    +
    1215  box_size += sample_group_description.ComputeSize();
    +
    1216  for (auto& sample_to_group : sample_to_groups)
    +
    1217  box_size += sample_to_group.ComputeSize();
    +
    1218  return box_size;
    +
    1219 }
    +
    1220 
    +
    1221 EditList::EditList() = default;
    +
    1222 EditList::~EditList() = default;
    +
    1223 
    +
    1224 FourCC EditList::BoxType() const {
    +
    1225  return FOURCC_elst;
    +
    1226 }
    +
    1227 
    +
    1228 bool EditList::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1229  uint32_t count = static_cast<uint32_t>(edits.size());
    +
    1230  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&count));
    +
    1231  edits.resize(count);
    +
    1232 
    +
    1233  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    1234  for (uint32_t i = 0; i < count; ++i) {
    +
    1235  RCHECK(
    +
    1236  buffer->ReadWriteUInt64NBytes(&edits[i].segment_duration, num_bytes) &&
    +
    1237  buffer->ReadWriteInt64NBytes(&edits[i].media_time, num_bytes) &&
    +
    1238  buffer->ReadWriteInt16(&edits[i].media_rate_integer) &&
    +
    1239  buffer->ReadWriteInt16(&edits[i].media_rate_fraction));
    +
    1240  }
    +
    1241  return true;
    +
    1242 }
    +
    1243 
    +
    1244 size_t EditList::ComputeSizeInternal() {
    +
    1245  // EditList box is optional. Skip it if it is empty.
    +
    1246  if (edits.empty())
    +
    1247  return 0;
    +
    1248 
    +
    1249  version = 0;
    +
    1250  for (uint32_t i = 0; i < edits.size(); ++i) {
    +
    1251  if (!IsFitIn32Bits(edits[i].segment_duration, edits[i].media_time)) {
    +
    1252  version = 1;
    +
    1253  break;
    +
    1254  }
    +
    1255  }
    +
    1256  return HeaderSize() + sizeof(uint32_t) +
    +
    1257  (sizeof(uint32_t) * (1 + version) * 2 + sizeof(int16_t) * 2) *
    +
    1258  edits.size();
    +
    1259 }
    +
    1260 
    +
    1261 Edit::Edit() = default;
    +
    1262 Edit::~Edit() = default;
    +
    1263 
    +
    1264 FourCC Edit::BoxType() const {
    +
    1265  return FOURCC_edts;
    +
    1266 }
    +
    1267 
    +
    1268 bool Edit::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1269  return ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    1270  buffer->ReadWriteChild(&list);
    +
    1271 }
    +
    1272 
    +
    1273 size_t Edit::ComputeSizeInternal() {
    +
    1274  // Edit box is optional. Skip it if it is empty.
    +
    1275  if (list.edits.empty())
    +
    1276  return 0;
    +
    1277  return HeaderSize() + list.ComputeSize();
    +
    1278 }
    +
    1279 
    +
    1280 HandlerReference::HandlerReference() = default;
    +
    1281 HandlerReference::~HandlerReference() = default;
    +
    1282 
    + +
    1284  return FOURCC_hdlr;
    +
    1285 }
    +
    1286 
    +
    1287 bool HandlerReference::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1288  std::vector<uint8_t> handler_name;
    +
    1289  if (!buffer->Reading()) {
    +
    1290  switch (handler_type) {
    +
    1291  case FOURCC_vide:
    +
    1292  handler_name.assign(kVideoHandlerName,
    +
    1293  kVideoHandlerName + arraysize(kVideoHandlerName));
    +
    1294  break;
    +
    1295  case FOURCC_soun:
    +
    1296  handler_name.assign(kAudioHandlerName,
    +
    1297  kAudioHandlerName + arraysize(kAudioHandlerName));
    +
    1298  break;
    +
    1299  case FOURCC_text:
    +
    1300  handler_name.assign(kTextHandlerName,
    +
    1301  kTextHandlerName + arraysize(kTextHandlerName));
    +
    1302  break;
    +
    1303  case FOURCC_subt:
    +
    1304  handler_name.assign(
    +
    1305  kSubtitleHandlerName,
    +
    1306  kSubtitleHandlerName + arraysize(kSubtitleHandlerName));
    +
    1307  break;
    +
    1308  case FOURCC_ID32:
    +
    1309  break;
    +
    1310  default:
    +
    1311  NOTIMPLEMENTED();
    +
    1312  return false;
    +
    1313  }
    +
    1314  }
    +
    1315  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    1316  buffer->IgnoreBytes(4) && // predefined.
    +
    1317  buffer->ReadWriteFourCC(&handler_type));
    +
    1318  if (!buffer->Reading()) {
    +
    1319  RCHECK(buffer->IgnoreBytes(12) && // reserved.
    +
    1320  buffer->ReadWriteVector(&handler_name, handler_name.size()));
    +
    1321  }
    +
    1322  return true;
    +
    1323 }
    +
    1324 
    +
    1325 size_t HandlerReference::ComputeSizeInternal() {
    +
    1326  size_t box_size = HeaderSize() + kFourCCSize + 16; // 16 bytes Reserved
    +
    1327  switch (handler_type) {
    +
    1328  case FOURCC_vide:
    +
    1329  box_size += sizeof(kVideoHandlerName);
    +
    1330  break;
    +
    1331  case FOURCC_soun:
    +
    1332  box_size += sizeof(kAudioHandlerName);
    +
    1333  break;
    +
    1334  case FOURCC_text:
    +
    1335  box_size += sizeof(kTextHandlerName);
    +
    1336  break;
    +
    1337  case FOURCC_subt:
    +
    1338  box_size += sizeof(kSubtitleHandlerName);
    +
    1339  break;
    +
    1340  case FOURCC_ID32:
    +
    1341  break;
    +
    1342  default:
    +
    1343  NOTIMPLEMENTED();
    +
    1344  }
    +
    1345  return box_size;
    +
    1346 }
    +
    1347 
    +
    1348 bool Language::ReadWrite(BoxBuffer* buffer) {
    +
    1349  if (buffer->Reading()) {
    +
    1350  // Read language codes into temp first then use BitReader to read the
    +
    1351  // values. ISO-639-2/T language code: unsigned int(5)[3] language (2 bytes).
    +
    1352  std::vector<uint8_t> temp;
    +
    1353  RCHECK(buffer->ReadWriteVector(&temp, 2));
    +
    1354 
    +
    1355  BitReader bit_reader(&temp[0], 2);
    +
    1356  bit_reader.SkipBits(1);
    +
    1357  char language[3];
    +
    1358  for (int i = 0; i < 3; ++i) {
    +
    1359  CHECK(bit_reader.ReadBits(5, &language[i]));
    +
    1360  language[i] += 0x60;
    +
    1361  }
    +
    1362  code.assign(language, 3);
    +
    1363  } else {
    +
    1364  // Set up default language if it is not set.
    +
    1365  const char kUndefinedLanguage[] = "und";
    +
    1366  if (code.empty())
    +
    1367  code = kUndefinedLanguage;
    +
    1368  DCHECK_EQ(code.size(), 3u);
    +
    1369 
    +
    1370  // Lang format: bit(1) pad, unsigned int(5)[3] language.
    +
    1371  uint16_t lang = 0;
    +
    1372  for (int i = 0; i < 3; ++i)
    +
    1373  lang |= (code[i] - 0x60) << ((2 - i) * 5);
    +
    1374  RCHECK(buffer->ReadWriteUInt16(&lang));
    +
    1375  }
    +
    1376  return true;
    +
    1377 }
    +
    1378 
    +
    1379 uint32_t Language::ComputeSize() const {
    +
    1380  // ISO-639-2/T language code: unsigned int(5)[3] language (2 bytes).
    +
    1381  return 2;
    +
    1382 }
    +
    1383 
    +
    1384 ID3v2::ID3v2() = default;
    +
    1385 ID3v2::~ID3v2() = default;
    +
    1386 
    +
    1387 FourCC ID3v2::BoxType() const {
    +
    1388  return FOURCC_ID32;
    +
    1389 }
    +
    1390 
    +
    1391 bool ID3v2::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1392  RCHECK(ReadWriteHeaderInternal(buffer) && language.ReadWrite(buffer) &&
    +
    1393  buffer->ReadWriteVector(&id3v2_data, buffer->Reading()
    +
    1394  ? buffer->BytesLeft()
    +
    1395  : id3v2_data.size()));
    +
    1396  return true;
    +
    1397 }
    +
    1398 
    +
    1399 size_t ID3v2::ComputeSizeInternal() {
    +
    1400  // Skip ID3v2 box generation if there is no id3 data.
    +
    1401  return id3v2_data.size() == 0
    +
    1402  ? 0
    +
    1403  : HeaderSize() + language.ComputeSize() + id3v2_data.size();
    +
    1404 }
    +
    1405 
    +
    1406 Metadata::Metadata() = default;
    +
    1407 Metadata::~Metadata() = default;
    +
    1408 
    +
    1409 FourCC Metadata::BoxType() const {
    +
    1410  return FOURCC_meta;
    +
    1411 }
    +
    1412 
    +
    1413 bool Metadata::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1414  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    1415  buffer->ReadWriteChild(&handler) && buffer->TryReadWriteChild(&id3v2));
    +
    1416  return true;
    +
    1417 }
    +
    1418 
    +
    1419 size_t Metadata::ComputeSizeInternal() {
    +
    1420  size_t id3v2_size = id3v2.ComputeSize();
    +
    1421  // Skip metadata box generation if there is no metadata box.
    +
    1422  return id3v2_size == 0 ? 0
    +
    1423  : HeaderSize() + handler.ComputeSize() + id3v2_size;
    +
    1424 }
    +
    1425 
    +
    1426 CodecConfiguration::CodecConfiguration() = default;
    +
    1427 CodecConfiguration::~CodecConfiguration() = default;
    +
    1428 
    + +
    1430  // CodecConfiguration box should be parsed according to format recovered in
    +
    1431  // VideoSampleEntry. |box_type| is determined dynamically there.
    +
    1432  return box_type;
    +
    1433 }
    +
    1434 
    +
    1435 bool CodecConfiguration::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1436  DCHECK_NE(box_type, FOURCC_NULL);
    +
    1437  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1438 
    +
    1439  // VPCodecConfiguration box inherits from FullBox instead of Box. The extra 4
    +
    1440  // bytes are handled here.
    +
    1441  if (box_type == FOURCC_vpcC) {
    +
    1442  // Only version 1 box is supported.
    +
    1443  uint8_t vpcc_version = 1;
    +
    1444  uint32_t version_flags = vpcc_version << 24;
    +
    1445  RCHECK(buffer->ReadWriteUInt32(&version_flags));
    +
    1446  vpcc_version = version_flags >> 24;
    +
    1447  RCHECK(vpcc_version == 1);
    +
    1448  }
    +
    1449 
    +
    1450  if (buffer->Reading()) {
    +
    1451  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
    +
    1452  } else {
    +
    1453  RCHECK(buffer->ReadWriteVector(&data, data.size()));
    +
    1454  }
    +
    1455  return true;
    +
    1456 }
    +
    1457 
    +
    1458 size_t CodecConfiguration::ComputeSizeInternal() {
    +
    1459  if (data.empty())
    +
    1460  return 0;
    +
    1461  DCHECK_NE(box_type, FOURCC_NULL);
    +
    1462  return HeaderSize() + (box_type == FOURCC_vpcC ? 4 : 0) + data.size();
    +
    1463 }
    +
    1464 
    +
    1465 PixelAspectRatio::PixelAspectRatio() = default;
    +
    1466 PixelAspectRatio::~PixelAspectRatio() = default;
    +
    1467 
    + +
    1469  return FOURCC_pasp;
    +
    1470 }
    +
    1471 
    +
    1472 bool PixelAspectRatio::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1473  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    1474  buffer->ReadWriteUInt32(&h_spacing) &&
    +
    1475  buffer->ReadWriteUInt32(&v_spacing));
    +
    1476  return true;
    +
    1477 }
    +
    1478 
    +
    1479 size_t PixelAspectRatio::ComputeSizeInternal() {
    +
    1480  // This box is optional. Skip it if it is not initialized.
    +
    1481  if (h_spacing == 0 && v_spacing == 0)
    +
    1482  return 0;
    +
    1483  // Both values must be positive.
    +
    1484  DCHECK(h_spacing != 0 && v_spacing != 0);
    +
    1485  return HeaderSize() + sizeof(h_spacing) + sizeof(v_spacing);
    +
    1486 }
    +
    1487 
    +
    1488 VideoSampleEntry::VideoSampleEntry() = default;
    +
    1489 VideoSampleEntry::~VideoSampleEntry() = default;
    +
    1490 
    + +
    1492  if (format == FOURCC_NULL) {
    +
    1493  LOG(ERROR) << "VideoSampleEntry should be parsed according to the "
    +
    1494  << "handler type recovered in its Media ancestor.";
    +
    1495  }
    +
    1496  return format;
    +
    1497 }
    +
    1498 
    +
    1499 bool VideoSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1500  std::vector<uint8_t> compressor_name;
    +
    1501  if (buffer->Reading()) {
    +
    1502  DCHECK(buffer->reader());
    +
    1503  format = buffer->reader()->type();
    +
    1504  } else {
    +
    1505  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1506 
    +
    1507  const FourCC actual_format = GetActualFormat();
    +
    1508  switch (actual_format) {
    +
    1509  case FOURCC_av01:
    +
    1510  compressor_name.assign(std::begin(kAv1CompressorName),
    +
    1511  std::end(kAv1CompressorName));
    +
    1512  break;
    +
    1513  case FOURCC_avc1:
    +
    1514  case FOURCC_avc3:
    +
    1515  compressor_name.assign(std::begin(kAvcCompressorName),
    +
    1516  std::end(kAvcCompressorName));
    +
    1517  break;
    +
    1518  case FOURCC_dvh1:
    +
    1519  case FOURCC_dvhe:
    +
    1520  compressor_name.assign(std::begin(kDolbyVisionCompressorName),
    +
    1521  std::end(kDolbyVisionCompressorName));
    +
    1522  break;
    +
    1523  case FOURCC_hev1:
    +
    1524  case FOURCC_hvc1:
    +
    1525  compressor_name.assign(std::begin(kHevcCompressorName),
    +
    1526  std::end(kHevcCompressorName));
    +
    1527  break;
    +
    1528  case FOURCC_vp08:
    +
    1529  case FOURCC_vp09:
    +
    1530  compressor_name.assign(std::begin(kVpcCompressorName),
    +
    1531  std::end(kVpcCompressorName));
    +
    1532  break;
    +
    1533  default:
    +
    1534  LOG(ERROR) << FourCCToString(actual_format) << " is not supported.";
    +
    1535  return false;
    +
    1536  }
    +
    1537  compressor_name.resize(kCompressorNameSize);
    +
    1538  }
    +
    1539 
    +
    1540  uint32_t video_resolution = kVideoResolution;
    +
    1541  uint16_t video_frame_count = kVideoFrameCount;
    +
    1542  uint16_t video_depth = kVideoDepth;
    +
    1543  int16_t predefined = -1;
    +
    1544  RCHECK(buffer->IgnoreBytes(6) && // reserved.
    +
    1545  buffer->ReadWriteUInt16(&data_reference_index) &&
    +
    1546  buffer->IgnoreBytes(16) && // predefined 0.
    +
    1547  buffer->ReadWriteUInt16(&width) && buffer->ReadWriteUInt16(&height) &&
    +
    1548  buffer->ReadWriteUInt32(&video_resolution) &&
    +
    1549  buffer->ReadWriteUInt32(&video_resolution) &&
    +
    1550  buffer->IgnoreBytes(4) && // reserved.
    +
    1551  buffer->ReadWriteUInt16(&video_frame_count) &&
    +
    1552  buffer->ReadWriteVector(&compressor_name, kCompressorNameSize) &&
    +
    1553  buffer->ReadWriteUInt16(&video_depth) &&
    +
    1554  buffer->ReadWriteInt16(&predefined));
    +
    1555 
    +
    1556  RCHECK(buffer->PrepareChildren());
    +
    1557 
    +
    1558  // This has to happen before reading codec configuration box as the actual
    +
    1559  // format is read from sinf.format.format, which is needed to parse the codec
    +
    1560  // configuration box.
    +
    1561  if (format == FOURCC_encv && buffer->Reading()) {
    +
    1562  // Continue scanning until a supported protection scheme is found, or
    +
    1563  // until we run out of protection schemes.
    +
    1564  while (!IsProtectionSchemeSupported(sinf.type.type))
    +
    1565  RCHECK(buffer->ReadWriteChild(&sinf));
    +
    1566  }
    +
    1567 
    +
    1568  const FourCC actual_format = GetActualFormat();
    +
    1569  if (buffer->Reading()) {
    +
    1570  codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
    +
    1571  } else {
    +
    1572  DCHECK_EQ(codec_configuration.box_type,
    +
    1573  GetCodecConfigurationBoxType(actual_format));
    +
    1574  }
    +
    1575  if (codec_configuration.box_type == FOURCC_NULL)
    +
    1576  return false;
    +
    1577 
    +
    1578  RCHECK(buffer->ReadWriteChild(&codec_configuration));
    +
    1579 
    +
    1580  if (buffer->Reading()) {
    +
    1581  extra_codec_configs.clear();
    +
    1582  // Handle Dolby Vision boxes.
    +
    1583  const bool is_hevc =
    +
    1584  actual_format == FOURCC_dvhe || actual_format == FOURCC_dvh1 ||
    +
    1585  actual_format == FOURCC_hev1 || actual_format == FOURCC_hvc1;
    +
    1586  if (is_hevc) {
    +
    1587  for (FourCC fourcc : {FOURCC_dvcC, FOURCC_dvvC, FOURCC_hvcE}) {
    +
    1588  CodecConfiguration dv_box;
    +
    1589  dv_box.box_type = fourcc;
    +
    1590  RCHECK(buffer->TryReadWriteChild(&dv_box));
    +
    1591  if (!dv_box.data.empty())
    +
    1592  extra_codec_configs.push_back(std::move(dv_box));
    +
    1593  }
    +
    1594  }
    +
    1595  } else {
    +
    1596  for (CodecConfiguration& extra_codec_config : extra_codec_configs)
    +
    1597  RCHECK(buffer->ReadWriteChild(&extra_codec_config));
    +
    1598  }
    +
    1599 
    +
    1600  RCHECK(buffer->TryReadWriteChild(&pixel_aspect));
    +
    1601 
    +
    1602  // Somehow Edge does not support having sinf box before codec_configuration,
    +
    1603  // box, so just do it in the end of VideoSampleEntry. See
    +
    1604  // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12658991/
    +
    1605  if (format == FOURCC_encv && !buffer->Reading()) {
    +
    1606  DCHECK(IsProtectionSchemeSupported(sinf.type.type));
    +
    1607  RCHECK(buffer->ReadWriteChild(&sinf));
    +
    1608  }
    +
    1609  return true;
    +
    1610 }
    +
    1611 
    +
    1612 size_t VideoSampleEntry::ComputeSizeInternal() {
    +
    1613  const FourCC actual_format = GetActualFormat();
    +
    1614  if (actual_format == FOURCC_NULL)
    +
    1615  return 0;
    +
    1616  codec_configuration.box_type = GetCodecConfigurationBoxType(actual_format);
    +
    1617  DCHECK_NE(codec_configuration.box_type, FOURCC_NULL);
    +
    1618  size_t size = HeaderSize() + sizeof(data_reference_index) + sizeof(width) +
    +
    1619  sizeof(height) + sizeof(kVideoResolution) * 2 +
    +
    1620  sizeof(kVideoFrameCount) + sizeof(kVideoDepth) +
    +
    1621  pixel_aspect.ComputeSize() + sinf.ComputeSize() +
    +
    1622  codec_configuration.ComputeSize() + kCompressorNameSize + 6 +
    +
    1623  4 + 16 + 2; // 6 + 4 bytes reserved, 16 + 2 bytes predefined.
    +
    1624  for (CodecConfiguration& codec_config : extra_codec_configs)
    +
    1625  size += codec_config.ComputeSize();
    +
    1626  return size;
    +
    1627 }
    +
    1628 
    +
    1629 FourCC VideoSampleEntry::GetCodecConfigurationBoxType(FourCC format) const {
    +
    1630  switch (format) {
    +
    1631  case FOURCC_av01:
    +
    1632  return FOURCC_av1C;
    +
    1633  case FOURCC_avc1:
    +
    1634  case FOURCC_avc3:
    +
    1635  return FOURCC_avcC;
    +
    1636  case FOURCC_dvh1:
    +
    1637  case FOURCC_dvhe:
    +
    1638  case FOURCC_hev1:
    +
    1639  case FOURCC_hvc1:
    +
    1640  return FOURCC_hvcC;
    +
    1641  case FOURCC_vp08:
    +
    1642  case FOURCC_vp09:
    +
    1643  return FOURCC_vpcC;
    +
    1644  default:
    +
    1645  LOG(ERROR) << FourCCToString(format) << " is not supported.";
    +
    1646  return FOURCC_NULL;
    +
    1647  }
    +
    1648 }
    +
    1649 
    +
    1650 std::vector<uint8_t> VideoSampleEntry::ExtraCodecConfigsAsVector() const {
    +
    1651  BufferWriter buffer;
    +
    1652  for (CodecConfiguration codec_config : extra_codec_configs)
    +
    1653  codec_config.Write(&buffer);
    +
    1654  return std::vector<uint8_t>(buffer.Buffer(), buffer.Buffer() + buffer.Size());
    +
    1655 }
    +
    1656 
    +
    1657 bool VideoSampleEntry::ParseExtraCodecConfigsVector(
    +
    1658  const std::vector<uint8_t>& data) {
    +
    1659  extra_codec_configs.clear();
    +
    1660  size_t pos = 0;
    +
    1661  while (pos < data.size()) {
    +
    1662  bool err = false;
    +
    1663  std::unique_ptr<BoxReader> box_reader(
    +
    1664  BoxReader::ReadBox(data.data() + pos, data.size() - pos, &err));
    +
    1665  RCHECK(!err && box_reader);
    +
    1666 
    +
    1667  CodecConfiguration codec_config;
    +
    1668  codec_config.box_type = box_reader->type();
    +
    1669  RCHECK(codec_config.Parse(box_reader.get()));
    +
    1670  extra_codec_configs.push_back(std::move(codec_config));
    +
    1671 
    +
    1672  pos += box_reader->pos();
    +
    1673  }
    +
    1674  return true;
    +
    1675 }
    +
    1676 
    +
    1677 ElementaryStreamDescriptor::ElementaryStreamDescriptor() = default;
    +
    1678 ElementaryStreamDescriptor::~ElementaryStreamDescriptor() = default;
    +
    1679 
    + +
    1681  return FOURCC_esds;
    +
    1682 }
    +
    1683 
    +
    1684 bool ElementaryStreamDescriptor::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1685  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1686  if (buffer->Reading()) {
    +
    1687  std::vector<uint8_t> data;
    +
    1688  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
    +
    1689  RCHECK(es_descriptor.Parse(data));
    +
    1690  if (es_descriptor.decoder_config_descriptor().IsAAC()) {
    +
    1691  RCHECK(aac_audio_specific_config.Parse(
    +
    1692  es_descriptor.decoder_config_descriptor()
    +
    1693  .decoder_specific_info_descriptor()
    +
    1694  .data()));
    +
    1695  }
    +
    1696  } else {
    +
    1697  DCHECK(buffer->writer());
    +
    1698  es_descriptor.Write(buffer->writer());
    +
    1699  }
    +
    1700  return true;
    +
    1701 }
    +
    1702 
    +
    1703 size_t ElementaryStreamDescriptor::ComputeSizeInternal() {
    +
    1704  // This box is optional. Skip it if not initialized.
    +
    1705  if (es_descriptor.decoder_config_descriptor().object_type() ==
    +
    1706  ObjectType::kForbidden) {
    +
    1707  return 0;
    +
    1708  }
    +
    1709  return HeaderSize() + es_descriptor.ComputeSize();
    +
    1710 }
    +
    1711 
    +
    1712 DTSSpecific::DTSSpecific() = default;
    +
    1713 DTSSpecific::~DTSSpecific() = default;
    +
    1714 ;
    +
    1715 
    +
    1716 FourCC DTSSpecific::BoxType() const {
    +
    1717  return FOURCC_ddts;
    +
    1718 }
    +
    1719 
    +
    1720 bool DTSSpecific::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1721  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    1722  buffer->ReadWriteUInt32(&sampling_frequency) &&
    +
    1723  buffer->ReadWriteUInt32(&max_bitrate) &&
    +
    1724  buffer->ReadWriteUInt32(&avg_bitrate) &&
    +
    1725  buffer->ReadWriteUInt8(&pcm_sample_depth));
    +
    1726 
    +
    1727  if (buffer->Reading()) {
    +
    1728  RCHECK(buffer->ReadWriteVector(&extra_data, buffer->BytesLeft()));
    +
    1729  } else {
    +
    1730  if (extra_data.empty()) {
    +
    1731  extra_data.assign(kDdtsExtraData,
    +
    1732  kDdtsExtraData + sizeof(kDdtsExtraData));
    +
    1733  }
    +
    1734  RCHECK(buffer->ReadWriteVector(&extra_data, extra_data.size()));
    +
    1735  }
    +
    1736  return true;
    +
    1737 }
    +
    1738 
    +
    1739 size_t DTSSpecific::ComputeSizeInternal() {
    +
    1740  // This box is optional. Skip it if not initialized.
    +
    1741  if (sampling_frequency == 0)
    +
    1742  return 0;
    +
    1743  return HeaderSize() + sizeof(sampling_frequency) + sizeof(max_bitrate) +
    +
    1744  sizeof(avg_bitrate) + sizeof(pcm_sample_depth) +
    +
    1745  sizeof(kDdtsExtraData);
    +
    1746 }
    +
    1747 
    +
    1748 AC3Specific::AC3Specific() = default;
    +
    1749 AC3Specific::~AC3Specific() = default;
    +
    1750 
    +
    1751 FourCC AC3Specific::BoxType() const {
    +
    1752  return FOURCC_dac3;
    +
    1753 }
    +
    1754 
    +
    1755 bool AC3Specific::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1756  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    1757  buffer->ReadWriteVector(
    +
    1758  &data, buffer->Reading() ? buffer->BytesLeft() : data.size()));
    +
    1759  return true;
    +
    1760 }
    +
    1761 
    +
    1762 size_t AC3Specific::ComputeSizeInternal() {
    +
    1763  // This box is optional. Skip it if not initialized.
    +
    1764  if (data.empty())
    +
    1765  return 0;
    +
    1766  return HeaderSize() + data.size();
    +
    1767 }
    +
    1768 
    +
    1769 EC3Specific::EC3Specific() = default;
    +
    1770 EC3Specific::~EC3Specific() = default;
    +
    1771 
    +
    1772 FourCC EC3Specific::BoxType() const {
    +
    1773  return FOURCC_dec3;
    +
    1774 }
    +
    1775 
    +
    1776 bool EC3Specific::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1777  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1778  size_t size = buffer->Reading() ? buffer->BytesLeft() : data.size();
    +
    1779  RCHECK(buffer->ReadWriteVector(&data, size));
    +
    1780  return true;
    +
    1781 }
    +
    1782 
    +
    1783 size_t EC3Specific::ComputeSizeInternal() {
    +
    1784  // This box is optional. Skip it if not initialized.
    +
    1785  if (data.empty())
    +
    1786  return 0;
    +
    1787  return HeaderSize() + data.size();
    +
    1788 }
    +
    1789 
    +
    1790 AC4Specific::AC4Specific() = default;
    +
    1791 AC4Specific::~AC4Specific() = default;
    +
    1792 
    +
    1793 FourCC AC4Specific::BoxType() const {
    +
    1794  return FOURCC_dac4;
    +
    1795 }
    +
    1796 
    +
    1797 bool AC4Specific::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1798  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1799  size_t size = buffer->Reading() ? buffer->BytesLeft() : data.size();
    +
    1800  RCHECK(buffer->ReadWriteVector(&data, size));
    +
    1801  return true;
    +
    1802 }
    +
    1803 
    +
    1804 size_t AC4Specific::ComputeSizeInternal() {
    +
    1805  // This box is optional. Skip it if not initialized.
    +
    1806  if (data.empty())
    +
    1807  return 0;
    +
    1808  return HeaderSize() + data.size();
    +
    1809 }
    +
    1810 
    +
    1811 OpusSpecific::OpusSpecific() = default;
    +
    1812 OpusSpecific::~OpusSpecific() = default;
    +
    1813 
    +
    1814 FourCC OpusSpecific::BoxType() const {
    +
    1815  return FOURCC_dOps;
    +
    1816 }
    +
    1817 
    +
    1818 bool OpusSpecific::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1819  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1820  if (buffer->Reading()) {
    +
    1821  std::vector<uint8_t> data;
    +
    1822  const int kMinOpusSpecificBoxDataSize = 11;
    +
    1823  RCHECK(buffer->BytesLeft() >= kMinOpusSpecificBoxDataSize);
    +
    1824  RCHECK(buffer->ReadWriteVector(&data, buffer->BytesLeft()));
    +
    1825  preskip = data[2] + (data[3] << 8);
    +
    1826 
    +
    1827  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
    +
    1828  BufferWriter writer;
    +
    1829  writer.AppendInt(FOURCC_Opus);
    +
    1830  writer.AppendInt(FOURCC_Head);
    +
    1831  // The version must always be 1.
    +
    1832  const uint8_t kOpusIdentificationHeaderVersion = 1;
    +
    1833  data[0] = kOpusIdentificationHeaderVersion;
    +
    1834  writer.AppendVector(data);
    +
    1835  writer.SwapBuffer(&opus_identification_header);
    +
    1836  } else {
    +
    1837  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
    +
    1838  // The first 8 bytes is "magic signature".
    +
    1839  const size_t kOpusMagicSignatureSize = 8u;
    +
    1840  DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
    +
    1841  // https://www.opus-codec.org/docs/opus_in_isobmff.html
    +
    1842  // The version field shall be set to 0.
    +
    1843  const uint8_t kOpusSpecificBoxVersion = 0;
    +
    1844  buffer->writer()->AppendInt(kOpusSpecificBoxVersion);
    +
    1845  buffer->writer()->AppendArray(
    +
    1846  &opus_identification_header[kOpusMagicSignatureSize + 1],
    +
    1847  opus_identification_header.size() - kOpusMagicSignatureSize - 1);
    +
    1848  }
    +
    1849  return true;
    +
    1850 }
    +
    1851 
    +
    1852 size_t OpusSpecific::ComputeSizeInternal() {
    +
    1853  // This box is optional. Skip it if not initialized.
    +
    1854  if (opus_identification_header.empty())
    +
    1855  return 0;
    +
    1856  // https://tools.ietf.org/html/draft-ietf-codec-oggopus-06#section-5
    +
    1857  // The first 8 bytes is "magic signature".
    +
    1858  const size_t kOpusMagicSignatureSize = 8u;
    +
    1859  DCHECK_GT(opus_identification_header.size(), kOpusMagicSignatureSize);
    +
    1860  return HeaderSize() + opus_identification_header.size() -
    +
    1861  kOpusMagicSignatureSize;
    +
    1862 }
    +
    1863 
    +
    1864 FlacSpecific::FlacSpecific() = default;
    +
    1865 FlacSpecific::~FlacSpecific() = default;
    +
    1866 
    +
    1867 FourCC FlacSpecific::BoxType() const {
    +
    1868  return FOURCC_dfLa;
    +
    1869 }
    +
    1870 
    +
    1871 bool FlacSpecific::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1872  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1873  size_t size = buffer->Reading() ? buffer->BytesLeft() : data.size();
    +
    1874  RCHECK(buffer->ReadWriteVector(&data, size));
    +
    1875  return true;
    +
    1876 }
    +
    1877 
    +
    1878 size_t FlacSpecific::ComputeSizeInternal() {
    +
    1879  // This box is optional. Skip it if not initialized.
    +
    1880  if (data.empty())
    +
    1881  return 0;
    +
    1882  return HeaderSize() + data.size();
    +
    1883 }
    +
    1884 
    +
    1885 AudioSampleEntry::AudioSampleEntry() = default;
    +
    1886 AudioSampleEntry::~AudioSampleEntry() = default;
    +
    1887 
    + +
    1889  if (format == FOURCC_NULL) {
    +
    1890  LOG(ERROR) << "AudioSampleEntry should be parsed according to the "
    +
    1891  << "handler type recovered in its Media ancestor.";
    +
    1892  }
    +
    1893  return format;
    +
    1894 }
    +
    1895 
    +
    1896 bool AudioSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1897  if (buffer->Reading()) {
    +
    1898  DCHECK(buffer->reader());
    +
    1899  format = buffer->reader()->type();
    +
    1900  } else {
    +
    1901  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1902  }
    +
    1903 
    +
    1904  // Convert from integer to 16.16 fixed point for writing.
    +
    1905  samplerate <<= 16;
    +
    1906  RCHECK(buffer->IgnoreBytes(6) && // reserved.
    +
    1907  buffer->ReadWriteUInt16(&data_reference_index) &&
    +
    1908  buffer->IgnoreBytes(8) && // reserved.
    +
    1909  buffer->ReadWriteUInt16(&channelcount) &&
    +
    1910  buffer->ReadWriteUInt16(&samplesize) &&
    +
    1911  buffer->IgnoreBytes(4) && // predefined.
    +
    1912  buffer->ReadWriteUInt32(&samplerate));
    +
    1913  // Convert from 16.16 fixed point to integer.
    +
    1914  samplerate >>= 16;
    +
    1915 
    +
    1916  RCHECK(buffer->PrepareChildren());
    +
    1917 
    +
    1918  RCHECK(buffer->TryReadWriteChild(&esds));
    +
    1919  RCHECK(buffer->TryReadWriteChild(&ddts));
    +
    1920  RCHECK(buffer->TryReadWriteChild(&dac3));
    +
    1921  RCHECK(buffer->TryReadWriteChild(&dec3));
    +
    1922  RCHECK(buffer->TryReadWriteChild(&dac4));
    +
    1923  RCHECK(buffer->TryReadWriteChild(&dops));
    +
    1924  RCHECK(buffer->TryReadWriteChild(&dfla));
    +
    1925 
    +
    1926  // Somehow Edge does not support having sinf box before codec_configuration,
    +
    1927  // box, so just do it in the end of AudioSampleEntry. See
    +
    1928  // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12658991/
    +
    1929  if (format == FOURCC_enca) {
    +
    1930  if (buffer->Reading()) {
    +
    1931  // Continue scanning until a supported protection scheme is found, or
    +
    1932  // until we run out of protection schemes.
    +
    1933  while (!IsProtectionSchemeSupported(sinf.type.type))
    +
    1934  RCHECK(buffer->ReadWriteChild(&sinf));
    +
    1935  } else {
    +
    1936  DCHECK(IsProtectionSchemeSupported(sinf.type.type));
    +
    1937  RCHECK(buffer->ReadWriteChild(&sinf));
    +
    1938  }
    +
    1939  }
    +
    1940  return true;
    +
    1941 }
    +
    1942 
    +
    1943 size_t AudioSampleEntry::ComputeSizeInternal() {
    +
    1944  if (GetActualFormat() == FOURCC_NULL)
    +
    1945  return 0;
    +
    1946  return HeaderSize() + sizeof(data_reference_index) + sizeof(channelcount) +
    +
    1947  sizeof(samplesize) + sizeof(samplerate) + sinf.ComputeSize() +
    +
    1948  esds.ComputeSize() + ddts.ComputeSize() + dac3.ComputeSize() +
    +
    1949  dec3.ComputeSize() + dops.ComputeSize() + dfla.ComputeSize() +
    +
    1950  dac4.ComputeSize() +
    +
    1951  // Reserved and predefined bytes.
    +
    1952  6 + 8 + // 6 + 8 bytes reserved.
    +
    1953  4; // 4 bytes predefined.
    +
    1954 }
    +
    1955 
    +
    1956 WebVTTConfigurationBox::WebVTTConfigurationBox() = default;
    +
    1957 WebVTTConfigurationBox::~WebVTTConfigurationBox() = default;
    +
    1958 
    + +
    1960  return FOURCC_vttC;
    +
    1961 }
    +
    1962 
    +
    1963 bool WebVTTConfigurationBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1964  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1965  return buffer->ReadWriteString(
    +
    1966  &config, buffer->Reading() ? buffer->BytesLeft() : config.size());
    +
    1967 }
    +
    1968 
    +
    1969 size_t WebVTTConfigurationBox::ComputeSizeInternal() {
    +
    1970  return HeaderSize() + config.size();
    +
    1971 }
    +
    1972 
    +
    1973 WebVTTSourceLabelBox::WebVTTSourceLabelBox() = default;
    +
    1974 WebVTTSourceLabelBox::~WebVTTSourceLabelBox() = default;
    +
    1975 
    + +
    1977  return FOURCC_vlab;
    +
    1978 }
    +
    1979 
    +
    1980 bool WebVTTSourceLabelBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    1981  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    1982  return buffer->ReadWriteString(&source_label, buffer->Reading()
    +
    1983  ? buffer->BytesLeft()
    +
    1984  : source_label.size());
    +
    1985 }
    +
    1986 
    +
    1987 size_t WebVTTSourceLabelBox::ComputeSizeInternal() {
    +
    1988  if (source_label.empty())
    +
    1989  return 0;
    +
    1990  return HeaderSize() + source_label.size();
    +
    1991 }
    +
    1992 
    +
    1993 TextSampleEntry::TextSampleEntry() = default;
    +
    1994 TextSampleEntry::~TextSampleEntry() = default;
    +
    1995 
    + +
    1997  if (format == FOURCC_NULL) {
    +
    1998  LOG(ERROR) << "TextSampleEntry should be parsed according to the "
    +
    1999  << "handler type recovered in its Media ancestor.";
    +
    2000  }
    +
    2001  return format;
    +
    2002 }
    +
    2003 
    +
    2004 bool TextSampleEntry::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2005  if (buffer->Reading()) {
    +
    2006  DCHECK(buffer->reader());
    +
    2007  format = buffer->reader()->type();
    +
    2008  } else {
    +
    2009  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2010  }
    +
    2011  RCHECK(buffer->IgnoreBytes(6) && // reserved for SampleEntry.
    +
    2012  buffer->ReadWriteUInt16(&data_reference_index));
    +
    2013 
    +
    2014  if (format == FOURCC_wvtt) {
    +
    2015  // TODO(rkuroiwa): Handle the optional MPEG4BitRateBox.
    +
    2016  RCHECK(buffer->PrepareChildren() && buffer->ReadWriteChild(&config) &&
    +
    2017  buffer->ReadWriteChild(&label));
    +
    2018  } else if (format == FOURCC_stpp) {
    +
    2019  // These are marked as "optional"; but they should still have the
    +
    2020  // null-terminator, so this should still work.
    +
    2021  RCHECK(buffer->ReadWriteCString(&namespace_) &&
    +
    2022  buffer->ReadWriteCString(&schema_location));
    +
    2023  }
    +
    2024  return true;
    +
    2025 }
    +
    2026 
    +
    2027 size_t TextSampleEntry::ComputeSizeInternal() {
    +
    2028  // 6 for the (anonymous) reserved bytes for SampleEntry class.
    +
    2029  size_t ret = HeaderSize() + 6 + sizeof(data_reference_index);
    +
    2030  if (format == FOURCC_wvtt) {
    +
    2031  ret += config.ComputeSize() + label.ComputeSize();
    +
    2032  } else if (format == FOURCC_stpp) {
    +
    2033  // +2 for the two null terminators for these strings.
    +
    2034  ret += namespace_.size() + schema_location.size() + 2;
    +
    2035  }
    +
    2036  return ret;
    +
    2037 }
    +
    2038 
    +
    2039 MediaHeader::MediaHeader() = default;
    +
    2040 MediaHeader::~MediaHeader() = default;
    +
    2041 
    +
    2042 FourCC MediaHeader::BoxType() const {
    +
    2043  return FOURCC_mdhd;
    +
    2044 }
    +
    2045 
    +
    2046 bool MediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2047  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2048 
    +
    2049  uint8_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    2050  RCHECK(buffer->ReadWriteUInt64NBytes(&creation_time, num_bytes) &&
    +
    2051  buffer->ReadWriteUInt64NBytes(&modification_time, num_bytes) &&
    +
    2052  buffer->ReadWriteUInt32(&timescale) &&
    +
    2053  buffer->ReadWriteUInt64NBytes(&duration, num_bytes) &&
    +
    2054  language.ReadWrite(buffer) &&
    +
    2055  // predefined.
    +
    2056  buffer->IgnoreBytes(2));
    +
    2057  return true;
    +
    2058 }
    +
    2059 
    +
    2060 size_t MediaHeader::ComputeSizeInternal() {
    +
    2061  version = IsFitIn32Bits(creation_time, modification_time, duration) ? 0 : 1;
    +
    2062  return HeaderSize() + sizeof(timescale) +
    +
    2063  sizeof(uint32_t) * (1 + version) * 3 + language.ComputeSize() +
    +
    2064  2; // 2 bytes predefined.
    +
    2065 }
    +
    2066 
    +
    2067 VideoMediaHeader::VideoMediaHeader() {
    +
    2068  const uint32_t kVideoMediaHeaderFlags = 1;
    +
    2069  flags = kVideoMediaHeaderFlags;
    +
    2070 }
    +
    2071 
    +
    2072 VideoMediaHeader::~VideoMediaHeader() = default;
    +
    2073 
    + +
    2075  return FOURCC_vmhd;
    +
    2076 }
    +
    2077 bool VideoMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2078  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    2079  buffer->ReadWriteUInt16(&graphicsmode) &&
    +
    2080  buffer->ReadWriteUInt16(&opcolor_red) &&
    +
    2081  buffer->ReadWriteUInt16(&opcolor_green) &&
    +
    2082  buffer->ReadWriteUInt16(&opcolor_blue));
    +
    2083  return true;
    +
    2084 }
    +
    2085 
    +
    2086 size_t VideoMediaHeader::ComputeSizeInternal() {
    +
    2087  return HeaderSize() + sizeof(graphicsmode) + sizeof(opcolor_red) +
    +
    2088  sizeof(opcolor_green) + sizeof(opcolor_blue);
    +
    2089 }
    +
    2090 
    +
    2091 SoundMediaHeader::SoundMediaHeader() = default;
    +
    2092 SoundMediaHeader::~SoundMediaHeader() = default;
    +
    2093 
    + +
    2095  return FOURCC_smhd;
    +
    2096 }
    +
    2097 
    +
    2098 bool SoundMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2099  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt16(&balance) &&
    +
    2100  buffer->IgnoreBytes(2)); // reserved.
    +
    2101  return true;
    +
    2102 }
    +
    2103 
    +
    2104 size_t SoundMediaHeader::ComputeSizeInternal() {
    +
    2105  return HeaderSize() + sizeof(balance) + sizeof(uint16_t);
    +
    2106 }
    +
    2107 
    +
    2108 NullMediaHeader::NullMediaHeader() = default;
    +
    2109 NullMediaHeader::~NullMediaHeader() = default;
    +
    2110 
    + +
    2112  return FOURCC_nmhd;
    +
    2113 }
    +
    2114 
    +
    2115 bool NullMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2116  return ReadWriteHeaderInternal(buffer);
    +
    2117 }
    +
    2118 
    +
    2119 size_t NullMediaHeader::ComputeSizeInternal() {
    +
    2120  return HeaderSize();
    +
    2121 }
    +
    2122 
    +
    2123 SubtitleMediaHeader::SubtitleMediaHeader() = default;
    +
    2124 SubtitleMediaHeader::~SubtitleMediaHeader() = default;
    +
    2125 
    + +
    2127  return FOURCC_sthd;
    +
    2128 }
    +
    2129 
    +
    2130 bool SubtitleMediaHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2131  return ReadWriteHeaderInternal(buffer);
    +
    2132 }
    +
    2133 
    +
    2134 size_t SubtitleMediaHeader::ComputeSizeInternal() {
    +
    2135  return HeaderSize();
    +
    2136 }
    +
    2137 
    +
    2138 DataEntryUrl::DataEntryUrl() {
    +
    2139  const uint32_t kDataEntryUrlFlags = 1;
    +
    2140  flags = kDataEntryUrlFlags;
    +
    2141 }
    +
    2142 
    +
    2143 DataEntryUrl::~DataEntryUrl() = default;
    +
    2144 
    +
    2145 FourCC DataEntryUrl::BoxType() const {
    +
    2146  return FOURCC_url;
    +
    2147 }
    +
    2148 bool DataEntryUrl::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2149  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2150  if (buffer->Reading()) {
    +
    2151  RCHECK(buffer->ReadWriteVector(&location, buffer->BytesLeft()));
    +
    2152  } else {
    +
    2153  RCHECK(buffer->ReadWriteVector(&location, location.size()));
    +
    2154  }
    +
    2155  return true;
    +
    2156 }
    +
    2157 
    +
    2158 size_t DataEntryUrl::ComputeSizeInternal() {
    +
    2159  return HeaderSize() + location.size();
    +
    2160 }
    +
    2161 
    +
    2162 DataReference::DataReference() = default;
    +
    2163 DataReference::~DataReference() = default;
    +
    2164 
    +
    2165 FourCC DataReference::BoxType() const {
    +
    2166  return FOURCC_dref;
    +
    2167 }
    +
    2168 bool DataReference::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2169  uint32_t entry_count = static_cast<uint32_t>(data_entry.size());
    +
    2170  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    2171  buffer->ReadWriteUInt32(&entry_count));
    +
    2172  data_entry.resize(entry_count);
    +
    2173  RCHECK(buffer->PrepareChildren());
    +
    2174  for (uint32_t i = 0; i < entry_count; ++i)
    +
    2175  RCHECK(buffer->ReadWriteChild(&data_entry[i]));
    +
    2176  return true;
    +
    2177 }
    +
    2178 
    +
    2179 size_t DataReference::ComputeSizeInternal() {
    +
    2180  uint32_t count = static_cast<uint32_t>(data_entry.size());
    +
    2181  size_t box_size = HeaderSize() + sizeof(count);
    +
    2182  for (uint32_t i = 0; i < count; ++i)
    +
    2183  box_size += data_entry[i].ComputeSize();
    +
    2184  return box_size;
    +
    2185 }
    +
    2186 
    +
    2187 DataInformation::DataInformation() = default;
    +
    2188 DataInformation::~DataInformation() = default;
    +
    2189 
    + +
    2191  return FOURCC_dinf;
    +
    2192 }
    +
    2193 
    +
    2194 bool DataInformation::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2195  return ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2196  buffer->ReadWriteChild(&dref);
    +
    2197 }
    +
    2198 
    +
    2199 size_t DataInformation::ComputeSizeInternal() {
    +
    2200  return HeaderSize() + dref.ComputeSize();
    +
    2201 }
    +
    2202 
    +
    2203 MediaInformation::MediaInformation() = default;
    +
    2204 MediaInformation::~MediaInformation() = default;
    +
    2205 
    + +
    2207  return FOURCC_minf;
    +
    2208 }
    +
    2209 
    +
    2210 bool MediaInformation::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2211  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2212  buffer->ReadWriteChild(&dinf) &&
    +
    2213  buffer->ReadWriteChild(&sample_table));
    +
    2214  switch (sample_table.description.type) {
    +
    2215  case kVideo:
    +
    2216  RCHECK(buffer->ReadWriteChild(&vmhd));
    +
    2217  break;
    +
    2218  case kAudio:
    +
    2219  RCHECK(buffer->ReadWriteChild(&smhd));
    +
    2220  break;
    +
    2221  case kText:
    +
    2222  RCHECK(buffer->TryReadWriteChild(&nmhd));
    +
    2223  break;
    +
    2224  case kSubtitle:
    +
    2225  RCHECK(buffer->TryReadWriteChild(&sthd));
    +
    2226  break;
    +
    2227  default:
    +
    2228  NOTIMPLEMENTED();
    +
    2229  }
    +
    2230  // Hint is not supported for now.
    +
    2231  return true;
    +
    2232 }
    +
    2233 
    +
    2234 size_t MediaInformation::ComputeSizeInternal() {
    +
    2235  size_t box_size =
    +
    2236  HeaderSize() + dinf.ComputeSize() + sample_table.ComputeSize();
    +
    2237  switch (sample_table.description.type) {
    +
    2238  case kVideo:
    +
    2239  box_size += vmhd.ComputeSize();
    +
    2240  break;
    +
    2241  case kAudio:
    +
    2242  box_size += smhd.ComputeSize();
    +
    2243  break;
    +
    2244  case kText:
    +
    2245  box_size += nmhd.ComputeSize();
    +
    2246  break;
    +
    2247  case kSubtitle:
    +
    2248  box_size += sthd.ComputeSize();
    +
    2249  break;
    +
    2250  default:
    +
    2251  NOTIMPLEMENTED();
    +
    2252  }
    +
    2253  return box_size;
    +
    2254 }
    +
    2255 
    +
    2256 Media::Media() = default;
    +
    2257 Media::~Media() = default;
    +
    2258 
    +
    2259 FourCC Media::BoxType() const {
    +
    2260  return FOURCC_mdia;
    +
    2261 }
    +
    2262 
    +
    2263 bool Media::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2264  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2265  buffer->ReadWriteChild(&header));
    +
    2266  if (buffer->Reading()) {
    +
    2267  RCHECK(buffer->ReadWriteChild(&handler));
    +
    2268  // Maddeningly, the HandlerReference box specifies how to parse the
    +
    2269  // SampleDescription box, making the latter the only box (of those that we
    +
    2270  // support) which cannot be parsed correctly on its own (or even with
    +
    2271  // information from its strict ancestor tree). We thus copy the handler type
    +
    2272  // to the sample description box *before* parsing it to provide this
    +
    2273  // information while parsing.
    +
    2274  information.sample_table.description.type =
    +
    2275  FourCCToTrackType(handler.handler_type);
    +
    2276  } else {
    +
    2277  handler.handler_type =
    +
    2278  TrackTypeToFourCC(information.sample_table.description.type);
    +
    2279  RCHECK(handler.handler_type != FOURCC_NULL);
    +
    2280  RCHECK(buffer->ReadWriteChild(&handler));
    +
    2281  }
    +
    2282  RCHECK(buffer->ReadWriteChild(&information));
    +
    2283  return true;
    +
    2284 }
    +
    2285 
    +
    2286 size_t Media::ComputeSizeInternal() {
    +
    2287  handler.handler_type =
    +
    2288  TrackTypeToFourCC(information.sample_table.description.type);
    +
    2289  return HeaderSize() + header.ComputeSize() + handler.ComputeSize() +
    +
    2290  information.ComputeSize();
    +
    2291 }
    +
    2292 
    +
    2293 Track::Track() = default;
    +
    2294 Track::~Track() = default;
    +
    2295 
    +
    2296 FourCC Track::BoxType() const {
    +
    2297  return FOURCC_trak;
    +
    2298 }
    +
    2299 
    +
    2300 bool Track::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2301  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2302  buffer->ReadWriteChild(&header) && buffer->ReadWriteChild(&media) &&
    +
    2303  buffer->TryReadWriteChild(&edit) &&
    +
    2304  buffer->TryReadWriteChild(&sample_encryption));
    +
    2305  return true;
    +
    2306 }
    +
    2307 
    +
    2308 size_t Track::ComputeSizeInternal() {
    +
    2309  return HeaderSize() + header.ComputeSize() + media.ComputeSize() +
    +
    2310  edit.ComputeSize();
    +
    2311 }
    +
    2312 
    +
    2313 MovieExtendsHeader::MovieExtendsHeader() = default;
    +
    2314 MovieExtendsHeader::~MovieExtendsHeader() = default;
    +
    2315 
    + +
    2317  return FOURCC_mehd;
    +
    2318 }
    +
    2319 
    +
    2320 bool MovieExtendsHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2321  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2322  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    2323  RCHECK(buffer->ReadWriteUInt64NBytes(&fragment_duration, num_bytes));
    +
    2324  return true;
    +
    2325 }
    +
    2326 
    +
    2327 size_t MovieExtendsHeader::ComputeSizeInternal() {
    +
    2328  // This box is optional. Skip it if it is not used.
    +
    2329  if (fragment_duration == 0)
    +
    2330  return 0;
    +
    2331  version = IsFitIn32Bits(fragment_duration) ? 0 : 1;
    +
    2332  return HeaderSize() + sizeof(uint32_t) * (1 + version);
    +
    2333 }
    +
    2334 
    +
    2335 TrackExtends::TrackExtends() = default;
    +
    2336 TrackExtends::~TrackExtends() = default;
    +
    2337 
    +
    2338 FourCC TrackExtends::BoxType() const {
    +
    2339  return FOURCC_trex;
    +
    2340 }
    +
    2341 
    +
    2342 bool TrackExtends::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2343  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    2344  buffer->ReadWriteUInt32(&track_id) &&
    +
    2345  buffer->ReadWriteUInt32(&default_sample_description_index) &&
    +
    2346  buffer->ReadWriteUInt32(&default_sample_duration) &&
    +
    2347  buffer->ReadWriteUInt32(&default_sample_size) &&
    +
    2348  buffer->ReadWriteUInt32(&default_sample_flags));
    +
    2349  return true;
    +
    2350 }
    +
    2351 
    +
    2352 size_t TrackExtends::ComputeSizeInternal() {
    +
    2353  return HeaderSize() + sizeof(track_id) +
    +
    2354  sizeof(default_sample_description_index) +
    +
    2355  sizeof(default_sample_duration) + sizeof(default_sample_size) +
    +
    2356  sizeof(default_sample_flags);
    +
    2357 }
    +
    2358 
    +
    2359 MovieExtends::MovieExtends() = default;
    +
    2360 MovieExtends::~MovieExtends() = default;
    +
    2361 
    +
    2362 FourCC MovieExtends::BoxType() const {
    +
    2363  return FOURCC_mvex;
    +
    2364 }
    +
    2365 
    +
    2366 bool MovieExtends::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2367  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2368  buffer->TryReadWriteChild(&header));
    +
    2369  if (buffer->Reading()) {
    +
    2370  DCHECK(buffer->reader());
    +
    2371  RCHECK(buffer->reader()->ReadChildren(&tracks));
    +
    2372  } else {
    +
    2373  for (uint32_t i = 0; i < tracks.size(); ++i)
    +
    2374  RCHECK(buffer->ReadWriteChild(&tracks[i]));
    +
    2375  }
    +
    2376  return true;
    +
    2377 }
    +
    2378 
    +
    2379 size_t MovieExtends::ComputeSizeInternal() {
    +
    2380  // This box is optional. Skip it if it does not contain any track.
    +
    2381  if (tracks.size() == 0)
    +
    2382  return 0;
    +
    2383  size_t box_size = HeaderSize() + header.ComputeSize();
    +
    2384  for (uint32_t i = 0; i < tracks.size(); ++i)
    +
    2385  box_size += tracks[i].ComputeSize();
    +
    2386  return box_size;
    +
    2387 }
    +
    2388 
    +
    2389 Movie::Movie() = default;
    +
    2390 Movie::~Movie() = default;
    +
    2391 
    +
    2392 FourCC Movie::BoxType() const {
    +
    2393  return FOURCC_moov;
    +
    2394 }
    +
    2395 
    +
    2396 bool Movie::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2397  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2398  buffer->ReadWriteChild(&header));
    +
    2399  if (buffer->Reading()) {
    +
    2400  BoxReader* reader = buffer->reader();
    +
    2401  DCHECK(reader);
    +
    2402  RCHECK(reader->ReadChildren(&tracks) && reader->TryReadChild(&extends) &&
    +
    2403  reader->TryReadChildren(&pssh));
    +
    2404  } else {
    +
    2405  // The 'meta' box is not well formed in the video captured by Android's
    +
    2406  // default camera app: spec indicates that it is a FullBox but it is written
    +
    2407  // as a Box. This results in the box failed to be parsed. See
    +
    2408  // https://github.com/google/shaka-packager/issues/319 for details.
    +
    2409  // We do not care the content of metadata box in the source content, so just
    +
    2410  // skip reading the box.
    +
    2411  RCHECK(buffer->TryReadWriteChild(&metadata));
    +
    2412  if (FLAGS_mvex_before_trak) {
    +
    2413  // |extends| has to be written before |tracks| to workaround Android
    +
    2414  // MediaExtractor bug which requires |mvex| to be placed before |trak|.
    +
    2415  // See https://github.com/google/shaka-packager/issues/711 for details.
    +
    2416  RCHECK(buffer->TryReadWriteChild(&extends));
    +
    2417  }
    +
    2418  for (uint32_t i = 0; i < tracks.size(); ++i)
    +
    2419  RCHECK(buffer->ReadWriteChild(&tracks[i]));
    +
    2420  if (!FLAGS_mvex_before_trak) {
    +
    2421  RCHECK(buffer->TryReadWriteChild(&extends));
    +
    2422  }
    +
    2423  for (uint32_t i = 0; i < pssh.size(); ++i)
    +
    2424  RCHECK(buffer->ReadWriteChild(&pssh[i]));
    +
    2425  }
    +
    2426  return true;
    +
    2427 }
    +
    2428 
    +
    2429 size_t Movie::ComputeSizeInternal() {
    +
    2430  size_t box_size = HeaderSize() + header.ComputeSize() +
    +
    2431  metadata.ComputeSize() + extends.ComputeSize();
    +
    2432  for (uint32_t i = 0; i < tracks.size(); ++i)
    +
    2433  box_size += tracks[i].ComputeSize();
    +
    2434  for (uint32_t i = 0; i < pssh.size(); ++i)
    +
    2435  box_size += pssh[i].ComputeSize();
    +
    2436  return box_size;
    +
    2437 }
    +
    2438 
    +
    2439 TrackFragmentDecodeTime::TrackFragmentDecodeTime() = default;
    +
    2440 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() = default;
    +
    2441 
    + +
    2443  return FOURCC_tfdt;
    +
    2444 }
    +
    2445 
    +
    2446 bool TrackFragmentDecodeTime::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2447  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2448  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    2449  RCHECK(buffer->ReadWriteUInt64NBytes(&decode_time, num_bytes));
    +
    2450  return true;
    +
    2451 }
    +
    2452 
    +
    2453 size_t TrackFragmentDecodeTime::ComputeSizeInternal() {
    +
    2454  version = IsFitIn32Bits(decode_time) ? 0 : 1;
    +
    2455  return HeaderSize() + sizeof(uint32_t) * (1 + version);
    +
    2456 }
    +
    2457 
    +
    2458 MovieFragmentHeader::MovieFragmentHeader() = default;
    +
    2459 MovieFragmentHeader::~MovieFragmentHeader() = default;
    +
    2460 
    + +
    2462  return FOURCC_mfhd;
    +
    2463 }
    +
    2464 
    +
    2465 bool MovieFragmentHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2466  return ReadWriteHeaderInternal(buffer) &&
    +
    2467  buffer->ReadWriteUInt32(&sequence_number);
    +
    2468 }
    +
    2469 
    +
    2470 size_t MovieFragmentHeader::ComputeSizeInternal() {
    +
    2471  return HeaderSize() + sizeof(sequence_number);
    +
    2472 }
    +
    2473 
    +
    2474 TrackFragmentHeader::TrackFragmentHeader() = default;
    +
    2475 TrackFragmentHeader::~TrackFragmentHeader() = default;
    +
    2476 
    + +
    2478  return FOURCC_tfhd;
    +
    2479 }
    +
    2480 
    +
    2481 bool TrackFragmentHeader::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2482  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteUInt32(&track_id));
    +
    2483 
    +
    2484  if (flags & kBaseDataOffsetPresentMask) {
    +
    2485  // MSE requires 'default-base-is-moof' to be set and
    +
    2486  // 'base-data-offset-present' not to be set. We omit these checks as some
    +
    2487  // valid files in the wild don't follow these rules, though they use moof as
    +
    2488  // base.
    +
    2489  uint64_t base_data_offset;
    +
    2490  RCHECK(buffer->ReadWriteUInt64(&base_data_offset));
    +
    2491  DLOG(WARNING) << "base-data-offset-present is not expected. Assumes "
    +
    2492  "default-base-is-moof.";
    +
    2493  }
    +
    2494 
    +
    2495  if (flags & kSampleDescriptionIndexPresentMask) {
    +
    2496  RCHECK(buffer->ReadWriteUInt32(&sample_description_index));
    +
    2497  } else if (buffer->Reading()) {
    +
    2498  sample_description_index = 0;
    +
    2499  }
    +
    2500 
    +
    2501  if (flags & kDefaultSampleDurationPresentMask) {
    +
    2502  RCHECK(buffer->ReadWriteUInt32(&default_sample_duration));
    +
    2503  } else if (buffer->Reading()) {
    +
    2504  default_sample_duration = 0;
    +
    2505  }
    +
    2506 
    +
    2507  if (flags & kDefaultSampleSizePresentMask) {
    +
    2508  RCHECK(buffer->ReadWriteUInt32(&default_sample_size));
    +
    2509  } else if (buffer->Reading()) {
    +
    2510  default_sample_size = 0;
    +
    2511  }
    +
    2512 
    +
    2513  if (flags & kDefaultSampleFlagsPresentMask)
    +
    2514  RCHECK(buffer->ReadWriteUInt32(&default_sample_flags));
    +
    2515  return true;
    +
    2516 }
    +
    2517 
    +
    2518 size_t TrackFragmentHeader::ComputeSizeInternal() {
    +
    2519  size_t box_size = HeaderSize() + sizeof(track_id);
    +
    2520  if (flags & kSampleDescriptionIndexPresentMask)
    +
    2521  box_size += sizeof(sample_description_index);
    +
    2522  if (flags & kDefaultSampleDurationPresentMask)
    +
    2523  box_size += sizeof(default_sample_duration);
    +
    2524  if (flags & kDefaultSampleSizePresentMask)
    +
    2525  box_size += sizeof(default_sample_size);
    +
    2526  if (flags & kDefaultSampleFlagsPresentMask)
    +
    2527  box_size += sizeof(default_sample_flags);
    +
    2528  return box_size;
    +
    2529 }
    +
    2530 
    +
    2531 TrackFragmentRun::TrackFragmentRun() = default;
    +
    2532 TrackFragmentRun::~TrackFragmentRun() = default;
    +
    2533 
    + +
    2535  return FOURCC_trun;
    +
    2536 }
    +
    2537 
    +
    2538 bool TrackFragmentRun::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2539  if (!buffer->Reading()) {
    +
    2540  // Determine whether version 0 or version 1 should be used.
    +
    2541  // Use version 0 if possible, use version 1 if there is a negative
    +
    2542  // sample_offset value.
    +
    2543  version = 0;
    +
    2544  if (flags & kSampleCompTimeOffsetsPresentMask) {
    +
    2545  for (uint32_t i = 0; i < sample_count; ++i) {
    +
    2546  if (sample_composition_time_offsets[i] < 0) {
    +
    2547  version = 1;
    +
    2548  break;
    +
    2549  }
    +
    2550  }
    +
    2551  }
    +
    2552  }
    +
    2553 
    +
    2554  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    2555  buffer->ReadWriteUInt32(&sample_count));
    +
    2556 
    +
    2557  bool data_offset_present = (flags & kDataOffsetPresentMask) != 0;
    +
    2558  bool first_sample_flags_present = (flags & kFirstSampleFlagsPresentMask) != 0;
    +
    2559  bool sample_duration_present = (flags & kSampleDurationPresentMask) != 0;
    +
    2560  bool sample_size_present = (flags & kSampleSizePresentMask) != 0;
    +
    2561  bool sample_flags_present = (flags & kSampleFlagsPresentMask) != 0;
    +
    2562  bool sample_composition_time_offsets_present =
    +
    2563  (flags & kSampleCompTimeOffsetsPresentMask) != 0;
    +
    2564 
    +
    2565  if (data_offset_present) {
    +
    2566  RCHECK(buffer->ReadWriteUInt32(&data_offset));
    +
    2567  } else {
    +
    2568  // NOTE: If the data-offset is not present, then the data for this run
    +
    2569  // starts immediately after the data of the previous run, or at the
    +
    2570  // base-data-offset defined by the track fragment header if this is the
    +
    2571  // first run in a track fragment. If the data-offset is present, it is
    +
    2572  // relative to the base-data-offset established in the track fragment
    +
    2573  // header.
    +
    2574  NOTIMPLEMENTED();
    +
    2575  }
    +
    2576 
    +
    2577  uint32_t first_sample_flags(0);
    +
    2578 
    +
    2579  if (buffer->Reading()) {
    +
    2580  if (first_sample_flags_present)
    +
    2581  RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
    +
    2582 
    +
    2583  if (sample_duration_present)
    +
    2584  sample_durations.resize(sample_count);
    +
    2585  if (sample_size_present)
    +
    2586  sample_sizes.resize(sample_count);
    +
    2587  if (sample_flags_present)
    +
    2588  sample_flags.resize(sample_count);
    +
    2589  if (sample_composition_time_offsets_present)
    +
    2590  sample_composition_time_offsets.resize(sample_count);
    +
    2591  } else {
    +
    2592  if (first_sample_flags_present) {
    +
    2593  first_sample_flags = sample_flags[0];
    +
    2594  DCHECK(sample_flags.size() == 1);
    +
    2595  RCHECK(buffer->ReadWriteUInt32(&first_sample_flags));
    +
    2596  }
    +
    2597 
    +
    2598  if (sample_duration_present)
    +
    2599  DCHECK(sample_durations.size() == sample_count);
    +
    2600  if (sample_size_present)
    +
    2601  DCHECK(sample_sizes.size() == sample_count);
    +
    2602  if (sample_flags_present)
    +
    2603  DCHECK(sample_flags.size() == sample_count);
    +
    2604  if (sample_composition_time_offsets_present)
    +
    2605  DCHECK(sample_composition_time_offsets.size() == sample_count);
    +
    2606  }
    +
    2607 
    +
    2608  for (uint32_t i = 0; i < sample_count; ++i) {
    +
    2609  if (sample_duration_present)
    +
    2610  RCHECK(buffer->ReadWriteUInt32(&sample_durations[i]));
    +
    2611  if (sample_size_present)
    +
    2612  RCHECK(buffer->ReadWriteUInt32(&sample_sizes[i]));
    +
    2613  if (sample_flags_present)
    +
    2614  RCHECK(buffer->ReadWriteUInt32(&sample_flags[i]));
    +
    2615 
    +
    2616  if (sample_composition_time_offsets_present) {
    +
    2617  if (version == 0) {
    +
    2618  uint32_t sample_offset = sample_composition_time_offsets[i];
    +
    2619  RCHECK(buffer->ReadWriteUInt32(&sample_offset));
    +
    2620  sample_composition_time_offsets[i] = sample_offset;
    +
    2621  } else {
    +
    2622  int32_t sample_offset = sample_composition_time_offsets[i];
    +
    2623  RCHECK(buffer->ReadWriteInt32(&sample_offset));
    +
    2624  sample_composition_time_offsets[i] = sample_offset;
    +
    2625  }
    +
    2626  }
    +
    2627  }
    +
    2628 
    +
    2629  if (buffer->Reading()) {
    +
    2630  if (first_sample_flags_present) {
    +
    2631  if (sample_flags.size() == 0) {
    +
    2632  sample_flags.push_back(first_sample_flags);
    +
    2633  } else {
    +
    2634  sample_flags[0] = first_sample_flags;
    +
    2635  }
    +
    2636  }
    +
    2637  }
    +
    2638  return true;
    +
    2639 }
    +
    2640 
    +
    2641 size_t TrackFragmentRun::ComputeSizeInternal() {
    +
    2642  size_t box_size = HeaderSize() + sizeof(sample_count);
    +
    2643  if (flags & kDataOffsetPresentMask)
    +
    2644  box_size += sizeof(data_offset);
    +
    2645  if (flags & kFirstSampleFlagsPresentMask)
    +
    2646  box_size += sizeof(uint32_t);
    +
    2647  uint32_t fields = (flags & kSampleDurationPresentMask ? 1 : 0) +
    +
    2648  (flags & kSampleSizePresentMask ? 1 : 0) +
    +
    2649  (flags & kSampleFlagsPresentMask ? 1 : 0) +
    +
    2650  (flags & kSampleCompTimeOffsetsPresentMask ? 1 : 0);
    +
    2651  box_size += fields * sizeof(uint32_t) * sample_count;
    +
    2652  return box_size;
    +
    2653 }
    +
    2654 
    +
    2655 TrackFragment::TrackFragment() = default;
    +
    2656 TrackFragment::~TrackFragment() = default;
    +
    2657 
    +
    2658 FourCC TrackFragment::BoxType() const {
    +
    2659  return FOURCC_traf;
    +
    2660 }
    +
    2661 
    +
    2662 bool TrackFragment::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2663  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2664  buffer->ReadWriteChild(&header));
    +
    2665  if (buffer->Reading()) {
    +
    2666  DCHECK(buffer->reader());
    +
    2667  decode_time_absent = !buffer->reader()->ChildExist(&decode_time);
    +
    2668  if (!decode_time_absent)
    +
    2669  RCHECK(buffer->ReadWriteChild(&decode_time));
    +
    2670  RCHECK(buffer->reader()->TryReadChildren(&runs) &&
    +
    2671  buffer->reader()->TryReadChildren(&sample_group_descriptions) &&
    +
    2672  buffer->reader()->TryReadChildren(&sample_to_groups));
    +
    2673  } else {
    +
    2674  if (!decode_time_absent)
    +
    2675  RCHECK(buffer->ReadWriteChild(&decode_time));
    +
    2676  for (uint32_t i = 0; i < runs.size(); ++i)
    +
    2677  RCHECK(buffer->ReadWriteChild(&runs[i]));
    +
    2678  for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
    +
    2679  RCHECK(buffer->ReadWriteChild(&sample_to_groups[i]));
    +
    2680  for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
    +
    2681  RCHECK(buffer->ReadWriteChild(&sample_group_descriptions[i]));
    +
    2682  }
    +
    2683  return buffer->TryReadWriteChild(&auxiliary_size) &&
    +
    2684  buffer->TryReadWriteChild(&auxiliary_offset) &&
    +
    2685  buffer->TryReadWriteChild(&sample_encryption);
    +
    2686 }
    +
    2687 
    +
    2688 size_t TrackFragment::ComputeSizeInternal() {
    +
    2689  size_t box_size = HeaderSize() + header.ComputeSize() +
    +
    2690  decode_time.ComputeSize() + auxiliary_size.ComputeSize() +
    +
    2691  auxiliary_offset.ComputeSize() +
    +
    2692  sample_encryption.ComputeSize();
    +
    2693  for (uint32_t i = 0; i < runs.size(); ++i)
    +
    2694  box_size += runs[i].ComputeSize();
    +
    2695  for (uint32_t i = 0; i < sample_group_descriptions.size(); ++i)
    +
    2696  box_size += sample_group_descriptions[i].ComputeSize();
    +
    2697  for (uint32_t i = 0; i < sample_to_groups.size(); ++i)
    +
    2698  box_size += sample_to_groups[i].ComputeSize();
    +
    2699  return box_size;
    +
    2700 }
    +
    2701 
    +
    2702 MovieFragment::MovieFragment() = default;
    +
    2703 MovieFragment::~MovieFragment() = default;
    +
    2704 
    +
    2705 FourCC MovieFragment::BoxType() const {
    +
    2706  return FOURCC_moof;
    +
    2707 }
    +
    2708 
    +
    2709 bool MovieFragment::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2710  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2711  buffer->ReadWriteChild(&header));
    +
    2712  if (buffer->Reading()) {
    +
    2713  BoxReader* reader = buffer->reader();
    +
    2714  DCHECK(reader);
    +
    2715  RCHECK(reader->ReadChildren(&tracks) && reader->TryReadChildren(&pssh));
    +
    2716  } else {
    +
    2717  for (uint32_t i = 0; i < tracks.size(); ++i)
    +
    2718  RCHECK(buffer->ReadWriteChild(&tracks[i]));
    +
    2719  for (uint32_t i = 0; i < pssh.size(); ++i)
    +
    2720  RCHECK(buffer->ReadWriteChild(&pssh[i]));
    +
    2721  }
    +
    2722  return true;
    +
    2723 }
    +
    2724 
    +
    2725 size_t MovieFragment::ComputeSizeInternal() {
    +
    2726  size_t box_size = HeaderSize() + header.ComputeSize();
    +
    2727  for (uint32_t i = 0; i < tracks.size(); ++i)
    +
    2728  box_size += tracks[i].ComputeSize();
    +
    2729  for (uint32_t i = 0; i < pssh.size(); ++i)
    +
    2730  box_size += pssh[i].ComputeSize();
    +
    2731  return box_size;
    +
    2732 }
    +
    2733 
    +
    2734 SegmentIndex::SegmentIndex() = default;
    +
    2735 SegmentIndex::~SegmentIndex() = default;
    +
    2736 
    +
    2737 FourCC SegmentIndex::BoxType() const {
    +
    2738  return FOURCC_sidx;
    +
    2739 }
    +
    2740 
    +
    2741 bool SegmentIndex::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2742  RCHECK(ReadWriteHeaderInternal(buffer) &&
    +
    2743  buffer->ReadWriteUInt32(&reference_id) &&
    +
    2744  buffer->ReadWriteUInt32(&timescale));
    +
    2745 
    +
    2746  size_t num_bytes = (version == 1) ? sizeof(uint64_t) : sizeof(uint32_t);
    +
    2747  RCHECK(
    +
    2748  buffer->ReadWriteUInt64NBytes(&earliest_presentation_time, num_bytes) &&
    +
    2749  buffer->ReadWriteUInt64NBytes(&first_offset, num_bytes));
    +
    2750 
    +
    2751  uint16_t reference_count;
    +
    2752  if (references.size() <= std::numeric_limits<uint16_t>::max()) {
    +
    2753  reference_count = static_cast<uint16_t>(references.size());
    +
    2754  } else {
    +
    2755  reference_count = std::numeric_limits<uint16_t>::max();
    +
    2756  LOG(WARNING) << "Seeing " << references.size()
    +
    2757  << " subsegment references, but at most " << reference_count
    +
    2758  << " references can be stored in 'sidx' box."
    +
    2759  << " The extra references are truncated.";
    +
    2760  LOG(WARNING) << "The stream will not play to the end in DASH.";
    +
    2761  LOG(WARNING) << "A possible workaround is to increase segment duration.";
    +
    2762  }
    +
    2763  RCHECK(buffer->IgnoreBytes(2) && // reserved.
    +
    2764  buffer->ReadWriteUInt16(&reference_count));
    +
    2765  if (buffer->Reading())
    +
    2766  references.resize(reference_count);
    +
    2767 
    +
    2768  uint32_t reference_type_size;
    +
    2769  uint32_t sap;
    +
    2770  for (uint32_t i = 0; i < reference_count; ++i) {
    +
    2771  if (!buffer->Reading()) {
    +
    2772  reference_type_size = references[i].referenced_size;
    +
    2773  if (references[i].reference_type)
    +
    2774  reference_type_size |= (1 << 31);
    +
    2775  sap = (references[i].sap_type << 28) | references[i].sap_delta_time;
    +
    2776  if (references[i].starts_with_sap)
    +
    2777  sap |= (1 << 31);
    +
    2778  }
    +
    2779  RCHECK(buffer->ReadWriteUInt32(&reference_type_size) &&
    +
    2780  buffer->ReadWriteUInt32(&references[i].subsegment_duration) &&
    +
    2781  buffer->ReadWriteUInt32(&sap));
    +
    2782  if (buffer->Reading()) {
    +
    2783  references[i].reference_type = (reference_type_size >> 31) ? true : false;
    +
    2784  references[i].referenced_size = reference_type_size & ~(1 << 31);
    +
    2785  references[i].starts_with_sap = (sap >> 31) ? true : false;
    +
    2786  references[i].sap_type =
    +
    2787  static_cast<SegmentReference::SAPType>((sap >> 28) & 0x07);
    +
    2788  references[i].sap_delta_time = sap & ~(0xF << 28);
    +
    2789  }
    +
    2790  }
    +
    2791  return true;
    +
    2792 }
    +
    2793 
    +
    2794 size_t SegmentIndex::ComputeSizeInternal() {
    +
    2795  version = IsFitIn32Bits(earliest_presentation_time, first_offset) ? 0 : 1;
    +
    2796  return HeaderSize() + sizeof(reference_id) + sizeof(timescale) +
    +
    2797  sizeof(uint32_t) * (1 + version) * 2 + 2 * sizeof(uint16_t) +
    +
    2798  3 * sizeof(uint32_t) *
    +
    2799  std::min(
    +
    2800  references.size(),
    +
    2801  static_cast<size_t>(std::numeric_limits<uint16_t>::max()));
    +
    2802 }
    +
    2803 
    +
    2804 MediaData::MediaData() = default;
    +
    2805 MediaData::~MediaData() = default;
    +
    2806 
    +
    2807 FourCC MediaData::BoxType() const {
    +
    2808  return FOURCC_mdat;
    +
    2809 }
    +
    2810 
    +
    2811 bool MediaData::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2812  NOTIMPLEMENTED() << "Actual data is parsed and written separately.";
    +
    2813  return false;
    +
    2814 }
    +
    2815 
    +
    2816 size_t MediaData::ComputeSizeInternal() {
    +
    2817  return HeaderSize() + data_size;
    +
    2818 }
    +
    2819 
    +
    2820 CueSourceIDBox::CueSourceIDBox() = default;
    +
    2821 CueSourceIDBox::~CueSourceIDBox() = default;
    +
    2822 
    +
    2823 FourCC CueSourceIDBox::BoxType() const {
    +
    2824  return FOURCC_vsid;
    +
    2825 }
    +
    2826 
    +
    2827 bool CueSourceIDBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2828  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->ReadWriteInt32(&source_id));
    +
    2829  return true;
    +
    2830 }
    +
    2831 
    +
    2832 size_t CueSourceIDBox::ComputeSizeInternal() {
    +
    2833  if (source_id == kCueSourceIdNotSet)
    +
    2834  return 0;
    +
    2835  return HeaderSize() + sizeof(source_id);
    +
    2836 }
    +
    2837 
    +
    2838 CueTimeBox::CueTimeBox() = default;
    +
    2839 CueTimeBox::~CueTimeBox() = default;
    +
    2840 
    +
    2841 FourCC CueTimeBox::BoxType() const {
    +
    2842  return FOURCC_ctim;
    +
    2843 }
    +
    2844 
    +
    2845 bool CueTimeBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2846  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2847  return buffer->ReadWriteString(
    +
    2848  &cue_current_time,
    +
    2849  buffer->Reading() ? buffer->BytesLeft() : cue_current_time.size());
    +
    2850 }
    +
    2851 
    +
    2852 size_t CueTimeBox::ComputeSizeInternal() {
    +
    2853  if (cue_current_time.empty())
    +
    2854  return 0;
    +
    2855  return HeaderSize() + cue_current_time.size();
    +
    2856 }
    +
    2857 
    +
    2858 CueIDBox::CueIDBox() = default;
    +
    2859 CueIDBox::~CueIDBox() = default;
    +
    2860 
    +
    2861 FourCC CueIDBox::BoxType() const {
    +
    2862  return FOURCC_iden;
    +
    2863 }
    +
    2864 
    +
    2865 bool CueIDBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2866  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2867  return buffer->ReadWriteString(
    +
    2868  &cue_id, buffer->Reading() ? buffer->BytesLeft() : cue_id.size());
    +
    2869 }
    +
    2870 
    +
    2871 size_t CueIDBox::ComputeSizeInternal() {
    +
    2872  if (cue_id.empty())
    +
    2873  return 0;
    +
    2874  return HeaderSize() + cue_id.size();
    +
    2875 }
    +
    2876 
    +
    2877 CueSettingsBox::CueSettingsBox() = default;
    +
    2878 CueSettingsBox::~CueSettingsBox() = default;
    +
    2879 
    +
    2880 FourCC CueSettingsBox::BoxType() const {
    +
    2881  return FOURCC_sttg;
    +
    2882 }
    +
    2883 
    +
    2884 bool CueSettingsBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2885  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2886  return buffer->ReadWriteString(
    +
    2887  &settings, buffer->Reading() ? buffer->BytesLeft() : settings.size());
    +
    2888 }
    +
    2889 
    +
    2890 size_t CueSettingsBox::ComputeSizeInternal() {
    +
    2891  if (settings.empty())
    +
    2892  return 0;
    +
    2893  return HeaderSize() + settings.size();
    +
    2894 }
    +
    2895 
    +
    2896 CuePayloadBox::CuePayloadBox() = default;
    +
    2897 CuePayloadBox::~CuePayloadBox() = default;
    +
    2898 
    +
    2899 FourCC CuePayloadBox::BoxType() const {
    +
    2900  return FOURCC_payl;
    +
    2901 }
    +
    2902 
    +
    2903 bool CuePayloadBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2904  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2905  return buffer->ReadWriteString(
    +
    2906  &cue_text, buffer->Reading() ? buffer->BytesLeft() : cue_text.size());
    +
    2907 }
    +
    2908 
    +
    2909 size_t CuePayloadBox::ComputeSizeInternal() {
    +
    2910  return HeaderSize() + cue_text.size();
    +
    2911 }
    +
    2912 
    +
    2913 VTTEmptyCueBox::VTTEmptyCueBox() = default;
    +
    2914 VTTEmptyCueBox::~VTTEmptyCueBox() = default;
    +
    2915 
    +
    2916 FourCC VTTEmptyCueBox::BoxType() const {
    +
    2917  return FOURCC_vtte;
    +
    2918 }
    +
    2919 
    +
    2920 bool VTTEmptyCueBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2921  return ReadWriteHeaderInternal(buffer);
    +
    2922 }
    +
    2923 
    +
    2924 size_t VTTEmptyCueBox::ComputeSizeInternal() {
    +
    2925  return HeaderSize();
    +
    2926 }
    +
    2927 
    +
    2928 VTTAdditionalTextBox::VTTAdditionalTextBox() = default;
    +
    2929 VTTAdditionalTextBox::~VTTAdditionalTextBox() = default;
    +
    2930 
    + +
    2932  return FOURCC_vtta;
    +
    2933 }
    +
    2934 
    +
    2935 bool VTTAdditionalTextBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2936  RCHECK(ReadWriteHeaderInternal(buffer));
    +
    2937  return buffer->ReadWriteString(
    +
    2938  &cue_additional_text,
    +
    2939  buffer->Reading() ? buffer->BytesLeft() : cue_additional_text.size());
    +
    2940 }
    +
    2941 
    +
    2942 size_t VTTAdditionalTextBox::ComputeSizeInternal() {
    +
    2943  return HeaderSize() + cue_additional_text.size();
    +
    2944 }
    +
    2945 
    +
    2946 VTTCueBox::VTTCueBox() = default;
    +
    2947 VTTCueBox::~VTTCueBox() = default;
    +
    2948 
    +
    2949 FourCC VTTCueBox::BoxType() const {
    +
    2950  return FOURCC_vttc;
    +
    2951 }
    +
    2952 
    +
    2953 bool VTTCueBox::ReadWriteInternal(BoxBuffer* buffer) {
    +
    2954  RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() &&
    +
    2955  buffer->TryReadWriteChild(&cue_source_id) &&
    +
    2956  buffer->TryReadWriteChild(&cue_id) &&
    +
    2957  buffer->TryReadWriteChild(&cue_time) &&
    +
    2958  buffer->TryReadWriteChild(&cue_settings) &&
    +
    2959  buffer->ReadWriteChild(&cue_payload));
    +
    2960  return true;
    +
    2961 }
    +
    2962 
    +
    2963 size_t VTTCueBox::ComputeSizeInternal() {
    +
    2964  return HeaderSize() + cue_source_id.ComputeSize() + cue_id.ComputeSize() +
    +
    2965  cue_time.ComputeSize() + cue_settings.ComputeSize() +
    +
    2966  cue_payload.ComputeSize();
    +
    2967 }
    +
    2968 
    +
    2969 } // namespace mp4
    +
    2970 } // namespace media
    +
    2971 } // namespace shaka
    +
    virtual bool Parse(const std::vector< uint8_t > &data)
    + +
    bool Parse(const std::vector< uint8_t > &data)
    +
    void Write(BufferWriter *writer)
    + + + + + +
    BufferWriter * writer()
    Definition: box_buffer.h:210
    +
    bool IgnoreBytes(size_t num_bytes)
    Definition: box_buffer.h:199
    + +
    bool ReadWriteUInt64NBytes(uint64_t *v, size_t num_bytes)
    Definition: box_buffer.h:117
    + +
    bool TryReadWriteChild(Box *box)
    Definition: box_buffer.h:187
    +
    size_t BytesLeft() const
    Definition: box_buffer.h:62
    + +
    bool ReadWriteString(std::string *str, size_t size)
    Definition: box_buffer.h:139
    +
    bool ReadWriteChild(Box *box)
    Definition: box_buffer.h:176
    +
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    +
    bool TryReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:106
    +
    bool TryReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
    Definition: box_reader.h:134
    +
    bool ReadChild(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:90
    +
    bool ChildExist(Box *child) WARN_UNUSED_RESULT
    Definition: box_reader.cc:102
    +
    static BoxReader * ReadBox(const uint8_t *buf, const size_t buf_size, bool *err)
    Definition: box_reader.cc:36
    +
    bool ReadChildren(std::vector< T > *children) WARN_UNUSED_RESULT
    Definition: box_reader.h:128
    +
    All the methods that are virtual are virtual for mocking.
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + +
    virtual uint32_t HeaderSize() const
    Definition: box.cc:55
    +
    void Write(BufferWriter *writer)
    Definition: box.cc:25
    +
    virtual bool ReadWriteHeaderInternal(BoxBuffer *buffer)
    Definition: box.cc:61
    +
    uint32_t ComputeSize()
    Definition: box.cc:50
    +
    uint32_t box_size()
    Definition: box.h:55
    + + +
    FourCC BoxType() const override
    + + + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + +
    FourCC BoxType() const override
    + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    uint32_t HeaderSize() const final
    Definition: box.cc:75
    +
    bool ReadWriteHeaderInternal(BoxBuffer *buffer) final
    Definition: box.cc:80
    + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + +
    FourCC BoxType() const override
    + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + + + + + + +
    bool ParseFromBuffer(uint8_t iv_size, bool has_subsamples, BufferReader *reader)
    +
    bool ReadWrite(uint8_t iv_size, bool has_subsamples, BoxBuffer *buffer)
    + + +
    bool ParseFromSampleEncryptionData(uint8_t iv_size, std::vector< SampleEncryptionEntry > *sample_encryption_entries) const
    +
    std::vector< uint8_t > sample_encryption_data
    + + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + + +
    FourCC BoxType() const override
    + + +
    FourCC BoxType() const override
    + + + +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    +
    FourCC BoxType() const override
    + +
    FourCC BoxType() const override
    + + + + +
    diff --git a/docs/dd/df2/webm_2multi__segment__segmenter_8h_source.html b/docs/dd/df2/webm_2multi__segment__segmenter_8h_source.html index 638b295ca8..2a380f30b4 100644 --- a/docs/dd/df2/webm_2multi__segment__segmenter_8h_source.html +++ b/docs/dd/df2/webm_2multi__segment__segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/multi_segment_segmenter.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    multi_segment_segmenter.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_MULTI_SEGMENT_SEGMENTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_MULTI_SEGMENT_SEGMENTER_H_
    9 
    10 #include <memory>
    11 #include "packager/media/formats/webm/mkv_writer.h"
    12 #include "packager/media/formats/webm/segmenter.h"
    13 #include "packager/status.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    18 struct MuxerOptions;
    19 
    20 namespace webm {
    21 
    25  public:
    26  explicit MultiSegmentSegmenter(const MuxerOptions& options);
    27  ~MultiSegmentSegmenter() override;
    28 
    31  Status FinalizeSegment(uint64_t start_timestamp,
    32  uint64_t duration_timestamp,
    33  bool is_subsegment) override;
    34  bool GetInitRangeStartAndEnd(uint64_t* start, uint64_t* end) override;
    35  bool GetIndexRangeStartAndEnd(uint64_t* start, uint64_t* end) override;
    36  std::vector<Range> GetSegmentRanges() override;
    38 
    39  protected:
    40  // Segmenter implementation overrides.
    41  Status DoInitialize() override;
    42  Status DoFinalize() override;
    43 
    44  private:
    45  // Segmenter implementation overrides.
    46  Status NewSegment(uint64_t start_timestamp, bool is_subsegment) override;
    47 
    48  std::unique_ptr<MkvWriter> writer_;
    49  uint32_t num_segment_;
    50 
    51  DISALLOW_COPY_AND_ASSIGN(MultiSegmentSegmenter);
    52 };
    53 
    54 } // namespace webm
    55 } // namespace media
    56 } // namespace shaka
    57 
    58 #endif // PACKAGER_MEDIA_FORMATS_WEBM_MULTI_SEGMENT_SEGMENTER_H_
    bool GetIndexRangeStartAndEnd(uint64_t *start, uint64_t *end) override
    -
    bool GetInitRangeStartAndEnd(uint64_t *start, uint64_t *end) override
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration_timestamp, bool is_subsegment) override
    Finalize the (sub)segment.
    - - +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_MULTI_SEGMENT_SEGMENTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_MULTI_SEGMENT_SEGMENTER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 
    +
    12 #include "packager/media/formats/webm/mkv_writer.h"
    +
    13 #include "packager/media/formats/webm/segmenter.h"
    +
    14 #include "packager/status.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 struct MuxerOptions;
    +
    20 
    +
    21 namespace webm {
    +
    22 
    + +
    26  public:
    +
    27  explicit MultiSegmentSegmenter(const MuxerOptions& options);
    +
    28  ~MultiSegmentSegmenter() override;
    +
    29 
    +
    32  Status FinalizeSegment(uint64_t start_timestamp,
    +
    33  uint64_t duration_timestamp,
    +
    34  bool is_subsegment) override;
    +
    35  bool GetInitRangeStartAndEnd(uint64_t* start, uint64_t* end) override;
    +
    36  bool GetIndexRangeStartAndEnd(uint64_t* start, uint64_t* end) override;
    +
    37  std::vector<Range> GetSegmentRanges() override;
    +
    39 
    +
    40  protected:
    +
    41  // Segmenter implementation overrides.
    +
    42  Status DoInitialize() override;
    +
    43  Status DoFinalize() override;
    +
    44 
    +
    45  private:
    +
    46  // Segmenter implementation overrides.
    +
    47  Status NewSegment(uint64_t start_timestamp, bool is_subsegment) override;
    +
    48 
    +
    49  std::unique_ptr<MkvWriter> writer_;
    +
    50  uint32_t num_segment_;
    +
    51  std::string temp_file_name_;
    +
    52 
    +
    53  DISALLOW_COPY_AND_ASSIGN(MultiSegmentSegmenter);
    +
    54 };
    +
    55 
    +
    56 } // namespace webm
    +
    57 } // namespace media
    +
    58 } // namespace shaka
    +
    59 
    +
    60 #endif // PACKAGER_MEDIA_FORMATS_WEBM_MULTI_SEGMENT_SEGMENTER_H_
    + + +
    bool GetIndexRangeStartAndEnd(uint64_t *start, uint64_t *end) override
    +
    Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration_timestamp, bool is_subsegment) override
    Finalize the (sub)segment.
    +
    bool GetInitRangeStartAndEnd(uint64_t *start, uint64_t *end) override
    + +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/dd/df3/classshaka_1_1media_1_1PsshGenerator-members.html b/docs/dd/df3/classshaka_1_1media_1_1PsshGenerator-members.html index b6121564f7..e83e07c186 100644 --- a/docs/dd/df3/classshaka_1_1media_1_1PsshGenerator-members.html +++ b/docs/dd/df3/classshaka_1_1media_1_1PsshGenerator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dd/df5/structshaka_1_1media_1_1mp4_1_1TrackFragmentRun.html b/docs/dd/df5/structshaka_1_1media_1_1mp4_1_1TrackFragmentRun.html index efc6d8138e..a029eb3855 100644 --- a/docs/dd/df5/structshaka_1_1media_1_1mp4_1_1TrackFragmentRun.html +++ b/docs/dd/df5/structshaka_1_1media_1_1mp4_1_1TrackFragmentRun.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TrackFragmentRun Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -151,7 +154,7 @@ Additional Inherited Members

    Public Types

    enum  TrackFragmentFlagsMasks {
    -  kDataOffsetPresentMask = 0x000001, -kFirstSampleFlagsPresentMask = 0x000004, -kSampleDurationPresentMask = 0x000100, -kSampleSizePresentMask = 0x000200, -
    -  kSampleFlagsPresentMask = 0x000400, -kSampleCompTimeOffsetsPresentMask = 0x000800 +  kDataOffsetPresentMask = 0x000001 +, kFirstSampleFlagsPresentMask = 0x000004 +, kSampleDurationPresentMask = 0x000100 +, kSampleSizePresentMask = 0x000200 +,
    +  kSampleFlagsPresentMask = 0x000400 +, kSampleCompTimeOffsetsPresentMask = 0x000800
    }
     

    Detailed Description

    -

    Definition at line 719 of file box_definitions.h.

    +

    Definition at line 737 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -179,7 +182,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2445 of file box_definitions.cc.

    +

    Definition at line 2534 of file box_definitions.cc.

    @@ -190,9 +193,7 @@ Additional Inherited Members diff --git a/docs/dd/df6/structshaka_1_1media_1_1mp4_1_1Metadata.html b/docs/dd/df6/structshaka_1_1media_1_1mp4_1_1Metadata.html index 4a13266674..dc4d1880b7 100644 --- a/docs/dd/df6/structshaka_1_1media_1_1mp4_1_1Metadata.html +++ b/docs/dd/df6/structshaka_1_1media_1_1mp4_1_1Metadata.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::Metadata Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -124,7 +127,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 248 of file box_definitions.h.

    +

    Definition at line 249 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -152,7 +155,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1383 of file box_definitions.cc.

    +

    Definition at line 1409 of file box_definitions.cc.

    @@ -163,9 +166,7 @@ Additional Inherited Members diff --git a/docs/dd/df9/classshaka_1_1media_1_1PlayReadyPsshGenerator-members.html b/docs/dd/df9/classshaka_1_1media_1_1PlayReadyPsshGenerator-members.html index 3ac1765968..967b5a0bce 100644 --- a/docs/dd/df9/classshaka_1_1media_1_1PlayReadyPsshGenerator-members.html +++ b/docs/dd/df9/classshaka_1_1media_1_1PlayReadyPsshGenerator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    GeneratePsshFromKeyIdAndKey(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key, ProtectionSystemSpecificInfo *info) constshaka::media::PsshGenerator GeneratePsshFromKeyIds(const std::vector< std::vector< uint8_t >> &key_ids, ProtectionSystemSpecificInfo *info) constshaka::media::PsshGenerator - PlayReadyPsshGenerator(FourCC protection_scheme) (defined in shaka::media::PlayReadyPsshGenerator)shaka::media::PlayReadyPsshGeneratorexplicit + PlayReadyPsshGenerator(const std::string &extra_header_data, FourCC protection_scheme) (defined in shaka::media::PlayReadyPsshGenerator)shaka::media::PlayReadyPsshGeneratorexplicit PsshGenerator(const std::vector< uint8_t > &system_id, uint8_t box_version)shaka::media::PsshGenerator SupportMultipleKeys() overrideshaka::media::PlayReadyPsshGeneratorvirtual ~PlayReadyPsshGenerator() override (defined in shaka::media::PlayReadyPsshGenerator)shaka::media::PlayReadyPsshGenerator @@ -79,9 +82,7 @@ $(function() {
    diff --git a/docs/dd/dfd/structshaka_1_1AdCueGeneratorParams.html b/docs/dd/dfd/structshaka_1_1AdCueGeneratorParams.html index 4b0fbc8485..669f0e8c38 100644 --- a/docs/dd/dfd/structshaka_1_1AdCueGeneratorParams.html +++ b/docs/dd/dfd/structshaka_1_1AdCueGeneratorParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::AdCueGeneratorParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    C
    diff --git a/docs/dd/dff/classshaka_1_1media_1_1SubtitleComposer-members.html b/docs/dd/dff/classshaka_1_1media_1_1SubtitleComposer-members.html new file mode 100644 index 0000000000..857b4e11e7 --- /dev/null +++ b/docs/dd/dff/classshaka_1_1media_1_1SubtitleComposer-members.html @@ -0,0 +1,93 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::SubtitleComposer Member List
    +
    +
    + +

    This is the complete list of members for shaka::media::SubtitleComposer, including all inherited members.

    + + + + + + + + + + + + + +
    ClearObjects() (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    DISALLOW_COPY_AND_ASSIGN(SubtitleComposer) (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    GetColorSpace(uint8_t color_space_id) (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    GetColorSpaceForObject(uint16_t object_id) (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    GetObjectImage(uint16_t object_id) (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    GetSamples(int64_t start, int64_t end, std::vector< std::shared_ptr< TextSample >> *samples) const (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    SetDisplaySize(uint16_t width, uint16_t height) (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    SetObjectInfo(uint16_t object_id, uint8_t region_id, uint16_t x, uint16_t y, int default_color_code) (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    SetRegionInfo(uint8_t region_id, uint8_t color_space_id, uint16_t width, uint16_t height) (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    SetRegionPosition(uint8_t region_id, uint16_t x, uint16_t y) (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    SubtitleComposer() (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    ~SubtitleComposer() (defined in shaka::media::SubtitleComposer)shaka::media::SubtitleComposer
    + + + + diff --git a/docs/de/d00/ac3__header_8h_source.html b/docs/de/d00/ac3__header_8h_source.html index 960d2a40e1..58db198caa 100644 --- a/docs/de/d00/ac3__header_8h_source.html +++ b/docs/de/d00/ac3__header_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ac3_header.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    ac3_header.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_AC3_HEADER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_AC3_HEADER_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <vector>
    13 
    14 #include "packager/media/formats/mp2t/audio_header.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 namespace mp2t {
    19 
    22 class Ac3Header : public AudioHeader {
    23  public:
    24  Ac3Header() = default;
    25  ~Ac3Header() override = default;
    26 
    29  bool IsSyncWord(const uint8_t* buf) const override;
    30  size_t GetMinFrameSize() const override;
    31  size_t GetSamplesPerFrame() const override;
    32  bool Parse(const uint8_t* adts_frame, size_t adts_frame_size) override;
    33  size_t GetHeaderSize() const override;
    34  size_t GetFrameSize() const override;
    35  size_t GetFrameSizeWithoutParsing(const uint8_t* data,
    36  size_t num_bytes) const override;
    37  void GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const override;
    38  uint8_t GetObjectType() const override;
    39  uint32_t GetSamplingFrequency() const override;
    40  uint8_t GetNumChannels() const override;
    42 
    43  private:
    44  Ac3Header(const Ac3Header&) = delete;
    45  Ac3Header& operator=(const Ac3Header&) = delete;
    46 
    47  uint8_t fscod_ = 0; // Sample rate code
    48  uint8_t frmsizecod_ = 0; // Frame size code
    49  uint8_t bsid_ = 0; // Bit stream identification
    50  uint8_t bsmod_ = 0; // Bit stream mode
    51  uint8_t acmod_ = 0; // Audio coding mode
    52  uint8_t lfeon_ = 0; // Low frequency effects channel on
    53 };
    54 
    55 } // namespace mp2t
    56 } // namespace media
    57 } // namespace shaka
    58 
    59 #endif // PACKAGER_MEDIA_FORMATS_MP2T_AC3_HEADER_H_
    size_t GetHeaderSize() const override
    Definition: ac3_header.cc:113
    -
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    Definition: ac3_header.cc:123
    -
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: ac3_header.cc:58
    -
    All the methods that are virtual are virtual for mocking.
    - -
    size_t GetMinFrameSize() const override
    Definition: ac3_header.cc:64
    -
    uint32_t GetSamplingFrequency() const override
    Definition: ac3_header.cc:151
    -
    size_t GetFrameSize() const override
    Definition: ac3_header.cc:119
    -
    uint8_t GetObjectType() const override
    Definition: ac3_header.cc:146
    -
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: ac3_header.cc:77
    - -
    size_t GetSamplesPerFrame() const override
    Definition: ac3_header.cc:70
    -
    uint8_t GetNumChannels() const override
    Definition: ac3_header.cc:156
    -
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: ac3_header.cc:131
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_AC3_HEADER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_AC3_HEADER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/media/formats/mp2t/audio_header.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 namespace mp2t {
    +
    19 
    +
    22 class Ac3Header : public AudioHeader {
    +
    23  public:
    +
    24  Ac3Header() = default;
    +
    25  ~Ac3Header() override = default;
    +
    26 
    +
    29  bool IsSyncWord(const uint8_t* buf) const override;
    +
    30  size_t GetMinFrameSize() const override;
    +
    31  size_t GetSamplesPerFrame() const override;
    +
    32  bool Parse(const uint8_t* adts_frame, size_t adts_frame_size) override;
    +
    33  size_t GetHeaderSize() const override;
    +
    34  size_t GetFrameSize() const override;
    +
    35  size_t GetFrameSizeWithoutParsing(const uint8_t* data,
    +
    36  size_t num_bytes) const override;
    +
    37  void GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const override;
    +
    38  uint8_t GetObjectType() const override;
    +
    39  uint32_t GetSamplingFrequency() const override;
    +
    40  uint8_t GetNumChannels() const override;
    +
    42 
    +
    43  private:
    +
    44  Ac3Header(const Ac3Header&) = delete;
    +
    45  Ac3Header& operator=(const Ac3Header&) = delete;
    +
    46 
    +
    47  uint8_t fscod_ = 0; // Sample rate code
    +
    48  uint8_t frmsizecod_ = 0; // Frame size code
    +
    49  uint8_t bsid_ = 0; // Bit stream identification
    +
    50  uint8_t bsmod_ = 0; // Bit stream mode
    +
    51  uint8_t acmod_ = 0; // Audio coding mode
    +
    52  uint8_t lfeon_ = 0; // Low frequency effects channel on
    +
    53 };
    +
    54 
    +
    55 } // namespace mp2t
    +
    56 } // namespace media
    +
    57 } // namespace shaka
    +
    58 
    +
    59 #endif // PACKAGER_MEDIA_FORMATS_MP2T_AC3_HEADER_H_
    + +
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: ac3_header.cc:77
    +
    size_t GetMinFrameSize() const override
    Definition: ac3_header.cc:64
    +
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: ac3_header.cc:58
    +
    uint8_t GetObjectType() const override
    Definition: ac3_header.cc:146
    +
    size_t GetHeaderSize() const override
    Definition: ac3_header.cc:113
    +
    size_t GetFrameSize() const override
    Definition: ac3_header.cc:119
    +
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    Definition: ac3_header.cc:123
    +
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: ac3_header.cc:131
    +
    uint32_t GetSamplingFrequency() const override
    Definition: ac3_header.cc:151
    +
    uint8_t GetNumChannels() const override
    Definition: ac3_header.cc:156
    +
    size_t GetSamplesPerFrame() const override
    Definition: ac3_header.cc:70
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d03/text__padder_8cc_source.html b/docs/de/d03/text__padder_8cc_source.html index 73feaaec56..5f028892c6 100644 --- a/docs/de/d03/text__padder_8cc_source.html +++ b/docs/de/d03/text__padder_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt/text_padder.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    text_padder.cc
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/webvtt/text_padder.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/status_macros.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace {
    16 const uint64_t kStreamIndex = 0;
    17 } // namespace
    18 
    19 TextPadder::TextPadder(int64_t zero_start_bias_ms)
    20  : zero_start_bias_ms_(zero_start_bias_ms) {}
    21 
    22 Status TextPadder::InitializeInternal() {
    23  return Status::OK;
    24 }
    25 
    26 Status TextPadder::Process(std::unique_ptr<StreamData> data) {
    27  DCHECK_EQ(data->stream_index, kStreamIndex);
    28  const bool is_text_sample =
    29  data->stream_data_type == StreamDataType::kTextSample;
    30  return is_text_sample ? OnTextSample(std::move(data))
    31  : Dispatch(std::move(data));
    32 }
    33 
    34 Status TextPadder::OnTextSample(std::unique_ptr<StreamData> data) {
    35  const TextSample& sample = *data->text_sample;
    36 
    37  // If this is the first sample we have seen, we need to check if we should
    38  // start at time zero.
    39  if (max_end_time_ms_ < 0) {
    40  max_end_time_ms_ =
    41  sample.start_time() > zero_start_bias_ms_ ? sample.start_time() : 0;
    42  }
    43 
    44  // Check if there will be a gap between samples if we just dispatch this
    45  // sample right away. If there will be one, create an empty sample that will
    46  // fill in that gap.
    47  if (sample.start_time() > max_end_time_ms_) {
    48  std::shared_ptr<TextSample> filler = std::make_shared<TextSample>();
    49  filler->SetTime(max_end_time_ms_, sample.start_time());
    50  RETURN_IF_ERROR(
    51  MediaHandler::DispatchTextSample(kStreamIndex, std::move(filler)));
    52  }
    53 
    54  max_end_time_ms_ = std::max(max_end_time_ms_, sample.EndTime());
    55  return Dispatch(std::move(data));
    56 }
    57 } // namespace media
    58 } // namespace shaka
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    -
    All the methods that are virtual are virtual for mocking.
    - -
    Status DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
    Dispatch the text sample to downstream handlers.
    -
    TextPadder(int64_t zero_start_bias_ms)
    Definition: text_padder.cc:19
    - +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/webvtt/text_padder.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/status_macros.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace {
    +
    16 const uint64_t kStreamIndex = 0;
    +
    17 } // namespace
    +
    18 
    +
    19 TextPadder::TextPadder(int64_t zero_start_bias_ms)
    +
    20  : zero_start_bias_ms_(zero_start_bias_ms) {}
    +
    21 
    +
    22 Status TextPadder::InitializeInternal() {
    +
    23  return Status::OK;
    +
    24 }
    +
    25 
    +
    26 Status TextPadder::Process(std::unique_ptr<StreamData> data) {
    +
    27  DCHECK_EQ(data->stream_index, kStreamIndex);
    +
    28  const bool is_text_sample =
    +
    29  data->stream_data_type == StreamDataType::kTextSample;
    +
    30  return is_text_sample ? OnTextSample(std::move(data))
    +
    31  : Dispatch(std::move(data));
    +
    32 }
    +
    33 
    +
    34 Status TextPadder::OnTextSample(std::unique_ptr<StreamData> data) {
    +
    35  const TextSample& sample = *data->text_sample;
    +
    36 
    +
    37  // If this is the first sample we have seen, we need to check if we should
    +
    38  // start at time zero.
    +
    39  if (max_end_time_ms_ < 0) {
    +
    40  max_end_time_ms_ =
    +
    41  sample.start_time() > zero_start_bias_ms_ ? sample.start_time() : 0;
    +
    42  }
    +
    43 
    +
    44  // Check if there will be a gap between samples if we just dispatch this
    +
    45  // sample right away. If there will be one, create an empty sample that will
    +
    46  // fill in that gap.
    +
    47  if (sample.start_time() > max_end_time_ms_) {
    +
    48  const std::string kNoId = "";
    +
    49  auto filler = std::make_shared<TextSample>(kNoId, max_end_time_ms_,
    +
    50  sample.start_time(),
    +
    51  TextSettings{}, TextFragment{});
    +
    52  RETURN_IF_ERROR(
    +
    53  MediaHandler::DispatchTextSample(kStreamIndex, std::move(filler)));
    +
    54  }
    +
    55 
    +
    56  max_end_time_ms_ = std::max(max_end_time_ms_, sample.EndTime());
    +
    57  return Dispatch(std::move(data));
    +
    58 }
    +
    59 } // namespace media
    +
    60 } // namespace shaka
    + +
    Status DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) const
    Dispatch the text sample to downstream handlers.
    +
    Status Dispatch(std::unique_ptr< StreamData > stream_data) const
    +
    TextPadder(int64_t zero_start_bias_ms)
    Definition: text_padder.cc:19
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d0a/classshaka_1_1media_1_1SubsampleGenerator-members.html b/docs/de/d0a/classshaka_1_1media_1_1SubsampleGenerator-members.html index 89a677e330..1637261e29 100644 --- a/docs/de/d0a/classshaka_1_1media_1_1SubsampleGenerator-members.html +++ b/docs/de/d0a/classshaka_1_1media_1_1SubsampleGenerator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/de/d0e/widevine__pssh__generator_8h_source.html b/docs/de/d0e/widevine__pssh__generator_8h_source.html index 72843eddd0..5c58c2c9cf 100644 --- a/docs/de/d0e/widevine__pssh__generator_8h_source.html +++ b/docs/de/d0e/widevine__pssh__generator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/widevine_pssh_generator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    widevine_pssh_generator.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef MEDIA_BASE_WIDEVINE_PSSH_GENERATOR_H_
    8 #define MEDIA_BASE_WIDEVINE_PSSH_GENERATOR_H_
    9 
    10 #include "packager/media/base/fourccs.h"
    11 #include "packager/media/base/pssh_generator.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    17  public:
    18  explicit WidevinePsshGenerator(FourCC protection_scheme);
    19  ~WidevinePsshGenerator() override;
    20 
    23  bool SupportMultipleKeys() override;
    25 
    26  private:
    27  WidevinePsshGenerator& operator=(const WidevinePsshGenerator&) = delete;
    29 
    30  // PsshGenerator implemetation overrides.
    31 
    32  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
    33  const std::vector<std::vector<uint8_t>>& key_ids) const override;
    34 
    35  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
    36  const std::vector<uint8_t>& key_id,
    37  const std::vector<uint8_t>& key) const override;
    38 
    39  FourCC protection_scheme_ = FOURCC_NULL;
    40 };
    41 
    42 } // namespace media
    43 } // namespace shaka
    44 
    45 #endif // MEDIA_BASE_WIDEVINE_PSSH_GENERATOR_H_
    All the methods that are virtual are virtual for mocking.
    - - - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef MEDIA_BASE_WIDEVINE_PSSH_GENERATOR_H_
    +
    8 #define MEDIA_BASE_WIDEVINE_PSSH_GENERATOR_H_
    +
    9 
    +
    10 #include "packager/media/base/fourccs.h"
    +
    11 #include "packager/media/base/pssh_generator.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    + +
    17  public:
    +
    18  explicit WidevinePsshGenerator(FourCC protection_scheme);
    +
    19  ~WidevinePsshGenerator() override;
    +
    20 
    +
    23  bool SupportMultipleKeys() override;
    +
    25 
    +
    26  private:
    +
    27  WidevinePsshGenerator& operator=(const WidevinePsshGenerator&) = delete;
    + +
    29 
    +
    30  // PsshGenerator implemetation overrides.
    +
    31 
    +
    32  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
    +
    33  const std::vector<std::vector<uint8_t>>& key_ids) const override;
    +
    34 
    +
    35  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
    +
    36  const std::vector<uint8_t>& key_id,
    +
    37  const std::vector<uint8_t>& key) const override;
    +
    38 
    +
    39  FourCC protection_scheme_ = FOURCC_NULL;
    +
    40 };
    +
    41 
    +
    42 } // namespace media
    +
    43 } // namespace shaka
    +
    44 
    +
    45 #endif // MEDIA_BASE_WIDEVINE_PSSH_GENERATOR_H_
    + + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d0f/local__file_8h_source.html b/docs/de/d0f/local__file_8h_source.html index 8a6589fcc1..3616db1f29 100644 --- a/docs/de/d0f/local__file_8h_source.html +++ b/docs/de/d0f/local__file_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/local_file.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    local_file.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_FILE_LOCAL_FILE_H_
    8 #define PACKAGER_FILE_LOCAL_FILE_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <string>
    13 
    14 #include "packager/base/compiler_specific.h"
    15 #include "packager/file/file.h"
    16 
    17 namespace shaka {
    18 
    20 class LocalFile : public File {
    21  public:
    25  LocalFile(const char* file_name, const char* mode);
    26 
    29  bool Close() override;
    30  int64_t Read(void* buffer, uint64_t length) override;
    31  int64_t Write(const void* buffer, uint64_t length) override;
    32  int64_t Size() override;
    33  bool Flush() override;
    34  bool Seek(uint64_t position) override;
    35  bool Tell(uint64_t* position) override;
    37 
    41  static bool Delete(const char* file_name);
    42 
    43  protected:
    44  ~LocalFile() override;
    45 
    46  bool Open() override;
    47 
    48  private:
    49  std::string file_mode_;
    50  FILE* internal_file_;
    51 
    52  DISALLOW_COPY_AND_ASSIGN(LocalFile);
    53 };
    54 
    55 } // namespace shaka
    56 
    57 #endif // PACKAGER_FILE_LOCAL_FILE_H_
    bool Close() override
    Definition: local_file.cc:104
    -
    bool Seek(uint64_t position) override
    Definition: local_file.cc:161
    -
    bool Flush() override
    Definition: local_file.cc:156
    -
    Define an abstract file interface.
    Definition: file.h:26
    -
    const std::string & file_name() const
    Definition: file.h:94
    -
    All the methods that are virtual are virtual for mocking.
    -
    int64_t Size() override
    Definition: local_file.cc:138
    -
    static bool Delete(const char *file_name)
    Definition: local_file.cc:199
    -
    Implement LocalFile which deals with local storage.
    Definition: local_file.h:20
    -
    int64_t Read(void *buffer, uint64_t length) override
    Definition: local_file.cc:114
    -
    bool Open() override
    Internal open. Should not be used directly.
    Definition: local_file.cc:184
    -
    int64_t Write(const void *buffer, uint64_t length) override
    Definition: local_file.cc:126
    -
    bool Tell(uint64_t *position) override
    Definition: local_file.cc:170
    -
    LocalFile(const char *file_name, const char *mode)
    Definition: local_file.cc:98
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_FILE_LOCAL_FILE_H_
    +
    8 #define PACKAGER_FILE_LOCAL_FILE_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <string>
    +
    13 
    +
    14 #include "packager/base/compiler_specific.h"
    +
    15 #include "packager/file/file.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 
    +
    20 class LocalFile : public File {
    +
    21  public:
    +
    25  LocalFile(const char* file_name, const char* mode);
    +
    26 
    +
    29  bool Close() override;
    +
    30  int64_t Read(void* buffer, uint64_t length) override;
    +
    31  int64_t Write(const void* buffer, uint64_t length) override;
    +
    32  int64_t Size() override;
    +
    33  bool Flush() override;
    +
    34  bool Seek(uint64_t position) override;
    +
    35  bool Tell(uint64_t* position) override;
    +
    37 
    +
    41  static bool Delete(const char* file_name);
    +
    42 
    +
    43  protected:
    +
    44  ~LocalFile() override;
    +
    45 
    +
    46  bool Open() override;
    +
    47 
    +
    48  private:
    +
    49  std::string file_mode_;
    +
    50  FILE* internal_file_;
    +
    51 
    +
    52  DISALLOW_COPY_AND_ASSIGN(LocalFile);
    +
    53 };
    +
    54 
    +
    55 } // namespace shaka
    +
    56 
    +
    57 #endif // PACKAGER_FILE_LOCAL_FILE_H_
    +
    Define an abstract file interface.
    Definition: file.h:27
    +
    const std::string & file_name() const
    Definition: file.h:95
    +
    Implement LocalFile which deals with local storage.
    Definition: local_file.h:20
    +
    bool Flush() override
    Definition: local_file.cc:156
    +
    bool Seek(uint64_t position) override
    Definition: local_file.cc:161
    +
    int64_t Read(void *buffer, uint64_t length) override
    Definition: local_file.cc:114
    +
    LocalFile(const char *file_name, const char *mode)
    Definition: local_file.cc:98
    +
    bool Close() override
    Definition: local_file.cc:104
    +
    static bool Delete(const char *file_name)
    Definition: local_file.cc:199
    +
    bool Open() override
    Internal open. Should not be used directly.
    Definition: local_file.cc:184
    +
    int64_t Size() override
    Definition: local_file.cc:138
    +
    int64_t Write(const void *buffer, uint64_t length) override
    Definition: local_file.cc:126
    +
    bool Tell(uint64_t *position) override
    Definition: local_file.cc:170
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d12/container__names_8h_source.html b/docs/de/d12/container__names_8h_source.html index c117cca1ff..12e08b4c17 100644 --- a/docs/de/d12/container__names_8h_source.html +++ b/docs/de/d12/container__names_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/container_names.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    container_names.h
    -
    1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_BASE_CONTAINER_NAMES_H_
    6 #define PACKAGER_MEDIA_BASE_CONTAINER_NAMES_H_
    7 
    8 #include <stdint.h>
    9 
    10 #include <string>
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    17 enum MediaContainerName {
    18  CONTAINER_UNKNOWN, // Unknown
    19  CONTAINER_AAC, // AAC (Advanced Audio Coding)
    20  CONTAINER_AC3, // AC-3
    21  CONTAINER_AIFF, // AIFF (Audio Interchange File Format)
    22  CONTAINER_AMR, // AMR (Adaptive Multi-Rate Audio)
    23  CONTAINER_APE, // APE (Monkey's Audio)
    24  CONTAINER_ASF, // ASF (Advanced / Active Streaming Format)
    25  CONTAINER_ASS, // SSA (SubStation Alpha) subtitle
    26  CONTAINER_AVI, // AVI (Audio Video Interleaved)
    27  CONTAINER_BINK, // Bink
    28  CONTAINER_CAF, // CAF (Apple Core Audio Format)
    29  CONTAINER_DTS, // DTS
    30  CONTAINER_DTSHD, // DTS-HD
    31  CONTAINER_DV, // DV (Digital Video)
    32  CONTAINER_DXA, // DXA
    33  CONTAINER_EAC3, // Enhanced AC-3
    34  CONTAINER_FLAC, // FLAC (Free Lossless Audio Codec)
    35  CONTAINER_FLV, // FLV (Flash Video)
    36  CONTAINER_GSM, // GSM (Global System for Mobile Audio)
    37  CONTAINER_H261, // H.261
    38  CONTAINER_H263, // H.263
    39  CONTAINER_H264, // H.264
    40  CONTAINER_HLS, // HLS (Apple HTTP Live Streaming PlayList)
    41  CONTAINER_IRCAM, // Berkeley/IRCAM/CARL Sound Format
    42  CONTAINER_MJPEG, // MJPEG video
    43  CONTAINER_MOV, // QuickTime / MOV / MPEG4
    44  CONTAINER_MP3, // MP3 (MPEG audio layer 2/3)
    45  CONTAINER_MPEG2PS, // MPEG-2 Program Stream
    46  CONTAINER_MPEG2TS, // MPEG-2 Transport Stream
    47  CONTAINER_MPEG4BS, // MPEG-4 Bitstream
    48  CONTAINER_OGG, // Ogg
    49  CONTAINER_RM, // RM (RealMedia)
    50  CONTAINER_SRT, // SRT (SubRip subtitle)
    51  CONTAINER_SWF, // SWF (ShockWave Flash)
    52  CONTAINER_TTML, // TTML file.
    53  CONTAINER_VC1, // VC-1
    54  CONTAINER_WAV, // WAV / WAVE (Waveform Audio)
    55  CONTAINER_WEBM, // Matroska / WebM
    56  CONTAINER_WEBVTT, // WebVTT file.
    57  CONTAINER_WTV, // WTV (Windows Television)
    58  CONTAINER_WVM, // WVM (Widevine Classic Format)
    59  CONTAINER_MAX // Must be last
    60 };
    61 
    63 MediaContainerName DetermineContainer(const uint8_t* buffer, int buffer_size);
    64 
    67 MediaContainerName DetermineContainerFromFormatName(
    68  const std::string& format_name);
    69 
    72 MediaContainerName DetermineContainerFromFileName(const std::string& file_name);
    73 
    74 } // namespace media
    75 } // namespace shaka
    76 
    77 #endif // PACKAGER_MEDIA_BASE_CONTAINER_NAMES_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_BASE_CONTAINER_NAMES_H_
    +
    6 #define PACKAGER_MEDIA_BASE_CONTAINER_NAMES_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    17 enum MediaContainerName {
    +
    18  CONTAINER_UNKNOWN, // Unknown
    +
    19  CONTAINER_AAC, // AAC (Advanced Audio Coding)
    +
    20  CONTAINER_AC3, // AC-3
    +
    21  CONTAINER_AIFF, // AIFF (Audio Interchange File Format)
    +
    22  CONTAINER_AMR, // AMR (Adaptive Multi-Rate Audio)
    +
    23  CONTAINER_APE, // APE (Monkey's Audio)
    +
    24  CONTAINER_ASF, // ASF (Advanced / Active Streaming Format)
    +
    25  CONTAINER_ASS, // SSA (SubStation Alpha) subtitle
    +
    26  CONTAINER_AVI, // AVI (Audio Video Interleaved)
    +
    27  CONTAINER_BINK, // Bink
    +
    28  CONTAINER_CAF, // CAF (Apple Core Audio Format)
    +
    29  CONTAINER_DTS, // DTS
    +
    30  CONTAINER_DTSHD, // DTS-HD
    +
    31  CONTAINER_DV, // DV (Digital Video)
    +
    32  CONTAINER_DXA, // DXA
    +
    33  CONTAINER_EAC3, // Enhanced AC-3
    +
    34  CONTAINER_FLAC, // FLAC (Free Lossless Audio Codec)
    +
    35  CONTAINER_FLV, // FLV (Flash Video)
    +
    36  CONTAINER_GSM, // GSM (Global System for Mobile Audio)
    +
    37  CONTAINER_H261, // H.261
    +
    38  CONTAINER_H263, // H.263
    +
    39  CONTAINER_H264, // H.264
    +
    40  CONTAINER_HLS, // HLS (Apple HTTP Live Streaming PlayList)
    +
    41  CONTAINER_IRCAM, // Berkeley/IRCAM/CARL Sound Format
    +
    42  CONTAINER_MJPEG, // MJPEG video
    +
    43  CONTAINER_MOV, // QuickTime / MOV / MPEG4
    +
    44  CONTAINER_MP3, // MP3 (MPEG audio layer 2/3)
    +
    45  CONTAINER_MPEG2PS, // MPEG-2 Program Stream
    +
    46  CONTAINER_MPEG2TS, // MPEG-2 Transport Stream
    +
    47  CONTAINER_MPEG4BS, // MPEG-4 Bitstream
    +
    48  CONTAINER_OGG, // Ogg
    +
    49  CONTAINER_RM, // RM (RealMedia)
    +
    50  CONTAINER_SRT, // SRT (SubRip subtitle)
    +
    51  CONTAINER_SWF, // SWF (ShockWave Flash)
    +
    52  CONTAINER_TTML, // TTML file.
    +
    53  CONTAINER_VC1, // VC-1
    +
    54  CONTAINER_WAV, // WAV / WAVE (Waveform Audio)
    +
    55  CONTAINER_WEBM, // Matroska / WebM
    +
    56  CONTAINER_WEBVTT, // WebVTT file.
    +
    57  CONTAINER_WTV, // WTV (Windows Television)
    +
    58  CONTAINER_WVM, // WVM (Widevine Classic Format)
    +
    59  CONTAINER_MAX // Must be last
    +
    60 };
    +
    61 
    +
    63 MediaContainerName DetermineContainer(const uint8_t* buffer, int buffer_size);
    +
    64 
    +
    67 MediaContainerName DetermineContainerFromFormatName(
    +
    68  const std::string& format_name);
    +
    69 
    +
    72 MediaContainerName DetermineContainerFromFileName(const std::string& file_name);
    +
    73 
    +
    74 } // namespace media
    +
    75 } // namespace shaka
    +
    76 
    +
    77 #endif // PACKAGER_MEDIA_BASE_CONTAINER_NAMES_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d13/ts__writer_8cc_source.html b/docs/de/d13/ts__writer_8cc_source.html index 8b0733a221..4056bbd480 100644 --- a/docs/de/d13/ts__writer_8cc_source.html +++ b/docs/de/d13/ts__writer_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_writer.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    ts_writer.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp2t/ts_writer.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/media/base/buffer_writer.h"
    13 #include "packager/media/base/media_sample.h"
    14 #include "packager/media/formats/mp2t/pes_packet.h"
    15 #include "packager/media/formats/mp2t/program_map_table_writer.h"
    16 #include "packager/media/formats/mp2t/ts_packet_writer_util.h"
    17 
    18 namespace shaka {
    19 namespace media {
    20 namespace mp2t {
    21 
    22 namespace {
    23 
    24 // For all the pointer fields in the following PAT and PMTs, they are not really
    25 // part of PAT or PMT but it's there so that TsPacket can point to a memory
    26 // location that starts from pointer field.
    27 const uint8_t kProgramAssociationTableId = 0x00;
    28 
    29 // This PAT can be used for both encrypted and clear.
    30 const uint8_t kPat[] = {
    31  0x00, // pointer field
    32  kProgramAssociationTableId,
    33  0xB0, // The last 2 '00' assumes that this PAT is not very long.
    34  0x0D, // Length of the rest of this array.
    35  0x00, 0x00, // Transport stream ID is 0.
    36  0xC1, // version number 0, current next indicator 1.
    37  0x00, // section number
    38  0x00, // last section number
    39  // program number -> PMT PID mapping.
    40  0x00, 0x01, // program number is 1.
    41  0xE0, // first 3 bits is reserved.
    42  ProgramMapTableWriter::kPmtPid,
    43  // CRC32.
    44  0xF9, 0x62, 0xF5, 0x8B,
    45 };
    46 
    47 const bool kHasPcr = true;
    48 const bool kPayloadUnitStartIndicator = true;
    49 
    50 // This is the size of the first few fields in a TS packet, i.e. TS packet size
    51 // without adaptation field or the payload.
    52 const int kTsPacketHeaderSize = 4;
    53 const int kTsPacketSize = 188;
    54 const int kTsPacketMaximumPayloadSize =
    55  kTsPacketSize - kTsPacketHeaderSize;
    56 
    57 const size_t kMaxPesPacketLengthValue = 0xFFFF;
    58 
    59 void WritePatToBuffer(const uint8_t* pat,
    60  int pat_size,
    61  ContinuityCounter* continuity_counter,
    62  BufferWriter* writer) {
    63  const int kPatPid = 0;
    64  WritePayloadToBufferWriter(pat, pat_size, kPayloadUnitStartIndicator, kPatPid,
    65  !kHasPcr, 0, continuity_counter, writer);
    66 }
    67 
    68 // The only difference between writing PTS or DTS is the leading bits.
    69 void WritePtsOrDts(uint8_t leading_bits,
    70  uint64_t pts_or_dts,
    71  BufferWriter* writer) {
    72  // First byte has 3 MSB of PTS.
    73  uint8_t first_byte =
    74  leading_bits << 4 | (((pts_or_dts >> 30) & 0x07) << 1) | 1;
    75  // Second byte has the next 8 bits of pts.
    76  uint8_t second_byte = (pts_or_dts >> 22) & 0xFF;
    77  // Third byte has the next 7 bits of pts followed by a marker bit.
    78  uint8_t third_byte = (((pts_or_dts >> 15) & 0x7F) << 1) | 1;
    79  // Fourth byte has the next 8 bits of pts.
    80  uint8_t fourth_byte = ((pts_or_dts >> 7) & 0xFF);
    81  // Fifth byte has the last 7 bits of pts followed by a marker bit.
    82  uint8_t fifth_byte = ((pts_or_dts & 0x7F) << 1) | 1;
    83  writer->AppendInt(first_byte);
    84  writer->AppendInt(second_byte);
    85  writer->AppendInt(third_byte);
    86  writer->AppendInt(fourth_byte);
    87  writer->AppendInt(fifth_byte);
    88 }
    89 
    90 bool WritePesToFile(const PesPacket& pes,
    91  ContinuityCounter* continuity_counter,
    92  File* file) {
    93  // The size of the length field.
    94  const int kAdaptationFieldLengthSize = 1;
    95  // The size of the flags field.
    96  const int kAdaptationFieldHeaderSize = 1;
    97  const int kPcrFieldSize = 6;
    98  const int kTsPacketMaxPayloadWithPcr =
    99  kTsPacketMaximumPayloadSize - kAdaptationFieldLengthSize -
    100  kAdaptationFieldHeaderSize - kPcrFieldSize;
    101  const uint64_t pcr_base = pes.has_dts() ? pes.dts() : pes.pts();
    102  const int pid = ProgramMapTableWriter::kElementaryPid;
    103 
    104  // This writer will hold part of PES packet after PES_packet_length field.
    105  BufferWriter pes_header_writer;
    106  // The first bit must be '10' for PES with video or audio stream id. The other
    107  // flags (bits) don't matter so they are 0.
    108  pes_header_writer.AppendInt(static_cast<uint8_t>(0x80));
    109  pes_header_writer.AppendInt(
    110  static_cast<uint8_t>(static_cast<int>(pes.has_pts()) << 7 |
    111  static_cast<int>(pes.has_dts()) << 6
    112  // Other fields are all 0.
    113  ));
    114  uint8_t pes_header_data_length = 0;
    115  if (pes.has_pts())
    116  pes_header_data_length += 5;
    117  if (pes.has_dts())
    118  pes_header_data_length += 5;
    119  pes_header_writer.AppendInt(pes_header_data_length);
    120 
    121  if (pes.has_pts() && pes.has_dts()) {
    122  WritePtsOrDts(0x03, pes.pts(), &pes_header_writer);
    123  WritePtsOrDts(0x01, pes.dts(), &pes_header_writer);
    124  } else if (pes.has_pts()) {
    125  WritePtsOrDts(0x02, pes.pts(), &pes_header_writer);
    126  }
    127 
    128  // Put the first TS packet's payload into a buffer. This contains the PES
    129  // packet's header.
    130  BufferWriter first_ts_packet_buffer(kTsPacketSize);
    131  first_ts_packet_buffer.AppendNBytes(static_cast<uint64_t>(0x000001), 3);
    132  first_ts_packet_buffer.AppendInt(pes.stream_id());
    133  const size_t pes_packet_length = pes.data().size() + pes_header_writer.Size();
    134  first_ts_packet_buffer.AppendInt(static_cast<uint16_t>(
    135  pes_packet_length > kMaxPesPacketLengthValue ? 0 : pes_packet_length));
    136  first_ts_packet_buffer.AppendBuffer(pes_header_writer);
    137 
    138  const size_t available_payload =
    139  kTsPacketMaxPayloadWithPcr - first_ts_packet_buffer.Size();
    140  const size_t bytes_consumed = std::min(pes.data().size(), available_payload);
    141  first_ts_packet_buffer.AppendArray(pes.data().data(), bytes_consumed);
    142 
    143  BufferWriter output_writer;
    144  WritePayloadToBufferWriter(first_ts_packet_buffer.Buffer(),
    145  first_ts_packet_buffer.Size(),
    146  kPayloadUnitStartIndicator, pid, kHasPcr, pcr_base,
    147  continuity_counter, &output_writer);
    148 
    149  const size_t remaining_pes_data_size = pes.data().size() - bytes_consumed;
    150  if (remaining_pes_data_size > 0) {
    151  WritePayloadToBufferWriter(pes.data().data() + bytes_consumed,
    152  remaining_pes_data_size,
    153  !kPayloadUnitStartIndicator, pid, !kHasPcr, 0,
    154  continuity_counter, &output_writer);
    155  }
    156  return output_writer.WriteToFile(file).ok();
    157 }
    158 
    159 } // namespace
    160 
    161 TsWriter::TsWriter(std::unique_ptr<ProgramMapTableWriter> pmt_writer)
    162  : pmt_writer_(std::move(pmt_writer)) {}
    163 
    164 TsWriter::~TsWriter() {}
    165 
    166 bool TsWriter::NewSegment(const std::string& file_name) {
    167  if (current_file_) {
    168  LOG(ERROR) << "File " << current_file_->file_name() << " still open.";
    169  return false;
    170  }
    171  current_file_.reset(File::Open(file_name.c_str(), "w"));
    172  if (!current_file_) {
    173  LOG(ERROR) << "Failed to open file " << file_name;
    174  return false;
    175  }
    176 
    177  BufferWriter psi;
    178  WritePatToBuffer(kPat, arraysize(kPat), &pat_continuity_counter_, &psi);
    179  if (encrypted_) {
    180  if (!pmt_writer_->EncryptedSegmentPmt(&psi)) {
    181  return false;
    182  }
    183  } else {
    184  if (!pmt_writer_->ClearSegmentPmt(&psi)) {
    185  return false;
    186  }
    187  }
    188 
    189  if (!psi.WriteToFile(current_file_.get()).ok()) {
    190  LOG(ERROR) << "Failed to write PSI to file.";
    191  return false;
    192  }
    193 
    194  return true;
    195 }
    196 
    198  encrypted_ = true;
    199 }
    200 
    202  return current_file_.release()->Close();
    203 }
    204 
    205 bool TsWriter::AddPesPacket(std::unique_ptr<PesPacket> pes_packet) {
    206  DCHECK(current_file_);
    207  if (!WritePesToFile(*pes_packet, &elementary_stream_continuity_counter_,
    208  current_file_.get())) {
    209  LOG(ERROR) << "Failed to write pes to file.";
    210  return false;
    211  }
    212 
    213  // No need to keep pes_packet around so not passing it anywhere.
    214  return true;
    215 }
    216 
    217 base::Optional<uint64_t> TsWriter::GetFilePosition() {
    218  if (!current_file_)
    219  return base::nullopt;
    220  uint64_t position;
    221  return current_file_->Tell(&position) ? base::make_optional(position)
    222  : base::nullopt;
    223 }
    224 
    225 } // namespace mp2t
    226 } // namespace media
    227 } // namespace shaka
    virtual bool NewSegment(const std::string &file_name)
    Definition: ts_writer.cc:166
    -
    STL namespace.
    -
    base::Optional< uint64_t > GetFilePosition()
    Definition: ts_writer.cc:217
    -
    All the methods that are virtual are virtual for mocking.
    -
    virtual bool AddPesPacket(std::unique_ptr< PesPacket > pes_packet)
    Definition: ts_writer.cc:205
    - -
    virtual bool FinalizeSegment()
    Definition: ts_writer.cc:201
    -
    virtual bool Open()=0
    Internal open. Should not be used directly.
    -
    Status WriteToFile(File *file)
    -
    virtual void SignalEncrypted()
    Signals the writer that the rest of the segments are encrypted.
    Definition: ts_writer.cc:197
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/ts_writer.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/buffer_writer.h"
    +
    13 #include "packager/media/base/media_sample.h"
    +
    14 #include "packager/media/formats/mp2t/pes_packet.h"
    +
    15 #include "packager/media/formats/mp2t/program_map_table_writer.h"
    +
    16 #include "packager/media/formats/mp2t/ts_packet_writer_util.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 namespace mp2t {
    +
    21 
    +
    22 namespace {
    +
    23 
    +
    24 // For all the pointer fields in the following PAT and PMTs, they are not really
    +
    25 // part of PAT or PMT but it's there so that TsPacket can point to a memory
    +
    26 // location that starts from pointer field.
    +
    27 const uint8_t kProgramAssociationTableId = 0x00;
    +
    28 
    +
    29 // This PAT can be used for both encrypted and clear.
    +
    30 const uint8_t kPat[] = {
    +
    31  0x00, // pointer field
    +
    32  kProgramAssociationTableId,
    +
    33  0xB0, // The last 2 '00' assumes that this PAT is not very long.
    +
    34  0x0D, // Length of the rest of this array.
    +
    35  0x00, 0x00, // Transport stream ID is 0.
    +
    36  0xC1, // version number 0, current next indicator 1.
    +
    37  0x00, // section number
    +
    38  0x00, // last section number
    +
    39  // program number -> PMT PID mapping.
    +
    40  0x00, 0x01, // program number is 1.
    +
    41  0xE0, // first 3 bits is reserved.
    +
    42  ProgramMapTableWriter::kPmtPid,
    +
    43  // CRC32.
    +
    44  0xF9, 0x62, 0xF5, 0x8B,
    +
    45 };
    +
    46 
    +
    47 const bool kHasPcr = true;
    +
    48 const bool kPayloadUnitStartIndicator = true;
    +
    49 
    +
    50 // This is the size of the first few fields in a TS packet, i.e. TS packet size
    +
    51 // without adaptation field or the payload.
    +
    52 const int kTsPacketHeaderSize = 4;
    +
    53 const int kTsPacketSize = 188;
    +
    54 const int kTsPacketMaximumPayloadSize =
    +
    55  kTsPacketSize - kTsPacketHeaderSize;
    +
    56 
    +
    57 const size_t kMaxPesPacketLengthValue = 0xFFFF;
    +
    58 
    +
    59 void WritePatToBuffer(const uint8_t* pat,
    +
    60  int pat_size,
    +
    61  ContinuityCounter* continuity_counter,
    +
    62  BufferWriter* writer) {
    +
    63  const int kPatPid = 0;
    +
    64  WritePayloadToBufferWriter(pat, pat_size, kPayloadUnitStartIndicator, kPatPid,
    +
    65  !kHasPcr, 0, continuity_counter, writer);
    +
    66 }
    +
    67 
    +
    68 // The only difference between writing PTS or DTS is the leading bits.
    +
    69 void WritePtsOrDts(uint8_t leading_bits,
    +
    70  uint64_t pts_or_dts,
    +
    71  BufferWriter* writer) {
    +
    72  // First byte has 3 MSB of PTS.
    +
    73  uint8_t first_byte =
    +
    74  leading_bits << 4 | (((pts_or_dts >> 30) & 0x07) << 1) | 1;
    +
    75  // Second byte has the next 8 bits of pts.
    +
    76  uint8_t second_byte = (pts_or_dts >> 22) & 0xFF;
    +
    77  // Third byte has the next 7 bits of pts followed by a marker bit.
    +
    78  uint8_t third_byte = (((pts_or_dts >> 15) & 0x7F) << 1) | 1;
    +
    79  // Fourth byte has the next 8 bits of pts.
    +
    80  uint8_t fourth_byte = ((pts_or_dts >> 7) & 0xFF);
    +
    81  // Fifth byte has the last 7 bits of pts followed by a marker bit.
    +
    82  uint8_t fifth_byte = ((pts_or_dts & 0x7F) << 1) | 1;
    +
    83  writer->AppendInt(first_byte);
    +
    84  writer->AppendInt(second_byte);
    +
    85  writer->AppendInt(third_byte);
    +
    86  writer->AppendInt(fourth_byte);
    +
    87  writer->AppendInt(fifth_byte);
    +
    88 }
    +
    89 
    +
    90 bool WritePesToBuffer(const PesPacket& pes,
    +
    91  ContinuityCounter* continuity_counter,
    +
    92  BufferWriter* current_buffer) {
    +
    93  // The size of the length field.
    +
    94  const int kAdaptationFieldLengthSize = 1;
    +
    95  // The size of the flags field.
    +
    96  const int kAdaptationFieldHeaderSize = 1;
    +
    97  const int kPcrFieldSize = 6;
    +
    98  const int kTsPacketMaxPayloadWithPcr =
    +
    99  kTsPacketMaximumPayloadSize - kAdaptationFieldLengthSize -
    +
    100  kAdaptationFieldHeaderSize - kPcrFieldSize;
    +
    101  const uint64_t pcr_base = pes.has_dts() ? pes.dts() : pes.pts();
    +
    102  const int pid = ProgramMapTableWriter::kElementaryPid;
    +
    103 
    +
    104  // This writer will hold part of PES packet after PES_packet_length field.
    +
    105  BufferWriter pes_header_writer;
    +
    106  // The first bit must be '10' for PES with video or audio stream id. The other
    +
    107  // flags (bits) don't matter so they are 0.
    +
    108  pes_header_writer.AppendInt(static_cast<uint8_t>(0x80));
    +
    109  pes_header_writer.AppendInt(
    +
    110  static_cast<uint8_t>(static_cast<int>(pes.has_pts()) << 7 |
    +
    111  static_cast<int>(pes.has_dts()) << 6
    +
    112  // Other fields are all 0.
    +
    113  ));
    +
    114  uint8_t pes_header_data_length = 0;
    +
    115  if (pes.has_pts())
    +
    116  pes_header_data_length += 5;
    +
    117  if (pes.has_dts())
    +
    118  pes_header_data_length += 5;
    +
    119  pes_header_writer.AppendInt(pes_header_data_length);
    +
    120 
    +
    121  if (pes.has_pts() && pes.has_dts()) {
    +
    122  WritePtsOrDts(0x03, pes.pts(), &pes_header_writer);
    +
    123  WritePtsOrDts(0x01, pes.dts(), &pes_header_writer);
    +
    124  } else if (pes.has_pts()) {
    +
    125  WritePtsOrDts(0x02, pes.pts(), &pes_header_writer);
    +
    126  }
    +
    127 
    +
    128  // Put the first TS packet's payload into a buffer. This contains the PES
    +
    129  // packet's header.
    +
    130  BufferWriter first_ts_packet_buffer(kTsPacketSize);
    +
    131  first_ts_packet_buffer.AppendNBytes(static_cast<uint64_t>(0x000001), 3);
    +
    132  first_ts_packet_buffer.AppendInt(pes.stream_id());
    +
    133  const size_t pes_packet_length = pes.data().size() + pes_header_writer.Size();
    +
    134  first_ts_packet_buffer.AppendInt(static_cast<uint16_t>(
    +
    135  pes_packet_length > kMaxPesPacketLengthValue ? 0 : pes_packet_length));
    +
    136  first_ts_packet_buffer.AppendBuffer(pes_header_writer);
    +
    137 
    +
    138  const size_t available_payload =
    +
    139  kTsPacketMaxPayloadWithPcr - first_ts_packet_buffer.Size();
    +
    140  const size_t bytes_consumed = std::min(pes.data().size(), available_payload);
    +
    141  first_ts_packet_buffer.AppendArray(pes.data().data(), bytes_consumed);
    +
    142 
    +
    143  BufferWriter output_writer;
    +
    144  WritePayloadToBufferWriter(first_ts_packet_buffer.Buffer(),
    +
    145  first_ts_packet_buffer.Size(),
    +
    146  kPayloadUnitStartIndicator, pid, kHasPcr, pcr_base,
    +
    147  continuity_counter, &output_writer);
    +
    148 
    +
    149  const size_t remaining_pes_data_size = pes.data().size() - bytes_consumed;
    +
    150  if (remaining_pes_data_size > 0) {
    +
    151  WritePayloadToBufferWriter(pes.data().data() + bytes_consumed,
    +
    152  remaining_pes_data_size,
    +
    153  !kPayloadUnitStartIndicator, pid, !kHasPcr, 0,
    +
    154  continuity_counter, &output_writer);
    +
    155  }
    +
    156 
    +
    157  current_buffer->AppendBuffer(output_writer);
    +
    158  return true;
    +
    159 }
    +
    160 
    +
    161 } // namespace
    +
    162 
    +
    163 TsWriter::TsWriter(std::unique_ptr<ProgramMapTableWriter> pmt_writer)
    +
    164  : pmt_writer_(std::move(pmt_writer)) {}
    +
    165 
    +
    166 TsWriter::~TsWriter() {}
    +
    167 
    +
    168 bool TsWriter::NewSegment(BufferWriter* buffer) {
    +
    169  BufferWriter psi;
    +
    170  WritePatToBuffer(kPat, arraysize(kPat), &pat_continuity_counter_, &psi);
    +
    171  if (encrypted_) {
    +
    172  if (!pmt_writer_->EncryptedSegmentPmt(&psi)) {
    +
    173  return false;
    +
    174  }
    +
    175  } else {
    +
    176  if (!pmt_writer_->ClearSegmentPmt(&psi)) {
    +
    177  return false;
    +
    178  }
    +
    179  }
    +
    180  buffer->AppendBuffer(psi);
    +
    181 
    +
    182  return true;
    +
    183 }
    +
    184 
    +
    185 void TsWriter::SignalEncrypted() {
    +
    186  encrypted_ = true;
    +
    187 }
    +
    188 
    +
    189 bool TsWriter::AddPesPacket(std::unique_ptr<PesPacket> pes_packet,
    +
    190  BufferWriter* buffer) {
    +
    191 
    +
    192  if (!WritePesToBuffer(*pes_packet, &elementary_stream_continuity_counter_,
    +
    193  buffer)) {
    +
    194  LOG(ERROR) << "Failed to write pes to buffer.";
    +
    195  return false;
    +
    196  }
    +
    197 
    +
    198  // No need to keep pes_packet around so not passing it anywhere.
    +
    199  return true;
    +
    200 }
    +
    201 
    +
    202 } // namespace mp2t
    +
    203 } // namespace media
    +
    204 } // namespace shaka
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d16/classshaka_1_1media_1_1TextTrackConfig-members.html b/docs/de/d16/classshaka_1_1media_1_1TextTrackConfig-members.html index 692692169f..6a20eea698 100644 --- a/docs/de/d16/classshaka_1_1media_1_1TextTrackConfig-members.html +++ b/docs/de/d16/classshaka_1_1media_1_1TextTrackConfig-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/de/d17/cluster__builder_8cc_source.html b/docs/de/d17/cluster__builder_8cc_source.html index 5b111c60fc..91b8bc4b85 100644 --- a/docs/de/d17/cluster__builder_8cc_source.html +++ b/docs/de/d17/cluster__builder_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/cluster_builder.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    cluster_builder.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/webm/cluster_builder.h"
    6 
    7 #include "packager/base/logging.h"
    8 #include "packager/media/formats/webm/webm_constants.h"
    9 
    10 namespace shaka {
    11 namespace media {
    12 
    13 static const uint8_t kClusterHeader[] = {
    14  0x1F, 0x43, 0xB6, 0x75, // CLUSTER ID
    15  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // cluster(size = 0)
    16  0xE7, // Timecode ID
    17  0x88, // timecode(size=8)
    18  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // timecode value
    19 };
    20 
    21 static const uint8_t kSimpleBlockHeader[] = {
    22  0xA3, // SimpleBlock ID
    23  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SimpleBlock(size = 0)
    24 };
    25 
    26 static const uint8_t kBlockGroupHeader[] = {
    27  0xA0, // BlockGroup ID
    28  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BlockGroup(size = 0)
    29  0x9B, // BlockDuration ID
    30  0x88, // BlockDuration(size = 8)
    31  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // duration
    32  0xA1, // Block ID
    33  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block(size = 0)
    34 };
    35 
    36 static const uint8_t kBlockGroupHeaderWithoutBlockDuration[] = {
    37  0xA0, // BlockGroup ID
    38  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BlockGroup(size = 0)
    39  0xA1, // Block ID
    40  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block(size = 0)
    41 };
    42 
    43 static const uint8_t kBlockGroupReferenceBlock[] = {
    44  0xFB, // ReferenceBlock ID
    45  0x81, 0x00, // ReferenceBlock (size=1, value=0)
    46 };
    47 
    48 enum {
    49  kClusterSizeOffset = 4,
    50  kClusterTimecodeOffset = 14,
    51 
    52  kSimpleBlockSizeOffset = 1,
    53 
    54  kBlockGroupSizeOffset = 1,
    55  kBlockGroupWithoutBlockDurationBlockSizeOffset = 10,
    56  kBlockGroupDurationOffset = 11,
    57  kBlockGroupBlockSizeOffset = 20,
    58 
    59  kInitialBufferSize = 32768,
    60 };
    61 
    62 Cluster::Cluster(std::unique_ptr<uint8_t[]> data, int size)
    63  : data_(std::move(data)), size_(size) {}
    64 Cluster::~Cluster() {}
    65 
    66 ClusterBuilder::ClusterBuilder() { Reset(); }
    67 ClusterBuilder::~ClusterBuilder() {}
    68 
    69 void ClusterBuilder::SetClusterTimecode(int64_t cluster_timecode) {
    70  DCHECK_EQ(cluster_timecode_, -1);
    71 
    72  cluster_timecode_ = cluster_timecode;
    73 
    74  // Write the timecode into the header.
    75  uint8_t* buf = buffer_.get() + kClusterTimecodeOffset;
    76  for (int i = 7; i >= 0; --i) {
    77  buf[i] = cluster_timecode & 0xff;
    78  cluster_timecode >>= 8;
    79  }
    80 }
    81 
    82 void ClusterBuilder::AddSimpleBlock(int track_num,
    83  int64_t timecode,
    84  int flags,
    85  const uint8_t* data,
    86  int size) {
    87  int block_size = size + 4;
    88  int bytes_needed = sizeof(kSimpleBlockHeader) + block_size;
    89  if (bytes_needed > (buffer_size_ - bytes_used_))
    90  ExtendBuffer(bytes_needed);
    91 
    92  uint8_t* buf = buffer_.get() + bytes_used_;
    93  int block_offset = bytes_used_;
    94  memcpy(buf, kSimpleBlockHeader, sizeof(kSimpleBlockHeader));
    95  UpdateUInt64(block_offset + kSimpleBlockSizeOffset, block_size);
    96  buf += sizeof(kSimpleBlockHeader);
    97 
    98  WriteBlock(buf, track_num, timecode, flags, data, size);
    99 
    100  bytes_used_ += bytes_needed;
    101 }
    102 
    103 void ClusterBuilder::AddBlockGroup(int track_num,
    104  int64_t timecode,
    105  int duration,
    106  int flags,
    107  bool is_key_frame,
    108  const uint8_t* data,
    109  int size) {
    110  AddBlockGroupInternal(track_num, timecode, true, duration, flags,
    111  is_key_frame, data, size);
    112 }
    113 
    114 void ClusterBuilder::AddBlockGroupWithoutBlockDuration(int track_num,
    115  int64_t timecode,
    116  int flags,
    117  bool is_key_frame,
    118  const uint8_t* data,
    119  int size) {
    120  AddBlockGroupInternal(track_num, timecode, false, 0, flags, is_key_frame,
    121  data, size);
    122 }
    123 
    124 void ClusterBuilder::AddBlockGroupInternal(int track_num,
    125  int64_t timecode,
    126  bool include_block_duration,
    127  int duration,
    128  int flags,
    129  bool is_key_frame,
    130  const uint8_t* data,
    131  int size) {
    132  int block_size = size + 4;
    133  int bytes_needed = block_size;
    134  if (include_block_duration) {
    135  bytes_needed += sizeof(kBlockGroupHeader);
    136  } else {
    137  bytes_needed += sizeof(kBlockGroupHeaderWithoutBlockDuration);
    138  }
    139  if (!is_key_frame) {
    140  bytes_needed += sizeof(kBlockGroupReferenceBlock);
    141  }
    142 
    143  int block_group_size = bytes_needed - 9;
    144 
    145  if (bytes_needed > (buffer_size_ - bytes_used_))
    146  ExtendBuffer(bytes_needed);
    147 
    148  uint8_t* buf = buffer_.get() + bytes_used_;
    149  int block_group_offset = bytes_used_;
    150  if (include_block_duration) {
    151  memcpy(buf, kBlockGroupHeader, sizeof(kBlockGroupHeader));
    152  UpdateUInt64(block_group_offset + kBlockGroupDurationOffset, duration);
    153  UpdateUInt64(block_group_offset + kBlockGroupBlockSizeOffset, block_size);
    154  buf += sizeof(kBlockGroupHeader);
    155  } else {
    156  memcpy(buf, kBlockGroupHeaderWithoutBlockDuration,
    157  sizeof(kBlockGroupHeaderWithoutBlockDuration));
    158  UpdateUInt64(
    159  block_group_offset + kBlockGroupWithoutBlockDurationBlockSizeOffset,
    160  block_size);
    161  buf += sizeof(kBlockGroupHeaderWithoutBlockDuration);
    162  }
    163 
    164  UpdateUInt64(block_group_offset + kBlockGroupSizeOffset, block_group_size);
    165 
    166  // Make sure the 4 most-significant bits are 0.
    167  // http://www.matroska.org/technical/specs/index.html#block_structure
    168  flags &= 0x0f;
    169 
    170  WriteBlock(buf, track_num, timecode, flags, data, size);
    171  buf += size + 4;
    172 
    173  if (!is_key_frame)
    174  memcpy(buf, kBlockGroupReferenceBlock, sizeof(kBlockGroupReferenceBlock));
    175  bytes_used_ += bytes_needed;
    176 }
    177 
    178 void ClusterBuilder::WriteBlock(uint8_t* buf,
    179  int track_num,
    180  int64_t timecode,
    181  int flags,
    182  const uint8_t* data,
    183  int size) {
    184  DCHECK_GE(track_num, 0);
    185  DCHECK_LE(track_num, 126);
    186  DCHECK_GE(flags, 0);
    187  DCHECK_LE(flags, 0xff);
    188  DCHECK(data);
    189  DCHECK_GT(size, 0);
    190  DCHECK_NE(cluster_timecode_, -1);
    191 
    192  int64_t timecode_delta = timecode - cluster_timecode_;
    193  DCHECK_GE(timecode_delta, -32768);
    194  DCHECK_LE(timecode_delta, 32767);
    195 
    196  buf[0] = 0x80 | (track_num & 0x7F);
    197  buf[1] = (timecode_delta >> 8) & 0xff;
    198  buf[2] = timecode_delta & 0xff;
    199  buf[3] = flags & 0xff;
    200  memcpy(buf + 4, data, size);
    201 }
    202 
    203 std::unique_ptr<Cluster> ClusterBuilder::Finish() {
    204  DCHECK_NE(cluster_timecode_, -1);
    205 
    206  UpdateUInt64(kClusterSizeOffset, bytes_used_ - (kClusterSizeOffset + 8));
    207 
    208  std::unique_ptr<Cluster> ret(new Cluster(std::move(buffer_), bytes_used_));
    209  Reset();
    210  return ret;
    211 }
    212 
    213 std::unique_ptr<Cluster> ClusterBuilder::FinishWithUnknownSize() {
    214  DCHECK_NE(cluster_timecode_, -1);
    215 
    216  UpdateUInt64(kClusterSizeOffset, kWebMUnknownSize);
    217 
    218  std::unique_ptr<Cluster> ret(new Cluster(std::move(buffer_), bytes_used_));
    219  Reset();
    220  return ret;
    221 }
    222 
    223 void ClusterBuilder::Reset() {
    224  buffer_size_ = kInitialBufferSize;
    225  buffer_.reset(new uint8_t[buffer_size_]);
    226  memcpy(buffer_.get(), kClusterHeader, sizeof(kClusterHeader));
    227  bytes_used_ = sizeof(kClusterHeader);
    228  cluster_timecode_ = -1;
    229 }
    230 
    231 void ClusterBuilder::ExtendBuffer(int bytes_needed) {
    232  int new_buffer_size = 2 * buffer_size_;
    233 
    234  while ((new_buffer_size - bytes_used_) < bytes_needed)
    235  new_buffer_size *= 2;
    236 
    237  std::unique_ptr<uint8_t[]> new_buffer(new uint8_t[new_buffer_size]);
    238 
    239  memcpy(new_buffer.get(), buffer_.get(), bytes_used_);
    240  buffer_.reset(new_buffer.release());
    241  buffer_size_ = new_buffer_size;
    242 }
    243 
    244 void ClusterBuilder::UpdateUInt64(int offset, int64_t value) {
    245  DCHECK_LE(offset + 7, buffer_size_);
    246  uint8_t* buf = buffer_.get() + offset;
    247 
    248  // Fill the last 7 bytes of size field in big-endian order.
    249  for (int i = 7; i > 0; i--) {
    250  buf[i] = value & 0xff;
    251  value >>= 8;
    252  }
    253 }
    254 
    255 } // namespace media
    256 } // namespace shaka
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/webm/cluster_builder.h"
    +
    6 
    +
    7 #include "packager/base/logging.h"
    +
    8 #include "packager/media/formats/webm/webm_constants.h"
    +
    9 
    +
    10 namespace shaka {
    +
    11 namespace media {
    +
    12 
    +
    13 static const uint8_t kClusterHeader[] = {
    +
    14  0x1F, 0x43, 0xB6, 0x75, // CLUSTER ID
    +
    15  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // cluster(size = 0)
    +
    16  0xE7, // Timecode ID
    +
    17  0x88, // timecode(size=8)
    +
    18  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // timecode value
    +
    19 };
    +
    20 
    +
    21 static const uint8_t kSimpleBlockHeader[] = {
    +
    22  0xA3, // SimpleBlock ID
    +
    23  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SimpleBlock(size = 0)
    +
    24 };
    +
    25 
    +
    26 static const uint8_t kBlockGroupHeader[] = {
    +
    27  0xA0, // BlockGroup ID
    +
    28  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BlockGroup(size = 0)
    +
    29  0x9B, // BlockDuration ID
    +
    30  0x88, // BlockDuration(size = 8)
    +
    31  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // duration
    +
    32  0xA1, // Block ID
    +
    33  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block(size = 0)
    +
    34 };
    +
    35 
    +
    36 static const uint8_t kBlockGroupHeaderWithoutBlockDuration[] = {
    +
    37  0xA0, // BlockGroup ID
    +
    38  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // BlockGroup(size = 0)
    +
    39  0xA1, // Block ID
    +
    40  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Block(size = 0)
    +
    41 };
    +
    42 
    +
    43 static const uint8_t kBlockGroupReferenceBlock[] = {
    +
    44  0xFB, // ReferenceBlock ID
    +
    45  0x81, 0x00, // ReferenceBlock (size=1, value=0)
    +
    46 };
    +
    47 
    +
    48 enum {
    +
    49  kClusterSizeOffset = 4,
    +
    50  kClusterTimecodeOffset = 14,
    +
    51 
    +
    52  kSimpleBlockSizeOffset = 1,
    +
    53 
    +
    54  kBlockGroupSizeOffset = 1,
    +
    55  kBlockGroupWithoutBlockDurationBlockSizeOffset = 10,
    +
    56  kBlockGroupDurationOffset = 11,
    +
    57  kBlockGroupBlockSizeOffset = 20,
    +
    58 
    +
    59  kInitialBufferSize = 32768,
    +
    60 };
    +
    61 
    +
    62 Cluster::Cluster(std::unique_ptr<uint8_t[]> data, int size)
    +
    63  : data_(std::move(data)), size_(size) {}
    +
    64 Cluster::~Cluster() {}
    +
    65 
    +
    66 ClusterBuilder::ClusterBuilder() { Reset(); }
    +
    67 ClusterBuilder::~ClusterBuilder() {}
    +
    68 
    +
    69 void ClusterBuilder::SetClusterTimecode(int64_t cluster_timecode) {
    +
    70  DCHECK_EQ(cluster_timecode_, -1);
    +
    71 
    +
    72  cluster_timecode_ = cluster_timecode;
    +
    73 
    +
    74  // Write the timecode into the header.
    +
    75  uint8_t* buf = buffer_.get() + kClusterTimecodeOffset;
    +
    76  for (int i = 7; i >= 0; --i) {
    +
    77  buf[i] = cluster_timecode & 0xff;
    +
    78  cluster_timecode >>= 8;
    +
    79  }
    +
    80 }
    +
    81 
    +
    82 void ClusterBuilder::AddSimpleBlock(int track_num,
    +
    83  int64_t timecode,
    +
    84  int flags,
    +
    85  const uint8_t* data,
    +
    86  int size) {
    +
    87  int block_size = size + 4;
    +
    88  int bytes_needed = sizeof(kSimpleBlockHeader) + block_size;
    +
    89  if (bytes_needed > (buffer_size_ - bytes_used_))
    +
    90  ExtendBuffer(bytes_needed);
    +
    91 
    +
    92  uint8_t* buf = buffer_.get() + bytes_used_;
    +
    93  int block_offset = bytes_used_;
    +
    94  memcpy(buf, kSimpleBlockHeader, sizeof(kSimpleBlockHeader));
    +
    95  UpdateUInt64(block_offset + kSimpleBlockSizeOffset, block_size);
    +
    96  buf += sizeof(kSimpleBlockHeader);
    +
    97 
    +
    98  WriteBlock(buf, track_num, timecode, flags, data, size);
    +
    99 
    +
    100  bytes_used_ += bytes_needed;
    +
    101 }
    +
    102 
    +
    103 void ClusterBuilder::AddBlockGroup(int track_num,
    +
    104  int64_t timecode,
    +
    105  int duration,
    +
    106  int flags,
    +
    107  bool is_key_frame,
    +
    108  const uint8_t* data,
    +
    109  int size) {
    +
    110  AddBlockGroupInternal(track_num, timecode, true, duration, flags,
    +
    111  is_key_frame, data, size);
    +
    112 }
    +
    113 
    +
    114 void ClusterBuilder::AddBlockGroupWithoutBlockDuration(int track_num,
    +
    115  int64_t timecode,
    +
    116  int flags,
    +
    117  bool is_key_frame,
    +
    118  const uint8_t* data,
    +
    119  int size) {
    +
    120  AddBlockGroupInternal(track_num, timecode, false, 0, flags, is_key_frame,
    +
    121  data, size);
    +
    122 }
    +
    123 
    +
    124 void ClusterBuilder::AddBlockGroupInternal(int track_num,
    +
    125  int64_t timecode,
    +
    126  bool include_block_duration,
    +
    127  int duration,
    +
    128  int flags,
    +
    129  bool is_key_frame,
    +
    130  const uint8_t* data,
    +
    131  int size) {
    +
    132  int block_size = size + 4;
    +
    133  int bytes_needed = block_size;
    +
    134  if (include_block_duration) {
    +
    135  bytes_needed += sizeof(kBlockGroupHeader);
    +
    136  } else {
    +
    137  bytes_needed += sizeof(kBlockGroupHeaderWithoutBlockDuration);
    +
    138  }
    +
    139  if (!is_key_frame) {
    +
    140  bytes_needed += sizeof(kBlockGroupReferenceBlock);
    +
    141  }
    +
    142 
    +
    143  int block_group_size = bytes_needed - 9;
    +
    144 
    +
    145  if (bytes_needed > (buffer_size_ - bytes_used_))
    +
    146  ExtendBuffer(bytes_needed);
    +
    147 
    +
    148  uint8_t* buf = buffer_.get() + bytes_used_;
    +
    149  int block_group_offset = bytes_used_;
    +
    150  if (include_block_duration) {
    +
    151  memcpy(buf, kBlockGroupHeader, sizeof(kBlockGroupHeader));
    +
    152  UpdateUInt64(block_group_offset + kBlockGroupDurationOffset, duration);
    +
    153  UpdateUInt64(block_group_offset + kBlockGroupBlockSizeOffset, block_size);
    +
    154  buf += sizeof(kBlockGroupHeader);
    +
    155  } else {
    +
    156  memcpy(buf, kBlockGroupHeaderWithoutBlockDuration,
    +
    157  sizeof(kBlockGroupHeaderWithoutBlockDuration));
    +
    158  UpdateUInt64(
    +
    159  block_group_offset + kBlockGroupWithoutBlockDurationBlockSizeOffset,
    +
    160  block_size);
    +
    161  buf += sizeof(kBlockGroupHeaderWithoutBlockDuration);
    +
    162  }
    +
    163 
    +
    164  UpdateUInt64(block_group_offset + kBlockGroupSizeOffset, block_group_size);
    +
    165 
    +
    166  // Make sure the 4 most-significant bits are 0.
    +
    167  // http://www.matroska.org/technical/specs/index.html#block_structure
    +
    168  flags &= 0x0f;
    +
    169 
    +
    170  WriteBlock(buf, track_num, timecode, flags, data, size);
    +
    171  buf += size + 4;
    +
    172 
    +
    173  if (!is_key_frame)
    +
    174  memcpy(buf, kBlockGroupReferenceBlock, sizeof(kBlockGroupReferenceBlock));
    +
    175  bytes_used_ += bytes_needed;
    +
    176 }
    +
    177 
    +
    178 void ClusterBuilder::WriteBlock(uint8_t* buf,
    +
    179  int track_num,
    +
    180  int64_t timecode,
    +
    181  int flags,
    +
    182  const uint8_t* data,
    +
    183  int size) {
    +
    184  DCHECK_GE(track_num, 0);
    +
    185  DCHECK_LE(track_num, 126);
    +
    186  DCHECK_GE(flags, 0);
    +
    187  DCHECK_LE(flags, 0xff);
    +
    188  DCHECK(data);
    +
    189  DCHECK_GT(size, 0);
    +
    190  DCHECK_NE(cluster_timecode_, -1);
    +
    191 
    +
    192  int64_t timecode_delta = timecode - cluster_timecode_;
    +
    193  DCHECK_GE(timecode_delta, -32768);
    +
    194  DCHECK_LE(timecode_delta, 32767);
    +
    195 
    +
    196  buf[0] = 0x80 | (track_num & 0x7F);
    +
    197  buf[1] = (timecode_delta >> 8) & 0xff;
    +
    198  buf[2] = timecode_delta & 0xff;
    +
    199  buf[3] = flags & 0xff;
    +
    200  memcpy(buf + 4, data, size);
    +
    201 }
    +
    202 
    +
    203 std::unique_ptr<Cluster> ClusterBuilder::Finish() {
    +
    204  DCHECK_NE(cluster_timecode_, -1);
    +
    205 
    +
    206  UpdateUInt64(kClusterSizeOffset, bytes_used_ - (kClusterSizeOffset + 8));
    +
    207 
    +
    208  std::unique_ptr<Cluster> ret(new Cluster(std::move(buffer_), bytes_used_));
    +
    209  Reset();
    +
    210  return ret;
    +
    211 }
    +
    212 
    +
    213 std::unique_ptr<Cluster> ClusterBuilder::FinishWithUnknownSize() {
    +
    214  DCHECK_NE(cluster_timecode_, -1);
    +
    215 
    +
    216  UpdateUInt64(kClusterSizeOffset, kWebMUnknownSize);
    +
    217 
    +
    218  std::unique_ptr<Cluster> ret(new Cluster(std::move(buffer_), bytes_used_));
    +
    219  Reset();
    +
    220  return ret;
    +
    221 }
    +
    222 
    +
    223 void ClusterBuilder::Reset() {
    +
    224  buffer_size_ = kInitialBufferSize;
    +
    225  buffer_.reset(new uint8_t[buffer_size_]);
    +
    226  memcpy(buffer_.get(), kClusterHeader, sizeof(kClusterHeader));
    +
    227  bytes_used_ = sizeof(kClusterHeader);
    +
    228  cluster_timecode_ = -1;
    +
    229 }
    +
    230 
    +
    231 void ClusterBuilder::ExtendBuffer(int bytes_needed) {
    +
    232  int new_buffer_size = 2 * buffer_size_;
    +
    233 
    +
    234  while ((new_buffer_size - bytes_used_) < bytes_needed)
    +
    235  new_buffer_size *= 2;
    +
    236 
    +
    237  std::unique_ptr<uint8_t[]> new_buffer(new uint8_t[new_buffer_size]);
    +
    238 
    +
    239  memcpy(new_buffer.get(), buffer_.get(), bytes_used_);
    +
    240  buffer_.reset(new_buffer.release());
    +
    241  buffer_size_ = new_buffer_size;
    +
    242 }
    +
    243 
    +
    244 void ClusterBuilder::UpdateUInt64(int offset, int64_t value) {
    +
    245  DCHECK_LE(offset + 7, buffer_size_);
    +
    246  uint8_t* buf = buffer_.get() + offset;
    +
    247 
    +
    248  // Fill the last 7 bytes of size field in big-endian order.
    +
    249  for (int i = 7; i > 0; i--) {
    +
    250  buf[i] = value & 0xff;
    +
    251  value >>= 8;
    +
    252  }
    +
    253 }
    +
    254 
    +
    255 } // namespace media
    +
    256 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d1a/classshaka_1_1media_1_1wvm_1_1WvmMediaParser-members.html b/docs/de/d1a/classshaka_1_1media_1_1wvm_1_1WvmMediaParser-members.html index 6ca4a130b0..e8dc02e350 100644 --- a/docs/de/d1a/classshaka_1_1media_1_1wvm_1_1WvmMediaParser-members.html +++ b/docs/de/d1a/classshaka_1_1media_1_1wvm_1_1WvmMediaParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::wvm::WvmMediaParser, including all inherited members.

    - + - - - - - + + + + + +
    Flush() override WARN_UNUSED_RESULTshaka::media::wvm::WvmMediaParservirtual
    Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) overrideshaka::media::wvm::WvmMediaParservirtual
    Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) overrideshaka::media::wvm::WvmMediaParservirtual
    InitCB typedefshaka::media::MediaParser
    MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinline
    NewSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULTshaka::media::wvm::WvmMediaParservirtual
    WvmMediaParser() (defined in shaka::media::wvm::WvmMediaParser)shaka::media::wvm::WvmMediaParser
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    ~WvmMediaParser() override (defined in shaka::media::wvm::WvmMediaParser)shaka::media::wvm::WvmMediaParser
    NewMediaSampleCB typedefshaka::media::MediaParser
    NewTextSampleCB typedefshaka::media::MediaParser
    Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULTshaka::media::wvm::WvmMediaParservirtual
    WvmMediaParser() (defined in shaka::media::wvm::WvmMediaParser)shaka::media::wvm::WvmMediaParser
    ~MediaParser() (defined in shaka::media::MediaParser)shaka::media::MediaParserinlinevirtual
    ~WvmMediaParser() override (defined in shaka::media::wvm::WvmMediaParser)shaka::media::wvm::WvmMediaParser
    diff --git a/docs/de/d1a/structshaka_1_1media_1_1mp4_1_1KeyFrameInfo-members.html b/docs/de/d1a/structshaka_1_1media_1_1mp4_1_1KeyFrameInfo-members.html index fa00d5f74c..07c852c467 100644 --- a/docs/de/d1a/structshaka_1_1media_1_1mp4_1_1KeyFrameInfo-members.html +++ b/docs/de/d1a/structshaka_1_1media_1_1mp4_1_1KeyFrameInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/d1e/mp4_2single__segment__segmenter_8cc_source.html b/docs/de/d1e/mp4_2single__segment__segmenter_8cc_source.html index d9d5b2a3ce..b4390e83d8 100644 --- a/docs/de/d1e/mp4_2single__segment__segmenter_8cc_source.html +++ b/docs/de/d1e/mp4_2single__segment__segmenter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/single_segment_segmenter.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    single_segment_segmenter.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp4/single_segment_segmenter.h"
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/file/file.h"
    12 #include "packager/file/file_util.h"
    13 #include "packager/media/base/buffer_writer.h"
    14 #include "packager/media/base/muxer_options.h"
    15 #include "packager/media/event/progress_listener.h"
    16 #include "packager/media/formats/mp4/box_definitions.h"
    17 #include "packager/media/formats/mp4/key_frame_info.h"
    18 
    19 namespace shaka {
    20 namespace media {
    21 namespace mp4 {
    22 
    23 SingleSegmentSegmenter::SingleSegmentSegmenter(const MuxerOptions& options,
    24  std::unique_ptr<FileType> ftyp,
    25  std::unique_ptr<Movie> moov)
    26  : Segmenter(options, std::move(ftyp), std::move(moov)) {}
    27 
    28 SingleSegmentSegmenter::~SingleSegmentSegmenter() {
    29  if (temp_file_)
    30  temp_file_.release()->Close();
    31  if (!temp_file_name_.empty()) {
    32  if (!File::Delete(temp_file_name_.c_str()))
    33  LOG(ERROR) << "Unable to delete temporary file " << temp_file_name_;
    34  }
    35 }
    36 
    37 bool SingleSegmentSegmenter::GetInitRange(size_t* offset, size_t* size) {
    38  // In Finalize, ftyp and moov gets written first so offset must be 0.
    39  *offset = 0;
    40  *size = ftyp()->ComputeSize() + moov()->ComputeSize();
    41  return true;
    42 }
    43 
    44 bool SingleSegmentSegmenter::GetIndexRange(size_t* offset, size_t* size) {
    45  // Index range is right after init range so the offset must be the size of
    46  // ftyp and moov.
    47  *offset = ftyp()->ComputeSize() + moov()->ComputeSize();
    48  *size = vod_sidx_->ComputeSize();
    49  return true;
    50 }
    51 
    52 std::vector<Range> SingleSegmentSegmenter::GetSegmentRanges() {
    53  std::vector<Range> ranges;
    54  uint64_t next_offset =
    55  ftyp()->ComputeSize() + moov()->ComputeSize() + vod_sidx_->ComputeSize() +
    56  vod_sidx_->first_offset;
    57  for (const SegmentReference& segment_reference : vod_sidx_->references) {
    58  Range r;
    59  r.start = next_offset;
    60  // Ranges are inclusive, so -1 to the size.
    61  r.end = r.start + segment_reference.referenced_size - 1;
    62  next_offset = r.end + 1;
    63  ranges.push_back(r);
    64  }
    65  return ranges;
    66 }
    67 
    68 Status SingleSegmentSegmenter::DoInitialize() {
    69  // Single segment segmentation involves two stages:
    70  // Stage 1: Create media subsegments from media samples
    71  // Stage 2: Update media header (moov) which involves copying of media
    72  // subsegments
    73  // Assumes stage 2 takes similar amount of time as stage 1. The previous
    74  // progress_target was set for stage 1. Times two to account for stage 2.
    75  set_progress_target(progress_target() * 2);
    76 
    77  if (!TempFilePath(options().temp_dir, &temp_file_name_))
    78  return Status(error::FILE_FAILURE, "Unable to create temporary file.");
    79  temp_file_.reset(File::Open(temp_file_name_.c_str(), "w"));
    80  return temp_file_
    81  ? Status::OK
    82  : Status(error::FILE_FAILURE,
    83  "Cannot open file to write " + temp_file_name_);
    84 }
    85 
    86 Status SingleSegmentSegmenter::DoFinalize() {
    87  DCHECK(temp_file_);
    88  DCHECK(ftyp());
    89  DCHECK(moov());
    90  DCHECK(vod_sidx_);
    91 
    92  // Close the temp file to prepare for reading later.
    93  if (!temp_file_.release()->Close()) {
    94  return Status(
    95  error::FILE_FAILURE,
    96  "Cannot close the temp file " + temp_file_name_ +
    97  ", possibly file permission issue or running out of disk space.");
    98  }
    99 
    100  std::unique_ptr<File, FileCloser> file(
    101  File::Open(options().output_file_name.c_str(), "w"));
    102  if (file == NULL) {
    103  return Status(error::FILE_FAILURE,
    104  "Cannot open file to write " + options().output_file_name);
    105  }
    106 
    107  LOG(INFO) << "Update media header (moov) and rewrite the file to '"
    108  << options().output_file_name << "'.";
    109 
    110  // Write ftyp, moov and sidx to output file.
    111  std::unique_ptr<BufferWriter> buffer(new BufferWriter());
    112  ftyp()->Write(buffer.get());
    113  moov()->Write(buffer.get());
    114  vod_sidx_->Write(buffer.get());
    115  Status status = buffer->WriteToFile(file.get());
    116  if (!status.ok())
    117  return status;
    118 
    119  // Load the temp file and write to output file.
    120  std::unique_ptr<File, FileCloser> temp_file(
    121  File::Open(temp_file_name_.c_str(), "r"));
    122  if (temp_file == NULL) {
    123  return Status(error::FILE_FAILURE,
    124  "Cannot open file to read " + temp_file_name_);
    125  }
    126 
    127  // The target of 2nd stage of single segment segmentation.
    128  const uint64_t re_segment_progress_target = progress_target() * 0.5;
    129 
    130  const int kBufSize = 0x200000; // 2MB.
    131  std::unique_ptr<uint8_t[]> buf(new uint8_t[kBufSize]);
    132  while (true) {
    133  int64_t size = temp_file->Read(buf.get(), kBufSize);
    134  if (size == 0) {
    135  break;
    136  } else if (size < 0) {
    137  return Status(error::FILE_FAILURE,
    138  "Failed to read file " + temp_file_name_);
    139  }
    140  int64_t size_written = file->Write(buf.get(), size);
    141  if (size_written != size) {
    142  return Status(error::FILE_FAILURE,
    143  "Failed to write file " + options().output_file_name);
    144  }
    145  UpdateProgress(static_cast<double>(size) / temp_file->Size() *
    146  re_segment_progress_target);
    147  }
    148  if (!temp_file.release()->Close()) {
    149  return Status(error::FILE_FAILURE, "Cannot close the temp file " +
    150  temp_file_name_ + " after reading.");
    151  }
    152  if (!file.release()->Close()) {
    153  return Status(
    154  error::FILE_FAILURE,
    155  "Cannot close file " + options().output_file_name +
    156  ", possibly file permission issue or running out of disk space.");
    157  }
    158  SetComplete();
    159  return Status::OK;
    160 }
    161 
    162 Status SingleSegmentSegmenter::DoFinalizeSegment() {
    163  DCHECK(sidx());
    164  DCHECK(fragment_buffer());
    165  // sidx() contains pre-generated segment references with one reference per
    166  // fragment. In VOD, this segment is converted into a subsegment, i.e. one
    167  // reference, which contains all the fragments in sidx().
    168  std::vector<SegmentReference>& refs = sidx()->references;
    169  SegmentReference& vod_ref = refs[0];
    170  uint64_t first_sap_time =
    171  refs[0].sap_delta_time + refs[0].earliest_presentation_time;
    172  for (uint32_t i = 1; i < refs.size(); ++i) {
    173  vod_ref.referenced_size += refs[i].referenced_size;
    174  // NOTE: We calculate subsegment duration based on the total duration of
    175  // this subsegment instead of subtracting earliest_presentation_time as
    176  // indicated in the spec.
    177  vod_ref.subsegment_duration += refs[i].subsegment_duration;
    178  vod_ref.earliest_presentation_time = std::min(
    179  vod_ref.earliest_presentation_time, refs[i].earliest_presentation_time);
    180 
    181  if (vod_ref.sap_type == SegmentReference::TypeUnknown &&
    182  refs[i].sap_type != SegmentReference::TypeUnknown) {
    183  vod_ref.sap_type = refs[i].sap_type;
    184  first_sap_time =
    185  refs[i].sap_delta_time + refs[i].earliest_presentation_time;
    186  }
    187  }
    188  // Calculate sap delta time w.r.t. earliest_presentation_time.
    189  if (vod_ref.sap_type != SegmentReference::TypeUnknown) {
    190  vod_ref.sap_delta_time =
    191  first_sap_time - vod_ref.earliest_presentation_time;
    192  }
    193 
    194  // Create segment if it does not exist yet.
    195  if (vod_sidx_ == NULL) {
    196  vod_sidx_.reset(new SegmentIndex());
    197  vod_sidx_->reference_id = sidx()->reference_id;
    198  vod_sidx_->timescale = sidx()->timescale;
    199  vod_sidx_->earliest_presentation_time = vod_ref.earliest_presentation_time;
    200  }
    201  vod_sidx_->references.push_back(vod_ref);
    202 
    203  if (muxer_listener()) {
    204  for (const KeyFrameInfo& key_frame_info : key_frame_infos()) {
    205  // Unlike multisegment-segmenter, there is no (sub)segment header (styp,
    206  // sidx), so this is already the offset within the (sub)segment.
    207  muxer_listener()->OnKeyFrame(key_frame_info.timestamp,
    208  key_frame_info.start_byte_offset,
    209  key_frame_info.size);
    210  }
    211  }
    212  // Append fragment buffer to temp file.
    213  size_t segment_size = fragment_buffer()->Size();
    214  Status status = fragment_buffer()->WriteToFile(temp_file_.get());
    215  if (!status.ok()) return status;
    216 
    217  UpdateProgress(vod_ref.subsegment_duration);
    218  if (muxer_listener()) {
    219  muxer_listener()->OnSampleDurationReady(sample_duration());
    220  muxer_listener()->OnNewSegment(options().output_file_name,
    221  vod_ref.earliest_presentation_time,
    222  vod_ref.subsegment_duration, segment_size);
    223  }
    224  return Status::OK;
    225 }
    226 
    227 } // namespace mp4
    228 } // namespace media
    229 } // namespace shaka
    static bool Delete(const char *file_name)
    Definition: file.cc:198
    -
    virtual void OnSampleDurationReady(uint32_t sample_duration)=0
    - - -
    STL namespace.
    -
    bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
    Definition: file_util.cc:38
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    Tracks key frame information.
    - -
    virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
    -
    virtual bool Open()=0
    Internal open. Should not be used directly.
    - -
    void UpdateProgress(uint64_t progress)
    Update segmentation progress using ProgressListener.
    Definition: segmenter.cc:270
    -
    virtual void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp4/single_segment_segmenter.h"
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/file/file.h"
    +
    12 #include "packager/file/file_util.h"
    +
    13 #include "packager/media/base/buffer_writer.h"
    +
    14 #include "packager/media/base/muxer_options.h"
    +
    15 #include "packager/media/event/progress_listener.h"
    +
    16 #include "packager/media/formats/mp4/box_definitions.h"
    +
    17 #include "packager/media/formats/mp4/key_frame_info.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 namespace mp4 {
    +
    22 
    +
    23 SingleSegmentSegmenter::SingleSegmentSegmenter(const MuxerOptions& options,
    +
    24  std::unique_ptr<FileType> ftyp,
    +
    25  std::unique_ptr<Movie> moov)
    +
    26  : Segmenter(options, std::move(ftyp), std::move(moov)) {}
    +
    27 
    +
    28 SingleSegmentSegmenter::~SingleSegmentSegmenter() {
    +
    29  if (temp_file_)
    +
    30  temp_file_.release()->Close();
    +
    31  if (!temp_file_name_.empty()) {
    +
    32  if (!File::Delete(temp_file_name_.c_str()))
    +
    33  LOG(ERROR) << "Unable to delete temporary file " << temp_file_name_;
    +
    34  }
    +
    35 }
    +
    36 
    +
    37 bool SingleSegmentSegmenter::GetInitRange(size_t* offset, size_t* size) {
    +
    38  // In Finalize, ftyp and moov gets written first so offset must be 0.
    +
    39  *offset = 0;
    +
    40  *size = ftyp()->ComputeSize() + moov()->ComputeSize();
    +
    41  return true;
    +
    42 }
    +
    43 
    +
    44 bool SingleSegmentSegmenter::GetIndexRange(size_t* offset, size_t* size) {
    +
    45  // Index range is right after init range so the offset must be the size of
    +
    46  // ftyp and moov.
    +
    47  *offset = ftyp()->ComputeSize() + moov()->ComputeSize();
    +
    48  *size = options().mp4_params.generate_sidx_in_media_segments
    +
    49  ? vod_sidx_->ComputeSize()
    +
    50  : 0;
    +
    51  return true;
    +
    52 }
    +
    53 
    +
    54 std::vector<Range> SingleSegmentSegmenter::GetSegmentRanges() {
    +
    55  std::vector<Range> ranges;
    +
    56  uint64_t next_offset = ftyp()->ComputeSize() + moov()->ComputeSize() +
    +
    57  (options().mp4_params.generate_sidx_in_media_segments
    +
    58  ? vod_sidx_->ComputeSize()
    +
    59  : 0) +
    +
    60  vod_sidx_->first_offset;
    +
    61  for (const SegmentReference& segment_reference : vod_sidx_->references) {
    +
    62  Range r;
    +
    63  r.start = next_offset;
    +
    64  // Ranges are inclusive, so -1 to the size.
    +
    65  r.end = r.start + segment_reference.referenced_size - 1;
    +
    66  next_offset = r.end + 1;
    +
    67  ranges.push_back(r);
    +
    68  }
    +
    69  return ranges;
    +
    70 }
    +
    71 
    +
    72 Status SingleSegmentSegmenter::DoInitialize() {
    +
    73  // Single segment segmentation involves two stages:
    +
    74  // Stage 1: Create media subsegments from media samples
    +
    75  // Stage 2: Update media header (moov) which involves copying of media
    +
    76  // subsegments
    +
    77  // Assumes stage 2 takes similar amount of time as stage 1. The previous
    +
    78  // progress_target was set for stage 1. Times two to account for stage 2.
    +
    79  set_progress_target(progress_target() * 2);
    +
    80 
    +
    81  if (!TempFilePath(options().temp_dir, &temp_file_name_))
    +
    82  return Status(error::FILE_FAILURE, "Unable to create temporary file.");
    +
    83  temp_file_.reset(File::Open(temp_file_name_.c_str(), "w"));
    +
    84  return temp_file_
    +
    85  ? Status::OK
    +
    86  : Status(error::FILE_FAILURE,
    +
    87  "Cannot open file to write " + temp_file_name_);
    +
    88 }
    +
    89 
    +
    90 Status SingleSegmentSegmenter::DoFinalize() {
    +
    91  DCHECK(temp_file_);
    +
    92  DCHECK(ftyp());
    +
    93  DCHECK(moov());
    +
    94  DCHECK(vod_sidx_);
    +
    95 
    +
    96  // Close the temp file to prepare for reading later.
    +
    97  if (!temp_file_.release()->Close()) {
    +
    98  return Status(
    +
    99  error::FILE_FAILURE,
    +
    100  "Cannot close the temp file " + temp_file_name_ +
    +
    101  ", possibly file permission issue or running out of disk space.");
    +
    102  }
    +
    103 
    +
    104  std::unique_ptr<File, FileCloser> file(
    +
    105  File::Open(options().output_file_name.c_str(), "w"));
    +
    106  if (file == NULL) {
    +
    107  return Status(error::FILE_FAILURE,
    +
    108  "Cannot open file to write " + options().output_file_name);
    +
    109  }
    +
    110 
    +
    111  LOG(INFO) << "Update media header (moov) and rewrite the file to '"
    +
    112  << options().output_file_name << "'.";
    +
    113 
    +
    114  // Write ftyp, moov and sidx to output file.
    +
    115  std::unique_ptr<BufferWriter> buffer(new BufferWriter());
    +
    116  ftyp()->Write(buffer.get());
    +
    117  moov()->Write(buffer.get());
    +
    118 
    +
    119  if (options().mp4_params.generate_sidx_in_media_segments)
    +
    120  vod_sidx_->Write(buffer.get());
    +
    121 
    +
    122  Status status = buffer->WriteToFile(file.get());
    +
    123  if (!status.ok())
    +
    124  return status;
    +
    125 
    +
    126  // Load the temp file and write to output file.
    +
    127  std::unique_ptr<File, FileCloser> temp_file(
    +
    128  File::Open(temp_file_name_.c_str(), "r"));
    +
    129  if (temp_file == NULL) {
    +
    130  return Status(error::FILE_FAILURE,
    +
    131  "Cannot open file to read " + temp_file_name_);
    +
    132  }
    +
    133 
    +
    134  // The target of 2nd stage of single segment segmentation.
    +
    135  const uint64_t re_segment_progress_target = progress_target() * 0.5;
    +
    136 
    +
    137  const int kBufSize = 0x200000; // 2MB.
    +
    138  std::unique_ptr<uint8_t[]> buf(new uint8_t[kBufSize]);
    +
    139  while (true) {
    +
    140  int64_t size = temp_file->Read(buf.get(), kBufSize);
    +
    141  if (size == 0) {
    +
    142  break;
    +
    143  } else if (size < 0) {
    +
    144  return Status(error::FILE_FAILURE,
    +
    145  "Failed to read file " + temp_file_name_);
    +
    146  }
    +
    147  int64_t size_written = file->Write(buf.get(), size);
    +
    148  if (size_written != size) {
    +
    149  return Status(error::FILE_FAILURE,
    +
    150  "Failed to write file " + options().output_file_name);
    +
    151  }
    +
    152  UpdateProgress(static_cast<double>(size) / temp_file->Size() *
    +
    153  re_segment_progress_target);
    +
    154  }
    +
    155  if (!temp_file.release()->Close()) {
    +
    156  return Status(error::FILE_FAILURE, "Cannot close the temp file " +
    +
    157  temp_file_name_ + " after reading.");
    +
    158  }
    +
    159  if (!file.release()->Close()) {
    +
    160  return Status(
    +
    161  error::FILE_FAILURE,
    +
    162  "Cannot close file " + options().output_file_name +
    +
    163  ", possibly file permission issue or running out of disk space.");
    +
    164  }
    +
    165  SetComplete();
    +
    166  return Status::OK;
    +
    167 }
    +
    168 
    +
    169 Status SingleSegmentSegmenter::DoFinalizeSegment() {
    +
    170  DCHECK(sidx());
    +
    171  DCHECK(fragment_buffer());
    +
    172  // sidx() contains pre-generated segment references with one reference per
    +
    173  // fragment. In VOD, this segment is converted into a subsegment, i.e. one
    +
    174  // reference, which contains all the fragments in sidx().
    +
    175  std::vector<SegmentReference>& refs = sidx()->references;
    +
    176  SegmentReference& vod_ref = refs[0];
    +
    177  uint64_t first_sap_time =
    +
    178  refs[0].sap_delta_time + refs[0].earliest_presentation_time;
    +
    179  for (uint32_t i = 1; i < refs.size(); ++i) {
    +
    180  vod_ref.referenced_size += refs[i].referenced_size;
    +
    181  // NOTE: We calculate subsegment duration based on the total duration of
    +
    182  // this subsegment instead of subtracting earliest_presentation_time as
    +
    183  // indicated in the spec.
    +
    184  vod_ref.subsegment_duration += refs[i].subsegment_duration;
    +
    185  vod_ref.earliest_presentation_time = std::min(
    +
    186  vod_ref.earliest_presentation_time, refs[i].earliest_presentation_time);
    +
    187 
    +
    188  if (vod_ref.sap_type == SegmentReference::TypeUnknown &&
    +
    189  refs[i].sap_type != SegmentReference::TypeUnknown) {
    +
    190  vod_ref.sap_type = refs[i].sap_type;
    +
    191  first_sap_time =
    +
    192  refs[i].sap_delta_time + refs[i].earliest_presentation_time;
    +
    193  }
    +
    194  }
    +
    195  // Calculate sap delta time w.r.t. earliest_presentation_time.
    +
    196  if (vod_ref.sap_type != SegmentReference::TypeUnknown) {
    +
    197  vod_ref.sap_delta_time =
    +
    198  first_sap_time - vod_ref.earliest_presentation_time;
    +
    199  }
    +
    200 
    +
    201  // Create segment if it does not exist yet.
    +
    202  if (vod_sidx_ == NULL) {
    +
    203  vod_sidx_.reset(new SegmentIndex());
    +
    204  vod_sidx_->reference_id = sidx()->reference_id;
    +
    205  vod_sidx_->timescale = sidx()->timescale;
    +
    206  vod_sidx_->earliest_presentation_time = vod_ref.earliest_presentation_time;
    +
    207  }
    +
    208  vod_sidx_->references.push_back(vod_ref);
    +
    209 
    +
    210  if (muxer_listener()) {
    +
    211  for (const KeyFrameInfo& key_frame_info : key_frame_infos()) {
    +
    212  // Unlike multisegment-segmenter, there is no (sub)segment header (styp,
    +
    213  // sidx), so this is already the offset within the (sub)segment.
    +
    214  muxer_listener()->OnKeyFrame(key_frame_info.timestamp,
    +
    215  key_frame_info.start_byte_offset,
    +
    216  key_frame_info.size);
    +
    217  }
    +
    218  }
    +
    219  // Append fragment buffer to temp file.
    +
    220  size_t segment_size = fragment_buffer()->Size();
    +
    221  Status status = fragment_buffer()->WriteToFile(temp_file_.get());
    +
    222  if (!status.ok()) return status;
    +
    223 
    +
    224  UpdateProgress(vod_ref.subsegment_duration);
    +
    225  if (muxer_listener()) {
    +
    226  muxer_listener()->OnSampleDurationReady(sample_duration());
    +
    227  muxer_listener()->OnNewSegment(options().output_file_name,
    +
    228  vod_ref.earliest_presentation_time,
    +
    229  vod_ref.subsegment_duration, segment_size);
    +
    230  }
    +
    231  return Status::OK;
    +
    232 }
    +
    233 
    +
    234 } // namespace mp4
    +
    235 } // namespace media
    +
    236 } // namespace shaka
    + +
    All the methods that are virtual are virtual for mocking.
    +
    bool TempFilePath(const std::string &temp_dir, std::string *temp_file_path)
    Definition: file_util.cc:38
    + +
    diff --git a/docs/de/d22/aes__pattern__cryptor_8cc_source.html b/docs/de/d22/aes__pattern__cryptor_8cc_source.html index d4c4cd2676..6814d1ccff 100644 --- a/docs/de/d22/aes__pattern__cryptor_8cc_source.html +++ b/docs/de/d22/aes__pattern__cryptor_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/aes_pattern_cryptor.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    aes_pattern_cryptor.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/aes_pattern_cryptor.h"
    8 
    9 #include <openssl/aes.h>
    10 #include <algorithm>
    11 #include "packager/base/logging.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 AesPatternCryptor::AesPatternCryptor(uint8_t crypt_byte_block,
    17  uint8_t skip_byte_block,
    18  PatternEncryptionMode encryption_mode,
    19  ConstantIvFlag constant_iv_flag,
    20  std::unique_ptr<AesCryptor> cryptor)
    21  : AesCryptor(constant_iv_flag),
    22  crypt_byte_block_(crypt_byte_block),
    23  skip_byte_block_(skip_byte_block),
    24  encryption_mode_(encryption_mode),
    25  cryptor_(std::move(cryptor)) {
    26  // Treat pattern 0:0 as 1:0.
    27  if (crypt_byte_block_ == 0 && skip_byte_block_ == 0)
    28  crypt_byte_block_ = 1;
    29  DCHECK(cryptor_);
    30  DCHECK(!cryptor_->use_constant_iv());
    31 }
    32 
    33 AesPatternCryptor::~AesPatternCryptor() {}
    34 
    35 bool AesPatternCryptor::InitializeWithIv(const std::vector<uint8_t>& key,
    36  const std::vector<uint8_t>& iv) {
    37  return SetIv(iv) && cryptor_->InitializeWithIv(key, iv);
    38 }
    39 
    40 bool AesPatternCryptor::CryptInternal(const uint8_t* text,
    41  size_t text_size,
    42  uint8_t* crypt_text,
    43  size_t* crypt_text_size) {
    44  // |crypt_text_size| is always the same as |text_size| for pattern encryption.
    45  if (*crypt_text_size < text_size) {
    46  LOG(ERROR) << "Expecting output size of at least " << text_size
    47  << " bytes.";
    48  return false;
    49  }
    50  *crypt_text_size = text_size;
    51 
    52  while (text_size > 0) {
    53  const size_t crypt_byte_size = crypt_byte_block_ * AES_BLOCK_SIZE;
    54 
    55  if (text_size <= crypt_byte_size) {
    56  const bool need_encrypt =
    57  encryption_mode_ != kSkipIfCryptByteBlockRemaining &&
    58  text_size >= AES_BLOCK_SIZE;
    59  if (need_encrypt) {
    60  // The partial pattern SHALL be followed with the partial 16-byte block
    61  // remains unencrypted.
    62  const size_t aligned_crypt_byte_size =
    63  text_size / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
    64  if (!cryptor_->Crypt(text, aligned_crypt_byte_size, crypt_text))
    65  return false;
    66  text += aligned_crypt_byte_size;
    67  text_size -= aligned_crypt_byte_size;
    68  crypt_text += aligned_crypt_byte_size;
    69  }
    70 
    71  // The remaining bytes are not encrypted.
    72  memcpy(crypt_text, text, text_size);
    73  return true;
    74  }
    75 
    76  if (!cryptor_->Crypt(text, crypt_byte_size, crypt_text))
    77  return false;
    78  text += crypt_byte_size;
    79  text_size -= crypt_byte_size;
    80  crypt_text += crypt_byte_size;
    81 
    82  const size_t skip_byte_size = std::min(
    83  static_cast<size_t>(skip_byte_block_ * AES_BLOCK_SIZE), text_size);
    84  memcpy(crypt_text, text, skip_byte_size);
    85  text += skip_byte_size;
    86  text_size -= skip_byte_size;
    87  crypt_text += skip_byte_size;
    88  }
    89  return true;
    90 }
    91 
    92 void AesPatternCryptor::SetIvInternal() {
    93  CHECK(cryptor_->SetIv(iv()));
    94 }
    95 
    96 } // namespace media
    97 } // namespace shaka
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    - - -
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    - -
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    -
    bool SetIv(const std::vector< uint8_t > &iv)
    Definition: aes_cryptor.cc:70
    -
    AesPatternCryptor(uint8_t crypt_byte_block, uint8_t skip_byte_block, PatternEncryptionMode encryption_mode, ConstantIvFlag constant_iv_flag, std::unique_ptr< AesCryptor > cryptor)
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/aes_pattern_cryptor.h"
    +
    8 
    +
    9 #include <openssl/aes.h>
    +
    10 #include <algorithm>
    +
    11 #include "packager/base/logging.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 AesPatternCryptor::AesPatternCryptor(uint8_t crypt_byte_block,
    +
    17  uint8_t skip_byte_block,
    +
    18  PatternEncryptionMode encryption_mode,
    +
    19  ConstantIvFlag constant_iv_flag,
    +
    20  std::unique_ptr<AesCryptor> cryptor)
    +
    21  : AesCryptor(constant_iv_flag),
    +
    22  crypt_byte_block_(crypt_byte_block),
    +
    23  skip_byte_block_(skip_byte_block),
    +
    24  encryption_mode_(encryption_mode),
    +
    25  cryptor_(std::move(cryptor)) {
    +
    26  // Treat pattern 0:0 as 1:0.
    +
    27  if (crypt_byte_block_ == 0 && skip_byte_block_ == 0)
    +
    28  crypt_byte_block_ = 1;
    +
    29  DCHECK(cryptor_);
    +
    30  DCHECK(!cryptor_->use_constant_iv());
    +
    31 }
    +
    32 
    +
    33 AesPatternCryptor::~AesPatternCryptor() {}
    +
    34 
    +
    35 bool AesPatternCryptor::InitializeWithIv(const std::vector<uint8_t>& key,
    +
    36  const std::vector<uint8_t>& iv) {
    +
    37  return SetIv(iv) && cryptor_->InitializeWithIv(key, iv);
    +
    38 }
    +
    39 
    +
    40 bool AesPatternCryptor::CryptInternal(const uint8_t* text,
    +
    41  size_t text_size,
    +
    42  uint8_t* crypt_text,
    +
    43  size_t* crypt_text_size) {
    +
    44  // |crypt_text_size| is always the same as |text_size| for pattern encryption.
    +
    45  if (*crypt_text_size < text_size) {
    +
    46  LOG(ERROR) << "Expecting output size of at least " << text_size
    +
    47  << " bytes.";
    +
    48  return false;
    +
    49  }
    +
    50  *crypt_text_size = text_size;
    +
    51 
    +
    52  while (text_size > 0) {
    +
    53  const size_t crypt_byte_size = crypt_byte_block_ * AES_BLOCK_SIZE;
    +
    54 
    +
    55  if (text_size <= crypt_byte_size) {
    +
    56  const bool need_encrypt =
    +
    57  encryption_mode_ != kSkipIfCryptByteBlockRemaining &&
    +
    58  text_size >= AES_BLOCK_SIZE;
    +
    59  if (need_encrypt) {
    +
    60  // The partial pattern SHALL be followed with the partial 16-byte block
    +
    61  // remains unencrypted.
    +
    62  const size_t aligned_crypt_byte_size =
    +
    63  text_size / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
    +
    64  if (!cryptor_->Crypt(text, aligned_crypt_byte_size, crypt_text))
    +
    65  return false;
    +
    66  text += aligned_crypt_byte_size;
    +
    67  text_size -= aligned_crypt_byte_size;
    +
    68  crypt_text += aligned_crypt_byte_size;
    +
    69  }
    +
    70 
    +
    71  // The remaining bytes are not encrypted.
    +
    72  memcpy(crypt_text, text, text_size);
    +
    73  return true;
    +
    74  }
    +
    75 
    +
    76  if (!cryptor_->Crypt(text, crypt_byte_size, crypt_text))
    +
    77  return false;
    +
    78  text += crypt_byte_size;
    +
    79  text_size -= crypt_byte_size;
    +
    80  crypt_text += crypt_byte_size;
    +
    81 
    +
    82  const size_t skip_byte_size = std::min(
    +
    83  static_cast<size_t>(skip_byte_block_ * AES_BLOCK_SIZE), text_size);
    +
    84  memcpy(crypt_text, text, skip_byte_size);
    +
    85  text += skip_byte_size;
    +
    86  text_size -= skip_byte_size;
    +
    87  crypt_text += skip_byte_size;
    +
    88  }
    +
    89  return true;
    +
    90 }
    +
    91 
    +
    92 void AesPatternCryptor::SetIvInternal() {
    +
    93  CHECK(cryptor_->SetIv(iv()));
    +
    94 }
    +
    95 
    +
    96 } // namespace media
    +
    97 } // namespace shaka
    + +
    const std::vector< uint8_t > & iv() const
    Definition: aes_cryptor.h:82
    +
    bool SetIv(const std::vector< uint8_t > &iv)
    Definition: aes_cryptor.cc:70
    + + +
    AesPatternCryptor(uint8_t crypt_byte_block, uint8_t skip_byte_block, PatternEncryptionMode encryption_mode, ConstantIvFlag constant_iv_flag, std::unique_ptr< AesCryptor > cryptor)
    +
    bool InitializeWithIv(const std::vector< uint8_t > &key, const std::vector< uint8_t > &iv) override
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d26/classshaka_1_1media_1_1Id3Tag.html b/docs/de/d26/classshaka_1_1media_1_1Id3Tag.html index 5c1de00cd9..097def0ad0 100644 --- a/docs/de/d26/classshaka_1_1media_1_1Id3Tag.html +++ b/docs/de/d26/classshaka_1_1media_1_1Id3Tag.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::Id3Tag Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -

    Add a "Private Frame". See http://id3.org/id3v2.4.0-frames 4.27. contains the owner identifier. contains the data for this private frame.

    +

    Add a "Private Frame". See http://id3.org/id3v2.4.0-frames 4.27. @owner contains the owner identifier. @data contains the data for this private frame.

    Definition at line 49 of file id3_tag.cc.

    @@ -203,9 +206,7 @@ Public Member Functions
    diff --git a/docs/de/d27/es__parser__audio_8cc_source.html b/docs/de/d27/es__parser__audio_8cc_source.html index 2e6b3a34c1..dcd897785a 100644 --- a/docs/de/d27/es__parser__audio_8cc_source.html +++ b/docs/de/d27/es__parser__audio_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser_audio.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    es_parser_audio.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/mp2t/es_parser_audio.h"
    6 
    7 #include <stdint.h>
    8 
    9 #include <algorithm>
    10 #include <list>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/media/base/audio_timestamp_helper.h"
    15 #include "packager/media/base/bit_reader.h"
    16 #include "packager/media/base/media_sample.h"
    17 #include "packager/media/base/timestamp.h"
    18 #include "packager/media/formats/mp2t/ac3_header.h"
    19 #include "packager/media/formats/mp2t/adts_header.h"
    20 #include "packager/media/formats/mp2t/mp2t_common.h"
    21 #include "packager/media/formats/mp2t/ts_stream_type.h"
    22 
    23 namespace shaka {
    24 namespace media {
    25 namespace mp2t {
    26 
    27 // Look for a syncword.
    28 // |new_pos| returns
    29 // - either the byte position of the frame (if found)
    30 // - or the byte position of 1st byte that was not processed (if not found).
    31 // In every case, the returned value in |new_pos| is such that new_pos >= pos
    32 // |audio_header| is updated with the new audio frame info if a syncword is
    33 // found.
    34 // Return whether a syncword was found.
    35 static bool LookForSyncWord(const uint8_t* raw_es,
    36  int raw_es_size,
    37  int pos,
    38  int* new_pos,
    39  AudioHeader* audio_header) {
    40  DCHECK_GE(pos, 0);
    41  DCHECK_LE(pos, raw_es_size);
    42 
    43  const int max_offset =
    44  raw_es_size - static_cast<int>(audio_header->GetMinFrameSize());
    45  if (pos >= max_offset) {
    46  // Do not change the position if:
    47  // - max_offset < 0: not enough bytes to get a full header
    48  // Since pos >= 0, this is a subcase of the next condition.
    49  // - pos >= max_offset: might be the case after reading one full frame,
    50  // |pos| is then incremented by the frame size and might then point
    51  // to the end of the buffer.
    52  *new_pos = pos;
    53  return false;
    54  }
    55 
    56  for (int offset = pos; offset < max_offset; offset++) {
    57  const uint8_t* cur_buf = &raw_es[offset];
    58 
    59  if (!audio_header->IsSyncWord(cur_buf))
    60  continue;
    61 
    62  const size_t remaining_size = static_cast<size_t>(raw_es_size - offset);
    63  const int kSyncWordSize = 2;
    64  const size_t frame_size =
    65  audio_header->GetFrameSizeWithoutParsing(cur_buf, remaining_size);
    66  if (frame_size < audio_header->GetMinFrameSize())
    67  // Too short to be a valid frame.
    68  continue;
    69  if (remaining_size < frame_size)
    70  // Not a full frame: will resume when we have more data.
    71  return false;
    72  // Check whether there is another frame |size| apart from the current one.
    73  if (remaining_size >= frame_size + kSyncWordSize &&
    74  !audio_header->IsSyncWord(&cur_buf[frame_size])) {
    75  continue;
    76  }
    77 
    78  if (!audio_header->Parse(cur_buf, frame_size))
    79  continue;
    80 
    81  *new_pos = offset;
    82  return true;
    83  }
    84 
    85  *new_pos = max_offset;
    86  return false;
    87 }
    88 
    89 EsParserAudio::EsParserAudio(uint32_t pid,
    90  TsStreamType stream_type,
    91  const NewStreamInfoCB& new_stream_info_cb,
    92  const EmitSampleCB& emit_sample_cb,
    93  bool sbr_in_mimetype)
    94  : EsParser(pid),
    95  stream_type_(stream_type),
    96  new_stream_info_cb_(new_stream_info_cb),
    97  emit_sample_cb_(emit_sample_cb),
    98  sbr_in_mimetype_(sbr_in_mimetype) {
    99  if (stream_type == TsStreamType::kAc3) {
    100  audio_header_.reset(new Ac3Header);
    101  } else {
    102  DCHECK_EQ(stream_type, TsStreamType::kAdtsAac);
    103  audio_header_.reset(new AdtsHeader);
    104  }
    105 }
    106 
    107 EsParserAudio::~EsParserAudio() {}
    108 
    109 bool EsParserAudio::Parse(const uint8_t* buf,
    110  int size,
    111  int64_t pts,
    112  int64_t dts) {
    113  int raw_es_size;
    114  const uint8_t* raw_es;
    115 
    116  // The incoming PTS applies to the access unit that comes just after
    117  // the beginning of |buf|.
    118  if (pts != kNoTimestamp) {
    119  es_byte_queue_.Peek(&raw_es, &raw_es_size);
    120  pts_list_.push_back(EsPts(raw_es_size, pts));
    121  }
    122 
    123  // Copy the input data to the ES buffer.
    124  es_byte_queue_.Push(buf, static_cast<int>(size));
    125  es_byte_queue_.Peek(&raw_es, &raw_es_size);
    126 
    127  // Look for every frame in the ES buffer starting at offset = 0
    128  int es_position = 0;
    129  while (LookForSyncWord(raw_es, raw_es_size, es_position, &es_position,
    130  audio_header_.get())) {
    131  const uint8_t* frame_ptr = raw_es + es_position;
    132  DVLOG(LOG_LEVEL_ES) << "syncword @ pos=" << es_position
    133  << " frame_size=" << audio_header_->GetFrameSize();
    134  DVLOG(LOG_LEVEL_ES) << "header: "
    135  << base::HexEncode(frame_ptr,
    136  audio_header_->GetHeaderSize());
    137 
    138  // Do not process the frame if this one is a partial frame.
    139  int remaining_size = raw_es_size - es_position;
    140  if (static_cast<int>(audio_header_->GetFrameSize()) > remaining_size)
    141  break;
    142 
    143  // Update the audio configuration if needed.
    144  if (!UpdateAudioConfiguration(*audio_header_))
    145  return false;
    146 
    147  // Get the PTS & the duration of this access unit.
    148  while (!pts_list_.empty() && pts_list_.front().first <= es_position) {
    149  audio_timestamp_helper_->SetBaseTimestamp(pts_list_.front().second);
    150  pts_list_.pop_front();
    151  }
    152 
    153  int64_t current_pts = audio_timestamp_helper_->GetTimestamp();
    154  int64_t frame_duration = audio_timestamp_helper_->GetFrameDuration(
    155  audio_header_->GetSamplesPerFrame());
    156 
    157  // Emit an audio frame.
    158  bool is_key_frame = true;
    159 
    160  std::shared_ptr<MediaSample> sample = MediaSample::CopyFrom(
    161  frame_ptr + audio_header_->GetHeaderSize(),
    162  audio_header_->GetFrameSize() - audio_header_->GetHeaderSize(),
    163  is_key_frame);
    164  sample->set_pts(current_pts);
    165  sample->set_dts(current_pts);
    166  sample->set_duration(frame_duration);
    167  emit_sample_cb_.Run(pid(), sample);
    168 
    169  // Update the PTS of the next frame.
    170  audio_timestamp_helper_->AddFrames(audio_header_->GetSamplesPerFrame());
    171 
    172  // Skip the current frame.
    173  es_position += static_cast<int>(audio_header_->GetFrameSize());
    174  }
    175 
    176  // Discard all the bytes that have been processed.
    177  DiscardEs(es_position);
    178 
    179  return true;
    180 }
    181 
    182 void EsParserAudio::Flush() {}
    183 
    184 void EsParserAudio::Reset() {
    185  es_byte_queue_.Reset();
    186  pts_list_.clear();
    187  last_audio_decoder_config_ = std::shared_ptr<AudioStreamInfo>();
    188 }
    189 
    190 bool EsParserAudio::UpdateAudioConfiguration(const AudioHeader& audio_header) {
    191  const uint8_t kAacSampleSizeBits(16);
    192 
    193  std::vector<uint8_t> audio_specific_config;
    194  audio_header.GetAudioSpecificConfig(&audio_specific_config);
    195 
    196  if (last_audio_decoder_config_) {
    197  // Verify that the audio decoder config has not changed.
    198  if (last_audio_decoder_config_->codec_config() == audio_specific_config) {
    199  // Audio configuration has not changed.
    200  return true;
    201  }
    202  NOTIMPLEMENTED() << "Varying audio configurations are not supported.";
    203  return false;
    204  }
    205 
    206  // The following code is written according to ISO 14496 Part 3 Table 1.11 and
    207  // Table 1.22. (Table 1.11 refers to the capping to 48000, Table 1.22 refers
    208  // to SBR doubling the AAC sample rate.)
    209  int samples_per_second = audio_header.GetSamplingFrequency();
    210  // TODO(kqyang): Review if it makes sense to have |sbr_in_mimetype_| in
    211  // es_parser.
    212  int extended_samples_per_second =
    213  sbr_in_mimetype_ ? std::min(2 * samples_per_second, 48000)
    214  : samples_per_second;
    215 
    216  const Codec codec =
    217  stream_type_ == TsStreamType::kAc3 ? kCodecAC3 : kCodecAAC;
    218  last_audio_decoder_config_ = std::make_shared<AudioStreamInfo>(
    219  pid(), kMpeg2Timescale, kInfiniteDuration, codec,
    220  AudioStreamInfo::GetCodecString(codec, audio_header.GetObjectType()),
    221  audio_specific_config.data(), audio_specific_config.size(),
    222  kAacSampleSizeBits, audio_header.GetNumChannels(),
    223  extended_samples_per_second, 0 /* seek preroll */, 0 /* codec delay */,
    224  0 /* max bitrate */, 0 /* avg bitrate */, std::string(), false);
    225 
    226  DVLOG(1) << "Sampling frequency: " << samples_per_second;
    227  DVLOG(1) << "Extended sampling frequency: " << extended_samples_per_second;
    228  DVLOG(1) << "Channel config: "
    229  << static_cast<int>(audio_header.GetNumChannels());
    230  DVLOG(1) << "Object type: " << static_cast<int>(audio_header.GetObjectType());
    231  // Reset the timestamp helper to use a new sampling frequency.
    232  if (audio_timestamp_helper_) {
    233  int64_t base_timestamp = audio_timestamp_helper_->GetTimestamp();
    234  audio_timestamp_helper_.reset(
    235  new AudioTimestampHelper(kMpeg2Timescale, samples_per_second));
    236  audio_timestamp_helper_->SetBaseTimestamp(base_timestamp);
    237  } else {
    238  audio_timestamp_helper_.reset(
    239  new AudioTimestampHelper(kMpeg2Timescale, extended_samples_per_second));
    240  }
    241 
    242  // Audio config notification.
    243  new_stream_info_cb_.Run(last_audio_decoder_config_);
    244 
    245  return true;
    246 }
    247 
    248 void EsParserAudio::DiscardEs(int nbytes) {
    249  DCHECK_GE(nbytes, 0);
    250  if (nbytes <= 0)
    251  return;
    252 
    253  // Adjust the ES position of each PTS.
    254  for (EsPtsList::iterator it = pts_list_.begin(); it != pts_list_.end(); ++it)
    255  it->first -= nbytes;
    256 
    257  // Discard |nbytes| of ES.
    258  es_byte_queue_.Pop(nbytes);
    259 }
    260 
    261 } // namespace mp2t
    262 } // namespace media
    263 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    -
    static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
    -
    static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
    Definition: media_sample.cc:42
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/mp2t/es_parser_audio.h"
    +
    6 
    +
    7 #include <stdint.h>
    +
    8 
    +
    9 #include <algorithm>
    +
    10 #include <list>
    +
    11 
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/base/strings/string_number_conversions.h"
    +
    14 #include "packager/media/base/audio_timestamp_helper.h"
    +
    15 #include "packager/media/base/bit_reader.h"
    +
    16 #include "packager/media/base/media_sample.h"
    +
    17 #include "packager/media/base/timestamp.h"
    +
    18 #include "packager/media/formats/mp2t/ac3_header.h"
    +
    19 #include "packager/media/formats/mp2t/adts_header.h"
    +
    20 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    21 #include "packager/media/formats/mp2t/mpeg1_header.h"
    +
    22 #include "packager/media/formats/mp2t/ts_stream_type.h"
    +
    23 
    +
    24 namespace shaka {
    +
    25 namespace media {
    +
    26 namespace mp2t {
    +
    27 
    +
    28 // Look for a syncword.
    +
    29 // |new_pos| returns
    +
    30 // - either the byte position of the frame (if found)
    +
    31 // - or the byte position of 1st byte that was not processed (if not found).
    +
    32 // In every case, the returned value in |new_pos| is such that new_pos >= pos
    +
    33 // |audio_header| is updated with the new audio frame info if a syncword is
    +
    34 // found.
    +
    35 // Return whether a syncword was found.
    +
    36 static bool LookForSyncWord(const uint8_t* raw_es,
    +
    37  int raw_es_size,
    +
    38  int pos,
    +
    39  int* new_pos,
    +
    40  AudioHeader* audio_header) {
    +
    41  DCHECK_GE(pos, 0);
    +
    42  DCHECK_LE(pos, raw_es_size);
    +
    43 
    +
    44  const int max_offset =
    +
    45  raw_es_size - static_cast<int>(audio_header->GetMinFrameSize());
    +
    46  if (pos >= max_offset) {
    +
    47  // Do not change the position if:
    +
    48  // - max_offset < 0: not enough bytes to get a full header
    +
    49  // Since pos >= 0, this is a subcase of the next condition.
    +
    50  // - pos >= max_offset: might be the case after reading one full frame,
    +
    51  // |pos| is then incremented by the frame size and might then point
    +
    52  // to the end of the buffer.
    +
    53  *new_pos = pos;
    +
    54  return false;
    +
    55  }
    +
    56 
    +
    57  for (int offset = pos; offset < max_offset; offset++) {
    +
    58  const uint8_t* cur_buf = &raw_es[offset];
    +
    59 
    +
    60  if (!audio_header->IsSyncWord(cur_buf))
    +
    61  continue;
    +
    62 
    +
    63  const size_t remaining_size = static_cast<size_t>(raw_es_size - offset);
    +
    64  const int kSyncWordSize = 2;
    +
    65  const size_t frame_size =
    +
    66  audio_header->GetFrameSizeWithoutParsing(cur_buf, remaining_size);
    +
    67  if (frame_size < audio_header->GetMinFrameSize())
    +
    68  // Too short to be a valid frame.
    +
    69  continue;
    +
    70  if (remaining_size < frame_size)
    +
    71  // Not a full frame: will resume when we have more data.
    +
    72  return false;
    +
    73  // Check whether there is another frame |size| apart from the current one.
    +
    74  if (remaining_size >= frame_size + kSyncWordSize &&
    +
    75  !audio_header->IsSyncWord(&cur_buf[frame_size])) {
    +
    76  continue;
    +
    77  }
    +
    78 
    +
    79  if (!audio_header->Parse(cur_buf, frame_size))
    +
    80  continue;
    +
    81 
    +
    82  *new_pos = offset;
    +
    83  return true;
    +
    84  }
    +
    85 
    +
    86  *new_pos = max_offset;
    +
    87  return false;
    +
    88 }
    +
    89 
    +
    90 EsParserAudio::EsParserAudio(uint32_t pid,
    +
    91  TsStreamType stream_type,
    +
    92  const NewStreamInfoCB& new_stream_info_cb,
    +
    93  const EmitSampleCB& emit_sample_cb,
    +
    94  bool sbr_in_mimetype)
    +
    95  : EsParser(pid),
    +
    96  stream_type_(stream_type),
    +
    97  new_stream_info_cb_(new_stream_info_cb),
    +
    98  emit_sample_cb_(emit_sample_cb),
    +
    99  sbr_in_mimetype_(sbr_in_mimetype) {
    +
    100  if (stream_type == TsStreamType::kAc3) {
    +
    101  audio_header_.reset(new Ac3Header);
    +
    102  } else if (stream_type == TsStreamType::kMpeg1Audio) {
    +
    103  audio_header_.reset(new Mpeg1Header);
    +
    104  } else {
    +
    105  DCHECK_EQ(stream_type, TsStreamType::kAdtsAac);
    +
    106  audio_header_.reset(new AdtsHeader);
    +
    107  }
    +
    108 }
    +
    109 
    +
    110 EsParserAudio::~EsParserAudio() {}
    +
    111 
    +
    112 bool EsParserAudio::Parse(const uint8_t* buf,
    +
    113  int size,
    +
    114  int64_t pts,
    +
    115  int64_t dts) {
    +
    116  int raw_es_size;
    +
    117  const uint8_t* raw_es;
    +
    118 
    +
    119  // The incoming PTS applies to the access unit that comes just after
    +
    120  // the beginning of |buf|.
    +
    121  if (pts != kNoTimestamp) {
    +
    122  es_byte_queue_.Peek(&raw_es, &raw_es_size);
    +
    123  pts_list_.push_back(EsPts(raw_es_size, pts));
    +
    124  }
    +
    125 
    +
    126  // Copy the input data to the ES buffer.
    +
    127  es_byte_queue_.Push(buf, static_cast<int>(size));
    +
    128  es_byte_queue_.Peek(&raw_es, &raw_es_size);
    +
    129 
    +
    130  // Look for every frame in the ES buffer starting at offset = 0
    +
    131  int es_position = 0;
    +
    132  while (LookForSyncWord(raw_es, raw_es_size, es_position, &es_position,
    +
    133  audio_header_.get())) {
    +
    134  const uint8_t* frame_ptr = raw_es + es_position;
    +
    135  DVLOG(LOG_LEVEL_ES) << "syncword @ pos=" << es_position
    +
    136  << " frame_size=" << audio_header_->GetFrameSize();
    +
    137  DVLOG(LOG_LEVEL_ES) << "header: "
    +
    138  << base::HexEncode(frame_ptr,
    +
    139  audio_header_->GetHeaderSize());
    +
    140 
    +
    141  // Do not process the frame if this one is a partial frame.
    +
    142  int remaining_size = raw_es_size - es_position;
    +
    143  if (static_cast<int>(audio_header_->GetFrameSize()) > remaining_size)
    +
    144  break;
    +
    145 
    +
    146  // Update the audio configuration if needed.
    +
    147  if (!UpdateAudioConfiguration(*audio_header_))
    +
    148  return false;
    +
    149 
    +
    150  // Get the PTS & the duration of this access unit.
    +
    151  while (!pts_list_.empty() && pts_list_.front().first <= es_position) {
    +
    152  audio_timestamp_helper_->SetBaseTimestamp(pts_list_.front().second);
    +
    153  pts_list_.pop_front();
    +
    154  }
    +
    155 
    +
    156  int64_t current_pts = audio_timestamp_helper_->GetTimestamp();
    +
    157  int64_t frame_duration = audio_timestamp_helper_->GetFrameDuration(
    +
    158  audio_header_->GetSamplesPerFrame());
    +
    159 
    +
    160  // Emit an audio frame.
    +
    161  bool is_key_frame = true;
    +
    162 
    +
    163  std::shared_ptr<MediaSample> sample = MediaSample::CopyFrom(
    +
    164  frame_ptr + audio_header_->GetHeaderSize(),
    +
    165  audio_header_->GetFrameSize() - audio_header_->GetHeaderSize(),
    +
    166  is_key_frame);
    +
    167  sample->set_pts(current_pts);
    +
    168  sample->set_dts(current_pts);
    +
    169  sample->set_duration(frame_duration);
    +
    170  emit_sample_cb_.Run(sample);
    +
    171 
    +
    172  // Update the PTS of the next frame.
    +
    173  audio_timestamp_helper_->AddFrames(audio_header_->GetSamplesPerFrame());
    +
    174 
    +
    175  // Skip the current frame.
    +
    176  es_position += static_cast<int>(audio_header_->GetFrameSize());
    +
    177  }
    +
    178 
    +
    179  // Discard all the bytes that have been processed.
    +
    180  DiscardEs(es_position);
    +
    181 
    +
    182  return true;
    +
    183 }
    +
    184 
    +
    185 bool EsParserAudio::Flush() {
    +
    186  return true;
    +
    187 }
    +
    188 
    +
    189 void EsParserAudio::Reset() {
    +
    190  es_byte_queue_.Reset();
    +
    191  pts_list_.clear();
    +
    192  last_audio_decoder_config_ = std::shared_ptr<AudioStreamInfo>();
    +
    193 }
    +
    194 
    +
    195 bool EsParserAudio::UpdateAudioConfiguration(const AudioHeader& audio_header) {
    +
    196  const uint8_t kAacSampleSizeBits(16);
    +
    197 
    +
    198  std::vector<uint8_t> audio_specific_config;
    +
    199  audio_header.GetAudioSpecificConfig(&audio_specific_config);
    +
    200 
    +
    201  if (last_audio_decoder_config_) {
    +
    202  // Verify that the audio decoder config has not changed.
    +
    203  if (last_audio_decoder_config_->codec_config() == audio_specific_config) {
    +
    204  // Audio configuration has not changed.
    +
    205  return true;
    +
    206  }
    +
    207  NOTIMPLEMENTED() << "Varying audio configurations are not supported.";
    +
    208  return false;
    +
    209  }
    +
    210 
    +
    211  // The following code is written according to ISO 14496 Part 3 Table 1.11 and
    +
    212  // Table 1.22. (Table 1.11 refers to the capping to 48000, Table 1.22 refers
    +
    213  // to SBR doubling the AAC sample rate.)
    +
    214  int samples_per_second = audio_header.GetSamplingFrequency();
    +
    215  // TODO(kqyang): Review if it makes sense to have |sbr_in_mimetype_| in
    +
    216  // es_parser.
    +
    217  int extended_samples_per_second =
    +
    218  sbr_in_mimetype_ ? std::min(2 * samples_per_second, 48000)
    +
    219  : samples_per_second;
    +
    220 
    +
    221  const Codec codec =
    +
    222  stream_type_ == TsStreamType::kAc3
    +
    223  ? kCodecAC3
    +
    224  : (stream_type_ == TsStreamType::kMpeg1Audio ? kCodecMP3 : kCodecAAC);
    +
    225  last_audio_decoder_config_ = std::make_shared<AudioStreamInfo>(
    +
    226  pid(), kMpeg2Timescale, kInfiniteDuration, codec,
    +
    227  AudioStreamInfo::GetCodecString(codec, audio_header.GetObjectType()),
    +
    228  audio_specific_config.data(), audio_specific_config.size(),
    +
    229  kAacSampleSizeBits, audio_header.GetNumChannels(),
    +
    230  extended_samples_per_second, 0 /* seek preroll */, 0 /* codec delay */,
    +
    231  0 /* max bitrate */, 0 /* avg bitrate */, std::string(), false);
    +
    232 
    +
    233  DVLOG(1) << "Sampling frequency: " << samples_per_second;
    +
    234  DVLOG(1) << "Extended sampling frequency: " << extended_samples_per_second;
    +
    235  DVLOG(1) << "Channel config: "
    +
    236  << static_cast<int>(audio_header.GetNumChannels());
    +
    237  DVLOG(1) << "Object type: " << static_cast<int>(audio_header.GetObjectType());
    +
    238  // Reset the timestamp helper to use a new sampling frequency.
    +
    239  if (audio_timestamp_helper_) {
    +
    240  int64_t base_timestamp = audio_timestamp_helper_->GetTimestamp();
    +
    241  audio_timestamp_helper_.reset(
    +
    242  new AudioTimestampHelper(kMpeg2Timescale, samples_per_second));
    +
    243  audio_timestamp_helper_->SetBaseTimestamp(base_timestamp);
    +
    244  } else {
    +
    245  audio_timestamp_helper_.reset(
    +
    246  new AudioTimestampHelper(kMpeg2Timescale, extended_samples_per_second));
    +
    247  }
    +
    248 
    +
    249  // Audio config notification.
    +
    250  new_stream_info_cb_.Run(last_audio_decoder_config_);
    +
    251 
    +
    252  return true;
    +
    253 }
    +
    254 
    +
    255 void EsParserAudio::DiscardEs(int nbytes) {
    +
    256  DCHECK_GE(nbytes, 0);
    +
    257  if (nbytes <= 0)
    +
    258  return;
    +
    259 
    +
    260  // Adjust the ES position of each PTS.
    +
    261  for (EsPtsList::iterator it = pts_list_.begin(); it != pts_list_.end(); ++it)
    +
    262  it->first -= nbytes;
    +
    263 
    +
    264  // Discard |nbytes| of ES.
    +
    265  es_byte_queue_.Pop(nbytes);
    +
    266 }
    +
    267 
    +
    268 } // namespace mp2t
    +
    269 } // namespace media
    +
    270 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d29/es__parser__dvb_8cc_source.html b/docs/de/d29/es__parser__dvb_8cc_source.html new file mode 100644 index 0000000000..9226399126 --- /dev/null +++ b/docs/de/d29/es__parser__dvb_8cc_source.html @@ -0,0 +1,219 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/mp2t/es_parser_dvb.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    es_parser_dvb.cc
    +
    +
    +
    1 // Copyright 2020 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/es_parser_dvb.h"
    +
    8 
    +
    9 #include "packager/media/base/bit_reader.h"
    +
    10 #include "packager/media/base/text_stream_info.h"
    +
    11 #include "packager/media/base/timestamp.h"
    +
    12 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 namespace mp2t {
    +
    17 
    +
    18 namespace {
    +
    19 
    +
    20 bool ParseSubtitlingDescriptor(
    +
    21  const uint8_t* descriptor,
    +
    22  size_t size,
    +
    23  std::unordered_map<uint16_t, std::string>* langs) {
    +
    24  // See ETSI EN 300 468 Section 6.2.41.
    +
    25  BitReader reader(descriptor, size);
    +
    26  size_t data_size;
    +
    27  RCHECK(reader.SkipBits(8)); // descriptor_tag
    +
    28  RCHECK(reader.ReadBits(8, &data_size));
    +
    29  RCHECK(data_size + 2 <= size);
    +
    30  for (size_t i = 0; i < data_size; i += 8) {
    +
    31  uint32_t lang_code;
    +
    32  uint16_t page;
    +
    33  RCHECK(reader.ReadBits(24, &lang_code));
    +
    34  RCHECK(reader.SkipBits(8)); // subtitling_type
    +
    35  RCHECK(reader.ReadBits(16, &page));
    +
    36  RCHECK(reader.SkipBits(16)); // ancillary_page_id
    +
    37 
    +
    38  // The lang code is a ISO 639-2 code coded in Latin-1.
    +
    39  std::string lang(3, '\0');
    +
    40  lang[0] = (lang_code >> 16) & 0xff;
    +
    41  lang[1] = (lang_code >> 8) & 0xff;
    +
    42  lang[2] = (lang_code >> 0) & 0xff;
    +
    43  langs->emplace(page, std::move(lang));
    +
    44  }
    +
    45  return true;
    +
    46 }
    +
    47 
    +
    48 } // namespace
    +
    49 
    +
    50 EsParserDvb::EsParserDvb(uint32_t pid,
    +
    51  const NewStreamInfoCB& new_stream_info_cb,
    +
    52  const EmitTextSampleCB& emit_sample_cb,
    +
    53  const uint8_t* descriptor,
    +
    54  size_t descriptor_length)
    +
    55  : EsParser(pid),
    +
    56  new_stream_info_cb_(new_stream_info_cb),
    +
    57  emit_sample_cb_(emit_sample_cb) {
    +
    58  if (!ParseSubtitlingDescriptor(descriptor, descriptor_length, &languages_)) {
    +
    59  LOG(WARNING) << "Error parsing subtitling descriptor";
    +
    60  }
    +
    61 }
    +
    62 
    +
    63 EsParserDvb::~EsParserDvb() {}
    +
    64 
    +
    65 bool EsParserDvb::Parse(const uint8_t* buf,
    +
    66  int size,
    +
    67  int64_t pts,
    +
    68  int64_t dts) {
    +
    69  if (!sent_info_) {
    +
    70  sent_info_ = true;
    +
    71  std::shared_ptr<TextStreamInfo> info = std::make_shared<TextStreamInfo>(
    +
    72  pid(), kMpeg2Timescale, kInfiniteDuration, kCodecText,
    +
    73  /* codec_string= */ "", /* codec_config= */ "", /* width= */ 0,
    +
    74  /* height= */ 0, /* language= */ "");
    +
    75  for (const auto& pair : languages_) {
    +
    76  info->AddSubStream(pair.first, {pair.second});
    +
    77  }
    +
    78 
    +
    79  new_stream_info_cb_.Run(info);
    +
    80  }
    +
    81 
    +
    82  // TODO: Handle buffering and multiple reads? All content so far has been
    +
    83  // a whole segment, so it may not be needed.
    +
    84  return ParseInternal(buf, size, pts);
    +
    85 }
    +
    86 
    +
    87 bool EsParserDvb::Flush() {
    +
    88  for (auto& pair : parsers_) {
    +
    89  std::vector<std::shared_ptr<TextSample>> samples;
    +
    90  RCHECK(pair.second.Flush(&samples));
    +
    91 
    +
    92  for (auto sample : samples) {
    +
    93  sample->set_sub_stream_index(pair.first);
    +
    94  emit_sample_cb_.Run(sample);
    +
    95  }
    +
    96  }
    +
    97  return true;
    +
    98 }
    +
    99 
    +
    100 void EsParserDvb::Reset() {
    +
    101  parsers_.clear();
    +
    102 }
    +
    103 
    +
    104 bool EsParserDvb::ParseInternal(const uint8_t* data, size_t size, int64_t pts) {
    +
    105  // See EN 300 743 Table 3.
    +
    106  BitReader reader(data, size);
    +
    107  int data_identifier;
    +
    108  int subtitle_stream_id;
    +
    109  RCHECK(reader.ReadBits(8, &data_identifier));
    +
    110  RCHECK(reader.ReadBits(8, &subtitle_stream_id));
    +
    111  RCHECK(data_identifier == 0x20);
    +
    112  RCHECK(subtitle_stream_id == 0);
    +
    113 
    +
    114  int temp;
    +
    115  while (reader.ReadBits(8, &temp) && temp == 0xf) {
    +
    116  DvbSubSegmentType segment_type;
    +
    117  uint16_t page_id;
    +
    118  size_t segment_length;
    +
    119  RCHECK(reader.ReadBits(8, &segment_type));
    +
    120  RCHECK(reader.ReadBits(16, &page_id));
    +
    121  RCHECK(reader.ReadBits(16, &segment_length));
    +
    122  RCHECK(reader.bits_available() > segment_length * 8);
    +
    123 
    +
    124  const uint8_t* payload = data + (size - reader.bits_available() / 8);
    +
    125  std::vector<std::shared_ptr<TextSample>> samples;
    +
    126  RCHECK(parsers_[page_id].Parse(segment_type, pts, payload, segment_length,
    +
    127  &samples));
    +
    128  for (auto sample : samples) {
    +
    129  sample->set_sub_stream_index(page_id);
    +
    130  emit_sample_cb_.Run(sample);
    +
    131  }
    +
    132 
    +
    133  RCHECK(reader.SkipBytes(segment_length));
    +
    134  }
    +
    135  return temp == 0xff;
    +
    136 }
    +
    137 
    +
    138 } // namespace mp2t
    +
    139 } // namespace media
    +
    140 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/de/d29/structshaka_1_1media_1_1mp4_1_1TrackExtends.html b/docs/de/d29/structshaka_1_1media_1_1mp4_1_1TrackExtends.html index 83b91493ac..5d04288e9c 100644 --- a/docs/de/d29/structshaka_1_1media_1_1mp4_1_1TrackExtends.html +++ b/docs/de/d29/structshaka_1_1media_1_1mp4_1_1TrackExtends.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TrackExtends Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -133,7 +136,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 650 of file box_definitions.h.

    +

    Definition at line 668 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -161,7 +164,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2257 of file box_definitions.cc.

    +

    Definition at line 2338 of file box_definitions.cc.

    @@ -172,9 +175,7 @@ Additional Inherited Members diff --git a/docs/de/d33/classshaka_1_1media_1_1WebMTracksParser-members.html b/docs/de/d33/classshaka_1_1media_1_1WebMTracksParser-members.html index 92ce88bab7..1db972c846 100644 --- a/docs/de/d33/classshaka_1_1media_1_1WebMTracksParser-members.html +++ b/docs/de/d33/classshaka_1_1media_1_1WebMTracksParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/d33/structshaka_1_1media_1_1H265Pps.html b/docs/de/d33/structshaka_1_1media_1_1H265Pps.html index dd45f7fd3d..45d0f03bb1 100644 --- a/docs/de/d33/structshaka_1_1media_1_1H265Pps.html +++ b/docs/de/d33/structshaka_1_1media_1_1H265Pps.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265Pps Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    chroma_qp_offset_list
    diff --git a/docs/de/d34/offset__byte__queue_8h_source.html b/docs/de/d34/offset__byte__queue_8h_source.html index ec9a926533..c9ccdb24cb 100644 --- a/docs/de/d34/offset__byte__queue_8h_source.html +++ b/docs/de/d34/offset__byte__queue_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/offset_byte_queue.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    offset_byte_queue.h
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_BASE_OFFSET_BYTE_QUEUE_H_
    6 #define PACKAGER_MEDIA_BASE_OFFSET_BYTE_QUEUE_H_
    7 
    8 #include <stdint.h>
    9 
    10 #include "packager/media/base/byte_queue.h"
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    20  public:
    22  ~OffsetByteQueue();
    23 
    26  void Reset();
    27  void Push(const uint8_t* buf, int size);
    28  void Peek(const uint8_t** buf, int* size);
    29  void Pop(int count);
    31 
    38  void PeekAt(int64_t offset, const uint8_t** buf, int* size);
    39 
    49  bool Trim(int64_t max_offset);
    50 
    52  int64_t head() { return head_; }
    55  int64_t tail() { return head_ + size_; }
    56 
    57  private:
    58  // Synchronize |buf_| and |size_| with |queue_|.
    59  void Sync();
    60 
    61  ByteQueue queue_;
    62  const uint8_t* buf_;
    63  int size_;
    64  int64_t head_;
    65 
    66  DISALLOW_COPY_AND_ASSIGN(OffsetByteQueue);
    67 };
    68 
    69 } // namespace media
    70 } // namespace shaka
    71 
    72 #endif // PACKAGER_MEDIA_BASE_OFFSET_BYTE_QUEUE_H_
    -
    void PeekAt(int64_t offset, const uint8_t **buf, int *size)
    - -
    bool Trim(int64_t max_offset)
    -
    All the methods that are virtual are virtual for mocking.
    - - +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_BASE_OFFSET_BYTE_QUEUE_H_
    +
    6 #define PACKAGER_MEDIA_BASE_OFFSET_BYTE_QUEUE_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 
    +
    10 #include "packager/media/base/byte_queue.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    + +
    20  public:
    + +
    22  ~OffsetByteQueue();
    +
    23 
    +
    26  void Reset();
    +
    27  void Push(const uint8_t* buf, int size);
    +
    28  void Peek(const uint8_t** buf, int* size);
    +
    29  void Pop(int count);
    +
    31 
    +
    38  void PeekAt(int64_t offset, const uint8_t** buf, int* size);
    +
    39 
    +
    49  bool Trim(int64_t max_offset);
    +
    50 
    +
    52  int64_t head() { return head_; }
    +
    55  int64_t tail() { return head_ + size_; }
    +
    56 
    +
    57  private:
    +
    58  // Synchronize |buf_| and |size_| with |queue_|.
    +
    59  void Sync();
    +
    60 
    +
    61  ByteQueue queue_;
    +
    62  const uint8_t* buf_;
    +
    63  int size_;
    +
    64  int64_t head_;
    +
    65 
    +
    66  DISALLOW_COPY_AND_ASSIGN(OffsetByteQueue);
    +
    67 };
    +
    68 
    +
    69 } // namespace media
    +
    70 } // namespace shaka
    +
    71 
    +
    72 #endif // PACKAGER_MEDIA_BASE_OFFSET_BYTE_QUEUE_H_
    + + + +
    void PeekAt(int64_t offset, const uint8_t **buf, int *size)
    +
    bool Trim(int64_t max_offset)
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d39/id3__tag_8cc_source.html b/docs/de/d39/id3__tag_8cc_source.html index 99c6801f2e..08de68061c 100644 --- a/docs/de/d39/id3__tag_8cc_source.html +++ b/docs/de/d39/id3__tag_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/id3_tag.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    id3_tag.cc
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/id3_tag.h"
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/media/base/buffer_writer.h"
    11 #include "packager/media/base/fourccs.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 namespace {
    16 
    17 // ID3v2 header: http://id3.org/id3v2.4.0-structure.
    18 const char kID3v2Identifier[] = "ID3";
    19 const uint16_t kID3v2Version = 0x0400; // id3v2.4.0
    20 
    21 const uint32_t kMaxSynchsafeSize = 0x0FFFFFFF; // 28 effective bits.
    22 
    23 // Convert the specified size into synchsafe integer, where the most significant
    24 // bit (bit 7) is set to zero in every byte.
    25 uint32_t EncodeSynchsafe(uint32_t size) {
    26  return (size & 0x7F) | (((size >> 7) & 0x7F) << 8) |
    27  (((size >> 14) & 0x7F) << 16) | (((size >> 21) & 0x7F) << 24);
    28 }
    29 
    30 bool WriteId3v2Header(uint32_t frames_size, BufferWriter* buffer_writer) {
    31  buffer_writer->AppendString(kID3v2Identifier);
    32  buffer_writer->AppendInt(kID3v2Version);
    33  const uint8_t flags = 0;
    34  buffer_writer->AppendInt(flags);
    35 
    36  if (frames_size > kMaxSynchsafeSize) {
    37  LOG(ERROR) << "Input size (" << frames_size
    38  << ") is out of range (> max synchsafe integer "
    39  << kMaxSynchsafeSize << ").";
    40  return false;
    41  }
    42  buffer_writer->AppendInt(EncodeSynchsafe(frames_size));
    43 
    44  return true;
    45 }
    46 
    47 } // namespace
    48 
    49 void Id3Tag::AddPrivateFrame(const std::string& owner,
    50  const std::string& data) {
    51  private_frames_.push_back({owner, data});
    52 }
    53 
    54 bool Id3Tag::WriteToBuffer(BufferWriter* buffer_writer) {
    55  BufferWriter frames_buffer;
    56  for (const PrivateFrame& private_frame : private_frames_) {
    57  if (!WritePrivateFrame(private_frame, &frames_buffer))
    58  return false;
    59  }
    60 
    61  if (!WriteId3v2Header(frames_buffer.Size(), buffer_writer))
    62  return false;
    63  buffer_writer->AppendBuffer(frames_buffer);
    64  return true;
    65 }
    66 
    67 bool Id3Tag::WriteToVector(std::vector<uint8_t>* output) {
    68  BufferWriter buffer_writer;
    69  if (!WriteToBuffer(&buffer_writer))
    70  return false;
    71  buffer_writer.SwapBuffer(output);
    72  return true;
    73 }
    74 
    75 // Implemented per http://id3.org/id3v2.4.0-frames 4.27.
    76 bool Id3Tag::WritePrivateFrame(const PrivateFrame& private_frame,
    77  BufferWriter* buffer_writer) {
    78  buffer_writer->AppendInt(static_cast<uint32_t>(FOURCC_PRIV));
    79 
    80  const uint32_t frame_size = static_cast<uint32_t>(
    81  private_frame.owner.size() + 1 + private_frame.data.size());
    82  if (frame_size > kMaxSynchsafeSize) {
    83  LOG(ERROR) << "Input size (" << frame_size
    84  << ") is out of range (> max synchsafe integer "
    85  << kMaxSynchsafeSize << ").";
    86  return false;
    87  }
    88  buffer_writer->AppendInt(EncodeSynchsafe(frame_size));
    89 
    90  const uint16_t flags = 0;
    91  buffer_writer->AppendInt(flags);
    92 
    93  buffer_writer->AppendString(private_frame.owner);
    94  uint8_t byte = 0; // NULL terminating byte between owner and value.
    95  buffer_writer->AppendInt(byte);
    96  buffer_writer->AppendString(private_frame.data);
    97  return true;
    98 }
    99 
    100 } // namespace media
    101 } // namespace shaka
    virtual bool WriteToVector(std::vector< uint8_t > *output)
    Definition: id3_tag.cc:67
    -
    virtual void AddPrivateFrame(const std::string &owner, const std::string &data)
    Definition: id3_tag.cc:49
    -
    All the methods that are virtual are virtual for mocking.
    - - -
    virtual bool WriteToBuffer(BufferWriter *buffer_writer)
    Definition: id3_tag.cc:54
    +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/id3_tag.h"
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/media/base/buffer_writer.h"
    +
    11 #include "packager/media/base/fourccs.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 namespace {
    +
    16 
    +
    17 // ID3v2 header: http://id3.org/id3v2.4.0-structure.
    +
    18 const char kID3v2Identifier[] = "ID3";
    +
    19 const uint16_t kID3v2Version = 0x0400; // id3v2.4.0
    +
    20 
    +
    21 const uint32_t kMaxSynchsafeSize = 0x0FFFFFFF; // 28 effective bits.
    +
    22 
    +
    23 // Convert the specified size into synchsafe integer, where the most significant
    +
    24 // bit (bit 7) is set to zero in every byte.
    +
    25 uint32_t EncodeSynchsafe(uint32_t size) {
    +
    26  return (size & 0x7F) | (((size >> 7) & 0x7F) << 8) |
    +
    27  (((size >> 14) & 0x7F) << 16) | (((size >> 21) & 0x7F) << 24);
    +
    28 }
    +
    29 
    +
    30 bool WriteId3v2Header(uint32_t frames_size, BufferWriter* buffer_writer) {
    +
    31  buffer_writer->AppendString(kID3v2Identifier);
    +
    32  buffer_writer->AppendInt(kID3v2Version);
    +
    33  const uint8_t flags = 0;
    +
    34  buffer_writer->AppendInt(flags);
    +
    35 
    +
    36  if (frames_size > kMaxSynchsafeSize) {
    +
    37  LOG(ERROR) << "Input size (" << frames_size
    +
    38  << ") is out of range (> max synchsafe integer "
    +
    39  << kMaxSynchsafeSize << ").";
    +
    40  return false;
    +
    41  }
    +
    42  buffer_writer->AppendInt(EncodeSynchsafe(frames_size));
    +
    43 
    +
    44  return true;
    +
    45 }
    +
    46 
    +
    47 } // namespace
    +
    48 
    +
    49 void Id3Tag::AddPrivateFrame(const std::string& owner,
    +
    50  const std::string& data) {
    +
    51  private_frames_.push_back({owner, data});
    +
    52 }
    +
    53 
    +
    54 bool Id3Tag::WriteToBuffer(BufferWriter* buffer_writer) {
    +
    55  BufferWriter frames_buffer;
    +
    56  for (const PrivateFrame& private_frame : private_frames_) {
    +
    57  if (!WritePrivateFrame(private_frame, &frames_buffer))
    +
    58  return false;
    +
    59  }
    +
    60 
    +
    61  if (!WriteId3v2Header(frames_buffer.Size(), buffer_writer))
    +
    62  return false;
    +
    63  buffer_writer->AppendBuffer(frames_buffer);
    +
    64  return true;
    +
    65 }
    +
    66 
    +
    67 bool Id3Tag::WriteToVector(std::vector<uint8_t>* output) {
    +
    68  BufferWriter buffer_writer;
    +
    69  if (!WriteToBuffer(&buffer_writer))
    +
    70  return false;
    +
    71  buffer_writer.SwapBuffer(output);
    +
    72  return true;
    +
    73 }
    +
    74 
    +
    75 // Implemented per http://id3.org/id3v2.4.0-frames 4.27.
    +
    76 bool Id3Tag::WritePrivateFrame(const PrivateFrame& private_frame,
    +
    77  BufferWriter* buffer_writer) {
    +
    78  buffer_writer->AppendInt(static_cast<uint32_t>(FOURCC_PRIV));
    +
    79 
    +
    80  const uint32_t frame_size = static_cast<uint32_t>(
    +
    81  private_frame.owner.size() + 1 + private_frame.data.size());
    +
    82  if (frame_size > kMaxSynchsafeSize) {
    +
    83  LOG(ERROR) << "Input size (" << frame_size
    +
    84  << ") is out of range (> max synchsafe integer "
    +
    85  << kMaxSynchsafeSize << ").";
    +
    86  return false;
    +
    87  }
    +
    88  buffer_writer->AppendInt(EncodeSynchsafe(frame_size));
    +
    89 
    +
    90  const uint16_t flags = 0;
    +
    91  buffer_writer->AppendInt(flags);
    +
    92 
    +
    93  buffer_writer->AppendString(private_frame.owner);
    +
    94  uint8_t byte = 0; // NULL terminating byte between owner and value.
    +
    95  buffer_writer->AppendInt(byte);
    +
    96  buffer_writer->AppendString(private_frame.data);
    +
    97  return true;
    +
    98 }
    +
    99 
    +
    100 } // namespace media
    +
    101 } // namespace shaka
    + + +
    virtual bool WriteToBuffer(BufferWriter *buffer_writer)
    Definition: id3_tag.cc:54
    +
    virtual void AddPrivateFrame(const std::string &owner, const std::string &data)
    Definition: id3_tag.cc:49
    +
    virtual bool WriteToVector(std::vector< uint8_t > *output)
    Definition: id3_tag.cc:67
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d3c/h26x__byte__to__unit__stream__converter_8cc_source.html b/docs/de/d3c/h26x__byte__to__unit__stream__converter_8cc_source.html index 3f76cd2502..abc59e0631 100644 --- a/docs/de/d3c/h26x__byte__to__unit__stream__converter_8cc_source.html +++ b/docs/de/d3c/h26x__byte__to__unit__stream__converter_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/h26x_byte_to_unit_stream_converter.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    h26x_byte_to_unit_stream_converter.cc
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/h26x_byte_to_unit_stream_converter.h"
    8 
    9 #include <gflags/gflags.h>
    10 #include <limits>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/media/base/buffer_writer.h"
    15 
    16 // TODO(kqyang): Move byte to unit stream convertion to muxer and make it a
    17 // muxer option.
    18 DEFINE_bool(strip_parameter_set_nalus,
    19  true,
    20  "When converting from NAL byte stream (AnnexB stream) to NAL unit "
    21  "stream, this flag determines whether to strip parameter sets NAL "
    22  "units, i.e. SPS/PPS for H264 and SPS/PPS/VPS for H265, from the "
    23  "frames. Note that avc1/hvc1 is generated if this flag is enabled; "
    24  "otherwise avc3/hev1 is generated.");
    25 
    26 namespace shaka {
    27 namespace media {
    28 
    29 namespace {
    30 // Additional space to reserve for output frame. This value ought to be enough
    31 // to acommodate frames consisting of 100 NAL units with 3-byte start codes.
    32 const size_t kStreamConversionOverhead = 100;
    33 }
    34 
    36  Nalu::CodecType type)
    37  : type_(type),
    38  stream_format_(
    39  FLAGS_strip_parameter_set_nalus
    40  ? H26xStreamFormat::kNalUnitStreamWithoutParameterSetNalus
    41  : H26xStreamFormat::kNalUnitStreamWithParameterSetNalus) {}
    42 
    44  Nalu::CodecType type,
    45  H26xStreamFormat stream_format)
    46  : type_(type), stream_format_(stream_format) {}
    47 
    48 H26xByteToUnitStreamConverter::~H26xByteToUnitStreamConverter() {}
    49 
    51  const uint8_t* input_frame,
    52  size_t input_frame_size,
    53  std::vector<uint8_t>* output_frame) {
    54  DCHECK(input_frame);
    55  DCHECK(output_frame);
    56 
    57  BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead);
    58 
    59  Nalu nalu;
    60  NaluReader reader(type_, kIsAnnexbByteStream, input_frame, input_frame_size);
    61  if (!reader.StartsWithStartCode()) {
    62  LOG(ERROR) << "H.26x byte stream frame did not begin with start code.";
    63  return false;
    64  }
    65 
    66  while (reader.Advance(&nalu) == NaluReader::kOk) {
    67  const uint64_t nalu_size = nalu.payload_size() + nalu.header_size();
    68  DCHECK_LE(nalu_size, std::numeric_limits<uint32_t>::max());
    69 
    70  if (ProcessNalu(nalu))
    71  continue;
    72 
    73  // Append 4-byte length and NAL unit data to the buffer.
    74  output_buffer.AppendInt(static_cast<uint32_t>(nalu_size));
    75  output_buffer.AppendArray(nalu.data(), nalu_size);
    76  }
    77 
    78  output_buffer.SwapBuffer(output_frame);
    79  return true;
    80 }
    81 
    82 void H26xByteToUnitStreamConverter::WarnIfNotMatch(
    83  int nalu_type,
    84  const uint8_t* nalu_ptr,
    85  size_t nalu_size,
    86  const std::vector<uint8_t>& vector) {
    87  if (vector.empty())
    88  return;
    89  if (vector.size() != nalu_size ||
    90  memcmp(vector.data(), nalu_ptr, nalu_size) != 0) {
    91  LOG(WARNING) << "Seeing varying NAL unit of type " << nalu_type
    92  << ". You may need to set --strip_parameter_set_nalus=false "
    93  "during packaging to generate a playable stream.";
    94  VLOG(1) << "Old: " << base::HexEncode(vector.data(), vector.size());
    95  VLOG(1) << "New: " << base::HexEncode(nalu_ptr, nalu_size);
    96  }
    97 }
    98 
    99 } // namespace media
    100 } // namespace shaka
    bool ConvertByteStreamToNalUnitStream(const uint8_t *input_frame, size_t input_frame_size, std::vector< uint8_t > *output_frame)
    -
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    - - -
    All the methods that are virtual are virtual for mocking.
    - -
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    - -
    Result Advance(Nalu *nalu)
    Definition: nalu_reader.cc:241
    - - -
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/h26x_byte_to_unit_stream_converter.h"
    +
    8 
    +
    9 #include <gflags/gflags.h>
    +
    10 #include <limits>
    +
    11 
    +
    12 #include "packager/base/logging.h"
    +
    13 #include "packager/base/strings/string_number_conversions.h"
    +
    14 #include "packager/media/base/buffer_writer.h"
    +
    15 
    +
    16 // TODO(kqyang): Move byte to unit stream convertion to muxer and make it a
    +
    17 // muxer option.
    +
    18 DEFINE_bool(strip_parameter_set_nalus,
    +
    19  true,
    +
    20  "When converting from NAL byte stream (AnnexB stream) to NAL unit "
    +
    21  "stream, this flag determines whether to strip parameter sets NAL "
    +
    22  "units, i.e. SPS/PPS for H264 and SPS/PPS/VPS for H265, from the "
    +
    23  "frames. Note that avc1/hvc1 is generated if this flag is enabled; "
    +
    24  "otherwise avc3/hev1 is generated.");
    +
    25 
    +
    26 namespace shaka {
    +
    27 namespace media {
    +
    28 
    +
    29 namespace {
    +
    30 // Additional space to reserve for output frame. This value ought to be enough
    +
    31 // to acommodate frames consisting of 100 NAL units with 3-byte start codes.
    +
    32 const size_t kStreamConversionOverhead = 100;
    +
    33 }
    +
    34 
    + +
    36  Nalu::CodecType type)
    +
    37  : type_(type),
    +
    38  stream_format_(
    +
    39  FLAGS_strip_parameter_set_nalus
    +
    40  ? H26xStreamFormat::kNalUnitStreamWithoutParameterSetNalus
    +
    41  : H26xStreamFormat::kNalUnitStreamWithParameterSetNalus) {}
    +
    42 
    + +
    44  Nalu::CodecType type,
    +
    45  H26xStreamFormat stream_format)
    +
    46  : type_(type), stream_format_(stream_format) {}
    +
    47 
    +
    48 H26xByteToUnitStreamConverter::~H26xByteToUnitStreamConverter() {}
    +
    49 
    + +
    51  const uint8_t* input_frame,
    +
    52  size_t input_frame_size,
    +
    53  std::vector<uint8_t>* output_frame) {
    +
    54  DCHECK(input_frame);
    +
    55  DCHECK(output_frame);
    +
    56 
    +
    57  BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead);
    +
    58 
    +
    59  Nalu nalu;
    +
    60  NaluReader reader(type_, kIsAnnexbByteStream, input_frame, input_frame_size);
    +
    61  if (!reader.StartsWithStartCode()) {
    +
    62  LOG(ERROR) << "H.26x byte stream frame did not begin with start code.";
    +
    63  return false;
    +
    64  }
    +
    65 
    +
    66  while (reader.Advance(&nalu) == NaluReader::kOk) {
    +
    67  const uint64_t nalu_size = nalu.payload_size() + nalu.header_size();
    +
    68  DCHECK_LE(nalu_size, std::numeric_limits<uint32_t>::max());
    +
    69 
    +
    70  if (ProcessNalu(nalu))
    +
    71  continue;
    +
    72 
    +
    73  // Append 4-byte length and NAL unit data to the buffer.
    +
    74  output_buffer.AppendInt(static_cast<uint32_t>(nalu_size));
    +
    75  output_buffer.AppendArray(nalu.data(), nalu_size);
    +
    76  }
    +
    77 
    +
    78  output_buffer.SwapBuffer(output_frame);
    +
    79  return true;
    +
    80 }
    +
    81 
    +
    82 void H26xByteToUnitStreamConverter::WarnIfNotMatch(
    +
    83  int nalu_type,
    +
    84  const uint8_t* nalu_ptr,
    +
    85  size_t nalu_size,
    +
    86  const std::vector<uint8_t>& vector) {
    +
    87  if (vector.empty())
    +
    88  return;
    +
    89  if (vector.size() != nalu_size ||
    +
    90  memcmp(vector.data(), nalu_ptr, nalu_size) != 0) {
    +
    91  LOG(WARNING) << "Seeing varying NAL unit of type " << nalu_type
    +
    92  << ". You may need to set --strip_parameter_set_nalus=false "
    +
    93  "during packaging to generate a playable stream.";
    +
    94  VLOG(1) << "Old: " << base::HexEncode(vector.data(), vector.size());
    +
    95  VLOG(1) << "New: " << base::HexEncode(nalu_ptr, nalu_size);
    +
    96  }
    +
    97 }
    +
    98 
    +
    99 } // namespace media
    +
    100 } // namespace shaka
    + + +
    bool ConvertByteStreamToNalUnitStream(const uint8_t *input_frame, size_t input_frame_size, std::vector< uint8_t > *output_frame)
    + + + +
    Result Advance(Nalu *nalu)
    Definition: nalu_reader.cc:241
    + +
    const uint8_t * data() const
    This is the pointer to the Nalu data, pointing to the header.
    Definition: nalu_reader.h:97
    +
    uint64_t header_size() const
    The size of the header, e.g. 1 for H.264.
    Definition: nalu_reader.h:100
    +
    uint64_t payload_size() const
    Size of this Nalu minus header_size().
    Definition: nalu_reader.h:102
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d3c/macros_8h_source.html b/docs/de/d3c/macros_8h_source.html index c36c3927be..ea69383f12 100644 --- a/docs/de/d3c/macros_8h_source.html +++ b/docs/de/d3c/macros_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/macros.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    macros.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_MACROS_H_
    8 #define PACKAGER_MEDIA_BASE_MACROS_H_
    9 
    10 // The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
    11 // between switch labels:
    12 // switch (x) {
    13 // case 40:
    14 // case 41:
    15 // if (truth_is_out_there) {
    16 // ++x;
    17 // FALLTHROUGH_INTENDED; // Use instead of/along with annotations in
    18 // // comments.
    19 // } else {
    20 // return x;
    21 // }
    22 // case 42:
    23 // ...
    24 //
    25 // As shown in the example above, the FALLTHROUGH_INTENDED macro should be
    26 // followed by a semicolon. It is designed to mimic control-flow statements
    27 // like 'break;', so it can be placed in most places where 'break;' can, but
    28 // only if there are no statements on the execution path between it and the
    29 // next switch label.
    30 //
    31 // When compiled with clang in C++11 mode, the FALLTHROUGH_INTENDED macro is
    32 // expanded to [[clang::fallthrough]] attribute, which is analysed when
    33 // performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough').
    34 // See clang documentation on language extensions for details:
    35 // http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
    36 //
    37 // When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no
    38 // effect on diagnostics.
    39 //
    40 // In either case this macro has no effect on runtime behavior and performance
    41 // of code.
    42 #if defined(__clang__) && __cplusplus >= 201103L && defined(__has_warning)
    43 #if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
    44 #define FALLTHROUGH_INTENDED [[clang::fallthrough]] // NOLINT
    45 #endif
    46 #endif
    47 
    48 #ifndef FALLTHROUGH_INTENDED
    49 #define FALLTHROUGH_INTENDED \
    50  do { \
    51  } while (0)
    52 #endif
    53 
    54 #endif // PACKAGER_MEDIA_BASE_MACROS_H_
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_MACROS_H_
    +
    8 #define PACKAGER_MEDIA_BASE_MACROS_H_
    +
    9 
    +
    10 // The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
    +
    11 // between switch labels:
    +
    12 // switch (x) {
    +
    13 // case 40:
    +
    14 // case 41:
    +
    15 // if (truth_is_out_there) {
    +
    16 // ++x;
    +
    17 // FALLTHROUGH_INTENDED; // Use instead of/along with annotations in
    +
    18 // // comments.
    +
    19 // } else {
    +
    20 // return x;
    +
    21 // }
    +
    22 // case 42:
    +
    23 // ...
    +
    24 //
    +
    25 // As shown in the example above, the FALLTHROUGH_INTENDED macro should be
    +
    26 // followed by a semicolon. It is designed to mimic control-flow statements
    +
    27 // like 'break;', so it can be placed in most places where 'break;' can, but
    +
    28 // only if there are no statements on the execution path between it and the
    +
    29 // next switch label.
    +
    30 //
    +
    31 // When compiled with clang in C++11 mode, the FALLTHROUGH_INTENDED macro is
    +
    32 // expanded to [[clang::fallthrough]] attribute, which is analysed when
    +
    33 // performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough').
    +
    34 // See clang documentation on language extensions for details:
    +
    35 // http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
    +
    36 //
    +
    37 // When used with unsupported compilers, the FALLTHROUGH_INTENDED macro has no
    +
    38 // effect on diagnostics.
    +
    39 //
    +
    40 // In either case this macro has no effect on runtime behavior and performance
    +
    41 // of code.
    +
    42 #if defined(__clang__) && __cplusplus >= 201103L && defined(__has_warning)
    +
    43 #if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
    +
    44 #define FALLTHROUGH_INTENDED [[clang::fallthrough]] // NOLINT
    +
    45 #endif
    +
    46 #endif
    +
    47 
    +
    48 #ifndef FALLTHROUGH_INTENDED
    +
    49 #define FALLTHROUGH_INTENDED \
    +
    50  do { \
    +
    51  } while (0)
    +
    52 #endif
    +
    53 
    +
    54 #endif // PACKAGER_MEDIA_BASE_MACROS_H_
    +
    diff --git a/docs/de/d3e/buffer__reader_8h_source.html b/docs/de/d3e/buffer__reader_8h_source.html index 0092ae21ad..448caa4ee0 100644 --- a/docs/de/d3e/buffer__reader_8h_source.html +++ b/docs/de/d3e/buffer__reader_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/buffer_reader.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    buffer_reader.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_BUFFER_READER_H_
    8 #define PACKAGER_MEDIA_BASE_BUFFER_READER_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <string>
    13 #include <vector>
    14 
    15 #include "packager/base/compiler_specific.h"
    16 #include "packager/base/macros.h"
    17 
    18 namespace shaka {
    19 namespace media {
    20 
    23 class BufferReader {
    24  public:
    26  BufferReader(const uint8_t* buf, size_t size)
    27  : buf_(buf), size_(size), pos_(0) {}
    28  ~BufferReader() {}
    29 
    32  bool HasBytes(size_t count) { return pos() + count <= size(); }
    33 
    38  bool Read1(uint8_t* v) WARN_UNUSED_RESULT;
    39  bool Read2(uint16_t* v) WARN_UNUSED_RESULT;
    40  bool Read2s(int16_t* v) WARN_UNUSED_RESULT;
    41  bool Read4(uint32_t* v) WARN_UNUSED_RESULT;
    42  bool Read4s(int32_t* v) WARN_UNUSED_RESULT;
    43  bool Read8(uint64_t* v) WARN_UNUSED_RESULT;
    44  bool Read8s(int64_t* v) WARN_UNUSED_RESULT;
    46 
    52  bool ReadNBytesInto8(uint64_t* v, size_t num_bytes) WARN_UNUSED_RESULT;
    53  bool ReadNBytesInto8s(int64_t* v, size_t num_bytes) WARN_UNUSED_RESULT;
    55 
    56  bool ReadToVector(std::vector<uint8_t>* t, size_t count) WARN_UNUSED_RESULT;
    57  bool ReadToString(std::string* str, size_t size) WARN_UNUSED_RESULT;
    58 
    61  bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT;
    62 
    63  const uint8_t* data() const { return buf_; }
    64  size_t size() const { return size_; }
    65  void set_size(size_t size) { size_ = size; }
    66  size_t pos() const { return pos_; }
    67 
    68  private:
    69  // Internal implementation of multi-byte reads.
    70  template <typename T>
    71  bool Read(T* t) WARN_UNUSED_RESULT;
    72  template <typename T>
    73  bool ReadNBytes(T* t, size_t num_bytes) WARN_UNUSED_RESULT;
    74 
    75  const uint8_t* buf_;
    76  size_t size_;
    77  size_t pos_;
    78 
    79  DISALLOW_COPY_AND_ASSIGN(BufferReader);
    80 };
    81 
    82 } // namespace media
    83 } // namespace shaka
    84 
    85 #endif // PACKAGER_MEDIA_BASE_BUFFER_READER_H_
    BufferReader(const uint8_t *buf, size_t size)
    Create a BufferReader from a raw buffer.
    Definition: buffer_reader.h:26
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULT
    -
    bool HasBytes(size_t count)
    Definition: buffer_reader.h:32
    -
    bool Read1(uint8_t *v) WARN_UNUSED_RESULT
    -
    bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_BUFFER_READER_H_
    +
    8 #define PACKAGER_MEDIA_BASE_BUFFER_READER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <string>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/base/compiler_specific.h"
    +
    16 #include "packager/base/macros.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    +
    23 class BufferReader {
    +
    24  public:
    +
    26  BufferReader(const uint8_t* buf, size_t size)
    +
    27  : buf_(buf), size_(size), pos_(0) {}
    +
    28  ~BufferReader() {}
    +
    29 
    +
    32  bool HasBytes(size_t count) { return pos() + count <= size(); }
    +
    33 
    +
    38  bool Read1(uint8_t* v) WARN_UNUSED_RESULT;
    +
    39  bool Read2(uint16_t* v) WARN_UNUSED_RESULT;
    +
    40  bool Read2s(int16_t* v) WARN_UNUSED_RESULT;
    +
    41  bool Read4(uint32_t* v) WARN_UNUSED_RESULT;
    +
    42  bool Read4s(int32_t* v) WARN_UNUSED_RESULT;
    +
    43  bool Read8(uint64_t* v) WARN_UNUSED_RESULT;
    +
    44  bool Read8s(int64_t* v) WARN_UNUSED_RESULT;
    +
    46 
    +
    52  bool ReadNBytesInto8(uint64_t* v, size_t num_bytes) WARN_UNUSED_RESULT;
    +
    53  bool ReadNBytesInto8s(int64_t* v, size_t num_bytes) WARN_UNUSED_RESULT;
    +
    55 
    +
    56  bool ReadToVector(std::vector<uint8_t>* t, size_t count) WARN_UNUSED_RESULT;
    +
    57  bool ReadToString(std::string* str, size_t size) WARN_UNUSED_RESULT;
    +
    58 
    +
    60  bool ReadCString(std::string* str) WARN_UNUSED_RESULT;
    +
    61 
    +
    64  bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT;
    +
    65 
    +
    66  const uint8_t* data() const { return buf_; }
    +
    67  size_t size() const { return size_; }
    +
    68  void set_size(size_t size) { size_ = size; }
    +
    69  size_t pos() const { return pos_; }
    +
    70 
    +
    71  private:
    +
    72  // Internal implementation of multi-byte reads.
    +
    73  template <typename T>
    +
    74  bool Read(T* t) WARN_UNUSED_RESULT;
    +
    75  template <typename T>
    +
    76  bool ReadNBytes(T* t, size_t num_bytes) WARN_UNUSED_RESULT;
    +
    77 
    +
    78  const uint8_t* buf_;
    +
    79  size_t size_;
    +
    80  size_t pos_;
    +
    81 
    +
    82  DISALLOW_COPY_AND_ASSIGN(BufferReader);
    +
    83 };
    +
    84 
    +
    85 } // namespace media
    +
    86 } // namespace shaka
    +
    87 
    +
    88 #endif // PACKAGER_MEDIA_BASE_BUFFER_READER_H_
    + +
    bool HasBytes(size_t count)
    Definition: buffer_reader.h:32
    +
    bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
    +
    bool Read1(uint8_t *v) WARN_UNUSED_RESULT
    +
    BufferReader(const uint8_t *buf, size_t size)
    Create a BufferReader from a raw buffer.
    Definition: buffer_reader.h:26
    +
    bool ReadNBytesInto8(uint64_t *v, size_t num_bytes) WARN_UNUSED_RESULT
    +
    bool ReadCString(std::string *str) WARN_UNUSED_RESULT
    Reads a null-terminated string.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d3e/classshaka_1_1media_1_1H264Parser-members.html b/docs/de/d3e/classshaka_1_1media_1_1H264Parser-members.html index b2eab9c3ce..8d81ca9afb 100644 --- a/docs/de/d3e/classshaka_1_1media_1_1H264Parser-members.html +++ b/docs/de/d3e/classshaka_1_1media_1_1H264Parser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/de/d43/classshaka_1_1media_1_1mp2t_1_1PesPacket-members.html b/docs/de/d43/classshaka_1_1media_1_1mp2t_1_1PesPacket-members.html index 467c8d0379..5e24c115ce 100644 --- a/docs/de/d43/classshaka_1_1media_1_1mp2t_1_1PesPacket-members.html +++ b/docs/de/d43/classshaka_1_1media_1_1mp2t_1_1PesPacket-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/d49/classshaka_1_1media_1_1DecryptConfig.html b/docs/de/d49/classshaka_1_1media_1_1DecryptConfig.html index d1fd3f1e0d..51bdc86367 100644 --- a/docs/de/d49/classshaka_1_1media_1_1DecryptConfig.html +++ b/docs/de/d49/classshaka_1_1media_1_1DecryptConfig.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::DecryptConfig Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/d4a/muxer__listener__internal_8h_source.html b/docs/de/d4a/muxer__listener__internal_8h_source.html index 1c510ff47c..0646917d42 100644 --- a/docs/de/d4a/muxer__listener__internal_8h_source.html +++ b/docs/de/d4a/muxer__listener__internal_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/muxer_listener_internal.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    muxer_listener_internal.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_EVENT_MUXER_LISTENER_INTERNAL_H_
    8 #define PACKAGER_MEDIA_EVENT_MUXER_LISTENER_INTERNAL_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <string>
    13 #include <vector>
    14 
    15 #include "packager/media/event/muxer_listener.h"
    16 
    17 namespace shaka {
    18 
    19 class MediaInfo;
    20 
    21 namespace media {
    22 
    23 class StreamInfo;
    24 struct MuxerOptions;
    25 
    26 namespace internal {
    27 
    30 bool GenerateMediaInfo(const MuxerOptions& muxer_options,
    31  const StreamInfo& stream_info,
    32  uint32_t reference_time_scale_,
    33  MuxerListener::ContainerType container_type,
    34  MediaInfo* media_info);
    35 
    38 bool IsMediaInfoCompatible(const MediaInfo& media_info1,
    39  const MediaInfo& media_info2);
    40 
    43 bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges,
    44  float duration_seconds,
    45  MediaInfo* media_info);
    46 
    54 void SetContentProtectionFields(
    55  FourCC protection_scheme,
    56  const std::vector<uint8_t>& default_key_id,
    57  const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
    58  MediaInfo* media_info);
    59 
    62 std::string CreateUUIDString(const std::vector<uint8_t>& data);
    63 
    64 } // namespace internal
    65 } // namespace media
    66 } // namespace shaka
    67 #endif // PACKAGER_MEDIA_EVENT_MUXER_LISTENER_INTERNAL_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_EVENT_MUXER_LISTENER_INTERNAL_H_
    +
    8 #define PACKAGER_MEDIA_EVENT_MUXER_LISTENER_INTERNAL_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <string>
    +
    13 #include <vector>
    +
    14 
    +
    15 #include "packager/media/event/muxer_listener.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 
    +
    19 class MediaInfo;
    +
    20 
    +
    21 namespace media {
    +
    22 
    +
    23 class StreamInfo;
    +
    24 struct MuxerOptions;
    +
    25 
    +
    26 namespace internal {
    +
    27 
    +
    30 bool GenerateMediaInfo(const MuxerOptions& muxer_options,
    +
    31  const StreamInfo& stream_info,
    +
    32  uint32_t reference_time_scale_,
    +
    33  MuxerListener::ContainerType container_type,
    +
    34  MediaInfo* media_info);
    +
    35 
    +
    38 bool IsMediaInfoCompatible(const MediaInfo& media_info1,
    +
    39  const MediaInfo& media_info2);
    +
    40 
    +
    43 bool SetVodInformation(const MuxerListener::MediaRanges& media_ranges,
    +
    44  float duration_seconds,
    +
    45  MediaInfo* media_info);
    +
    46 
    +
    54 void SetContentProtectionFields(
    +
    55  FourCC protection_scheme,
    +
    56  const std::vector<uint8_t>& default_key_id,
    +
    57  const std::vector<ProtectionSystemSpecificInfo>& key_system_info,
    +
    58  MediaInfo* media_info);
    +
    59 
    +
    62 std::string CreateUUIDString(const std::vector<uint8_t>& data);
    +
    63 
    +
    64 } // namespace internal
    +
    65 } // namespace media
    +
    66 } // namespace shaka
    +
    67 #endif // PACKAGER_MEDIA_EVENT_MUXER_LISTENER_INTERNAL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d52/classshaka_1_1Representation.html b/docs/de/d52/classshaka_1_1Representation.html index 271a96a68e..8960484700 100644 --- a/docs/de/d52/classshaka_1_1Representation.html +++ b/docs/de/d52/classshaka_1_1Representation.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::Representation Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::MockRepresentation - -
    + + -

    Public Types

    enum  SuppressFlag { kSuppressWidth = 1, -kSuppressHeight = 2, -kSuppressFrameRate = 4 +
    enum  SuppressFlag { kSuppressWidth = 1 +, kSuppressHeight = 2 +, kSuppressFrameRate = 4 }
     
    @@ -110,13 +113,13 @@ class  - - + + - + @@ -133,7 +136,7 @@ void 
    RepresentationTest 
    virtual const MediaInfo & GetMediaInfo () const
     
    xml::scoped_xml_ptr< xmlNode > GetXml ()
     
    base::Optional< xml::XmlNodeGetXml ()
     
    void SuppressOnce (SuppressFlag flag)
     
    void SetPresentationTimeOffset (double presentation_time_offset)
     Set in SegmentBase / SegmentTemplate.
     Set @presentationTimeOffset in SegmentBase / SegmentTemplate.
     
    bool GetStartAndEndTimestamps (double *start_timestamp_seconds, double *end_timestamp_seconds) const
     
    set_media_info (c

    Detailed Description

    Representation class contains references to a single media stream, as well as optional ContentProtection elements for that stream.

    -

    Definition at line 54 of file representation.h.

    +

    Definition at line 50 of file representation.h.

    Constructor & Destructor Documentation

    ◆ Representation() [1/2]

    @@ -388,18 +391,18 @@ void 
    set_media_info (c
    Returns
    true if successful, false otherwise.
    -

    Definition at line 296 of file representation.cc.

    +

    Definition at line 298 of file representation.cc.

    - -

    ◆ GetXml()

    + +

    ◆ GetXml()

    - + @@ -436,7 +439,7 @@ void 
    xml::scoped_xml_ptr< xmlNode > shaka::Representation::GetXml base::Optional< xml::XmlNode > shaka::Representation::GetXml ( ) set_media_info (c
    Returns
    ID number for <Representation>.
    -

    Definition at line 146 of file representation.h.

    +

    Definition at line 142 of file representation.h.

    @@ -509,9 +512,9 @@ void 
    set_media_info (c
    -

    By calling this methods, the next time GetXml() is called, the corresponding attributes will not be set. For example, if SuppressOnce(kSuppressWidth) is called, then GetXml() will return a <Representation> element without a attribute. Note that it only applies to the next call to GetXml(), calling GetXml() again without calling this methods will return a <Representation> element with the attribute. This may be called multiple times to set different (or the same) flags.

    +

    By calling this methods, the next time GetXml() is called, the corresponding attributes will not be set. For example, if SuppressOnce(kSuppressWidth) is called, then GetXml() will return a <Representation> element without a @width attribute. Note that it only applies to the next call to GetXml(), calling GetXml() again without calling this methods will return a <Representation> element with the attribute. This may be called multiple times to set different (or the same) flags.

    -

    Definition at line 284 of file representation.cc.

    +

    Definition at line 286 of file representation.cc.

    @@ -568,9 +571,7 @@ void 
    set_media_info (c diff --git a/docs/de/d53/classshaka_1_1media_1_1FakeInputMediaHandler-members.html b/docs/de/d53/classshaka_1_1media_1_1FakeInputMediaHandler-members.html index 1b8a66d143..9a25c88a72 100644 --- a/docs/de/d53/classshaka_1_1media_1_1FakeInputMediaHandler-members.html +++ b/docs/de/d53/classshaka_1_1media_1_1FakeInputMediaHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::FakeInputMediaHandler, including all inherited members.

    - - - - - - - - - - + + + + + + + + + + + + @@ -93,9 +98,7 @@ $(function() {
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
    Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
    DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) constshaka::media::MediaHandlerinlineprotected
    DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) constshaka::media::MediaHandlerinlineprotected
    DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) constshaka::media::MediaHandlerinlineprotected
    DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) constshaka::media::MediaHandlerinlineprotected
    FlushAllDownstreams()shaka::media::MediaHandlerprotected
    FlushDownstream(size_t output_stream_index)shaka::media::MediaHandlerprotected
    Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::FakeInputMediaHandler
    shaka::media::MediaHandler::Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
    DispatchScte35Event(size_t stream_index, std::shared_ptr< const Scte35Event > scte35_event) constshaka::media::MediaHandlerinlineprotected
    DispatchSegmentInfo(size_t stream_index, std::shared_ptr< const SegmentInfo > segment_info) constshaka::media::MediaHandlerinlineprotected
    DispatchStreamInfo(size_t stream_index, std::shared_ptr< const StreamInfo > stream_info) constshaka::media::MediaHandlerinlineprotected
    DispatchTextSample(size_t stream_index, std::shared_ptr< const TextSample > text_sample) constshaka::media::MediaHandlerinlineprotected
    FlushAllDownstreams()shaka::media::FakeInputMediaHandler
    FlushDownstream(size_t output_stream_index)shaka::media::FakeInputMediaHandler
    shaka::media::MediaHandler::FlushDownstream(size_t output_stream_index)shaka::media::MediaHandlerprotected
    Initialize()shaka::media::MediaHandler
    initialized() (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerinlineprotected
    IsConnected()shaka::media::MediaHandlerinline
    diff --git a/docs/de/d54/structshaka_1_1media_1_1mp4_1_1FlacSpecific.html b/docs/de/d54/structshaka_1_1media_1_1mp4_1_1FlacSpecific.html index eef562811c..26bc984cb8 100644 --- a/docs/de/d54/structshaka_1_1media_1_1mp4_1_1FlacSpecific.html +++ b/docs/de/d54/structshaka_1_1media_1_1mp4_1_1FlacSpecific.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::FlacSpecific Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 347 of file box_definitions.h.

    +

    Definition at line 354 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1820 of file box_definitions.cc.

    +

    Definition at line 1867 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/de/d55/structshaka_1_1media_1_1mp4_1_1Language-members.html b/docs/de/d55/structshaka_1_1media_1_1mp4_1_1Language-members.html index f34a2ab67a..5e4b013894 100644 --- a/docs/de/d55/structshaka_1_1media_1_1mp4_1_1Language-members.html +++ b/docs/de/d55/structshaka_1_1media_1_1mp4_1_1Language-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/d5b/adts__header_8cc_source.html b/docs/de/d5b/adts__header_8cc_source.html index bdc184a901..8730ffda3e 100644 --- a/docs/de/d5b/adts__header_8cc_source.html +++ b/docs/de/d5b/adts__header_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/adts_header.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    adts_header.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/formats/mp2t/adts_header.h"
    8 
    9 #include "packager/media/base/bit_reader.h"
    10 #include "packager/media/base/bit_writer.h"
    11 #include "packager/media/formats/mp2t/mp2t_common.h"
    12 
    13 namespace {
    14 const size_t kAdtsHeaderMinSize = 7;
    15 
    16 // The following conversion table is extracted from ISO 14496 Part 3 -
    17 // Table 1.16 - Sampling Frequency Index.
    18 const int kAdtsFrequencyTable[] = {96000, 88200, 64000, 48000, 44100,
    19  32000, 24000, 22050, 16000, 12000,
    20  11025, 8000, 7350};
    21 const size_t kAdtsFrequencyTableSize = arraysize(kAdtsFrequencyTable);
    22 
    23 // The following conversion table is extracted from ISO 14496 Part 3 -
    24 // Table 1.17 - Channel Configuration.
    25 const int kAdtsNumChannelsTable[] = {0, 1, 2, 3, 4, 5, 6, 8};
    26 const size_t kAdtsNumChannelsTableSize = arraysize(kAdtsNumChannelsTable);
    27 } // namespace
    28 
    29 namespace shaka {
    30 namespace media {
    31 namespace mp2t {
    32 
    33 bool AdtsHeader::IsSyncWord(const uint8_t* buf) const {
    34  return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0);
    35 }
    36 
    38  return kAdtsHeaderMinSize + 1;
    39 }
    40 
    42  const size_t kSamplesPerAacFrame = 1024;
    43  return kSamplesPerAacFrame;
    44 }
    45 
    46 bool AdtsHeader::Parse(const uint8_t* adts_frame, size_t adts_frame_size) {
    47  CHECK(adts_frame);
    48 
    49  if (adts_frame_size < kAdtsHeaderMinSize)
    50  return false;
    51 
    52  BitReader frame(adts_frame, adts_frame_size);
    53  // Verify frame starts with sync bits (0xfff).
    54  uint32_t sync;
    55  RCHECK(frame.ReadBits(12, &sync));
    56  RCHECK(sync == 0xfff);
    57  // Skip MPEG version and layer.
    58  RCHECK(frame.SkipBits(3));
    59  RCHECK(frame.ReadBits(1, &protection_absent_));
    60  RCHECK(frame.ReadBits(2, &profile_));
    61  RCHECK(frame.ReadBits(4, &sampling_frequency_index_));
    62  RCHECK(sampling_frequency_index_ < kAdtsFrequencyTableSize);
    63  // Skip private stream bit.
    64  RCHECK(frame.SkipBits(1));
    65  RCHECK(frame.ReadBits(3, &channel_configuration_));
    66  RCHECK(channel_configuration_ < kAdtsNumChannelsTableSize);
    67  // Skip originality, home and copyright info.
    68  RCHECK(frame.SkipBits(4));
    69  RCHECK(frame.ReadBits(13, &frame_size_));
    70  // Skip buffer fullness indicator.
    71  RCHECK(frame.SkipBits(11));
    72  uint8_t num_blocks_minus_1;
    73  RCHECK(frame.ReadBits(2, &num_blocks_minus_1));
    74  if (num_blocks_minus_1) {
    75  NOTIMPLEMENTED() << "ADTS frames with more than one data block "
    76  "not supported.";
    77  return false;
    78  }
    79  return true;
    80 }
    81 
    82 size_t AdtsHeader::GetHeaderSize() const {
    83  const size_t kCrcSize = sizeof(uint16_t);
    84  return kAdtsHeaderMinSize + (protection_absent_ ? 0 : kCrcSize);
    85 }
    86 
    87 size_t AdtsHeader::GetFrameSize() const {
    88  return frame_size_;
    89 }
    90 
    91 size_t AdtsHeader::GetFrameSizeWithoutParsing(const uint8_t* data,
    92  size_t num_bytes) const {
    93  DCHECK_GT(num_bytes, static_cast<size_t>(5));
    94  return ((static_cast<int>(data[5]) >> 5) | (static_cast<int>(data[4]) << 3) |
    95  ((static_cast<int>(data[3]) & 0x3) << 11));
    96 }
    97 
    98 void AdtsHeader::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
    99  DCHECK(buffer);
    100  buffer->clear();
    101  BitWriter config(buffer);
    102  config.WriteBits(GetObjectType(), 5);
    103  config.WriteBits(sampling_frequency_index_, 4);
    104  config.WriteBits(channel_configuration_, 4);
    105  config.Flush();
    106 }
    107 
    108 uint8_t AdtsHeader::GetObjectType() const {
    109  return profile_ + 1;
    110 }
    111 
    113  DCHECK_LT(sampling_frequency_index_, kAdtsFrequencyTableSize);
    114  return kAdtsFrequencyTable[sampling_frequency_index_];
    115 }
    116 
    117 uint8_t AdtsHeader::GetNumChannels() const {
    118  DCHECK_LT(channel_configuration_, kAdtsNumChannelsTableSize);
    119  return kAdtsNumChannelsTable[channel_configuration_];
    120 }
    121 
    122 } // namespace mp2t
    123 } // namespace media
    124 } // namespace shaka
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    -
    A class to read bit streams.
    Definition: bit_reader.h:17
    -
    size_t GetHeaderSize() const override
    Definition: adts_header.cc:82
    -
    uint8_t GetObjectType() const override
    Definition: adts_header.cc:108
    -
    All the methods that are virtual are virtual for mocking.
    - -
    size_t GetSamplesPerFrame() const override
    Definition: adts_header.cc:41
    -
    size_t GetMinFrameSize() const override
    Definition: adts_header.cc:37
    -
    bool SkipBits(size_t num_bits)
    Definition: bit_reader.cc:24
    -
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: adts_header.cc:33
    -
    uint8_t GetNumChannels() const override
    Definition: adts_header.cc:117
    -
    uint32_t GetSamplingFrequency() const override
    Definition: adts_header.cc:112
    -
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: adts_header.cc:98
    -
    void WriteBits(uint32_t bits, size_t number_of_bits)
    Definition: bit_writer.cc:15
    -
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    Definition: adts_header.cc:91
    -
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: adts_header.cc:46
    -
    void Flush()
    Write pending bits, and align bitstream with extra zero bits.
    Definition: bit_writer.cc:31
    -
    size_t GetFrameSize() const override
    Definition: adts_header.cc:87
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/formats/mp2t/adts_header.h"
    +
    8 
    +
    9 #include "packager/media/base/bit_reader.h"
    +
    10 #include "packager/media/base/bit_writer.h"
    +
    11 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    12 
    +
    13 namespace {
    +
    14 const size_t kAdtsHeaderMinSize = 7;
    +
    15 
    +
    16 // The following conversion table is extracted from ISO 14496 Part 3 -
    +
    17 // Table 1.16 - Sampling Frequency Index.
    +
    18 const int kAdtsFrequencyTable[] = {96000, 88200, 64000, 48000, 44100,
    +
    19  32000, 24000, 22050, 16000, 12000,
    +
    20  11025, 8000, 7350};
    +
    21 const size_t kAdtsFrequencyTableSize = arraysize(kAdtsFrequencyTable);
    +
    22 
    +
    23 // The following conversion table is extracted from ISO 14496 Part 3 -
    +
    24 // Table 1.17 - Channel Configuration.
    +
    25 const int kAdtsNumChannelsTable[] = {0, 1, 2, 3, 4, 5, 6, 8};
    +
    26 const size_t kAdtsNumChannelsTableSize = arraysize(kAdtsNumChannelsTable);
    +
    27 } // namespace
    +
    28 
    +
    29 namespace shaka {
    +
    30 namespace media {
    +
    31 namespace mp2t {
    +
    32 
    +
    33 bool AdtsHeader::IsSyncWord(const uint8_t* buf) const {
    +
    34  return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0);
    +
    35 }
    +
    36 
    + +
    38  return kAdtsHeaderMinSize + 1;
    +
    39 }
    +
    40 
    + +
    42  const size_t kSamplesPerAacFrame = 1024;
    +
    43  return kSamplesPerAacFrame;
    +
    44 }
    +
    45 
    +
    46 bool AdtsHeader::Parse(const uint8_t* adts_frame, size_t adts_frame_size) {
    +
    47  CHECK(adts_frame);
    +
    48 
    +
    49  if (adts_frame_size < kAdtsHeaderMinSize)
    +
    50  return false;
    +
    51 
    +
    52  BitReader frame(adts_frame, adts_frame_size);
    +
    53  // Verify frame starts with sync bits (0xfff).
    +
    54  uint32_t sync;
    +
    55  RCHECK(frame.ReadBits(12, &sync));
    +
    56  RCHECK(sync == 0xfff);
    +
    57  // Skip MPEG version and layer.
    +
    58  RCHECK(frame.SkipBits(3));
    +
    59  RCHECK(frame.ReadBits(1, &protection_absent_));
    +
    60  RCHECK(frame.ReadBits(2, &profile_));
    +
    61  RCHECK(frame.ReadBits(4, &sampling_frequency_index_));
    +
    62  RCHECK(sampling_frequency_index_ < kAdtsFrequencyTableSize);
    +
    63  // Skip private stream bit.
    +
    64  RCHECK(frame.SkipBits(1));
    +
    65  RCHECK(frame.ReadBits(3, &channel_configuration_));
    +
    66  RCHECK(channel_configuration_ < kAdtsNumChannelsTableSize);
    +
    67  // Skip originality, home and copyright info.
    +
    68  RCHECK(frame.SkipBits(4));
    +
    69  RCHECK(frame.ReadBits(13, &frame_size_));
    +
    70  // Skip buffer fullness indicator.
    +
    71  RCHECK(frame.SkipBits(11));
    +
    72  uint8_t num_blocks_minus_1;
    +
    73  RCHECK(frame.ReadBits(2, &num_blocks_minus_1));
    +
    74  if (num_blocks_minus_1) {
    +
    75  NOTIMPLEMENTED() << "ADTS frames with more than one data block "
    +
    76  "not supported.";
    +
    77  return false;
    +
    78  }
    +
    79  return true;
    +
    80 }
    +
    81 
    +
    82 size_t AdtsHeader::GetHeaderSize() const {
    +
    83  const size_t kCrcSize = sizeof(uint16_t);
    +
    84  return kAdtsHeaderMinSize + (protection_absent_ ? 0 : kCrcSize);
    +
    85 }
    +
    86 
    +
    87 size_t AdtsHeader::GetFrameSize() const {
    +
    88  return frame_size_;
    +
    89 }
    +
    90 
    +
    91 size_t AdtsHeader::GetFrameSizeWithoutParsing(const uint8_t* data,
    +
    92  size_t num_bytes) const {
    +
    93  DCHECK_GT(num_bytes, static_cast<size_t>(5));
    +
    94  return ((static_cast<int>(data[5]) >> 5) | (static_cast<int>(data[4]) << 3) |
    +
    95  ((static_cast<int>(data[3]) & 0x3) << 11));
    +
    96 }
    +
    97 
    +
    98 void AdtsHeader::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
    +
    99  DCHECK(buffer);
    +
    100  buffer->clear();
    +
    101  BitWriter config(buffer);
    +
    102  config.WriteBits(GetObjectType(), 5);
    +
    103  config.WriteBits(sampling_frequency_index_, 4);
    +
    104  config.WriteBits(channel_configuration_, 4);
    +
    105  config.Flush();
    +
    106 }
    +
    107 
    +
    108 uint8_t AdtsHeader::GetObjectType() const {
    +
    109  return profile_ + 1;
    +
    110 }
    +
    111 
    + +
    113  DCHECK_LT(sampling_frequency_index_, kAdtsFrequencyTableSize);
    +
    114  return kAdtsFrequencyTable[sampling_frequency_index_];
    +
    115 }
    +
    116 
    +
    117 uint8_t AdtsHeader::GetNumChannels() const {
    +
    118  DCHECK_LT(channel_configuration_, kAdtsNumChannelsTableSize);
    +
    119  return kAdtsNumChannelsTable[channel_configuration_];
    +
    120 }
    +
    121 
    +
    122 } // namespace mp2t
    +
    123 } // namespace media
    +
    124 } // namespace shaka
    +
    A class to read bit streams.
    Definition: bit_reader.h:17
    +
    bool SkipBits(size_t num_bits)
    Definition: bit_reader.cc:24
    +
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    + +
    void Flush()
    Write pending bits, and align bitstream with extra zero bits.
    Definition: bit_writer.cc:31
    +
    void WriteBits(uint32_t bits, size_t number_of_bits)
    Definition: bit_writer.cc:15
    +
    size_t GetSamplesPerFrame() const override
    Definition: adts_header.cc:41
    +
    uint8_t GetNumChannels() const override
    Definition: adts_header.cc:117
    +
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    Definition: adts_header.cc:98
    +
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    Definition: adts_header.cc:91
    +
    size_t GetHeaderSize() const override
    Definition: adts_header.cc:82
    +
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: adts_header.cc:33
    +
    bool Parse(const uint8_t *adts_frame, size_t adts_frame_size) override
    Definition: adts_header.cc:46
    +
    size_t GetMinFrameSize() const override
    Definition: adts_header.cc:37
    +
    uint8_t GetObjectType() const override
    Definition: adts_header.cc:108
    +
    size_t GetFrameSize() const override
    Definition: adts_header.cc:87
    +
    uint32_t GetSamplingFrequency() const override
    Definition: adts_header.cc:112
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d5c/mpd__flags_8h_source.html b/docs/de/d5c/mpd__flags_8h_source.html index 1ee3198a6e..b1bdee9805 100644 --- a/docs/de/d5c/mpd__flags_8h_source.html +++ b/docs/de/d5c/mpd__flags_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/mpd_flags.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mpd_flags.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Defines Mpd flags.
    8 
    9 #ifndef APP_MPD_FLAGS_H_
    10 #define APP_MPD_FLAGS_H_
    11 
    12 #include <gflags/gflags.h>
    13 
    14 DECLARE_bool(generate_static_live_mpd);
    15 DECLARE_bool(output_media_info);
    16 DECLARE_string(mpd_output);
    17 DECLARE_string(base_urls);
    18 DECLARE_double(minimum_update_period);
    19 DECLARE_double(min_buffer_time);
    20 DECLARE_double(suggested_presentation_delay);
    21 DECLARE_string(utc_timings);
    22 DECLARE_bool(generate_dash_if_iop_compliant_mpd);
    23 DECLARE_bool(allow_approximate_segment_timeline);
    24 
    25 #endif // APP_MPD_FLAGS_H_
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Defines Mpd flags.
    +
    8 
    +
    9 #ifndef APP_MPD_FLAGS_H_
    +
    10 #define APP_MPD_FLAGS_H_
    +
    11 
    +
    12 #include <gflags/gflags.h>
    +
    13 
    +
    14 DECLARE_bool(generate_static_live_mpd);
    +
    15 DECLARE_bool(output_media_info);
    +
    16 DECLARE_string(mpd_output);
    +
    17 DECLARE_string(base_urls);
    +
    18 DECLARE_double(minimum_update_period);
    +
    19 DECLARE_double(min_buffer_time);
    +
    20 DECLARE_double(suggested_presentation_delay);
    +
    21 DECLARE_string(utc_timings);
    +
    22 DECLARE_bool(generate_dash_if_iop_compliant_mpd);
    +
    23 DECLARE_bool(allow_approximate_segment_timeline);
    +
    24 DECLARE_bool(allow_codec_switching);
    +
    25 DECLARE_bool(include_mspr_pro_for_playready);
    +
    26 
    +
    27 #endif // APP_MPD_FLAGS_H_
    +
    diff --git a/docs/de/d60/classshaka_1_1media_1_1mp2t_1_1ProgramMapTableWriter-members.html b/docs/de/d60/classshaka_1_1media_1_1mp2t_1_1ProgramMapTableWriter-members.html index 78a5261c10..501a0f8ec9 100644 --- a/docs/de/d60/classshaka_1_1media_1_1mp2t_1_1ProgramMapTableWriter-members.html +++ b/docs/de/d60/classshaka_1_1media_1_1mp2t_1_1ProgramMapTableWriter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/d64/classshaka_1_1media_1_1mp2t_1_1TsWriter.html b/docs/de/d64/classshaka_1_1media_1_1mp2t_1_1TsWriter.html index 575055553e..09d835041d 100644 --- a/docs/de/d64/classshaka_1_1media_1_1mp2t_1_1TsWriter.html +++ b/docs/de/d64/classshaka_1_1media_1_1mp2t_1_1TsWriter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::TsWriter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
     TsWriter (std::unique_ptr< ProgramMapTableWriter > pmt_writer)   -virtual bool NewSegment (const std::string &file_name) -  +virtual bool NewSegment (BufferWriter *buffer) +  virtual void SignalEncrypted ()  Signals the writer that the rest of the segments are encrypted.
      -virtual bool FinalizeSegment () -  -virtual bool AddPesPacket (std::unique_ptr< PesPacket > pes_packet) -  -base::Optional< uint64_t > GetFilePosition () -  +virtual bool AddPesPacket (std::unique_ptr< PesPacket > pes_packet, BufferWriter *buffer) + 

    Detailed Description

    -

    This class takes PesPackets, encapsulates them into TS packets, and write the data to file. This also creates PSI from StreamInfo.

    +

    This class takes PesPackets, encapsulates them into TS packets, and write the data to file. This also creates PSI from StreamInfo.

    -

    Definition at line 29 of file ts_writer.h.

    +

    Definition at line 30 of file ts_writer.h.

    Member Function Documentation

    - -

    ◆ AddPesPacket()

    + +

    ◆ AddPesPacket()

    @@ -108,8 +107,18 @@ virtual void bool shaka::media::mp2t::TsWriter::AddPesPacket ( std::unique_ptr< PesPacket >  - pes_packet) + pes_packet, + + + + BufferWriter *  + buffer  + + + + ) + @@ -118,68 +127,21 @@ virtual void 
    -

    Add PesPacket to the instance. PesPacket might not get written to file immediately.

    Parameters
    +

    Add PesPacket to the instance. PesPacket might not be added to the buffer immediately.

    Parameters
    +
    pes_packetgets added to the writer.
    bufferto write pes packet.
    Returns
    true on success, false otherwise.
    -

    Definition at line 205 of file ts_writer.cc.

    +

    Definition at line 189 of file ts_writer.cc.

    - -

    ◆ FinalizeSegment()

    - -
    -
    - - - - - -
    - - - - - - - -
    bool shaka::media::mp2t::TsWriter::FinalizeSegment ()
    -
    -virtual
    -
    -

    Flush all the pending PesPackets that have not been written to file and close the file.

    Returns
    true on success, false otherwise.
    - -

    Definition at line 201 of file ts_writer.cc.

    - -
    -
    - -

    ◆ GetFilePosition()

    - -
    -
    - - - - - - - -
    base::Optional< uint64_t > shaka::media::mp2t::TsWriter::GetFilePosition ()
    -
    -
    Returns
    current file position on success, nullopt otherwise.
    - -

    Definition at line 217 of file ts_writer.cc.

    - -
    -
    - -

    ◆ NewSegment()

    + +

    ◆ NewSegment()

    @@ -221,9 +182,7 @@ virtual void  diff --git a/docs/de/d69/single__thread__job__manager_8h_source.html b/docs/de/d69/single__thread__job__manager_8h_source.html new file mode 100644 index 0000000000..fbe2a674cf --- /dev/null +++ b/docs/de/d69/single__thread__job__manager_8h_source.html @@ -0,0 +1,114 @@ + + + + + + + +Shaka Packager SDK: packager/app/single_thread_job_manager.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    single_thread_job_manager.h
    +
    +
    +
    1 // Copyright 2020 Google LLLC All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_APP_SINGLE_THREAD_JOB_MANAGER_H_
    +
    8 #define PACKAGER_APP_SINGLE_THREAD_JOB_MANAGER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 
    +
    12 #include "packager/app/job_manager.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 // A subclass of JobManager that runs all the jobs in a single thread.
    + +
    19  public:
    +
    20  // @param sync_points is an optional SyncPointQueue used to synchronize and
    +
    21  // align cue points. JobManager cancels @a sync_points when any job
    +
    22  // fails or is cancelled. It can be NULL.
    +
    23  explicit SingleThreadJobManager(std::unique_ptr<SyncPointQueue> sync_points);
    +
    24 
    +
    25  Status InitializeJobs() override;
    +
    26  Status RunJobs() override;
    +
    27 };
    +
    28 
    +
    29 } // namespace media
    +
    30 } // namespace shaka
    +
    31 
    +
    32 #endif // PACKAGER_APP_SINGLE_THREAD_JOB_MANAGER_H_
    + + + +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/de/d6c/mock__media__playlist_8h_source.html b/docs/de/d6c/mock__media__playlist_8h_source.html index d03edb2b20..c0a499ced6 100644 --- a/docs/de/d6c/mock__media__playlist_8h_source.html +++ b/docs/de/d6c/mock__media__playlist_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/mock_media_playlist.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mock_media_playlist.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_HLS_BASE_MOCK_MEDIA_PLAYLIST_H_
    8 #define PACKAGER_HLS_BASE_MOCK_MEDIA_PLAYLIST_H_
    9 
    10 #include <gmock/gmock.h>
    11 
    12 #include "packager/hls/base/media_playlist.h"
    13 
    14 namespace shaka {
    15 namespace hls {
    16 
    18  public:
    19  // The actual parameters to MediaPlaylist() (parent) constructor doesn't
    20  // matter because the return value can be mocked.
    21  MockMediaPlaylist(const std::string& file_name,
    22  const std::string& name,
    23  const std::string& group_id);
    24  ~MockMediaPlaylist() override;
    25 
    26  MOCK_METHOD1(SetMediaInfo, bool(const MediaInfo& media_info));
    27  MOCK_METHOD5(AddSegment,
    28  void(const std::string& file_name,
    29  int64_t start_time,
    30  int64_t duration,
    31  uint64_t start_byte_offset,
    32  uint64_t size));
    33  MOCK_METHOD3(AddKeyFrame,
    34  void(int64_t timestamp,
    35  uint64_t start_byte_offset,
    36  uint64_t size));
    37  MOCK_METHOD6(AddEncryptionInfo,
    38  void(EncryptionMethod method,
    39  const std::string& url,
    40  const std::string& key_id,
    41  const std::string& iv,
    42  const std::string& key_format,
    43  const std::string& key_format_versions));
    44  MOCK_METHOD0(AddPlacementOpportunity, void());
    45  MOCK_METHOD1(WriteToFile, bool(const std::string& file_path));
    46  MOCK_CONST_METHOD0(MaxBitrate, uint64_t());
    47  MOCK_CONST_METHOD0(AvgBitrate, uint64_t());
    48  MOCK_CONST_METHOD0(GetLongestSegmentDuration, double());
    49  MOCK_METHOD1(SetTargetDuration, void(uint32_t target_duration));
    50  MOCK_CONST_METHOD0(GetNumChannels, int());
    51  MOCK_CONST_METHOD2(GetDisplayResolution,
    52  bool(uint32_t* width, uint32_t* height));
    53  MOCK_CONST_METHOD0(GetFrameRate, double());
    54 };
    55 
    56 } // namespace hls
    57 } // namespace shaka
    58 
    59 #endif // PACKAGER_HLS_BASE_MOCK_MEDIA_PLAYLIST_H_
    -
    virtual void AddKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    -
    virtual uint64_t MaxBitrate() const
    -
    virtual void SetTargetDuration(uint32_t target_duration)
    -
    All the methods that are virtual are virtual for mocking.
    -
    virtual bool SetMediaInfo(const MediaInfo &media_info)
    -
    Methods are virtual for mocking.
    -
    virtual void AddSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t start_byte_offset, uint64_t size)
    -
    virtual double GetLongestSegmentDuration() const
    -
    virtual double GetFrameRate() const
    -
    virtual void AddPlacementOpportunity()
    -
    virtual void AddEncryptionInfo(EncryptionMethod method, const std::string &url, const std::string &key_id, const std::string &iv, const std::string &key_format, const std::string &key_format_versions)
    -
    virtual bool GetDisplayResolution(uint32_t *width, uint32_t *height) const
    -
    virtual bool WriteToFile(const std::string &file_path)
    -
    virtual int GetNumChannels() const
    -
    virtual uint64_t AvgBitrate() const
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_HLS_BASE_MOCK_MEDIA_PLAYLIST_H_
    +
    8 #define PACKAGER_HLS_BASE_MOCK_MEDIA_PLAYLIST_H_
    +
    9 
    +
    10 #include <gmock/gmock.h>
    +
    11 
    +
    12 #include "packager/hls/base/media_playlist.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace hls {
    +
    16 
    + +
    18  public:
    +
    19  // The actual parameters to MediaPlaylist() (parent) constructor doesn't
    +
    20  // matter because the return value can be mocked.
    +
    21  MockMediaPlaylist(const std::string& file_name,
    +
    22  const std::string& name,
    +
    23  const std::string& group_id);
    +
    24  ~MockMediaPlaylist() override;
    +
    25 
    +
    26  MOCK_METHOD1(SetMediaInfo, bool(const MediaInfo& media_info));
    +
    27  MOCK_METHOD5(AddSegment,
    +
    28  void(const std::string& file_name,
    +
    29  int64_t start_time,
    +
    30  int64_t duration,
    +
    31  uint64_t start_byte_offset,
    +
    32  uint64_t size));
    +
    33  MOCK_METHOD3(AddKeyFrame,
    +
    34  void(int64_t timestamp,
    +
    35  uint64_t start_byte_offset,
    +
    36  uint64_t size));
    +
    37  MOCK_METHOD6(AddEncryptionInfo,
    +
    38  void(EncryptionMethod method,
    +
    39  const std::string& url,
    +
    40  const std::string& key_id,
    +
    41  const std::string& iv,
    +
    42  const std::string& key_format,
    +
    43  const std::string& key_format_versions));
    +
    44  MOCK_METHOD0(AddPlacementOpportunity, void());
    +
    45  MOCK_METHOD1(WriteToFile, bool(const std::string& file_path));
    +
    46  MOCK_CONST_METHOD0(MaxBitrate, uint64_t());
    +
    47  MOCK_CONST_METHOD0(AvgBitrate, uint64_t());
    +
    48  MOCK_CONST_METHOD0(GetLongestSegmentDuration, double());
    +
    49  MOCK_METHOD1(SetTargetDuration, void(uint32_t target_duration));
    +
    50  MOCK_CONST_METHOD0(GetNumChannels, int());
    +
    51  MOCK_CONST_METHOD0(GetEC3JocComplexity, int());
    +
    52  MOCK_CONST_METHOD0(GetAC4ImsFlag, bool());
    +
    53  MOCK_CONST_METHOD0(GetAC4CbiFlag, bool());
    +
    54  MOCK_CONST_METHOD2(GetDisplayResolution,
    +
    55  bool(uint32_t* width, uint32_t* height));
    +
    56  MOCK_CONST_METHOD0(GetFrameRate, double());
    +
    57 };
    +
    58 
    +
    59 } // namespace hls
    +
    60 } // namespace shaka
    +
    61 
    +
    62 #endif // PACKAGER_HLS_BASE_MOCK_MEDIA_PLAYLIST_H_
    +
    Methods are virtual for mocking.
    +
    virtual bool WriteToFile(const std::string &file_path)
    +
    virtual bool GetAC4ImsFlag() const
    +
    virtual void AddEncryptionInfo(EncryptionMethod method, const std::string &url, const std::string &key_id, const std::string &iv, const std::string &key_format, const std::string &key_format_versions)
    +
    virtual void AddKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    +
    virtual double GetFrameRate() const
    +
    virtual uint64_t AvgBitrate() const
    +
    virtual bool GetDisplayResolution(uint32_t *width, uint32_t *height) const
    +
    virtual double GetLongestSegmentDuration() const
    +
    virtual int GetEC3JocComplexity() const
    +
    virtual uint64_t MaxBitrate() const
    +
    virtual int GetNumChannels() const
    +
    virtual void AddPlacementOpportunity()
    +
    virtual bool SetMediaInfo(const MediaInfo &media_info)
    +
    virtual bool GetAC4CbiFlag() const
    +
    virtual void SetTargetDuration(uint32_t target_duration)
    +
    virtual void AddSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t start_byte_offset, uint64_t size)
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d6c/structshaka_1_1media_1_1mp4_1_1SampleToGroupEntry-members.html b/docs/de/d6c/structshaka_1_1media_1_1mp4_1_1SampleToGroupEntry-members.html index 0174b93be6..81efe74da0 100644 --- a/docs/de/d6c/structshaka_1_1media_1_1mp4_1_1SampleToGroupEntry-members.html +++ b/docs/de/d6c/structshaka_1_1media_1_1mp4_1_1SampleToGroupEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/de/d6e/classshaka_1_1media_1_1MockOutputMediaHandler-members.html b/docs/de/d6e/classshaka_1_1media_1_1MockOutputMediaHandler-members.html index b09d7214de..2fdcc2f4c2 100644 --- a/docs/de/d6e/classshaka_1_1media_1_1MockOutputMediaHandler-members.html +++ b/docs/de/d6e/classshaka_1_1media_1_1MockOutputMediaHandler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    This is the complete list of members for shaka::media::MockOutputMediaHandler, including all inherited members.

    - + @@ -95,9 +98,7 @@ $(function() {
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
    Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
    diff --git a/docs/de/d6e/language__utils_8h_source.html b/docs/de/d6e/language__utils_8h_source.html index 7471028712..d9647d49f6 100644 --- a/docs/de/d6e/language__utils_8h_source.html +++ b/docs/de/d6e/language__utils_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/language_utils.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    language_utils.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Funtions used by MpdBuilder class to generate an MPD file.
    8 
    9 #ifndef PACKAGER_MEDIA_BASE_LANGUAGE_UTILS_H_
    10 #define PACKAGER_MEDIA_BASE_LANGUAGE_UTILS_H_
    11 
    12 #include <string>
    13 
    14 namespace shaka {
    15 
    16 class MediaInfo;
    17 
    22 std::string LanguageToShortestForm(const std::string& language);
    23 
    27 std::string LanguageToISO_639_2(const std::string& language);
    28 
    29 } // namespace shaka
    30 
    31 #endif // PACKAGER_MEDIA_BASE_LANGUAGE_UTILS_H_
    std::string LanguageToShortestForm(const std::string &language)
    -
    All the methods that are virtual are virtual for mocking.
    -
    std::string LanguageToISO_639_2(const std::string &language)
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Funtions used by MpdBuilder class to generate an MPD file.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_BASE_LANGUAGE_UTILS_H_
    +
    10 #define PACKAGER_MEDIA_BASE_LANGUAGE_UTILS_H_
    +
    11 
    +
    12 #include <string>
    +
    13 
    +
    14 namespace shaka {
    +
    15 
    +
    16 class MediaInfo;
    +
    17 
    +
    22 std::string LanguageToShortestForm(const std::string& language);
    +
    23 
    +
    27 std::string LanguageToISO_639_2(const std::string& language);
    +
    28 
    +
    29 } // namespace shaka
    +
    30 
    +
    31 #endif // PACKAGER_MEDIA_BASE_LANGUAGE_UTILS_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    std::string LanguageToISO_639_2(const std::string &language)
    +
    std::string LanguageToShortestForm(const std::string &language)
    diff --git a/docs/de/d70/http__key__fetcher_8cc_source.html b/docs/de/d70/http__key__fetcher_8cc_source.html index c4ad657c8b..4b2f6d9f79 100644 --- a/docs/de/d70/http__key__fetcher_8cc_source.html +++ b/docs/de/d70/http__key__fetcher_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/http_key_fetcher.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    http_key_fetcher.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/http_key_fetcher.h"
    8 
    9 #include <curl/curl.h>
    10 #include <gflags/gflags.h>
    11 
    12 #include "packager/base/logging.h"
    13 #include "packager/base/strings/string_number_conversions.h"
    14 #include "packager/base/strings/stringprintf.h"
    15 #include "packager/base/synchronization/lock.h"
    16 
    17 DEFINE_bool(disable_peer_verification,
    18  false,
    19  "Disable peer verification. This is needed to talk to servers "
    20  "without valid certificates.");
    21 
    22 namespace shaka {
    23 
    24 namespace {
    25 const char kUserAgentString[] = "shaka-packager-http_fetcher/1.0";
    26 const char kSoapActionHeader[] =
    27  "SOAPAction: \"http://schemas.microsoft.com/DRM/2007/03/protocols/"
    28  "AcquirePackagingData\"";
    29 const char kXmlContentTypeHeader[] = "Content-Type: text/xml; charset=UTF-8";
    30 const char kJsonContentTypeHeader[] = "Content-Type: application/json";
    31 
    32 const int kMinLogLevelForCurlDebugFunction = 2;
    33 
    34 int CurlDebugFunction(CURL* /* handle */,
    35  curl_infotype type,
    36  const char* data,
    37  size_t size,
    38  void* /* userptr */) {
    39  const char* type_text;
    40  int log_level = kMinLogLevelForCurlDebugFunction;
    41  switch (type) {
    42  case CURLINFO_TEXT:
    43  type_text = "== Info";
    44  log_level = kMinLogLevelForCurlDebugFunction + 1;
    45  break;
    46  case CURLINFO_HEADER_IN:
    47  type_text = "<= Recv header";
    48  log_level = kMinLogLevelForCurlDebugFunction;
    49  break;
    50  case CURLINFO_HEADER_OUT:
    51  type_text = "=> Send header";
    52  log_level = kMinLogLevelForCurlDebugFunction;
    53  break;
    54  case CURLINFO_DATA_IN:
    55  type_text = "<= Recv data";
    56  log_level = kMinLogLevelForCurlDebugFunction + 1;
    57  break;
    58  case CURLINFO_DATA_OUT:
    59  type_text = "=> Send data";
    60  log_level = kMinLogLevelForCurlDebugFunction + 1;
    61  break;
    62  case CURLINFO_SSL_DATA_IN:
    63  type_text = "<= Recv SSL data";
    64  log_level = kMinLogLevelForCurlDebugFunction + 2;
    65  break;
    66  case CURLINFO_SSL_DATA_OUT:
    67  type_text = "=> Send SSL data";
    68  log_level = kMinLogLevelForCurlDebugFunction + 2;
    69  break;
    70  default:
    71  // Ignore other debug data.
    72  return 0;
    73  }
    74 
    75  VLOG(log_level) << "\n\n"
    76  << type_text << " (0x" << std::hex << size << std::dec
    77  << " bytes)"
    78  << "\n"
    79  << std::string(data, size) << "\nHex Format: \n"
    80  << base::HexEncode(data, size);
    81  return 0;
    82 }
    83 
    84 // Scoped CURL implementation which cleans up itself when goes out of scope.
    85 class ScopedCurl {
    86  public:
    87  ScopedCurl() { ptr_ = curl_easy_init(); }
    88  ~ScopedCurl() {
    89  if (ptr_)
    90  curl_easy_cleanup(ptr_);
    91  }
    92 
    93  CURL* get() { return ptr_; }
    94 
    95  private:
    96  CURL* ptr_;
    97  DISALLOW_COPY_AND_ASSIGN(ScopedCurl);
    98 };
    99 
    100 size_t AppendToString(char* ptr, size_t size, size_t nmemb, std::string* response) {
    101  DCHECK(ptr);
    102  DCHECK(response);
    103  const size_t total_size = size * nmemb;
    104  response->append(ptr, total_size);
    105  return total_size;
    106 }
    107 
    108 class LibCurlInitializer {
    109  public:
    110  LibCurlInitializer() : initialized_(false) {
    111  base::AutoLock lock(lock_);
    112  if (!initialized_) {
    113  curl_global_init(CURL_GLOBAL_DEFAULT);
    114  initialized_ = true;
    115  }
    116  }
    117 
    118  ~LibCurlInitializer() {
    119  base::AutoLock lock(lock_);
    120  if (initialized_) {
    121  curl_global_cleanup();
    122  initialized_ = false;
    123  }
    124  }
    125 
    126  private:
    127  base::Lock lock_;
    128  bool initialized_;
    129 
    130  DISALLOW_COPY_AND_ASSIGN(LibCurlInitializer);
    131 };
    132 
    133 } // namespace
    134 
    135 namespace media {
    136 
    137 HttpKeyFetcher::HttpKeyFetcher() : timeout_in_seconds_(0) {}
    138 
    139 HttpKeyFetcher::HttpKeyFetcher(uint32_t timeout_in_seconds)
    140  : timeout_in_seconds_(timeout_in_seconds) {}
    141 
    142 HttpKeyFetcher::~HttpKeyFetcher() {}
    143 
    144 Status HttpKeyFetcher::FetchKeys(const std::string& url,
    145  const std::string& request,
    146  std::string* response) {
    147  return Post(url, request, response);
    148 }
    149 
    150 Status HttpKeyFetcher::Get(const std::string& path, std::string* response) {
    151  return FetchInternal(GET, path, "", response);
    152 }
    153 
    154 Status HttpKeyFetcher::Post(const std::string& path,
    155  const std::string& data,
    156  std::string* response) {
    157  return FetchInternal(POST, path, data, response);
    158 }
    159 
    160 Status HttpKeyFetcher::FetchInternal(HttpMethod method,
    161  const std::string& path,
    162  const std::string& data,
    163  std::string* response) {
    164  DCHECK(method == GET || method == POST);
    165  static LibCurlInitializer lib_curl_initializer;
    166 
    167  ScopedCurl scoped_curl;
    168  CURL* curl = scoped_curl.get();
    169  if (!curl) {
    170  LOG(ERROR) << "curl_easy_init() failed.";
    171  return Status(error::HTTP_FAILURE, "curl_easy_init() failed.");
    172  }
    173  response->clear();
    174 
    175  curl_easy_setopt(curl, CURLOPT_URL, path.c_str());
    176  curl_easy_setopt(curl, CURLOPT_USERAGENT, kUserAgentString);
    177  curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout_in_seconds_);
    178  curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
    179  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    180  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, AppendToString);
    181  curl_easy_setopt(curl, CURLOPT_WRITEDATA, response);
    182 
    183  if (FLAGS_disable_peer_verification)
    184  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    185 
    186  if (!client_cert_private_key_file_.empty() && !client_cert_file_.empty()) {
    187  // Some PlayReady packaging servers only allow connects via HTTPS with
    188  // client certificates.
    189  curl_easy_setopt(curl, CURLOPT_SSLKEY,
    190  client_cert_private_key_file_.data());
    191  if (!client_cert_private_key_password_.empty()) {
    192  curl_easy_setopt(curl, CURLOPT_KEYPASSWD,
    193  client_cert_private_key_password_.data());
    194  }
    195  curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
    196  curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
    197  curl_easy_setopt(curl, CURLOPT_SSLCERT, client_cert_file_.data());
    198  }
    199  if (!ca_file_.empty()) {
    200  // Host validation needs to be off when using self-signed certificates.
    201  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
    202  curl_easy_setopt(curl, CURLOPT_CAINFO, ca_file_.data());
    203  }
    204  if (method == POST) {
    205  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
    206  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.size());
    207 
    208  curl_slist* chunk = nullptr;
    209  if (data.find("soap:Envelope") != std::string::npos) {
    210  // Adds Http headers for SOAP requests.
    211  chunk = curl_slist_append(chunk, kXmlContentTypeHeader);
    212  chunk = curl_slist_append(chunk, kSoapActionHeader);
    213  } else {
    214  chunk = curl_slist_append(chunk, kJsonContentTypeHeader);
    215  }
    216  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
    217  }
    218 
    219  if (VLOG_IS_ON(kMinLogLevelForCurlDebugFunction)) {
    220  curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, CurlDebugFunction);
    221  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    222  }
    223 
    224  CURLcode res = curl_easy_perform(curl);
    225  if (res != CURLE_OK) {
    226  std::string error_message = base::StringPrintf(
    227  "curl_easy_perform() failed: %s.", curl_easy_strerror(res));
    228  if (res == CURLE_HTTP_RETURNED_ERROR) {
    229  long response_code = 0;
    230  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
    231  error_message += base::StringPrintf(" Response code: %ld.", response_code);
    232  }
    233 
    234  LOG(ERROR) << error_message;
    235  return Status(
    236  res == CURLE_OPERATION_TIMEDOUT ? error::TIME_OUT : error::HTTP_FAILURE,
    237  error_message);
    238  }
    239  return Status::OK;
    240 }
    241 
    242 } // namespace media
    243 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    - -
    virtual Status Get(const std::string &url, std::string *response)
    -
    Status FetchKeys(const std::string &url, const std::string &request, std::string *response) override
    -
    HttpKeyFetcher()
    Creates a fetcher with no timeout.
    -
    virtual Status Post(const std::string &url, const std::string &data, std::string *response)
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/http_key_fetcher.h"
    +
    8 
    +
    9 #include "packager/file/file_closer.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 namespace media {
    +
    13 
    +
    14 namespace {
    +
    15 
    +
    16 const char kSoapActionHeader[] =
    +
    17  "SOAPAction: \"http://schemas.microsoft.com/DRM/2007/03/protocols/"
    +
    18  "AcquirePackagingData\"";
    +
    19 const char kXmlContentType[] = "text/xml; charset=UTF-8";
    +
    20 const char kJsonContentType[] = "application/json";
    +
    21 constexpr size_t kBufferSize = 64 * 1024;
    +
    22 
    +
    23 } // namespace
    +
    24 
    +
    25 HttpKeyFetcher::HttpKeyFetcher() : timeout_in_seconds_(0) {}
    +
    26 
    +
    27 HttpKeyFetcher::HttpKeyFetcher(uint32_t timeout_in_seconds)
    +
    28  : timeout_in_seconds_(timeout_in_seconds) {}
    +
    29 
    +
    30 HttpKeyFetcher::~HttpKeyFetcher() {}
    +
    31 
    +
    32 Status HttpKeyFetcher::FetchKeys(const std::string& url,
    +
    33  const std::string& request,
    +
    34  std::string* response) {
    +
    35  return Post(url, request, response);
    +
    36 }
    +
    37 
    +
    38 Status HttpKeyFetcher::Get(const std::string& path, std::string* response) {
    +
    39  return FetchInternal(HttpMethod::kGet, path, "", response);
    +
    40 }
    +
    41 
    +
    42 Status HttpKeyFetcher::Post(const std::string& path,
    +
    43  const std::string& data,
    +
    44  std::string* response) {
    +
    45  return FetchInternal(HttpMethod::kPost, path, data, response);
    +
    46 }
    +
    47 
    +
    48 Status HttpKeyFetcher::FetchInternal(HttpMethod method,
    +
    49  const std::string& path,
    +
    50  const std::string& data,
    +
    51  std::string* response) {
    +
    52  std::string content_type;
    +
    53  std::vector<std::string> headers;
    +
    54  if (data.find("soap:Envelope") != std::string::npos) {
    +
    55  // Adds Http headers for SOAP requests.
    +
    56  content_type = kXmlContentType;
    +
    57  headers.push_back(kSoapActionHeader);
    +
    58  } else {
    +
    59  content_type = kJsonContentType;
    +
    60  }
    +
    61 
    +
    62  std::unique_ptr<HttpFile, FileCloser> file(
    +
    63  new HttpFile(method, path, content_type, headers, timeout_in_seconds_));
    +
    64  if (!file->Open()) {
    +
    65  return Status(error::INTERNAL_ERROR, "Cannot open URL");
    +
    66  }
    +
    67  file->Write(data.data(), data.size());
    +
    68  file->Flush();
    +
    69 
    +
    70  while (true) {
    +
    71  char temp[kBufferSize];
    +
    72  int64_t ret = file->Read(temp, kBufferSize);
    +
    73  if (ret <= 0)
    +
    74  break;
    +
    75  response->append(temp, ret);
    +
    76  }
    +
    77  return file.release()->CloseWithStatus();
    +
    78 }
    +
    79 
    +
    80 } // namespace media
    +
    81 } // namespace shaka
    + +
    HttpKeyFetcher()
    Creates a fetcher with no timeout.
    +
    virtual Status Post(const std::string &url, const std::string &data, std::string *response)
    +
    virtual Status Get(const std::string &url, std::string *response)
    +
    Status FetchKeys(const std::string &url, const std::string &request, std::string *response) override
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d75/mpeg1__header_8cc_source.html b/docs/de/d75/mpeg1__header_8cc_source.html new file mode 100644 index 0000000000..6ac38b3b6f --- /dev/null +++ b/docs/de/d75/mpeg1__header_8cc_source.html @@ -0,0 +1,339 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/mp2t/mpeg1_header.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    mpeg1_header.cc
    +
    +
    +
    1 #include "packager/media/formats/mp2t/mpeg1_header.h"
    +
    2 
    +
    3 #include "packager/media/base/bit_reader.h"
    +
    4 #include "packager/media/base/bit_writer.h"
    +
    5 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    6 
    +
    7 // Parsing is done according to
    +
    8 // https://www.datavoyage.com/mpgscript/mpeghdr.htm
    +
    9 namespace {
    +
    10 const size_t kMpeg1HeaderMinSize = 4;
    +
    11 
    +
    12 const uint8_t kMpeg1V_INV = 0b01; /* Invalid version */
    +
    13 const uint8_t kMpeg1L_INV = 0b00; /* Invalid layer */
    +
    14 
    +
    15 const uint8_t kMpeg1L_3 = 0b01;
    +
    16 const uint8_t kMpeg1L_2 = 0b10;
    +
    17 const uint8_t kMpeg1L_1 = 0b11;
    +
    18 
    +
    19 const size_t kMpeg1SamplesPerFrameTable[] = {
    +
    20  // L1, L2, L3
    +
    21  384, 1152, 1152};
    +
    22 
    +
    23 const uint32_t kMpeg1SampleRateTable[][3] = {
    +
    24  // clang-format off
    +
    25  // V1, V2, V2.5
    +
    26  {44100, 22050, 11025},
    +
    27  {48000, 24000, 12000},
    +
    28  {32000, 16000, 8000}};
    +
    29  // clang-format on
    +
    30 const size_t kMpeg1SampleRateTableSize = arraysize(kMpeg1SampleRateTable);
    +
    31 
    +
    32 static inline uint32_t Mpeg1SampleRate(uint8_t sr_idx, uint8_t version) {
    +
    33  static int sr_version_indexes[] = {2, -1, 1, 0}; // {V2.5, RESERVED, V2, V1}
    +
    34  DCHECK_NE(version, 1);
    +
    35  DCHECK_LT(sr_idx, kMpeg1SampleRateTableSize);
    +
    36  return kMpeg1SampleRateTable[sr_idx][sr_version_indexes[version]];
    +
    37 }
    +
    38 
    +
    39 const uint32_t kMpeg1BitrateTable[][5] = {
    +
    40  // clang-format off
    +
    41  // V1:L1, V1:L2, V1:L3, V2:L1, V2&V2.5:L2&L3
    +
    42  { 0, 0, 0, 0, 0},
    +
    43  { 32, 32, 32, 32, 8},
    +
    44  { 64, 48, 40, 48, 16},
    +
    45  { 96, 56, 48, 56, 24},
    +
    46  { 128, 64, 56, 64, 32},
    +
    47  { 160, 80, 64, 80, 40},
    +
    48  { 192, 96, 80, 96, 48},
    +
    49  { 224, 112, 96, 112, 56},
    +
    50  { 256, 128, 112, 128, 64},
    +
    51  { 288, 160, 128, 144, 80},
    +
    52  { 320, 192, 160, 160, 96},
    +
    53  { 352, 224, 192, 176, 112},
    +
    54  { 384, 256, 224, 192, 128},
    +
    55  { 416, 320, 256, 224, 144},
    +
    56  { 448, 384, 320, 256, 160}};
    +
    57  // clang-format on
    +
    58 const size_t kMpeg1BitrateTableSize = arraysize(kMpeg1BitrateTable);
    +
    59 
    +
    60 static inline uint32_t Mpeg1BitRate(uint8_t btr_idx,
    +
    61  uint8_t version,
    +
    62  uint8_t layer) {
    +
    63  static int btr_version_indexes[] = {1, -1, 1, 0}; // {V2.5, RESERVED, V2, V1}
    +
    64  static int btr_layer_indexes[] = {-1, 2, 1, 0}; // {RESERVED, L3, L2, L1}
    +
    65 
    +
    66  DCHECK_NE(version, 1);
    +
    67  DCHECK_NE(layer, 0);
    +
    68  int vidx = btr_version_indexes[version];
    +
    69  int lidx = btr_layer_indexes[layer];
    +
    70  if (vidx == 1 && lidx > 1)
    +
    71  lidx = 1;
    +
    72 
    +
    73  DCHECK_LT(vidx * 3 + lidx, 5);
    +
    74  DCHECK_LT(btr_idx, kMpeg1BitrateTableSize);
    +
    75  return kMpeg1BitrateTable[btr_idx][vidx * 3 + lidx] * 1000;
    +
    76 }
    +
    77 
    +
    78 static inline size_t Mpeg1FrameSize(uint8_t layer,
    +
    79  uint32_t bitrate,
    +
    80  uint32_t sample_rate,
    +
    81  uint8_t padded) {
    +
    82  DCHECK_GT(sample_rate, static_cast<uint32_t>(0));
    +
    83  if (layer == kMpeg1L_1)
    +
    84  return (12 * bitrate / sample_rate + padded) * 4;
    +
    85  return 144 * bitrate / sample_rate + padded;
    +
    86 }
    +
    87 
    +
    88 } // namespace
    +
    89 
    +
    90 namespace shaka {
    +
    91 namespace media {
    +
    92 namespace mp2t {
    +
    93 
    +
    94 bool Mpeg1Header::IsSyncWord(const uint8_t* buf) const {
    +
    95  return (buf[0] == 0xff) &&
    +
    96  ((buf[1] & 0b11100000) == 0b11100000)
    +
    97  // Version 01 is reserved
    +
    98  && ((buf[1] & 0b00011000) != 0b00001000)
    +
    99  // Layer 00 is reserved
    +
    100  && ((buf[1] & 0b00000110) != 0b00000000);
    +
    101 }
    +
    102 
    + +
    104  return kMpeg1HeaderMinSize + 1;
    +
    105 }
    +
    106 
    + +
    108  static int spf_layer_indexes[] = {-1, 2, 1, 0}; // {RESERVED, L3, L2, L1}
    +
    109  DCHECK_NE(layer_, 0);
    +
    110  return kMpeg1SamplesPerFrameTable[spf_layer_indexes[layer_]];
    +
    111 }
    +
    112 
    +
    113 bool Mpeg1Header::Parse(const uint8_t* mpeg1_frame, size_t mpeg1_frame_size) {
    +
    114  DCHECK(mpeg1_frame);
    +
    115 
    +
    116  if (mpeg1_frame_size < kMpeg1HeaderMinSize)
    +
    117  return false;
    +
    118 
    +
    119  BitReader frame(mpeg1_frame, mpeg1_frame_size);
    +
    120  // Verify frame starts with sync bits (0x7ff).
    +
    121  uint32_t sync;
    +
    122  RCHECK(frame.ReadBits(11, &sync));
    +
    123  RCHECK(sync == 0x7ff);
    +
    124  // MPEG version and layer.
    +
    125  RCHECK(frame.ReadBits(2, &version_));
    +
    126  RCHECK(version_ != kMpeg1V_INV);
    +
    127  RCHECK(frame.ReadBits(2, &layer_));
    +
    128  RCHECK(layer_ != kMpeg1L_INV);
    +
    129  RCHECK(frame.ReadBits(1, &protection_absent_));
    +
    130 
    +
    131  uint8_t btr_idx;
    +
    132  RCHECK(frame.ReadBits(4, &btr_idx));
    +
    133  RCHECK(btr_idx > 0);
    +
    134  bitrate_ = Mpeg1BitRate(btr_idx, version_, layer_);
    +
    135 
    +
    136  uint8_t sr_idx;
    +
    137  RCHECK(frame.ReadBits(2, &sr_idx));
    +
    138  RCHECK(sr_idx < 0b11);
    +
    139  sample_rate_ = Mpeg1SampleRate(sr_idx, version_);
    +
    140 
    +
    141  RCHECK(frame.ReadBits(1, &padded_));
    +
    142  // Skip private stream bit.
    +
    143  RCHECK(frame.SkipBits(1));
    +
    144 
    +
    145  RCHECK(frame.ReadBits(2, &channel_mode_));
    +
    146  // Skip Mode extension
    +
    147  RCHECK(frame.SkipBits(2));
    +
    148  // Skip copyright, origination and emphasis info.
    +
    149  RCHECK(frame.SkipBits(4));
    +
    150 
    +
    151  return true;
    +
    152 }
    +
    153 
    + +
    155  // Unlike ADTS, for MP3, the whole frame is included in the media sample, so
    +
    156  // return 0 header size.
    +
    157  return 0;
    +
    158 }
    +
    159 
    + +
    161  return Mpeg1FrameSize(layer_, bitrate_, sample_rate_, padded_);
    +
    162 }
    +
    163 
    +
    164 size_t Mpeg1Header::GetFrameSizeWithoutParsing(const uint8_t* data,
    +
    165  size_t num_bytes) const {
    +
    166  DCHECK_GT(num_bytes, static_cast<size_t>(2));
    +
    167  uint8_t version = (data[1] & 0b00011000) >> 3;
    +
    168  uint8_t layer = (data[1] & 0b00000110) >> 1;
    +
    169  uint8_t btr_idx = (data[2] & 0b11110000) >> 4;
    +
    170  uint8_t sr_idx = (data[2] & 0b00001100) >> 2;
    +
    171  uint8_t padded = (data[2] & 0b00000010) >> 1;
    +
    172 
    +
    173  if ((version == kMpeg1V_INV) || (layer == kMpeg1L_INV) || (btr_idx == 0) ||
    +
    174  (sr_idx == 0b11))
    +
    175  return 0;
    +
    176 
    +
    177  uint32_t bitrate = Mpeg1BitRate(btr_idx, version, layer);
    +
    178  uint32_t samplerate = Mpeg1SampleRate(sr_idx, version);
    +
    179  return Mpeg1FrameSize(layer, bitrate, samplerate, padded);
    +
    180 }
    +
    181 
    +
    182 void Mpeg1Header::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
    +
    183  // The following conversion table is extracted from ISO 14496 Part 3 -
    +
    184  // Table 1.16 - Sampling Frequency Index.
    +
    185  static const size_t kConfigFrequencyTable[] = {
    +
    186  96000, 88200, 64000, 48000, 44100, 32000, 24000,
    +
    187  22050, 16000, 12000, 11025, 8000, 7350};
    +
    188  static const size_t kConfigFrequencyTableSize =
    +
    189  arraysize(kConfigFrequencyTable);
    +
    190  uint8_t cft_idx;
    +
    191 
    +
    192  for (cft_idx = 0; cft_idx < kConfigFrequencyTableSize; cft_idx++)
    +
    193  if (sample_rate_ == kConfigFrequencyTable[cft_idx])
    +
    194  break;
    +
    195 
    +
    196  DCHECK(buffer);
    +
    197  buffer->clear();
    +
    198  BitWriter config(buffer);
    +
    199 
    +
    200  // ISO/IEC 14496:3 Table 1.16 Syntax of GetAudioObjetType()
    +
    201  auto object_type = GetObjectType();
    +
    202  if (object_type <= 31) {
    +
    203  config.WriteBits(object_type, 5);
    +
    204  } else {
    +
    205  config.WriteBits(31, 5);
    +
    206  config.WriteBits(object_type - 32, 6);
    +
    207  }
    +
    208 
    +
    209  config.WriteBits(cft_idx, 4);
    +
    210  /*
    +
    211  * NOTE: Number of channels matches channel_configuration index,
    +
    212  * since mpeg1 audio has only 1 or 2 channels
    +
    213  */
    +
    214  config.WriteBits(GetNumChannels(), 4);
    +
    215  config.Flush();
    +
    216 }
    +
    217 
    +
    218 uint8_t Mpeg1Header::GetObjectType() const {
    +
    219  /*
    +
    220  * ISO14496-3:2009 Table 1.17 - Audio Object Types
    +
    221  */
    +
    222  if (layer_ == kMpeg1L_1)
    +
    223  return 32;
    +
    224  if (layer_ == kMpeg1L_2)
    +
    225  return 33;
    +
    226 
    +
    227  DCHECK_EQ(layer_, kMpeg1L_3);
    +
    228  return 34;
    +
    229 }
    +
    230 
    + +
    232  return sample_rate_;
    +
    233 }
    +
    234 
    + +
    236  if (channel_mode_ == 0b11)
    +
    237  return 1;
    +
    238  return 2;
    +
    239 }
    +
    240 
    +
    241 } // namespace mp2t
    +
    242 } // namespace media
    +
    243 } // namespace shaka
    +
    A class to read bit streams.
    Definition: bit_reader.h:17
    +
    bool SkipBits(size_t num_bits)
    Definition: bit_reader.cc:24
    +
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    + +
    void Flush()
    Write pending bits, and align bitstream with extra zero bits.
    Definition: bit_writer.cc:31
    +
    void WriteBits(uint32_t bits, size_t number_of_bits)
    Definition: bit_writer.cc:15
    +
    size_t GetMinFrameSize() const override
    +
    size_t GetFrameSize() const override
    +
    void GetAudioSpecificConfig(std::vector< uint8_t > *buffer) const override
    +
    size_t GetFrameSizeWithoutParsing(const uint8_t *data, size_t num_bytes) const override
    +
    bool IsSyncWord(const uint8_t *buf) const override
    Definition: mpeg1_header.cc:94
    +
    uint8_t GetObjectType() const override
    +
    uint8_t GetNumChannels() const override
    +
    size_t GetSamplesPerFrame() const override
    +
    uint32_t GetSamplingFrequency() const override
    +
    bool Parse(const uint8_t *mpeg1_frame, size_t mpeg1_frame_size) override
    +
    size_t GetHeaderSize() const override
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/de/d76/proto__json__util_8h_source.html b/docs/de/d76/proto__json__util_8h_source.html index d0fb42fabb..95d92336b4 100644 --- a/docs/de/d76/proto__json__util_8h_source.html +++ b/docs/de/d76/proto__json__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/proto_json_util.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    proto_json_util.h
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_
    8 #define PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_
    9 
    10 #include <string>
    11 
    12 namespace google {
    13 namespace protobuf {
    14 class Message;
    15 } // namespace protobuf
    16 } // namespace google
    17 
    18 namespace shaka {
    19 namespace media {
    20 
    24 std::string MessageToJsonString(const google::protobuf::Message& message);
    25 
    30 bool JsonStringToMessage(const std::string& input,
    31  google::protobuf::Message* message);
    32 
    33 } // namespace media
    34 } // namespace shaka
    35 
    36 #endif // PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_
    +
    8 #define PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 namespace google {
    +
    13 namespace protobuf {
    +
    14 class Message;
    +
    15 } // namespace protobuf
    +
    16 } // namespace google
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    +
    24 std::string MessageToJsonString(const google::protobuf::Message& message);
    +
    25 
    +
    30 bool JsonStringToMessage(const std::string& input,
    +
    31  google::protobuf::Message* message);
    +
    32 
    +
    33 } // namespace media
    +
    34 } // namespace shaka
    +
    35 
    +
    36 #endif // PACKAGER_MEDIA_BASE_PROTO_JSON_UTIL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d77/webm__content__encodings__client_8cc_source.html b/docs/de/d77/webm__content__encodings__client_8cc_source.html index 0aedc132c7..e50b768090 100644 --- a/docs/de/d77/webm__content__encodings__client_8cc_source.html +++ b/docs/de/d77/webm__content__encodings__client_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_content_encodings_client.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    webm_content_encodings_client.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/webm/webm_content_encodings_client.h"
    6 
    7 #include "packager/base/logging.h"
    8 #include "packager/media/formats/webm/webm_constants.h"
    9 
    10 namespace shaka {
    11 namespace media {
    12 
    13 WebMContentEncodingsClient::WebMContentEncodingsClient()
    14  : content_encryption_encountered_(false), content_encodings_ready_(false) {}
    15 
    16 WebMContentEncodingsClient::~WebMContentEncodingsClient() {}
    17 
    18 const ContentEncodings& WebMContentEncodingsClient::content_encodings() const {
    19  DCHECK(content_encodings_ready_);
    20  return content_encodings_;
    21 }
    22 
    24  if (id == kWebMIdContentEncodings) {
    25  DCHECK(!cur_content_encoding_.get());
    26  DCHECK(!content_encryption_encountered_);
    27  content_encodings_.clear();
    28  content_encodings_ready_ = false;
    29  return this;
    30  }
    31 
    32  if (id == kWebMIdContentEncoding) {
    33  DCHECK(!cur_content_encoding_.get());
    34  DCHECK(!content_encryption_encountered_);
    35  cur_content_encoding_.reset(new ContentEncoding());
    36  return this;
    37  }
    38 
    39  if (id == kWebMIdContentEncryption) {
    40  DCHECK(cur_content_encoding_.get());
    41  if (content_encryption_encountered_) {
    42  LOG(ERROR) << "Unexpected multiple ContentEncryption.";
    43  return NULL;
    44  }
    45  content_encryption_encountered_ = true;
    46  return this;
    47  }
    48 
    49  if (id == kWebMIdContentEncAESSettings) {
    50  DCHECK(cur_content_encoding_.get());
    51  return this;
    52  }
    53 
    54  // This should not happen if WebMListParser is working properly.
    55  DCHECK(false);
    56  return NULL;
    57 }
    58 
    59 // Mandatory occurrence restriction is checked in this function. Multiple
    60 // occurrence restriction is checked in OnUInt and OnBinary.
    61 bool WebMContentEncodingsClient::OnListEnd(int id) {
    62  if (id == kWebMIdContentEncodings) {
    63  // ContentEncoding element is mandatory. Check this!
    64  if (content_encodings_.empty()) {
    65  LOG(ERROR) << "Missing ContentEncoding.";
    66  return false;
    67  }
    68  content_encodings_ready_ = true;
    69  return true;
    70  }
    71 
    72  if (id == kWebMIdContentEncoding) {
    73  DCHECK(cur_content_encoding_.get());
    74 
    75  //
    76  // Specify default values to missing mandatory elements.
    77  //
    78 
    79  if (cur_content_encoding_->order() == ContentEncoding::kOrderInvalid) {
    80  // Default value of encoding order is 0, which should only be used on the
    81  // first ContentEncoding.
    82  if (!content_encodings_.empty()) {
    83  LOG(ERROR) << "Missing ContentEncodingOrder.";
    84  return false;
    85  }
    86  cur_content_encoding_->set_order(0);
    87  }
    88 
    89  if (cur_content_encoding_->scope() == ContentEncoding::kScopeInvalid)
    90  cur_content_encoding_->set_scope(ContentEncoding::kScopeAllFrameContents);
    91 
    92  if (cur_content_encoding_->type() == ContentEncoding::kTypeInvalid)
    93  cur_content_encoding_->set_type(ContentEncoding::kTypeCompression);
    94 
    95  // Check for elements valid in spec but not supported for now.
    96  if (cur_content_encoding_->type() == ContentEncoding::kTypeCompression) {
    97  LOG(ERROR) << "ContentCompression not supported.";
    98  return false;
    99  }
    100 
    101  // Enforce mandatory elements without default values.
    102  DCHECK_EQ(cur_content_encoding_->type(), ContentEncoding::kTypeEncryption);
    103  if (!content_encryption_encountered_) {
    104  LOG(ERROR) << "ContentEncodingType is encryption but"
    105  << " ContentEncryption is missing.";
    106  return false;
    107  }
    108 
    109  content_encodings_.push_back(std::move(cur_content_encoding_));
    110  content_encryption_encountered_ = false;
    111  return true;
    112  }
    113 
    114  if (id == kWebMIdContentEncryption) {
    115  DCHECK(cur_content_encoding_.get());
    116  // Specify default value for elements that are not present.
    117  if (cur_content_encoding_->encryption_algo() ==
    118  ContentEncoding::kEncAlgoInvalid) {
    119  cur_content_encoding_->set_encryption_algo(
    120  ContentEncoding::kEncAlgoNotEncrypted);
    121  }
    122  return true;
    123  }
    124 
    125  if (id == kWebMIdContentEncAESSettings) {
    126  if (cur_content_encoding_->cipher_mode() ==
    127  ContentEncoding::kCipherModeInvalid)
    128  cur_content_encoding_->set_cipher_mode(ContentEncoding::kCipherModeCtr);
    129  return true;
    130  }
    131 
    132  // This should not happen if WebMListParser is working properly.
    133  DCHECK(false);
    134  return false;
    135 }
    136 
    137 // Multiple occurrence restriction and range are checked in this function.
    138 // Mandatory occurrence restriction is checked in OnListEnd.
    139 bool WebMContentEncodingsClient::OnUInt(int id, int64_t val) {
    140  DCHECK(cur_content_encoding_.get());
    141 
    142  if (id == kWebMIdContentEncodingOrder) {
    143  if (cur_content_encoding_->order() != ContentEncoding::kOrderInvalid) {
    144  LOG(ERROR) << "Unexpected multiple ContentEncodingOrder.";
    145  return false;
    146  }
    147 
    148  if (val != static_cast<int64_t>(content_encodings_.size())) {
    149  // According to the spec, encoding order starts with 0 and counts upwards.
    150  LOG(ERROR) << "Unexpected ContentEncodingOrder.";
    151  return false;
    152  }
    153 
    154  cur_content_encoding_->set_order(val);
    155  return true;
    156  }
    157 
    158  if (id == kWebMIdContentEncodingScope) {
    159  if (cur_content_encoding_->scope() != ContentEncoding::kScopeInvalid) {
    160  LOG(ERROR) << "Unexpected multiple ContentEncodingScope.";
    161  return false;
    162  }
    163 
    164  if (val == ContentEncoding::kScopeInvalid ||
    165  val > ContentEncoding::kScopeMax) {
    166  LOG(ERROR) << "Unexpected ContentEncodingScope.";
    167  return false;
    168  }
    169 
    170  if (val & ContentEncoding::kScopeNextContentEncodingData) {
    171  LOG(ERROR) << "Encoded next ContentEncoding is not "
    172  "supported.";
    173  return false;
    174  }
    175 
    176  cur_content_encoding_->set_scope(static_cast<ContentEncoding::Scope>(val));
    177  return true;
    178  }
    179 
    180  if (id == kWebMIdContentEncodingType) {
    181  if (cur_content_encoding_->type() != ContentEncoding::kTypeInvalid) {
    182  LOG(ERROR) << "Unexpected multiple ContentEncodingType.";
    183  return false;
    184  }
    185 
    186  if (val == ContentEncoding::kTypeCompression) {
    187  LOG(ERROR) << "ContentCompression not supported.";
    188  return false;
    189  }
    190 
    191  if (val != ContentEncoding::kTypeEncryption) {
    192  LOG(ERROR) << "Unexpected ContentEncodingType " << val << ".";
    193  return false;
    194  }
    195 
    196  cur_content_encoding_->set_type(static_cast<ContentEncoding::Type>(val));
    197  return true;
    198  }
    199 
    200  if (id == kWebMIdContentEncAlgo) {
    201  if (cur_content_encoding_->encryption_algo() !=
    202  ContentEncoding::kEncAlgoInvalid) {
    203  LOG(ERROR) << "Unexpected multiple ContentEncAlgo.";
    204  return false;
    205  }
    206 
    207  if (val < ContentEncoding::kEncAlgoNotEncrypted ||
    208  val > ContentEncoding::kEncAlgoAes) {
    209  LOG(ERROR) << "Unexpected ContentEncAlgo " << val << ".";
    210  return false;
    211  }
    212 
    213  cur_content_encoding_->set_encryption_algo(
    214  static_cast<ContentEncoding::EncryptionAlgo>(val));
    215  return true;
    216  }
    217 
    218  if (id == kWebMIdAESSettingsCipherMode) {
    219  if (cur_content_encoding_->cipher_mode() !=
    220  ContentEncoding::kCipherModeInvalid) {
    221  LOG(ERROR) << "Unexpected multiple AESSettingsCipherMode.";
    222  return false;
    223  }
    224 
    225  if (val != ContentEncoding::kCipherModeCtr) {
    226  LOG(ERROR) << "Unexpected AESSettingsCipherMode " << val << ".";
    227  return false;
    228  }
    229 
    230  cur_content_encoding_->set_cipher_mode(
    231  static_cast<ContentEncoding::CipherMode>(val));
    232  return true;
    233  }
    234 
    235  // This should not happen if WebMListParser is working properly.
    236  DCHECK(false);
    237  return false;
    238 }
    239 
    240 // Multiple occurrence restriction is checked in this function. Mandatory
    241 // restriction is checked in OnListEnd.
    242 bool WebMContentEncodingsClient::OnBinary(int id,
    243  const uint8_t* data,
    244  int size) {
    245  DCHECK(cur_content_encoding_.get());
    246  DCHECK(data);
    247  DCHECK_GT(size, 0);
    248 
    249  if (id == kWebMIdContentEncKeyID) {
    250  if (!cur_content_encoding_->encryption_key_id().empty()) {
    251  LOG(ERROR) << "Unexpected multiple ContentEncKeyID";
    252  return false;
    253  }
    254  cur_content_encoding_->SetEncryptionKeyId(data, size);
    255  return true;
    256  }
    257 
    258  // This should not happen if WebMListParser is working properly.
    259  DCHECK(false);
    260  return false;
    261 }
    262 
    263 } // namespace media
    264 } // namespace shaka
    -
    All the methods that are virtual are virtual for mocking.
    - -
    WebMParserClient * OnListStart(int id) override
    WebMParserClient methods.
    - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/webm/webm_content_encodings_client.h"
    +
    6 
    +
    7 #include "packager/base/logging.h"
    +
    8 #include "packager/media/formats/webm/webm_constants.h"
    +
    9 
    +
    10 namespace shaka {
    +
    11 namespace media {
    +
    12 
    +
    13 WebMContentEncodingsClient::WebMContentEncodingsClient()
    +
    14  : content_encryption_encountered_(false), content_encodings_ready_(false) {}
    +
    15 
    +
    16 WebMContentEncodingsClient::~WebMContentEncodingsClient() {}
    +
    17 
    +
    18 const ContentEncodings& WebMContentEncodingsClient::content_encodings() const {
    +
    19  DCHECK(content_encodings_ready_);
    +
    20  return content_encodings_;
    +
    21 }
    +
    22 
    +
    23 WebMParserClient* WebMContentEncodingsClient::OnListStart(int id) {
    +
    24  if (id == kWebMIdContentEncodings) {
    +
    25  DCHECK(!cur_content_encoding_.get());
    +
    26  DCHECK(!content_encryption_encountered_);
    +
    27  content_encodings_.clear();
    +
    28  content_encodings_ready_ = false;
    +
    29  return this;
    +
    30  }
    +
    31 
    +
    32  if (id == kWebMIdContentEncoding) {
    +
    33  DCHECK(!cur_content_encoding_.get());
    +
    34  DCHECK(!content_encryption_encountered_);
    +
    35  cur_content_encoding_.reset(new ContentEncoding());
    +
    36  return this;
    +
    37  }
    +
    38 
    +
    39  if (id == kWebMIdContentEncryption) {
    +
    40  DCHECK(cur_content_encoding_.get());
    +
    41  if (content_encryption_encountered_) {
    +
    42  LOG(ERROR) << "Unexpected multiple ContentEncryption.";
    +
    43  return NULL;
    +
    44  }
    +
    45  content_encryption_encountered_ = true;
    +
    46  return this;
    +
    47  }
    +
    48 
    +
    49  if (id == kWebMIdContentEncAESSettings) {
    +
    50  DCHECK(cur_content_encoding_.get());
    +
    51  return this;
    +
    52  }
    +
    53 
    +
    54  // This should not happen if WebMListParser is working properly.
    +
    55  DCHECK(false);
    +
    56  return NULL;
    +
    57 }
    +
    58 
    +
    59 // Mandatory occurrence restriction is checked in this function. Multiple
    +
    60 // occurrence restriction is checked in OnUInt and OnBinary.
    +
    61 bool WebMContentEncodingsClient::OnListEnd(int id) {
    +
    62  if (id == kWebMIdContentEncodings) {
    +
    63  // ContentEncoding element is mandatory. Check this!
    +
    64  if (content_encodings_.empty()) {
    +
    65  LOG(ERROR) << "Missing ContentEncoding.";
    +
    66  return false;
    +
    67  }
    +
    68  content_encodings_ready_ = true;
    +
    69  return true;
    +
    70  }
    +
    71 
    +
    72  if (id == kWebMIdContentEncoding) {
    +
    73  DCHECK(cur_content_encoding_.get());
    +
    74 
    +
    75  //
    +
    76  // Specify default values to missing mandatory elements.
    +
    77  //
    +
    78 
    +
    79  if (cur_content_encoding_->order() == ContentEncoding::kOrderInvalid) {
    +
    80  // Default value of encoding order is 0, which should only be used on the
    +
    81  // first ContentEncoding.
    +
    82  if (!content_encodings_.empty()) {
    +
    83  LOG(ERROR) << "Missing ContentEncodingOrder.";
    +
    84  return false;
    +
    85  }
    +
    86  cur_content_encoding_->set_order(0);
    +
    87  }
    +
    88 
    +
    89  if (cur_content_encoding_->scope() == ContentEncoding::kScopeInvalid)
    +
    90  cur_content_encoding_->set_scope(ContentEncoding::kScopeAllFrameContents);
    +
    91 
    +
    92  if (cur_content_encoding_->type() == ContentEncoding::kTypeInvalid)
    +
    93  cur_content_encoding_->set_type(ContentEncoding::kTypeCompression);
    +
    94 
    +
    95  // Check for elements valid in spec but not supported for now.
    +
    96  if (cur_content_encoding_->type() == ContentEncoding::kTypeCompression) {
    +
    97  LOG(ERROR) << "ContentCompression not supported.";
    +
    98  return false;
    +
    99  }
    +
    100 
    +
    101  // Enforce mandatory elements without default values.
    +
    102  DCHECK_EQ(cur_content_encoding_->type(), ContentEncoding::kTypeEncryption);
    +
    103  if (!content_encryption_encountered_) {
    +
    104  LOG(ERROR) << "ContentEncodingType is encryption but"
    +
    105  << " ContentEncryption is missing.";
    +
    106  return false;
    +
    107  }
    +
    108 
    +
    109  content_encodings_.push_back(std::move(cur_content_encoding_));
    +
    110  content_encryption_encountered_ = false;
    +
    111  return true;
    +
    112  }
    +
    113 
    +
    114  if (id == kWebMIdContentEncryption) {
    +
    115  DCHECK(cur_content_encoding_.get());
    +
    116  // Specify default value for elements that are not present.
    +
    117  if (cur_content_encoding_->encryption_algo() ==
    +
    118  ContentEncoding::kEncAlgoInvalid) {
    +
    119  cur_content_encoding_->set_encryption_algo(
    +
    120  ContentEncoding::kEncAlgoNotEncrypted);
    +
    121  }
    +
    122  return true;
    +
    123  }
    +
    124 
    +
    125  if (id == kWebMIdContentEncAESSettings) {
    +
    126  if (cur_content_encoding_->cipher_mode() ==
    +
    127  ContentEncoding::kCipherModeInvalid)
    +
    128  cur_content_encoding_->set_cipher_mode(ContentEncoding::kCipherModeCtr);
    +
    129  return true;
    +
    130  }
    +
    131 
    +
    132  // This should not happen if WebMListParser is working properly.
    +
    133  DCHECK(false);
    +
    134  return false;
    +
    135 }
    +
    136 
    +
    137 // Multiple occurrence restriction and range are checked in this function.
    +
    138 // Mandatory occurrence restriction is checked in OnListEnd.
    +
    139 bool WebMContentEncodingsClient::OnUInt(int id, int64_t val) {
    +
    140  DCHECK(cur_content_encoding_.get());
    +
    141 
    +
    142  if (id == kWebMIdContentEncodingOrder) {
    +
    143  if (cur_content_encoding_->order() != ContentEncoding::kOrderInvalid) {
    +
    144  LOG(ERROR) << "Unexpected multiple ContentEncodingOrder.";
    +
    145  return false;
    +
    146  }
    +
    147 
    +
    148  if (val != static_cast<int64_t>(content_encodings_.size())) {
    +
    149  // According to the spec, encoding order starts with 0 and counts upwards.
    +
    150  LOG(ERROR) << "Unexpected ContentEncodingOrder.";
    +
    151  return false;
    +
    152  }
    +
    153 
    +
    154  cur_content_encoding_->set_order(val);
    +
    155  return true;
    +
    156  }
    +
    157 
    +
    158  if (id == kWebMIdContentEncodingScope) {
    +
    159  if (cur_content_encoding_->scope() != ContentEncoding::kScopeInvalid) {
    +
    160  LOG(ERROR) << "Unexpected multiple ContentEncodingScope.";
    +
    161  return false;
    +
    162  }
    +
    163 
    +
    164  if (val == ContentEncoding::kScopeInvalid ||
    +
    165  val > ContentEncoding::kScopeMax) {
    +
    166  LOG(ERROR) << "Unexpected ContentEncodingScope.";
    +
    167  return false;
    +
    168  }
    +
    169 
    +
    170  if (val & ContentEncoding::kScopeNextContentEncodingData) {
    +
    171  LOG(ERROR) << "Encoded next ContentEncoding is not "
    +
    172  "supported.";
    +
    173  return false;
    +
    174  }
    +
    175 
    +
    176  cur_content_encoding_->set_scope(static_cast<ContentEncoding::Scope>(val));
    +
    177  return true;
    +
    178  }
    +
    179 
    +
    180  if (id == kWebMIdContentEncodingType) {
    +
    181  if (cur_content_encoding_->type() != ContentEncoding::kTypeInvalid) {
    +
    182  LOG(ERROR) << "Unexpected multiple ContentEncodingType.";
    +
    183  return false;
    +
    184  }
    +
    185 
    +
    186  if (val == ContentEncoding::kTypeCompression) {
    +
    187  LOG(ERROR) << "ContentCompression not supported.";
    +
    188  return false;
    +
    189  }
    +
    190 
    +
    191  if (val != ContentEncoding::kTypeEncryption) {
    +
    192  LOG(ERROR) << "Unexpected ContentEncodingType " << val << ".";
    +
    193  return false;
    +
    194  }
    +
    195 
    +
    196  cur_content_encoding_->set_type(static_cast<ContentEncoding::Type>(val));
    +
    197  return true;
    +
    198  }
    +
    199 
    +
    200  if (id == kWebMIdContentEncAlgo) {
    +
    201  if (cur_content_encoding_->encryption_algo() !=
    +
    202  ContentEncoding::kEncAlgoInvalid) {
    +
    203  LOG(ERROR) << "Unexpected multiple ContentEncAlgo.";
    +
    204  return false;
    +
    205  }
    +
    206 
    +
    207  if (val < ContentEncoding::kEncAlgoNotEncrypted ||
    +
    208  val > ContentEncoding::kEncAlgoAes) {
    +
    209  LOG(ERROR) << "Unexpected ContentEncAlgo " << val << ".";
    +
    210  return false;
    +
    211  }
    +
    212 
    +
    213  cur_content_encoding_->set_encryption_algo(
    +
    214  static_cast<ContentEncoding::EncryptionAlgo>(val));
    +
    215  return true;
    +
    216  }
    +
    217 
    +
    218  if (id == kWebMIdAESSettingsCipherMode) {
    +
    219  if (cur_content_encoding_->cipher_mode() !=
    +
    220  ContentEncoding::kCipherModeInvalid) {
    +
    221  LOG(ERROR) << "Unexpected multiple AESSettingsCipherMode.";
    +
    222  return false;
    +
    223  }
    +
    224 
    +
    225  if (val != ContentEncoding::kCipherModeCtr) {
    +
    226  LOG(ERROR) << "Unexpected AESSettingsCipherMode " << val << ".";
    +
    227  return false;
    +
    228  }
    +
    229 
    +
    230  cur_content_encoding_->set_cipher_mode(
    +
    231  static_cast<ContentEncoding::CipherMode>(val));
    +
    232  return true;
    +
    233  }
    +
    234 
    +
    235  // This should not happen if WebMListParser is working properly.
    +
    236  DCHECK(false);
    +
    237  return false;
    +
    238 }
    +
    239 
    +
    240 // Multiple occurrence restriction is checked in this function. Mandatory
    +
    241 // restriction is checked in OnListEnd.
    +
    242 bool WebMContentEncodingsClient::OnBinary(int id,
    +
    243  const uint8_t* data,
    +
    244  int size) {
    +
    245  DCHECK(cur_content_encoding_.get());
    +
    246  DCHECK(data);
    +
    247  DCHECK_GT(size, 0);
    +
    248 
    +
    249  if (id == kWebMIdContentEncKeyID) {
    +
    250  if (!cur_content_encoding_->encryption_key_id().empty()) {
    +
    251  LOG(ERROR) << "Unexpected multiple ContentEncKeyID";
    +
    252  return false;
    +
    253  }
    +
    254  cur_content_encoding_->SetEncryptionKeyId(data, size);
    +
    255  return true;
    +
    256  }
    +
    257 
    +
    258  // This should not happen if WebMListParser is working properly.
    +
    259  DCHECK(false);
    +
    260  return false;
    +
    261 }
    +
    262 
    +
    263 } // namespace media
    +
    264 } // namespace shaka
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d7b/mp4__media__parser_8h_source.html b/docs/de/d7b/mp4__media__parser_8h_source.html index 1281940813..f9dce5644a 100644 --- a/docs/de/d7b/mp4__media__parser_8h_source.html +++ b/docs/de/d7b/mp4__media__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/mp4_media_parser.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mp4_media_parser.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_MP4_MEDIA_PARSER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_MP4_MEDIA_PARSER_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <map>
    13 #include <memory>
    14 #include <vector>
    15 
    16 #include "packager/base/callback_forward.h"
    17 #include "packager/media/base/decryptor_source.h"
    18 #include "packager/media/base/media_parser.h"
    19 #include "packager/media/base/offset_byte_queue.h"
    20 
    21 namespace shaka {
    22 namespace media {
    23 namespace mp4 {
    24 
    25 class BoxReader;
    26 class TrackRunIterator;
    27 struct Movie;
    28 struct ProtectionSystemSpecificHeader;
    29 
    30 class MP4MediaParser : public MediaParser {
    31  public:
    33  ~MP4MediaParser() override;
    34 
    37  void Init(const InitCB& init_cb,
    38  const NewSampleCB& new_sample_cb,
    39  KeySource* decryption_key_source) override;
    40  bool Flush() override WARN_UNUSED_RESULT;
    41  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
    43 
    50  bool LoadMoov(const std::string& file_path);
    51 
    52  private:
    53  enum State {
    54  kWaitingForInit,
    55  kParsingBoxes,
    56  kEmittingSamples,
    57  kError
    58  };
    59 
    60  bool ParseBox(bool* err);
    61  bool ParseMoov(mp4::BoxReader* reader);
    62  bool ParseMoof(mp4::BoxReader* reader);
    63 
    64  bool FetchKeysIfNecessary(
    65  const std::vector<ProtectionSystemSpecificHeader>& headers);
    66 
    67  // To retain proper framing, each 'mdat' box must be read; to limit memory
    68  // usage, the box's data needs to be discarded incrementally as frames are
    69  // extracted from the stream. This function discards data from the stream up
    70  // to |offset|, updating the |mdat_tail_| value so that framing can be
    71  // retained after all 'mdat' information has been read.
    72  // Returns 'true' on success, 'false' if there was an error.
    73  bool ReadAndDiscardMDATsUntil(const int64_t offset);
    74 
    75  void ChangeState(State new_state);
    76 
    77  bool EmitConfigs();
    78 
    79  bool EnqueueSample(bool* err);
    80 
    81  void Reset();
    82 
    83  State state_;
    84  InitCB init_cb_;
    85  NewSampleCB new_sample_cb_;
    86  KeySource* decryption_key_source_;
    87  std::unique_ptr<DecryptorSource> decryptor_source_;
    88 
    89  OffsetByteQueue queue_;
    90 
    91  // These two parameters are only valid in the |kEmittingSegments| state.
    92  //
    93  // |moof_head_| is the offset of the start of the most recently parsed moof
    94  // block. All byte offsets in sample information are relative to this offset,
    95  // as mandated by the Media Source spec.
    96  int64_t moof_head_;
    97  // |mdat_tail_| is the stream offset of the end of the current 'mdat' box.
    98  // Valid iff it is greater than the head of the queue.
    99  int64_t mdat_tail_;
    100 
    101  std::unique_ptr<Movie> moov_;
    102  std::unique_ptr<TrackRunIterator> runs_;
    103 
    104  DISALLOW_COPY_AND_ASSIGN(MP4MediaParser);
    105 };
    106 
    107 } // namespace mp4
    108 } // namespace media
    109 } // namespace shaka
    110 
    111 #endif // PACKAGER_MEDIA_FORMATS_MP4_MP4_MEDIA_PARSER_H_
    -
    bool Flush() override WARN_UNUSED_RESULT
    -
    All the methods that are virtual are virtual for mocking.
    -
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:34
    -
    bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    - -
    base::Callback< bool(uint32_t track_id, const std::shared_ptr< MediaSample > &media_sample)> NewSampleCB
    Definition: media_parser.h:43
    -
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    -
    bool LoadMoov(const std::string &file_path)
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    void Init(const InitCB &init_cb, const NewSampleCB &new_sample_cb, KeySource *decryption_key_source) override
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_MP4_MEDIA_PARSER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_MP4_MEDIA_PARSER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <map>
    +
    13 #include <memory>
    +
    14 #include <vector>
    +
    15 
    +
    16 #include "packager/base/callback_forward.h"
    +
    17 #include "packager/media/base/decryptor_source.h"
    +
    18 #include "packager/media/base/media_parser.h"
    +
    19 #include "packager/media/base/offset_byte_queue.h"
    +
    20 
    +
    21 namespace shaka {
    +
    22 namespace media {
    +
    23 namespace mp4 {
    +
    24 
    +
    25 class BoxReader;
    +
    26 class TrackRunIterator;
    +
    27 struct Movie;
    +
    28 struct ProtectionSystemSpecificHeader;
    +
    29 
    +
    30 class MP4MediaParser : public MediaParser {
    +
    31  public:
    + +
    33  ~MP4MediaParser() override;
    +
    34 
    +
    37  void Init(const InitCB& init_cb,
    +
    38  const NewMediaSampleCB& new_media_sample_cb,
    +
    39  const NewTextSampleCB& new_text_sample_cb,
    +
    40  KeySource* decryption_key_source) override;
    +
    41  bool Flush() override WARN_UNUSED_RESULT;
    +
    42  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
    +
    44 
    +
    51  bool LoadMoov(const std::string& file_path);
    +
    52 
    +
    53  private:
    +
    54  enum State {
    +
    55  kWaitingForInit,
    +
    56  kParsingBoxes,
    +
    57  kEmittingSamples,
    +
    58  kError
    +
    59  };
    +
    60 
    +
    61  bool ParseBox(bool* err);
    +
    62  bool ParseMoov(mp4::BoxReader* reader);
    +
    63  bool ParseMoof(mp4::BoxReader* reader);
    +
    64 
    +
    65  bool FetchKeysIfNecessary(
    +
    66  const std::vector<ProtectionSystemSpecificHeader>& headers);
    +
    67 
    +
    68  // To retain proper framing, each 'mdat' box must be read; to limit memory
    +
    69  // usage, the box's data needs to be discarded incrementally as frames are
    +
    70  // extracted from the stream. This function discards data from the stream up
    +
    71  // to |offset|, updating the |mdat_tail_| value so that framing can be
    +
    72  // retained after all 'mdat' information has been read.
    +
    73  // Returns 'true' on success, 'false' if there was an error.
    +
    74  bool ReadAndDiscardMDATsUntil(const int64_t offset);
    +
    75 
    +
    76  void ChangeState(State new_state);
    +
    77 
    +
    78  bool EmitConfigs();
    +
    79 
    +
    80  bool EnqueueSample(bool* err);
    +
    81 
    +
    82  void Reset();
    +
    83 
    +
    84  State state_;
    +
    85  InitCB init_cb_;
    +
    86  NewMediaSampleCB new_sample_cb_;
    +
    87  KeySource* decryption_key_source_;
    +
    88  std::unique_ptr<DecryptorSource> decryptor_source_;
    +
    89 
    +
    90  OffsetByteQueue queue_;
    +
    91 
    +
    92  // These two parameters are only valid in the |kEmittingSegments| state.
    +
    93  //
    +
    94  // |moof_head_| is the offset of the start of the most recently parsed moof
    +
    95  // block. All byte offsets in sample information are relative to this offset,
    +
    96  // as mandated by the Media Source spec.
    +
    97  int64_t moof_head_;
    +
    98  // |mdat_tail_| is the stream offset of the end of the current 'mdat' box.
    +
    99  // Valid iff it is greater than the head of the queue.
    +
    100  int64_t mdat_tail_;
    +
    101 
    +
    102  std::unique_ptr<Movie> moov_;
    +
    103  std::unique_ptr<TrackRunIterator> runs_;
    +
    104 
    +
    105  DISALLOW_COPY_AND_ASSIGN(MP4MediaParser);
    +
    106 };
    +
    107 
    +
    108 } // namespace mp4
    +
    109 } // namespace media
    +
    110 } // namespace shaka
    +
    111 
    +
    112 #endif // PACKAGER_MEDIA_FORMATS_MP4_MP4_MEDIA_PARSER_H_
    +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    + +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< TextSample > text_sample)> NewTextSampleCB
    Definition: media_parser.h:53
    +
    base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
    Definition: media_parser.h:44
    +
    base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
    Definition: media_parser.h:35
    + +
    Class for reading MP4 boxes.
    Definition: box_reader.h:25
    + +
    bool Parse(const uint8_t *buf, int size) override WARN_UNUSED_RESULT
    +
    bool Flush() override WARN_UNUSED_RESULT
    +
    void Init(const InitCB &init_cb, const NewMediaSampleCB &new_media_sample_cb, const NewTextSampleCB &new_text_sample_cb, KeySource *decryption_key_source) override
    +
    bool LoadMoov(const std::string &file_path)
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d7e/classshaka_1_1media_1_1mp2t_1_1TsSectionPsi.html b/docs/de/d7e/classshaka_1_1media_1_1mp2t_1_1TsSectionPsi.html index c5ead3d971..52f938ad33 100644 --- a/docs/de/d7e/classshaka_1_1media_1_1mp2t_1_1TsSectionPsi.html +++ b/docs/de/d7e/classshaka_1_1media_1_1mp2t_1_1TsSectionPsi.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::TsSectionPsi Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp2t::TsSection shaka::media::mp2t::TsSectionPat shaka::media::mp2t::TsSectionPmt - -
    + + - - + + @@ -103,11 +106,11 @@ virtual void  @@ -123,9 +126,7 @@ Additional Inherited Members diff --git a/docs/de/d7f/unionshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes_1_1OneOf-members.html b/docs/de/d7f/unionshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes_1_1OneOf-members.html index 70e9121ba1..2909003a0d 100644 --- a/docs/de/d7f/unionshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes_1_1OneOf-members.html +++ b/docs/de/d7f/unionshaka_1_1EncryptionParams_1_1EncryptedStreamAttributes_1_1OneOf-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    bool Parse (bool payload_unit_start_indicator, const uint8_t *buf, int size) override
     
    -void Flush () override
     
    +bool Flush () override
     
    void Reset () override
     
    ResetPsiSecti Additional Inherited Members
    - Public Types inherited from shaka::media::mp2t::TsSection
    enum  SpecialPid {
    -  kPidPat = 0x0, -kPidCat = 0x1, -kPidTsdt = 0x2, -kPidNullPacket = 0x1fff, -
    +  kPidPat = 0x0 +, kPidCat = 0x1 +, kPidTsdt = 0x2 +, kPidNullPacket = 0x1fff +,
      kPidMax = 0x1fff
    }
    - + +/* @license-end */
    diff --git a/docs/de/d83/box__definitions__comparison_8h_source.html b/docs/de/d83/box__definitions__comparison_8h_source.html index ff09d9c56a..fdf0c37c0d 100644 --- a/docs/de/d83/box__definitions__comparison_8h_source.html +++ b/docs/de/d83/box__definitions__comparison_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/box_definitions_comparison.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    box_definitions_comparison.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Overloads operator== for mp4 boxes, mainly used for testing.
    8 
    9 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_COMPARISON_H_
    10 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_COMPARISON_H_
    11 
    12 #include "packager/media/formats/mp4/box_definitions.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 inline bool operator==(const SubsampleEntry& lhs, const SubsampleEntry& rhs) {
    18  return lhs.clear_bytes == rhs.clear_bytes &&
    19  lhs.cipher_bytes == rhs.cipher_bytes;
    20 }
    21 
    22 namespace mp4 {
    23 
    24 inline bool operator==(const FileType& lhs, const FileType& rhs) {
    25  return lhs.major_brand == rhs.major_brand &&
    26  lhs.minor_version == rhs.minor_version &&
    27  lhs.compatible_brands == rhs.compatible_brands;
    28 }
    29 
    30 inline bool operator==(const ProtectionSystemSpecificHeader& lhs,
    31  const ProtectionSystemSpecificHeader& rhs) {
    32  return lhs.raw_box == rhs.raw_box;
    33 }
    34 
    35 inline bool operator==(const SampleAuxiliaryInformationOffset& lhs,
    36  const SampleAuxiliaryInformationOffset& rhs) {
    37  return lhs.offsets == rhs.offsets;
    38 }
    39 
    40 inline bool operator==(const SampleAuxiliaryInformationSize& lhs,
    41  const SampleAuxiliaryInformationSize& rhs) {
    42  return lhs.default_sample_info_size == rhs.default_sample_info_size &&
    43  lhs.sample_count == rhs.sample_count &&
    44  lhs.sample_info_sizes == rhs.sample_info_sizes;
    45 }
    46 
    47 inline bool operator==(const SampleEncryptionEntry& lhs,
    48  const SampleEncryptionEntry& rhs) {
    49  return lhs.initialization_vector == rhs.initialization_vector &&
    50  lhs.subsamples == rhs.subsamples;
    51 }
    52 
    53 inline bool operator==(const SampleEncryption& lhs,
    54  const SampleEncryption& rhs) {
    55  return lhs.iv_size == rhs.iv_size &&
    56  lhs.sample_encryption_entries == rhs.sample_encryption_entries;
    57 }
    58 
    59 inline bool operator==(const OriginalFormat& lhs, const OriginalFormat& rhs) {
    60  return lhs.format == rhs.format;
    61 }
    62 
    63 inline bool operator==(const SchemeType& lhs, const SchemeType& rhs) {
    64  return lhs.type == rhs.type && lhs.version == rhs.version;
    65 }
    66 
    67 inline bool operator==(const TrackEncryption& lhs, const TrackEncryption& rhs) {
    68  return lhs.default_is_protected == rhs.default_is_protected &&
    69  lhs.default_per_sample_iv_size == rhs.default_per_sample_iv_size &&
    70  lhs.default_kid == rhs.default_kid &&
    71  lhs.default_crypt_byte_block == rhs.default_crypt_byte_block &&
    72  lhs.default_skip_byte_block == rhs.default_skip_byte_block &&
    73  lhs.default_constant_iv == rhs.default_constant_iv;
    74 }
    75 
    76 inline bool operator==(const SchemeInfo& lhs, const SchemeInfo& rhs) {
    77  return lhs.track_encryption == rhs.track_encryption;
    78 }
    79 
    80 inline bool operator==(const ProtectionSchemeInfo& lhs,
    81  const ProtectionSchemeInfo& rhs) {
    82  return lhs.format == rhs.format && lhs.type == rhs.type &&
    83  lhs.info == rhs.info;
    84 }
    85 
    86 inline bool operator==(const MovieHeader& lhs, const MovieHeader& rhs) {
    87  return lhs.creation_time == rhs.creation_time &&
    88  lhs.modification_time == rhs.modification_time &&
    89  lhs.timescale == rhs.timescale && lhs.duration == rhs.duration &&
    90  lhs.rate == rhs.rate && lhs.volume == rhs.volume &&
    91  lhs.next_track_id == rhs.next_track_id;
    92 }
    93 
    94 inline bool operator==(const TrackHeader& lhs, const TrackHeader& rhs) {
    95  return lhs.creation_time == rhs.creation_time &&
    96  lhs.modification_time == rhs.modification_time &&
    97  lhs.track_id == rhs.track_id && lhs.duration == rhs.duration &&
    98  lhs.layer == rhs.layer && lhs.alternate_group == rhs.alternate_group &&
    99  lhs.volume == rhs.volume && lhs.width == rhs.width &&
    100  lhs.height == rhs.height;
    101 }
    102 
    103 inline bool operator==(const SampleDescription& lhs,
    104  const SampleDescription& rhs) {
    105  return lhs.type == rhs.type && lhs.video_entries == rhs.video_entries &&
    106  lhs.audio_entries == rhs.audio_entries;
    107 }
    108 
    109 inline bool operator==(const DecodingTime& lhs, const DecodingTime& rhs) {
    110  return lhs.sample_count == rhs.sample_count &&
    111  lhs.sample_delta == rhs.sample_delta;
    112 }
    113 
    114 inline bool operator==(const DecodingTimeToSample& lhs,
    115  const DecodingTimeToSample& rhs) {
    116  return lhs.decoding_time == rhs.decoding_time;
    117 }
    118 
    119 inline bool operator==(const CompositionOffset& lhs,
    120  const CompositionOffset& rhs) {
    121  return lhs.sample_count == rhs.sample_count &&
    122  lhs.sample_offset == rhs.sample_offset;
    123 }
    124 
    125 inline bool operator==(const CompositionTimeToSample& lhs,
    126  const CompositionTimeToSample& rhs) {
    127  return lhs.composition_offset == rhs.composition_offset;
    128 }
    129 
    130 inline bool operator==(const ChunkInfo& lhs, const ChunkInfo& rhs) {
    131  return lhs.first_chunk == rhs.first_chunk &&
    132  lhs.samples_per_chunk == rhs.samples_per_chunk &&
    133  lhs.sample_description_index == rhs.sample_description_index;
    134 }
    135 
    136 inline bool operator==(const SampleToChunk& lhs, const SampleToChunk& rhs) {
    137  return lhs.chunk_info == rhs.chunk_info;
    138 }
    139 
    140 inline bool operator==(const SampleSize& lhs, const SampleSize& rhs) {
    141  return lhs.sample_size == rhs.sample_size &&
    142  lhs.sample_count == rhs.sample_count && lhs.sizes == rhs.sizes;
    143 }
    144 
    145 inline bool operator==(const CompactSampleSize& lhs,
    146  const CompactSampleSize& rhs) {
    147  return lhs.field_size == rhs.field_size && lhs.sizes == rhs.sizes;
    148 }
    149 
    150 inline bool operator==(const ChunkLargeOffset& lhs,
    151  const ChunkLargeOffset& rhs) {
    152  return lhs.offsets == rhs.offsets;
    153 }
    154 
    155 inline bool operator==(const SyncSample& lhs, const SyncSample& rhs) {
    156  return lhs.sample_number == rhs.sample_number;
    157 }
    158 
    159 inline bool operator==(const CencSampleEncryptionInfoEntry& lhs,
    160  const CencSampleEncryptionInfoEntry& rhs) {
    161  return lhs.is_protected == rhs.is_protected &&
    162  lhs.per_sample_iv_size == rhs.per_sample_iv_size &&
    163  lhs.key_id == rhs.key_id &&
    164  lhs.crypt_byte_block == rhs.crypt_byte_block &&
    165  lhs.skip_byte_block == rhs.skip_byte_block &&
    166  lhs.constant_iv == rhs.constant_iv;
    167 }
    168 
    169 inline bool operator==(const AudioRollRecoveryEntry& lhs,
    170  const AudioRollRecoveryEntry& rhs) {
    171  return lhs.roll_distance == rhs.roll_distance;
    172 }
    173 
    174 inline bool operator==(const SampleGroupDescription& lhs,
    175  const SampleGroupDescription& rhs) {
    176  return lhs.grouping_type == rhs.grouping_type &&
    177  lhs.cenc_sample_encryption_info_entries ==
    178  rhs.cenc_sample_encryption_info_entries &&
    179  lhs.audio_roll_recovery_entries == rhs.audio_roll_recovery_entries;
    180 }
    181 
    182 inline bool operator==(const SampleToGroupEntry& lhs,
    183  const SampleToGroupEntry& rhs) {
    184  return lhs.sample_count == rhs.sample_count &&
    185  lhs.group_description_index == rhs.group_description_index;
    186 }
    187 
    188 inline bool operator==(const SampleToGroup& lhs,
    189  const SampleToGroup& rhs) {
    190  return lhs.grouping_type == rhs.grouping_type &&
    191  lhs.grouping_type_parameter == rhs.grouping_type_parameter &&
    192  lhs.entries == rhs.entries;
    193 }
    194 
    195 inline bool operator==(const SampleTable& lhs, const SampleTable& rhs) {
    196  return lhs.description == rhs.description &&
    197  lhs.decoding_time_to_sample == rhs.decoding_time_to_sample &&
    198  lhs.composition_time_to_sample == rhs.composition_time_to_sample &&
    199  lhs.sample_to_chunk == rhs.sample_to_chunk &&
    200  lhs.sample_size == rhs.sample_size &&
    201  lhs.chunk_large_offset == rhs.chunk_large_offset &&
    202  lhs.sync_sample == rhs.sync_sample &&
    203  lhs.sample_group_descriptions == rhs.sample_group_descriptions &&
    204  lhs.sample_to_groups == rhs.sample_to_groups;
    205 }
    206 
    207 inline bool operator==(const EditListEntry& lhs, const EditListEntry& rhs) {
    208  return lhs.segment_duration == rhs.segment_duration &&
    209  lhs.media_time == rhs.media_time &&
    210  lhs.media_rate_integer == rhs.media_rate_integer &&
    211  lhs.media_rate_fraction == rhs.media_rate_fraction;
    212 }
    213 
    214 inline bool operator==(const EditList& lhs, const EditList& rhs) {
    215  return lhs.edits == rhs.edits;
    216 }
    217 
    218 inline bool operator==(const Edit& lhs, const Edit& rhs) {
    219  return lhs.list == rhs.list;
    220 }
    221 
    222 inline bool operator==(const HandlerReference& lhs,
    223  const HandlerReference& rhs) {
    224  return lhs.handler_type == rhs.handler_type;
    225 }
    226 
    227 inline bool operator==(const Language& lhs,
    228  const Language& rhs) {
    229  return lhs.code == rhs.code;
    230 }
    231 
    232 inline bool operator==(const ID3v2& lhs, const ID3v2& rhs) {
    233  return lhs.language == rhs.language && lhs.id3v2_data == rhs.id3v2_data;
    234 }
    235 
    236 inline bool operator==(const Metadata& lhs, const Metadata& rhs) {
    237  return lhs.handler == rhs.handler && lhs.id3v2 == rhs.id3v2;
    238 }
    239 
    240 inline bool operator==(const CodecConfiguration& lhs,
    241  const CodecConfiguration& rhs) {
    242  return lhs.box_type == rhs.box_type && lhs.data == rhs.data;
    243 }
    244 
    245 inline bool operator==(const PixelAspectRatio& lhs,
    246  const PixelAspectRatio& rhs) {
    247  return lhs.h_spacing == rhs.h_spacing && lhs.v_spacing == rhs.v_spacing;
    248 }
    249 
    250 inline bool operator==(const VideoSampleEntry& lhs,
    251  const VideoSampleEntry& rhs) {
    252  return lhs.format == rhs.format &&
    253  lhs.data_reference_index == rhs.data_reference_index &&
    254  lhs.width == rhs.width && lhs.height == rhs.height &&
    255  lhs.pixel_aspect == rhs.pixel_aspect && lhs.sinf == rhs.sinf &&
    256  lhs.codec_configuration == rhs.codec_configuration;
    257 }
    258 
    259 inline bool operator==(const DecoderSpecificInfoDescriptor& lhs,
    260  const DecoderSpecificInfoDescriptor& rhs) {
    261  return lhs.data() == rhs.data();
    262 }
    263 
    264 inline bool operator==(const DecoderConfigDescriptor& lhs,
    265  const DecoderConfigDescriptor& rhs) {
    266  return lhs.buffer_size_db() == rhs.buffer_size_db() &&
    267  lhs.max_bitrate() == rhs.max_bitrate() &&
    268  lhs.avg_bitrate() == rhs.avg_bitrate() &&
    269  lhs.object_type() == rhs.object_type() &&
    270  lhs.decoder_specific_info_descriptor() ==
    271  rhs.decoder_specific_info_descriptor();
    272 }
    273 
    274 inline bool operator==(const ESDescriptor& lhs, const ESDescriptor& rhs) {
    275  return lhs.esid() == rhs.esid() &&
    276  lhs.decoder_config_descriptor() == rhs.decoder_config_descriptor();
    277 }
    278 
    279 inline bool operator==(const ElementaryStreamDescriptor& lhs,
    280  const ElementaryStreamDescriptor& rhs) {
    281  return lhs.es_descriptor == rhs.es_descriptor;
    282 }
    283 
    284 inline bool operator==(const DTSSpecific& lhs, const DTSSpecific& rhs) {
    285  return lhs.sampling_frequency == rhs.sampling_frequency &&
    286  lhs.max_bitrate == rhs.max_bitrate &&
    287  lhs.avg_bitrate == rhs.avg_bitrate &&
    288  lhs.pcm_sample_depth == rhs.pcm_sample_depth &&
    289  lhs.extra_data == rhs.extra_data;
    290 }
    291 
    292 inline bool operator==(const AC3Specific& lhs, const AC3Specific& rhs) {
    293  return lhs.data == rhs.data;
    294 }
    295 
    296 inline bool operator==(const EC3Specific& lhs, const EC3Specific& rhs) {
    297  return lhs.data == rhs.data;
    298 }
    299 
    300 inline bool operator==(const OpusSpecific& lhs, const OpusSpecific& rhs) {
    301  return lhs.opus_identification_header == rhs.opus_identification_header &&
    302  lhs.preskip == rhs.preskip;
    303 }
    304 
    305 inline bool operator==(const AudioSampleEntry& lhs,
    306  const AudioSampleEntry& rhs) {
    307  return lhs.format == rhs.format &&
    308  lhs.data_reference_index == rhs.data_reference_index &&
    309  lhs.channelcount == rhs.channelcount &&
    310  lhs.samplesize == rhs.samplesize && lhs.samplerate == rhs.samplerate &&
    311  lhs.sinf == rhs.sinf && lhs.esds == rhs.esds && lhs.ddts == rhs.ddts &&
    312  lhs.dac3 == rhs.dac3 && lhs.dec3 == rhs.dec3 && lhs.dops == rhs.dops;
    313 }
    314 
    315 inline bool operator==(const WebVTTConfigurationBox& lhs,
    316  const WebVTTConfigurationBox& rhs) {
    317  return lhs.config == rhs.config;
    318 }
    319 
    320 inline bool operator==(const WebVTTSourceLabelBox& lhs,
    321  const WebVTTSourceLabelBox& rhs) {
    322  return lhs.source_label == rhs.source_label;
    323 }
    324 
    325 inline bool operator==(const TextSampleEntry& lhs, const TextSampleEntry& rhs) {
    326  return lhs.config == rhs.config && lhs.label == rhs.label;
    327 }
    328 
    329 inline bool operator==(const MediaHeader& lhs, const MediaHeader& rhs) {
    330  return lhs.creation_time == rhs.creation_time &&
    331  lhs.modification_time == rhs.modification_time &&
    332  lhs.timescale == rhs.timescale && lhs.duration == rhs.duration &&
    333  lhs.language == rhs.language;
    334 }
    335 
    336 inline bool operator==(const VideoMediaHeader& lhs,
    337  const VideoMediaHeader& rhs) {
    338  return lhs.graphicsmode == rhs.graphicsmode &&
    339  lhs.opcolor_red == rhs.opcolor_red &&
    340  lhs.opcolor_green == rhs.opcolor_green &&
    341  lhs.opcolor_blue == rhs.opcolor_blue;
    342 }
    343 
    344 inline bool operator==(const SoundMediaHeader& lhs,
    345  const SoundMediaHeader& rhs) {
    346  return lhs.balance == rhs.balance;
    347 }
    348 
    349 inline bool operator==(const SubtitleMediaHeader& lhs,
    350  const SubtitleMediaHeader& rhs) {
    351  return true;
    352 }
    353 
    354 inline bool operator==(const DataEntryUrl& lhs, const DataEntryUrl& rhs) {
    355  return lhs.flags == rhs.flags && lhs.location == rhs.location;
    356 }
    357 
    358 inline bool operator==(const DataReference& lhs, const DataReference& rhs) {
    359  return lhs.data_entry == rhs.data_entry;
    360 }
    361 
    362 inline bool operator==(const DataInformation& lhs, const DataInformation& rhs) {
    363  return lhs.dref == rhs.dref;
    364 }
    365 
    366 inline bool operator==(const MediaInformation& lhs,
    367  const MediaInformation& rhs) {
    368  return lhs.dinf == rhs.dinf && lhs.sample_table == rhs.sample_table &&
    369  lhs.vmhd == rhs.vmhd && lhs.smhd == rhs.smhd;
    370 }
    371 
    372 inline bool operator==(const Media& lhs, const Media& rhs) {
    373  return lhs.header == rhs.header && lhs.handler == rhs.handler &&
    374  lhs.information == rhs.information;
    375 }
    376 
    377 inline bool operator==(const Track& lhs, const Track& rhs) {
    378  return lhs.header == rhs.header && lhs.media == rhs.media &&
    379  lhs.edit == rhs.edit && lhs.sample_encryption == rhs.sample_encryption;
    380 }
    381 
    382 inline bool operator==(const MovieExtendsHeader& lhs,
    383  const MovieExtendsHeader& rhs) {
    384  return lhs.fragment_duration == rhs.fragment_duration;
    385 }
    386 
    387 inline bool operator==(const TrackExtends& lhs, const TrackExtends& rhs) {
    388  return lhs.track_id == rhs.track_id &&
    389  lhs.default_sample_description_index ==
    390  rhs.default_sample_description_index &&
    391  lhs.default_sample_duration == rhs.default_sample_duration &&
    392  lhs.default_sample_size == rhs.default_sample_size &&
    393  lhs.default_sample_flags == rhs.default_sample_flags;
    394 }
    395 
    396 inline bool operator==(const MovieExtends& lhs, const MovieExtends& rhs) {
    397  return lhs.header == rhs.header && lhs.tracks == rhs.tracks;
    398 }
    399 
    400 inline bool operator==(const Movie& lhs, const Movie& rhs) {
    401  return lhs.header == rhs.header && lhs.extends == rhs.extends &&
    402  lhs.tracks == rhs.tracks && lhs.pssh == rhs.pssh;
    403 }
    404 
    405 inline bool operator==(const TrackFragmentDecodeTime& lhs,
    406  const TrackFragmentDecodeTime& rhs) {
    407  return lhs.decode_time == rhs.decode_time;
    408 }
    409 
    410 inline bool operator==(const MovieFragmentHeader& lhs,
    411  const MovieFragmentHeader& rhs) {
    412  return lhs.sequence_number == rhs.sequence_number;
    413 }
    414 
    415 inline bool operator==(const TrackFragmentHeader& lhs,
    416  const TrackFragmentHeader& rhs) {
    417  return lhs.flags == rhs.flags && lhs.track_id == rhs.track_id &&
    418  lhs.sample_description_index == rhs.sample_description_index &&
    419  lhs.default_sample_duration == rhs.default_sample_duration &&
    420  lhs.default_sample_size == rhs.default_sample_size &&
    421  lhs.default_sample_flags == rhs.default_sample_flags;
    422 }
    423 
    424 inline bool operator==(const TrackFragmentRun& lhs,
    425  const TrackFragmentRun& rhs) {
    426  return lhs.flags == rhs.flags && lhs.sample_count == rhs.sample_count &&
    427  lhs.data_offset == rhs.data_offset &&
    428  lhs.sample_flags == rhs.sample_flags &&
    429  lhs.sample_sizes == rhs.sample_sizes &&
    430  lhs.sample_durations == rhs.sample_durations &&
    431  lhs.sample_composition_time_offsets ==
    432  rhs.sample_composition_time_offsets;
    433 }
    434 
    435 inline bool operator==(const TrackFragment& lhs, const TrackFragment& rhs) {
    436  return lhs.header == rhs.header && lhs.runs == rhs.runs &&
    437  lhs.decode_time == rhs.decode_time &&
    438  lhs.auxiliary_offset == rhs.auxiliary_offset &&
    439  lhs.auxiliary_size == rhs.auxiliary_size &&
    440  lhs.sample_encryption == rhs.sample_encryption;
    441 }
    442 
    443 inline bool operator==(const MovieFragment& lhs, const MovieFragment& rhs) {
    444  return lhs.header == rhs.header && lhs.tracks == rhs.tracks &&
    445  lhs.pssh == rhs.pssh;
    446 }
    447 
    448 inline bool operator==(const SegmentReference& lhs,
    449  const SegmentReference& rhs) {
    450  return lhs.reference_type == rhs.reference_type &&
    451  lhs.referenced_size == rhs.referenced_size &&
    452  lhs.subsegment_duration == rhs.subsegment_duration &&
    453  lhs.starts_with_sap == rhs.starts_with_sap &&
    454  lhs.sap_type == rhs.sap_type &&
    455  lhs.sap_delta_time == rhs.sap_delta_time;
    456 }
    457 
    458 inline bool operator==(const SegmentIndex& lhs, const SegmentIndex& rhs) {
    459  return lhs.reference_id == rhs.reference_id &&
    460  lhs.timescale == rhs.timescale &&
    461  lhs.earliest_presentation_time == rhs.earliest_presentation_time &&
    462  lhs.first_offset == rhs.first_offset &&
    463  lhs.references == rhs.references;
    464 }
    465 
    466 inline bool operator==(const CueSourceIDBox& lhs,
    467  const CueSourceIDBox& rhs) {
    468  return lhs.source_id == rhs.source_id;
    469 }
    470 
    471 inline bool operator==(const CueTimeBox& lhs,
    472  const CueTimeBox& rhs) {
    473  return lhs.cue_current_time == rhs.cue_current_time;
    474 }
    475 
    476 inline bool operator==(const CueIDBox& lhs,
    477  const CueIDBox& rhs) {
    478  return lhs.cue_id == rhs.cue_id;
    479 }
    480 
    481 inline bool operator==(const CueSettingsBox& lhs,
    482  const CueSettingsBox& rhs) {
    483  return lhs.settings == rhs.settings;
    484 }
    485 
    486 inline bool operator==(const CuePayloadBox& lhs,
    487  const CuePayloadBox& rhs) {
    488  return lhs.cue_text == rhs.cue_text;
    489 }
    490 
    491 inline bool operator==(const VTTEmptyCueBox& lhs, const VTTEmptyCueBox& rhs) {
    492  return true;
    493 }
    494 
    495 inline bool operator==(const VTTAdditionalTextBox& lhs,
    496  const VTTAdditionalTextBox& rhs) {
    497  return lhs.cue_additional_text == rhs.cue_additional_text;
    498 }
    499 
    500 inline bool operator==(const VTTCueBox& lhs,
    501  const VTTCueBox& rhs) {
    502  return lhs.cue_source_id == rhs.cue_source_id && lhs.cue_id == rhs.cue_id &&
    503  lhs.cue_time == rhs.cue_time && lhs.cue_settings == rhs.cue_settings &&
    504  lhs.cue_payload == rhs.cue_payload;
    505 }
    506 
    507 } // namespace mp4
    508 } // namespace media
    509 } // namespace shaka
    510 
    511 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_COMPARISON_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Overloads operator== for mp4 boxes, mainly used for testing.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_COMPARISON_H_
    +
    10 #define PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_COMPARISON_H_
    +
    11 
    +
    12 #include "packager/media/formats/mp4/box_definitions.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    17 inline bool operator==(const SubsampleEntry& lhs, const SubsampleEntry& rhs) {
    +
    18  return lhs.clear_bytes == rhs.clear_bytes &&
    +
    19  lhs.cipher_bytes == rhs.cipher_bytes;
    +
    20 }
    +
    21 
    +
    22 namespace mp4 {
    +
    23 
    +
    24 inline bool operator==(const FileType& lhs, const FileType& rhs) {
    +
    25  return lhs.major_brand == rhs.major_brand &&
    +
    26  lhs.minor_version == rhs.minor_version &&
    +
    27  lhs.compatible_brands == rhs.compatible_brands;
    +
    28 }
    +
    29 
    +
    30 inline bool operator==(const ProtectionSystemSpecificHeader& lhs,
    +
    31  const ProtectionSystemSpecificHeader& rhs) {
    +
    32  return lhs.raw_box == rhs.raw_box;
    +
    33 }
    +
    34 
    +
    35 inline bool operator==(const SampleAuxiliaryInformationOffset& lhs,
    +
    36  const SampleAuxiliaryInformationOffset& rhs) {
    +
    37  return lhs.offsets == rhs.offsets;
    +
    38 }
    +
    39 
    +
    40 inline bool operator==(const SampleAuxiliaryInformationSize& lhs,
    +
    41  const SampleAuxiliaryInformationSize& rhs) {
    +
    42  return lhs.default_sample_info_size == rhs.default_sample_info_size &&
    +
    43  lhs.sample_count == rhs.sample_count &&
    +
    44  lhs.sample_info_sizes == rhs.sample_info_sizes;
    +
    45 }
    +
    46 
    +
    47 inline bool operator==(const SampleEncryptionEntry& lhs,
    +
    48  const SampleEncryptionEntry& rhs) {
    +
    49  return lhs.initialization_vector == rhs.initialization_vector &&
    +
    50  lhs.subsamples == rhs.subsamples;
    +
    51 }
    +
    52 
    +
    53 inline bool operator==(const SampleEncryption& lhs,
    +
    54  const SampleEncryption& rhs) {
    +
    55  return lhs.iv_size == rhs.iv_size &&
    +
    56  lhs.sample_encryption_entries == rhs.sample_encryption_entries;
    +
    57 }
    +
    58 
    +
    59 inline bool operator==(const OriginalFormat& lhs, const OriginalFormat& rhs) {
    +
    60  return lhs.format == rhs.format;
    +
    61 }
    +
    62 
    +
    63 inline bool operator==(const SchemeType& lhs, const SchemeType& rhs) {
    +
    64  return lhs.type == rhs.type && lhs.version == rhs.version;
    +
    65 }
    +
    66 
    +
    67 inline bool operator==(const TrackEncryption& lhs, const TrackEncryption& rhs) {
    +
    68  return lhs.default_is_protected == rhs.default_is_protected &&
    +
    69  lhs.default_per_sample_iv_size == rhs.default_per_sample_iv_size &&
    +
    70  lhs.default_kid == rhs.default_kid &&
    +
    71  lhs.default_crypt_byte_block == rhs.default_crypt_byte_block &&
    +
    72  lhs.default_skip_byte_block == rhs.default_skip_byte_block &&
    +
    73  lhs.default_constant_iv == rhs.default_constant_iv;
    +
    74 }
    +
    75 
    +
    76 inline bool operator==(const SchemeInfo& lhs, const SchemeInfo& rhs) {
    +
    77  return lhs.track_encryption == rhs.track_encryption;
    +
    78 }
    +
    79 
    +
    80 inline bool operator==(const ProtectionSchemeInfo& lhs,
    +
    81  const ProtectionSchemeInfo& rhs) {
    +
    82  return lhs.format == rhs.format && lhs.type == rhs.type &&
    +
    83  lhs.info == rhs.info;
    +
    84 }
    +
    85 
    +
    86 inline bool operator==(const MovieHeader& lhs, const MovieHeader& rhs) {
    +
    87  return lhs.creation_time == rhs.creation_time &&
    +
    88  lhs.modification_time == rhs.modification_time &&
    +
    89  lhs.timescale == rhs.timescale && lhs.duration == rhs.duration &&
    +
    90  lhs.rate == rhs.rate && lhs.volume == rhs.volume &&
    +
    91  lhs.next_track_id == rhs.next_track_id;
    +
    92 }
    +
    93 
    +
    94 inline bool operator==(const TrackHeader& lhs, const TrackHeader& rhs) {
    +
    95  return lhs.creation_time == rhs.creation_time &&
    +
    96  lhs.modification_time == rhs.modification_time &&
    +
    97  lhs.track_id == rhs.track_id && lhs.duration == rhs.duration &&
    +
    98  lhs.layer == rhs.layer && lhs.alternate_group == rhs.alternate_group &&
    +
    99  lhs.volume == rhs.volume && lhs.width == rhs.width &&
    +
    100  lhs.height == rhs.height;
    +
    101 }
    +
    102 
    +
    103 inline bool operator==(const SampleDescription& lhs,
    +
    104  const SampleDescription& rhs) {
    +
    105  return lhs.type == rhs.type && lhs.video_entries == rhs.video_entries &&
    +
    106  lhs.audio_entries == rhs.audio_entries;
    +
    107 }
    +
    108 
    +
    109 inline bool operator==(const DecodingTime& lhs, const DecodingTime& rhs) {
    +
    110  return lhs.sample_count == rhs.sample_count &&
    +
    111  lhs.sample_delta == rhs.sample_delta;
    +
    112 }
    +
    113 
    +
    114 inline bool operator==(const DecodingTimeToSample& lhs,
    +
    115  const DecodingTimeToSample& rhs) {
    +
    116  return lhs.decoding_time == rhs.decoding_time;
    +
    117 }
    +
    118 
    +
    119 inline bool operator==(const CompositionOffset& lhs,
    +
    120  const CompositionOffset& rhs) {
    +
    121  return lhs.sample_count == rhs.sample_count &&
    +
    122  lhs.sample_offset == rhs.sample_offset;
    +
    123 }
    +
    124 
    +
    125 inline bool operator==(const CompositionTimeToSample& lhs,
    +
    126  const CompositionTimeToSample& rhs) {
    +
    127  return lhs.composition_offset == rhs.composition_offset;
    +
    128 }
    +
    129 
    +
    130 inline bool operator==(const ChunkInfo& lhs, const ChunkInfo& rhs) {
    +
    131  return lhs.first_chunk == rhs.first_chunk &&
    +
    132  lhs.samples_per_chunk == rhs.samples_per_chunk &&
    +
    133  lhs.sample_description_index == rhs.sample_description_index;
    +
    134 }
    +
    135 
    +
    136 inline bool operator==(const SampleToChunk& lhs, const SampleToChunk& rhs) {
    +
    137  return lhs.chunk_info == rhs.chunk_info;
    +
    138 }
    +
    139 
    +
    140 inline bool operator==(const SampleSize& lhs, const SampleSize& rhs) {
    +
    141  return lhs.sample_size == rhs.sample_size &&
    +
    142  lhs.sample_count == rhs.sample_count && lhs.sizes == rhs.sizes;
    +
    143 }
    +
    144 
    +
    145 inline bool operator==(const CompactSampleSize& lhs,
    +
    146  const CompactSampleSize& rhs) {
    +
    147  return lhs.field_size == rhs.field_size && lhs.sizes == rhs.sizes;
    +
    148 }
    +
    149 
    +
    150 inline bool operator==(const ChunkLargeOffset& lhs,
    +
    151  const ChunkLargeOffset& rhs) {
    +
    152  return lhs.offsets == rhs.offsets;
    +
    153 }
    +
    154 
    +
    155 inline bool operator==(const SyncSample& lhs, const SyncSample& rhs) {
    +
    156  return lhs.sample_number == rhs.sample_number;
    +
    157 }
    +
    158 
    +
    159 inline bool operator==(const CencSampleEncryptionInfoEntry& lhs,
    +
    160  const CencSampleEncryptionInfoEntry& rhs) {
    +
    161  return lhs.is_protected == rhs.is_protected &&
    +
    162  lhs.per_sample_iv_size == rhs.per_sample_iv_size &&
    +
    163  lhs.key_id == rhs.key_id &&
    +
    164  lhs.crypt_byte_block == rhs.crypt_byte_block &&
    +
    165  lhs.skip_byte_block == rhs.skip_byte_block &&
    +
    166  lhs.constant_iv == rhs.constant_iv;
    +
    167 }
    +
    168 
    +
    169 inline bool operator==(const AudioRollRecoveryEntry& lhs,
    +
    170  const AudioRollRecoveryEntry& rhs) {
    +
    171  return lhs.roll_distance == rhs.roll_distance;
    +
    172 }
    +
    173 
    +
    174 inline bool operator==(const SampleGroupDescription& lhs,
    +
    175  const SampleGroupDescription& rhs) {
    +
    176  return lhs.grouping_type == rhs.grouping_type &&
    +
    177  lhs.cenc_sample_encryption_info_entries ==
    +
    178  rhs.cenc_sample_encryption_info_entries &&
    +
    179  lhs.audio_roll_recovery_entries == rhs.audio_roll_recovery_entries;
    +
    180 }
    +
    181 
    +
    182 inline bool operator==(const SampleToGroupEntry& lhs,
    +
    183  const SampleToGroupEntry& rhs) {
    +
    184  return lhs.sample_count == rhs.sample_count &&
    +
    185  lhs.group_description_index == rhs.group_description_index;
    +
    186 }
    +
    187 
    +
    188 inline bool operator==(const SampleToGroup& lhs,
    +
    189  const SampleToGroup& rhs) {
    +
    190  return lhs.grouping_type == rhs.grouping_type &&
    +
    191  lhs.grouping_type_parameter == rhs.grouping_type_parameter &&
    +
    192  lhs.entries == rhs.entries;
    +
    193 }
    +
    194 
    +
    195 inline bool operator==(const SampleTable& lhs, const SampleTable& rhs) {
    +
    196  return lhs.description == rhs.description &&
    +
    197  lhs.decoding_time_to_sample == rhs.decoding_time_to_sample &&
    +
    198  lhs.composition_time_to_sample == rhs.composition_time_to_sample &&
    +
    199  lhs.sample_to_chunk == rhs.sample_to_chunk &&
    +
    200  lhs.sample_size == rhs.sample_size &&
    +
    201  lhs.chunk_large_offset == rhs.chunk_large_offset &&
    +
    202  lhs.sync_sample == rhs.sync_sample &&
    +
    203  lhs.sample_group_descriptions == rhs.sample_group_descriptions &&
    +
    204  lhs.sample_to_groups == rhs.sample_to_groups;
    +
    205 }
    +
    206 
    +
    207 inline bool operator==(const EditListEntry& lhs, const EditListEntry& rhs) {
    +
    208  return lhs.segment_duration == rhs.segment_duration &&
    +
    209  lhs.media_time == rhs.media_time &&
    +
    210  lhs.media_rate_integer == rhs.media_rate_integer &&
    +
    211  lhs.media_rate_fraction == rhs.media_rate_fraction;
    +
    212 }
    +
    213 
    +
    214 inline bool operator==(const EditList& lhs, const EditList& rhs) {
    +
    215  return lhs.edits == rhs.edits;
    +
    216 }
    +
    217 
    +
    218 inline bool operator==(const Edit& lhs, const Edit& rhs) {
    +
    219  return lhs.list == rhs.list;
    +
    220 }
    +
    221 
    +
    222 inline bool operator==(const HandlerReference& lhs,
    +
    223  const HandlerReference& rhs) {
    +
    224  return lhs.handler_type == rhs.handler_type;
    +
    225 }
    +
    226 
    +
    227 inline bool operator==(const Language& lhs,
    +
    228  const Language& rhs) {
    +
    229  return lhs.code == rhs.code;
    +
    230 }
    +
    231 
    +
    232 inline bool operator==(const ID3v2& lhs, const ID3v2& rhs) {
    +
    233  return lhs.language == rhs.language && lhs.id3v2_data == rhs.id3v2_data;
    +
    234 }
    +
    235 
    +
    236 inline bool operator==(const Metadata& lhs, const Metadata& rhs) {
    +
    237  return lhs.handler == rhs.handler && lhs.id3v2 == rhs.id3v2;
    +
    238 }
    +
    239 
    +
    240 inline bool operator==(const CodecConfiguration& lhs,
    +
    241  const CodecConfiguration& rhs) {
    +
    242  return lhs.box_type == rhs.box_type && lhs.data == rhs.data;
    +
    243 }
    +
    244 
    +
    245 inline bool operator==(const PixelAspectRatio& lhs,
    +
    246  const PixelAspectRatio& rhs) {
    +
    247  return lhs.h_spacing == rhs.h_spacing && lhs.v_spacing == rhs.v_spacing;
    +
    248 }
    +
    249 
    +
    250 inline bool operator==(const VideoSampleEntry& lhs,
    +
    251  const VideoSampleEntry& rhs) {
    +
    252  return lhs.format == rhs.format &&
    +
    253  lhs.data_reference_index == rhs.data_reference_index &&
    +
    254  lhs.width == rhs.width && lhs.height == rhs.height &&
    +
    255  lhs.pixel_aspect == rhs.pixel_aspect && lhs.sinf == rhs.sinf &&
    +
    256  lhs.codec_configuration == rhs.codec_configuration;
    +
    257 }
    +
    258 
    +
    259 inline bool operator==(const DecoderSpecificInfoDescriptor& lhs,
    +
    260  const DecoderSpecificInfoDescriptor& rhs) {
    +
    261  return lhs.data() == rhs.data();
    +
    262 }
    +
    263 
    +
    264 inline bool operator==(const DecoderConfigDescriptor& lhs,
    +
    265  const DecoderConfigDescriptor& rhs) {
    +
    266  return lhs.buffer_size_db() == rhs.buffer_size_db() &&
    +
    267  lhs.max_bitrate() == rhs.max_bitrate() &&
    +
    268  lhs.avg_bitrate() == rhs.avg_bitrate() &&
    +
    269  lhs.object_type() == rhs.object_type() &&
    +
    270  lhs.decoder_specific_info_descriptor() ==
    +
    271  rhs.decoder_specific_info_descriptor();
    +
    272 }
    +
    273 
    +
    274 inline bool operator==(const ESDescriptor& lhs, const ESDescriptor& rhs) {
    +
    275  return lhs.esid() == rhs.esid() &&
    +
    276  lhs.decoder_config_descriptor() == rhs.decoder_config_descriptor();
    +
    277 }
    +
    278 
    +
    279 inline bool operator==(const ElementaryStreamDescriptor& lhs,
    +
    280  const ElementaryStreamDescriptor& rhs) {
    +
    281  return lhs.es_descriptor == rhs.es_descriptor;
    +
    282 }
    +
    283 
    +
    284 inline bool operator==(const DTSSpecific& lhs, const DTSSpecific& rhs) {
    +
    285  return lhs.sampling_frequency == rhs.sampling_frequency &&
    +
    286  lhs.max_bitrate == rhs.max_bitrate &&
    +
    287  lhs.avg_bitrate == rhs.avg_bitrate &&
    +
    288  lhs.pcm_sample_depth == rhs.pcm_sample_depth &&
    +
    289  lhs.extra_data == rhs.extra_data;
    +
    290 }
    +
    291 
    +
    292 inline bool operator==(const AC3Specific& lhs, const AC3Specific& rhs) {
    +
    293  return lhs.data == rhs.data;
    +
    294 }
    +
    295 
    +
    296 inline bool operator==(const EC3Specific& lhs, const EC3Specific& rhs) {
    +
    297  return lhs.data == rhs.data;
    +
    298 }
    +
    299 
    +
    300 inline bool operator==(const OpusSpecific& lhs, const OpusSpecific& rhs) {
    +
    301  return lhs.opus_identification_header == rhs.opus_identification_header &&
    +
    302  lhs.preskip == rhs.preskip;
    +
    303 }
    +
    304 
    +
    305 inline bool operator==(const AudioSampleEntry& lhs,
    +
    306  const AudioSampleEntry& rhs) {
    +
    307  return lhs.format == rhs.format &&
    +
    308  lhs.data_reference_index == rhs.data_reference_index &&
    +
    309  lhs.channelcount == rhs.channelcount &&
    +
    310  lhs.samplesize == rhs.samplesize && lhs.samplerate == rhs.samplerate &&
    +
    311  lhs.sinf == rhs.sinf && lhs.esds == rhs.esds && lhs.ddts == rhs.ddts &&
    +
    312  lhs.dac3 == rhs.dac3 && lhs.dec3 == rhs.dec3 && lhs.dops == rhs.dops;
    +
    313 }
    +
    314 
    +
    315 inline bool operator==(const WebVTTConfigurationBox& lhs,
    +
    316  const WebVTTConfigurationBox& rhs) {
    +
    317  return lhs.config == rhs.config;
    +
    318 }
    +
    319 
    +
    320 inline bool operator==(const WebVTTSourceLabelBox& lhs,
    +
    321  const WebVTTSourceLabelBox& rhs) {
    +
    322  return lhs.source_label == rhs.source_label;
    +
    323 }
    +
    324 
    +
    325 inline bool operator==(const TextSampleEntry& lhs, const TextSampleEntry& rhs) {
    +
    326  return lhs.config == rhs.config && lhs.label == rhs.label;
    +
    327 }
    +
    328 
    +
    329 inline bool operator==(const MediaHeader& lhs, const MediaHeader& rhs) {
    +
    330  return lhs.creation_time == rhs.creation_time &&
    +
    331  lhs.modification_time == rhs.modification_time &&
    +
    332  lhs.timescale == rhs.timescale && lhs.duration == rhs.duration &&
    +
    333  lhs.language == rhs.language;
    +
    334 }
    +
    335 
    +
    336 inline bool operator==(const VideoMediaHeader& lhs,
    +
    337  const VideoMediaHeader& rhs) {
    +
    338  return lhs.graphicsmode == rhs.graphicsmode &&
    +
    339  lhs.opcolor_red == rhs.opcolor_red &&
    +
    340  lhs.opcolor_green == rhs.opcolor_green &&
    +
    341  lhs.opcolor_blue == rhs.opcolor_blue;
    +
    342 }
    +
    343 
    +
    344 inline bool operator==(const SoundMediaHeader& lhs,
    +
    345  const SoundMediaHeader& rhs) {
    +
    346  return lhs.balance == rhs.balance;
    +
    347 }
    +
    348 
    +
    349 inline bool operator==(const SubtitleMediaHeader& lhs,
    +
    350  const SubtitleMediaHeader& rhs) {
    +
    351  return true;
    +
    352 }
    +
    353 
    +
    354 inline bool operator==(const DataEntryUrl& lhs, const DataEntryUrl& rhs) {
    +
    355  return lhs.flags == rhs.flags && lhs.location == rhs.location;
    +
    356 }
    +
    357 
    +
    358 inline bool operator==(const DataReference& lhs, const DataReference& rhs) {
    +
    359  return lhs.data_entry == rhs.data_entry;
    +
    360 }
    +
    361 
    +
    362 inline bool operator==(const DataInformation& lhs, const DataInformation& rhs) {
    +
    363  return lhs.dref == rhs.dref;
    +
    364 }
    +
    365 
    +
    366 inline bool operator==(const MediaInformation& lhs,
    +
    367  const MediaInformation& rhs) {
    +
    368  return lhs.dinf == rhs.dinf && lhs.sample_table == rhs.sample_table &&
    +
    369  lhs.vmhd == rhs.vmhd && lhs.smhd == rhs.smhd;
    +
    370 }
    +
    371 
    +
    372 inline bool operator==(const Media& lhs, const Media& rhs) {
    +
    373  return lhs.header == rhs.header && lhs.handler == rhs.handler &&
    +
    374  lhs.information == rhs.information;
    +
    375 }
    +
    376 
    +
    377 inline bool operator==(const Track& lhs, const Track& rhs) {
    +
    378  return lhs.header == rhs.header && lhs.media == rhs.media &&
    +
    379  lhs.edit == rhs.edit && lhs.sample_encryption == rhs.sample_encryption;
    +
    380 }
    +
    381 
    +
    382 inline bool operator==(const MovieExtendsHeader& lhs,
    +
    383  const MovieExtendsHeader& rhs) {
    +
    384  return lhs.fragment_duration == rhs.fragment_duration;
    +
    385 }
    +
    386 
    +
    387 inline bool operator==(const TrackExtends& lhs, const TrackExtends& rhs) {
    +
    388  return lhs.track_id == rhs.track_id &&
    +
    389  lhs.default_sample_description_index ==
    +
    390  rhs.default_sample_description_index &&
    +
    391  lhs.default_sample_duration == rhs.default_sample_duration &&
    +
    392  lhs.default_sample_size == rhs.default_sample_size &&
    +
    393  lhs.default_sample_flags == rhs.default_sample_flags;
    +
    394 }
    +
    395 
    +
    396 inline bool operator==(const MovieExtends& lhs, const MovieExtends& rhs) {
    +
    397  return lhs.header == rhs.header && lhs.tracks == rhs.tracks;
    +
    398 }
    +
    399 
    +
    400 inline bool operator==(const Movie& lhs, const Movie& rhs) {
    +
    401  return lhs.header == rhs.header && lhs.extends == rhs.extends &&
    +
    402  lhs.tracks == rhs.tracks && lhs.pssh == rhs.pssh;
    +
    403 }
    +
    404 
    +
    405 inline bool operator==(const TrackFragmentDecodeTime& lhs,
    +
    406  const TrackFragmentDecodeTime& rhs) {
    +
    407  return lhs.decode_time == rhs.decode_time;
    +
    408 }
    +
    409 
    +
    410 inline bool operator==(const MovieFragmentHeader& lhs,
    +
    411  const MovieFragmentHeader& rhs) {
    +
    412  return lhs.sequence_number == rhs.sequence_number;
    +
    413 }
    +
    414 
    +
    415 inline bool operator==(const TrackFragmentHeader& lhs,
    +
    416  const TrackFragmentHeader& rhs) {
    +
    417  return lhs.flags == rhs.flags && lhs.track_id == rhs.track_id &&
    +
    418  lhs.sample_description_index == rhs.sample_description_index &&
    +
    419  lhs.default_sample_duration == rhs.default_sample_duration &&
    +
    420  lhs.default_sample_size == rhs.default_sample_size &&
    +
    421  lhs.default_sample_flags == rhs.default_sample_flags;
    +
    422 }
    +
    423 
    +
    424 inline bool operator==(const TrackFragmentRun& lhs,
    +
    425  const TrackFragmentRun& rhs) {
    +
    426  return lhs.flags == rhs.flags && lhs.sample_count == rhs.sample_count &&
    +
    427  lhs.data_offset == rhs.data_offset &&
    +
    428  lhs.sample_flags == rhs.sample_flags &&
    +
    429  lhs.sample_sizes == rhs.sample_sizes &&
    +
    430  lhs.sample_durations == rhs.sample_durations &&
    +
    431  lhs.sample_composition_time_offsets ==
    +
    432  rhs.sample_composition_time_offsets;
    +
    433 }
    +
    434 
    +
    435 inline bool operator==(const TrackFragment& lhs, const TrackFragment& rhs) {
    +
    436  return lhs.header == rhs.header && lhs.runs == rhs.runs &&
    +
    437  lhs.decode_time == rhs.decode_time &&
    +
    438  lhs.auxiliary_offset == rhs.auxiliary_offset &&
    +
    439  lhs.auxiliary_size == rhs.auxiliary_size &&
    +
    440  lhs.sample_encryption == rhs.sample_encryption;
    +
    441 }
    +
    442 
    +
    443 inline bool operator==(const MovieFragment& lhs, const MovieFragment& rhs) {
    +
    444  return lhs.header == rhs.header && lhs.tracks == rhs.tracks &&
    +
    445  lhs.pssh == rhs.pssh;
    +
    446 }
    +
    447 
    +
    448 inline bool operator==(const SegmentReference& lhs,
    +
    449  const SegmentReference& rhs) {
    +
    450  return lhs.reference_type == rhs.reference_type &&
    +
    451  lhs.referenced_size == rhs.referenced_size &&
    +
    452  lhs.subsegment_duration == rhs.subsegment_duration &&
    +
    453  lhs.starts_with_sap == rhs.starts_with_sap &&
    +
    454  lhs.sap_type == rhs.sap_type &&
    +
    455  lhs.sap_delta_time == rhs.sap_delta_time;
    +
    456 }
    +
    457 
    +
    458 inline bool operator==(const SegmentIndex& lhs, const SegmentIndex& rhs) {
    +
    459  return lhs.reference_id == rhs.reference_id &&
    +
    460  lhs.timescale == rhs.timescale &&
    +
    461  lhs.earliest_presentation_time == rhs.earliest_presentation_time &&
    +
    462  lhs.first_offset == rhs.first_offset &&
    +
    463  lhs.references == rhs.references;
    +
    464 }
    +
    465 
    +
    466 inline bool operator==(const CueSourceIDBox& lhs,
    +
    467  const CueSourceIDBox& rhs) {
    +
    468  return lhs.source_id == rhs.source_id;
    +
    469 }
    +
    470 
    +
    471 inline bool operator==(const CueTimeBox& lhs,
    +
    472  const CueTimeBox& rhs) {
    +
    473  return lhs.cue_current_time == rhs.cue_current_time;
    +
    474 }
    +
    475 
    +
    476 inline bool operator==(const CueIDBox& lhs,
    +
    477  const CueIDBox& rhs) {
    +
    478  return lhs.cue_id == rhs.cue_id;
    +
    479 }
    +
    480 
    +
    481 inline bool operator==(const CueSettingsBox& lhs,
    +
    482  const CueSettingsBox& rhs) {
    +
    483  return lhs.settings == rhs.settings;
    +
    484 }
    +
    485 
    +
    486 inline bool operator==(const CuePayloadBox& lhs,
    +
    487  const CuePayloadBox& rhs) {
    +
    488  return lhs.cue_text == rhs.cue_text;
    +
    489 }
    +
    490 
    +
    491 inline bool operator==(const VTTEmptyCueBox& lhs, const VTTEmptyCueBox& rhs) {
    +
    492  return true;
    +
    493 }
    +
    494 
    +
    495 inline bool operator==(const VTTAdditionalTextBox& lhs,
    +
    496  const VTTAdditionalTextBox& rhs) {
    +
    497  return lhs.cue_additional_text == rhs.cue_additional_text;
    +
    498 }
    +
    499 
    +
    500 inline bool operator==(const VTTCueBox& lhs,
    +
    501  const VTTCueBox& rhs) {
    +
    502  return lhs.cue_source_id == rhs.cue_source_id && lhs.cue_id == rhs.cue_id &&
    +
    503  lhs.cue_time == rhs.cue_time && lhs.cue_settings == rhs.cue_settings &&
    +
    504  lhs.cue_payload == rhs.cue_payload;
    +
    505 }
    +
    506 
    +
    507 } // namespace mp4
    +
    508 } // namespace media
    +
    509 } // namespace shaka
    +
    510 
    +
    511 #endif // PACKAGER_MEDIA_FORMATS_MP4_BOX_DEFINITIONS_COMPARISON_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d85/classshaka_1_1media_1_1OriginHandler.html b/docs/de/d85/classshaka_1_1media_1_1OriginHandler.html index 15994ff70c..e2e576b24b 100644 --- a/docs/de/d85/classshaka_1_1media_1_1OriginHandler.html +++ b/docs/de/d85/classshaka_1_1media_1_1OriginHandler.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::OriginHandler Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::media::MediaHandler +shaka::media::MediaHandler shaka::media::Demuxer -shaka::media::WebVttParser - -
    + + @@ -108,9 +110,9 @@ bool  - - + + @@ -179,9 +181,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/de/d85/classshaka_1_1media_1_1OriginHandler.png b/docs/de/d85/classshaka_1_1media_1_1OriginHandler.png index 9cfdae6832a7384a37a5303ebaab3ba3e8fb31f0..97ec81b436a87ef4c9a21e9e4bbdcd3dcad75b65 100644 GIT binary patch delta 990 zcmZ3<-NB*Q8Q|y6%O%Cdz`(%k>ERLtq*noP2M05dbU4${J5kZ9o_V^bi(^OyR@zJhKN9wk3|9MXK*^ede=rZYeCq&BRbzR_~U-oo=YKVR4VX_0)|Sp2}$-)*;)%3j*)#LoS)?fbEH3^7-XAN0KP z%bhdRZ0lj2X3s+{RmpR>4xC;UyJ};Y?0?%;(NVFAwLz=P8UM#H=q?Xm{QOH?#B8s6 z>C@&_&6U;;brGsB-@|?872?@-tuM+;)0;yfj=#Zl3*W298+l$^t+0NnwT64)Gd>1^ z^)9R(VT+htv;!FzO7R413fS|sVOuLHN|-o7RveSiz5itWn0 z-|^>?w%4CMcU{|>U26Ru#XAjwD;Va+eZTkZKhxK#Eqg0@inhi1|Ne8u;`!a=-LrGA zzx?^9qDJbxp;VUa8?^-2JptzpOrvsRSAh=1j=SiCD(I{lcN zHBXP{q2nt)|0+>Fv%>uJD+8aUFK?XT`><@qdkK5phG~~qUo5WD&)M$y1oV5C`nbr2^{*(4yyze;mitPI6`epckI?GoQYjNJMsJH|7=?mV<*qMRv~k24%_V? zcNT7*w8XJqt0DWQ)T&xnpDKRuaCN>{sh&;)ZYv-(IwmOCLx6WSkt2^;qFMnYE zw5y3Tj_q-t%l&uN?Qce|A`aZ8rd59V>^pM8O>gXd5@S-C&OTv@=g&l-4^&sFxN5`l h)~!Hq%~a06%yAvA3LiF176fKl22WQ%mvv4FO#op=&}RSu literal 1449 zcmb_ceN2*D9DdOuCZTPu{2;?_R5L4gOH=d4G(QR}GHj`sqA@KeYH3BiEF{f7mZhPo z*X+ZU&Tp}1X!r_7scD9Y@+O#KWr;{+id0Bk>h5;$+TH!@p6#6TJik5XkLUUAcP@sK zwqtCZYybej5O)NU0RRzW#uuzD&1dm=dcFB_2;H?W$Ye5^;lz~gc+6@w0>y~3uVY)MpTlS3tX^jrnvbJPqf^5o(bOW^d}IE=T$(j@LSv~- znweI~+fNi8B*2Gl)opa}dUlGVcty0GN)&@S(HmFEaQxr|p5J+xpXpKM9M^LG$pa~K zQFD^*ok1+`@e)vbyMqRa_78dfz6aDw*f8BTSyR6TQb;ZlHVk>oypPOscMoTmWZ{hm z|1vB3+5NY|<^0L@4DLl+>+G}(E~QEyF34Fi))9TcL1_bC@1}gB?456HYLT>1A*NwQDc%Fy1|Lmk zB1*69PLI&XOR=NmxQo5!_I%!vO1BMwdf0HE?}2TKC65DrGlkq21Q~x6^>T52nLf71 zu2n)B7J(8}LYTf`0?UPCwG&necbgKLmdU{~y%Hr-W= zY&DG#$-ZAU5uMWP6v3q2T)gpY07UKC*mv18qnGj96@AT9iCdNL%_7#MUJb4~-l+gb zGoF==yqn)O1Jl~%XFIF-sDaMGuA?tXSk7Mi!)EGeIq5i+5iE2wb|tZL)f#e_S4H1i z@BS#B|4!b>KuEFWwrUYmzIkCdiua@+pV;ZAW!xXGXbjeDA0B6hwxc2A{>U|z3P;5m z5xkmiF!>VH1_qt7PAkfRC%@x-UX+XW?}hiJ;H#>P~|X@M^agt=Eo#tZd2 zmRCD^Mz|J1myT&sk4GBZ4;hT1|DK|G&D{&B` zwVay5Z>!1f)I`0KJ47LIUgzBtS|nI7Rp1v4GLj9Vw|(8zJzr|KYu|X%UuI2f+Ky#& zH_Dk5&gNF>GFCx698`2QNnIHZ4~AyRqKX8kk?!ASdv!;zKZoTmb0a23G~mnQAWp$K sT?pCfpM{R-RM+y-%-g&IGO0b|Y++)>Wb^w^=6@9+29W~mx5Z}u0f}YQEdT%j diff --git a/docs/de/d87/structshaka_1_1media_1_1wvm_1_1PrevSampleData-members.html b/docs/de/d87/structshaka_1_1media_1_1wvm_1_1PrevSampleData-members.html index 71bfb9e62b..9c8fc9b79e 100644 --- a/docs/de/d87/structshaka_1_1media_1_1wvm_1_1PrevSampleData-members.html +++ b/docs/de/d87/structshaka_1_1media_1_1wvm_1_1PrevSampleData-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    virtual Status InitializeInternal ()=0
     
    - + +/* @license-end */
    diff --git a/docs/de/d88/tag_8cc_source.html b/docs/de/d88/tag_8cc_source.html index 193bc0e010..6f8ba42612 100644 --- a/docs/de/d88/tag_8cc_source.html +++ b/docs/de/d88/tag_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base/tag.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    tag.cc
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/hls/base/tag.h"
    8 
    9 #include <inttypes.h>
    10 
    11 #include "packager/base/strings/stringprintf.h"
    12 
    13 namespace shaka {
    14 namespace hls {
    15 
    16 Tag::Tag(const std::string& name, std::string* buffer) : buffer_(buffer) {
    17  base::StringAppendF(buffer_, "%s:", name.c_str());
    18 }
    19 
    20 void Tag::AddString(const std::string& key, const std::string& value) {
    21  NextField();
    22  base::StringAppendF(buffer_, "%s=%s", key.c_str(), value.c_str());
    23 }
    24 
    25 void Tag::AddQuotedString(const std::string& key, const std::string& value) {
    26  NextField();
    27  base::StringAppendF(buffer_, "%s=\"%s\"", key.c_str(), value.c_str());
    28 }
    29 
    30 void Tag::AddNumber(const std::string& key, uint64_t value) {
    31  NextField();
    32  base::StringAppendF(buffer_, "%s=%" PRIu64, key.c_str(), value);
    33 }
    34 
    35 void Tag::AddFloat(const std::string& key, float value) {
    36  NextField();
    37  base::StringAppendF(buffer_, "%s=%.3f", key.c_str(), value);
    38 }
    39 
    40 void Tag::AddNumberPair(const std::string& key,
    41  uint64_t number1,
    42  char separator,
    43  uint64_t number2) {
    44  NextField();
    45  base::StringAppendF(buffer_, "%s=%" PRIu64 "%c%" PRIu64, key.c_str(), number1,
    46  separator, number2);
    47 }
    48 
    49 void Tag::AddQuotedNumberPair(const std::string& key,
    50  uint64_t number1,
    51  char separator,
    52  uint64_t number2) {
    53  NextField();
    54  base::StringAppendF(buffer_, "%s=\"%" PRIu64 "%c%" PRIu64 "\"", key.c_str(),
    55  number1, separator, number2);
    56 }
    57 
    58 void Tag::NextField() {
    59  if (fields++) {
    60  buffer_->append(",");
    61  }
    62 }
    63 
    64 } // namespace hls
    65 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    -
    void AddQuotedString(const std::string &key, const std::string &value)
    Add a quoted string value to the argument list.
    Definition: tag.cc:25
    -
    void AddString(const std::string &key, const std::string &value)
    Add a non-quoted string value to the argument list.
    Definition: tag.cc:20
    -
    void AddNumber(const std::string &key, uint64_t value)
    Add a non-quoted numeric value to the argument list.
    Definition: tag.cc:30
    -
    void AddFloat(const std::string &key, float value)
    Add a non-quoted float value to the argument list.
    Definition: tag.cc:35
    -
    void AddQuotedNumberPair(const std::string &key, uint64_t number1, char separator, uint64_t number2)
    Add a quoted pair of numbers with a symbol separating them.
    Definition: tag.cc:49
    -
    void AddNumberPair(const std::string &key, uint64_t number1, char separator, uint64_t number2)
    Add a pair of numbers with a symbol separating them.
    Definition: tag.cc:40
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/hls/base/tag.h"
    +
    8 
    +
    9 #include <inttypes.h>
    +
    10 
    +
    11 #include "packager/base/strings/stringprintf.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace hls {
    +
    15 
    +
    16 Tag::Tag(const std::string& name, std::string* buffer) : buffer_(buffer) {
    +
    17  base::StringAppendF(buffer_, "%s:", name.c_str());
    +
    18 }
    +
    19 
    +
    20 void Tag::AddString(const std::string& key, const std::string& value) {
    +
    21  NextField();
    +
    22  base::StringAppendF(buffer_, "%s=%s", key.c_str(), value.c_str());
    +
    23 }
    +
    24 
    +
    25 void Tag::AddQuotedString(const std::string& key, const std::string& value) {
    +
    26  NextField();
    +
    27  base::StringAppendF(buffer_, "%s=\"%s\"", key.c_str(), value.c_str());
    +
    28 }
    +
    29 
    +
    30 void Tag::AddNumber(const std::string& key, uint64_t value) {
    +
    31  NextField();
    +
    32  base::StringAppendF(buffer_, "%s=%" PRIu64, key.c_str(), value);
    +
    33 }
    +
    34 
    +
    35 void Tag::AddFloat(const std::string& key, float value) {
    +
    36  NextField();
    +
    37  base::StringAppendF(buffer_, "%s=%.3f", key.c_str(), value);
    +
    38 }
    +
    39 
    +
    40 void Tag::AddNumberPair(const std::string& key,
    +
    41  uint64_t number1,
    +
    42  char separator,
    +
    43  uint64_t number2) {
    +
    44  NextField();
    +
    45  base::StringAppendF(buffer_, "%s=%" PRIu64 "%c%" PRIu64, key.c_str(), number1,
    +
    46  separator, number2);
    +
    47 }
    +
    48 
    +
    49 void Tag::AddQuotedNumberPair(const std::string& key,
    +
    50  uint64_t number1,
    +
    51  char separator,
    +
    52  uint64_t number2) {
    +
    53  NextField();
    +
    54  base::StringAppendF(buffer_, "%s=\"%" PRIu64 "%c%" PRIu64 "\"", key.c_str(),
    +
    55  number1, separator, number2);
    +
    56 }
    +
    57 
    +
    58 void Tag::NextField() {
    +
    59  if (fields++) {
    +
    60  buffer_->append(",");
    +
    61  }
    +
    62 }
    +
    63 
    +
    64 } // namespace hls
    +
    65 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/d8d/structshaka_1_1media_1_1mp4_1_1MovieFragmentHeader-members.html b/docs/de/d8d/structshaka_1_1media_1_1mp4_1_1MovieFragmentHeader-members.html index 6dc6fd7ef3..021f76da2f 100644 --- a/docs/de/d8d/structshaka_1_1media_1_1mp4_1_1MovieFragmentHeader-members.html +++ b/docs/de/d8d/structshaka_1_1media_1_1mp4_1_1MovieFragmentHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/de/d93/classshaka_1_1media_1_1VP8Parser-members.html b/docs/de/d93/classshaka_1_1media_1_1VP8Parser-members.html index cef9ea08b8..2f0e3e18bf 100644 --- a/docs/de/d93/classshaka_1_1media_1_1VP8Parser-members.html +++ b/docs/de/d93/classshaka_1_1media_1_1VP8Parser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/da6/aes__encryptor__factory_8h_source.html b/docs/de/da6/aes__encryptor__factory_8h_source.html index 0c27227f54..c2f064705a 100644 --- a/docs/de/da6/aes__encryptor__factory_8h_source.html +++ b/docs/de/da6/aes__encryptor__factory_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto/aes_encryptor_factory.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    aes_encryptor_factory.h
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CRYPTO_AES_ENCRYPTOR_FACTORY_H_
    8 #define PACKAGER_MEDIA_CRYPTO_AES_ENCRYPTOR_FACTORY_H_
    9 
    10 #include "packager/media/base/fourccs.h"
    11 #include "packager/media/base/stream_info.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    16 class AesCryptor;
    17 
    20  public:
    21  AesEncryptorFactory() = default;
    22  virtual ~AesEncryptorFactory() = default;
    23 
    24  // Virtual for mocking.
    25  virtual std::unique_ptr<AesCryptor> CreateEncryptor(
    26  FourCC protection_scheme,
    27  uint8_t crypt_byte_block,
    28  uint8_t skip_byte_block,
    29  Codec codec,
    30  const std::vector<uint8_t>& key,
    31  const std::vector<uint8_t>& iv);
    32 
    33  private:
    35  AesEncryptorFactory& operator=(const AesEncryptorFactory&) = delete;
    36 };
    37 
    38 } // namespace media
    39 } // namespace shaka
    40 
    41 #endif // PACKAGER_MEDIA_CRYPTO_AES_ENCRYPTOR_FACTORY_H_
    All the methods that are virtual are virtual for mocking.
    -
    A factory class to create encryptors.
    +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CRYPTO_AES_ENCRYPTOR_FACTORY_H_
    +
    8 #define PACKAGER_MEDIA_CRYPTO_AES_ENCRYPTOR_FACTORY_H_
    +
    9 
    +
    10 #include "packager/media/base/fourccs.h"
    +
    11 #include "packager/media/base/stream_info.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 namespace media {
    +
    15 
    +
    16 class AesCryptor;
    +
    17 
    + +
    20  public:
    +
    21  AesEncryptorFactory() = default;
    +
    22  virtual ~AesEncryptorFactory() = default;
    +
    23 
    +
    24  // Virtual for mocking.
    +
    25  virtual std::unique_ptr<AesCryptor> CreateEncryptor(
    +
    26  FourCC protection_scheme,
    +
    27  uint8_t crypt_byte_block,
    +
    28  uint8_t skip_byte_block,
    +
    29  Codec codec,
    +
    30  const std::vector<uint8_t>& key,
    +
    31  const std::vector<uint8_t>& iv);
    +
    32 
    +
    33  private:
    + +
    35  AesEncryptorFactory& operator=(const AesEncryptorFactory&) = delete;
    +
    36 };
    +
    37 
    +
    38 } // namespace media
    +
    39 } // namespace shaka
    +
    40 
    +
    41 #endif // PACKAGER_MEDIA_CRYPTO_AES_ENCRYPTOR_FACTORY_H_
    +
    A factory class to create encryptors.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/da9/structshaka_1_1Element.html b/docs/de/da9/structshaka_1_1Element.html index e264017bc3..d1a64da14f 100644 --- a/docs/de/da9/structshaka_1_1Element.html +++ b/docs/de/da9/structshaka_1_1Element.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::Element Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    El
    diff --git a/docs/de/dab/es__parser__h26x_8cc_source.html b/docs/de/dab/es__parser__h26x_8cc_source.html index 8926108398..609456494d 100644 --- a/docs/de/dab/es__parser__h26x_8cc_source.html +++ b/docs/de/dab/es__parser__h26x_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser_h26x.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    es_parser_h26x.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/mp2t/es_parser_h26x.h"
    6 
    7 #include <stdint.h>
    8 
    9 #include "packager/base/logging.h"
    10 #include "packager/base/numerics/safe_conversions.h"
    11 #include "packager/media/base/media_sample.h"
    12 #include "packager/media/base/offset_byte_queue.h"
    13 #include "packager/media/base/timestamp.h"
    14 #include "packager/media/base/video_stream_info.h"
    15 #include "packager/media/codecs/h26x_byte_to_unit_stream_converter.h"
    16 #include "packager/media/formats/mp2t/mp2t_common.h"
    17 
    18 namespace shaka {
    19 namespace media {
    20 namespace mp2t {
    21 
    22 namespace {
    23 
    24 const int kStartCodeSize = 3;
    25 const int kH264NaluHeaderSize = 1;
    26 const int kH265NaluHeaderSize = 2;
    27 
    28 } // namespace
    29 
    30 EsParserH26x::EsParserH26x(
    31  Nalu::CodecType type,
    32  std::unique_ptr<H26xByteToUnitStreamConverter> stream_converter,
    33  uint32_t pid,
    34  const EmitSampleCB& emit_sample_cb)
    35  : EsParser(pid),
    36  emit_sample_cb_(emit_sample_cb),
    37  type_(type),
    38  es_queue_(new media::OffsetByteQueue()),
    39  stream_converter_(std::move(stream_converter)) {}
    40 
    41 EsParserH26x::~EsParserH26x() {}
    42 
    43 bool EsParserH26x::Parse(const uint8_t* buf,
    44  int size,
    45  int64_t pts,
    46  int64_t dts) {
    47  // Note: Parse is invoked each time a PES packet has been reassembled.
    48  // Unfortunately, a PES packet does not necessarily map
    49  // to an h264/h265 access unit, although the HLS recommendation is to use one
    50  // PES for each access unit (but this is just a recommendation and some
    51  // streams do not comply with this recommendation).
    52 
    53  // HLS recommendation: "In AVC video, you should have both a DTS and a
    54  // PTS in each PES header".
    55  // However, some streams do not comply with this recommendation.
    56  DVLOG_IF(1, pts == kNoTimestamp) << "Each video PES should have a PTS";
    57  if (pts != kNoTimestamp) {
    58  TimingDesc timing_desc;
    59  timing_desc.pts = pts;
    60  timing_desc.dts = (dts != kNoTimestamp) ? dts : pts;
    61 
    62  // Link the end of the byte queue with the incoming timing descriptor.
    63  timing_desc_list_.push_back(
    64  std::pair<int64_t, TimingDesc>(es_queue_->tail(), timing_desc));
    65 
    66  // Warns if there are a large number of cached timestamps, which should be 1
    67  // or 2 if everythings works as expected.
    68  const size_t kWarningSize =
    69  24; // An arbitrary number (it is 1 second for a fps of 24).
    70  LOG_IF(WARNING, timing_desc_list_.size() >= kWarningSize)
    71  << "Unusually large number of cached timestamps ("
    72  << timing_desc_list_.size() << ").";
    73  }
    74 
    75  // Add the incoming bytes to the ES queue.
    76  es_queue_->Push(buf, size);
    77  return ParseInternal();
    78 }
    79 
    80 void EsParserH26x::Flush() {
    81  DVLOG(1) << "EsParserH26x::Flush";
    82 
    83  // Simulate two additional AUDs to force emitting the last access unit
    84  // which is assumed to be complete at this point.
    85  // Two AUDs are needed because the exact size of a NAL unit can only be
    86  // determined after seeing the next NAL unit, so we need a second AUD to
    87  // finish the parsing of the first AUD.
    88  if (type_ == Nalu::kH264) {
    89  const uint8_t aud[] = {0x00, 0x00, 0x01, 0x09, 0x00, 0x00, 0x01, 0x09};
    90  es_queue_->Push(aud, sizeof(aud));
    91  } else {
    92  DCHECK_EQ(Nalu::kH265, type_);
    93  const uint8_t aud[] = {0x00, 0x00, 0x01, 0x46, 0x01,
    94  0x00, 0x00, 0x01, 0x46, 0x01};
    95  es_queue_->Push(aud, sizeof(aud));
    96  }
    97 
    98  CHECK(ParseInternal());
    99 
    100  if (pending_sample_) {
    101  // Flush pending sample.
    102  DCHECK(pending_sample_duration_);
    103  pending_sample_->set_duration(pending_sample_duration_);
    104  emit_sample_cb_.Run(pid(), pending_sample_);
    105  pending_sample_ = std::shared_ptr<MediaSample>();
    106  }
    107 }
    108 
    109 void EsParserH26x::Reset() {
    110  es_queue_.reset(new media::OffsetByteQueue());
    111  current_search_position_ = 0;
    112  current_access_unit_position_ = 0;
    113  current_video_slice_info_.valid = false;
    114  next_access_unit_position_set_ = false;
    115  next_access_unit_position_ = 0;
    116  current_nalu_info_.reset();
    117  timing_desc_list_.clear();
    118  pending_sample_ = std::shared_ptr<MediaSample>();
    119  pending_sample_duration_ = 0;
    120  waiting_for_key_frame_ = true;
    121 }
    122 
    123 bool EsParserH26x::SearchForNalu(uint64_t* position, Nalu* nalu) {
    124  const uint8_t* es;
    125  int es_size;
    126  es_queue_->PeekAt(current_search_position_, &es, &es_size);
    127 
    128  // Find a start code.
    129  uint64_t start_code_offset;
    130  uint8_t start_code_size;
    131  const bool start_code_found = NaluReader::FindStartCode(
    132  es, es_size, &start_code_offset, &start_code_size);
    133 
    134  if (!start_code_found) {
    135  // We didn't find a start code, so we don't have to search this data again.
    136  if (es_size > kStartCodeSize)
    137  current_search_position_ += es_size - kStartCodeSize;
    138  return false;
    139  }
    140 
    141  // Ensure the next NAL unit is a real NAL unit.
    142  const uint8_t* next_nalu_ptr = es + start_code_offset + start_code_size;
    143  // This size is likely inaccurate, this is just to get the header info.
    144  const int64_t next_nalu_size = es_size - start_code_offset - start_code_size;
    145  if (next_nalu_size <
    146  (type_ == Nalu::kH264 ? kH264NaluHeaderSize : kH265NaluHeaderSize)) {
    147  // There was not enough data, wait for more.
    148  return false;
    149  }
    150 
    151  // Update search position for next nalu.
    152  current_search_position_ += start_code_offset + start_code_size;
    153 
    154  // |next_nalu_info_| is made global intentionally to avoid repetitive memory
    155  // allocation which could create memory fragments.
    156  if (!next_nalu_info_)
    157  next_nalu_info_.reset(new NaluInfo);
    158  if (!next_nalu_info_->nalu.Initialize(type_, next_nalu_ptr, next_nalu_size)) {
    159  // This NAL unit is invalid, skip it and search again.
    160  return SearchForNalu(position, nalu);
    161  }
    162  next_nalu_info_->position = current_search_position_ - start_code_size;
    163  next_nalu_info_->start_code_size = start_code_size;
    164 
    165  const bool current_nalu_set = current_nalu_info_ ? true : false;
    166  if (current_nalu_info_) {
    167  // Starting position for the nalu including start code.
    168  *position = current_nalu_info_->position;
    169  // Update the NALU because the data pointer may have been invalidated.
    170  const uint8_t* current_nalu_ptr =
    171  next_nalu_ptr +
    172  (current_nalu_info_->position + current_nalu_info_->start_code_size) -
    173  current_search_position_;
    174  const uint64_t current_nalu_size = next_nalu_info_->position -
    175  current_nalu_info_->position -
    176  current_nalu_info_->start_code_size;
    177  CHECK(nalu->Initialize(type_, current_nalu_ptr, current_nalu_size));
    178  }
    179  current_nalu_info_.swap(next_nalu_info_);
    180  return current_nalu_set ? true : SearchForNalu(position, nalu);
    181 }
    182 
    183 bool EsParserH26x::ParseInternal() {
    184  uint64_t position;
    185  Nalu nalu;
    186  VideoSliceInfo video_slice_info;
    187  while (SearchForNalu(&position, &nalu)) {
    188  // ITU H.264 sec. 7.4.1.2.3
    189  // H264: The first of the NAL units with |can_start_access_unit() == true|
    190  // after the last VCL NAL unit of a primary coded picture specifies the
    191  // start of a new access unit.
    192  // ITU H.265 sec. 7.4.2.4.4
    193  // H265: The first of the NAL units with |can_start_access_unit() == true|
    194  // after the last VCL NAL unit preceding firstBlPicNalUnit (the first
    195  // VCL NAL unit of a coded picture with nuh_layer_id equal to 0), if
    196  // any, specifies the start of a new access unit.
    197  if (nalu.can_start_access_unit()) {
    198  if (!next_access_unit_position_set_) {
    199  next_access_unit_position_set_ = true;
    200  next_access_unit_position_ = position;
    201  }
    202  RCHECK(ProcessNalu(nalu, &video_slice_info));
    203  if (nalu.is_vcl() && !video_slice_info.valid) {
    204  // This could happen only if decoder config is not available yet. Drop
    205  // this frame.
    206  DCHECK(!current_video_slice_info_.valid);
    207  next_access_unit_position_set_ = false;
    208  continue;
    209  }
    210  } else if (nalu.is_vcl()) {
    211  // This isn't the first VCL NAL unit. Next access unit should start after
    212  // this NAL unit.
    213  next_access_unit_position_set_ = false;
    214  continue;
    215  }
    216 
    217  // AUD shall be the first NAL unit if present. There shall be at most one
    218  // AUD in any access unit. We can emit the current access unit which shall
    219  // not contain the AUD.
    220  if (nalu.is_aud()) {
    221  RCHECK(EmitCurrentAccessUnit());
    222  continue;
    223  }
    224 
    225  // We can only determine if the current access unit ends after seeing
    226  // another VCL NAL unit.
    227  if (!video_slice_info.valid)
    228  continue;
    229 
    230  // Check if it is the first VCL NAL unit of a primary coded picture. It is
    231  // always true for H265 as nuh_layer_id shall be == 0 at this point.
    232  bool is_first_vcl_nalu = true;
    233  if (type_ == Nalu::kH264) {
    234  if (current_video_slice_info_.valid) {
    235  // ITU H.264 sec. 7.4.1.2.4 Detection of the first VCL NAL unit of a
    236  // primary coded picture. Only pps_id and frame_num are checked here.
    237  is_first_vcl_nalu =
    238  video_slice_info.frame_num != current_video_slice_info_.frame_num ||
    239  video_slice_info.pps_id != current_video_slice_info_.pps_id;
    240  }
    241  }
    242  if (!is_first_vcl_nalu) {
    243  // This isn't the first VCL NAL unit. Next access unit should start after
    244  // this NAL unit.
    245  next_access_unit_position_set_ = false;
    246  continue;
    247  }
    248 
    249  DCHECK(next_access_unit_position_set_);
    250  RCHECK(EmitCurrentAccessUnit());
    251 
    252  // Delete the data we have already processed.
    253  es_queue_->Trim(next_access_unit_position_);
    254 
    255  current_access_unit_position_ = next_access_unit_position_;
    256  current_video_slice_info_ = video_slice_info;
    257  next_access_unit_position_set_ = false;
    258  }
    259  return true;
    260 }
    261 
    262 bool EsParserH26x::EmitCurrentAccessUnit() {
    263  if (current_video_slice_info_.valid) {
    264  if (current_video_slice_info_.is_key_frame)
    265  waiting_for_key_frame_ = false;
    266  if (!waiting_for_key_frame_) {
    267  RCHECK(
    268  EmitFrame(current_access_unit_position_,
    269  next_access_unit_position_ - current_access_unit_position_,
    270  current_video_slice_info_.is_key_frame,
    271  current_video_slice_info_.pps_id));
    272  }
    273  current_video_slice_info_.valid = false;
    274  }
    275  return true;
    276 }
    277 
    278 bool EsParserH26x::EmitFrame(int64_t access_unit_pos,
    279  int access_unit_size,
    280  bool is_key_frame,
    281  int pps_id) {
    282  // Get the access unit timing info.
    283  TimingDesc current_timing_desc = {kNoTimestamp, kNoTimestamp};
    284  while (!timing_desc_list_.empty() &&
    285  timing_desc_list_.front().first <= access_unit_pos) {
    286  current_timing_desc = timing_desc_list_.front().second;
    287  timing_desc_list_.pop_front();
    288  }
    289  if (current_timing_desc.pts == kNoTimestamp)
    290  return false;
    291 
    292  // Emit a frame.
    293  DVLOG(LOG_LEVEL_ES) << "Emit frame: stream_pos=" << access_unit_pos
    294  << " size=" << access_unit_size << " pts "
    295  << current_timing_desc.pts << " timing_desc_list size "
    296  << timing_desc_list_.size();
    297  int es_size;
    298  const uint8_t* es;
    299  es_queue_->PeekAt(access_unit_pos, &es, &es_size);
    300 
    301  // Convert frame to unit stream format.
    302  std::vector<uint8_t> converted_frame;
    303  if (!stream_converter_->ConvertByteStreamToNalUnitStream(
    304  es, access_unit_size, &converted_frame)) {
    305  DLOG(ERROR) << "Failure to convert video frame to unit stream format.";
    306  return false;
    307  }
    308 
    309  // Update the video decoder configuration if needed.
    310  RCHECK(UpdateVideoDecoderConfig(pps_id));
    311 
    312  // Create the media sample, emitting always the previous sample after
    313  // calculating its duration.
    314  std::shared_ptr<MediaSample> media_sample = MediaSample::CopyFrom(
    315  converted_frame.data(), converted_frame.size(), is_key_frame);
    316  media_sample->set_dts(current_timing_desc.dts);
    317  media_sample->set_pts(current_timing_desc.pts);
    318  if (pending_sample_) {
    319  if (media_sample->dts() <= pending_sample_->dts()) {
    320  LOG(WARNING) << "[MPEG-2 TS] PID " << pid() << " dts "
    321  << media_sample->dts()
    322  << " less than or equal to previous dts "
    323  << pending_sample_->dts();
    324  // Keep the sample but adjust the sample duration to a very small value,
    325  // in case that the sample is still needed for the decoding afterwards.
    326  const int64_t kArbitrarySmallDuration = 0.001 * kMpeg2Timescale; // 1ms.
    327  pending_sample_->set_duration(kArbitrarySmallDuration);
    328  } else {
    329  uint64_t sample_duration = media_sample->dts() - pending_sample_->dts();
    330  pending_sample_->set_duration(sample_duration);
    331 
    332  const int kArbitraryGapScale = 10;
    333  if (sample_duration > kArbitraryGapScale * pending_sample_duration_) {
    334  LOG(WARNING) << "[MPEG-2 TS] PID " << pid() << " Possible GAP at dts "
    335  << pending_sample_->dts() << " with next sample at dts "
    336  << media_sample->dts() << " (difference "
    337  << sample_duration << ")";
    338  }
    339 
    340  pending_sample_duration_ = sample_duration;
    341  }
    342  emit_sample_cb_.Run(pid(), std::move(pending_sample_));
    343  }
    344  pending_sample_ = media_sample;
    345 
    346  return true;
    347 }
    348 
    349 } // namespace mp2t
    350 } // namespace media
    351 } // namespace shaka
    STL namespace.
    -
    All the methods that are virtual are virtual for mocking.
    -
    static std::shared_ptr< MediaSample > CopyFrom(const uint8_t *data, size_t size, bool is_key_frame)
    Definition: media_sample.cc:42
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/mp2t/es_parser_h26x.h"
    +
    6 
    +
    7 #include <stdint.h>
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 #include "packager/base/numerics/safe_conversions.h"
    +
    11 #include "packager/media/base/media_sample.h"
    +
    12 #include "packager/media/base/offset_byte_queue.h"
    +
    13 #include "packager/media/base/timestamp.h"
    +
    14 #include "packager/media/base/video_stream_info.h"
    +
    15 #include "packager/media/codecs/h26x_byte_to_unit_stream_converter.h"
    +
    16 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 namespace mp2t {
    +
    21 
    +
    22 namespace {
    +
    23 
    +
    24 const int kStartCodeSize = 3;
    +
    25 const int kH264NaluHeaderSize = 1;
    +
    26 const int kH265NaluHeaderSize = 2;
    +
    27 
    +
    28 } // namespace
    +
    29 
    +
    30 EsParserH26x::EsParserH26x(
    +
    31  Nalu::CodecType type,
    +
    32  std::unique_ptr<H26xByteToUnitStreamConverter> stream_converter,
    +
    33  uint32_t pid,
    +
    34  const EmitSampleCB& emit_sample_cb)
    +
    35  : EsParser(pid),
    +
    36  emit_sample_cb_(emit_sample_cb),
    +
    37  type_(type),
    +
    38  es_queue_(new media::OffsetByteQueue()),
    +
    39  stream_converter_(std::move(stream_converter)) {}
    +
    40 
    +
    41 EsParserH26x::~EsParserH26x() {}
    +
    42 
    +
    43 bool EsParserH26x::Parse(const uint8_t* buf,
    +
    44  int size,
    +
    45  int64_t pts,
    +
    46  int64_t dts) {
    +
    47  // Note: Parse is invoked each time a PES packet has been reassembled.
    +
    48  // Unfortunately, a PES packet does not necessarily map
    +
    49  // to an h264/h265 access unit, although the HLS recommendation is to use one
    +
    50  // PES for each access unit (but this is just a recommendation and some
    +
    51  // streams do not comply with this recommendation).
    +
    52 
    +
    53  // HLS recommendation: "In AVC video, you should have both a DTS and a
    +
    54  // PTS in each PES header".
    +
    55  // However, some streams do not comply with this recommendation.
    +
    56  DVLOG_IF(1, pts == kNoTimestamp) << "Each video PES should have a PTS";
    +
    57  if (pts != kNoTimestamp) {
    +
    58  TimingDesc timing_desc;
    +
    59  timing_desc.pts = pts;
    +
    60  timing_desc.dts = (dts != kNoTimestamp) ? dts : pts;
    +
    61 
    +
    62  // Link the end of the byte queue with the incoming timing descriptor.
    +
    63  timing_desc_list_.push_back(
    +
    64  std::pair<int64_t, TimingDesc>(es_queue_->tail(), timing_desc));
    +
    65 
    +
    66  // Warns if there are a large number of cached timestamps, which should be 1
    +
    67  // or 2 if everythings works as expected.
    +
    68  const size_t kWarningSize =
    +
    69  24; // An arbitrary number (it is 1 second for a fps of 24).
    +
    70  LOG_IF(WARNING, timing_desc_list_.size() >= kWarningSize)
    +
    71  << "Unusually large number of cached timestamps ("
    +
    72  << timing_desc_list_.size() << ").";
    +
    73  }
    +
    74 
    +
    75  // Add the incoming bytes to the ES queue.
    +
    76  es_queue_->Push(buf, size);
    +
    77  return ParseInternal();
    +
    78 }
    +
    79 
    +
    80 bool EsParserH26x::Flush() {
    +
    81  DVLOG(1) << "EsParserH26x::Flush";
    +
    82 
    +
    83  // Simulate two additional AUDs to force emitting the last access unit
    +
    84  // which is assumed to be complete at this point.
    +
    85  // Two AUDs are needed because the exact size of a NAL unit can only be
    +
    86  // determined after seeing the next NAL unit, so we need a second AUD to
    +
    87  // finish the parsing of the first AUD.
    +
    88  if (type_ == Nalu::kH264) {
    +
    89  const uint8_t aud[] = {0x00, 0x00, 0x01, 0x09, 0x00, 0x00, 0x01, 0x09};
    +
    90  es_queue_->Push(aud, sizeof(aud));
    +
    91  } else {
    +
    92  DCHECK_EQ(Nalu::kH265, type_);
    +
    93  const uint8_t aud[] = {0x00, 0x00, 0x01, 0x46, 0x01,
    +
    94  0x00, 0x00, 0x01, 0x46, 0x01};
    +
    95  es_queue_->Push(aud, sizeof(aud));
    +
    96  }
    +
    97 
    +
    98  RCHECK(ParseInternal());
    +
    99 
    +
    100  if (pending_sample_) {
    +
    101  // Flush pending sample.
    +
    102  DCHECK(pending_sample_duration_);
    +
    103  pending_sample_->set_duration(pending_sample_duration_);
    +
    104  emit_sample_cb_.Run(std::move(pending_sample_));
    +
    105  }
    +
    106  return true;
    +
    107 }
    +
    108 
    +
    109 void EsParserH26x::Reset() {
    +
    110  es_queue_.reset(new media::OffsetByteQueue());
    +
    111  current_search_position_ = 0;
    +
    112  current_access_unit_position_ = 0;
    +
    113  current_video_slice_info_.valid = false;
    +
    114  next_access_unit_position_set_ = false;
    +
    115  next_access_unit_position_ = 0;
    +
    116  current_nalu_info_.reset();
    +
    117  timing_desc_list_.clear();
    +
    118  pending_sample_ = std::shared_ptr<MediaSample>();
    +
    119  pending_sample_duration_ = 0;
    +
    120  waiting_for_key_frame_ = true;
    +
    121 }
    +
    122 
    +
    123 bool EsParserH26x::SearchForNalu(uint64_t* position, Nalu* nalu) {
    +
    124  const uint8_t* es;
    +
    125  int es_size;
    +
    126  es_queue_->PeekAt(current_search_position_, &es, &es_size);
    +
    127 
    +
    128  // Find a start code.
    +
    129  uint64_t start_code_offset;
    +
    130  uint8_t start_code_size;
    +
    131  const bool start_code_found = NaluReader::FindStartCode(
    +
    132  es, es_size, &start_code_offset, &start_code_size);
    +
    133 
    +
    134  if (!start_code_found) {
    +
    135  // We didn't find a start code, so we don't have to search this data again.
    +
    136  if (es_size > kStartCodeSize)
    +
    137  current_search_position_ += es_size - kStartCodeSize;
    +
    138  return false;
    +
    139  }
    +
    140 
    +
    141  // Ensure the next NAL unit is a real NAL unit.
    +
    142  const uint8_t* next_nalu_ptr = es + start_code_offset + start_code_size;
    +
    143  // This size is likely inaccurate, this is just to get the header info.
    +
    144  const int64_t next_nalu_size = es_size - start_code_offset - start_code_size;
    +
    145  if (next_nalu_size <
    +
    146  (type_ == Nalu::kH264 ? kH264NaluHeaderSize : kH265NaluHeaderSize)) {
    +
    147  // There was not enough data, wait for more.
    +
    148  return false;
    +
    149  }
    +
    150 
    +
    151  // Update search position for next nalu.
    +
    152  current_search_position_ += start_code_offset + start_code_size;
    +
    153 
    +
    154  // |next_nalu_info_| is made global intentionally to avoid repetitive memory
    +
    155  // allocation which could create memory fragments.
    +
    156  if (!next_nalu_info_)
    +
    157  next_nalu_info_.reset(new NaluInfo);
    +
    158  if (!next_nalu_info_->nalu.Initialize(type_, next_nalu_ptr, next_nalu_size)) {
    +
    159  // This NAL unit is invalid, skip it and search again.
    +
    160  return SearchForNalu(position, nalu);
    +
    161  }
    +
    162  next_nalu_info_->position = current_search_position_ - start_code_size;
    +
    163  next_nalu_info_->start_code_size = start_code_size;
    +
    164 
    +
    165  const bool current_nalu_set = current_nalu_info_ ? true : false;
    +
    166  if (current_nalu_info_) {
    +
    167  // Starting position for the nalu including start code.
    +
    168  *position = current_nalu_info_->position;
    +
    169  // Update the NALU because the data pointer may have been invalidated.
    +
    170  const uint8_t* current_nalu_ptr =
    +
    171  next_nalu_ptr +
    +
    172  (current_nalu_info_->position + current_nalu_info_->start_code_size) -
    +
    173  current_search_position_;
    +
    174  const uint64_t current_nalu_size = next_nalu_info_->position -
    +
    175  current_nalu_info_->position -
    +
    176  current_nalu_info_->start_code_size;
    +
    177  CHECK(nalu->Initialize(type_, current_nalu_ptr, current_nalu_size));
    +
    178  }
    +
    179  current_nalu_info_.swap(next_nalu_info_);
    +
    180  return current_nalu_set ? true : SearchForNalu(position, nalu);
    +
    181 }
    +
    182 
    +
    183 bool EsParserH26x::ParseInternal() {
    +
    184  uint64_t position;
    +
    185  Nalu nalu;
    +
    186  VideoSliceInfo video_slice_info;
    +
    187  while (SearchForNalu(&position, &nalu)) {
    +
    188  // ITU H.264 sec. 7.4.1.2.3
    +
    189  // H264: The first of the NAL units with |can_start_access_unit() == true|
    +
    190  // after the last VCL NAL unit of a primary coded picture specifies the
    +
    191  // start of a new access unit.
    +
    192  // ITU H.265 sec. 7.4.2.4.4
    +
    193  // H265: The first of the NAL units with |can_start_access_unit() == true|
    +
    194  // after the last VCL NAL unit preceding firstBlPicNalUnit (the first
    +
    195  // VCL NAL unit of a coded picture with nuh_layer_id equal to 0), if
    +
    196  // any, specifies the start of a new access unit.
    +
    197  if (nalu.can_start_access_unit()) {
    +
    198  if (!next_access_unit_position_set_) {
    +
    199  next_access_unit_position_set_ = true;
    +
    200  next_access_unit_position_ = position;
    +
    201  }
    +
    202  RCHECK(ProcessNalu(nalu, &video_slice_info));
    +
    203  if (nalu.is_vcl() && !video_slice_info.valid) {
    +
    204  // This could happen only if decoder config is not available yet. Drop
    +
    205  // this frame.
    +
    206  DCHECK(!current_video_slice_info_.valid);
    +
    207  next_access_unit_position_set_ = false;
    +
    208  continue;
    +
    209  }
    +
    210  } else if (nalu.is_vcl()) {
    +
    211  // This isn't the first VCL NAL unit. Next access unit should start after
    +
    212  // this NAL unit.
    +
    213  next_access_unit_position_set_ = false;
    +
    214  continue;
    +
    215  }
    +
    216 
    +
    217  // AUD shall be the first NAL unit if present. There shall be at most one
    +
    218  // AUD in any access unit. We can emit the current access unit which shall
    +
    219  // not contain the AUD.
    +
    220  if (nalu.is_aud()) {
    +
    221  RCHECK(EmitCurrentAccessUnit());
    +
    222  continue;
    +
    223  }
    +
    224 
    +
    225  // We can only determine if the current access unit ends after seeing
    +
    226  // another VCL NAL unit.
    +
    227  if (!video_slice_info.valid)
    +
    228  continue;
    +
    229 
    +
    230  // Check if it is the first VCL NAL unit of a primary coded picture. It is
    +
    231  // always true for H265 as nuh_layer_id shall be == 0 at this point.
    +
    232  bool is_first_vcl_nalu = true;
    +
    233  if (type_ == Nalu::kH264) {
    +
    234  if (current_video_slice_info_.valid) {
    +
    235  // ITU H.264 sec. 7.4.1.2.4 Detection of the first VCL NAL unit of a
    +
    236  // primary coded picture. Only pps_id and frame_num are checked here.
    +
    237  is_first_vcl_nalu =
    +
    238  video_slice_info.frame_num != current_video_slice_info_.frame_num ||
    +
    239  video_slice_info.pps_id != current_video_slice_info_.pps_id;
    +
    240  }
    +
    241  }
    +
    242  if (!is_first_vcl_nalu) {
    +
    243  // This isn't the first VCL NAL unit. Next access unit should start after
    +
    244  // this NAL unit.
    +
    245  next_access_unit_position_set_ = false;
    +
    246  continue;
    +
    247  }
    +
    248 
    +
    249  DCHECK(next_access_unit_position_set_);
    +
    250  RCHECK(EmitCurrentAccessUnit());
    +
    251 
    +
    252  // Delete the data we have already processed.
    +
    253  es_queue_->Trim(next_access_unit_position_);
    +
    254 
    +
    255  current_access_unit_position_ = next_access_unit_position_;
    +
    256  current_video_slice_info_ = video_slice_info;
    +
    257  next_access_unit_position_set_ = false;
    +
    258  }
    +
    259  return true;
    +
    260 }
    +
    261 
    +
    262 bool EsParserH26x::EmitCurrentAccessUnit() {
    +
    263  if (current_video_slice_info_.valid) {
    +
    264  if (current_video_slice_info_.is_key_frame)
    +
    265  waiting_for_key_frame_ = false;
    +
    266  if (!waiting_for_key_frame_) {
    +
    267  RCHECK(
    +
    268  EmitFrame(current_access_unit_position_,
    +
    269  next_access_unit_position_ - current_access_unit_position_,
    +
    270  current_video_slice_info_.is_key_frame,
    +
    271  current_video_slice_info_.pps_id));
    +
    272  }
    +
    273  current_video_slice_info_.valid = false;
    +
    274  }
    +
    275  return true;
    +
    276 }
    +
    277 
    +
    278 bool EsParserH26x::EmitFrame(int64_t access_unit_pos,
    +
    279  int access_unit_size,
    +
    280  bool is_key_frame,
    +
    281  int pps_id) {
    +
    282  // Get the access unit timing info.
    +
    283  TimingDesc current_timing_desc = {kNoTimestamp, kNoTimestamp};
    +
    284  while (!timing_desc_list_.empty() &&
    +
    285  timing_desc_list_.front().first <= access_unit_pos) {
    +
    286  current_timing_desc = timing_desc_list_.front().second;
    +
    287  timing_desc_list_.pop_front();
    +
    288  }
    +
    289  if (current_timing_desc.pts == kNoTimestamp)
    +
    290  return false;
    +
    291 
    +
    292  // Emit a frame.
    +
    293  DVLOG(LOG_LEVEL_ES) << "Emit frame: stream_pos=" << access_unit_pos
    +
    294  << " size=" << access_unit_size << " pts "
    +
    295  << current_timing_desc.pts << " timing_desc_list size "
    +
    296  << timing_desc_list_.size();
    +
    297  int es_size;
    +
    298  const uint8_t* es;
    +
    299  es_queue_->PeekAt(access_unit_pos, &es, &es_size);
    +
    300 
    +
    301  // Convert frame to unit stream format.
    +
    302  std::vector<uint8_t> converted_frame;
    +
    303  if (!stream_converter_->ConvertByteStreamToNalUnitStream(
    +
    304  es, access_unit_size, &converted_frame)) {
    +
    305  DLOG(ERROR) << "Failure to convert video frame to unit stream format.";
    +
    306  return false;
    +
    307  }
    +
    308 
    +
    309  // Update the video decoder configuration if needed.
    +
    310  RCHECK(UpdateVideoDecoderConfig(pps_id));
    +
    311 
    +
    312  // Create the media sample, emitting always the previous sample after
    +
    313  // calculating its duration.
    +
    314  std::shared_ptr<MediaSample> media_sample = MediaSample::CopyFrom(
    +
    315  converted_frame.data(), converted_frame.size(), is_key_frame);
    +
    316  media_sample->set_dts(current_timing_desc.dts);
    +
    317  media_sample->set_pts(current_timing_desc.pts);
    +
    318  if (pending_sample_) {
    +
    319  if (media_sample->dts() <= pending_sample_->dts()) {
    +
    320  LOG(WARNING) << "[MPEG-2 TS] PID " << pid() << " dts "
    +
    321  << media_sample->dts()
    +
    322  << " less than or equal to previous dts "
    +
    323  << pending_sample_->dts();
    +
    324  // Keep the sample but adjust the sample duration to a very small value,
    +
    325  // in case that the sample is still needed for the decoding afterwards.
    +
    326  const int64_t kArbitrarySmallDuration = 0.001 * kMpeg2Timescale; // 1ms.
    +
    327  pending_sample_->set_duration(kArbitrarySmallDuration);
    +
    328  } else {
    +
    329  uint64_t sample_duration = media_sample->dts() - pending_sample_->dts();
    +
    330  pending_sample_->set_duration(sample_duration);
    +
    331 
    +
    332  const int kArbitraryGapScale = 10;
    +
    333  if (sample_duration > kArbitraryGapScale * pending_sample_duration_) {
    +
    334  LOG(WARNING) << "[MPEG-2 TS] PID " << pid() << " Possible GAP at dts "
    +
    335  << pending_sample_->dts() << " with next sample at dts "
    +
    336  << media_sample->dts() << " (difference "
    +
    337  << sample_duration << ")";
    +
    338  }
    +
    339 
    +
    340  pending_sample_duration_ = sample_duration;
    +
    341  }
    +
    342  emit_sample_cb_.Run(std::move(pending_sample_));
    +
    343  }
    +
    344  pending_sample_ = media_sample;
    +
    345 
    +
    346  return true;
    +
    347 }
    +
    348 
    +
    349 } // namespace mp2t
    +
    350 } // namespace media
    +
    351 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/dad/classshaka_1_1MemoryFile.html b/docs/de/dad/classshaka_1_1MemoryFile.html index a31207fb19..02ecdf825d 100644 --- a/docs/de/dad/classshaka_1_1MemoryFile.html +++ b/docs/de/dad/classshaka_1_1MemoryFile.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MemoryFile Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    -shaka::File - -
    +shaka::File + + @@ -155,7 +158,7 @@ bool 

    Public Member Functions

     

    Detailed Description

    -

    Implements a File that is stored in memory. This should be only used for testing, since this does not support larger files.

    +

    Implements a File that is stored in memory. This should be only used for testing, since this does not support larger files.

    Definition at line 21 of file memory_file.h.

    Member Function Documentation

    @@ -181,7 +184,7 @@ bool  -

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.
    +

    Flush() and de-allocate resources associated with this file, and delete this File object. THIS IS THE ONE TRUE WAY TO DEALLOCATE THIS OBJECT.

    Returns
    true on success. For writable files, returning false MAY INDICATE DATA LOSS.

    Implements shaka::File.

    @@ -268,7 +271,7 @@ bool  -

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.
    +

    Flush the file so that recently written data will survive an application crash (but not necessarily an OS crash). For instance, in LocalFile the data is flushed into the OS but not necessarily to disk.

    Returns
    true on success, false otherwise.

    Implements shaka::File.

    @@ -483,9 +486,7 @@ bool  diff --git a/docs/de/dad/validate__flag_8cc_source.html b/docs/de/dad/validate__flag_8cc_source.html index 7414e1d42c..827ac717fe 100644 --- a/docs/de/dad/validate__flag_8cc_source.html +++ b/docs/de/dad/validate__flag_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/validate_flag.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    validate_flag.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Flag validation help functions.
    8 
    9 #include "packager/app/validate_flag.h"
    10 
    11 #include <stdio.h>
    12 
    13 namespace shaka {
    14 
    15 void PrintError(const std::string& error_message) {
    16  fprintf(stderr, "ERROR: %s\n", error_message.c_str());
    17 }
    18 
    19 void PrintWarning(const std::string& warning_message) {
    20  fprintf(stderr, "WARNING: %s\n", warning_message.c_str());
    21 }
    22 
    23 } // namespace shaka
    void PrintError(const std::string &error_message)
    -
    All the methods that are virtual are virtual for mocking.
    -
    void PrintWarning(const std::string &warning_message)
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Flag validation help functions.
    +
    8 
    +
    9 #include "packager/app/validate_flag.h"
    +
    10 
    +
    11 #include <stdio.h>
    +
    12 
    +
    13 namespace shaka {
    +
    14 
    +
    15 void PrintError(const std::string& error_message) {
    +
    16  fprintf(stderr, "ERROR: %s\n", error_message.c_str());
    +
    17 }
    +
    18 
    +
    19 void PrintWarning(const std::string& warning_message) {
    +
    20  fprintf(stderr, "WARNING: %s\n", warning_message.c_str());
    +
    21 }
    +
    22 
    +
    23 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    void PrintWarning(const std::string &warning_message)
    +
    void PrintError(const std::string &error_message)
    diff --git a/docs/de/db2/classshaka_1_1media_1_1MockOutputMediaHandler.html b/docs/de/db2/classshaka_1_1media_1_1MockOutputMediaHandler.html index d3e191205f..9231dda756 100644 --- a/docs/de/db2/classshaka_1_1media_1_1MockOutputMediaHandler.html +++ b/docs/de/db2/classshaka_1_1media_1_1MockOutputMediaHandler.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MockOutputMediaHandler Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::MediaHandler - -
    + + @@ -106,9 +109,9 @@ bool  - - + + @@ -163,7 +166,7 @@ const std::map< size_t, std::pair< std::shared_ptr<

    Detailed Description

    -

    Definition at line 262 of file media_handler_test_base.h.

    +

    Definition at line 258 of file media_handler_test_base.h.


    The documentation for this class was generated from the following files:
    • packager/media/base/media_handler_test_base.h
    • packager/media/base/media_handler_test_base.cc
    • @@ -171,9 +174,7 @@ const std::map< size_t, std::pair< std::shared_ptr< diff --git a/docs/de/db3/classshaka_1_1media_1_1TextTrackConfig.html b/docs/de/db3/classshaka_1_1media_1_1TextTrackConfig.html index 31dfde9a96..bd37ef603c 100644 --- a/docs/de/db3/classshaka_1_1media_1_1TextTrackConfig.html +++ b/docs/de/db3/classshaka_1_1media_1_1TextTrackConfig.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::TextTrackConfig Class Reference @@ -29,18 +29,21 @@

    Public Member Functions

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     
    - Protected Member Functions inherited from shaka::media::MediaHandler
    virtual bool ValidateOutputStreamIndex (size_t stream_index) const
    - + +/* @license-end */
    id
    diff --git a/docs/de/db4/classshaka_1_1media_1_1H26xBitReader.html b/docs/de/db4/classshaka_1_1media_1_1H26xBitReader.html index 0eead1bda7..e1d9b66925 100644 --- a/docs/de/db4/classshaka_1_1media_1_1H26xBitReader.html +++ b/docs/de/db4/classshaka_1_1media_1_1H26xBitReader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H26xBitReader Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    NumEmulationPrevent
    diff --git a/docs/de/db5/structshaka_1_1media_1_1MuxerListenerFactory_1_1StreamData.html b/docs/de/db5/structshaka_1_1media_1_1MuxerListenerFactory_1_1StreamData.html index 983bbcbe4c..155a53e9c2 100644 --- a/docs/de/db5/structshaka_1_1media_1_1MuxerListenerFactory_1_1StreamData.html +++ b/docs/de/db5/structshaka_1_1media_1_1MuxerListenerFactory_1_1StreamData.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MuxerListenerFactory::StreamData Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    hls_iframe_pla std::vector< std::string > hls_characteristics   + +bool hls_only = false +  std::vector< std::string > dash_accessiblities   std::vector< std::string > dash_roles   + +bool dash_only = false + 

    Detailed Description

    The subset of data from a stream descriptor that the muxer listener factory needs in order to create listeners for the stream.

    @@ -109,9 +118,7 @@ std::vector< std::string >  diff --git a/docs/de/dbb/classshaka_1_1media_1_1MuxerListenerFactory.html b/docs/de/dbb/classshaka_1_1media_1_1MuxerListenerFactory.html index 5e92e4d252..074c3c5771 100644 --- a/docs/de/dbb/classshaka_1_1media_1_1MuxerListenerFactory.html +++ b/docs/de/dbb/classshaka_1_1media_1_1MuxerListenerFactory.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::MuxerListenerFactory Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    Definition at line 79 of file muxer_listener_factory.cc.

    +

    Definition at line 82 of file muxer_listener_factory.cc.

    @@ -161,7 +164,7 @@ std::unique_ptr<

    Create an HLS listener if possible. If it is not possible to create an HLS listener, this method will return null.

    -

    Definition at line 111 of file muxer_listener_factory.cc.

    +

    Definition at line 127 of file muxer_listener_factory.cc.

    @@ -172,9 +175,7 @@ std::unique_ptr< diff --git a/docs/de/dbd/structshaka_1_1media_1_1mp4_1_1NullMediaHeader-members.html b/docs/de/dbd/structshaka_1_1media_1_1mp4_1_1NullMediaHeader-members.html new file mode 100644 index 0000000000..6bd4ec23cc --- /dev/null +++ b/docs/de/dbd/structshaka_1_1media_1_1mp4_1_1NullMediaHeader-members.html @@ -0,0 +1,97 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::media::mp4::NullMediaHeader Member List
    +
    + + + + + diff --git a/docs/de/dbf/udp__options_8h_source.html b/docs/de/dbf/udp__options_8h_source.html index 5819c88587..e0a667803e 100644 --- a/docs/de/dbf/udp__options_8h_source.html +++ b/docs/de/dbf/udp__options_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/udp_options.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    udp_options.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include <memory>
    8 #include <string>
    9 
    10 #include "packager/base/strings/string_piece.h"
    11 
    12 namespace shaka {
    13 
    15 class UdpOptions {
    16  public:
    17  ~UdpOptions() = default;
    18 
    22  static std::unique_ptr<UdpOptions> ParseFromString(base::StringPiece udp_url);
    23 
    24  const std::string& address() const { return address_; }
    25  uint16_t port() const { return port_; }
    26  bool reuse() const { return reuse_; }
    27  const std::string& interface_address() const { return interface_address_; }
    28  unsigned timeout_us() const { return timeout_us_; }
    29  const std::string& source_address() const { return source_address_; }
    30  bool is_source_specific_multicast() const {
    31  return is_source_specific_multicast_;
    32  }
    33  int buffer_size() const { return buffer_size_; }
    34 
    35  private:
    36  UdpOptions() = default;
    37 
    38  // IP Address.
    39  std::string address_ = "0.0.0.0";
    40  uint16_t port_ = 0;
    41  // Allow or disallow reusing UDP sockets.
    42  bool reuse_ = false;
    43  // Address of the interface over which to receive UDP multicast streams.
    44  std::string interface_address_ = "0.0.0.0";
    45  // Timeout in microseconds. 0 to indicate unlimited timeout.
    46  unsigned timeout_us_ = 0;
    47  // Source specific multicast source address
    48  std::string source_address_ = "0.0.0.0";
    49  bool is_source_specific_multicast_ = false;
    50  // Maximum receive buffer size in bytes.
    51  // Note that the actual buffer size is capped by the maximum buffer size set
    52  // by the underlying operating system ('sysctl net.core.rmem_max' on Linux
    53  // returns the maximum receive memory size).
    54  int buffer_size_ = 0;
    55 };
    56 
    57 } // namespace shaka
    static std::unique_ptr< UdpOptions > ParseFromString(base::StringPiece udp_url)
    Definition: udp_options.cc:75
    -
    All the methods that are virtual are virtual for mocking.
    -
    Options parsed from UDP url string of the form: udp://ip:port[?options].
    Definition: udp_options.h:15
    +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include <memory>
    +
    8 #include <string>
    +
    9 
    +
    10 #include "packager/base/strings/string_piece.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 
    +
    15 class UdpOptions {
    +
    16  public:
    +
    17  ~UdpOptions() = default;
    +
    18 
    +
    22  static std::unique_ptr<UdpOptions> ParseFromString(base::StringPiece udp_url);
    +
    23 
    +
    24  const std::string& address() const { return address_; }
    +
    25  uint16_t port() const { return port_; }
    +
    26  bool reuse() const { return reuse_; }
    +
    27  const std::string& interface_address() const { return interface_address_; }
    +
    28  unsigned timeout_us() const { return timeout_us_; }
    +
    29  const std::string& source_address() const { return source_address_; }
    +
    30  bool is_source_specific_multicast() const {
    +
    31  return is_source_specific_multicast_;
    +
    32  }
    +
    33  int buffer_size() const { return buffer_size_; }
    +
    34 
    +
    35  private:
    +
    36  UdpOptions() = default;
    +
    37 
    +
    38  // IP Address.
    +
    39  std::string address_ = "0.0.0.0";
    +
    40  uint16_t port_ = 0;
    +
    41  // Allow or disallow reusing UDP sockets.
    +
    42  bool reuse_ = false;
    +
    43  // Address of the interface over which to receive UDP multicast streams.
    +
    44  std::string interface_address_ = "0.0.0.0";
    +
    45  // Timeout in microseconds. 0 to indicate unlimited timeout.
    +
    46  unsigned timeout_us_ = 0;
    +
    47  // Source specific multicast source address
    +
    48  std::string source_address_ = "0.0.0.0";
    +
    49  bool is_source_specific_multicast_ = false;
    +
    50  // Maximum receive buffer size in bytes.
    +
    51  // Note that the actual buffer size is capped by the maximum buffer size set
    +
    52  // by the underlying operating system ('sysctl net.core.rmem_max' on Linux
    +
    53  // returns the maximum receive memory size).
    +
    54  int buffer_size_ = 0;
    +
    55 };
    +
    56 
    +
    57 } // namespace shaka
    +
    Options parsed from UDP url string of the form: udp://ip:port[?options].
    Definition: udp_options.h:15
    +
    static std::unique_ptr< UdpOptions > ParseFromString(base::StringPiece udp_url)
    Definition: udp_options.cc:75
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/dc1/demuxer_8h_source.html b/docs/de/dc1/demuxer_8h_source.html index 1da4c2ba7c..44778a4bf9 100644 --- a/docs/de/dc1/demuxer_8h_source.html +++ b/docs/de/dc1/demuxer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/demuxer/demuxer.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    demuxer.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_DEMUXER_H_
    8 #define PACKAGER_MEDIA_BASE_DEMUXER_H_
    9 
    10 #include <deque>
    11 #include <memory>
    12 #include <vector>
    13 
    14 #include "packager/base/compiler_specific.h"
    15 #include "packager/media/base/container_names.h"
    16 #include "packager/media/origin/origin_handler.h"
    17 #include "packager/status.h"
    18 
    19 namespace shaka {
    20 
    21 class File;
    22 
    23 namespace media {
    24 
    25 class Decryptor;
    26 class KeySource;
    27 class MediaParser;
    28 class MediaSample;
    29 class StreamInfo;
    30 
    33 class Demuxer : public OriginHandler {
    34  public:
    38  explicit Demuxer(const std::string& file_name);
    39  ~Demuxer();
    40 
    45  void SetKeySource(std::unique_ptr<KeySource> key_source);
    46 
    49  Status Run() override;
    50 
    53  void Cancel() override;
    54 
    57  MediaContainerName container_name() { return container_name_; }
    58 
    63  Status SetHandler(const std::string& stream_label,
    64  std::shared_ptr<MediaHandler> handler);
    65 
    71  void SetLanguageOverride(const std::string& stream_label,
    72  const std::string& language_override);
    73 
    74  void set_dump_stream_info(bool dump_stream_info) {
    75  dump_stream_info_ = dump_stream_info;
    76  }
    77 
    78  protected:
    81  Status InitializeInternal() override { return Status::OK; }
    82  Status Process(std::unique_ptr<StreamData> stream_data) override {
    83  return Status(error::INTERNAL_ERROR,
    84  "Demuxer should not be the downstream handler.");
    85  }
    86  bool ValidateOutputStreamIndex(size_t stream_index) const override {
    87  // We don't know if the stream is valid or not when setting up the graph.
    88  // Will validate the stream index later when stream info is available.
    89  return true;
    90  }
    92 
    93  private:
    94  Demuxer(const Demuxer&) = delete;
    95  Demuxer& operator=(const Demuxer&) = delete;
    96 
    97  struct QueuedSample {
    98  QueuedSample(uint32_t track_id, std::shared_ptr<MediaSample> sample);
    99  ~QueuedSample();
    100 
    101  uint32_t track_id;
    102  std::shared_ptr<MediaSample> sample;
    103  };
    104 
    105  // Initialize the parser. This method primes the demuxer by parsing portions
    106  // of the media file to extract stream information.
    107  // @return OK on success.
    108  Status InitializeParser();
    109 
    110  // Parser init event.
    111  void ParserInitEvent(const std::vector<std::shared_ptr<StreamInfo>>& streams);
    112  // Parser new sample event handler. Queues the samples if init event has not
    113  // been received, otherwise calls PushSample() to push the sample to
    114  // corresponding stream.
    115  bool NewSampleEvent(uint32_t track_id,
    116  const std::shared_ptr<MediaSample>& sample);
    117  // Helper function to push the sample to corresponding stream.
    118  bool PushSample(uint32_t track_id,
    119  const std::shared_ptr<MediaSample>& sample);
    120 
    121  // Read from the source and send it to the parser.
    122  Status Parse();
    123 
    124  std::string file_name_;
    125  File* media_file_ = nullptr;
    126  // A stream is considered ready after receiving the stream info.
    127  bool all_streams_ready_ = false;
    128  // Queued samples received in NewSampleEvent() before ParserInitEvent().
    129  std::deque<QueuedSample> queued_samples_;
    130  std::unique_ptr<MediaParser> parser_;
    131  // TrackId -> StreamIndex map.
    132  std::map<uint32_t, size_t> track_id_to_stream_index_map_;
    133  // The list of stream indexes in the above map (in the same order as the input
    134  // stream info vector).
    135  std::vector<size_t> stream_indexes_;
    136  // StreamIndex -> language_override map.
    137  std::map<size_t, std::string> language_overrides_;
    138  MediaContainerName container_name_ = CONTAINER_UNKNOWN;
    139  std::unique_ptr<uint8_t[]> buffer_;
    140  std::unique_ptr<KeySource> key_source_;
    141  bool cancelled_ = false;
    142  // Whether to dump stream info when it is received.
    143  bool dump_stream_info_ = false;
    144  Status init_event_status_;
    145 };
    146 
    147 } // namespace media
    148 } // namespace shaka
    149 
    150 #endif // PACKAGER_MEDIA_BASE_DEMUXER_H_
    MediaContainerName container_name()
    Definition: demuxer.h:57
    -
    Status SetHandler(const std::string &stream_label, std::shared_ptr< MediaHandler > handler)
    Definition: demuxer.cc:132
    - -
    bool ValidateOutputStreamIndex(size_t stream_index) const override
    Validate if the stream at the specified index actually exists.
    Definition: demuxer.h:86
    -
    Status Run() override
    Definition: demuxer.cc:87
    -
    Define an abstract file interface.
    Definition: file.h:26
    -
    void SetLanguageOverride(const std::string &stream_label, const std::string &language_override)
    Definition: demuxer.cc:142
    -
    All the methods that are virtual are virtual for mocking.
    - -
    void SetKeySource(std::unique_ptr< KeySource > key_source)
    Definition: demuxer.cc:83
    - -
    Status InitializeInternal() override
    Definition: demuxer.h:81
    -
    Status Process(std::unique_ptr< StreamData > stream_data) override
    Definition: demuxer.h:82
    -
    Demuxer(const std::string &file_name)
    Definition: demuxer.cc:75
    -
    void Cancel() override
    Definition: demuxer.cc:128
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_DEMUXER_H_
    +
    8 #define PACKAGER_MEDIA_BASE_DEMUXER_H_
    +
    9 
    +
    10 #include <deque>
    +
    11 #include <memory>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/compiler_specific.h"
    +
    15 #include "packager/media/base/container_names.h"
    +
    16 #include "packager/media/origin/origin_handler.h"
    +
    17 #include "packager/status.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 
    +
    21 class File;
    +
    22 
    +
    23 namespace media {
    +
    24 
    +
    25 class Decryptor;
    +
    26 class KeySource;
    +
    27 class MediaParser;
    +
    28 class MediaSample;
    +
    29 class StreamInfo;
    +
    30 
    +
    33 class Demuxer : public OriginHandler {
    +
    34  public:
    +
    38  explicit Demuxer(const std::string& file_name);
    +
    39  ~Demuxer();
    +
    40 
    +
    45  void SetKeySource(std::unique_ptr<KeySource> key_source);
    +
    46 
    +
    49  Status Run() override;
    +
    50 
    +
    53  void Cancel() override;
    +
    54 
    +
    57  MediaContainerName container_name() { return container_name_; }
    +
    58 
    +
    63  Status SetHandler(const std::string& stream_label,
    +
    64  std::shared_ptr<MediaHandler> handler);
    +
    65 
    +
    71  void SetLanguageOverride(const std::string& stream_label,
    +
    72  const std::string& language_override);
    +
    73 
    +
    74  void set_dump_stream_info(bool dump_stream_info) {
    +
    75  dump_stream_info_ = dump_stream_info;
    +
    76  }
    +
    77 
    +
    78  protected:
    +
    81  Status InitializeInternal() override { return Status::OK; }
    +
    82  Status Process(std::unique_ptr<StreamData> stream_data) override {
    +
    83  return Status(error::INTERNAL_ERROR,
    +
    84  "Demuxer should not be the downstream handler.");
    +
    85  }
    +
    86  bool ValidateOutputStreamIndex(size_t stream_index) const override {
    +
    87  // We don't know if the stream is valid or not when setting up the graph.
    +
    88  // Will validate the stream index later when stream info is available.
    +
    89  return true;
    +
    90  }
    +
    92 
    +
    93  private:
    +
    94  Demuxer(const Demuxer&) = delete;
    +
    95  Demuxer& operator=(const Demuxer&) = delete;
    +
    96 
    +
    97  template <typename T>
    +
    98  struct QueuedSample {
    +
    99  QueuedSample(uint32_t track_id, std::shared_ptr<T> sample)
    +
    100  : track_id(track_id), sample(sample) {}
    +
    101 
    +
    102  ~QueuedSample() {}
    +
    103 
    +
    104  uint32_t track_id;
    +
    105  std::shared_ptr<T> sample;
    +
    106  };
    +
    107 
    +
    108  // Initialize the parser. This method primes the demuxer by parsing portions
    +
    109  // of the media file to extract stream information.
    +
    110  // @return OK on success.
    +
    111  Status InitializeParser();
    +
    112 
    +
    113  // Parser init event.
    +
    114  void ParserInitEvent(const std::vector<std::shared_ptr<StreamInfo>>& streams);
    +
    115  // Parser new sample event handler. Queues the samples if init event has not
    +
    116  // been received, otherwise calls PushSample() to push the sample to
    +
    117  // corresponding stream.
    +
    118  bool NewMediaSampleEvent(uint32_t track_id,
    +
    119  std::shared_ptr<MediaSample> sample);
    +
    120  bool NewTextSampleEvent(uint32_t track_id,
    +
    121  std::shared_ptr<TextSample> sample);
    +
    122  // Helper function to push the sample to corresponding stream.
    +
    123  bool PushMediaSample(uint32_t track_id, std::shared_ptr<MediaSample> sample);
    +
    124  bool PushTextSample(uint32_t track_id, std::shared_ptr<TextSample> sample);
    +
    125 
    +
    126  // Read from the source and send it to the parser.
    +
    127  Status Parse();
    +
    128 
    +
    129  std::string file_name_;
    +
    130  File* media_file_ = nullptr;
    +
    131  // A stream is considered ready after receiving the stream info.
    +
    132  bool all_streams_ready_ = false;
    +
    133  // Queued samples received in NewSampleEvent() before ParserInitEvent().
    +
    134  std::deque<QueuedSample<MediaSample>> queued_media_samples_;
    +
    135  std::deque<QueuedSample<TextSample>> queued_text_samples_;
    +
    136  std::unique_ptr<MediaParser> parser_;
    +
    137  // TrackId -> StreamIndex map.
    +
    138  std::map<uint32_t, size_t> track_id_to_stream_index_map_;
    +
    139  // The list of stream indexes in the above map (in the same order as the input
    +
    140  // stream info vector).
    +
    141  std::vector<size_t> stream_indexes_;
    +
    142  // StreamIndex -> language_override map.
    +
    143  std::map<size_t, std::string> language_overrides_;
    +
    144  MediaContainerName container_name_ = CONTAINER_UNKNOWN;
    +
    145  std::unique_ptr<uint8_t[]> buffer_;
    +
    146  std::unique_ptr<KeySource> key_source_;
    +
    147  bool cancelled_ = false;
    +
    148  // Whether to dump stream info when it is received.
    +
    149  bool dump_stream_info_ = false;
    +
    150  Status init_event_status_;
    +
    151 };
    +
    152 
    +
    153 } // namespace media
    +
    154 } // namespace shaka
    +
    155 
    +
    156 #endif // PACKAGER_MEDIA_BASE_DEMUXER_H_
    + + +
    Status Run() override
    Definition: demuxer.cc:88
    +
    Status SetHandler(const std::string &stream_label, std::shared_ptr< MediaHandler > handler)
    Definition: demuxer.cc:133
    +
    MediaContainerName container_name()
    Definition: demuxer.h:57
    +
    void Cancel() override
    Definition: demuxer.cc:129
    +
    Status InitializeInternal() override
    Definition: demuxer.h:81
    +
    Status Process(std::unique_ptr< StreamData > stream_data) override
    Definition: demuxer.h:82
    +
    bool ValidateOutputStreamIndex(size_t stream_index) const override
    Validate if the stream at the specified index actually exists.
    Definition: demuxer.h:86
    +
    void SetLanguageOverride(const std::string &stream_label, const std::string &language_override)
    Definition: demuxer.cc:143
    +
    void SetKeySource(std::unique_ptr< KeySource > key_source)
    Definition: demuxer.cc:84
    +
    Demuxer(const std::string &file_name)
    Definition: demuxer.cc:76
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/dc2/adaptation__set_8cc_source.html b/docs/de/dc2/adaptation__set_8cc_source.html index 4c4ead8733..3743d7668a 100644 --- a/docs/de/dc2/adaptation__set_8cc_source.html +++ b/docs/de/dc2/adaptation__set_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/adaptation_set.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    adaptation_set.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/mpd/base/adaptation_set.h"
    8 
    9 #include <cmath>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/base/strings/string_number_conversions.h"
    13 #include "packager/mpd/base/media_info.pb.h"
    14 #include "packager/mpd/base/mpd_options.h"
    15 #include "packager/mpd/base/mpd_utils.h"
    16 #include "packager/mpd/base/representation.h"
    17 #include "packager/mpd/base/xml/xml_node.h"
    18 
    19 namespace shaka {
    20 namespace {
    21 
    22 AdaptationSet::Role MediaInfoTextTypeToRole(
    23  MediaInfo::TextInfo::TextType type) {
    24  switch (type) {
    25  case MediaInfo::TextInfo::UNKNOWN:
    26  LOG(WARNING) << "Unknown text type, assuming subtitle.";
    27  return AdaptationSet::kRoleSubtitle;
    28  case MediaInfo::TextInfo::CAPTION:
    29  return AdaptationSet::kRoleCaption;
    30  case MediaInfo::TextInfo::SUBTITLE:
    31  return AdaptationSet::kRoleSubtitle;
    32  default:
    33  NOTREACHED() << "Unknown MediaInfo TextType: " << type
    34  << " assuming subtitle.";
    35  return AdaptationSet::kRoleSubtitle;
    36  }
    37 }
    38 
    39 std::string RoleToText(AdaptationSet::Role role) {
    40  // Using switch so that the compiler can detect whether there is a case that's
    41  // not being handled.
    42  switch (role) {
    43  case AdaptationSet::kRoleCaption:
    44  return "caption";
    45  case AdaptationSet::kRoleSubtitle:
    46  return "subtitle";
    47  case AdaptationSet::kRoleMain:
    48  return "main";
    49  case AdaptationSet::kRoleAlternate:
    50  return "alternate";
    51  case AdaptationSet::kRoleSupplementary:
    52  return "supplementary";
    53  case AdaptationSet::kRoleCommentary:
    54  return "commentary";
    55  case AdaptationSet::kRoleDub:
    56  return "dub";
    57  default:
    58  return "unknown";
    59  }
    60 }
    61 
    62 // Returns the picture aspect ratio string e.g. "16:9", "4:3".
    63 // "Reducing the quotient to minimal form" does not work well in practice as
    64 // there may be some rounding performed in the input, e.g. the resolution of
    65 // 480p is 854:480 for 16:9 aspect ratio, can only be reduced to 427:240.
    66 // The algorithm finds out the pair of integers, num and den, where num / den is
    67 // the closest ratio to scaled_width / scaled_height, by looping den through
    68 // common values.
    69 std::string GetPictureAspectRatio(uint32_t width,
    70  uint32_t height,
    71  uint32_t pixel_width,
    72  uint32_t pixel_height) {
    73  const uint32_t scaled_width = pixel_width * width;
    74  const uint32_t scaled_height = pixel_height * height;
    75  const double par = static_cast<double>(scaled_width) / scaled_height;
    76 
    77  // Typical aspect ratios have par_y less than or equal to 19:
    78  // https://en.wikipedia.org/wiki/List_of_common_resolutions
    79  const uint32_t kLargestPossibleParY = 19;
    80 
    81  uint32_t par_num = 0;
    82  uint32_t par_den = 0;
    83  double min_error = 1.0;
    84  for (uint32_t den = 1; den <= kLargestPossibleParY; ++den) {
    85  uint32_t num = par * den + 0.5;
    86  double error = fabs(par - static_cast<double>(num) / den);
    87  if (error < min_error) {
    88  min_error = error;
    89  par_num = num;
    90  par_den = den;
    91  if (error == 0)
    92  break;
    93  }
    94  }
    95  VLOG(2) << "width*pix_width : height*pixel_height (" << scaled_width << ":"
    96  << scaled_height << ") reduced to " << par_num << ":" << par_den
    97  << " with error " << min_error << ".";
    98 
    99  return base::IntToString(par_num) + ":" + base::IntToString(par_den);
    100 }
    101 
    102 // Adds an entry to picture_aspect_ratio if the size of picture_aspect_ratio is
    103 // less than 2 and video_info has both pixel width and pixel height.
    104 void AddPictureAspectRatio(const MediaInfo::VideoInfo& video_info,
    105  std::set<std::string>* picture_aspect_ratio) {
    106  // If there are more than one entries in picture_aspect_ratio, the @par
    107  // attribute cannot be set, so skip.
    108  if (picture_aspect_ratio->size() > 1)
    109  return;
    110 
    111  if (video_info.width() == 0 || video_info.height() == 0 ||
    112  video_info.pixel_width() == 0 || video_info.pixel_height() == 0) {
    113  // If there is even one Representation without a @sar attribute, @par cannot
    114  // be calculated.
    115  // Just populate the set with at least 2 bogus strings so that further call
    116  // to this function will bail out immediately.
    117  picture_aspect_ratio->insert("bogus");
    118  picture_aspect_ratio->insert("entries");
    119  return;
    120  }
    121 
    122  const std::string par = GetPictureAspectRatio(
    123  video_info.width(), video_info.height(), video_info.pixel_width(),
    124  video_info.pixel_height());
    125  DVLOG(1) << "Setting par as: " << par
    126  << " for video with width: " << video_info.width()
    127  << " height: " << video_info.height()
    128  << " pixel_width: " << video_info.pixel_width() << " pixel_height; "
    129  << video_info.pixel_height();
    130  picture_aspect_ratio->insert(par);
    131 }
    132 
    133 class RepresentationStateChangeListenerImpl
    134  : public RepresentationStateChangeListener {
    135  public:
    136  // |adaptation_set| is not owned by this class.
    137  RepresentationStateChangeListenerImpl(uint32_t representation_id,
    138  AdaptationSet* adaptation_set)
    139  : representation_id_(representation_id), adaptation_set_(adaptation_set) {
    140  DCHECK(adaptation_set_);
    141  }
    142  ~RepresentationStateChangeListenerImpl() override {}
    143 
    144  // RepresentationStateChangeListener implementation.
    145  void OnNewSegmentForRepresentation(int64_t start_time,
    146  int64_t duration) override {
    147  adaptation_set_->OnNewSegmentForRepresentation(representation_id_,
    148  start_time, duration);
    149  }
    150 
    151  void OnSetFrameRateForRepresentation(uint32_t frame_duration,
    152  uint32_t timescale) override {
    153  adaptation_set_->OnSetFrameRateForRepresentation(representation_id_,
    154  frame_duration, timescale);
    155  }
    156 
    157  private:
    158  const uint32_t representation_id_;
    159  AdaptationSet* const adaptation_set_;
    160 
    161  DISALLOW_COPY_AND_ASSIGN(RepresentationStateChangeListenerImpl);
    162 };
    163 
    164 } // namespace
    165 
    166 AdaptationSet::AdaptationSet(const std::string& language,
    167  const MpdOptions& mpd_options,
    168  uint32_t* counter)
    169  : representation_counter_(counter),
    170  language_(language),
    171  mpd_options_(mpd_options),
    172  segments_aligned_(kSegmentAlignmentUnknown),
    173  force_set_segment_alignment_(false) {
    174  DCHECK(counter);
    175 }
    176 
    177 AdaptationSet::~AdaptationSet() {}
    178 
    179 Representation* AdaptationSet::AddRepresentation(const MediaInfo& media_info) {
    180  const uint32_t representation_id = (*representation_counter_)++;
    181  // Note that AdaptationSet outlive Representation, so this object
    182  // will die before AdaptationSet.
    183  std::unique_ptr<RepresentationStateChangeListener> listener(
    184  new RepresentationStateChangeListenerImpl(representation_id, this));
    185  std::unique_ptr<Representation> new_representation(new Representation(
    186  media_info, mpd_options_, representation_id, std::move(listener)));
    187 
    188  if (!new_representation->Init()) {
    189  LOG(ERROR) << "Failed to initialize Representation.";
    190  return NULL;
    191  }
    192  UpdateFromMediaInfo(media_info);
    193  Representation* representation_ptr = new_representation.get();
    194  representation_map_[representation_ptr->id()] = std::move(new_representation);
    195  return representation_ptr;
    196 }
    197 
    199  const Representation& representation) {
    200  // Note that AdaptationSet outlive Representation, so this object
    201  // will die before AdaptationSet.
    202  std::unique_ptr<RepresentationStateChangeListener> listener(
    203  new RepresentationStateChangeListenerImpl(representation.id(), this));
    204  std::unique_ptr<Representation> new_representation(
    205  new Representation(representation, std::move(listener)));
    206 
    207  UpdateFromMediaInfo(new_representation->GetMediaInfo());
    208  Representation* representation_ptr = new_representation.get();
    209  representation_map_[representation_ptr->id()] = std::move(new_representation);
    210  return representation_ptr;
    211 }
    212 
    214  const ContentProtectionElement& content_protection_element) {
    215  content_protection_elements_.push_back(content_protection_element);
    216  RemoveDuplicateAttributes(&content_protection_elements_.back());
    217 }
    218 
    219 void AdaptationSet::UpdateContentProtectionPssh(const std::string& drm_uuid,
    220  const std::string& pssh) {
    221  UpdateContentProtectionPsshHelper(drm_uuid, pssh,
    222  &content_protection_elements_);
    223 }
    224 
    225 void AdaptationSet::AddAccessibility(const std::string& scheme,
    226  const std::string& value) {
    227  accessibilities_.push_back(Accessibility{scheme, value});
    228 }
    229 
    230 void AdaptationSet::AddRole(Role role) {
    231  roles_.insert(role);
    232 }
    233 
    234 // Creates a copy of <AdaptationSet> xml element, iterate thru all the
    235 // <Representation> (child) elements and add them to the copy.
    236 // Set all the attributes first and then add the children elements so that flags
    237 // can be passed to Representation to avoid setting redundant attributes. For
    238 // example, if AdaptationSet@width is set, then Representation@width is
    239 // redundant and should not be set.
    240 xml::scoped_xml_ptr<xmlNode> AdaptationSet::GetXml() {
    241  xml::AdaptationSetXmlNode adaptation_set;
    242 
    243  bool suppress_representation_width = false;
    244  bool suppress_representation_height = false;
    245  bool suppress_representation_frame_rate = false;
    246 
    247  if (id_)
    248  adaptation_set.SetId(id_.value());
    249  adaptation_set.SetStringAttribute("contentType", content_type_);
    250  if (!language_.empty() && language_ != "und") {
    251  adaptation_set.SetStringAttribute("lang", language_);
    252  }
    253 
    254  // Note that std::{set,map} are ordered, so the last element is the max value.
    255  if (video_widths_.size() == 1) {
    256  suppress_representation_width = true;
    257  adaptation_set.SetIntegerAttribute("width", *video_widths_.begin());
    258  } else if (video_widths_.size() > 1) {
    259  adaptation_set.SetIntegerAttribute("maxWidth", *video_widths_.rbegin());
    260  }
    261  if (video_heights_.size() == 1) {
    262  suppress_representation_height = true;
    263  adaptation_set.SetIntegerAttribute("height", *video_heights_.begin());
    264  } else if (video_heights_.size() > 1) {
    265  adaptation_set.SetIntegerAttribute("maxHeight", *video_heights_.rbegin());
    266  }
    267 
    268  if (video_frame_rates_.size() == 1) {
    269  suppress_representation_frame_rate = true;
    270  adaptation_set.SetStringAttribute("frameRate",
    271  video_frame_rates_.begin()->second);
    272  } else if (video_frame_rates_.size() > 1) {
    273  adaptation_set.SetStringAttribute("maxFrameRate",
    274  video_frame_rates_.rbegin()->second);
    275  }
    276 
    277  // Note: must be checked before checking segments_aligned_ (below). So that
    278  // segments_aligned_ is set before checking below.
    279  if (mpd_options_.mpd_type == MpdType::kStatic) {
    280  CheckStaticSegmentAlignment();
    281  }
    282 
    283  if (segments_aligned_ == kSegmentAlignmentTrue) {
    284  adaptation_set.SetStringAttribute(
    285  mpd_options_.dash_profile == DashProfile::kOnDemand
    286  ? "subsegmentAlignment"
    287  : "segmentAlignment",
    288  "true");
    289  }
    290 
    291  if (picture_aspect_ratio_.size() == 1)
    292  adaptation_set.SetStringAttribute("par", *picture_aspect_ratio_.begin());
    293 
    294  if (!adaptation_set.AddContentProtectionElements(
    295  content_protection_elements_)) {
    296  return xml::scoped_xml_ptr<xmlNode>();
    297  }
    298 
    299  std::string trick_play_reference_ids;
    300  for (const AdaptationSet* adaptation_set : trick_play_references_) {
    301  if (!trick_play_reference_ids.empty())
    302  trick_play_reference_ids += ',';
    303  CHECK(adaptation_set->has_id());
    304  trick_play_reference_ids += std::to_string(adaptation_set->id());
    305  }
    306  if (!trick_play_reference_ids.empty()) {
    307  adaptation_set.AddEssentialProperty(
    308  "http://dashif.org/guidelines/trickmode", trick_play_reference_ids);
    309  }
    310 
    311  std::string switching_ids;
    312  for (const AdaptationSet* adaptation_set : switchable_adaptation_sets_) {
    313  if (!switching_ids.empty())
    314  switching_ids += ',';
    315  CHECK(adaptation_set->has_id());
    316  switching_ids += std::to_string(adaptation_set->id());
    317  }
    318  if (!switching_ids.empty()) {
    319  adaptation_set.AddSupplementalProperty(
    320  "urn:mpeg:dash:adaptation-set-switching:2016", switching_ids);
    321  }
    322 
    323  for (const AdaptationSet::Accessibility& accessibility : accessibilities_) {
    324  adaptation_set.AddAccessibilityElement(accessibility.scheme,
    325  accessibility.value);
    326  }
    327 
    328  for (AdaptationSet::Role role : roles_)
    329  adaptation_set.AddRoleElement("urn:mpeg:dash:role:2011", RoleToText(role));
    330 
    331  for (const auto& representation_pair : representation_map_) {
    332  const auto& representation = representation_pair.second;
    333  if (suppress_representation_width)
    334  representation->SuppressOnce(Representation::kSuppressWidth);
    335  if (suppress_representation_height)
    336  representation->SuppressOnce(Representation::kSuppressHeight);
    337  if (suppress_representation_frame_rate)
    338  representation->SuppressOnce(Representation::kSuppressFrameRate);
    339  xml::scoped_xml_ptr<xmlNode> child(representation->GetXml());
    340  if (!child || !adaptation_set.AddChild(std::move(child)))
    341  return xml::scoped_xml_ptr<xmlNode>();
    342  }
    343 
    344  return adaptation_set.PassScopedPtr();
    345 }
    346 
    347 void AdaptationSet::ForceSetSegmentAlignment(bool segment_alignment) {
    348  segments_aligned_ =
    349  segment_alignment ? kSegmentAlignmentTrue : kSegmentAlignmentFalse;
    350  force_set_segment_alignment_ = true;
    351 }
    352 
    354  const AdaptationSet* adaptation_set) {
    355  switchable_adaptation_sets_.push_back(adaptation_set);
    356 }
    357 
    358 // For dynamic MPD, storing all start_time and duration will out-of-memory
    359 // because there's no way of knowing when it will end. Static MPD
    360 // subsegmentAlignment check is *not* done here because it is possible that some
    361 // Representations might not have been added yet (e.g. a thread is assigned per
    362 // muxer so one might run faster than others). To be clear, for dynamic MPD, all
    363 // Representations should be added before a segment is added.
    364 void AdaptationSet::OnNewSegmentForRepresentation(uint32_t representation_id,
    365  uint64_t start_time,
    366  uint64_t duration) {
    367  if (mpd_options_.mpd_type == MpdType::kDynamic) {
    368  CheckDynamicSegmentAlignment(representation_id, start_time, duration);
    369  } else {
    370  representation_segment_start_times_[representation_id].push_back(
    371  start_time);
    372  }
    373 }
    374 
    375 void AdaptationSet::OnSetFrameRateForRepresentation(uint32_t representation_id,
    376  uint32_t frame_duration,
    377  uint32_t timescale) {
    378  RecordFrameRate(frame_duration, timescale);
    379 }
    380 
    382  trick_play_references_.push_back(adaptation_set);
    383 }
    384 
    385 const std::list<Representation*> AdaptationSet::GetRepresentations() const {
    386  std::list<Representation*> representations;
    387  for (const auto& representation_pair : representation_map_) {
    388  representations.push_back(representation_pair.second.get());
    389  }
    390  return representations;
    391 }
    392 
    394  return content_type_ == "video";
    395 }
    396 
    397 void AdaptationSet::UpdateFromMediaInfo(const MediaInfo& media_info) {
    398  // For videos, record the width, height, and the frame rate to calculate the
    399  // max {width,height,framerate} required for DASH IOP.
    400  if (media_info.has_video_info()) {
    401  const MediaInfo::VideoInfo& video_info = media_info.video_info();
    402  DCHECK(video_info.has_width());
    403  DCHECK(video_info.has_height());
    404  video_widths_.insert(video_info.width());
    405  video_heights_.insert(video_info.height());
    406 
    407  if (video_info.has_time_scale() && video_info.has_frame_duration())
    408  RecordFrameRate(video_info.frame_duration(), video_info.time_scale());
    409 
    410  AddPictureAspectRatio(video_info, &picture_aspect_ratio_);
    411  }
    412 
    413  if (media_info.has_video_info()) {
    414  content_type_ = "video";
    415  } else if (media_info.has_audio_info()) {
    416  content_type_ = "audio";
    417  } else if (media_info.has_text_info()) {
    418  content_type_ = "text";
    419 
    420  if (media_info.text_info().has_type() &&
    421  (media_info.text_info().type() != MediaInfo::TextInfo::UNKNOWN)) {
    422  roles_.insert(MediaInfoTextTypeToRole(media_info.text_info().type()));
    423  }
    424  }
    425 }
    426 
    427 // This implementation assumes that each representations' segments' are
    428 // contiguous.
    429 // Also assumes that all Representations are added before this is called.
    430 // This checks whether the first elements of the lists in
    431 // representation_segment_start_times_ are aligned.
    432 // For example, suppose this method was just called with args rep_id=2
    433 // start_time=1.
    434 // 1 -> [1, 100, 200]
    435 // 2 -> [1]
    436 // The timestamps of the first elements match, so this flags
    437 // segments_aligned_=true.
    438 // Also since the first segment start times match, the first element of all the
    439 // lists are removed, so the map of lists becomes:
    440 // 1 -> [100, 200]
    441 // 2 -> []
    442 // Note that there could be false positives.
    443 // e.g. just got rep_id=3 start_time=1 duration=300, and the duration of the
    444 // whole AdaptationSet is 300.
    445 // 1 -> [1, 100, 200]
    446 // 2 -> [1, 90, 100]
    447 // 3 -> [1]
    448 // They are not aligned but this will be marked as aligned.
    449 // But since this is unlikely to happen in the packager (and to save
    450 // computation), this isn't handled at the moment.
    451 void AdaptationSet::CheckDynamicSegmentAlignment(uint32_t representation_id,
    452  uint64_t start_time,
    453  uint64_t /* duration */) {
    454  if (segments_aligned_ == kSegmentAlignmentFalse ||
    455  force_set_segment_alignment_) {
    456  return;
    457  }
    458 
    459  std::list<uint64_t>& current_representation_start_times =
    460  representation_segment_start_times_[representation_id];
    461  current_representation_start_times.push_back(start_time);
    462  // There's no way to detemine whether the segments are aligned if some
    463  // representations do not have any segments.
    464  if (representation_segment_start_times_.size() != representation_map_.size())
    465  return;
    466 
    467  DCHECK(!current_representation_start_times.empty());
    468  const uint64_t expected_start_time =
    469  current_representation_start_times.front();
    470  for (const auto& key_value : representation_segment_start_times_) {
    471  const std::list<uint64_t>& representation_start_time = key_value.second;
    472  // If there are no entries in a list, then there is no way for the
    473  // segment alignment status to change.
    474  // Note that it can be empty because entries get deleted below.
    475  if (representation_start_time.empty())
    476  return;
    477 
    478  if (expected_start_time != representation_start_time.front()) {
    479  VLOG(1) << "Seeing Misaligned segments with different start_times: "
    480  << expected_start_time << " vs "
    481  << representation_start_time.front();
    482  // Flag as false and clear the start times data, no need to keep it
    483  // around.
    484  segments_aligned_ = kSegmentAlignmentFalse;
    485  representation_segment_start_times_.clear();
    486  return;
    487  }
    488  }
    489  segments_aligned_ = kSegmentAlignmentTrue;
    490 
    491  for (auto& key_value : representation_segment_start_times_) {
    492  std::list<uint64_t>& representation_start_time = key_value.second;
    493  representation_start_time.pop_front();
    494  }
    495 }
    496 
    497 // Make sure all segements start times match for all Representations.
    498 // This assumes that the segments are contiguous.
    499 void AdaptationSet::CheckStaticSegmentAlignment() {
    500  if (segments_aligned_ == kSegmentAlignmentFalse ||
    501  force_set_segment_alignment_) {
    502  return;
    503  }
    504  if (representation_segment_start_times_.empty())
    505  return;
    506  if (representation_segment_start_times_.size() == 1) {
    507  segments_aligned_ = kSegmentAlignmentTrue;
    508  return;
    509  }
    510 
    511  // This is not the most efficient implementation to compare the values
    512  // because expected_time_line is compared against all other time lines, but
    513  // probably the most readable.
    514  const std::list<uint64_t>& expected_time_line =
    515  representation_segment_start_times_.begin()->second;
    516 
    517  bool all_segment_time_line_same_length = true;
    518  // Note that the first entry is skipped because it is expected_time_line.
    519  RepresentationTimeline::const_iterator it =
    520  representation_segment_start_times_.begin();
    521  for (++it; it != representation_segment_start_times_.end(); ++it) {
    522  const std::list<uint64_t>& other_time_line = it->second;
    523  if (expected_time_line.size() != other_time_line.size()) {
    524  all_segment_time_line_same_length = false;
    525  }
    526 
    527  const std::list<uint64_t>* longer_list = &other_time_line;
    528  const std::list<uint64_t>* shorter_list = &expected_time_line;
    529  if (expected_time_line.size() > other_time_line.size()) {
    530  shorter_list = &other_time_line;
    531  longer_list = &expected_time_line;
    532  }
    533 
    534  if (!std::equal(shorter_list->begin(), shorter_list->end(),
    535  longer_list->begin())) {
    536  // Some segments are definitely unaligned.
    537  segments_aligned_ = kSegmentAlignmentFalse;
    538  representation_segment_start_times_.clear();
    539  return;
    540  }
    541  }
    542 
    543  // TODO(rkuroiwa): The right way to do this is to also check the durations.
    544  // For example:
    545  // (a) 3 4 5
    546  // (b) 3 4 5 6
    547  // could be true or false depending on the length of the third segment of (a).
    548  // i.e. if length of the third segment is 2, then this is not aligned.
    549  if (!all_segment_time_line_same_length) {
    550  segments_aligned_ = kSegmentAlignmentUnknown;
    551  return;
    552  }
    553 
    554  segments_aligned_ = kSegmentAlignmentTrue;
    555 }
    556 
    557 // Since all AdaptationSet cares about is the maxFrameRate, representation_id
    558 // is not passed to this method.
    559 void AdaptationSet::RecordFrameRate(uint32_t frame_duration,
    560  uint32_t timescale) {
    561  if (frame_duration == 0) {
    562  LOG(ERROR) << "Frame duration is 0 and cannot be set.";
    563  return;
    564  }
    565  video_frame_rates_[static_cast<double>(timescale) / frame_duration] =
    566  base::IntToString(timescale) + "/" + base::IntToString(frame_duration);
    567 }
    568 
    569 } // namespace shaka
    void OnSetFrameRateForRepresentation(uint32_t representation_id, uint32_t frame_duration, uint32_t timescale)
    - -
    AdaptationSetType specified in MPD.
    Definition: xml_node.h:136
    -
    virtual Representation * AddRepresentation(const MediaInfo &media_info)
    -
    uint32_t id() const
    -
    scoped_xml_ptr< xmlNode > PassScopedPtr()
    Definition: xml_node.cc:204
    -
    All the methods that are virtual are virtual for mocking.
    -
    void AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:243
    - -
    virtual void AddContentProtectionElement(const ContentProtectionElement &element)
    -
    virtual Representation * CopyRepresentation(const Representation &representation)
    -
    void SetStringAttribute(const char *attribute_name, const std::string &attribute)
    Definition: xml_node.cc:166
    - -
    bool AddChild(scoped_xml_ptr< xmlNode > child)
    Definition: xml_node.cc:121
    -
    virtual void AddRole(Role role)
    -
    virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
    -
    void SetId(uint32_t id)
    Definition: xml_node.cc:189
    -
    void AddAccessibilityElement(const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:294
    -
    AdaptationSet(const std::string &language, const MpdOptions &mpd_options, uint32_t *representation_counter)
    -
    virtual void ForceSetSegmentAlignment(bool segment_alignment)
    -
    void AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:237
    -
    xml::scoped_xml_ptr< xmlNode > GetXml()
    -
    virtual void AddAccessibility(const std::string &scheme, const std::string &value)
    - -
    virtual void AddAdaptationSetSwitching(const AdaptationSet *adaptation_set)
    -
    void SetIntegerAttribute(const char *attribute_name, uint64_t number)
    Definition: xml_node.cc:173
    -
    void AddRoleElement(const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:300
    -
    Defines Mpd Options.
    Definition: mpd_options.h:25
    -
    void OnNewSegmentForRepresentation(uint32_t representation_id, uint64_t start_time, uint64_t duration)
    -
    virtual void AddTrickPlayReference(const AdaptationSet *adaptation_set)
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/mpd/base/adaptation_set.h"
    +
    8 
    +
    9 #include <cmath>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/base/strings/string_number_conversions.h"
    +
    13 #include "packager/mpd/base/media_info.pb.h"
    +
    14 #include "packager/mpd/base/mpd_options.h"
    +
    15 #include "packager/mpd/base/mpd_utils.h"
    +
    16 #include "packager/mpd/base/representation.h"
    +
    17 #include "packager/mpd/base/xml/xml_node.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace {
    +
    21 
    +
    22 AdaptationSet::Role MediaInfoTextTypeToRole(
    +
    23  MediaInfo::TextInfo::TextType type) {
    +
    24  switch (type) {
    +
    25  case MediaInfo::TextInfo::UNKNOWN:
    +
    26  LOG(WARNING) << "Unknown text type, assuming subtitle.";
    +
    27  return AdaptationSet::kRoleSubtitle;
    +
    28  case MediaInfo::TextInfo::CAPTION:
    +
    29  return AdaptationSet::kRoleCaption;
    +
    30  case MediaInfo::TextInfo::SUBTITLE:
    +
    31  return AdaptationSet::kRoleSubtitle;
    +
    32  default:
    +
    33  NOTREACHED() << "Unknown MediaInfo TextType: " << type
    +
    34  << " assuming subtitle.";
    +
    35  return AdaptationSet::kRoleSubtitle;
    +
    36  }
    +
    37 }
    +
    38 
    +
    39 std::string RoleToText(AdaptationSet::Role role) {
    +
    40  // Using switch so that the compiler can detect whether there is a case that's
    +
    41  // not being handled.
    +
    42  switch (role) {
    +
    43  case AdaptationSet::kRoleCaption:
    +
    44  return "caption";
    +
    45  case AdaptationSet::kRoleSubtitle:
    +
    46  return "subtitle";
    +
    47  case AdaptationSet::kRoleMain:
    +
    48  return "main";
    +
    49  case AdaptationSet::kRoleAlternate:
    +
    50  return "alternate";
    +
    51  case AdaptationSet::kRoleSupplementary:
    +
    52  return "supplementary";
    +
    53  case AdaptationSet::kRoleCommentary:
    +
    54  return "commentary";
    +
    55  case AdaptationSet::kRoleDub:
    +
    56  return "dub";
    +
    57  default:
    +
    58  return "unknown";
    +
    59  }
    +
    60 }
    +
    61 
    +
    62 // Returns the picture aspect ratio string e.g. "16:9", "4:3".
    +
    63 // "Reducing the quotient to minimal form" does not work well in practice as
    +
    64 // there may be some rounding performed in the input, e.g. the resolution of
    +
    65 // 480p is 854:480 for 16:9 aspect ratio, can only be reduced to 427:240.
    +
    66 // The algorithm finds out the pair of integers, num and den, where num / den is
    +
    67 // the closest ratio to scaled_width / scaled_height, by looping den through
    +
    68 // common values.
    +
    69 std::string GetPictureAspectRatio(uint32_t width,
    +
    70  uint32_t height,
    +
    71  uint32_t pixel_width,
    +
    72  uint32_t pixel_height) {
    +
    73  const uint32_t scaled_width = pixel_width * width;
    +
    74  const uint32_t scaled_height = pixel_height * height;
    +
    75  const double par = static_cast<double>(scaled_width) / scaled_height;
    +
    76 
    +
    77  // Typical aspect ratios have par_y less than or equal to 19:
    +
    78  // https://en.wikipedia.org/wiki/List_of_common_resolutions
    +
    79  const uint32_t kLargestPossibleParY = 19;
    +
    80 
    +
    81  uint32_t par_num = 0;
    +
    82  uint32_t par_den = 0;
    +
    83  double min_error = 1.0;
    +
    84  for (uint32_t den = 1; den <= kLargestPossibleParY; ++den) {
    +
    85  uint32_t num = par * den + 0.5;
    +
    86  double error = fabs(par - static_cast<double>(num) / den);
    +
    87  if (error < min_error) {
    +
    88  min_error = error;
    +
    89  par_num = num;
    +
    90  par_den = den;
    +
    91  if (error == 0)
    +
    92  break;
    +
    93  }
    +
    94  }
    +
    95  VLOG(2) << "width*pix_width : height*pixel_height (" << scaled_width << ":"
    +
    96  << scaled_height << ") reduced to " << par_num << ":" << par_den
    +
    97  << " with error " << min_error << ".";
    +
    98 
    +
    99  return base::IntToString(par_num) + ":" + base::IntToString(par_den);
    +
    100 }
    +
    101 
    +
    102 // Adds an entry to picture_aspect_ratio if the size of picture_aspect_ratio is
    +
    103 // less than 2 and video_info has both pixel width and pixel height.
    +
    104 void AddPictureAspectRatio(const MediaInfo::VideoInfo& video_info,
    +
    105  std::set<std::string>* picture_aspect_ratio) {
    +
    106  // If there are more than one entries in picture_aspect_ratio, the @par
    +
    107  // attribute cannot be set, so skip.
    +
    108  if (picture_aspect_ratio->size() > 1)
    +
    109  return;
    +
    110 
    +
    111  if (video_info.width() == 0 || video_info.height() == 0 ||
    +
    112  video_info.pixel_width() == 0 || video_info.pixel_height() == 0) {
    +
    113  // If there is even one Representation without a @sar attribute, @par cannot
    +
    114  // be calculated.
    +
    115  // Just populate the set with at least 2 bogus strings so that further call
    +
    116  // to this function will bail out immediately.
    +
    117  picture_aspect_ratio->insert("bogus");
    +
    118  picture_aspect_ratio->insert("entries");
    +
    119  return;
    +
    120  }
    +
    121 
    +
    122  const std::string par = GetPictureAspectRatio(
    +
    123  video_info.width(), video_info.height(), video_info.pixel_width(),
    +
    124  video_info.pixel_height());
    +
    125  DVLOG(1) << "Setting par as: " << par
    +
    126  << " for video with width: " << video_info.width()
    +
    127  << " height: " << video_info.height()
    +
    128  << " pixel_width: " << video_info.pixel_width() << " pixel_height; "
    +
    129  << video_info.pixel_height();
    +
    130  picture_aspect_ratio->insert(par);
    +
    131 }
    +
    132 
    +
    133 class RepresentationStateChangeListenerImpl
    +
    134  : public RepresentationStateChangeListener {
    +
    135  public:
    +
    136  // |adaptation_set| is not owned by this class.
    +
    137  RepresentationStateChangeListenerImpl(uint32_t representation_id,
    +
    138  AdaptationSet* adaptation_set)
    +
    139  : representation_id_(representation_id), adaptation_set_(adaptation_set) {
    +
    140  DCHECK(adaptation_set_);
    +
    141  }
    +
    142  ~RepresentationStateChangeListenerImpl() override {}
    +
    143 
    +
    144  // RepresentationStateChangeListener implementation.
    +
    145  void OnNewSegmentForRepresentation(int64_t start_time,
    +
    146  int64_t duration) override {
    +
    147  adaptation_set_->OnNewSegmentForRepresentation(representation_id_,
    +
    148  start_time, duration);
    +
    149  }
    +
    150 
    +
    151  void OnSetFrameRateForRepresentation(uint32_t frame_duration,
    +
    152  uint32_t timescale) override {
    +
    153  adaptation_set_->OnSetFrameRateForRepresentation(representation_id_,
    +
    154  frame_duration, timescale);
    +
    155  }
    +
    156 
    +
    157  private:
    +
    158  const uint32_t representation_id_;
    +
    159  AdaptationSet* const adaptation_set_;
    +
    160 
    +
    161  DISALLOW_COPY_AND_ASSIGN(RepresentationStateChangeListenerImpl);
    +
    162 };
    +
    163 
    +
    164 } // namespace
    +
    165 
    +
    166 AdaptationSet::AdaptationSet(const std::string& language,
    +
    167  const MpdOptions& mpd_options,
    +
    168  uint32_t* counter)
    +
    169  : representation_counter_(counter),
    +
    170  language_(language),
    +
    171  mpd_options_(mpd_options),
    +
    172  segments_aligned_(kSegmentAlignmentUnknown),
    +
    173  force_set_segment_alignment_(false) {
    +
    174  DCHECK(counter);
    +
    175 }
    +
    176 
    +
    177 AdaptationSet::~AdaptationSet() {}
    +
    178 
    +
    179 Representation* AdaptationSet::AddRepresentation(const MediaInfo& media_info) {
    +
    180  const uint32_t representation_id = (*representation_counter_)++;
    +
    181  // Note that AdaptationSet outlive Representation, so this object
    +
    182  // will die before AdaptationSet.
    +
    183  std::unique_ptr<RepresentationStateChangeListener> listener(
    +
    184  new RepresentationStateChangeListenerImpl(representation_id, this));
    +
    185  std::unique_ptr<Representation> new_representation(new Representation(
    +
    186  media_info, mpd_options_, representation_id, std::move(listener)));
    +
    187 
    +
    188  if (!new_representation->Init()) {
    +
    189  LOG(ERROR) << "Failed to initialize Representation.";
    +
    190  return NULL;
    +
    191  }
    +
    192  UpdateFromMediaInfo(media_info);
    +
    193  Representation* representation_ptr = new_representation.get();
    +
    194  representation_map_[representation_ptr->id()] = std::move(new_representation);
    +
    195  return representation_ptr;
    +
    196 }
    +
    197 
    + +
    199  const Representation& representation) {
    +
    200  // Note that AdaptationSet outlive Representation, so this object
    +
    201  // will die before AdaptationSet.
    +
    202  std::unique_ptr<RepresentationStateChangeListener> listener(
    +
    203  new RepresentationStateChangeListenerImpl(representation.id(), this));
    +
    204  std::unique_ptr<Representation> new_representation(
    +
    205  new Representation(representation, std::move(listener)));
    +
    206 
    +
    207  UpdateFromMediaInfo(new_representation->GetMediaInfo());
    +
    208  Representation* representation_ptr = new_representation.get();
    +
    209  representation_map_[representation_ptr->id()] = std::move(new_representation);
    +
    210  return representation_ptr;
    +
    211 }
    +
    212 
    + +
    214  const ContentProtectionElement& content_protection_element) {
    +
    215  content_protection_elements_.push_back(content_protection_element);
    +
    216  RemoveDuplicateAttributes(&content_protection_elements_.back());
    +
    217 }
    +
    218 
    +
    219 void AdaptationSet::UpdateContentProtectionPssh(const std::string& drm_uuid,
    +
    220  const std::string& pssh) {
    +
    221  UpdateContentProtectionPsshHelper(drm_uuid, pssh,
    +
    222  &content_protection_elements_);
    +
    223 }
    +
    224 
    +
    225 void AdaptationSet::AddAccessibility(const std::string& scheme,
    +
    226  const std::string& value) {
    +
    227  accessibilities_.push_back(Accessibility{scheme, value});
    +
    228 }
    +
    229 
    +
    230 void AdaptationSet::AddRole(Role role) {
    +
    231  roles_.insert(role);
    +
    232 }
    +
    233 
    +
    234 // Creates a copy of <AdaptationSet> xml element, iterate thru all the
    +
    235 // <Representation> (child) elements and add them to the copy.
    +
    236 // Set all the attributes first and then add the children elements so that flags
    +
    237 // can be passed to Representation to avoid setting redundant attributes. For
    +
    238 // example, if AdaptationSet@width is set, then Representation@width is
    +
    239 // redundant and should not be set.
    +
    240 base::Optional<xml::XmlNode> AdaptationSet::GetXml() {
    +
    241  xml::AdaptationSetXmlNode adaptation_set;
    +
    242 
    +
    243  bool suppress_representation_width = false;
    +
    244  bool suppress_representation_height = false;
    +
    245  bool suppress_representation_frame_rate = false;
    +
    246 
    +
    247  if (id_ && !adaptation_set.SetId(id_.value()))
    +
    248  return base::nullopt;
    +
    249  if (!adaptation_set.SetStringAttribute("contentType", content_type_))
    +
    250  return base::nullopt;
    +
    251  if (!language_.empty() && language_ != "und" &&
    +
    252  !adaptation_set.SetStringAttribute("lang", language_)) {
    +
    253  return base::nullopt;
    +
    254  }
    +
    255 
    +
    256  // Note that std::{set,map} are ordered, so the last element is the max value.
    +
    257  if (video_widths_.size() == 1) {
    +
    258  suppress_representation_width = true;
    +
    259  if (!adaptation_set.SetIntegerAttribute("width", *video_widths_.begin()))
    +
    260  return base::nullopt;
    +
    261  } else if (video_widths_.size() > 1) {
    +
    262  if (!adaptation_set.SetIntegerAttribute("maxWidth",
    +
    263  *video_widths_.rbegin())) {
    +
    264  return base::nullopt;
    +
    265  }
    +
    266  }
    +
    267  if (video_heights_.size() == 1) {
    +
    268  suppress_representation_height = true;
    +
    269  if (!adaptation_set.SetIntegerAttribute("height", *video_heights_.begin()))
    +
    270  return base::nullopt;
    +
    271  } else if (video_heights_.size() > 1) {
    +
    272  if (!adaptation_set.SetIntegerAttribute("maxHeight",
    +
    273  *video_heights_.rbegin())) {
    +
    274  return base::nullopt;
    +
    275  }
    +
    276  }
    +
    277 
    +
    278  if (video_frame_rates_.size() == 1) {
    +
    279  suppress_representation_frame_rate = true;
    +
    280  if (!adaptation_set.SetStringAttribute(
    +
    281  "frameRate", video_frame_rates_.begin()->second)) {
    +
    282  return base::nullopt;
    +
    283  }
    +
    284  } else if (video_frame_rates_.size() > 1) {
    +
    285  if (!adaptation_set.SetStringAttribute(
    +
    286  "maxFrameRate", video_frame_rates_.rbegin()->second)) {
    +
    287  return base::nullopt;
    +
    288  }
    +
    289  }
    +
    290 
    +
    291  // Note: must be checked before checking segments_aligned_ (below). So that
    +
    292  // segments_aligned_ is set before checking below.
    +
    293  if (mpd_options_.mpd_type == MpdType::kStatic) {
    +
    294  CheckStaticSegmentAlignment();
    +
    295  }
    +
    296 
    +
    297  if (segments_aligned_ == kSegmentAlignmentTrue) {
    +
    298  if (!adaptation_set.SetStringAttribute(
    +
    299  mpd_options_.dash_profile == DashProfile::kOnDemand
    +
    300  ? "subsegmentAlignment"
    +
    301  : "segmentAlignment",
    +
    302  "true")) {
    +
    303  return base::nullopt;
    +
    304  }
    +
    305  }
    +
    306 
    +
    307  if (picture_aspect_ratio_.size() == 1 &&
    +
    308  !adaptation_set.SetStringAttribute("par",
    +
    309  *picture_aspect_ratio_.begin())) {
    +
    310  return base::nullopt;
    +
    311  }
    +
    312 
    +
    313  if (!adaptation_set.AddContentProtectionElements(
    +
    314  content_protection_elements_)) {
    +
    315  return base::nullopt;
    +
    316  }
    +
    317 
    +
    318  std::string trick_play_reference_ids;
    +
    319  for (const AdaptationSet* adaptation_set : trick_play_references_) {
    +
    320  // Should be a whitespace-separated list, see DASH-IOP 3.2.9.
    +
    321  if (!trick_play_reference_ids.empty())
    +
    322  trick_play_reference_ids += ' ';
    +
    323  CHECK(adaptation_set->has_id());
    +
    324  trick_play_reference_ids += std::to_string(adaptation_set->id());
    +
    325  }
    +
    326  if (!trick_play_reference_ids.empty() &&
    +
    327  !adaptation_set.AddEssentialProperty(
    +
    328  "http://dashif.org/guidelines/trickmode", trick_play_reference_ids)) {
    +
    329  return base::nullopt;
    +
    330  }
    +
    331 
    +
    332  std::string switching_ids;
    +
    333  for (const AdaptationSet* adaptation_set : switchable_adaptation_sets_) {
    +
    334  // Should be a comma-separated list, see DASH-IOP 3.8.
    +
    335  if (!switching_ids.empty())
    +
    336  switching_ids += ',';
    +
    337  CHECK(adaptation_set->has_id());
    +
    338  switching_ids += std::to_string(adaptation_set->id());
    +
    339  }
    +
    340  if (!switching_ids.empty() &&
    +
    341  !adaptation_set.AddSupplementalProperty(
    +
    342  "urn:mpeg:dash:adaptation-set-switching:2016", switching_ids)) {
    +
    343  return base::nullopt;
    +
    344  }
    +
    345 
    +
    346  for (const AdaptationSet::Accessibility& accessibility : accessibilities_) {
    +
    347  if (!adaptation_set.AddAccessibilityElement(accessibility.scheme,
    +
    348  accessibility.value)) {
    +
    349  return base::nullopt;
    +
    350  }
    +
    351  }
    +
    352 
    +
    353  for (AdaptationSet::Role role : roles_) {
    +
    354  if (!adaptation_set.AddRoleElement("urn:mpeg:dash:role:2011",
    +
    355  RoleToText(role))) {
    +
    356  return base::nullopt;
    +
    357  }
    +
    358  }
    +
    359 
    +
    360  for (const auto& representation_pair : representation_map_) {
    +
    361  const auto& representation = representation_pair.second;
    +
    362  if (suppress_representation_width)
    +
    363  representation->SuppressOnce(Representation::kSuppressWidth);
    +
    364  if (suppress_representation_height)
    +
    365  representation->SuppressOnce(Representation::kSuppressHeight);
    +
    366  if (suppress_representation_frame_rate)
    +
    367  representation->SuppressOnce(Representation::kSuppressFrameRate);
    +
    368  auto child = representation->GetXml();
    +
    369  if (!child || !adaptation_set.AddChild(std::move(*child)))
    +
    370  return base::nullopt;
    +
    371  }
    +
    372 
    +
    373  return std::move(adaptation_set);
    +
    374 }
    +
    375 
    +
    376 void AdaptationSet::ForceSetSegmentAlignment(bool segment_alignment) {
    +
    377  segments_aligned_ =
    +
    378  segment_alignment ? kSegmentAlignmentTrue : kSegmentAlignmentFalse;
    +
    379  force_set_segment_alignment_ = true;
    +
    380 }
    +
    381 
    + +
    383  const AdaptationSet* adaptation_set) {
    +
    384  switchable_adaptation_sets_.push_back(adaptation_set);
    +
    385 }
    +
    386 
    +
    387 // For dynamic MPD, storing all start_time and duration will out-of-memory
    +
    388 // because there's no way of knowing when it will end. Static MPD
    +
    389 // subsegmentAlignment check is *not* done here because it is possible that some
    +
    390 // Representations might not have been added yet (e.g. a thread is assigned per
    +
    391 // muxer so one might run faster than others). To be clear, for dynamic MPD, all
    +
    392 // Representations should be added before a segment is added.
    +
    393 void AdaptationSet::OnNewSegmentForRepresentation(uint32_t representation_id,
    +
    394  uint64_t start_time,
    +
    395  uint64_t duration) {
    +
    396  if (mpd_options_.mpd_type == MpdType::kDynamic) {
    +
    397  CheckDynamicSegmentAlignment(representation_id, start_time, duration);
    +
    398  } else {
    +
    399  representation_segment_start_times_[representation_id].push_back(
    +
    400  start_time);
    +
    401  }
    +
    402 }
    +
    403 
    +
    404 void AdaptationSet::OnSetFrameRateForRepresentation(uint32_t representation_id,
    +
    405  uint32_t frame_duration,
    +
    406  uint32_t timescale) {
    +
    407  RecordFrameRate(frame_duration, timescale);
    +
    408 }
    +
    409 
    + +
    411  trick_play_references_.push_back(adaptation_set);
    +
    412 }
    +
    413 
    +
    414 const std::list<Representation*> AdaptationSet::GetRepresentations() const {
    +
    415  std::list<Representation*> representations;
    +
    416  for (const auto& representation_pair : representation_map_) {
    +
    417  representations.push_back(representation_pair.second.get());
    +
    418  }
    +
    419  return representations;
    +
    420 }
    +
    421 
    + +
    423  return content_type_ == "video";
    +
    424 }
    +
    425 
    +
    426 void AdaptationSet::UpdateFromMediaInfo(const MediaInfo& media_info) {
    +
    427  // For videos, record the width, height, and the frame rate to calculate the
    +
    428  // max {width,height,framerate} required for DASH IOP.
    +
    429  if (media_info.has_video_info()) {
    +
    430  const MediaInfo::VideoInfo& video_info = media_info.video_info();
    +
    431  DCHECK(video_info.has_width());
    +
    432  DCHECK(video_info.has_height());
    +
    433  video_widths_.insert(video_info.width());
    +
    434  video_heights_.insert(video_info.height());
    +
    435 
    +
    436  if (video_info.has_time_scale() && video_info.has_frame_duration())
    +
    437  RecordFrameRate(video_info.frame_duration(), video_info.time_scale());
    +
    438 
    +
    439  AddPictureAspectRatio(video_info, &picture_aspect_ratio_);
    +
    440  }
    +
    441 
    +
    442  if (media_info.has_video_info()) {
    +
    443  content_type_ = "video";
    +
    444  } else if (media_info.has_audio_info()) {
    +
    445  content_type_ = "audio";
    +
    446  } else if (media_info.has_text_info()) {
    +
    447  content_type_ = "text";
    +
    448 
    +
    449  if (media_info.text_info().has_type() &&
    +
    450  (media_info.text_info().type() != MediaInfo::TextInfo::UNKNOWN)) {
    +
    451  roles_.insert(MediaInfoTextTypeToRole(media_info.text_info().type()));
    +
    452  }
    +
    453  }
    +
    454 }
    +
    455 
    +
    456 // This implementation assumes that each representations' segments' are
    +
    457 // contiguous.
    +
    458 // Also assumes that all Representations are added before this is called.
    +
    459 // This checks whether the first elements of the lists in
    +
    460 // representation_segment_start_times_ are aligned.
    +
    461 // For example, suppose this method was just called with args rep_id=2
    +
    462 // start_time=1.
    +
    463 // 1 -> [1, 100, 200]
    +
    464 // 2 -> [1]
    +
    465 // The timestamps of the first elements match, so this flags
    +
    466 // segments_aligned_=true.
    +
    467 // Also since the first segment start times match, the first element of all the
    +
    468 // lists are removed, so the map of lists becomes:
    +
    469 // 1 -> [100, 200]
    +
    470 // 2 -> []
    +
    471 // Note that there could be false positives.
    +
    472 // e.g. just got rep_id=3 start_time=1 duration=300, and the duration of the
    +
    473 // whole AdaptationSet is 300.
    +
    474 // 1 -> [1, 100, 200]
    +
    475 // 2 -> [1, 90, 100]
    +
    476 // 3 -> [1]
    +
    477 // They are not aligned but this will be marked as aligned.
    +
    478 // But since this is unlikely to happen in the packager (and to save
    +
    479 // computation), this isn't handled at the moment.
    +
    480 void AdaptationSet::CheckDynamicSegmentAlignment(uint32_t representation_id,
    +
    481  uint64_t start_time,
    +
    482  uint64_t /* duration */) {
    +
    483  if (segments_aligned_ == kSegmentAlignmentFalse ||
    +
    484  force_set_segment_alignment_) {
    +
    485  return;
    +
    486  }
    +
    487 
    +
    488  std::list<uint64_t>& current_representation_start_times =
    +
    489  representation_segment_start_times_[representation_id];
    +
    490  current_representation_start_times.push_back(start_time);
    +
    491  // There's no way to detemine whether the segments are aligned if some
    +
    492  // representations do not have any segments.
    +
    493  if (representation_segment_start_times_.size() != representation_map_.size())
    +
    494  return;
    +
    495 
    +
    496  DCHECK(!current_representation_start_times.empty());
    +
    497  const uint64_t expected_start_time =
    +
    498  current_representation_start_times.front();
    +
    499  for (const auto& key_value : representation_segment_start_times_) {
    +
    500  const std::list<uint64_t>& representation_start_time = key_value.second;
    +
    501  // If there are no entries in a list, then there is no way for the
    +
    502  // segment alignment status to change.
    +
    503  // Note that it can be empty because entries get deleted below.
    +
    504  if (representation_start_time.empty())
    +
    505  return;
    +
    506 
    +
    507  if (expected_start_time != representation_start_time.front()) {
    +
    508  VLOG(1) << "Seeing Misaligned segments with different start_times: "
    +
    509  << expected_start_time << " vs "
    +
    510  << representation_start_time.front();
    +
    511  // Flag as false and clear the start times data, no need to keep it
    +
    512  // around.
    +
    513  segments_aligned_ = kSegmentAlignmentFalse;
    +
    514  representation_segment_start_times_.clear();
    +
    515  return;
    +
    516  }
    +
    517  }
    +
    518  segments_aligned_ = kSegmentAlignmentTrue;
    +
    519 
    +
    520  for (auto& key_value : representation_segment_start_times_) {
    +
    521  std::list<uint64_t>& representation_start_time = key_value.second;
    +
    522  representation_start_time.pop_front();
    +
    523  }
    +
    524 }
    +
    525 
    +
    526 // Make sure all segements start times match for all Representations.
    +
    527 // This assumes that the segments are contiguous.
    +
    528 void AdaptationSet::CheckStaticSegmentAlignment() {
    +
    529  if (segments_aligned_ == kSegmentAlignmentFalse ||
    +
    530  force_set_segment_alignment_) {
    +
    531  return;
    +
    532  }
    +
    533  if (representation_segment_start_times_.empty())
    +
    534  return;
    +
    535  if (representation_segment_start_times_.size() == 1) {
    +
    536  segments_aligned_ = kSegmentAlignmentTrue;
    +
    537  return;
    +
    538  }
    +
    539 
    +
    540  // This is not the most efficient implementation to compare the values
    +
    541  // because expected_time_line is compared against all other time lines, but
    +
    542  // probably the most readable.
    +
    543  const std::list<uint64_t>& expected_time_line =
    +
    544  representation_segment_start_times_.begin()->second;
    +
    545 
    +
    546  bool all_segment_time_line_same_length = true;
    +
    547  // Note that the first entry is skipped because it is expected_time_line.
    +
    548  RepresentationTimeline::const_iterator it =
    +
    549  representation_segment_start_times_.begin();
    +
    550  for (++it; it != representation_segment_start_times_.end(); ++it) {
    +
    551  const std::list<uint64_t>& other_time_line = it->second;
    +
    552  if (expected_time_line.size() != other_time_line.size()) {
    +
    553  all_segment_time_line_same_length = false;
    +
    554  }
    +
    555 
    +
    556  const std::list<uint64_t>* longer_list = &other_time_line;
    +
    557  const std::list<uint64_t>* shorter_list = &expected_time_line;
    +
    558  if (expected_time_line.size() > other_time_line.size()) {
    +
    559  shorter_list = &other_time_line;
    +
    560  longer_list = &expected_time_line;
    +
    561  }
    +
    562 
    +
    563  if (!std::equal(shorter_list->begin(), shorter_list->end(),
    +
    564  longer_list->begin())) {
    +
    565  // Some segments are definitely unaligned.
    +
    566  segments_aligned_ = kSegmentAlignmentFalse;
    +
    567  representation_segment_start_times_.clear();
    +
    568  return;
    +
    569  }
    +
    570  }
    +
    571 
    +
    572  // TODO(rkuroiwa): The right way to do this is to also check the durations.
    +
    573  // For example:
    +
    574  // (a) 3 4 5
    +
    575  // (b) 3 4 5 6
    +
    576  // could be true or false depending on the length of the third segment of (a).
    +
    577  // i.e. if length of the third segment is 2, then this is not aligned.
    +
    578  if (!all_segment_time_line_same_length) {
    +
    579  segments_aligned_ = kSegmentAlignmentUnknown;
    +
    580  return;
    +
    581  }
    +
    582 
    +
    583  segments_aligned_ = kSegmentAlignmentTrue;
    +
    584 }
    +
    585 
    +
    586 // Since all AdaptationSet cares about is the maxFrameRate, representation_id
    +
    587 // is not passed to this method.
    +
    588 void AdaptationSet::RecordFrameRate(uint32_t frame_duration,
    +
    589  uint32_t timescale) {
    +
    590  if (frame_duration == 0) {
    +
    591  LOG(ERROR) << "Frame duration is 0 and cannot be set.";
    +
    592  return;
    +
    593  }
    +
    594  video_frame_rates_[static_cast<double>(timescale) / frame_duration] =
    +
    595  base::IntToString(timescale) + "/" + base::IntToString(frame_duration);
    +
    596 }
    +
    597 
    +
    598 } // namespace shaka
    + +
    virtual Representation * AddRepresentation(const MediaInfo &media_info)
    +
    virtual void AddAccessibility(const std::string &scheme, const std::string &value)
    +
    base::Optional< xml::XmlNode > GetXml()
    +
    virtual void AddContentProtectionElement(const ContentProtectionElement &element)
    +
    void OnSetFrameRateForRepresentation(uint32_t representation_id, uint32_t frame_duration, uint32_t timescale)
    +
    virtual void ForceSetSegmentAlignment(bool segment_alignment)
    +
    virtual Representation * CopyRepresentation(const Representation &representation)
    +
    virtual void AddTrickPlayReference(const AdaptationSet *adaptation_set)
    +
    virtual void AddAdaptationSetSwitching(const AdaptationSet *adaptation_set)
    +
    AdaptationSet(const std::string &language, const MpdOptions &mpd_options, uint32_t *representation_counter)
    + +
    virtual void UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)
    +
    virtual void AddRole(Role role)
    +
    void OnNewSegmentForRepresentation(uint32_t representation_id, uint64_t start_time, uint64_t duration)
    + +
    uint32_t id() const
    +
    AdaptationSetType specified in MPD.
    Definition: xml_node.h:162
    +
    bool AddRoleElement(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:328
    +
    bool AddAccessibilityElement(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:322
    +
    bool AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:274
    +
    bool AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:280
    +
    bool AddChild(XmlNode child) WARN_UNUSED_RESULT
    Definition: xml_node.cc:140
    +
    bool SetIntegerAttribute(const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULT
    Definition: xml_node.cc:190
    +
    bool SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
    Definition: xml_node.cc:183
    +
    bool SetId(uint32_t id) WARN_UNUSED_RESULT
    Definition: xml_node.cc:204
    +
    All the methods that are virtual are virtual for mocking.
    + +
    Defines Mpd Options.
    Definition: mpd_options.h:25
    diff --git a/docs/de/dc2/classshaka_1_1media_1_1H265Parser.html b/docs/de/dc2/classshaka_1_1media_1_1H265Parser.html index 7f02f4b51e..4b224378b0 100644 --- a/docs/de/dc2/classshaka_1_1media_1_1H265Parser.html +++ b/docs/de/dc2/classshaka_1_1media_1_1H265Parser.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H265Parser Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Public Types

    -enum  Result { kOk, -kInvalidStream, -kUnsupportedStream, -kEOStream +enum  Result { kOk +, kInvalidStream +, kUnsupportedStream +, kEOStream }   @@ -242,9 +245,7 @@ Public Member Functions diff --git a/docs/de/dc9/structshaka_1_1media_1_1mp4_1_1DecodingTimeToSample-members.html b/docs/de/dc9/structshaka_1_1media_1_1mp4_1_1DecodingTimeToSample-members.html index 344da0489b..b2df0e6f15 100644 --- a/docs/de/dc9/structshaka_1_1media_1_1mp4_1_1DecodingTimeToSample-members.html +++ b/docs/de/dc9/structshaka_1_1media_1_1mp4_1_1DecodingTimeToSample-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/de/dcb/ts__segmenter_8h_source.html b/docs/de/dcb/ts__segmenter_8h_source.html index 635da46836..4ca8ee3590 100644 --- a/docs/de/dcb/ts__segmenter_8h_source.html +++ b/docs/de/dcb/ts__segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_segmenter.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    ts_segmenter.h
    -
    1 // Copyright 2016 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SEGMENTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SEGMENTER_H_
    9 
    10 #include <memory>
    11 #include "packager/file/file.h"
    12 #include "packager/media/base/muxer_options.h"
    13 #include "packager/media/formats/mp2t/pes_packet_generator.h"
    14 #include "packager/media/formats/mp2t/ts_writer.h"
    15 #include "packager/status.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    20 class KeySource;
    21 class MuxerListener;
    22 
    23 namespace mp2t {
    24 
    25 // TODO(rkuroiwa): For now, this implements multifile segmenter. Like other
    26 // make this an abstract super class and implement multifile and single file
    27 // segmenters.
    28 class TsSegmenter {
    29  public:
    30  // TODO(rkuroiwa): Add progress listener?
    35  TsSegmenter(const MuxerOptions& options, MuxerListener* listener);
    36  ~TsSegmenter();
    37 
    41  Status Initialize(const StreamInfo& stream_info);
    42 
    45  Status Finalize();
    46 
    49  Status AddSample(const MediaSample& sample);
    50 
    58  // TODO(kqyang): Remove the usage of segment start timestamp and duration in
    59  // xx_segmenter, which could cause confusions on which is the source of truth
    60  // as the segment start timestamp and duration could be tracked locally.
    61  Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration);
    62 
    64  void InjectTsWriterForTesting(std::unique_ptr<TsWriter> writer);
    65 
    68  std::unique_ptr<PesPacketGenerator> generator);
    69 
    71  void SetTsWriterFileOpenedForTesting(bool value);
    72 
    73  private:
    74  Status OpenNewSegmentIfClosed(uint32_t next_pts);
    75 
    76  // Writes PES packets (carried in TsPackets) to a file. If a file is not open,
    77  // it will open one. This will not close the file.
    78  Status WritePesPacketsToFile();
    79 
    80  const MuxerOptions& muxer_options_;
    81  MuxerListener* const listener_;
    82 
    83  // Codec for the stream.
    84  Codec codec_ = kUnknownCodec;
    85  std::vector<uint8_t> audio_codec_config_;
    86 
    87  const uint32_t transport_stream_timestamp_offset_ = 0;
    88  // Scale used to scale the input stream to TS's timesccale (which is 90000).
    89  // Used for calculating the duration in seconds fo the current segment.
    90  double timescale_scale_ = 1.0;
    91 
    92  // Used for segment template.
    93  uint64_t segment_number_ = 0;
    94 
    95  std::unique_ptr<TsWriter> ts_writer_;
    96  // Set to true if TsWriter::NewFile() succeeds, set to false after
    97  // TsWriter::FinalizeFile() succeeds.
    98  bool ts_writer_file_opened_ = false;
    99  std::unique_ptr<PesPacketGenerator> pes_packet_generator_;
    100 
    101  // For OnNewSegment().
    102  // Path of the current segment so that File::GetFileSize() can be used after
    103  // the segment has been finalized.
    104  std::string current_segment_path_;
    105 
    106  DISALLOW_COPY_AND_ASSIGN(TsSegmenter);
    107 };
    108 
    109 } // namespace mp2t
    110 } // namespace media
    111 } // namespace shaka
    112 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_SEGMENTER_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    - -
    Status Initialize(const StreamInfo &stream_info)
    Definition: ts_segmenter.cc:46
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    -
    Status AddSample(const MediaSample &sample)
    Definition: ts_segmenter.cc:74
    - -
    TsSegmenter(const MuxerOptions &options, MuxerListener *listener)
    Definition: ts_segmenter.cc:36
    - -
    void InjectPesPacketGeneratorForTesting(std::unique_ptr< PesPacketGenerator > generator)
    Only for testing.
    -
    void SetTsWriterFileOpenedForTesting(bool value)
    Only for testing.
    -
    void InjectTsWriterForTesting(std::unique_ptr< TsWriter > writer)
    Only for testing.
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    -
    Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration)
    - +
    1 // Copyright 2016 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_TS_SEGMENTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_TS_SEGMENTER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include "packager/file/file.h"
    +
    12 #include "packager/media/base/muxer_options.h"
    +
    13 #include "packager/media/formats/mp2t/pes_packet_generator.h"
    +
    14 #include "packager/media/formats/mp2t/ts_writer.h"
    +
    15 #include "packager/status.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    +
    20 class KeySource;
    +
    21 class MuxerListener;
    +
    22 
    +
    23 namespace mp2t {
    +
    24 
    +
    25 // TODO(rkuroiwa): For now, this implements multifile segmenter. Like other
    +
    26 // make this an abstract super class and implement multifile and single file
    +
    27 // segmenters.
    +
    28 class TsSegmenter {
    +
    29  public:
    +
    30  // TODO(rkuroiwa): Add progress listener?
    +
    35  TsSegmenter(const MuxerOptions& options, MuxerListener* listener);
    +
    36  ~TsSegmenter();
    +
    37 
    +
    41  Status Initialize(const StreamInfo& stream_info);
    +
    42 
    +
    45  Status Finalize();
    +
    46 
    +
    49  Status AddSample(const MediaSample& sample);
    +
    50 
    +
    58  // TODO(kqyang): Remove the usage of segment start timestamp and duration in
    +
    59  // xx_segmenter, which could cause confusions on which is the source of truth
    +
    60  // as the segment start timestamp and duration could be tracked locally.
    +
    61  Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration);
    +
    62 
    +
    64  void InjectTsWriterForTesting(std::unique_ptr<TsWriter> writer);
    +
    65 
    + +
    68  std::unique_ptr<PesPacketGenerator> generator);
    +
    69 
    +
    71  void SetSegmentStartedForTesting(bool value);
    +
    72 
    +
    73  private:
    +
    74  Status StartSegmentIfNeeded(int64_t next_pts);
    +
    75 
    +
    76  // Writes PES packets (carried in TsPackets) to a buffer.
    +
    77  Status WritePesPackets();
    +
    78 
    +
    79  const MuxerOptions& muxer_options_;
    +
    80  MuxerListener* const listener_;
    +
    81 
    +
    82  // Codec for the stream.
    +
    83  Codec codec_ = kUnknownCodec;
    +
    84  std::vector<uint8_t> audio_codec_config_;
    +
    85 
    +
    86  const uint32_t transport_stream_timestamp_offset_ = 0;
    +
    87  // Scale used to scale the input stream to TS's timesccale (which is 90000).
    +
    88  // Used for calculating the duration in seconds fo the current segment.
    +
    89  double timescale_scale_ = 1.0;
    +
    90 
    +
    91  // Used for segment template.
    +
    92  uint64_t segment_number_ = 0;
    +
    93 
    +
    94  std::unique_ptr<TsWriter> ts_writer_;
    +
    95 
    +
    96  BufferWriter segment_buffer_;
    +
    97 
    +
    98  // Set to true if segment_buffer_ is initialized, set to false after
    +
    99  // FinalizeSegment() succeeds.
    +
    100  bool segment_started_ = false;
    +
    101  std::unique_ptr<PesPacketGenerator> pes_packet_generator_;
    +
    102 
    +
    103  int64_t segment_start_timestamp_ = -1;
    +
    104  DISALLOW_COPY_AND_ASSIGN(TsSegmenter);
    +
    105 };
    +
    106 
    +
    107 } // namespace mp2t
    +
    108 } // namespace media
    +
    109 } // namespace shaka
    +
    110 #endif // PACKAGER_MEDIA_FORMATS_MP2T_TS_SEGMENTER_H_
    + + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    + +
    void SetSegmentStartedForTesting(bool value)
    Only for testing.
    +
    Status Initialize(const StreamInfo &stream_info)
    Definition: ts_segmenter.cc:47
    +
    void InjectPesPacketGeneratorForTesting(std::unique_ptr< PesPacketGenerator > generator)
    Only for testing.
    +
    Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration)
    + +
    Status AddSample(const MediaSample &sample)
    Definition: ts_segmenter.cc:75
    +
    void InjectTsWriterForTesting(std::unique_ptr< TsWriter > writer)
    Only for testing.
    +
    TsSegmenter(const MuxerOptions &options, MuxerListener *listener)
    Definition: ts_segmenter.cc:37
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/de/dcc/key__frame__info_8h_source.html b/docs/de/dcc/key__frame__info_8h_source.html index 6e16511b0c..968eace75c 100644 --- a/docs/de/dcc/key__frame__info_8h_source.html +++ b/docs/de/dcc/key__frame__info_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/key_frame_info.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    key_frame_info.h
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_KEY_FRAME_INFO_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_KEY_FRAME_INFO_H_
    9 
    10 #include <cstdint>
    11 
    12 namespace shaka {
    13 namespace media {
    14 namespace mp4 {
    15 
    17 struct KeyFrameInfo {
    18  uint64_t timestamp;
    19  uint64_t start_byte_offset;
    20  uint64_t size;
    21 };
    22 
    23 } // namespace mp4
    24 } // namespace media
    25 } // namespace shaka
    26 
    27 #endif // PACKAGER_MEDIA_FORMATS_MP4_KEY_FRAME_INFO_H_
    All the methods that are virtual are virtual for mocking.
    -
    Tracks key frame information.
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_KEY_FRAME_INFO_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_KEY_FRAME_INFO_H_
    +
    9 
    +
    10 #include <cstdint>
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 namespace mp4 {
    +
    15 
    +
    17 struct KeyFrameInfo {
    +
    18  uint64_t timestamp;
    +
    19  uint64_t start_byte_offset;
    +
    20  uint64_t size;
    +
    21 };
    +
    22 
    +
    23 } // namespace mp4
    +
    24 } // namespace media
    +
    25 } // namespace shaka
    +
    26 
    +
    27 #endif // PACKAGER_MEDIA_FORMATS_MP4_KEY_FRAME_INFO_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    Tracks key frame information.
    diff --git a/docs/de/dcc/mock__mpd__notifier_8cc_source.html b/docs/de/dcc/mock__mpd__notifier_8cc_source.html index 612f5c2e29..b81da0a070 100644 --- a/docs/de/dcc/mock__mpd__notifier_8cc_source.html +++ b/docs/de/dcc/mock__mpd__notifier_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mock_mpd_notifier.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    mock_mpd_notifier.cc
    -
    1 #include "packager/mpd/base/mock_mpd_notifier.h"
    2 
    3 namespace shaka {
    4 
    5 MockMpdNotifier::MockMpdNotifier(const MpdOptions& mpd_options)
    6  : MpdNotifier(mpd_options) {}
    7 MockMpdNotifier::~MockMpdNotifier() {}
    8 
    9 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 #include "packager/mpd/base/mock_mpd_notifier.h"
    +
    2 
    +
    3 namespace shaka {
    +
    4 
    +
    5 MockMpdNotifier::MockMpdNotifier(const MpdOptions& mpd_options)
    +
    6  : MpdNotifier(mpd_options) {}
    +
    7 MockMpdNotifier::~MockMpdNotifier() {}
    +
    8 
    +
    9 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/dcf/file__closer_8h_source.html b/docs/de/dcf/file__closer_8h_source.html index 1c90a2f2f9..99fdda02c1 100644 --- a/docs/de/dcf/file__closer_8h_source.html +++ b/docs/de/dcf/file__closer_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/file_closer.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    file_closer.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef MEDIA_FILE_FILE_CLOSER_H_
    8 #define MEDIA_FILE_FILE_CLOSER_H_
    9 
    10 #include "packager/base/logging.h"
    11 #include "packager/file/file.h"
    12 
    13 namespace shaka {
    14 
    17 struct FileCloser {
    18  inline void operator()(File* file) const {
    19  if (file != NULL) {
    20  const std::string filename = file->file_name();
    21  if (!file->Close()) {
    22  LOG(WARNING) << "Failed to close the file properly: " << filename;
    23  }
    24  }
    25  }
    26 };
    27 
    28 } // namespace shaka
    29 
    30 #endif // MEDIA_FILE_FILE_CLOSER_H_
    Define an abstract file interface.
    Definition: file.h:26
    - -
    const std::string & file_name() const
    Definition: file.h:94
    -
    All the methods that are virtual are virtual for mocking.
    -
    virtual bool Close()=0
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef MEDIA_FILE_FILE_CLOSER_H_
    +
    8 #define MEDIA_FILE_FILE_CLOSER_H_
    +
    9 
    +
    10 #include "packager/base/logging.h"
    +
    11 #include "packager/file/file.h"
    +
    12 
    +
    13 namespace shaka {
    +
    14 
    +
    17 struct FileCloser {
    +
    18  inline void operator()(File* file) const {
    +
    19  if (file != NULL) {
    +
    20  const std::string filename = file->file_name();
    +
    21  if (!file->Close()) {
    +
    22  LOG(WARNING) << "Failed to close the file properly: " << filename;
    +
    23  }
    +
    24  }
    +
    25  }
    +
    26 };
    +
    27 
    +
    28 } // namespace shaka
    +
    29 
    +
    30 #endif // MEDIA_FILE_FILE_CLOSER_H_
    +
    Define an abstract file interface.
    Definition: file.h:27
    +
    const std::string & file_name() const
    Definition: file.h:95
    +
    virtual bool Close()=0
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/de/dd4/protection__system__ids_8h_source.html b/docs/de/dd4/protection__system__ids_8h_source.html index e0da866fb3..48bac9d6f3 100644 --- a/docs/de/dd4/protection__system__ids_8h_source.html +++ b/docs/de/dd4/protection__system__ids_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/protection_system_ids.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    protection_system_ids.h
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_IDS_H_
    8 #define PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_IDS_H_
    9 
    10 namespace shaka {
    11 namespace media {
    12 
    13 // System Ids are defined in https://dashif.org/identifiers/content_protection/.
    14 
    15 // Common SystemID defined by EME, which requires Key System implementations
    16 // supporting ISO Common Encryption to support this SystemID and format.
    17 // https://goo.gl/kUv2Xd
    18 const uint8_t kCommonSystemId[] = {0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2,
    19  0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e,
    20  0x52, 0xe2, 0xfb, 0x4b};
    21 
    22 // Unofficial FairPlay system id extracted from
    23 // https://forums.developer.apple.com/thread/6185.
    24 const uint8_t kFairPlaySystemId[] = {0x29, 0x70, 0x1F, 0xE4, 0x3C, 0xC7,
    25  0x4A, 0x34, 0x8C, 0x5B, 0xAE, 0x90,
    26  0xC7, 0x43, 0x9A, 0x47};
    27 
    28 // Marlin Adaptive Streaming Specification – Simple Profile, V1.0.
    29 const uint8_t kMarlinSystemId[] = {0x5E, 0x62, 0x9A, 0xF5, 0x38, 0xDA,
    30  0x40, 0x63, 0x89, 0x77, 0x97, 0xFF,
    31  0xBD, 0x99, 0x02, 0xD4};
    32 
    33 const uint8_t kPlayReadySystemId[] = {0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40,
    34  0x42, 0x86, 0xab, 0x92, 0xe6, 0x5b,
    35  0xe0, 0x88, 0x5f, 0x95};
    36 
    37 const uint8_t kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
    38  0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
    39  0xd5, 0x1d, 0x21, 0xed};
    40 
    41 } // namespace media
    42 } // namespace shaka
    43 
    44 #endif // PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_IDS_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_IDS_H_
    +
    8 #define PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_IDS_H_
    +
    9 
    +
    10 namespace shaka {
    +
    11 namespace media {
    +
    12 
    +
    13 // System Ids are defined in https://dashif.org/identifiers/content_protection/.
    +
    14 
    +
    15 // Common SystemID defined by EME, which requires Key System implementations
    +
    16 // supporting ISO Common Encryption to support this SystemID and format.
    +
    17 // https://goo.gl/kUv2Xd
    +
    18 const uint8_t kCommonSystemId[] = {0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2,
    +
    19  0x4d, 0x02, 0xac, 0xe3, 0x3c, 0x1e,
    +
    20  0x52, 0xe2, 0xfb, 0x4b};
    +
    21 
    +
    22 // Unofficial FairPlay system id extracted from
    +
    23 // https://forums.developer.apple.com/thread/6185.
    +
    24 const uint8_t kFairPlaySystemId[] = {0x29, 0x70, 0x1F, 0xE4, 0x3C, 0xC7,
    +
    25  0x4A, 0x34, 0x8C, 0x5B, 0xAE, 0x90,
    +
    26  0xC7, 0x43, 0x9A, 0x47};
    +
    27 
    +
    28 // Marlin Adaptive Streaming Specification – Simple Profile, V1.0.
    +
    29 const uint8_t kMarlinSystemId[] = {0x5E, 0x62, 0x9A, 0xF5, 0x38, 0xDA,
    +
    30  0x40, 0x63, 0x89, 0x77, 0x97, 0xFF,
    +
    31  0xBD, 0x99, 0x02, 0xD4};
    +
    32 
    +
    33 const uint8_t kPlayReadySystemId[] = {0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40,
    +
    34  0x42, 0x86, 0xab, 0x92, 0xe6, 0x5b,
    +
    35  0xe0, 0x88, 0x5f, 0x95};
    +
    36 
    +
    37 const uint8_t kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
    +
    38  0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
    +
    39  0xd5, 0x1d, 0x21, 0xed};
    +
    40 
    +
    41 } // namespace media
    +
    42 } // namespace shaka
    +
    43 
    +
    44 #endif // PACKAGER_MEDIA_BASE_PROTECTION_SYSTEM_IDS_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/dd6/content__protection__element_8h_source.html b/docs/de/dd6/content__protection__element_8h_source.html index 123c02c572..6c2b80aebc 100644 --- a/docs/de/dd6/content__protection__element_8h_source.html +++ b/docs/de/dd6/content__protection__element_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/content_protection_element.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    content_protection_element.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // ContentProtectionElement is shared a structure that can be passed to
    8 // MPD generator classes to add ContentProtection element in the resulting MPD
    9 // file.
    10 // http://goo.gl/UrsSlF
    11 
    12 #ifndef MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_
    13 #define MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_
    14 
    15 #include <map>
    16 #include <string>
    17 #include <vector>
    18 
    19 namespace shaka {
    20 
    21 // This is any (XML) element.
    22 struct Element {
    23  Element();
    24  ~Element();
    25  // Name of this element.
    26  std::string name;
    27  // attributes for this element.
    28  std::map<std::string, std::string> attributes;
    29  // Content of this element.
    30  std::string content;
    31  std::vector<Element> subelements;
    32 };
    33 
    39 
    40  std::string value; // Will be set for 'value' attribute.
    41  std::string scheme_id_uri; // Will be set for 'schemeIdUri' attribute.
    42 
    43  // Other attributes for this element.
    44  std::map<std::string, std::string> additional_attributes;
    45 
    46  // The subelements that will be in this element.
    47  std::vector<Element> subelements;
    48 };
    49 
    50 } // namespace shaka
    51 
    52 #endif // MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_
    -
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // ContentProtectionElement is shared a structure that can be passed to
    +
    8 // MPD generator classes to add ContentProtection element in the resulting MPD
    +
    9 // file.
    +
    10 // http://goo.gl/UrsSlF
    +
    11 
    +
    12 #ifndef MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_
    +
    13 #define MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_
    +
    14 
    +
    15 #include <map>
    +
    16 #include <string>
    +
    17 #include <vector>
    +
    18 
    +
    19 namespace shaka {
    +
    20 
    +
    21 // This is any (XML) element.
    +
    22 struct Element {
    +
    23  Element();
    +
    24  ~Element();
    +
    25  // Name of this element.
    +
    26  std::string name;
    +
    27  // attributes for this element.
    +
    28  std::map<std::string, std::string> attributes;
    +
    29  // Content of this element.
    +
    30  std::string content;
    +
    31  std::vector<Element> subelements;
    +
    32 };
    +
    33 
    + + + +
    39 
    +
    40  std::string value; // Will be set for 'value' attribute.
    +
    41  std::string scheme_id_uri; // Will be set for 'schemeIdUri' attribute.
    +
    42 
    +
    43  // Other attributes for this element.
    +
    44  std::map<std::string, std::string> additional_attributes;
    +
    45 
    +
    46  // The subelements that will be in this element.
    +
    47  std::vector<Element> subelements;
    +
    48 };
    +
    49 
    +
    50 } // namespace shaka
    +
    51 
    +
    52 #endif // MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_
    +
    All the methods that are virtual are virtual for mocking.
    + +
    diff --git a/docs/de/dd6/muxer__listener__test__helper_8cc_source.html b/docs/de/dd6/muxer__listener__test__helper_8cc_source.html index 43f720a09f..bc70cc8540 100644 --- a/docs/de/dd6/muxer__listener__test__helper_8cc_source.html +++ b/docs/de/dd6/muxer__listener__test__helper_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/muxer_listener_test_helper.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    muxer_listener_test_helper.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/event/muxer_listener_test_helper.h"
    8 #include "packager/media/event/muxer_listener.h"
    9 
    10 #include <gtest/gtest.h>
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    15 VideoStreamInfoParameters::VideoStreamInfoParameters() {}
    16 VideoStreamInfoParameters::~VideoStreamInfoParameters() {}
    17 
    18 std::shared_ptr<VideoStreamInfo> CreateVideoStreamInfo(
    19  const VideoStreamInfoParameters& param) {
    20  return std::make_shared<VideoStreamInfo>(
    21  param.track_id, param.time_scale, param.duration, param.codec,
    22  H26xStreamFormat::kUnSpecified, param.codec_string,
    23  param.codec_config.data(), param.codec_config.size(), param.width,
    24  param.height, param.pixel_width, param.pixel_height,
    25  0, // transfer_characteristics
    26  0, // trick_play_factor
    27  param.nalu_length_size, param.language, param.is_encrypted);
    28 }
    29 
    30 VideoStreamInfoParameters GetDefaultVideoStreamInfoParams() {
    31  const int kTrackId = 0;
    32  const uint32_t kTimeScale = 10;
    33  const uint64_t kVideoStreamDuration = 200;
    34  const Codec kH264Codec = kCodecH264;
    35  const char* kCodecString = "avc1.010101";
    36  const char* kLanuageUndefined = "und";
    37  const uint16_t kWidth = 720;
    38  const uint16_t kHeight = 480;
    39  const uint32_t kPixelWidth = 1;
    40  const uint32_t kPixelHeight = 1;
    41  const uint8_t kNaluLengthSize = 1;
    42  const std::vector<uint8_t> kExtraData;
    43  const bool kEncryptedFlag = false;
    44  VideoStreamInfoParameters params;
    45  params.track_id = kTrackId;
    46  params.time_scale = kTimeScale;
    47  params.duration = kVideoStreamDuration;
    48  params.codec = kH264Codec;
    49  params.codec_string = kCodecString;
    50  params.language = kLanuageUndefined;
    51  params.width = kWidth;
    52  params.height = kHeight;
    53  params.pixel_width = kPixelWidth;
    54  params.pixel_height = kPixelHeight;
    55  params.nalu_length_size = kNaluLengthSize;
    56  params.codec_config = kExtraData;
    57  params.is_encrypted = kEncryptedFlag;
    58  return params;
    59 }
    60 
    61 OnMediaEndParameters GetDefaultOnMediaEndParams() {
    62  // Values for {init, index} range {start, end} are arbitrary, but makes sure
    63  // that it is monotonically increasing and contiguous.
    64  const uint64_t kInitRangeStart = 0;
    65  const uint64_t kInitRangeEnd = kInitRangeStart + 120;
    66  const uint64_t kIndexRangeStart = kInitRangeEnd + 1;
    67  const uint64_t kIndexRangeEnd = kIndexRangeStart + 100;
    68  const uint64_t kMediaSegmentRangeStart = kIndexRangeEnd + 1;
    69  const uint64_t kMediaSegmentRangeEnd = 9999;
    70  const float kMediaDuration = 10.5f;
    71  MuxerListener::MediaRanges media_ranges;
    72  Range init_range;
    73  init_range.start = kInitRangeStart;
    74  init_range.end = kInitRangeEnd;
    75  media_ranges.init_range = init_range;
    76  Range index_range;
    77  index_range.start = kIndexRangeStart;
    78  index_range.end = kIndexRangeEnd;
    79  media_ranges.index_range =index_range;
    80 
    81  Range media_segment_range;
    82  media_segment_range.start = kMediaSegmentRangeStart;
    83  media_segment_range.end = kMediaSegmentRangeEnd;
    84  media_ranges.subsegment_ranges.push_back(media_segment_range);
    85 
    86  OnMediaEndParameters param = {media_ranges, kMediaDuration};
    87  return param;
    88 }
    89 
    90 void SetDefaultMuxerOptions(MuxerOptions* muxer_options) {
    91  muxer_options->output_file_name = "test_output_file_name.mp4";
    92  muxer_options->segment_template.clear();
    93  muxer_options->temp_dir.clear();
    94 }
    95 
    96 std::vector<ProtectionSystemSpecificInfo> GetDefaultKeySystemInfo() {
    97  const uint8_t kTestSystemId[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
    98  0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
    99  0x0c, 0x0d, 0x0e, 0x0f};
    100  return {{{std::begin(kTestSystemId), std::end(kTestSystemId)},
    101  {std::begin(kExpectedDefaultPsshBox),
    102  // -1 to remove the null terminator.
    103  std::end(kExpectedDefaultPsshBox) - 1}}};
    104 }
    105 
    106 } // namespace media
    107 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/event/muxer_listener_test_helper.h"
    +
    8 #include "packager/media/event/muxer_listener.h"
    +
    9 
    +
    10 #include <gtest/gtest.h>
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    15 VideoStreamInfoParameters::VideoStreamInfoParameters() {}
    +
    16 VideoStreamInfoParameters::~VideoStreamInfoParameters() {}
    +
    17 
    +
    18 std::shared_ptr<VideoStreamInfo> CreateVideoStreamInfo(
    +
    19  const VideoStreamInfoParameters& param) {
    +
    20  return std::make_shared<VideoStreamInfo>(
    +
    21  param.track_id, param.time_scale, param.duration, param.codec,
    +
    22  H26xStreamFormat::kUnSpecified, param.codec_string,
    +
    23  param.codec_config.data(), param.codec_config.size(), param.width,
    +
    24  param.height, param.pixel_width, param.pixel_height,
    +
    25  0, // transfer_characteristics
    +
    26  0, // trick_play_factor
    +
    27  param.nalu_length_size, param.language, param.is_encrypted);
    +
    28 }
    +
    29 
    +
    30 VideoStreamInfoParameters GetDefaultVideoStreamInfoParams() {
    +
    31  const int kTrackId = 0;
    +
    32  const uint32_t kTimeScale = 10;
    +
    33  const uint64_t kVideoStreamDuration = 200;
    +
    34  const Codec kH264Codec = kCodecH264;
    +
    35  const char* kCodecString = "avc1.010101";
    +
    36  const char* kLanuageUndefined = "und";
    +
    37  const uint16_t kWidth = 720;
    +
    38  const uint16_t kHeight = 480;
    +
    39  const uint32_t kPixelWidth = 1;
    +
    40  const uint32_t kPixelHeight = 1;
    +
    41  const uint8_t kNaluLengthSize = 1;
    +
    42  const std::vector<uint8_t> kExtraData;
    +
    43  const bool kEncryptedFlag = false;
    +
    44  VideoStreamInfoParameters params;
    +
    45  params.track_id = kTrackId;
    +
    46  params.time_scale = kTimeScale;
    +
    47  params.duration = kVideoStreamDuration;
    +
    48  params.codec = kH264Codec;
    +
    49  params.codec_string = kCodecString;
    +
    50  params.language = kLanuageUndefined;
    +
    51  params.width = kWidth;
    +
    52  params.height = kHeight;
    +
    53  params.pixel_width = kPixelWidth;
    +
    54  params.pixel_height = kPixelHeight;
    +
    55  params.nalu_length_size = kNaluLengthSize;
    +
    56  params.codec_config = kExtraData;
    +
    57  params.is_encrypted = kEncryptedFlag;
    +
    58  return params;
    +
    59 }
    +
    60 
    +
    61 OnMediaEndParameters GetDefaultOnMediaEndParams() {
    +
    62  // Values for {init, index} range {start, end} are arbitrary, but makes sure
    +
    63  // that it is monotonically increasing and contiguous.
    +
    64  const uint64_t kInitRangeStart = 0;
    +
    65  const uint64_t kInitRangeEnd = kInitRangeStart + 120;
    +
    66  const uint64_t kIndexRangeStart = kInitRangeEnd + 1;
    +
    67  const uint64_t kIndexRangeEnd = kIndexRangeStart + 100;
    +
    68  const uint64_t kMediaSegmentRangeStart = kIndexRangeEnd + 1;
    +
    69  const uint64_t kMediaSegmentRangeEnd = 9999;
    +
    70  const float kMediaDuration = 10.5f;
    +
    71  MuxerListener::MediaRanges media_ranges;
    +
    72  Range init_range;
    +
    73  init_range.start = kInitRangeStart;
    +
    74  init_range.end = kInitRangeEnd;
    +
    75  media_ranges.init_range = init_range;
    +
    76  Range index_range;
    +
    77  index_range.start = kIndexRangeStart;
    +
    78  index_range.end = kIndexRangeEnd;
    +
    79  media_ranges.index_range =index_range;
    +
    80 
    +
    81  Range media_segment_range;
    +
    82  media_segment_range.start = kMediaSegmentRangeStart;
    +
    83  media_segment_range.end = kMediaSegmentRangeEnd;
    +
    84  media_ranges.subsegment_ranges.push_back(media_segment_range);
    +
    85 
    +
    86  OnMediaEndParameters param = {media_ranges, kMediaDuration};
    +
    87  return param;
    +
    88 }
    +
    89 
    +
    90 void SetDefaultMuxerOptions(MuxerOptions* muxer_options) {
    +
    91  muxer_options->output_file_name = "test_output_file_name.mp4";
    +
    92  muxer_options->segment_template.clear();
    +
    93  muxer_options->temp_dir.clear();
    +
    94 }
    +
    95 
    +
    96 std::vector<ProtectionSystemSpecificInfo> GetDefaultKeySystemInfo() {
    +
    97  const uint8_t kTestSystemId[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
    +
    98  0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
    +
    99  0x0c, 0x0d, 0x0e, 0x0f};
    +
    100  return {{{std::begin(kTestSystemId), std::end(kTestSystemId)},
    +
    101  {std::begin(kExpectedDefaultPsshBox),
    +
    102  // -1 to remove the null terminator.
    +
    103  std::end(kExpectedDefaultPsshBox) - 1}}};
    +
    104 }
    +
    105 
    +
    106 } // namespace media
    +
    107 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/de/ddc/multi__codec__muxer__listener_8h_source.html b/docs/de/ddc/multi__codec__muxer__listener_8h_source.html new file mode 100644 index 0000000000..a1d93deb9d --- /dev/null +++ b/docs/de/ddc/multi__codec__muxer__listener_8h_source.html @@ -0,0 +1,116 @@ + + + + + + + +Shaka Packager SDK: packager/media/event/multi_codec_muxer_listener.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    multi_codec_muxer_listener.h
    +
    +
    +
    1 // Copyright 2019 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_EVENT_MULTI_CODEC_MUXER_LISTENER_H_
    +
    8 #define PACKAGER_MEDIA_EVENT_MULTI_CODEC_MUXER_LISTENER_H_
    +
    9 
    +
    10 #include "packager/media/event/combined_muxer_listener.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    + +
    23  public:
    +
    24  MultiCodecMuxerListener() = default;
    +
    25 
    +
    28  void OnMediaStart(const MuxerOptions& muxer_options,
    +
    29  const StreamInfo& stream_info,
    +
    30  uint32_t time_scale,
    +
    31  ContainerType container_type) override;
    +
    33 
    +
    34  private:
    + +
    36  MultiCodecMuxerListener& operator=(const MultiCodecMuxerListener&) = delete;
    +
    37 };
    +
    38 
    +
    39 } // namespace media
    +
    40 } // namespace shaka
    +
    41 
    +
    42 #endif // PACKAGER_MEDIA_EVENT_MULTI_CODEC_MUXER_LISTENER_H_
    + + +
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    +
    + + + + diff --git a/docs/de/ddd/classshaka_1_1media_1_1Muxer-members.html b/docs/de/ddd/classshaka_1_1media_1_1Muxer-members.html index e09fa40c8b..eb028fef5f 100644 --- a/docs/de/ddd/classshaka_1_1media_1_1Muxer-members.html +++ b/docs/de/ddd/classshaka_1_1media_1_1Muxer-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline Cancel()shaka::media::Muxer - Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic + Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic clock() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected @@ -107,9 +110,7 @@ $(function() {
    diff --git a/docs/de/dde/classshaka_1_1media_1_1mp2t_1_1TsSegmenter.html b/docs/de/dde/classshaka_1_1media_1_1mp2t_1_1TsSegmenter.html index 766076d043..627b408c2a 100644 --- a/docs/de/dde/classshaka_1_1media_1_1mp2t_1_1TsSegmenter.html +++ b/docs/de/dde/classshaka_1_1media_1_1mp2t_1_1TsSegmenter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp2t::TsSegmenter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    InjectPesPacketGeneratorForTesting (std::unique_ptr< PesPacketGenerator > generator)  Only for testing.
      - -void SetTsWriterFileOpenedForTesting (bool value) - Only for testing.
    -  + +void SetSegmentStartedForTesting (bool value) + Only for testing.

    Detailed Description

    @@ -132,7 +135,7 @@ void Definition at line 36 of file ts_segmenter.cc.

    +

    Definition at line 37 of file ts_segmenter.cc.

    @@ -160,7 +163,7 @@ void 
    Returns
    OK on success.
    -

    Definition at line 74 of file ts_segmenter.cc.

    +

    Definition at line 75 of file ts_segmenter.cc.

    @@ -180,7 +183,7 @@ void 

    Finalize the segmenter.

    Returns
    OK on success.
    -

    Definition at line 70 of file ts_segmenter.cc.

    +

    Definition at line 71 of file ts_segmenter.cc.

    @@ -217,7 +220,7 @@ void Definition at line 171 of file ts_segmenter.cc.

    +

    Definition at line 166 of file ts_segmenter.cc.

    @@ -244,7 +247,7 @@ void 
    Returns
    OK on success.
    -

    Definition at line 46 of file ts_segmenter.cc.

    +

    Definition at line 47 of file ts_segmenter.cc.

    @@ -255,9 +258,7 @@ void  diff --git a/docs/de/ddf/structshaka_1_1media_1_1mp4_1_1MediaData-members.html b/docs/de/ddf/structshaka_1_1media_1_1mp4_1_1MediaData-members.html index a3987ba93d..1acb86c413 100644 --- a/docs/de/ddf/structshaka_1_1media_1_1mp4_1_1MediaData-members.html +++ b/docs/de/ddf/structshaka_1_1media_1_1mp4_1_1MediaData-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/de0/classshaka_1_1media_1_1DecoderConfigurationRecord.html b/docs/de/de0/classshaka_1_1media_1_1DecoderConfigurationRecord.html index 37c53467a1..f98af1ee24 100644 --- a/docs/de/de0/classshaka_1_1media_1_1DecoderConfigurationRecord.html +++ b/docs/de/de0/classshaka_1_1media_1_1DecoderConfigurationRecord.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::DecoderConfigurationRecord Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::media::AVCDecoderConfigurationRecord -shaka::media::HEVCDecoderConfigurationRecord - -
    +shaka::media::AVCDecoderConfigurationRecord +shaka::media::HEVCDecoderConfigurationRecord + + @@ -355,9 +358,7 @@ void 

    Public Member Functions

    diff --git a/docs/de/de0/classshaka_1_1media_1_1mp4_1_1MP4Muxer-members.html b/docs/de/de0/classshaka_1_1media_1_1mp4_1_1MP4Muxer-members.html index 83329a4f3b..5922938711 100644 --- a/docs/de/de0/classshaka_1_1media_1_1mp4_1_1MP4Muxer-members.html +++ b/docs/de/de0/classshaka_1_1media_1_1mp4_1_1MP4Muxer-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline Cancel()shaka::media::Muxer - Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic + Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic clock() (defined in shaka::media::Muxer)shaka::media::Muxerinlineprotected Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected @@ -109,9 +112,7 @@ $(function() {
    diff --git a/docs/de/de4/structshaka_1_1media_1_1H264Pps.html b/docs/de/de4/structshaka_1_1media_1_1H264Pps.html index 7356596262..3252676990 100644 --- a/docs/de/de4/structshaka_1_1media_1_1H264Pps.html +++ b/docs/de/de4/structshaka_1_1media_1_1H264Pps.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264Pps Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    second_chroma_qp_index

    Detailed Description

    -

    Definition at line 94 of file h264_parser.h.

    -

    The documentation for this struct was generated from the following files:

    The documentation for this struct was generated from the following file: diff --git a/docs/de/dea/classshaka_1_1media_1_1H26xByteToUnitStreamConverter.html b/docs/de/dea/classshaka_1_1media_1_1H26xByteToUnitStreamConverter.html index 8925591739..779931ac24 100644 --- a/docs/de/dea/classshaka_1_1media_1_1H26xByteToUnitStreamConverter.html +++ b/docs/de/dea/classshaka_1_1media_1_1H26xByteToUnitStreamConverter.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H26xByteToUnitStreamConverter Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::H264ByteToUnitStreamConverter shaka::media::H265ByteToUnitStreamConverter - -
    + + @@ -250,7 +253,7 @@ void 

    Public Member Functions

    WarnIfNotMatch (i
    -

    Creates either an AVCDecoderConfigurationRecord or a HEVCDecoderConfigurationRecord from the units extracted from the byte stream.

    Parameters
    +

    Creates either an AVCDecoderConfigurationRecord or a HEVCDecoderConfigurationRecord from the units extracted from the byte stream.

    Parameters
    decoder_configis a pointer to a vector, which on successful return will contain the computed record.
    @@ -258,7 +261,7 @@ void WarnIfNotMatch (i
    Returns
    true if successful, or false otherwise.
    -

    Implemented in shaka::media::H264ByteToUnitStreamConverter, and shaka::media::H265ByteToUnitStreamConverter.

    +

    Implemented in shaka::media::H265ByteToUnitStreamConverter, and shaka::media::H264ByteToUnitStreamConverter.

    @@ -269,9 +272,7 @@ void WarnIfNotMatch (i diff --git a/docs/de/deb/structshaka_1_1Cuepoint.html b/docs/de/deb/structshaka_1_1Cuepoint.html index 7f63e0db7e..9c94aedacd 100644 --- a/docs/de/deb/structshaka_1_1Cuepoint.html +++ b/docs/de/deb/structshaka_1_1Cuepoint.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::Cuepoint Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/de/def/structshaka_1_1media_1_1mp4_1_1DecodingTimeToSample.html b/docs/de/def/structshaka_1_1media_1_1mp4_1_1DecodingTimeToSample.html index 5a3a051cc4..461fe4fdf3 100644 --- a/docs/de/def/structshaka_1_1media_1_1mp4_1_1DecodingTimeToSample.html +++ b/docs/de/def/structshaka_1_1media_1_1mp4_1_1DecodingTimeToSample.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::DecodingTimeToSample Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 426 of file box_definitions.h.

    +

    Definition at line 439 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 686 of file box_definitions.cc.

    +

    Definition at line 699 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/de/df2/combined__muxer__listener_8h_source.html b/docs/de/df2/combined__muxer__listener_8h_source.html index b4be86f3f8..792909ef80 100644 --- a/docs/de/df2/combined__muxer__listener_8h_source.html +++ b/docs/de/df2/combined__muxer__listener_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/combined_muxer_listener.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    combined_muxer_listener.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_EVENT_COMBINED_MUXER_LISTENER_H_
    8 #define PACKAGER_MEDIA_EVENT_COMBINED_MUXER_LISTENER_H_
    9 
    10 #include <list>
    11 #include <memory>
    12 
    13 #include "packager/media/event/muxer_listener.h"
    14 
    15 namespace shaka {
    16 namespace media {
    17 
    19  public:
    20  CombinedMuxerListener() = default;
    21 
    22  void AddListener(std::unique_ptr<MuxerListener> listener);
    23 
    24  void OnEncryptionInfoReady(bool is_initial_encryption_info,
    25  FourCC protection_scheme,
    26  const std::vector<uint8_t>& key_id,
    27  const std::vector<uint8_t>& iv,
    28  const std::vector<ProtectionSystemSpecificInfo>&
    29  key_system_info) override;
    30  void OnEncryptionStart() override;
    31  void OnMediaStart(const MuxerOptions& muxer_options,
    32  const StreamInfo& stream_info,
    33  uint32_t time_scale,
    34  ContainerType container_type) override;
    35  void OnSampleDurationReady(uint32_t sample_duration) override;
    36  void OnMediaEnd(const MediaRanges& media_ranges,
    37  float duration_seconds) override;
    38  void OnNewSegment(const std::string& file_name,
    39  int64_t start_time,
    40  int64_t duration,
    41  uint64_t segment_file_size) override;
    42  void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size);
    43  void OnCueEvent(int64_t timestamp, const std::string& cue_data) override;
    44 
    45  private:
    46  std::list<std::unique_ptr<MuxerListener>> muxer_listeners_;
    47 
    48  DISALLOW_COPY_AND_ASSIGN(CombinedMuxerListener);
    49 };
    50 
    51 } // namespace media
    52 } // namespace shaka
    53 
    54 #endif // PACKAGER_MEDIA_EVENT_COMBINED_MUXER_LISTENER_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
    -
    void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
    - -
    All the methods that are virtual are virtual for mocking.
    -
    void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    -
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    -
    void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
    - -
    void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    - -
    void OnSampleDurationReady(uint32_t sample_duration) override
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_EVENT_COMBINED_MUXER_LISTENER_H_
    +
    8 #define PACKAGER_MEDIA_EVENT_COMBINED_MUXER_LISTENER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <vector>
    +
    12 
    +
    13 #include "packager/media/event/muxer_listener.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    + +
    21  public:
    +
    22  CombinedMuxerListener() = default;
    +
    23 
    +
    24  void AddListener(std::unique_ptr<MuxerListener> listener);
    +
    25 
    +
    28  void OnEncryptionInfoReady(bool is_initial_encryption_info,
    +
    29  FourCC protection_scheme,
    +
    30  const std::vector<uint8_t>& key_id,
    +
    31  const std::vector<uint8_t>& iv,
    +
    32  const std::vector<ProtectionSystemSpecificInfo>&
    +
    33  key_system_info) override;
    +
    34  void OnEncryptionStart() override;
    +
    35  void OnMediaStart(const MuxerOptions& muxer_options,
    +
    36  const StreamInfo& stream_info,
    +
    37  uint32_t time_scale,
    +
    38  ContainerType container_type) override;
    +
    39  void OnSampleDurationReady(uint32_t sample_duration) override;
    +
    40  void OnMediaEnd(const MediaRanges& media_ranges,
    +
    41  float duration_seconds) override;
    +
    42  void OnNewSegment(const std::string& file_name,
    +
    43  int64_t start_time,
    +
    44  int64_t duration,
    +
    45  uint64_t segment_file_size) override;
    +
    46  void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size);
    +
    47  void OnCueEvent(int64_t timestamp, const std::string& cue_data) override;
    +
    49 
    +
    50  protected:
    +
    55  void LimitNumOfMuxerListners(size_t num) {
    +
    56  if (num < muxer_listeners_.size())
    +
    57  muxer_listeners_.resize(num);
    +
    58  }
    +
    61  MuxerListener* MuxerListenerAt(size_t index) {
    +
    62  return (index < muxer_listeners_.size()) ? muxer_listeners_[index].get()
    +
    63  : nullptr;
    +
    64  }
    +
    65 
    +
    66  private:
    + +
    68  CombinedMuxerListener& operator=(const CombinedMuxerListener&) = delete;
    +
    69 
    +
    70  std::vector<std::unique_ptr<MuxerListener>> muxer_listeners_;
    +
    71 };
    +
    72 
    +
    73 } // namespace media
    +
    74 } // namespace shaka
    +
    75 
    +
    76 #endif // PACKAGER_MEDIA_EVENT_COMBINED_MUXER_LISTENER_H_
    + + +
    void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)
    +
    void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type) override
    + +
    void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info) override
    +
    void OnCueEvent(int64_t timestamp, const std::string &cue_data) override
    +
    MuxerListener * MuxerListenerAt(size_t index)
    +
    void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds) override
    +
    void OnSampleDurationReady(uint32_t sample_duration) override
    +
    void OnNewSegment(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t segment_file_size) override
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    + +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/de/df6/classshaka_1_1media_1_1mp4_1_1TrackRunIterator.html b/docs/de/df6/classshaka_1_1media_1_1mp4_1_1TrackRunIterator.html index ba26e0e869..654ca53805 100644 --- a/docs/de/df6/classshaka_1_1media_1_1mp4_1_1TrackRunIterator.html +++ b/docs/de/df6/classshaka_1_1media_1_1mp4_1_1TrackRunIterator.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TrackRunIterator Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    is_keyframe () co
    diff --git a/docs/de/dfa/muxer__listener_8h_source.html b/docs/de/dfa/muxer__listener_8h_source.html index df1300c62a..1cd262e2f1 100644 --- a/docs/de/dfa/muxer__listener_8h_source.html +++ b/docs/de/dfa/muxer__listener_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event/muxer_listener.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    muxer_listener.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Event handler for events fired by Muxer.
    8 
    9 #ifndef PACKAGER_MEDIA_EVENT_MUXER_LISTENER_H_
    10 #define PACKAGER_MEDIA_EVENT_MUXER_LISTENER_H_
    11 
    12 #include <stdint.h>
    13 
    14 #include <string>
    15 #include <vector>
    16 
    17 #include "packager/base/optional.h"
    18 #include "packager/media/base/fourccs.h"
    19 #include "packager/media/base/range.h"
    20 
    21 namespace shaka {
    22 namespace media {
    23 
    24 struct MuxerOptions;
    25 struct ProtectionSystemSpecificInfo;
    26 class StreamInfo;
    27 
    33  public:
    34  enum ContainerType {
    35  kContainerUnknown = 0,
    36  kContainerMp4,
    37  kContainerMpeg2ts,
    38  kContainerWebM,
    39  kContainerText,
    40  kContainerPackedAudio,
    41  };
    42 
    46  struct MediaRanges {
    48  base::Optional<Range> init_range;
    50  base::Optional<Range> index_range;
    54  std::vector<Range> subsegment_ranges;
    55  };
    56 
    57  virtual ~MuxerListener() = default;
    58 
    77  virtual void OnEncryptionInfoReady(
    78  bool is_initial_encryption_info,
    79  FourCC protection_scheme,
    80  const std::vector<uint8_t>& key_id,
    81  const std::vector<uint8_t>& iv,
    82  const std::vector<ProtectionSystemSpecificInfo>& key_system_info) = 0;
    83 
    88  virtual void OnEncryptionStart() = 0;
    89 
    98  virtual void OnMediaStart(const MuxerOptions& muxer_options,
    99  const StreamInfo& stream_info,
    100  uint32_t time_scale,
    101  ContainerType container_type) = 0;
    102 
    105  virtual void OnSampleDurationReady(uint32_t sample_duration) = 0;
    106 
    113  virtual void OnMediaEnd(const MediaRanges& media_ranges,
    114  float duration_seconds) = 0;
    115 
    127  virtual void OnNewSegment(const std::string& segment_name,
    128  int64_t start_time,
    129  int64_t duration,
    130  uint64_t segment_file_size) = 0;
    131 
    137  virtual void OnKeyFrame(int64_t timestamp,
    138  uint64_t start_byte_offset,
    139  uint64_t size) = 0;
    140 
    144  virtual void OnCueEvent(int64_t timestamp, const std::string& cue_data) = 0;
    145 
    146  protected:
    147  MuxerListener() = default;
    148 };
    149 
    150 } // namespace media
    151 } // namespace shaka
    152 
    153 #endif // PACKAGER_MEDIA_EVENT_MUXER_LISTENER_H_
    virtual void OnCueEvent(int64_t timestamp, const std::string &cue_data)=0
    -
    virtual void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info)=0
    -
    base::Optional< Range > init_range
    Range of the initialization section of a segment.
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    virtual void OnSampleDurationReady(uint32_t sample_duration)=0
    -
    base::Optional< Range > index_range
    Range of the index section of a segment.
    - -
    virtual void OnEncryptionStart()=0
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    - -
    virtual void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds)=0
    -
    virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
    -
    virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
    - -
    virtual void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Event handler for events fired by Muxer.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_EVENT_MUXER_LISTENER_H_
    +
    10 #define PACKAGER_MEDIA_EVENT_MUXER_LISTENER_H_
    +
    11 
    +
    12 #include <stdint.h>
    +
    13 
    +
    14 #include <string>
    +
    15 #include <vector>
    +
    16 
    +
    17 #include "packager/base/optional.h"
    +
    18 #include "packager/media/base/fourccs.h"
    +
    19 #include "packager/media/base/range.h"
    +
    20 
    +
    21 namespace shaka {
    +
    22 namespace media {
    +
    23 
    +
    24 struct MuxerOptions;
    +
    25 struct ProtectionSystemSpecificInfo;
    +
    26 class StreamInfo;
    +
    27 
    + +
    33  public:
    +
    34  enum ContainerType {
    +
    35  kContainerUnknown = 0,
    +
    36  kContainerMp4,
    +
    37  kContainerMpeg2ts,
    +
    38  kContainerWebM,
    +
    39  kContainerText,
    +
    40  kContainerPackedAudio,
    +
    41  };
    +
    42 
    +
    46  struct MediaRanges {
    +
    48  base::Optional<Range> init_range;
    +
    50  base::Optional<Range> index_range;
    +
    54  std::vector<Range> subsegment_ranges;
    +
    55  };
    +
    56 
    +
    57  virtual ~MuxerListener() = default;
    +
    58 
    +
    77  virtual void OnEncryptionInfoReady(
    +
    78  bool is_initial_encryption_info,
    +
    79  FourCC protection_scheme,
    +
    80  const std::vector<uint8_t>& key_id,
    +
    81  const std::vector<uint8_t>& iv,
    +
    82  const std::vector<ProtectionSystemSpecificInfo>& key_system_info) = 0;
    +
    83 
    +
    88  virtual void OnEncryptionStart() = 0;
    +
    89 
    +
    98  virtual void OnMediaStart(const MuxerOptions& muxer_options,
    +
    99  const StreamInfo& stream_info,
    +
    100  uint32_t time_scale,
    +
    101  ContainerType container_type) = 0;
    +
    102 
    +
    105  virtual void OnSampleDurationReady(uint32_t sample_duration) = 0;
    +
    106 
    +
    113  virtual void OnMediaEnd(const MediaRanges& media_ranges,
    +
    114  float duration_seconds) = 0;
    +
    115 
    +
    127  virtual void OnNewSegment(const std::string& segment_name,
    +
    128  int64_t start_time,
    +
    129  int64_t duration,
    +
    130  uint64_t segment_file_size) = 0;
    +
    131 
    +
    137  virtual void OnKeyFrame(int64_t timestamp,
    +
    138  uint64_t start_byte_offset,
    +
    139  uint64_t size) = 0;
    +
    140 
    +
    144  virtual void OnCueEvent(int64_t timestamp, const std::string& cue_data) = 0;
    +
    145 
    +
    146  protected:
    +
    147  MuxerListener() = default;
    +
    148 };
    +
    149 
    +
    150 } // namespace media
    +
    151 } // namespace shaka
    +
    152 
    +
    153 #endif // PACKAGER_MEDIA_EVENT_MUXER_LISTENER_H_
    + +
    virtual void OnMediaEnd(const MediaRanges &media_ranges, float duration_seconds)=0
    +
    virtual void OnMediaStart(const MuxerOptions &muxer_options, const StreamInfo &stream_info, uint32_t time_scale, ContainerType container_type)=0
    +
    virtual void OnEncryptionStart()=0
    +
    virtual void OnCueEvent(int64_t timestamp, const std::string &cue_data)=0
    +
    virtual void OnNewSegment(const std::string &segment_name, int64_t start_time, int64_t duration, uint64_t segment_file_size)=0
    +
    virtual void OnEncryptionInfoReady(bool is_initial_encryption_info, FourCC protection_scheme, const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< ProtectionSystemSpecificInfo > &key_system_info)=0
    +
    virtual void OnSampleDurationReady(uint32_t sample_duration)=0
    +
    virtual void OnKeyFrame(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)=0
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    + +
    base::Optional< Range > init_range
    Range of the initialization section of a segment.
    + +
    base::Optional< Range > index_range
    Range of the index section of a segment.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/de/dfa/structshaka_1_1media_1_1mp4_1_1OpusSpecific.html b/docs/de/dfa/structshaka_1_1media_1_1mp4_1_1OpusSpecific.html index af694bcbff..c7781b6fee 100644 --- a/docs/de/dfa/structshaka_1_1media_1_1mp4_1_1OpusSpecific.html +++ b/docs/de/dfa/structshaka_1_1media_1_1mp4_1_1OpusSpecific.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::OpusSpecific Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -115,7 +118,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 336 of file box_definitions.h.

    +

    Definition at line 343 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -143,7 +146,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 1767 of file box_definitions.cc.

    +

    Definition at line 1814 of file box_definitions.cc.

    @@ -154,9 +157,7 @@ Additional Inherited Members diff --git a/docs/de/dfd/stream__info_8cc_source.html b/docs/de/dfd/stream__info_8cc_source.html index 38fff8cb95..4a1ee8efa0 100644 --- a/docs/de/dfd/stream__info_8cc_source.html +++ b/docs/de/dfd/stream__info_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/stream_info.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    stream_info.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/stream_info.h"
    8 
    9 #include <inttypes.h>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/base/strings/stringprintf.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    17 std::string StreamTypeToString(StreamType type) {
    18  switch (type) {
    19  case kStreamUnknown:
    20  return "Unknown";
    21  case kStreamVideo:
    22  return "Video";
    23  case kStreamAudio:
    24  return "Audio";
    25  case kStreamText:
    26  return "Text";
    27  }
    28 
    29  NOTREACHED() << "Unhandled StreamType with value " << static_cast<int>(type);
    30  return "";
    31 }
    32 
    33 StreamInfo::StreamInfo(StreamType stream_type,
    34  int track_id,
    35  uint32_t time_scale,
    36  uint64_t duration,
    37  Codec codec,
    38  const std::string& codec_string,
    39  const uint8_t* codec_config,
    40  size_t codec_config_size,
    41  const std::string& language,
    42  bool is_encrypted)
    43  : stream_type_(stream_type),
    44  track_id_(track_id),
    45  time_scale_(time_scale),
    46  duration_(duration),
    47  codec_(codec),
    48  codec_string_(codec_string),
    49  language_(language),
    50  is_encrypted_(is_encrypted) {
    51  if (codec_config_size > 0) {
    52  codec_config_.assign(codec_config, codec_config + codec_config_size);
    53  }
    54 }
    55 
    56 StreamInfo::~StreamInfo() {}
    57 
    58 std::string StreamInfo::ToString() const {
    59  return base::StringPrintf(
    60  "type: %s\n codec_string: %s\n time_scale: %d\n duration: "
    61  "%" PRIu64 " (%.1f seconds)\n is_encrypted: %s\n",
    62  (stream_type_ == kStreamAudio ? "Audio" : "Video"), codec_string_.c_str(),
    63  time_scale_, duration_, static_cast<double>(duration_) / time_scale_,
    64  is_encrypted_ ? "true" : "false");
    65 }
    66 
    67 } // namespace media
    68 } // namespace shaka
    virtual std::string ToString() const
    Definition: stream_info.cc:58
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/stream_info.h"
    +
    8 
    +
    9 #include <inttypes.h>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/base/strings/stringprintf.h"
    +
    13 #include "packager/media/base/timestamp.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    +
    18 std::string StreamTypeToString(StreamType type) {
    +
    19  switch (type) {
    +
    20  case kStreamUnknown:
    +
    21  return "Unknown";
    +
    22  case kStreamVideo:
    +
    23  return "Video";
    +
    24  case kStreamAudio:
    +
    25  return "Audio";
    +
    26  case kStreamText:
    +
    27  return "Text";
    +
    28  }
    +
    29 
    +
    30  NOTREACHED() << "Unhandled StreamType with value " << static_cast<int>(type);
    +
    31  return "";
    +
    32 }
    +
    33 
    +
    34 StreamInfo::StreamInfo(StreamType stream_type,
    +
    35  int track_id,
    +
    36  uint32_t time_scale,
    +
    37  uint64_t duration,
    +
    38  Codec codec,
    +
    39  const std::string& codec_string,
    +
    40  const uint8_t* codec_config,
    +
    41  size_t codec_config_size,
    +
    42  const std::string& language,
    +
    43  bool is_encrypted)
    +
    44  : stream_type_(stream_type),
    +
    45  track_id_(track_id),
    +
    46  time_scale_(time_scale),
    +
    47  duration_(duration),
    +
    48  codec_(codec),
    +
    49  codec_string_(codec_string),
    +
    50  language_(language),
    +
    51  is_encrypted_(is_encrypted) {
    +
    52  if (codec_config_size > 0) {
    +
    53  codec_config_.assign(codec_config, codec_config + codec_config_size);
    +
    54  }
    +
    55 }
    +
    56 
    +
    57 StreamInfo::~StreamInfo() {}
    +
    58 
    +
    59 std::string StreamInfo::ToString() const {
    +
    60  std::string duration;
    +
    61  if (duration_ == kInfiniteDuration) {
    +
    62  duration = "Infinite";
    +
    63  } else {
    +
    64  duration = base::StringPrintf("%" PRIu64 " (%.1f seconds)", duration_,
    +
    65  static_cast<double>(duration_) / time_scale_);
    +
    66  }
    +
    67 
    +
    68  return base::StringPrintf(
    +
    69  "type: %s\n codec_string: %s\n time_scale: %d\n duration: "
    +
    70  "%s\n is_encrypted: %s\n",
    +
    71  StreamTypeToString(stream_type_).c_str(), codec_string_.c_str(),
    +
    72  time_scale_, duration.c_str(), is_encrypted_ ? "true" : "false");
    +
    73 }
    +
    74 
    +
    75 } // namespace media
    +
    76 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d00/playready__key__source_8h_source.html b/docs/df/d00/playready__key__source_8h_source.html index d65878bdb4..01be5a82c7 100644 --- a/docs/df/d00/playready__key__source_8h_source.html +++ b/docs/df/d00/playready__key__source_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/playready_key_source.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    playready_key_source.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_PLAYREADY_SOURCE_H_
    8 #define PACKAGER_MEDIA_BASE_PLAYREADY_SOURCE_H_
    9 
    10 #include <memory>
    11 #include <string>
    12 #include <vector>
    13 
    14 #include "packager/media/base/key_source.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    20 class PlayReadyKeySource : public KeySource {
    21  public:
    29  PlayReadyKeySource(const std::string& server_url,
    30  int protection_systems_flags,
    31  FourCC protection_scheme);
    43  PlayReadyKeySource(const std::string& server_url,
    44  const std::string& client_cert_file,
    45  const std::string& client_cert_private_key_file,
    46  const std::string& client_cert_private_key_password,
    47  int protection_systems_flags,
    48  FourCC protection_scheme);
    49  ~PlayReadyKeySource() override;
    50 
    53  Status FetchKeys(EmeInitDataType init_data_type,
    54  const std::vector<uint8_t>& init_data) override;
    55  Status GetKey(const std::string& stream_label, EncryptionKey* key) override;
    56  Status GetKey(const std::vector<uint8_t>& key_id,
    57  EncryptionKey* key) override;
    58  Status GetCryptoPeriodKey(uint32_t crypto_period_index,
    59  uint32_t crypto_period_duration_in_seconds,
    60  const std::string& stream_label,
    61  EncryptionKey* key) override;
    63  virtual Status FetchKeysWithProgramIdentifier(const std::string& program_identifier);
    64 
    69  static std::unique_ptr<PlayReadyKeySource> CreateFromKeyAndKeyId(
    70  const std::vector<uint8_t>& key_id,
    71  const std::vector<uint8_t>& key);
    73  void SetCaFile(const std::string& ca_file) {
    74  ca_file_ = ca_file;
    75  }
    76 
    77  private:
    78  Status GetKeyInternal();
    79  Status GetCryptoPeriodKeyInternal();
    80 
    81  // Indicates whether PlayReady protection system should be generated.
    82  bool generate_playready_protection_system_ = true;
    83 
    84  std::unique_ptr<EncryptionKey> encryption_key_;
    85  std::string server_url_;
    86  std::string ca_file_;
    87  std::string client_cert_file_;
    88  std::string client_cert_private_key_file_;
    89  std::string client_cert_private_key_password_;
    90 
    91  DISALLOW_COPY_AND_ASSIGN(PlayReadyKeySource);
    92 };
    93 
    94 } // namespace media
    95 } // namespace shaka
    96 
    97 #endif // PACKAGER_MEDIA_BASE_PLAYREADY_SOURCE_H_
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    -
    static std::unique_ptr< PlayReadyKeySource > CreateFromKeyAndKeyId(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key)
    -
    All the methods that are virtual are virtual for mocking.
    -
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    - -
    A key source that uses PlayReady for encryption.
    - -
    void SetCaFile(const std::string &ca_file)
    Sets the Certificate Authority file for validating self-signed certificates.
    -
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    -
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:48
    -
    PlayReadyKeySource(const std::string &server_url, int protection_systems_flags, FourCC protection_scheme)
    +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_PLAYREADY_SOURCE_H_
    +
    8 #define PACKAGER_MEDIA_BASE_PLAYREADY_SOURCE_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <string>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/media/base/key_source.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    20 class PlayReadyKeySource : public KeySource {
    +
    21  public:
    +
    26  PlayReadyKeySource(const std::string& server_url,
    +
    27  ProtectionSystem protection_systems);
    +
    28  ~PlayReadyKeySource() override;
    +
    29 
    +
    32  Status FetchKeys(EmeInitDataType init_data_type,
    +
    33  const std::vector<uint8_t>& init_data) override;
    +
    34  Status GetKey(const std::string& stream_label, EncryptionKey* key) override;
    +
    35  Status GetKey(const std::vector<uint8_t>& key_id,
    +
    36  EncryptionKey* key) override;
    +
    37  Status GetCryptoPeriodKey(uint32_t crypto_period_index,
    +
    38  uint32_t crypto_period_duration_in_seconds,
    +
    39  const std::string& stream_label,
    +
    40  EncryptionKey* key) override;
    +
    42  virtual Status FetchKeysWithProgramIdentifier(const std::string& program_identifier);
    +
    43 
    +
    48  static std::unique_ptr<PlayReadyKeySource> CreateFromKeyAndKeyId(
    +
    49  const std::vector<uint8_t>& key_id,
    +
    50  const std::vector<uint8_t>& key);
    +
    51 
    +
    52  private:
    +
    53  Status GetKeyInternal();
    +
    54  Status GetCryptoPeriodKeyInternal();
    +
    55 
    +
    56  // Indicates whether PlayReady protection system should be generated.
    +
    57  bool generate_playready_protection_system_ = true;
    +
    58 
    +
    59  std::unique_ptr<EncryptionKey> encryption_key_;
    +
    60  std::string server_url_;
    +
    61 
    +
    62  DISALLOW_COPY_AND_ASSIGN(PlayReadyKeySource);
    +
    63 };
    +
    64 
    +
    65 } // namespace media
    +
    66 } // namespace shaka
    +
    67 
    +
    68 #endif // PACKAGER_MEDIA_BASE_PLAYREADY_SOURCE_H_
    + +
    KeySource is responsible for encryption key acquisition.
    Definition: key_source.h:51
    +
    A key source that uses PlayReady for encryption.
    +
    Status GetKey(const std::string &stream_label, EncryptionKey *key) override
    +
    static std::unique_ptr< PlayReadyKeySource > CreateFromKeyAndKeyId(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key)
    +
    Status FetchKeys(EmeInitDataType init_data_type, const std::vector< uint8_t > &init_data) override
    +
    PlayReadyKeySource(const std::string &server_url, ProtectionSystem protection_systems)
    +
    Status GetCryptoPeriodKey(uint32_t crypto_period_index, uint32_t crypto_period_duration_in_seconds, const std::string &stream_label, EncryptionKey *key) override
    +
    All the methods that are virtual are virtual for mocking.
    +
    ProtectionSystem
    Definition: crypto_params.h:31
    +
    diff --git a/docs/df/d05/vp__codec__configuration__record_8cc_source.html b/docs/df/d05/vp__codec__configuration__record_8cc_source.html index 915124684e..f9ac283fad 100644 --- a/docs/df/d05/vp__codec__configuration__record_8cc_source.html +++ b/docs/df/d05/vp__codec__configuration__record_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/vp_codec_configuration_record.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    vp_codec_configuration_record.cc
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/codecs/vp_codec_configuration_record.h"
    8 
    9 #include "packager/base/strings/string_number_conversions.h"
    10 #include "packager/base/strings/string_util.h"
    11 #include "packager/media/base/bit_reader.h"
    12 #include "packager/media/base/buffer_reader.h"
    13 #include "packager/media/base/buffer_writer.h"
    14 #include "packager/media/base/rcheck.h"
    15 #include "packager/base/strings/stringprintf.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 namespace {
    20 enum VP9CodecFeatures {
    21  kFeatureProfile = 1,
    22  kFeatureLevel = 2,
    23  kFeatureBitDepth = 3,
    24  kFeatureChromaSubsampling = 4,
    25 };
    26 
    27 std::string VPCodecAsString(Codec codec) {
    28  switch (codec) {
    29  case kCodecVP8:
    30  return "vp08";
    31  case kCodecVP9:
    32  return "vp09";
    33  default:
    34  LOG(WARNING) << "Unknown VP codec: " << codec;
    35  return std::string();
    36  }
    37 }
    38 
    39 template <typename T>
    40 void MergeField(const std::string& name,
    41  const base::Optional<T>& source_value,
    42  base::Optional<T>* dest_value) {
    43  if (*dest_value) {
    44  if (source_value && *source_value != **dest_value) {
    45  LOG(WARNING) << "VPx " << name << " is inconsistent, "
    46  << static_cast<int>(**dest_value) << " vs "
    47  << static_cast<int>(*source_value);
    48  }
    49  } else {
    50  // Only set dest_value if it is not set.
    51  *dest_value = source_value;
    52  }
    53 }
    54 
    55 enum VP9Level {
    56  LEVEL_UNKNOWN = 0,
    57  LEVEL_1 = 10,
    58  LEVEL_1_1 = 11,
    59  LEVEL_2 = 20,
    60  LEVEL_2_1 = 21,
    61  LEVEL_3 = 30,
    62  LEVEL_3_1 = 31,
    63  LEVEL_4 = 40,
    64  LEVEL_4_1 = 41,
    65  LEVEL_5 = 50,
    66  LEVEL_5_1 = 51,
    67  LEVEL_5_2 = 52,
    68  LEVEL_6 = 60,
    69  LEVEL_6_1 = 61,
    70  LEVEL_6_2 = 62,
    71  LEVEL_MAX = 255
    72 };
    73 
    74 struct VP9LevelCharacteristics {
    75  uint64_t max_luma_sample_rate;
    76  uint32_t max_luma_picture_size;
    77  double max_avg_bitrate;
    78  double max_cpb_size;
    79  double min_compression_ratio;
    80  uint8_t max_num_column_tiles;
    81  uint32_t min_altref_distance;
    82  uint8_t max_ref_frame_buffers;
    83 };
    84 
    85 struct VP9LevelDefinition {
    86  VP9Level level;
    87  VP9LevelCharacteristics characteristics;
    88 };
    89 
    90 VP9Level LevelFromCharacteristics(uint64_t luma_sample_rate,
    91  uint32_t luma_picture_size) {
    92  // https://www.webmproject.org/vp9/levels/.
    93  const VP9LevelDefinition vp9_level_definitions[] = {
    94  {LEVEL_1, {829440, 36864, 200, 400, 2, 1, 4, 8}},
    95  {LEVEL_1_1, {2764800, 73728, 800, 1000, 2, 1, 4, 8}},
    96  {LEVEL_2, {4608000, 122880, 1800, 1500, 2, 1, 4, 8}},
    97  {LEVEL_2_1, {9216000, 245760, 3600, 2800, 2, 2, 4, 8}},
    98  {LEVEL_3, {20736000, 552960, 7200, 6000, 2, 4, 4, 8}},
    99  {LEVEL_3_1, {36864000, 983040, 12000, 10000, 2, 4, 4, 8}},
    100  {LEVEL_4, {83558400, 2228224, 18000, 16000, 4, 4, 4, 8}},
    101  {LEVEL_4_1, {160432128, 2228224, 30000, 18000, 4, 4, 5, 6}},
    102  {LEVEL_5, {311951360, 8912896, 60000, 36000, 6, 8, 6, 4}},
    103  {LEVEL_5_1, {588251136, 8912896, 120000, 46000, 8, 8, 10, 4}},
    104  {LEVEL_5_2, {1176502272, 8912896, 180000, 90000, 8, 8, 10, 4}},
    105  {LEVEL_6, {1176502272, 35651584, 180000, 90000, 8, 16, 10, 4}},
    106  {LEVEL_6_1, {2353004544u, 35651584, 240000, 180000, 8, 16, 10, 4}},
    107  {LEVEL_6_2, {4706009088u, 35651584, 480000, 360000, 8, 16, 10, 4}},
    108  };
    109 
    110  for (const VP9LevelDefinition& def : vp9_level_definitions) {
    111  // All the characteristic fields except max_luma_sample_rate and
    112  // max_luma_picture_size are ignored to avoid the extra complexities of
    113  // computing those values. It may result in incorrect level being returned.
    114  // If this is a problem, please file a bug to
    115  // https://github.com/google/shaka-packager/issues.
    116  if (luma_sample_rate <= def.characteristics.max_luma_sample_rate &&
    117  luma_picture_size <= def.characteristics.max_luma_picture_size) {
    118  return def.level;
    119  }
    120  }
    121 
    122  LOG(WARNING) << "Cannot determine VP9 level for luma_sample_rate ("
    123  << luma_sample_rate << ") or luma_picture_size ("
    124  << luma_picture_size << "). Returning LEVEL_1.";
    125  return LEVEL_1;
    126 }
    127 
    128 } // namespace
    129 
    130 VPCodecConfigurationRecord::VPCodecConfigurationRecord() {}
    131 
    132 VPCodecConfigurationRecord::VPCodecConfigurationRecord(
    133  uint8_t profile,
    134  uint8_t level,
    135  uint8_t bit_depth,
    136  uint8_t chroma_subsampling,
    137  bool video_full_range_flag,
    138  uint8_t color_primaries,
    139  uint8_t transfer_characteristics,
    140  uint8_t matrix_coefficients,
    141  const std::vector<uint8_t>& codec_initialization_data)
    142  : profile_(profile),
    143  level_(level),
    144  bit_depth_(bit_depth),
    145  chroma_subsampling_(chroma_subsampling),
    146  video_full_range_flag_(video_full_range_flag),
    147  color_primaries_(color_primaries),
    148  transfer_characteristics_(transfer_characteristics),
    149  matrix_coefficients_(matrix_coefficients),
    150  codec_initialization_data_(codec_initialization_data) {}
    151 
    152 VPCodecConfigurationRecord::~VPCodecConfigurationRecord(){};
    153 
    154 // https://www.webmproject.org/vp9/mp4/
    155 bool VPCodecConfigurationRecord::ParseMP4(const std::vector<uint8_t>& data) {
    156  BitReader reader(data.data(), data.size());
    157  uint8_t value;
    158  RCHECK(reader.ReadBits(8, &value));
    159  profile_ = value;
    160  RCHECK(reader.ReadBits(8, &value));
    161  level_ = value;
    162  RCHECK(reader.ReadBits(4, &value));
    163  bit_depth_ = value;
    164  RCHECK(reader.ReadBits(3, &value));
    165  chroma_subsampling_ = value;
    166  bool bool_value;
    167  RCHECK(reader.ReadBits(1, &bool_value));
    168  video_full_range_flag_ = bool_value;
    169  RCHECK(reader.ReadBits(8, &value));
    170  color_primaries_ = value;
    171  RCHECK(reader.ReadBits(8, &value));
    172  transfer_characteristics_ = value;
    173  RCHECK(reader.ReadBits(8, &value));
    174  matrix_coefficients_ = value;
    175 
    176  uint16_t codec_initialization_data_size = 0;
    177  RCHECK(reader.ReadBits(16, &codec_initialization_data_size));
    178  RCHECK(reader.bits_available() >= codec_initialization_data_size * 8u);
    179  const size_t header_size = data.size() - reader.bits_available() / 8;
    180  codec_initialization_data_.assign(
    181  data.begin() + header_size,
    182  data.begin() + header_size + codec_initialization_data_size);
    183  return true;
    184 }
    185 
    186 // http://wiki.webmproject.org/vp9-codecprivate
    187 bool VPCodecConfigurationRecord::ParseWebM(const std::vector<uint8_t>& data) {
    188  BufferReader reader(data.data(), data.size());
    189 
    190  while (reader.HasBytes(1)) {
    191  uint8_t id;
    192  uint8_t size;
    193  RCHECK(reader.Read1(&id));
    194  RCHECK(reader.Read1(&size));
    195 
    196  uint8_t value = 0;
    197  switch (id) {
    198  case kFeatureProfile:
    199  RCHECK(size == 1);
    200  RCHECK(reader.Read1(&value));
    201  profile_ = value;
    202  break;
    203  case kFeatureLevel:
    204  RCHECK(size == 1);
    205  RCHECK(reader.Read1(&value));
    206  level_ = value;
    207  break;
    208  case kFeatureBitDepth:
    209  RCHECK(size == 1);
    210  RCHECK(reader.Read1(&value));
    211  bit_depth_ = value;
    212  break;
    213  case kFeatureChromaSubsampling:
    214  RCHECK(size == 1);
    215  RCHECK(reader.Read1(&value));
    216  chroma_subsampling_ = value;
    217  break;
    218  default: {
    219  LOG(WARNING) << "Skipping unknown VP9 codec feature " << id;
    220  RCHECK(reader.SkipBytes(size));
    221  }
    222  }
    223  }
    224 
    225  return true;
    226 }
    227 
    229  uint16_t height,
    230  double sample_duration_seconds) {
    231  // https://www.webmproject.org/vp9/levels/.
    232 
    233  const uint32_t luma_picture_size = width * height;
    234  // Alt-Ref frames are not taken into consideration intentionally to avoid the
    235  // extra complexities. It may result in smaller luma_sample_rate may than the
    236  // actual luma_sample_rate, leading to incorrect level being returned.
    237  // If this is a problem, please file a bug to
    238  // https://github.com/google/shaka-packager/issues.
    239  const double kUnknownSampleDuration = 0.0;
    240  // The decision is based on luma_picture_size only if duration is unknown.
    241  uint64_t luma_sample_rate = 0;
    242  if (sample_duration_seconds != kUnknownSampleDuration)
    243  luma_sample_rate = luma_picture_size / sample_duration_seconds;
    244 
    245  level_ = LevelFromCharacteristics(luma_sample_rate, luma_picture_size);
    246 }
    247 
    248 void VPCodecConfigurationRecord::WriteMP4(std::vector<uint8_t>* data) const {
    249  BufferWriter writer;
    250  writer.AppendInt(profile());
    251  writer.AppendInt(level());
    252  uint8_t bit_depth_chroma = (bit_depth() << 4) | (chroma_subsampling() << 1) |
    253  (video_full_range_flag() ? 1 : 0);
    254  writer.AppendInt(bit_depth_chroma);
    255  writer.AppendInt(color_primaries());
    256  writer.AppendInt(transfer_characteristics());
    257  writer.AppendInt(matrix_coefficients());
    258  uint16_t codec_initialization_data_size =
    259  static_cast<uint16_t>(codec_initialization_data_.size());
    260  writer.AppendInt(codec_initialization_data_size);
    261  writer.AppendVector(codec_initialization_data_);
    262  writer.SwapBuffer(data);
    263 }
    264 
    265 void VPCodecConfigurationRecord::WriteWebM(std::vector<uint8_t>* data) const {
    266  BufferWriter writer;
    267 
    268  if (profile_) {
    269  writer.AppendInt(static_cast<uint8_t>(kFeatureProfile)); // ID = 1
    270  writer.AppendInt(static_cast<uint8_t>(1)); // Length = 1
    271  writer.AppendInt(*profile_);
    272  }
    273 
    274  if (level_) {
    275  writer.AppendInt(static_cast<uint8_t>(kFeatureLevel)); // ID = 2
    276  writer.AppendInt(static_cast<uint8_t>(1)); // Length = 1
    277  writer.AppendInt(*level_);
    278  }
    279 
    280  if (bit_depth_) {
    281  writer.AppendInt(static_cast<uint8_t>(kFeatureBitDepth)); // ID = 3
    282  writer.AppendInt(static_cast<uint8_t>(1)); // Length = 1
    283  writer.AppendInt(*bit_depth_);
    284  }
    285 
    286  if (chroma_subsampling_) {
    287  // ID = 4, Length = 1
    288  writer.AppendInt(static_cast<uint8_t>(kFeatureChromaSubsampling));
    289  writer.AppendInt(static_cast<uint8_t>(1));
    290  writer.AppendInt(*chroma_subsampling_);
    291  }
    292 
    293  writer.SwapBuffer(data);
    294 }
    295 
    296 std::string VPCodecConfigurationRecord::GetCodecString(Codec codec) const {
    297  const std::string fields[] = {
    298  base::IntToString(profile()),
    299  base::IntToString(level()),
    300  base::IntToString(bit_depth()),
    301  base::IntToString(chroma_subsampling()),
    302  base::IntToString(color_primaries()),
    303  base::IntToString(transfer_characteristics()),
    304  base::IntToString(matrix_coefficients()),
    305  (video_full_range_flag_ && *video_full_range_flag_) ? "01" : "00",
    306  };
    307 
    308  std::string codec_string = VPCodecAsString(codec);
    309  for (const std::string& field : fields) {
    310  // Make sure every field is at least 2-chars wide. The space will be
    311  // replaced with '0' afterwards.
    312  base::StringAppendF(&codec_string, ".%2s", field.c_str());
    313  }
    314  base::ReplaceChars(codec_string, " ", "0", &codec_string);
    315  return codec_string;
    316 }
    317 
    319  const VPCodecConfigurationRecord& other) {
    320  MergeField("profile", other.profile_, &profile_);
    321  MergeField("level", other.level_, &level_);
    322  MergeField("bit depth", other.bit_depth_, &bit_depth_);
    323  MergeField("chroma subsampling", other.chroma_subsampling_,
    324  &chroma_subsampling_);
    325  MergeField("video full range flag", other.video_full_range_flag_,
    326  &video_full_range_flag_);
    327  MergeField("color primaries", other.color_primaries_, &color_primaries_);
    328  MergeField("transfer characteristics", other.transfer_characteristics_,
    329  &transfer_characteristics_);
    330  MergeField("matrix coefficients", other.matrix_coefficients_,
    331  &matrix_coefficients_);
    332 
    333  if (codec_initialization_data_.empty() ||
    334  !other.codec_initialization_data_.empty()) {
    335  if (!codec_initialization_data_.empty() &&
    336  codec_initialization_data_ != other.codec_initialization_data_) {
    337  LOG(WARNING) << "VPx codec initialization data is inconsistent";
    338  }
    339  codec_initialization_data_ = other.codec_initialization_data_;
    340  }
    341 
    342  MergeField("chroma location", other.chroma_location_, &chroma_location_);
    343  UpdateChromaSubsamplingIfNeeded();
    344 }
    345 
    346 void VPCodecConfigurationRecord::SetChromaSubsampling(uint8_t subsampling_x,
    347  uint8_t subsampling_y) {
    348  VLOG(3) << "Set Chroma subsampling " << static_cast<int>(subsampling_x) << " "
    349  << static_cast<int>(subsampling_y);
    350  if (subsampling_x == 0 && subsampling_y == 0) {
    351  chroma_subsampling_ = CHROMA_444;
    352  } else if (subsampling_x == 0 && subsampling_y == 1) {
    353  chroma_subsampling_ = CHROMA_440;
    354  } else if (subsampling_x == 1 && subsampling_y == 0) {
    355  chroma_subsampling_ = CHROMA_422;
    356  } else if (subsampling_x == 1 && subsampling_y == 1) {
    357  // VP9 assumes that chrome samples are collocated with luma samples if
    358  // there is no explicit signaling outside of VP9 bitstream.
    359  chroma_subsampling_ = CHROMA_420_COLLOCATED_WITH_LUMA;
    360  } else {
    361  LOG(WARNING) << "Unexpected chroma subsampling values: "
    362  << static_cast<int>(subsampling_x) << " "
    363  << static_cast<int>(subsampling_y);
    364  }
    365  UpdateChromaSubsamplingIfNeeded();
    366 }
    367 
    368 void VPCodecConfigurationRecord::SetChromaSubsampling(
    369  ChromaSubsampling chroma_subsampling) {
    370  chroma_subsampling_ = chroma_subsampling;
    371  UpdateChromaSubsamplingIfNeeded();
    372 }
    373 
    374 void VPCodecConfigurationRecord::SetChromaLocation(uint8_t chroma_siting_x,
    375  uint8_t chroma_siting_y) {
    376  VLOG(3) << "Set Chroma Location " << static_cast<int>(chroma_siting_x) << " "
    377  << static_cast<int>(chroma_siting_y);
    378  if (chroma_siting_x == kLeftCollocated && chroma_siting_y == kTopCollocated) {
    379  chroma_location_ = AVCHROMA_LOC_TOPLEFT;
    380  } else if (chroma_siting_x == kLeftCollocated && chroma_siting_y == kHalf) {
    381  chroma_location_ = AVCHROMA_LOC_LEFT;
    382  } else if (chroma_siting_x == kHalf && chroma_siting_y == kTopCollocated) {
    383  chroma_location_ = AVCHROMA_LOC_TOP;
    384  } else if (chroma_siting_x == kHalf && chroma_siting_y == kHalf) {
    385  chroma_location_ = AVCHROMA_LOC_CENTER;
    386  } else {
    387  LOG(WARNING) << "Unexpected chroma siting values: "
    388  << static_cast<int>(chroma_siting_x) << " "
    389  << static_cast<int>(chroma_siting_y);
    390  }
    391  UpdateChromaSubsamplingIfNeeded();
    392 }
    393 
    394 void VPCodecConfigurationRecord::UpdateChromaSubsamplingIfNeeded() {
    395  // Use chroma location to fix the chroma subsampling format.
    396  if (chroma_location_ && chroma_subsampling_ &&
    397  (*chroma_subsampling_ == CHROMA_420_VERTICAL ||
    398  *chroma_subsampling_ == CHROMA_420_COLLOCATED_WITH_LUMA)) {
    399  if (*chroma_location_ == AVCHROMA_LOC_TOPLEFT)
    400  chroma_subsampling_ = CHROMA_420_COLLOCATED_WITH_LUMA;
    401  else if (*chroma_location_ == AVCHROMA_LOC_LEFT)
    402  chroma_subsampling_ = CHROMA_420_VERTICAL;
    403  VLOG(3) << "Chroma subsampling " << static_cast<int>(*chroma_subsampling_);
    404  }
    405 }
    406 
    407 } // namespace media
    408 } // namespace shaka
    void WriteWebM(std::vector< uint8_t > *data) const
    -
    Class for parsing or writing VP codec configuration record.
    -
    A class to read bit streams.
    Definition: bit_reader.h:17
    -
    All the methods that are virtual are virtual for mocking.
    - -
    void SetVP9Level(uint16_t width, uint16_t height, double sample_duration_seconds)
    Compute and set VP9 Level based on the input attributes.
    - -
    void WriteMP4(std::vector< uint8_t > *data) const
    - -
    bool ParseMP4(const std::vector< uint8_t > &data)
    -
    void MergeFrom(const VPCodecConfigurationRecord &other)
    - -
    bool ParseWebM(const std::vector< uint8_t > &data)
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/codecs/vp_codec_configuration_record.h"
    +
    8 
    +
    9 #include "packager/base/strings/string_number_conversions.h"
    +
    10 #include "packager/base/strings/string_util.h"
    +
    11 #include "packager/media/base/bit_reader.h"
    +
    12 #include "packager/media/base/buffer_reader.h"
    +
    13 #include "packager/media/base/buffer_writer.h"
    +
    14 #include "packager/media/base/rcheck.h"
    +
    15 #include "packager/base/strings/stringprintf.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 namespace {
    +
    20 enum VP9CodecFeatures {
    +
    21  kFeatureProfile = 1,
    +
    22  kFeatureLevel = 2,
    +
    23  kFeatureBitDepth = 3,
    +
    24  kFeatureChromaSubsampling = 4,
    +
    25 };
    +
    26 
    +
    27 std::string VPCodecAsString(Codec codec) {
    +
    28  switch (codec) {
    +
    29  case kCodecVP8:
    +
    30  return "vp08";
    +
    31  case kCodecVP9:
    +
    32  return "vp09";
    +
    33  default:
    +
    34  LOG(WARNING) << "Unknown VP codec: " << codec;
    +
    35  return std::string();
    +
    36  }
    +
    37 }
    +
    38 
    +
    39 template <typename T>
    +
    40 void MergeField(const std::string& name,
    +
    41  const base::Optional<T>& source_value,
    +
    42  base::Optional<T>* dest_value) {
    +
    43  if (*dest_value) {
    +
    44  if (source_value && *source_value != **dest_value) {
    +
    45  LOG(WARNING) << "VPx " << name << " is inconsistent, "
    +
    46  << static_cast<int>(**dest_value) << " vs "
    +
    47  << static_cast<int>(*source_value);
    +
    48  }
    +
    49  } else {
    +
    50  // Only set dest_value if it is not set.
    +
    51  *dest_value = source_value;
    +
    52  }
    +
    53 }
    +
    54 
    +
    55 enum VP9Level {
    +
    56  LEVEL_UNKNOWN = 0,
    +
    57  LEVEL_1 = 10,
    +
    58  LEVEL_1_1 = 11,
    +
    59  LEVEL_2 = 20,
    +
    60  LEVEL_2_1 = 21,
    +
    61  LEVEL_3 = 30,
    +
    62  LEVEL_3_1 = 31,
    +
    63  LEVEL_4 = 40,
    +
    64  LEVEL_4_1 = 41,
    +
    65  LEVEL_5 = 50,
    +
    66  LEVEL_5_1 = 51,
    +
    67  LEVEL_5_2 = 52,
    +
    68  LEVEL_6 = 60,
    +
    69  LEVEL_6_1 = 61,
    +
    70  LEVEL_6_2 = 62,
    +
    71  LEVEL_MAX = 255
    +
    72 };
    +
    73 
    +
    74 struct VP9LevelCharacteristics {
    +
    75  uint64_t max_luma_sample_rate;
    +
    76  uint32_t max_luma_picture_size;
    +
    77  double max_avg_bitrate;
    +
    78  double max_cpb_size;
    +
    79  double min_compression_ratio;
    +
    80  uint8_t max_num_column_tiles;
    +
    81  uint32_t min_altref_distance;
    +
    82  uint8_t max_ref_frame_buffers;
    +
    83 };
    +
    84 
    +
    85 struct VP9LevelDefinition {
    +
    86  VP9Level level;
    +
    87  VP9LevelCharacteristics characteristics;
    +
    88 };
    +
    89 
    +
    90 VP9Level LevelFromCharacteristics(uint64_t luma_sample_rate,
    +
    91  uint32_t luma_picture_size) {
    +
    92  // https://www.webmproject.org/vp9/levels/.
    +
    93  const VP9LevelDefinition vp9_level_definitions[] = {
    +
    94  {LEVEL_1, {829440, 36864, 200, 400, 2, 1, 4, 8}},
    +
    95  {LEVEL_1_1, {2764800, 73728, 800, 1000, 2, 1, 4, 8}},
    +
    96  {LEVEL_2, {4608000, 122880, 1800, 1500, 2, 1, 4, 8}},
    +
    97  {LEVEL_2_1, {9216000, 245760, 3600, 2800, 2, 2, 4, 8}},
    +
    98  {LEVEL_3, {20736000, 552960, 7200, 6000, 2, 4, 4, 8}},
    +
    99  {LEVEL_3_1, {36864000, 983040, 12000, 10000, 2, 4, 4, 8}},
    +
    100  {LEVEL_4, {83558400, 2228224, 18000, 16000, 4, 4, 4, 8}},
    +
    101  {LEVEL_4_1, {160432128, 2228224, 30000, 18000, 4, 4, 5, 6}},
    +
    102  {LEVEL_5, {311951360, 8912896, 60000, 36000, 6, 8, 6, 4}},
    +
    103  {LEVEL_5_1, {588251136, 8912896, 120000, 46000, 8, 8, 10, 4}},
    +
    104  {LEVEL_5_2, {1176502272, 8912896, 180000, 90000, 8, 8, 10, 4}},
    +
    105  {LEVEL_6, {1176502272, 35651584, 180000, 90000, 8, 16, 10, 4}},
    +
    106  {LEVEL_6_1, {2353004544u, 35651584, 240000, 180000, 8, 16, 10, 4}},
    +
    107  {LEVEL_6_2, {4706009088u, 35651584, 480000, 360000, 8, 16, 10, 4}},
    +
    108  };
    +
    109 
    +
    110  for (const VP9LevelDefinition& def : vp9_level_definitions) {
    +
    111  // All the characteristic fields except max_luma_sample_rate and
    +
    112  // max_luma_picture_size are ignored to avoid the extra complexities of
    +
    113  // computing those values. It may result in incorrect level being returned.
    +
    114  // If this is a problem, please file a bug to
    +
    115  // https://github.com/google/shaka-packager/issues.
    +
    116  if (luma_sample_rate <= def.characteristics.max_luma_sample_rate &&
    +
    117  luma_picture_size <= def.characteristics.max_luma_picture_size) {
    +
    118  return def.level;
    +
    119  }
    +
    120  }
    +
    121 
    +
    122  LOG(WARNING) << "Cannot determine VP9 level for luma_sample_rate ("
    +
    123  << luma_sample_rate << ") or luma_picture_size ("
    +
    124  << luma_picture_size << "). Returning LEVEL_1.";
    +
    125  return LEVEL_1;
    +
    126 }
    +
    127 
    +
    128 } // namespace
    +
    129 
    +
    130 VPCodecConfigurationRecord::VPCodecConfigurationRecord() {}
    +
    131 
    +
    132 VPCodecConfigurationRecord::VPCodecConfigurationRecord(
    +
    133  uint8_t profile,
    +
    134  uint8_t level,
    +
    135  uint8_t bit_depth,
    +
    136  uint8_t chroma_subsampling,
    +
    137  bool video_full_range_flag,
    +
    138  uint8_t color_primaries,
    +
    139  uint8_t transfer_characteristics,
    +
    140  uint8_t matrix_coefficients,
    +
    141  const std::vector<uint8_t>& codec_initialization_data)
    +
    142  : profile_(profile),
    +
    143  level_(level),
    +
    144  bit_depth_(bit_depth),
    +
    145  chroma_subsampling_(chroma_subsampling),
    +
    146  video_full_range_flag_(video_full_range_flag),
    +
    147  color_primaries_(color_primaries),
    +
    148  transfer_characteristics_(transfer_characteristics),
    +
    149  matrix_coefficients_(matrix_coefficients),
    +
    150  codec_initialization_data_(codec_initialization_data) {}
    +
    151 
    +
    152 VPCodecConfigurationRecord::~VPCodecConfigurationRecord(){};
    +
    153 
    +
    154 // https://www.webmproject.org/vp9/mp4/
    +
    155 bool VPCodecConfigurationRecord::ParseMP4(const std::vector<uint8_t>& data) {
    +
    156  BitReader reader(data.data(), data.size());
    +
    157  uint8_t value;
    +
    158  RCHECK(reader.ReadBits(8, &value));
    +
    159  profile_ = value;
    +
    160  RCHECK(reader.ReadBits(8, &value));
    +
    161  level_ = value;
    +
    162  RCHECK(reader.ReadBits(4, &value));
    +
    163  bit_depth_ = value;
    +
    164  RCHECK(reader.ReadBits(3, &value));
    +
    165  chroma_subsampling_ = value;
    +
    166  bool bool_value;
    +
    167  RCHECK(reader.ReadBits(1, &bool_value));
    +
    168  video_full_range_flag_ = bool_value;
    +
    169  RCHECK(reader.ReadBits(8, &value));
    +
    170  color_primaries_ = value;
    +
    171  RCHECK(reader.ReadBits(8, &value));
    +
    172  transfer_characteristics_ = value;
    +
    173  RCHECK(reader.ReadBits(8, &value));
    +
    174  matrix_coefficients_ = value;
    +
    175 
    +
    176  uint16_t codec_initialization_data_size = 0;
    +
    177  RCHECK(reader.ReadBits(16, &codec_initialization_data_size));
    +
    178  RCHECK(reader.bits_available() >= codec_initialization_data_size * 8u);
    +
    179  const size_t header_size = data.size() - reader.bits_available() / 8;
    +
    180  codec_initialization_data_.assign(
    +
    181  data.begin() + header_size,
    +
    182  data.begin() + header_size + codec_initialization_data_size);
    +
    183  return true;
    +
    184 }
    +
    185 
    +
    186 // http://wiki.webmproject.org/vp9-codecprivate
    +
    187 bool VPCodecConfigurationRecord::ParseWebM(const std::vector<uint8_t>& data) {
    +
    188  BufferReader reader(data.data(), data.size());
    +
    189 
    +
    190  while (reader.HasBytes(1)) {
    +
    191  uint8_t id;
    +
    192  uint8_t size;
    +
    193  RCHECK(reader.Read1(&id));
    +
    194  RCHECK(reader.Read1(&size));
    +
    195 
    +
    196  uint8_t value = 0;
    +
    197  switch (id) {
    +
    198  case kFeatureProfile:
    +
    199  RCHECK(size == 1);
    +
    200  RCHECK(reader.Read1(&value));
    +
    201  profile_ = value;
    +
    202  break;
    +
    203  case kFeatureLevel:
    +
    204  RCHECK(size == 1);
    +
    205  RCHECK(reader.Read1(&value));
    +
    206  level_ = value;
    +
    207  break;
    +
    208  case kFeatureBitDepth:
    +
    209  RCHECK(size == 1);
    +
    210  RCHECK(reader.Read1(&value));
    +
    211  bit_depth_ = value;
    +
    212  break;
    +
    213  case kFeatureChromaSubsampling:
    +
    214  RCHECK(size == 1);
    +
    215  RCHECK(reader.Read1(&value));
    +
    216  chroma_subsampling_ = value;
    +
    217  break;
    +
    218  default: {
    +
    219  LOG(WARNING) << "Skipping unknown VP9 codec feature " << id;
    +
    220  RCHECK(reader.SkipBytes(size));
    +
    221  }
    +
    222  }
    +
    223  }
    +
    224 
    +
    225  return true;
    +
    226 }
    +
    227 
    +
    228 void VPCodecConfigurationRecord::SetVP9Level(uint16_t width,
    +
    229  uint16_t height,
    +
    230  double sample_duration_seconds) {
    +
    231  // https://www.webmproject.org/vp9/levels/.
    +
    232 
    +
    233  const uint32_t luma_picture_size = width * height;
    +
    234  // Alt-Ref frames are not taken into consideration intentionally to avoid the
    +
    235  // extra complexities. It may result in smaller luma_sample_rate may than the
    +
    236  // actual luma_sample_rate, leading to incorrect level being returned.
    +
    237  // If this is a problem, please file a bug to
    +
    238  // https://github.com/google/shaka-packager/issues.
    +
    239  const double kUnknownSampleDuration = 0.0;
    +
    240  // The decision is based on luma_picture_size only if duration is unknown.
    +
    241  uint64_t luma_sample_rate = 0;
    +
    242  if (sample_duration_seconds != kUnknownSampleDuration)
    +
    243  luma_sample_rate = luma_picture_size / sample_duration_seconds;
    +
    244 
    +
    245  level_ = LevelFromCharacteristics(luma_sample_rate, luma_picture_size);
    +
    246 }
    +
    247 
    +
    248 void VPCodecConfigurationRecord::WriteMP4(std::vector<uint8_t>* data) const {
    +
    249  BufferWriter writer;
    +
    250  writer.AppendInt(profile());
    +
    251  writer.AppendInt(level());
    +
    252  uint8_t bit_depth_chroma = (bit_depth() << 4) | (chroma_subsampling() << 1) |
    +
    253  (video_full_range_flag() ? 1 : 0);
    +
    254  writer.AppendInt(bit_depth_chroma);
    +
    255  writer.AppendInt(color_primaries());
    +
    256  writer.AppendInt(transfer_characteristics());
    +
    257  writer.AppendInt(matrix_coefficients());
    +
    258  uint16_t codec_initialization_data_size =
    +
    259  static_cast<uint16_t>(codec_initialization_data_.size());
    +
    260  writer.AppendInt(codec_initialization_data_size);
    +
    261  writer.AppendVector(codec_initialization_data_);
    +
    262  writer.SwapBuffer(data);
    +
    263 }
    +
    264 
    +
    265 void VPCodecConfigurationRecord::WriteWebM(std::vector<uint8_t>* data) const {
    +
    266  BufferWriter writer;
    +
    267 
    +
    268  if (profile_) {
    +
    269  writer.AppendInt(static_cast<uint8_t>(kFeatureProfile)); // ID = 1
    +
    270  writer.AppendInt(static_cast<uint8_t>(1)); // Length = 1
    +
    271  writer.AppendInt(*profile_);
    +
    272  }
    +
    273 
    +
    274  if (level_) {
    +
    275  writer.AppendInt(static_cast<uint8_t>(kFeatureLevel)); // ID = 2
    +
    276  writer.AppendInt(static_cast<uint8_t>(1)); // Length = 1
    +
    277  writer.AppendInt(*level_);
    +
    278  }
    +
    279 
    +
    280  if (bit_depth_) {
    +
    281  writer.AppendInt(static_cast<uint8_t>(kFeatureBitDepth)); // ID = 3
    +
    282  writer.AppendInt(static_cast<uint8_t>(1)); // Length = 1
    +
    283  writer.AppendInt(*bit_depth_);
    +
    284  }
    +
    285 
    +
    286  if (chroma_subsampling_) {
    +
    287  // ID = 4, Length = 1
    +
    288  writer.AppendInt(static_cast<uint8_t>(kFeatureChromaSubsampling));
    +
    289  writer.AppendInt(static_cast<uint8_t>(1));
    +
    290  writer.AppendInt(*chroma_subsampling_);
    +
    291  }
    +
    292 
    +
    293  writer.SwapBuffer(data);
    +
    294 }
    +
    295 
    +
    296 std::string VPCodecConfigurationRecord::GetCodecString(Codec codec) const {
    +
    297  const std::string fields[] = {
    +
    298  base::IntToString(profile()),
    +
    299  base::IntToString(level()),
    +
    300  base::IntToString(bit_depth()),
    +
    301  base::IntToString(chroma_subsampling()),
    +
    302  base::IntToString(color_primaries()),
    +
    303  base::IntToString(transfer_characteristics()),
    +
    304  base::IntToString(matrix_coefficients()),
    +
    305  (video_full_range_flag_ && *video_full_range_flag_) ? "01" : "00",
    +
    306  };
    +
    307 
    +
    308  std::string codec_string = VPCodecAsString(codec);
    +
    309  for (const std::string& field : fields) {
    +
    310  // Make sure every field is at least 2-chars wide. The space will be
    +
    311  // replaced with '0' afterwards.
    +
    312  base::StringAppendF(&codec_string, ".%2s", field.c_str());
    +
    313  }
    +
    314  base::ReplaceChars(codec_string, " ", "0", &codec_string);
    +
    315  return codec_string;
    +
    316 }
    +
    317 
    +
    318 void VPCodecConfigurationRecord::MergeFrom(
    +
    319  const VPCodecConfigurationRecord& other) {
    +
    320  MergeField("profile", other.profile_, &profile_);
    +
    321  MergeField("level", other.level_, &level_);
    +
    322  MergeField("bit depth", other.bit_depth_, &bit_depth_);
    +
    323  MergeField("chroma subsampling", other.chroma_subsampling_,
    +
    324  &chroma_subsampling_);
    +
    325  MergeField("video full range flag", other.video_full_range_flag_,
    +
    326  &video_full_range_flag_);
    +
    327  MergeField("color primaries", other.color_primaries_, &color_primaries_);
    +
    328  MergeField("transfer characteristics", other.transfer_characteristics_,
    +
    329  &transfer_characteristics_);
    +
    330  MergeField("matrix coefficients", other.matrix_coefficients_,
    +
    331  &matrix_coefficients_);
    +
    332 
    +
    333  if (codec_initialization_data_.empty() ||
    +
    334  !other.codec_initialization_data_.empty()) {
    +
    335  if (!codec_initialization_data_.empty() &&
    +
    336  codec_initialization_data_ != other.codec_initialization_data_) {
    +
    337  LOG(WARNING) << "VPx codec initialization data is inconsistent";
    +
    338  }
    +
    339  codec_initialization_data_ = other.codec_initialization_data_;
    +
    340  }
    +
    341 
    +
    342  MergeField("chroma location", other.chroma_location_, &chroma_location_);
    +
    343  UpdateChromaSubsamplingIfNeeded();
    +
    344 }
    +
    345 
    +
    346 void VPCodecConfigurationRecord::SetChromaSubsampling(uint8_t subsampling_x,
    +
    347  uint8_t subsampling_y) {
    +
    348  VLOG(3) << "Set Chroma subsampling " << static_cast<int>(subsampling_x) << " "
    +
    349  << static_cast<int>(subsampling_y);
    +
    350  if (subsampling_x == 0 && subsampling_y == 0) {
    +
    351  chroma_subsampling_ = CHROMA_444;
    +
    352  } else if (subsampling_x == 0 && subsampling_y == 1) {
    +
    353  chroma_subsampling_ = CHROMA_440;
    +
    354  } else if (subsampling_x == 1 && subsampling_y == 0) {
    +
    355  chroma_subsampling_ = CHROMA_422;
    +
    356  } else if (subsampling_x == 1 && subsampling_y == 1) {
    +
    357  // VP9 assumes that chrome samples are collocated with luma samples if
    +
    358  // there is no explicit signaling outside of VP9 bitstream.
    +
    359  chroma_subsampling_ = CHROMA_420_COLLOCATED_WITH_LUMA;
    +
    360  } else {
    +
    361  LOG(WARNING) << "Unexpected chroma subsampling values: "
    +
    362  << static_cast<int>(subsampling_x) << " "
    +
    363  << static_cast<int>(subsampling_y);
    +
    364  }
    +
    365  UpdateChromaSubsamplingIfNeeded();
    +
    366 }
    +
    367 
    +
    368 void VPCodecConfigurationRecord::SetChromaSubsampling(
    +
    369  ChromaSubsampling chroma_subsampling) {
    +
    370  chroma_subsampling_ = chroma_subsampling;
    +
    371  UpdateChromaSubsamplingIfNeeded();
    +
    372 }
    +
    373 
    +
    374 void VPCodecConfigurationRecord::SetChromaLocation(uint8_t chroma_siting_x,
    +
    375  uint8_t chroma_siting_y) {
    +
    376  VLOG(3) << "Set Chroma Location " << static_cast<int>(chroma_siting_x) << " "
    +
    377  << static_cast<int>(chroma_siting_y);
    +
    378  if (chroma_siting_x == kLeftCollocated && chroma_siting_y == kTopCollocated) {
    +
    379  chroma_location_ = AVCHROMA_LOC_TOPLEFT;
    +
    380  } else if (chroma_siting_x == kLeftCollocated && chroma_siting_y == kHalf) {
    +
    381  chroma_location_ = AVCHROMA_LOC_LEFT;
    +
    382  } else if (chroma_siting_x == kHalf && chroma_siting_y == kTopCollocated) {
    +
    383  chroma_location_ = AVCHROMA_LOC_TOP;
    +
    384  } else if (chroma_siting_x == kHalf && chroma_siting_y == kHalf) {
    +
    385  chroma_location_ = AVCHROMA_LOC_CENTER;
    +
    386  } else {
    +
    387  LOG(WARNING) << "Unexpected chroma siting values: "
    +
    388  << static_cast<int>(chroma_siting_x) << " "
    +
    389  << static_cast<int>(chroma_siting_y);
    +
    390  }
    +
    391  UpdateChromaSubsamplingIfNeeded();
    +
    392 }
    +
    393 
    +
    394 void VPCodecConfigurationRecord::UpdateChromaSubsamplingIfNeeded() {
    +
    395  // Use chroma location to fix the chroma subsampling format.
    +
    396  if (chroma_location_ && chroma_subsampling_ &&
    +
    397  (*chroma_subsampling_ == CHROMA_420_VERTICAL ||
    +
    398  *chroma_subsampling_ == CHROMA_420_COLLOCATED_WITH_LUMA)) {
    +
    399  if (*chroma_location_ == AVCHROMA_LOC_TOPLEFT)
    +
    400  chroma_subsampling_ = CHROMA_420_COLLOCATED_WITH_LUMA;
    +
    401  else if (*chroma_location_ == AVCHROMA_LOC_LEFT)
    +
    402  chroma_subsampling_ = CHROMA_420_VERTICAL;
    +
    403  VLOG(3) << "Chroma subsampling " << static_cast<int>(*chroma_subsampling_);
    +
    404  }
    +
    405 }
    +
    406 
    +
    407 } // namespace media
    +
    408 } // namespace shaka
    +
    A class to read bit streams.
    Definition: bit_reader.h:17
    +
    size_t bits_available() const
    Definition: bit_reader.h:89
    +
    bool ReadBits(size_t num_bits, T *out)
    Definition: bit_reader.h:35
    + +
    bool HasBytes(size_t count)
    Definition: buffer_reader.h:32
    +
    bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT
    +
    bool Read1(uint8_t *v) WARN_UNUSED_RESULT
    + + +
    Class for parsing or writing VP codec configuration record.
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d0d/classshaka_1_1media_1_1BlockReader.html b/docs/df/d0d/classshaka_1_1media_1_1BlockReader.html index 940a7f8af7..a12a1dd197 100644 --- a/docs/df/d0d/classshaka_1_1media_1_1BlockReader.html +++ b/docs/df/d0d/classshaka_1_1media_1_1BlockReader.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::BlockReader Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Public Member Functions

    -BlockReader (std::unique_ptr< FileReader > source) -  - -bool Next (std::vector< std::string > *out) + +void PushData (const uint8_t *data, size_t data_size) + Pushes data onto the end of the buffer.
    +  +bool Next (std::vector< std::string > *out)   +void Flush () + 

    Detailed Description

    -

    Definition at line 75 of file text_readers.h.

    -

    The documentation for this class was generated from the following files:

    Member Function Documentation

    + +

    ◆ Flush()

    + +
    +
    + + + + + + + +
    void shaka::media::BlockReader::Flush ()
    +
    +

    Indicates that no more data is coming and that calls to Next should return even possibly-incomplete data.

    + +

    Definition at line 103 of file text_readers.cc.

    + +
    +
    + +

    ◆ Next()

    + +
    +
    + + + + + + + + +
    bool shaka::media::BlockReader::Next (std::vector< std::string > * out)
    +
    +

    Reads the next block from the buffer.

    Returns
    True if a block is read, false if there is no block in the buffer.
    + +

    Definition at line 78 of file text_readers.cc.

    + +
    +
    +
    The documentation for this class was generated from the following files: diff --git a/docs/df/d11/playready__pssh__generator_8h_source.html b/docs/df/d11/playready__pssh__generator_8h_source.html index 62acc6506c..d4cf553493 100644 --- a/docs/df/d11/playready__pssh__generator_8h_source.html +++ b/docs/df/d11/playready__pssh__generator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/playready_pssh_generator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    playready_pssh_generator.h
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef MEDIA_BASE_PLAYREADY_PSSH_GENERATOR_H_
    8 #define MEDIA_BASE_PLAYREADY_PSSH_GENERATOR_H_
    9 
    10 #include "packager/media/base/fourccs.h"
    11 #include "packager/media/base/pssh_generator.h"
    12 
    13 namespace shaka {
    14 namespace media {
    15 
    17  public:
    18  explicit PlayReadyPsshGenerator(FourCC protection_scheme);
    19  ~PlayReadyPsshGenerator() override;
    20 
    23  bool SupportMultipleKeys() override;
    25 
    26  private:
    27  PlayReadyPsshGenerator& operator=(const PlayReadyPsshGenerator&) = delete;
    29 
    30  // PsshGenerator implemetation overrides.
    31 
    32  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
    33  const std::vector<std::vector<uint8_t>>& key_ids) const override;
    34 
    35  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
    36  const std::vector<uint8_t>& key_id,
    37  const std::vector<uint8_t>& key) const override;
    38 
    39  FourCC protection_scheme_ = FOURCC_NULL;
    40 };
    41 
    42 } // namespace media
    43 } // namespace shaka
    44 
    45 #endif // MEDIA_BASE_PLAYREADY_PSSH_GENERATOR_H_
    All the methods that are virtual are virtual for mocking.
    - - - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef MEDIA_BASE_PLAYREADY_PSSH_GENERATOR_H_
    +
    8 #define MEDIA_BASE_PLAYREADY_PSSH_GENERATOR_H_
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 #include "packager/media/base/fourccs.h"
    +
    13 #include "packager/media/base/pssh_generator.h"
    +
    14 
    +
    15 namespace shaka {
    +
    16 namespace media {
    +
    17 
    + +
    19  public:
    +
    20  explicit PlayReadyPsshGenerator(const std::string& extra_header_data,
    +
    21  FourCC protection_scheme);
    +
    22  ~PlayReadyPsshGenerator() override;
    +
    23 
    +
    26  bool SupportMultipleKeys() override;
    +
    28 
    +
    29  private:
    +
    30  PlayReadyPsshGenerator& operator=(const PlayReadyPsshGenerator&) = delete;
    + +
    32 
    +
    33  // PsshGenerator implemetation overrides.
    +
    34 
    +
    35  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIds(
    +
    36  const std::vector<std::vector<uint8_t>>& key_ids) const override;
    +
    37 
    +
    38  base::Optional<std::vector<uint8_t>> GeneratePsshDataFromKeyIdAndKey(
    +
    39  const std::vector<uint8_t>& key_id,
    +
    40  const std::vector<uint8_t>& key) const override;
    +
    41 
    +
    42  const std::string extra_header_data_;
    +
    43  const FourCC protection_scheme_;
    +
    44 };
    +
    45 
    +
    46 } // namespace media
    +
    47 } // namespace shaka
    +
    48 
    +
    49 #endif // MEDIA_BASE_PLAYREADY_PSSH_GENERATOR_H_
    + + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d1a/offset__byte__queue_8cc_source.html b/docs/df/d1a/offset__byte__queue_8cc_source.html index e27a80c936..4ee69a99e0 100644 --- a/docs/df/d1a/offset__byte__queue_8cc_source.html +++ b/docs/df/d1a/offset__byte__queue_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/offset_byte_queue.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    offset_byte_queue.cc
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/base/offset_byte_queue.h"
    6 
    7 #include <stdint.h>
    8 
    9 #include "packager/base/logging.h"
    10 
    11 namespace shaka {
    12 namespace media {
    13 
    14 OffsetByteQueue::OffsetByteQueue() : buf_(NULL), size_(0), head_(0) {}
    15 OffsetByteQueue::~OffsetByteQueue() {}
    16 
    17 void OffsetByteQueue::Reset() {
    18  queue_.Reset();
    19  buf_ = NULL;
    20  size_ = 0;
    21  head_ = 0;
    22 }
    23 
    24 void OffsetByteQueue::Push(const uint8_t* buf, int size) {
    25  queue_.Push(buf, size);
    26  Sync();
    27  DVLOG(4) << "Buffer pushed. head=" << head() << " tail=" << tail();
    28 }
    29 
    30 void OffsetByteQueue::Peek(const uint8_t** buf, int* size) {
    31  *buf = size_ > 0 ? buf_ : NULL;
    32  *size = size_;
    33 }
    34 
    35 void OffsetByteQueue::Pop(int count) {
    36  queue_.Pop(count);
    37  head_ += count;
    38  Sync();
    39 }
    40 
    41 void OffsetByteQueue::PeekAt(int64_t offset, const uint8_t** buf, int* size) {
    42  if (offset < head() || offset >= tail()) {
    43  *buf = NULL;
    44  *size = 0;
    45  return;
    46  }
    47  *buf = &buf_[offset - head()];
    48  *size = tail() - offset;
    49 }
    50 
    51 bool OffsetByteQueue::Trim(int64_t max_offset) {
    52  if (max_offset < head_) return true;
    53  if (max_offset > tail()) {
    54  Pop(size_);
    55  return false;
    56  }
    57  Pop(max_offset - head_);
    58  return true;
    59 }
    60 
    61 void OffsetByteQueue::Sync() {
    62  queue_.Peek(&buf_, &size_);
    63 }
    64 
    65 } // namespace media
    66 } // namespace shaka
    void PeekAt(int64_t offset, const uint8_t **buf, int *size)
    -
    bool Trim(int64_t max_offset)
    -
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/base/offset_byte_queue.h"
    +
    6 
    +
    7 #include <stdint.h>
    +
    8 
    +
    9 #include "packager/base/logging.h"
    +
    10 
    +
    11 namespace shaka {
    +
    12 namespace media {
    +
    13 
    +
    14 OffsetByteQueue::OffsetByteQueue() : buf_(NULL), size_(0), head_(0) {}
    +
    15 OffsetByteQueue::~OffsetByteQueue() {}
    +
    16 
    +
    17 void OffsetByteQueue::Reset() {
    +
    18  queue_.Reset();
    +
    19  buf_ = NULL;
    +
    20  size_ = 0;
    +
    21  head_ = 0;
    +
    22 }
    +
    23 
    +
    24 void OffsetByteQueue::Push(const uint8_t* buf, int size) {
    +
    25  queue_.Push(buf, size);
    +
    26  Sync();
    +
    27  DVLOG(4) << "Buffer pushed. head=" << head() << " tail=" << tail();
    +
    28 }
    +
    29 
    +
    30 void OffsetByteQueue::Peek(const uint8_t** buf, int* size) {
    +
    31  *buf = size_ > 0 ? buf_ : NULL;
    +
    32  *size = size_;
    +
    33 }
    +
    34 
    +
    35 void OffsetByteQueue::Pop(int count) {
    +
    36  queue_.Pop(count);
    +
    37  head_ += count;
    +
    38  Sync();
    +
    39 }
    +
    40 
    +
    41 void OffsetByteQueue::PeekAt(int64_t offset, const uint8_t** buf, int* size) {
    +
    42  if (offset < head() || offset >= tail()) {
    +
    43  *buf = NULL;
    +
    44  *size = 0;
    +
    45  return;
    +
    46  }
    +
    47  *buf = &buf_[offset - head()];
    +
    48  *size = tail() - offset;
    +
    49 }
    +
    50 
    +
    51 bool OffsetByteQueue::Trim(int64_t max_offset) {
    +
    52  if (max_offset < head_) return true;
    +
    53  if (max_offset > tail()) {
    +
    54  Pop(size_);
    +
    55  return false;
    +
    56  }
    +
    57  Pop(max_offset - head_);
    +
    58  return true;
    +
    59 }
    +
    60 
    +
    61 void OffsetByteQueue::Sync() {
    +
    62  queue_.Peek(&buf_, &size_);
    +
    63 }
    +
    64 
    +
    65 } // namespace media
    +
    66 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d1c/classshaka_1_1media_1_1MediaSample-members.html b/docs/df/d1c/classshaka_1_1media_1_1MediaSample-members.html index b9f868f737..e4ff6bc617 100644 --- a/docs/df/d1c/classshaka_1_1media_1_1MediaSample-members.html +++ b/docs/df/d1c/classshaka_1_1media_1_1MediaSample-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/df/d1c/composition__offset__iterator_8h_source.html b/docs/df/d1c/composition__offset__iterator_8h_source.html index 487c0d6dce..ab40754165 100644 --- a/docs/df/d1c/composition__offset__iterator_8h_source.html +++ b/docs/df/d1c/composition__offset__iterator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4/composition_offset_iterator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    composition_offset_iterator.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_COMPOSITION_OFFSET_ITERATOR_H_
    8 #define PACKAGER_MEDIA_FORMATS_MP4_COMPOSITION_OFFSET_ITERATOR_H_
    9 
    10 #include <stdint.h>
    11 
    12 #include <vector>
    13 
    14 #include "packager/base/macros.h"
    15 #include "packager/media/formats/mp4/box_definitions.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 namespace mp4 {
    20 
    25  public:
    28  const CompositionTimeToSample& composition_time_to_sample);
    30 
    33  bool AdvanceSample();
    34 
    37  bool IsValid() const;
    38 
    40  int64_t sample_offset() const { return iterator_->sample_offset; }
    41 
    43  int64_t SampleOffset(uint32_t sample) const;
    44 
    46  uint32_t NumSamples() const;
    47 
    48  private:
    49  uint32_t sample_index_;
    50  const std::vector<CompositionOffset>& composition_offset_table_;
    51  std::vector<CompositionOffset>::const_iterator iterator_;
    52 
    53  DISALLOW_COPY_AND_ASSIGN(CompositionOffsetIterator);
    54 };
    55 
    56 } // namespace mp4
    57 } // namespace media
    58 } // namespace shaka
    59 
    60 #endif // PACKAGER_MEDIA_FORMATS_MP4_COMPOSITION_OFFSET_ITERATOR_H_
    - -
    All the methods that are virtual are virtual for mocking.
    - - -
    CompositionOffsetIterator(const CompositionTimeToSample &composition_time_to_sample)
    Create CompositionOffsetIterator from composition time to sample box.
    - - - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP4_COMPOSITION_OFFSET_ITERATOR_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP4_COMPOSITION_OFFSET_ITERATOR_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/macros.h"
    +
    15 #include "packager/media/formats/mp4/box_definitions.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 namespace mp4 {
    +
    20 
    + +
    25  public:
    + +
    28  const CompositionTimeToSample& composition_time_to_sample);
    + +
    30 
    +
    33  bool AdvanceSample();
    +
    34 
    +
    37  bool IsValid() const;
    +
    38 
    +
    40  int64_t sample_offset() const { return iterator_->sample_offset; }
    +
    41 
    +
    43  int64_t SampleOffset(uint32_t sample) const;
    +
    44 
    +
    46  uint32_t NumSamples() const;
    +
    47 
    +
    48  private:
    +
    49  uint32_t sample_index_;
    +
    50  const std::vector<CompositionOffset>& composition_offset_table_;
    +
    51  std::vector<CompositionOffset>::const_iterator iterator_;
    +
    52 
    +
    53  DISALLOW_COPY_AND_ASSIGN(CompositionOffsetIterator);
    +
    54 };
    +
    55 
    +
    56 } // namespace mp4
    +
    57 } // namespace media
    +
    58 } // namespace shaka
    +
    59 
    +
    60 #endif // PACKAGER_MEDIA_FORMATS_MP4_COMPOSITION_OFFSET_ITERATOR_H_
    + + +
    CompositionOffsetIterator(const CompositionTimeToSample &composition_time_to_sample)
    Create CompositionOffsetIterator from composition time to sample box.
    + + + + +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/df/d1d/ac3__audio__util_8h_source.html b/docs/df/d1d/ac3__audio__util_8h_source.html index 0e11001442..a63464be6f 100644 --- a/docs/df/d1d/ac3__audio__util_8h_source.html +++ b/docs/df/d1d/ac3__audio__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/ac3_audio_util.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    ac3_audio_util.h
    -
    1 // Copyright 2018 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // AC3 audio utility functions.
    8 
    9 #ifndef PACKAGER_MEDIA_CODECS_AC3_AUDIO_UTIL_H_
    10 #define PACKAGER_MEDIA_CODECS_AC3_AUDIO_UTIL_H_
    11 
    12 #include <stddef.h>
    13 #include <stdint.h>
    14 #include <vector>
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    22 size_t GetAc3NumChannels(const std::vector<uint8_t>& ac3_data);
    23 
    24 } // namespace media
    25 } // namespace shaka
    26 
    27 #endif // PACKAGER_MEDIA_CODECS_AC3_AUDIO_UTIL_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2018 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // AC3 audio utility functions.
    +
    8 
    +
    9 #ifndef PACKAGER_MEDIA_CODECS_AC3_AUDIO_UTIL_H_
    +
    10 #define PACKAGER_MEDIA_CODECS_AC3_AUDIO_UTIL_H_
    +
    11 
    +
    12 #include <stddef.h>
    +
    13 #include <stdint.h>
    +
    14 #include <vector>
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    22 size_t GetAc3NumChannels(const std::vector<uint8_t>& ac3_data);
    +
    23 
    +
    24 } // namespace media
    +
    25 } // namespace shaka
    +
    26 
    +
    27 #endif // PACKAGER_MEDIA_CODECS_AC3_AUDIO_UTIL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d21/classshaka_1_1media_1_1SegmentTestBase_1_1ClusterParser-members.html b/docs/df/d21/classshaka_1_1media_1_1SegmentTestBase_1_1ClusterParser-members.html index 18f7ad8722..e9cc8bbe52 100644 --- a/docs/df/d21/classshaka_1_1media_1_1SegmentTestBase_1_1ClusterParser-members.html +++ b/docs/df/d21/classshaka_1_1media_1_1SegmentTestBase_1_1ClusterParser-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    cluster_count() const (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser ClusterParser() (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser - DISALLOW_COPY_AND_ASSIGN(WebMParserClient) (defined in shaka::media::WebMParserClient)shaka::media::WebMParserClientprivate - GetFrameCountForCluster(size_t cluster_index) const (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser - GetFrameTimecode(size_t cluster_index, size_t frame_index) const (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser - PopulateFromCluster(const std::string &file_name) (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser - PopulateFromSegment(const std::string &file_name) (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser - WebMParserClient() (defined in shaka::media::WebMParserClient)shaka::media::WebMParserClientprivate + GetFrameCountForCluster(size_t cluster_index) const (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser + GetFrameTimecode(size_t cluster_index, size_t frame_index) const (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser + PopulateFromCluster(const std::string &file_name) (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser + PopulateFromSegment(const std::string &file_name) (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser ~ClusterParser() override (defined in shaka::media::SegmentTestBase::ClusterParser)shaka::media::SegmentTestBase::ClusterParser - ~WebMParserClient() (defined in shaka::media::WebMParserClient)shaka::media::WebMParserClientprivatevirtual
    diff --git a/docs/df/d22/structshaka_1_1WidevineSigner.html b/docs/df/d22/structshaka_1_1WidevineSigner.html index 38fa8ac00a..d654732be8 100644 --- a/docs/df/d22/structshaka_1_1WidevineSigner.html +++ b/docs/df/d22/structshaka_1_1WidevineSigner.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::WidevineSigner Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

    Public Types

    -enum  SigningKeyType { kNone, -kAes, -kRsa +enum class  SigningKeyType { kNone +, kAes +, kRsa }   @@ -92,7 +95,7 @@ std::string  - @@ -102,21 +105,21 @@ struct {    std::vector< uint8_t >   iv - - - + + - - + +
     
    SigningKeyType signing_key_type = SigningKeyType::kNone
     
    +
    struct {
       std::vector< uint8_t >   key
     AES signing IV.
     
    aes
     
    +
    aes
     
    struct {
       std::string   key
     RSA signing private key.
     
    rsa
     
    rsa
     

    Detailed Description

    Signer credential for Widevine license server.

    -

    Definition at line 26 of file crypto_params.h.

    +

    Definition at line 63 of file crypto_params.h.

    Member Data Documentation

    ◆ signing_key_type

    @@ -131,7 +134,7 @@ struct {

    Specifies the signing key type, which determines whether AES or RSA key are used to authenticate the signer. A type of 'kNone' is invalid.

    -

    Definition at line 37 of file crypto_params.h.

    +

    Definition at line 74 of file crypto_params.h.

    @@ -141,9 +144,7 @@ struct { diff --git a/docs/df/d22/validate__flag_8h_source.html b/docs/df/d22/validate__flag_8h_source.html index fd645fa203..8fb8ec9236 100644 --- a/docs/df/d22/validate__flag_8h_source.html +++ b/docs/df/d22/validate__flag_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/validate_flag.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    validate_flag.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Flag validation help functions.
    8 
    9 #ifndef APP_VALIDATE_FLAG_H_
    10 #define APP_VALIDATE_FLAG_H_
    11 
    12 #include <string>
    13 
    14 #include "packager/base/strings/stringprintf.h"
    15 
    16 namespace shaka {
    17 
    20 void PrintError(const std::string& error_message);
    21 
    24 void PrintWarning(const std::string& warning_message);
    25 
    31 // and cannot be empty; If condition is false, then this flag should
    32 // not be set.
    36 template <class FlagType>
    37 bool ValidateFlag(const char* flag_name,
    38  const FlagType& flag_value,
    39  bool condition,
    40  bool optional,
    41  const char* label) {
    42  if (flag_value.empty()) {
    43  if (!optional && condition) {
    44  PrintError(
    45  base::StringPrintf("--%s is required if %s.", flag_name, label));
    46  return false;
    47  }
    48  } else if (!condition) {
    49  PrintError(base::StringPrintf(
    50  "--%s should be specified only if %s.", flag_name, label));
    51  return false;
    52  }
    53  return true;
    54 }
    55 
    56 } // namespace shaka
    57 
    58 #endif // APP_VALIDATE_FLAG_H_
    void PrintError(const std::string &error_message)
    -
    bool ValidateFlag(const char *flag_name, const FlagType &flag_value, bool condition, bool optional, const char *label)
    Definition: validate_flag.h:37
    -
    All the methods that are virtual are virtual for mocking.
    -
    void PrintWarning(const std::string &warning_message)
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Flag validation help functions.
    +
    8 
    +
    9 #ifndef APP_VALIDATE_FLAG_H_
    +
    10 #define APP_VALIDATE_FLAG_H_
    +
    11 
    +
    12 #include <string>
    +
    13 
    +
    14 #include "packager/base/strings/stringprintf.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 
    +
    20 void PrintError(const std::string& error_message);
    +
    21 
    +
    24 void PrintWarning(const std::string& warning_message);
    +
    25 
    +
    31 // and cannot be empty; If condition is false, then this flag should
    +
    32 // not be set.
    +
    36 template <class FlagType>
    +
    37 bool ValidateFlag(const char* flag_name,
    +
    38  const FlagType& flag_value,
    +
    39  bool condition,
    +
    40  bool optional,
    +
    41  const char* label) {
    +
    42  if (flag_value.empty()) {
    +
    43  if (!optional && condition) {
    +
    44  PrintError(
    +
    45  base::StringPrintf("--%s is required if %s.", flag_name, label));
    +
    46  return false;
    +
    47  }
    +
    48  } else if (!condition) {
    +
    49  PrintError(base::StringPrintf(
    +
    50  "--%s should be specified only if %s.", flag_name, label));
    +
    51  return false;
    +
    52  }
    +
    53  return true;
    +
    54 }
    +
    55 
    +
    56 } // namespace shaka
    +
    57 
    +
    58 #endif // APP_VALIDATE_FLAG_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    void PrintWarning(const std::string &warning_message)
    +
    void PrintError(const std::string &error_message)
    +
    bool ValidateFlag(const char *flag_name, const FlagType &flag_value, bool condition, bool optional, const char *label)
    Definition: validate_flag.h:37
    diff --git a/docs/df/d2a/classshaka_1_1media_1_1mp4_1_1DecodingTimeIterator-members.html b/docs/df/d2a/classshaka_1_1media_1_1mp4_1_1DecodingTimeIterator-members.html index fc273b7d41..67d7ccccdc 100644 --- a/docs/df/d2a/classshaka_1_1media_1_1mp4_1_1DecodingTimeIterator-members.html +++ b/docs/df/d2a/classshaka_1_1media_1_1mp4_1_1DecodingTimeIterator-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/df/d2b/pssh__generator_8cc_source.html b/docs/df/d2b/pssh__generator_8cc_source.html index 25a9ae86fd..2164603148 100644 --- a/docs/df/d2b/pssh__generator_8cc_source.html +++ b/docs/df/d2b/pssh__generator_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/pssh_generator.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    pssh_generator.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/pssh_generator.h"
    8 
    9 namespace shaka {
    10 namespace media {
    11 namespace {
    12 
    13 std::vector<uint8_t> CreatePsshBox(
    14  const std::vector<uint8_t>& system_id,
    15  uint8_t version,
    16  const std::vector<std::vector<uint8_t>>& key_ids,
    17  const std::vector<uint8_t>& pssh_data) {
    18  PsshBoxBuilder pssh_builder;
    19  pssh_builder.set_pssh_data(pssh_data);
    20  for (const std::vector<uint8_t>& key_id : key_ids) {
    21  pssh_builder.add_key_id(key_id);
    22  }
    23  pssh_builder.set_pssh_box_version(version);
    24  pssh_builder.set_system_id(system_id.data(), system_id.size());
    25 
    26  return pssh_builder.CreateBox();
    27 }
    28 
    29 } // namespace
    30 
    31 PsshGenerator::PsshGenerator(const std::vector<uint8_t>& system_id,
    32  uint8_t box_version)
    33  : system_id_(system_id), box_version_(box_version) {}
    34 
    35 PsshGenerator::~PsshGenerator() = default;
    36 
    38  const std::vector<std::vector<uint8_t>>& key_ids,
    39  ProtectionSystemSpecificInfo* info) const {
    40  base::Optional<std::vector<uint8_t>> pssh_data =
    41  GeneratePsshDataFromKeyIds(key_ids);
    42  if (!pssh_data) {
    43  return Status(error::ENCRYPTION_FAILURE,
    44  "Fail to generate PSSH data from multiple Key IDs.");
    45  }
    46  info->system_id = system_id_;
    47  info->psshs =
    48  CreatePsshBox(system_id_, box_version_, key_ids, pssh_data.value());
    49  return Status::OK;
    50 }
    51 
    53  const std::vector<uint8_t>& key_id,
    54  const std::vector<uint8_t>& key,
    55  ProtectionSystemSpecificInfo* info) const {
    56  base::Optional<std::vector<uint8_t>> pssh_data =
    57  GeneratePsshDataFromKeyIdAndKey(key_id, key);
    58  if (!pssh_data) {
    59  return Status(error::ENCRYPTION_FAILURE,
    60  "Fail to generate PSSH data from Key ID and Key.");
    61  }
    62  info->system_id = system_id_;
    63  info->psshs =
    64  CreatePsshBox(system_id_, box_version_, {key_id}, pssh_data.value());
    65  return Status::OK;
    66 }
    67 
    68 } // namespace media
    69 } // namespace shaka
    PsshGenerator(const std::vector< uint8_t > &system_id, uint8_t box_version)
    -
    Status GeneratePsshFromKeyIds(const std::vector< std::vector< uint8_t >> &key_ids, ProtectionSystemSpecificInfo *info) const
    -
    All the methods that are virtual are virtual for mocking.
    - -
    Status GeneratePsshFromKeyIdAndKey(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key, ProtectionSystemSpecificInfo *info) const
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/pssh_generator.h"
    +
    8 
    +
    9 namespace shaka {
    +
    10 namespace media {
    +
    11 namespace {
    +
    12 
    +
    13 std::vector<uint8_t> CreatePsshBox(
    +
    14  const std::vector<uint8_t>& system_id,
    +
    15  uint8_t version,
    +
    16  const std::vector<std::vector<uint8_t>>& key_ids,
    +
    17  const std::vector<uint8_t>& pssh_data) {
    +
    18  PsshBoxBuilder pssh_builder;
    +
    19  pssh_builder.set_pssh_data(pssh_data);
    +
    20  for (const std::vector<uint8_t>& key_id : key_ids) {
    +
    21  pssh_builder.add_key_id(key_id);
    +
    22  }
    +
    23  pssh_builder.set_pssh_box_version(version);
    +
    24  pssh_builder.set_system_id(system_id.data(), system_id.size());
    +
    25 
    +
    26  return pssh_builder.CreateBox();
    +
    27 }
    +
    28 
    +
    29 } // namespace
    +
    30 
    +
    31 PsshGenerator::PsshGenerator(const std::vector<uint8_t>& system_id,
    +
    32  uint8_t box_version)
    +
    33  : system_id_(system_id), box_version_(box_version) {}
    +
    34 
    +
    35 PsshGenerator::~PsshGenerator() = default;
    +
    36 
    + +
    38  const std::vector<std::vector<uint8_t>>& key_ids,
    +
    39  ProtectionSystemSpecificInfo* info) const {
    +
    40  base::Optional<std::vector<uint8_t>> pssh_data =
    +
    41  GeneratePsshDataFromKeyIds(key_ids);
    +
    42  if (!pssh_data) {
    +
    43  return Status(error::ENCRYPTION_FAILURE,
    +
    44  "Fail to generate PSSH data from multiple Key IDs.");
    +
    45  }
    +
    46  info->system_id = system_id_;
    +
    47  info->psshs =
    +
    48  CreatePsshBox(system_id_, box_version_, key_ids, pssh_data.value());
    +
    49  return Status::OK;
    +
    50 }
    +
    51 
    + +
    53  const std::vector<uint8_t>& key_id,
    +
    54  const std::vector<uint8_t>& key,
    +
    55  ProtectionSystemSpecificInfo* info) const {
    +
    56  base::Optional<std::vector<uint8_t>> pssh_data =
    +
    57  GeneratePsshDataFromKeyIdAndKey(key_id, key);
    +
    58  if (!pssh_data) {
    +
    59  return Status(error::ENCRYPTION_FAILURE,
    +
    60  "Fail to generate PSSH data from Key ID and Key.");
    +
    61  }
    +
    62  info->system_id = system_id_;
    +
    63  info->psshs =
    +
    64  CreatePsshBox(system_id_, box_version_, {key_id}, pssh_data.value());
    +
    65  return Status::OK;
    +
    66 }
    +
    67 
    +
    68 } // namespace media
    +
    69 } // namespace shaka
    + +
    Status GeneratePsshFromKeyIds(const std::vector< std::vector< uint8_t >> &key_ids, ProtectionSystemSpecificInfo *info) const
    +
    PsshGenerator(const std::vector< uint8_t > &system_id, uint8_t box_version)
    +
    Status GeneratePsshFromKeyIdAndKey(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key, ProtectionSystemSpecificInfo *info) const
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/df/d2d/classshaka_1_1media_1_1AesCbcDecryptor.html b/docs/df/d2d/classshaka_1_1media_1_1AesCbcDecryptor.html index 33499a12f4..013e0246e2 100644 --- a/docs/df/d2d/classshaka_1_1media_1_1AesCbcDecryptor.html +++ b/docs/df/d2d/classshaka_1_1media_1_1AesCbcDecryptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AesCbcDecryptor Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::AesCryptor - -
    + + @@ -119,8 +122,8 @@ bool  - @@ -162,7 +165,7 @@ AES_KEY * 

    Public Member Functions

    Crypt (const uint

    Additional Inherited Members

    - Public Types inherited from shaka::media::AesCryptor
    enum  ConstantIvFlag { kUseConstantIv, -kDontUseConstantIv +
    enum  ConstantIvFlag { kUseConstantIv +, kDontUseConstantIv }
     
    - Static Public Member Functions inherited from shaka::media::AesCryptor
    mutable_aes_key<
    -

    Creates a AesCbcDecryptor with continous cipher block chain across Crypt calls.

    Parameters
    +

    Creates a AesCbcDecryptor with continous cipher block chain across Crypt calls.

    Parameters
    padding_schemeindicates the padding scheme used. Currently supported schemes: kNoPadding, kPkcs5Padding, kCtsPadding.
    @@ -259,9 +262,7 @@ AES_KEY * mutable_aes_key<
    diff --git a/docs/df/d31/muxer__util_8cc_source.html b/docs/df/d31/muxer__util_8cc_source.html index 4fb49edb47..072c4a530d 100644 --- a/docs/df/d31/muxer__util_8cc_source.html +++ b/docs/df/d31/muxer__util_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/muxer_util.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    muxer_util.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/media/base/muxer_util.h"
    8 
    9 #include <inttypes.h>
    10 
    11 #include <string>
    12 #include <vector>
    13 
    14 #include "packager/base/logging.h"
    15 #include "packager/base/strings/string_number_conversions.h"
    16 #include "packager/base/strings/string_split.h"
    17 #include "packager/base/strings/stringprintf.h"
    18 #include "packager/media/base/video_stream_info.h"
    19 
    20 namespace shaka {
    21 namespace {
    22 Status ValidateFormatTag(const std::string& format_tag) {
    23  if (format_tag.empty()) {
    24  return Status(error::INVALID_ARGUMENT, "Format tag should not be empty");
    25  }
    26 
    27  // Format tag should follow this prototype: %0[width]d.
    28  if (format_tag.size() > 3 && format_tag[0] == '%' && format_tag[1] == '0' &&
    29  format_tag[format_tag.size() - 1] == 'd') {
    30  unsigned out;
    31  if (base::StringToUint(format_tag.substr(2, format_tag.size() - 3), &out)) {
    32  return Status::OK;
    33  }
    34  }
    35 
    36  return Status(
    37  error::INVALID_ARGUMENT,
    38  "Format tag should follow this prototype: %0[width]d if exist.");
    39 }
    40 } // namespace
    41 
    42 namespace media {
    43 
    44 Status ValidateSegmentTemplate(const std::string& segment_template) {
    45  if (segment_template.empty()) {
    46  return Status(error::INVALID_ARGUMENT,
    47  "Segment template should not be empty.");
    48  }
    49 
    50  std::vector<std::string> splits = base::SplitString(
    51  segment_template, "$", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    52 
    53  // ISO/IEC 23009-1:2012 5.3.9.4.4 Template-based Segment URL construction.
    54  // Allowed identifiers: $$, $RepresentationID$, $Number$, $Bandwidth$, $Time$.
    55  // "$" always appears in pairs, so there should be odd number of splits.
    56  if (splits.size() % 2 == 0) {
    57  return Status(error::INVALID_ARGUMENT,
    58  "In segment templates, '$' should appear in pairs.");
    59  }
    60 
    61  bool has_number = false;
    62  bool has_time = false;
    63  // Every second substring in split output should be an identifier.
    64  for (size_t i = 1; i < splits.size(); i += 2) {
    65  // Each identifier may be suffixed, within the enclosing ‘$’ characters,
    66  // with an additional format tag aligned with the printf format tag as
    67  // defined in IEEE 1003.1-2008 [10] following this prototype: %0[width]d.
    68  size_t format_pos = splits[i].find('%');
    69  std::string identifier = splits[i].substr(0, format_pos);
    70  if (format_pos != std::string::npos) {
    71  Status tag_check = ValidateFormatTag(splits[i].substr(format_pos));
    72  if (!tag_check.ok()) {
    73  return tag_check;
    74  }
    75  }
    76 
    77  // TODO(kqyang): Support "RepresentationID".
    78  if (identifier == "RepresentationID") {
    79  return Status(
    80  error::UNIMPLEMENTED,
    81  "Segment template flag $RepresentationID$ is not supported yet.");
    82  } else if (identifier == "Number") {
    83  has_number = true;
    84  } else if (identifier == "Time") {
    85  has_time = true;
    86  } else if (identifier == "") {
    87  if (format_pos != std::string::npos) {
    88  return Status(error::INVALID_ARGUMENT,
    89  "'$$' should not have any format tags.");
    90  }
    91  } else if (identifier != "Bandwidth") {
    92  return Status(error::INVALID_ARGUMENT,
    93  "'$" + splits[i] + "$' is not a valid identifier.");
    94  }
    95  }
    96  if (has_number && has_time) {
    97  return Status(
    98  error::INVALID_ARGUMENT,
    99  "In segment templates $Number$ and $Time$ should not co-exist.");
    100  }
    101  if (!has_number && !has_time) {
    102  return Status(error::INVALID_ARGUMENT,
    103  "In segment templates $Number$ or $Time$ should exist.");
    104  }
    105  // Note: The below check is skipped.
    106  // Strings outside identifiers shall only contain characters that are
    107  // permitted within URLs according to RFC 1738.
    108  return Status::OK;
    109 }
    110 
    111 std::string GetSegmentName(const std::string& segment_template,
    112  uint64_t segment_start_time,
    113  uint32_t segment_index,
    114  uint32_t bandwidth) {
    115  DCHECK_EQ(Status::OK, ValidateSegmentTemplate(segment_template));
    116 
    117  std::vector<std::string> splits = base::SplitString(
    118  segment_template, "$", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    119  // "$" always appears in pairs, so there should be odd number of splits.
    120  DCHECK_EQ(1u, splits.size() % 2);
    121 
    122  std::string segment_name;
    123  for (size_t i = 0; i < splits.size(); ++i) {
    124  // Every second substring in split output should be an identifier.
    125  // Simply copy the non-identifier part.
    126  if (i % 2 == 0) {
    127  segment_name += splits[i];
    128  continue;
    129  }
    130  if (splits[i].empty()) {
    131  // "$$" is an escape sequence, replaced with a single "$".
    132  segment_name += "$";
    133  continue;
    134  }
    135  size_t format_pos = splits[i].find('%');
    136  std::string identifier = splits[i].substr(0, format_pos);
    137  DCHECK(identifier == "Number" || identifier == "Time" ||
    138  identifier == "Bandwidth");
    139 
    140  std::string format_tag;
    141  if (format_pos != std::string::npos) {
    142  format_tag = splits[i].substr(format_pos);
    143  DCHECK_EQ(Status::OK, ValidateFormatTag(format_tag));
    144  // Replace %d formatting to correctly format uint64_t.
    145  format_tag = format_tag.substr(0, format_tag.size() - 1) + PRIu64;
    146  } else {
    147  // Default format tag "%01d", modified to format uint64_t correctly.
    148  format_tag = "%01" PRIu64;
    149  }
    150 
    151  if (identifier == "Number") {
    152  // SegmentNumber starts from 1.
    153  segment_name += base::StringPrintf(
    154  format_tag.c_str(), static_cast<uint64_t>(segment_index + 1));
    155  } else if (identifier == "Time") {
    156  segment_name +=
    157  base::StringPrintf(format_tag.c_str(), segment_start_time);
    158  } else if (identifier == "Bandwidth") {
    159  segment_name += base::StringPrintf(format_tag.c_str(),
    160  static_cast<uint64_t>(bandwidth));
    161  }
    162  }
    163  return segment_name;
    164 }
    165 
    166 } // namespace media
    167 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/media/base/muxer_util.h"
    +
    8 
    +
    9 #include <inttypes.h>
    +
    10 
    +
    11 #include <string>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/logging.h"
    +
    15 #include "packager/base/strings/string_number_conversions.h"
    +
    16 #include "packager/base/strings/string_split.h"
    +
    17 #include "packager/base/strings/stringprintf.h"
    +
    18 #include "packager/media/base/video_stream_info.h"
    +
    19 
    +
    20 namespace shaka {
    +
    21 namespace {
    +
    22 Status ValidateFormatTag(const std::string& format_tag) {
    +
    23  if (format_tag.empty()) {
    +
    24  return Status(error::INVALID_ARGUMENT, "Format tag should not be empty");
    +
    25  }
    +
    26 
    +
    27  // Format tag should follow this prototype: %0[width]d.
    +
    28  if (format_tag.size() > 3 && format_tag[0] == '%' && format_tag[1] == '0' &&
    +
    29  format_tag[format_tag.size() - 1] == 'd') {
    +
    30  unsigned out;
    +
    31  if (base::StringToUint(format_tag.substr(2, format_tag.size() - 3), &out)) {
    +
    32  return Status::OK;
    +
    33  }
    +
    34  }
    +
    35 
    +
    36  return Status(
    +
    37  error::INVALID_ARGUMENT,
    +
    38  "Format tag should follow this prototype: %0[width]d if exist.");
    +
    39 }
    +
    40 } // namespace
    +
    41 
    +
    42 namespace media {
    +
    43 
    +
    44 Status ValidateSegmentTemplate(const std::string& segment_template) {
    +
    45  if (segment_template.empty()) {
    +
    46  return Status(error::INVALID_ARGUMENT,
    +
    47  "Segment template should not be empty.");
    +
    48  }
    +
    49 
    +
    50  std::vector<std::string> splits = base::SplitString(
    +
    51  segment_template, "$", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    +
    52 
    +
    53  // ISO/IEC 23009-1:2012 5.3.9.4.4 Template-based Segment URL construction.
    +
    54  // Allowed identifiers: $$, $RepresentationID$, $Number$, $Bandwidth$, $Time$.
    +
    55  // "$" always appears in pairs, so there should be odd number of splits.
    +
    56  if (splits.size() % 2 == 0) {
    +
    57  return Status(error::INVALID_ARGUMENT,
    +
    58  "In segment templates, '$' should appear in pairs.");
    +
    59  }
    +
    60 
    +
    61  bool has_number = false;
    +
    62  bool has_time = false;
    +
    63  // Every second substring in split output should be an identifier.
    +
    64  for (size_t i = 1; i < splits.size(); i += 2) {
    +
    65  // Each identifier may be suffixed, within the enclosing ‘$’ characters,
    +
    66  // with an additional format tag aligned with the printf format tag as
    +
    67  // defined in IEEE 1003.1-2008 [10] following this prototype: %0[width]d.
    +
    68  size_t format_pos = splits[i].find('%');
    +
    69  std::string identifier = splits[i].substr(0, format_pos);
    +
    70  if (format_pos != std::string::npos) {
    +
    71  Status tag_check = ValidateFormatTag(splits[i].substr(format_pos));
    +
    72  if (!tag_check.ok()) {
    +
    73  return tag_check;
    +
    74  }
    +
    75  }
    +
    76 
    +
    77  // TODO(kqyang): Support "RepresentationID".
    +
    78  if (identifier == "RepresentationID") {
    +
    79  return Status(
    +
    80  error::UNIMPLEMENTED,
    +
    81  "Segment template flag $RepresentationID$ is not supported yet.");
    +
    82  } else if (identifier == "Number") {
    +
    83  has_number = true;
    +
    84  } else if (identifier == "Time") {
    +
    85  has_time = true;
    +
    86  } else if (identifier == "") {
    +
    87  if (format_pos != std::string::npos) {
    +
    88  return Status(error::INVALID_ARGUMENT,
    +
    89  "'$$' should not have any format tags.");
    +
    90  }
    +
    91  } else if (identifier != "Bandwidth") {
    +
    92  return Status(error::INVALID_ARGUMENT,
    +
    93  "'$" + splits[i] + "$' is not a valid identifier.");
    +
    94  }
    +
    95  }
    +
    96  if (has_number && has_time) {
    +
    97  return Status(
    +
    98  error::INVALID_ARGUMENT,
    +
    99  "In segment templates $Number$ and $Time$ should not co-exist.");
    +
    100  }
    +
    101  if (!has_number && !has_time) {
    +
    102  return Status(error::INVALID_ARGUMENT,
    +
    103  "In segment templates $Number$ or $Time$ should exist.");
    +
    104  }
    +
    105  // Note: The below check is skipped.
    +
    106  // Strings outside identifiers shall only contain characters that are
    +
    107  // permitted within URLs according to RFC 1738.
    +
    108  return Status::OK;
    +
    109 }
    +
    110 
    +
    111 std::string GetSegmentName(const std::string& segment_template,
    +
    112  uint64_t segment_start_time,
    +
    113  uint32_t segment_index,
    +
    114  uint32_t bandwidth) {
    +
    115  DCHECK_EQ(Status::OK, ValidateSegmentTemplate(segment_template));
    +
    116 
    +
    117  std::vector<std::string> splits = base::SplitString(
    +
    118  segment_template, "$", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
    +
    119  // "$" always appears in pairs, so there should be odd number of splits.
    +
    120  DCHECK_EQ(1u, splits.size() % 2);
    +
    121 
    +
    122  std::string segment_name;
    +
    123  for (size_t i = 0; i < splits.size(); ++i) {
    +
    124  // Every second substring in split output should be an identifier.
    +
    125  // Simply copy the non-identifier part.
    +
    126  if (i % 2 == 0) {
    +
    127  segment_name += splits[i];
    +
    128  continue;
    +
    129  }
    +
    130  if (splits[i].empty()) {
    +
    131  // "$$" is an escape sequence, replaced with a single "$".
    +
    132  segment_name += "$";
    +
    133  continue;
    +
    134  }
    +
    135  size_t format_pos = splits[i].find('%');
    +
    136  std::string identifier = splits[i].substr(0, format_pos);
    +
    137  DCHECK(identifier == "Number" || identifier == "Time" ||
    +
    138  identifier == "Bandwidth");
    +
    139 
    +
    140  std::string format_tag;
    +
    141  if (format_pos != std::string::npos) {
    +
    142  format_tag = splits[i].substr(format_pos);
    +
    143  DCHECK_EQ(Status::OK, ValidateFormatTag(format_tag));
    +
    144  // Replace %d formatting to correctly format uint64_t.
    +
    145  format_tag = format_tag.substr(0, format_tag.size() - 1) + PRIu64;
    +
    146  } else {
    +
    147  // Default format tag "%01d", modified to format uint64_t correctly.
    +
    148  format_tag = "%01" PRIu64;
    +
    149  }
    +
    150 
    +
    151  if (identifier == "Number") {
    +
    152  // SegmentNumber starts from 1.
    +
    153  segment_name += base::StringPrintf(
    +
    154  format_tag.c_str(), static_cast<uint64_t>(segment_index + 1));
    +
    155  } else if (identifier == "Time") {
    +
    156  segment_name +=
    +
    157  base::StringPrintf(format_tag.c_str(), segment_start_time);
    +
    158  } else if (identifier == "Bandwidth") {
    +
    159  segment_name += base::StringPrintf(format_tag.c_str(),
    +
    160  static_cast<uint64_t>(bandwidth));
    +
    161  }
    +
    162  }
    +
    163  return segment_name;
    +
    164 }
    +
    165 
    +
    166 } // namespace media
    +
    167 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d32/audio__stream__info_8h_source.html b/docs/df/d32/audio__stream__info_8h_source.html index 4dc68d0885..85b99fdb4d 100644 --- a/docs/df/d32/audio__stream__info_8h_source.html +++ b/docs/df/d32/audio__stream__info_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/audio_stream_info.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    audio_stream_info.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_AUDIO_STREAM_INFO_H_
    8 #define PACKAGER_MEDIA_BASE_AUDIO_STREAM_INFO_H_
    9 
    10 #include <vector>
    11 
    12 #include "packager/media/base/stream_info.h"
    13 
    14 namespace shaka {
    15 namespace media {
    16 
    18 class AudioStreamInfo : public StreamInfo {
    19  public:
    21  AudioStreamInfo(int track_id, uint32_t time_scale, uint64_t duration,
    22  Codec codec, const std::string& codec_string,
    23  const uint8_t* codec_config, size_t codec_config_size,
    24  uint8_t sample_bits, uint8_t num_channels,
    25  uint32_t sampling_frequency, uint64_t seek_preroll_ns,
    26  uint64_t codec_delay_ns, uint32_t max_bitrate,
    27  uint32_t avg_bitrate, const std::string& language,
    28  bool is_encrypted);
    29 
    30  ~AudioStreamInfo() override;
    31 
    34  bool IsValidConfig() const override;
    35  std::string ToString() const override;
    36  std::unique_ptr<StreamInfo> Clone() const override;
    38 
    39  uint8_t sample_bits() const { return sample_bits_; }
    40  uint8_t sample_bytes() const { return sample_bits_ / 8; }
    41  uint8_t num_channels() const { return num_channels_; }
    42  uint32_t sampling_frequency() const { return sampling_frequency_; }
    43  uint32_t bytes_per_frame() const {
    44  return static_cast<uint32_t>(num_channels_) * sample_bits_ / 8;
    45  }
    46  uint64_t seek_preroll_ns() const { return seek_preroll_ns_; }
    47  uint64_t codec_delay_ns() const { return codec_delay_ns_; }
    48  uint32_t max_bitrate() const { return max_bitrate_; }
    49  uint32_t avg_bitrate() const { return avg_bitrate_; }
    50 
    51  void set_sampling_frequency(const uint32_t sampling_frequency) {
    52  sampling_frequency_ = sampling_frequency;
    53  }
    54 
    57  static std::string GetCodecString(Codec codec, uint8_t audio_object_type);
    58 
    59  private:
    60  uint8_t sample_bits_;
    61  uint8_t num_channels_;
    62  uint32_t sampling_frequency_;
    63  uint64_t seek_preroll_ns_;
    64  uint64_t codec_delay_ns_;
    65  uint32_t max_bitrate_;
    66  uint32_t avg_bitrate_;
    67 
    68  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
    69  // generated copy constructor and assignment operator. Since the extra data is
    70  // typically small, the performance impact is minimal.
    71 };
    72 
    73 } // namespace media
    74 } // namespace shaka
    75 
    76 #endif // PACKAGER_MEDIA_BASE_AUDIO_STREAM_INFO_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    std::string ToString() const override
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool IsValidConfig() const override
    -
    static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
    -
    std::unique_ptr< StreamInfo > Clone() const override
    -
    AudioStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const uint8_t *codec_config, size_t codec_config_size, uint8_t sample_bits, uint8_t num_channels, uint32_t sampling_frequency, uint64_t seek_preroll_ns, uint64_t codec_delay_ns, uint32_t max_bitrate, uint32_t avg_bitrate, const std::string &language, bool is_encrypted)
    Construct an initialized audio stream info object.
    -
    Holds audio stream information.
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_AUDIO_STREAM_INFO_H_
    +
    8 #define PACKAGER_MEDIA_BASE_AUDIO_STREAM_INFO_H_
    +
    9 
    +
    10 #include <vector>
    +
    11 
    +
    12 #include "packager/media/base/stream_info.h"
    +
    13 
    +
    14 namespace shaka {
    +
    15 namespace media {
    +
    16 
    +
    18 class AudioStreamInfo : public StreamInfo {
    +
    19  public:
    +
    21  AudioStreamInfo(int track_id, uint32_t time_scale, uint64_t duration,
    +
    22  Codec codec, const std::string& codec_string,
    +
    23  const uint8_t* codec_config, size_t codec_config_size,
    +
    24  uint8_t sample_bits, uint8_t num_channels,
    +
    25  uint32_t sampling_frequency, uint64_t seek_preroll_ns,
    +
    26  uint64_t codec_delay_ns, uint32_t max_bitrate,
    +
    27  uint32_t avg_bitrate, const std::string& language,
    +
    28  bool is_encrypted);
    +
    29 
    +
    30  ~AudioStreamInfo() override;
    +
    31 
    +
    34  bool IsValidConfig() const override;
    +
    35  std::string ToString() const override;
    +
    36  std::unique_ptr<StreamInfo> Clone() const override;
    +
    38 
    +
    39  uint8_t sample_bits() const { return sample_bits_; }
    +
    40  uint8_t sample_bytes() const { return sample_bits_ / 8; }
    +
    41  uint8_t num_channels() const { return num_channels_; }
    +
    42  uint32_t sampling_frequency() const { return sampling_frequency_; }
    +
    43  uint32_t bytes_per_frame() const {
    +
    44  return static_cast<uint32_t>(num_channels_) * sample_bits_ / 8;
    +
    45  }
    +
    46  uint64_t seek_preroll_ns() const { return seek_preroll_ns_; }
    +
    47  uint64_t codec_delay_ns() const { return codec_delay_ns_; }
    +
    48  uint32_t max_bitrate() const { return max_bitrate_; }
    +
    49  uint32_t avg_bitrate() const { return avg_bitrate_; }
    +
    50 
    +
    51  void set_sampling_frequency(const uint32_t sampling_frequency) {
    +
    52  sampling_frequency_ = sampling_frequency;
    +
    53  }
    +
    54 
    +
    57  static std::string GetCodecString(Codec codec, uint8_t audio_object_type);
    +
    58 
    +
    59  private:
    +
    60  uint8_t sample_bits_;
    +
    61  uint8_t num_channels_;
    +
    62  uint32_t sampling_frequency_;
    +
    63  uint64_t seek_preroll_ns_;
    +
    64  uint64_t codec_delay_ns_;
    +
    65  uint32_t max_bitrate_;
    +
    66  uint32_t avg_bitrate_;
    +
    67 
    +
    68  // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
    +
    69  // generated copy constructor and assignment operator. Since the extra data is
    +
    70  // typically small, the performance impact is minimal.
    +
    71 };
    +
    72 
    +
    73 } // namespace media
    +
    74 } // namespace shaka
    +
    75 
    +
    76 #endif // PACKAGER_MEDIA_BASE_AUDIO_STREAM_INFO_H_
    +
    Holds audio stream information.
    +
    AudioStreamInfo(int track_id, uint32_t time_scale, uint64_t duration, Codec codec, const std::string &codec_string, const uint8_t *codec_config, size_t codec_config_size, uint8_t sample_bits, uint8_t num_channels, uint32_t sampling_frequency, uint64_t seek_preroll_ns, uint64_t codec_delay_ns, uint32_t max_bitrate, uint32_t avg_bitrate, const std::string &language, bool is_encrypted)
    Construct an initialized audio stream info object.
    +
    std::unique_ptr< StreamInfo > Clone() const override
    +
    bool IsValidConfig() const override
    +
    std::string ToString() const override
    +
    static std::string GetCodecString(Codec codec, uint8_t audio_object_type)
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d33/classshaka_1_1AdaptationSet-members.html b/docs/df/d33/classshaka_1_1AdaptationSet-members.html index a1b31c6f99..84667a9672 100644 --- a/docs/df/d33/classshaka_1_1AdaptationSet-members.html +++ b/docs/df/d33/classshaka_1_1AdaptationSet-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    AddRepresentation(const MediaInfo &media_info)shaka::AdaptationSetvirtual AddRole(Role role)shaka::AdaptationSetvirtual AddTrickPlayReference(const AdaptationSet *adaptation_set)shaka::AdaptationSetvirtual - CopyRepresentation(const Representation &representation)shaka::AdaptationSetvirtual - ForceSetSegmentAlignment(bool segment_alignment)shaka::AdaptationSetvirtual - GetRepresentations() const (defined in shaka::AdaptationSet)shaka::AdaptationSet - GetXml()shaka::AdaptationSet - has_id() constshaka::AdaptationSetinline - id() const (defined in shaka::AdaptationSet)shaka::AdaptationSetinline - IsVideo() constshaka::AdaptationSet - kRoleAlternate enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleCaption enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleCommentary enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleDub enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleMain enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleSubtitle enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleSupplementary enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - kRoleUnknown enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet - OnNewSegmentForRepresentation(uint32_t representation_id, uint64_t start_time, uint64_t duration)shaka::AdaptationSet - OnSetFrameRateForRepresentation(uint32_t representation_id, uint32_t frame_duration, uint32_t timescale)shaka::AdaptationSet - Period (defined in shaka::AdaptationSet)shaka::AdaptationSetfriend - Role enum name (defined in shaka::AdaptationSet)shaka::AdaptationSet + codec() constshaka::AdaptationSetinline + CopyRepresentation(const Representation &representation)shaka::AdaptationSetvirtual + ForceSetSegmentAlignment(bool segment_alignment)shaka::AdaptationSetvirtual + GetRepresentations() const (defined in shaka::AdaptationSet)shaka::AdaptationSet + GetXml()shaka::AdaptationSet + has_id() constshaka::AdaptationSetinline + id() const (defined in shaka::AdaptationSet)shaka::AdaptationSetinline + IsVideo() constshaka::AdaptationSet + kRoleAlternate enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleCaption enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleCommentary enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleDub enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleMain enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleSubtitle enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleSupplementary enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + kRoleUnknown enum value (defined in shaka::AdaptationSet)shaka::AdaptationSet + OnNewSegmentForRepresentation(uint32_t representation_id, uint64_t start_time, uint64_t duration)shaka::AdaptationSet + OnSetFrameRateForRepresentation(uint32_t representation_id, uint32_t frame_duration, uint32_t timescale)shaka::AdaptationSet + Period (defined in shaka::AdaptationSet)shaka::AdaptationSetfriend + Role enum name (defined in shaka::AdaptationSet)shaka::AdaptationSet + set_codec(const std::string &codec)shaka::AdaptationSetinline set_id(uint32_t id)shaka::AdaptationSetinline UpdateContentProtectionPssh(const std::string &drm_uuid, const std::string &pssh)shaka::AdaptationSetvirtual ~AdaptationSet() (defined in shaka::AdaptationSet)shaka::AdaptationSetvirtual
    diff --git a/docs/df/d38/classshaka_1_1media_1_1SLConfigDescriptor.html b/docs/df/d38/classshaka_1_1media_1_1SLConfigDescriptor.html index 72dffae76d..08f15f0d61 100644 --- a/docs/df/d38/classshaka_1_1media_1_1SLConfigDescriptor.html +++ b/docs/df/d38/classshaka_1_1media_1_1SLConfigDescriptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::SLConfigDescriptor Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::BaseDescriptor - -
    + + @@ -105,7 +108,7 @@ void 

    Additional Inherited Members

    Detailed Description

    Implements SLConfig descriptor according to ISO 14496-1:2004 7.2.6.8 SLConfigDescriptor.

    -

    Definition at line 158 of file es_descriptor.h.

    +

    Definition at line 160 of file es_descriptor.h.


    The documentation for this class was generated from the following files:
    diff --git a/docs/df/d38/structshaka_1_1media_1_1mp4_1_1ChunkInfo.html b/docs/df/d38/structshaka_1_1media_1_1mp4_1_1ChunkInfo.html index a96221b320..d9a1015be8 100644 --- a/docs/df/d38/structshaka_1_1media_1_1mp4_1_1ChunkInfo.html +++ b/docs/df/d38/structshaka_1_1media_1_1mp4_1_1ChunkInfo.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::ChunkInfo Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    sample_descriptio

    Detailed Description

    -

    Definition at line 447 of file box_definitions.h.

    +

    Definition at line 460 of file box_definitions.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/df/d38/structshaka_1_1media_1_1mp4_1_1MovieExtendsHeader-members.html b/docs/df/d38/structshaka_1_1media_1_1mp4_1_1MovieExtendsHeader-members.html index bf0d33903c..5ee6888abe 100644 --- a/docs/df/d38/structshaka_1_1media_1_1mp4_1_1MovieExtendsHeader-members.html +++ b/docs/df/d38/structshaka_1_1media_1_1mp4_1_1MovieExtendsHeader-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/d3c/classshaka_1_1media_1_1RequestSigner.html b/docs/df/d3c/classshaka_1_1media_1_1RequestSigner.html index d75e9e6a0c..d4652f1b09 100644 --- a/docs/df/d3c/classshaka_1_1media_1_1RequestSigner.html +++ b/docs/df/d3c/classshaka_1_1media_1_1RequestSigner.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::RequestSigner Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::media::AesRequestSigner -shaka::media::RsaRequestSigner - -
    +shaka::media::AesRequestSigner +shaka::media::RsaRequestSigner + + @@ -157,9 +160,7 @@ Protected Member Functions diff --git a/docs/df/d46/classshaka_1_1media_1_1Muxer.html b/docs/df/d46/classshaka_1_1media_1_1Muxer.html index 149e0d4fff..30248086c2 100644 --- a/docs/df/d46/classshaka_1_1media_1_1Muxer.html +++ b/docs/df/d46/classshaka_1_1media_1_1Muxer.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: shaka::media::Muxer Class Reference @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    -shaka::media::MediaHandler -shaka::media::mp2t::TsMuxer -shaka::media::mp4::MP4Muxer -shaka::media::PackedAudioWriter -shaka::media::webm::WebMMuxer - -
    +shaka::media::MediaHandler +shaka::media::PackedAudioWriter +shaka::media::TextMuxer +shaka::media::mp2t::TsMuxer +shaka::media::mp4::MP4Muxer +shaka::media::webm::WebMMuxer +shaka::media::ttml::TtmlMuxer +shaka::media::webvtt::WebVttMuxer + + @@ -196,12 +202,12 @@ const std::map< size_t, std::pair< std::shared_ptr< - - + +

    Public Member Functions

    Additional Inherited Members

    - Static Public Member Functions inherited from shaka::media::MediaHandler
    -static Status Chain (std::initializer_list< std::shared_ptr< MediaHandler >> list)
     
    +static Status Chain (const std::vector< std::shared_ptr< MediaHandler >> &list)
     

    Detailed Description

    -

    Muxer is responsible for taking elementary stream samples and producing media containers. An optional KeySource can be provided to Muxer to generate encrypted outputs.

    +

    Muxer is responsible for taking elementary stream samples and producing media containers. An optional KeySource can be provided to Muxer to generate encrypted outputs.

    Definition at line 30 of file muxer.h.

    Member Function Documentation

    @@ -361,7 +367,7 @@ static Status
    -

    Set a ProgressListener event handler for this object.

    Parameters
    +

    Set a ProgressListener event handler for this object.

    Parameters
    progress_listenershould not be NULL.
    @@ -379,9 +385,7 @@ static Status
    diff --git a/docs/df/d46/classshaka_1_1media_1_1Muxer.png b/docs/df/d46/classshaka_1_1media_1_1Muxer.png index 2bbe81038eaaa55152373a223bcdb11f9b6edbfe..0d7b7ab6b3e85cc7a3add11d422612f8d30fc7c1 100644 GIT binary patch literal 3521 zcmcgvc~leU7DvSm5Ns8Kl7dUES|V`)i6VC_5ztY79XUt;Vnkh(SPv2!aH{miJBUJMDYtczWLZqjS#8-0ytf_q%iNcYpWZ zxoU5FXob>RB?SeA6;_rO#}pJ42|%u2wg^01%r*kLEYv$wL??-0H~-1R0c{fUO+Z(`4FuVpDC7W>y) z5I0XBU>m@`iWzBZ--+;w!;RZjxQ6HB;^GW75rlInVbQ{c-J5s|z~#DCb=k6I?+(Le z;BrDI7XA{!gYyw-c_)H&eA?x29NfW459)?vDy8aLs~jO$Yp}MyhFw5F$RGD6m7n$H ztX`_97*%4#gI(TUhFLldEWtvPpd)7@T!g*dOj+e610L+vL&6FqwB>fMAgJ{icIC=Z zy~@O1wzCW;^lP`Z4lPO^kMlVdq%F{<#(D^B#Cc8d@#PT2$|bB@*W>y@gHQTekjlZe zOPYmab!BEo{yBuSMQQ`g(2jz6zh`*}c^hiZNN^3|>9!rFeRkL8?%U`M)oi1~mZhDo z+z)F0>F>#Akshdp^B0YH_oZ!h5$~Vz;P${!e+@qEJVR7PPU<_4x?>6xh~W!=c5`?b z3MY+JTn>0L;Q<$ZcLcTD^lS~mwu$0aXiAKorzulAohup!<4i9b7^QnAR#z+yjBY2B z&roI z%RvV63}2wD&$`QJwUax*>BbfPFM6(v{^l*ioo~((qE>-;3%`IT`u&Axrn?RkwI_P8 zrref|d13}@619!p6idW9vsDM8d+}4&pAqt$I{Z>}8p>ldD{TdthIjn1Z z8f6PYUX~6pP+P;Op}AR%sj3%v)(*}M6XVH;B=rn_*&(+P=HVsT$?_%AuE&`glBzcR zKg)tzjCahrs1h-JYKg`^oIJk9W?ztS!%U_%oN3s?+o9?=?Pcu$e0%R~?@jdcqLSPT z%OJI+GqRHqcDxm*EIJ6|=qS1B2f{;hSx(g#q?8;&L)a^B+D2QZ|LU*yZTL5?KW5@h zSxa87X#kGc8&dDAl<1YNv1ddlFTGz5uvuDiJx%_NR(~ez=a~8OSzhM8`J1C@b{D_* zqvoIPsU@Q}oXNrK-uLiUOKOs>7tf>uajR|1|c7AfP`V>A2YW11h59lB3wmNVgeX$9;Jd|L6#1cGRX;M;2!2E=mQ%o$-?XWplrqk6&)LJ_5dlC!z!va9gv z+)L(B@R8OTHha3`v5X>YBn|$Q*&ZD#m7OUI6dStD7YQ20o`UM`?2)LqxdgpI$5nb+^H~?%Dxa3} zKE7xa2no!tPY!Oc>F3&53J{c`O>`@+jUQk0%r2+kOjLPE_KJ3ENw>ZDYJfUlI{unh zlQMk$e0uqgX8k#r)`x6%2b{rs-dweXKE9wAX6TD=*ept4mcf6Lf_ZkAB~^vWgALxC zY~W$^pT|PjVj8=utD{wPxLeI0Dj!Vo#&hBso{Y%RgPnEC?N*Y0d&b?Of8b1HHf*ss ze#J`@dyH3l4#O$HplF38ynzDi>xO4@=0dz4^tYaD8}xgny)$fjtdScVEN9(rH zTMuSCz6d#4u$e1d+^&RLbIZG!6HipHrPtsZ-G3O~6zQAacb8>e$n>@21FzYfZ{Y^2 z^Czl&W-qK^@a~@=IYpP66bw-~Rdp=~s{K2pIa*oOQCEVDx6C61x3yHMrHO+*ct0|O6Co-caMp@`ISwpjCBaHA>Z6Y$byZJ++r3Nn{?7= z!qyu->eeE|wz{tgw}iAg+xzfUEdF#+D@r0`eEYHV=G&ihqn#0dkWQh7VdWjGvwmeOZ-wYF>(# z##$~}V7J#CG+y<_XenFvZjZJ=-U6h^OLI1}+wvSb8!ev=HzUj2v%kvtpP~MvqeHjc za|bDTDi<^sJrF01DsQZE|4*!yzkRvjpz7PIfq}9Iu;!&VrlYcC70`2Cy@kAwECX(w zFa}CTm!obrLTj#FGV1H|pnOKfqYhUE4NlK0)a#+^Ky75+EM==g26bsfkYZvku?`i5 z+Khn4Z^D;xtpLdmE+DvF&p|Yb3#fRbdG-xlLw0P|Ws?*GbZd_d(3jXs6aCa(l;}kw z$vE?-fhsf98Q(MWr>j4;Fbxv@_Fc8k zNg4^1-@$y~C(pP(`|*xX^>3aynZfs0;}i;- z_WGID6yBP^^_mwV9l@?xeDm`kACll#CtCA5L%A)tYYTzHrW7X=a;hH<5bNebdJhK0 zbgkVT%icmqxU(+!JCa{H1UAyq>I1X4^81UWFXuDof4QaoJze~Ht6`!SWoCYsq|r(B zs!eTJ-@Kt6D{+QNjxU0D(2koN$BsO{uesasp%0AX(<7Nr(ov^_Hg-2N-|5*b1%qSO z;&thLo_6Z|#B)gj_plWZHsEMs<%kA9v_*a_8NB-(#*qE^P(yr%b_0G3y)UXcf_Q`o z%9Sg&xcNTeBK66J1|PW0Ye2?q{ES~pu$`1f&18Rg*QE55PEB)H>|PJ{1cslaEP9{p z!wWbPCheCjH;w@(erE_UoqlIU1NB+XfF>iQxx}4TJDe3EO8IPHWnvCO4g(}c-YfrC zaI8alxk&Col$YOF!e;fGEm0ntfxg&eKiETF`sH{7Q5rOc#^=vcsm{d%#7z~~PMd)L PEd{FswiZR^9`XMIoH=eH literal 2254 zcmcImdsGuw9uAK#tS_+C#a19H6!r)L3Q|ysy5(U+LJ=kwkqWZ%FbN<+0!ReuHpn6m zVTA&Pu~5h|SXfL#fPew5(iKCD0WrM7Lrp@60Z9T*H0gvr?H{}CIlF)CoHH}`@!k7- zeczoa_zV}gaotDjP$<+!>`}iHD3l2XXu1Nq{q=f1(v&W!(@XA_ zBCWN%udnaDf(Zl0JnaN7426IU*T}>0y~t1$*6&DohLK`Yo;vSs=|59K-lEk1Sf0D_ zbkWQ_fFtj*jLvaX%Sg+M}(#XdNdd>4Upn;KRB4yeR4`=y(y8Frncc%d1&W645Zr zciVbjXz8`&b1|GcsJa*NH^XThJ{{GSGk2yVSI`_;$?y1Q9d86*D7|ZR4tr38!bSDxUDr&<$_iSU!?R{n!XecA&gFyyVmNz(O$p4YG&gyL^ z9fIUr8482jX_)wpy?(ul|6efrfh=u5)eu3=YU!QA-zJlPj+hsC&_~xojPSA5ACm;4 z%@=V~bc?t)p?YG~LigTU)>`jyer8YAY?gblk7D1PsEr$WjzWEqNGF}Q8DVr7Xon3E zM{T1ntkfKstC7u*RB+sDV#lt_m&?yDI;?G^v#TAuG`0)xvD-gE#~ZAGk8{Qs>=r%N zChs`bvQ|dclghbx1wN!RH{T8`U^y(t_S;FlGJ~13A!$2cl zS<(CIxo%7lKbG$`_;O37^S1qWLy(j&;^1l~Ng-^Ub24iBvg<&lQNu@!Jw-vI%X8tv z(}+ErDhnBB&FNpKz<-ntM;FSha#2Q@s~)E2meUbyV!ZdpCI=zFrhj!ReU}gpWz?;) z?ETDNB>UeN`z_Z8I)qW|&dJCH}hrC!T>U62YW}6zRNxnnD z^fN!Sw*%I6z!C1-f!*otB{18BeZRlG0F!dG%)B^Qb>-8t|8Z$%P<_l++R2M{w3v)N zSWo0kk~j$5H+8dI&=N zgdoHh0I;pehrfa5b=7D9AiV}Ou`gt*sJ%C+wp6`K((-df-DOX=^}-6z!sNZYyLiC& z{ulM)bx$r!Enaf!p6&N7={4_SwVrf>AQ3?er?#^x+gkLpO>P1@G{1Rnw&tNmvD#B? zup3+5=vBz=;pn=aD~i?QJUqY{rCvECzj$hJrPE$)fY@iL6YZwTLkJ<@g-e~qT+$y# zF$u~`^77`_F(S{IRq}_?qWHN|?dTg#`P)!%l$L1CY~-u6a&8s*ac%y5YFd{)dR>u9 zcV~3_REh~!Lk+#&p^U#KHp#?Oc%QcMVabeeOd#1$w4n|Twx0aZ<7mX;~Q>p^aY(?qt1I+uwptEq)GK(;~7Nlh*oo!lB`91cvCc z$B&(T59%Xh9|a~!8T0*e<-?{3W+iegM*4o&*l=i`@s3GWMSM^axugg?(?)TrQuJ!! zi9@W+e6|nXnahp^M#{|K9?wVF*uwj6oL1+j0rlcdsVfQ1eByKBbz9h_p?8M>C#u89 zyPI?cbQYZ-G7bkglP)hWTy`eP7>w7MZx20|+=y{SOW)3BS7`0$ud%A6lrLRe*;)zw zWQYwPuO69<6MO+CsLr+!1td1$Hm^~MikS`kIp4+W)@;1UC6a2cNW~u*PX8f;q^`mP z%UL)1gnKR&(Eotz5c!8wPOy4=P@pETH7@G}h$e&LU?zMs1W*vdK=omyjf~MfTKM3H1bacUSr@5vW0`~c=jr}I5qCACdp(69?Rl>IIL9uhA?CM81%1Ax9F5JohCaoezr{uqL? zJ_f)3qhY`ZAt;nD4Fl8?KM;bP400KG*^5l|UiFOpML!5je^w2{pcQ06`q3vu1nY=E wZOhi6Z;n!FF;6r#@Pod09-HFTLb^7Dbh`s4gs{}i3~6Y4KeasU7T diff --git a/docs/df/d47/classshaka_1_1media_1_1DecoderConfigDescriptor-members.html b/docs/df/d47/classshaka_1_1media_1_1DecoderConfigDescriptor-members.html index 11bb727aee..68fc40cbe9 100644 --- a/docs/df/d47/classshaka_1_1media_1_1DecoderConfigDescriptor-members.html +++ b/docs/df/d47/classshaka_1_1media_1_1DecoderConfigDescriptor-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/d47/structshaka_1_1PlayReadyEncryptionParams.html b/docs/df/d47/structshaka_1_1PlayReadyEncryptionParams.html index e031e09510..f2587cf429 100644 --- a/docs/df/d47/structshaka_1_1PlayReadyEncryptionParams.html +++ b/docs/df/d47/structshaka_1_1PlayReadyEncryptionParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::PlayReadyEncryptionParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */

    Detailed Description

    PlayReady encryption parameters. key_server_url and program_identifier are required. The presence of other parameters may be necessary depends on server configuration.

    -

    Definition at line 69 of file crypto_params.h.

    +

    Definition at line 106 of file crypto_params.h.

    Member Data Documentation

    ◆ ca_file

    @@ -115,7 +118,7 @@ std::string 
    @@ -125,9 +128,7 @@ std::string  diff --git a/docs/df/d4e/classshaka_1_1IoCache.html b/docs/df/d4e/classshaka_1_1IoCache.html index 191899f71b..119d2b0d95 100644 --- a/docs/df/d4e/classshaka_1_1IoCache.html +++ b/docs/df/d4e/classshaka_1_1IoCache.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::IoCache Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/d51/classshaka_1_1media_1_1RsaPrivateKey-members.html b/docs/df/d51/classshaka_1_1media_1_1RsaPrivateKey-members.html index 39f865381f..7f61cebbe5 100644 --- a/docs/df/d51/classshaka_1_1media_1_1RsaPrivateKey-members.html +++ b/docs/df/d51/classshaka_1_1media_1_1RsaPrivateKey-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/df/d5b/classshaka_1_1CallbackFile-members.html b/docs/df/d5b/classshaka_1_1CallbackFile-members.html index fbc799933b..29701d1a60 100644 --- a/docs/df/d5b/classshaka_1_1CallbackFile-members.html +++ b/docs/df/d5b/classshaka_1_1CallbackFile-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/d60/classshaka_1_1MockMpdBuilder.html b/docs/df/d60/classshaka_1_1MockMpdBuilder.html index 09a9a16067..4aa698ede3 100644 --- a/docs/df/d60/classshaka_1_1MockMpdBuilder.html +++ b/docs/df/d60/classshaka_1_1MockMpdBuilder.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MockMpdBuilder Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::MpdBuilder - -
    +shaka::MpdBuilder + + @@ -85,7 +88,7 @@ Public Member Functions   +  @@ -94,8 +97,8 @@ Public Member Functions - - + + @@ -117,9 +120,7 @@ Additional Inherited Members diff --git a/docs/df/d60/structshaka_1_1media_1_1KeyFrameEvent-members.html b/docs/df/d60/structshaka_1_1media_1_1KeyFrameEvent-members.html index 24e193c37b..7046f7fb8f 100644 --- a/docs/df/d60/structshaka_1_1media_1_1KeyFrameEvent-members.html +++ b/docs/df/d60/structshaka_1_1media_1_1KeyFrameEvent-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    MOCK_METHOD1 (GetOrCreatePeriod, Period *(double start_time_in_seconds))
     
    MOCK_METHOD1 (ToString, bool(std::string *output))
    MOCK_METHOD1 (ToString, bool(std::string *output))
     
    - Public Member Functions inherited from shaka::MpdBuilder
     MpdBuilder (const MpdOptions &mpd_options)
     
    virtual PeriodGetOrCreatePeriod (double start_time_in_seconds)
     
    virtual bool ToString (std::string *output)
     
    virtual bool ToString (std::string *output) WARN_UNUSED_RESULT
     
    void InjectClockForTesting (std::unique_ptr< base::Clock > clock)
     This is for testing.
    - + +/* @license-end */
    diff --git a/docs/df/d63/structshaka_1_1media_1_1mp4_1_1AudioRollRecoveryEntry-members.html b/docs/df/d63/structshaka_1_1media_1_1mp4_1_1AudioRollRecoveryEntry-members.html index 8d91089121..fb0c19c47e 100644 --- a/docs/df/d63/structshaka_1_1media_1_1mp4_1_1AudioRollRecoveryEntry-members.html +++ b/docs/df/d63/structshaka_1_1media_1_1mp4_1_1AudioRollRecoveryEntry-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/d66/classshaka_1_1media_1_1KeyFetcher.html b/docs/df/d66/classshaka_1_1media_1_1KeyFetcher.html index e2fdf07185..c8261be324 100644 --- a/docs/df/d66/classshaka_1_1media_1_1KeyFetcher.html +++ b/docs/df/d66/classshaka_1_1media_1_1KeyFetcher.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::KeyFetcher Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::HttpKeyFetcher - -
    + + @@ -154,9 +157,7 @@ Public Member Functions diff --git a/docs/df/d6a/classshaka_1_1MockMpdBuilder-members.html b/docs/df/d6a/classshaka_1_1MockMpdBuilder-members.html index fe1b438fa0..b3ca664203 100644 --- a/docs/df/d6a/classshaka_1_1MockMpdBuilder-members.html +++ b/docs/df/d6a/classshaka_1_1MockMpdBuilder-members.html @@ -1,9 +1,9 @@ - + - +Shaka Packager SDK: Member List @@ -29,18 +29,21 @@

    Public Member Functions

    - + +/* @license-end */
    MOCK_METHOD1(ToString, bool(std::string *output)) (defined in shaka::MockMpdBuilder)shaka::MockMpdBuilder MockMpdBuilder() (defined in shaka::MockMpdBuilder)shaka::MockMpdBuilder MpdBuilder(const MpdOptions &mpd_options)shaka::MpdBuilderexplicit - ToString(std::string *output)shaka::MpdBuildervirtual + ToString(std::string *output) WARN_UNUSED_RESULTshaka::MpdBuildervirtual ~MockMpdBuilder() override (defined in shaka::MockMpdBuilder)shaka::MockMpdBuilder ~MpdBuilder() (defined in shaka::MpdBuilder)shaka::MpdBuildervirtual
    diff --git a/docs/df/d6a/structshaka_1_1media_1_1mp4_1_1OpusSpecific-members.html b/docs/df/d6a/structshaka_1_1media_1_1mp4_1_1OpusSpecific-members.html index e78c63601c..67163752b8 100644 --- a/docs/df/d6a/structshaka_1_1media_1_1mp4_1_1OpusSpecific-members.html +++ b/docs/df/d6a/structshaka_1_1media_1_1mp4_1_1OpusSpecific-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/d6d/structshaka_1_1media_1_1OnNewSegmentParameters.html b/docs/df/d6d/structshaka_1_1media_1_1OnNewSegmentParameters.html index a3f2f8afb5..254462f85b 100644 --- a/docs/df/d6d/structshaka_1_1media_1_1OnNewSegmentParameters.html +++ b/docs/df/d6d/structshaka_1_1media_1_1OnNewSegmentParameters.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::OnNewSegmentParameters Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    segment_file_size
    diff --git a/docs/df/d7b/structshaka_1_1media_1_1mp4_1_1CompositionTimeToSample.html b/docs/df/d7b/structshaka_1_1media_1_1mp4_1_1CompositionTimeToSample.html index a7d50c75fd..d32bcb09db 100644 --- a/docs/df/d7b/structshaka_1_1media_1_1mp4_1_1CompositionTimeToSample.html +++ b/docs/df/d7b/structshaka_1_1media_1_1mp4_1_1CompositionTimeToSample.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::CompositionTimeToSample Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 441 of file box_definitions.h.

    +

    Definition at line 454 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 710 of file box_definitions.cc.

    +

    Definition at line 723 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/df/d7b/structshaka_1_1media_1_1mp4_1_1TrackFragment.html b/docs/df/d7b/structshaka_1_1media_1_1mp4_1_1TrackFragment.html index 54329d0af4..be032f85e0 100644 --- a/docs/df/d7b/structshaka_1_1media_1_1mp4_1_1TrackFragment.html +++ b/docs/df/d7b/structshaka_1_1media_1_1mp4_1_1TrackFragment.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TrackFragment Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::media::mp4::Box - -
    + + @@ -136,7 +139,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 739 of file box_definitions.h.

    +

    Definition at line 757 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -164,7 +167,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2569 of file box_definitions.cc.

    +

    Definition at line 2658 of file box_definitions.cc.

    @@ -175,9 +178,7 @@ Additional Inherited Members diff --git a/docs/df/d7d/webm__info__parser_8cc_source.html b/docs/df/d7d/webm__info__parser_8cc_source.html index e5767f74dc..3500ccb2ef 100644 --- a/docs/df/d7d/webm__info__parser_8cc_source.html +++ b/docs/df/d7d/webm__info__parser_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/webm_info_parser.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    webm_info_parser.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/webm/webm_info_parser.h"
    6 
    7 #include "packager/base/logging.h"
    8 #include "packager/media/formats/webm/webm_constants.h"
    9 
    10 namespace shaka {
    11 namespace media {
    12 
    13 // Default timecode scale if the TimecodeScale element is
    14 // not specified in the INFO element.
    15 static const int kWebMDefaultTimecodeScale = 1000000;
    16 
    17 WebMInfoParser::WebMInfoParser()
    18  : timecode_scale_(-1),
    19  duration_(-1) {
    20 }
    21 
    22 WebMInfoParser::~WebMInfoParser() {}
    23 
    24 int WebMInfoParser::Parse(const uint8_t* buf, int size) {
    25  timecode_scale_ = -1;
    26  duration_ = -1;
    27 
    28  WebMListParser parser(kWebMIdInfo, this);
    29  int result = parser.Parse(buf, size);
    30 
    31  if (result <= 0)
    32  return result;
    33 
    34  // For now we do all or nothing parsing.
    35  return parser.IsParsingComplete() ? result : 0;
    36 }
    37 
    38 WebMParserClient* WebMInfoParser::OnListStart(int id) { return this; }
    39 
    40 bool WebMInfoParser::OnListEnd(int id) {
    41  if (id == kWebMIdInfo && timecode_scale_ == -1) {
    42  // Set timecode scale to default value if it isn't present in
    43  // the Info element.
    44  timecode_scale_ = kWebMDefaultTimecodeScale;
    45  }
    46  return true;
    47 }
    48 
    49 bool WebMInfoParser::OnUInt(int id, int64_t val) {
    50  if (id != kWebMIdTimecodeScale)
    51  return true;
    52 
    53  if (timecode_scale_ != -1) {
    54  DVLOG(1) << "Multiple values for id " << std::hex << id << " specified";
    55  return false;
    56  }
    57 
    58  timecode_scale_ = val;
    59  return true;
    60 }
    61 
    62 bool WebMInfoParser::OnFloat(int id, double val) {
    63  if (id != kWebMIdDuration) {
    64  DVLOG(1) << "Unexpected float for id" << std::hex << id;
    65  return false;
    66  }
    67 
    68  if (duration_ != -1) {
    69  DVLOG(1) << "Multiple values for duration.";
    70  return false;
    71  }
    72 
    73  duration_ = val;
    74  return true;
    75 }
    76 
    77 bool WebMInfoParser::OnBinary(int id, const uint8_t* data, int size) {
    78  if (id == kWebMIdDateUTC) {
    79  if (size != 8)
    80  return false;
    81 
    82  int64_t date_in_nanoseconds = 0;
    83  for (int i = 0; i < size; ++i)
    84  date_in_nanoseconds = (date_in_nanoseconds << 8) | data[i];
    85 
    86  base::Time::Exploded exploded_epoch;
    87  exploded_epoch.year = 2001;
    88  exploded_epoch.month = 1;
    89  exploded_epoch.day_of_month = 1;
    90  exploded_epoch.hour = 0;
    91  exploded_epoch.minute = 0;
    92  exploded_epoch.second = 0;
    93  exploded_epoch.millisecond = 0;
    94  date_utc_ = base::Time::FromUTCExploded(exploded_epoch) +
    95  base::TimeDelta::FromMicroseconds(date_in_nanoseconds / 1000);
    96  }
    97  return true;
    98 }
    99 
    100 bool WebMInfoParser::OnString(int id, const std::string& str) {
    101  return true;
    102 }
    103 
    104 } // namespace media
    105 } // namespace shaka
    -
    All the methods that are virtual are virtual for mocking.
    - -
    int Parse(const uint8_t *buf, int size)
    Definition: webm_parser.cc:738
    - -
    int Parse(const uint8_t *buf, int size)
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/webm/webm_info_parser.h"
    +
    6 
    +
    7 #include "packager/base/logging.h"
    +
    8 #include "packager/media/formats/webm/webm_constants.h"
    +
    9 
    +
    10 namespace shaka {
    +
    11 namespace media {
    +
    12 
    +
    13 // Default timecode scale if the TimecodeScale element is
    +
    14 // not specified in the INFO element.
    +
    15 static const int kWebMDefaultTimecodeScale = 1000000;
    +
    16 
    +
    17 WebMInfoParser::WebMInfoParser()
    +
    18  : timecode_scale_(-1),
    +
    19  duration_(-1) {
    +
    20 }
    +
    21 
    +
    22 WebMInfoParser::~WebMInfoParser() {}
    +
    23 
    +
    24 int WebMInfoParser::Parse(const uint8_t* buf, int size) {
    +
    25  timecode_scale_ = -1;
    +
    26  duration_ = -1;
    +
    27 
    +
    28  WebMListParser parser(kWebMIdInfo, this);
    +
    29  int result = parser.Parse(buf, size);
    +
    30 
    +
    31  if (result <= 0)
    +
    32  return result;
    +
    33 
    +
    34  // For now we do all or nothing parsing.
    +
    35  return parser.IsParsingComplete() ? result : 0;
    +
    36 }
    +
    37 
    +
    38 WebMParserClient* WebMInfoParser::OnListStart(int id) { return this; }
    +
    39 
    +
    40 bool WebMInfoParser::OnListEnd(int id) {
    +
    41  if (id == kWebMIdInfo && timecode_scale_ == -1) {
    +
    42  // Set timecode scale to default value if it isn't present in
    +
    43  // the Info element.
    +
    44  timecode_scale_ = kWebMDefaultTimecodeScale;
    +
    45  }
    +
    46  return true;
    +
    47 }
    +
    48 
    +
    49 bool WebMInfoParser::OnUInt(int id, int64_t val) {
    +
    50  if (id != kWebMIdTimecodeScale)
    +
    51  return true;
    +
    52 
    +
    53  if (timecode_scale_ != -1) {
    +
    54  DVLOG(1) << "Multiple values for id " << std::hex << id << " specified";
    +
    55  return false;
    +
    56  }
    +
    57 
    +
    58  timecode_scale_ = val;
    +
    59  return true;
    +
    60 }
    +
    61 
    +
    62 bool WebMInfoParser::OnFloat(int id, double val) {
    +
    63  if (id != kWebMIdDuration) {
    +
    64  DVLOG(1) << "Unexpected float for id" << std::hex << id;
    +
    65  return false;
    +
    66  }
    +
    67 
    +
    68  if (duration_ != -1) {
    +
    69  DVLOG(1) << "Multiple values for duration.";
    +
    70  return false;
    +
    71  }
    +
    72 
    +
    73  duration_ = val;
    +
    74  return true;
    +
    75 }
    +
    76 
    +
    77 bool WebMInfoParser::OnBinary(int id, const uint8_t* data, int size) {
    +
    78  if (id == kWebMIdDateUTC) {
    +
    79  if (size != 8)
    +
    80  return false;
    +
    81 
    +
    82  int64_t date_in_nanoseconds = 0;
    +
    83  for (int i = 0; i < size; ++i)
    +
    84  date_in_nanoseconds = (date_in_nanoseconds << 8) | data[i];
    +
    85 
    +
    86  base::Time::Exploded exploded_epoch;
    +
    87  exploded_epoch.year = 2001;
    +
    88  exploded_epoch.month = 1;
    +
    89  exploded_epoch.day_of_month = 1;
    +
    90  exploded_epoch.hour = 0;
    +
    91  exploded_epoch.minute = 0;
    +
    92  exploded_epoch.second = 0;
    +
    93  exploded_epoch.millisecond = 0;
    +
    94  date_utc_ = base::Time::FromUTCExploded(exploded_epoch) +
    +
    95  base::TimeDelta::FromMicroseconds(date_in_nanoseconds / 1000);
    +
    96  }
    +
    97  return true;
    +
    98 }
    +
    99 
    +
    100 bool WebMInfoParser::OnString(int id, const std::string& str) {
    +
    101  return true;
    +
    102 }
    +
    103 
    +
    104 } // namespace media
    +
    105 } // namespace shaka
    + +
    int Parse(const uint8_t *buf, int size)
    Definition: webm_parser.cc:738
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d82/classshaka_1_1media_1_1DecoderConfigurationRecord-members.html b/docs/df/d82/classshaka_1_1media_1_1DecoderConfigurationRecord-members.html index 0df3c6228d..81772e118b 100644 --- a/docs/df/d82/classshaka_1_1media_1_1DecoderConfigurationRecord-members.html +++ b/docs/df/d82/classshaka_1_1media_1_1DecoderConfigurationRecord-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/df/d83/classshaka_1_1media_1_1TextPadder-members.html b/docs/df/d83/classshaka_1_1media_1_1TextPadder-members.html index 0ca847ec4d..4897897ff1 100644 --- a/docs/df/d83/classshaka_1_1media_1_1TextPadder-members.html +++ b/docs/df/d83/classshaka_1_1media_1_1TextPadder-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    This is the complete list of members for shaka::media::TextPadder, including all inherited members.

    - + @@ -96,9 +99,7 @@ $(function() {
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
    Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
    diff --git a/docs/df/d87/classshaka_1_1media_1_1AesCryptor.html b/docs/df/d87/classshaka_1_1media_1_1AesCryptor.html index 6b2cb7ccef..bc1115a760 100644 --- a/docs/df/d87/classshaka_1_1media_1_1AesCryptor.html +++ b/docs/df/d87/classshaka_1_1media_1_1AesCryptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::AesCryptor Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    -shaka::media::AesCbcDecryptor +shaka::media::AesCbcDecryptor shaka::media::AesEncryptor -shaka::media::AesPatternCryptor +shaka::media::AesPatternCryptor shaka::media::MockAesCryptor shaka::media::SampleAesEc3Cryptor shaka::media::AesCbcEncryptor shaka::media::AesCtrEncryptor - -
    + + -

    Public Types

    enum  ConstantIvFlag { kUseConstantIv, -kDontUseConstantIv +
    enum  ConstantIvFlag { kUseConstantIv +, kDontUseConstantIv }
     
    @@ -308,7 +311,7 @@ AES_KEY * 
    mutable_aes_key<

    Initialize the cryptor with specified key and IV.

    Returns
    true on successful initialization, false otherwise.
    -

    Implemented in shaka::media::AesPatternCryptor, shaka::media::AesCbcDecryptor, shaka::media::AesEncryptor, and shaka::media::SampleAesEc3Cryptor.

    +

    Implemented in shaka::media::SampleAesEc3Cryptor, shaka::media::AesPatternCryptor, shaka::media::AesEncryptor, and shaka::media::AesCbcDecryptor.

    @@ -416,9 +419,7 @@ AES_KEY * 
    mutable_aes_key< diff --git a/docs/df/d87/classshaka_1_1media_1_1ttml_1_1TtmlGenerator.html b/docs/df/d87/classshaka_1_1media_1_1ttml_1_1TtmlGenerator.html new file mode 100644 index 0000000000..bcf9514ab0 --- /dev/null +++ b/docs/df/d87/classshaka_1_1media_1_1ttml_1_1TtmlGenerator.html @@ -0,0 +1,111 @@ + + + + + + + +Shaka Packager SDK: shaka::media::ttml::TtmlGenerator Class Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    shaka::media::ttml::TtmlGenerator Class Reference
    +
    +
    + + + + + + + + + + +

    +Public Member Functions

    +void Initialize (const std::map< std::string, TextRegion > &regions, const std::string &language, uint32_t time_scale)
     
    +void AddSample (const TextSample &sample)
     
    +void Reset ()
     
    +bool Dump (std::string *result) const
     
    + + + +

    +Static Public Attributes

    +static const char * kTtNamespace = "http://www.w3.org/ns/ttml"
     
    +

    Detailed Description

    +
    +

    Definition at line 22 of file ttml_generator.h.

    +

    The documentation for this class was generated from the following files: +
    + + + + diff --git a/docs/df/d8a/structshaka_1_1media_1_1mp4_1_1DataEntryUrl.html b/docs/df/d8a/structshaka_1_1media_1_1mp4_1_1DataEntryUrl.html index 7cdd4e92d1..300dbe1a1c 100644 --- a/docs/df/d8a/structshaka_1_1media_1_1mp4_1_1DataEntryUrl.html +++ b/docs/df/d8a/structshaka_1_1media_1_1mp4_1_1DataEntryUrl.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::DataEntryUrl Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 597 of file box_definitions.h.

    +

    Definition at line 614 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2070 of file box_definitions.cc.

    +

    Definition at line 2145 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/df/d8a/vp9__parser_8h_source.html b/docs/df/d8a/vp9__parser_8h_source.html index a1070ce9d1..7636935106 100644 --- a/docs/df/d8a/vp9__parser_8h_source.html +++ b/docs/df/d8a/vp9__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/vp9_parser.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    vp9_parser.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_VP9_PARSER_H_
    8 #define PACKAGER_MEDIA_CODECS_VP9_PARSER_H_
    9 
    10 #include <stdint.h>
    11 #include <stdlib.h>
    12 
    13 #include "packager/base/macros.h"
    14 #include "packager/media/codecs/vpx_parser.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    20 class VP9Parser : public VPxParser {
    21  public:
    22  VP9Parser();
    23  ~VP9Parser() override;
    24 
    31  bool Parse(const uint8_t* data,
    32  size_t data_size,
    33  std::vector<VPxFrameInfo>* vpx_frames) override;
    34 
    40  static bool IsKeyframe(const uint8_t* data, size_t data_size);
    41 
    42  private:
    43  // Keep track of the current width and height. Note that they may change from
    44  // frame to frame.
    45  uint32_t width_;
    46  uint32_t height_;
    47 
    48  DISALLOW_COPY_AND_ASSIGN(VP9Parser);
    49 };
    50 
    51 } // namespace media
    52 } // namespace shaka
    53 
    54 #endif // PACKAGER_MEDIA_CODECS_VP9_PARSER_H_
    static bool IsKeyframe(const uint8_t *data, size_t data_size)
    Definition: vp9_parser.cc:572
    - -
    bool Parse(const uint8_t *data, size_t data_size, std::vector< VPxFrameInfo > *vpx_frames) override
    Definition: vp9_parser.cc:455
    -
    All the methods that are virtual are virtual for mocking.
    -
    Class to parse a vp9 bit stream.
    Definition: vp9_parser.h:20
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_VP9_PARSER_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_VP9_PARSER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <stdlib.h>
    +
    12 
    +
    13 #include "packager/base/macros.h"
    +
    14 #include "packager/media/codecs/vpx_parser.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    20 class VP9Parser : public VPxParser {
    +
    21  public:
    +
    22  VP9Parser();
    +
    23  ~VP9Parser() override;
    +
    24 
    +
    31  bool Parse(const uint8_t* data,
    +
    32  size_t data_size,
    +
    33  std::vector<VPxFrameInfo>* vpx_frames) override;
    +
    34 
    +
    40  static bool IsKeyframe(const uint8_t* data, size_t data_size);
    +
    41 
    +
    42  private:
    +
    43  // Keep track of the current width and height. Note that they may change from
    +
    44  // frame to frame.
    +
    45  uint32_t width_;
    +
    46  uint32_t height_;
    +
    47 
    +
    48  DISALLOW_COPY_AND_ASSIGN(VP9Parser);
    +
    49 };
    +
    50 
    +
    51 } // namespace media
    +
    52 } // namespace shaka
    +
    53 
    +
    54 #endif // PACKAGER_MEDIA_CODECS_VP9_PARSER_H_
    +
    Class to parse a vp9 bit stream.
    Definition: vp9_parser.h:20
    +
    static bool IsKeyframe(const uint8_t *data, size_t data_size)
    Definition: vp9_parser.cc:572
    +
    bool Parse(const uint8_t *data, size_t data_size, std::vector< VPxFrameInfo > *vpx_frames) override
    Definition: vp9_parser.cc:455
    + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/d8a/vpx__parser_8h_source.html b/docs/df/d8a/vpx__parser_8h_source.html index cec83c119f..848fad5ac6 100644 --- a/docs/df/d8a/vpx__parser_8h_source.html +++ b/docs/df/d8a/vpx__parser_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/vpx_parser.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    vpx_parser.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_VPX_PARSER_H_
    8 #define PACKAGER_MEDIA_CODECS_VPX_PARSER_H_
    9 
    10 #include <stdint.h>
    11 #include <stdlib.h>
    12 
    13 #include "packager/base/macros.h"
    14 #include "packager/media/codecs/vp_codec_configuration_record.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    19 struct VPxFrameInfo {
    20  size_t frame_size;
    21  size_t uncompressed_header_size;
    22  bool is_keyframe;
    23  uint32_t width;
    24  uint32_t height;
    25 };
    26 
    27 class VPxParser {
    28  public:
    29  VPxParser() {}
    30  virtual ~VPxParser() {}
    31 
    38  virtual bool Parse(const uint8_t* data,
    39  size_t data_size,
    40  std::vector<VPxFrameInfo>* vpx_frames) = 0;
    41 
    45  return codec_config_;
    46  }
    47 
    48  protected:
    49  VPCodecConfigurationRecord* writable_codec_config() { return &codec_config_; }
    50 
    51  private:
    52  VPCodecConfigurationRecord codec_config_;
    53 
    54  DISALLOW_COPY_AND_ASSIGN(VPxParser);
    55 };
    56 
    57 } // namespace media
    58 } // namespace shaka
    59 
    60 #endif // PACKAGER_MEDIA_CODECS_VPX_PARSER_H_
    Class for parsing or writing VP codec configuration record.
    - - -
    All the methods that are virtual are virtual for mocking.
    -
    const VPCodecConfigurationRecord & codec_config() const
    Definition: vpx_parser.h:44
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_VPX_PARSER_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_VPX_PARSER_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <stdlib.h>
    +
    12 
    +
    13 #include "packager/base/macros.h"
    +
    14 #include "packager/media/codecs/vp_codec_configuration_record.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    19 struct VPxFrameInfo {
    +
    20  size_t frame_size;
    +
    21  size_t uncompressed_header_size;
    +
    22  bool is_keyframe;
    +
    23  uint32_t width;
    +
    24  uint32_t height;
    +
    25 };
    +
    26 
    +
    27 class VPxParser {
    +
    28  public:
    +
    29  VPxParser() {}
    +
    30  virtual ~VPxParser() {}
    +
    31 
    +
    38  virtual bool Parse(const uint8_t* data,
    +
    39  size_t data_size,
    +
    40  std::vector<VPxFrameInfo>* vpx_frames) = 0;
    +
    41 
    + +
    45  return codec_config_;
    +
    46  }
    +
    47 
    +
    48  protected:
    +
    49  VPCodecConfigurationRecord* writable_codec_config() { return &codec_config_; }
    +
    50 
    +
    51  private:
    +
    52  VPCodecConfigurationRecord codec_config_;
    +
    53 
    +
    54  DISALLOW_COPY_AND_ASSIGN(VPxParser);
    +
    55 };
    +
    56 
    +
    57 } // namespace media
    +
    58 } // namespace shaka
    +
    59 
    +
    60 #endif // PACKAGER_MEDIA_CODECS_VPX_PARSER_H_
    +
    Class for parsing or writing VP codec configuration record.
    + +
    const VPCodecConfigurationRecord & codec_config() const
    Definition: vpx_parser.h:44
    +
    virtual bool Parse(const uint8_t *data, size_t data_size, std::vector< VPxFrameInfo > *vpx_frames)=0
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/df/d8c/classshaka_1_1media_1_1mp4_1_1MultiSegmentSegmenter-members.html b/docs/df/d8c/classshaka_1_1media_1_1mp4_1_1MultiSegmentSegmenter-members.html index ef2de6facf..1033887d95 100644 --- a/docs/df/d8c/classshaka_1_1media_1_1mp4_1_1MultiSegmentSegmenter-members.html +++ b/docs/df/d8c/classshaka_1_1media_1_1mp4_1_1MultiSegmentSegmenter-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/df/d8d/es__parser__h26x_8h_source.html b/docs/df/d8d/es__parser__h26x_8h_source.html index 81706bb0ce..adbdc3ba3a 100644 --- a/docs/df/d8d/es__parser__h26x_8h_source.html +++ b/docs/df/d8d/es__parser__h26x_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/es_parser_h26x.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    es_parser_h26x.h
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H26x_H_
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H26x_H_
    7 
    8 #include <stdint.h>
    9 
    10 #include <deque>
    11 #include <list>
    12 #include <memory>
    13 
    14 #include "packager/base/callback.h"
    15 #include "packager/base/compiler_specific.h"
    16 #include "packager/media/codecs/nalu_reader.h"
    17 #include "packager/media/formats/mp2t/es_parser.h"
    18 
    19 namespace shaka {
    20 namespace media {
    21 
    22 class H26xByteToUnitStreamConverter;
    23 class OffsetByteQueue;
    24 
    25 namespace mp2t {
    26 
    27 // A base class for common code between the H.264/H.265 es parsers.
    28 class EsParserH26x : public EsParser {
    29  public:
    30  EsParserH26x(Nalu::CodecType type,
    31  std::unique_ptr<H26xByteToUnitStreamConverter> stream_converter,
    32  uint32_t pid,
    33  const EmitSampleCB& emit_sample_cb);
    34  ~EsParserH26x() override;
    35 
    36  // EsParser implementation overrides.
    37  bool Parse(const uint8_t* buf, int size, int64_t pts, int64_t dts) override;
    38  void Flush() override;
    39  void Reset() override;
    40 
    41  protected:
    42  struct VideoSliceInfo {
    43  bool valid = false;
    44  bool is_key_frame = false;
    45  // Both pps_id and frame_num are extracted from slice header (frame_num is
    46  // only for H.264).
    47  int pps_id = 0;
    48  int frame_num = 0;
    49  };
    50 
    51  const H26xByteToUnitStreamConverter* stream_converter() const {
    52  return stream_converter_.get();
    53  }
    54 
    55  private:
    56  struct TimingDesc {
    57  int64_t dts;
    58  int64_t pts;
    59  };
    60  struct NaluInfo {
    61  // NOTE: Nalu does not own the memory pointed by its data pointers. The
    62  // caller owns and maintains the memory.
    63  Nalu nalu;
    64  // The offset of the NALU from the beginning of the stream, usable as an
    65  // argument to OffsetByteQueue. This points to the start code.
    66  uint64_t position = 0;
    67  uint8_t start_code_size = 0;
    68  };
    69 
    70  // Processes a NAL unit found in ParseInternal. |video_slice_info| should not
    71  // be null, it will contain the video slice info if it is a video slice nalu
    72  // and it is processed successfully; otherwise the |valid| member will be set
    73  // to false with other members untouched.
    74  virtual bool ProcessNalu(const Nalu& nalu,
    75  VideoSliceInfo* video_slice_info) = 0;
    76 
    77  // Update the video decoder config.
    78  // Return true if successful.
    79  virtual bool UpdateVideoDecoderConfig(int pps_id) = 0;
    80 
    81  // Finds the NAL unit by finding the next start code. This will modify the
    82  // search position.
    83  // Returns true when it has found the NALU.
    84  bool SearchForNalu(uint64_t* position, Nalu* nalu);
    85 
    86  // Resumes the H26x ES parsing.
    87  // Return true if successful.
    88  bool ParseInternal();
    89 
    90  // Emit the current access unit if exists.
    91  bool EmitCurrentAccessUnit();
    92 
    93  // Emit a frame whose position in the ES queue starts at |access_unit_pos|.
    94  // Returns true if successful, false if no PTS is available for the frame.
    95  bool EmitFrame(int64_t access_unit_pos,
    96  int access_unit_size,
    97  bool is_key_frame,
    98  int pps_id);
    99 
    100  // Callback to pass the frames.
    101  EmitSampleCB emit_sample_cb_;
    102 
    103  // The type of stream being parsed.
    104  Nalu::CodecType type_;
    105 
    106  // Bytes of the ES stream that have not been emitted yet.
    107  std::unique_ptr<media::OffsetByteQueue> es_queue_;
    108  std::list<std::pair<int64_t, TimingDesc>> timing_desc_list_;
    109 
    110  // Parser state.
    111  // The position of the search head.
    112  uint64_t current_search_position_ = 0;
    113  // Current access unit starting position.
    114  uint64_t current_access_unit_position_ = 0;
    115  // The VideoSliceInfo in the current access unit, useful for first vcl nalu
    116  // detection (for H.264).
    117  VideoSliceInfo current_video_slice_info_;
    118  bool next_access_unit_position_set_ = false;
    119  uint64_t next_access_unit_position_ = 0;
    120  // Current nalu information.
    121  std::unique_ptr<NaluInfo> current_nalu_info_;
    122  // This is really a temporary storage for the next nalu information.
    123  std::unique_ptr<NaluInfo> next_nalu_info_;
    124 
    125  // Filter to convert H.264/H.265 Annex B byte stream to unit stream.
    126  std::unique_ptr<H26xByteToUnitStreamConverter> stream_converter_;
    127 
    128  // Frame for which we do not yet have a duration.
    129  std::shared_ptr<MediaSample> pending_sample_;
    130  uint64_t pending_sample_duration_ = 0;
    131 
    132  // Indicates whether waiting for first key frame.
    133  bool waiting_for_key_frame_ = true;
    134 };
    135 
    136 } // namespace mp2t
    137 } // namespace media
    138 } // namespace shaka
    139 
    140 #endif
    - -
    All the methods that are virtual are virtual for mocking.
    -
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    - - +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H26x_H_
    +
    6 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_H26x_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 
    +
    10 #include <deque>
    +
    11 #include <list>
    +
    12 #include <memory>
    +
    13 
    +
    14 #include "packager/base/callback.h"
    +
    15 #include "packager/base/compiler_specific.h"
    +
    16 #include "packager/media/codecs/nalu_reader.h"
    +
    17 #include "packager/media/formats/mp2t/es_parser.h"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 
    +
    22 class H26xByteToUnitStreamConverter;
    +
    23 class OffsetByteQueue;
    +
    24 
    +
    25 namespace mp2t {
    +
    26 
    +
    27 // A base class for common code between the H.264/H.265 es parsers.
    +
    28 class EsParserH26x : public EsParser {
    +
    29  public:
    +
    30  EsParserH26x(Nalu::CodecType type,
    +
    31  std::unique_ptr<H26xByteToUnitStreamConverter> stream_converter,
    +
    32  uint32_t pid,
    +
    33  const EmitSampleCB& emit_sample_cb);
    +
    34  ~EsParserH26x() override;
    +
    35 
    +
    36  // EsParser implementation overrides.
    +
    37  bool Parse(const uint8_t* buf, int size, int64_t pts, int64_t dts) override;
    +
    38  bool Flush() override;
    +
    39  void Reset() override;
    +
    40 
    +
    41  protected:
    +
    42  struct VideoSliceInfo {
    +
    43  bool valid = false;
    +
    44  bool is_key_frame = false;
    +
    45  // Both pps_id and frame_num are extracted from slice header (frame_num is
    +
    46  // only for H.264).
    +
    47  int pps_id = 0;
    +
    48  int frame_num = 0;
    +
    49  };
    +
    50 
    +
    51  const H26xByteToUnitStreamConverter* stream_converter() const {
    +
    52  return stream_converter_.get();
    +
    53  }
    +
    54 
    +
    55  private:
    +
    56  struct TimingDesc {
    +
    57  int64_t dts;
    +
    58  int64_t pts;
    +
    59  };
    +
    60  struct NaluInfo {
    +
    61  // NOTE: Nalu does not own the memory pointed by its data pointers. The
    +
    62  // caller owns and maintains the memory.
    +
    63  Nalu nalu;
    +
    64  // The offset of the NALU from the beginning of the stream, usable as an
    +
    65  // argument to OffsetByteQueue. This points to the start code.
    +
    66  uint64_t position = 0;
    +
    67  uint8_t start_code_size = 0;
    +
    68  };
    +
    69 
    +
    70  // Processes a NAL unit found in ParseInternal. |video_slice_info| should not
    +
    71  // be null, it will contain the video slice info if it is a video slice nalu
    +
    72  // and it is processed successfully; otherwise the |valid| member will be set
    +
    73  // to false with other members untouched.
    +
    74  virtual bool ProcessNalu(const Nalu& nalu,
    +
    75  VideoSliceInfo* video_slice_info) = 0;
    +
    76 
    +
    77  // Update the video decoder config.
    +
    78  // Return true if successful.
    +
    79  virtual bool UpdateVideoDecoderConfig(int pps_id) = 0;
    +
    80 
    +
    81  // Finds the NAL unit by finding the next start code. This will modify the
    +
    82  // search position.
    +
    83  // Returns true when it has found the NALU.
    +
    84  bool SearchForNalu(uint64_t* position, Nalu* nalu);
    +
    85 
    +
    86  // Resumes the H26x ES parsing.
    +
    87  // Return true if successful.
    +
    88  bool ParseInternal();
    +
    89 
    +
    90  // Emit the current access unit if exists.
    +
    91  bool EmitCurrentAccessUnit();
    +
    92 
    +
    93  // Emit a frame whose position in the ES queue starts at |access_unit_pos|.
    +
    94  // Returns true if successful, false if no PTS is available for the frame.
    +
    95  bool EmitFrame(int64_t access_unit_pos,
    +
    96  int access_unit_size,
    +
    97  bool is_key_frame,
    +
    98  int pps_id);
    +
    99 
    +
    100  // Callback to pass the frames.
    +
    101  EmitSampleCB emit_sample_cb_;
    +
    102 
    +
    103  // The type of stream being parsed.
    +
    104  Nalu::CodecType type_;
    +
    105 
    +
    106  // Bytes of the ES stream that have not been emitted yet.
    +
    107  std::unique_ptr<media::OffsetByteQueue> es_queue_;
    +
    108  std::list<std::pair<int64_t, TimingDesc>> timing_desc_list_;
    +
    109 
    +
    110  // Parser state.
    +
    111  // The position of the search head.
    +
    112  uint64_t current_search_position_ = 0;
    +
    113  // Current access unit starting position.
    +
    114  uint64_t current_access_unit_position_ = 0;
    +
    115  // The VideoSliceInfo in the current access unit, useful for first vcl nalu
    +
    116  // detection (for H.264).
    +
    117  VideoSliceInfo current_video_slice_info_;
    +
    118  bool next_access_unit_position_set_ = false;
    +
    119  uint64_t next_access_unit_position_ = 0;
    +
    120  // Current nalu information.
    +
    121  std::unique_ptr<NaluInfo> current_nalu_info_;
    +
    122  // This is really a temporary storage for the next nalu information.
    +
    123  std::unique_ptr<NaluInfo> next_nalu_info_;
    +
    124 
    +
    125  // Filter to convert H.264/H.265 Annex B byte stream to unit stream.
    +
    126  std::unique_ptr<H26xByteToUnitStreamConverter> stream_converter_;
    +
    127 
    +
    128  // Frame for which we do not yet have a duration.
    +
    129  std::shared_ptr<MediaSample> pending_sample_;
    +
    130  uint64_t pending_sample_duration_ = 0;
    +
    131 
    +
    132  // Indicates whether waiting for first key frame.
    +
    133  bool waiting_for_key_frame_ = true;
    +
    134 };
    +
    135 
    +
    136 } // namespace mp2t
    +
    137 } // namespace media
    +
    138 } // namespace shaka
    +
    139 
    +
    140 #endif
    +
    A base class that is used to convert H.26x byte streams to NAL unit streams.
    + + + +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/df/d94/classshaka_1_1RepresentationStateChangeListener.html b/docs/df/d94/classshaka_1_1RepresentationStateChangeListener.html index d5330abe5b..8b2ae029de 100644 --- a/docs/df/d94/classshaka_1_1RepresentationStateChangeListener.html +++ b/docs/df/d94/classshaka_1_1RepresentationStateChangeListener.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::RepresentationStateChangeListener Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */

    Detailed Description

    -

    Definition at line 32 of file representation.h.

    +

    Definition at line 28 of file representation.h.

    Member Function Documentation

    ◆ OnNewSegmentForRepresentation()

    @@ -173,9 +176,7 @@ Public Member Functions
    diff --git a/docs/df/d96/xml__node_8cc_source.html b/docs/df/d96/xml__node_8cc_source.html index 787aa48a50..bce38bef31 100644 --- a/docs/df/d96/xml__node_8cc_source.html +++ b/docs/df/d96/xml__node_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/xml/xml_node.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    xml_node.cc
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #include "packager/mpd/base/xml/xml_node.h"
    8 
    9 #include <gflags/gflags.h>
    10 
    11 #include <limits>
    12 #include <set>
    13 
    14 #include "packager/base/logging.h"
    15 #include "packager/base/macros.h"
    16 #include "packager/base/strings/string_number_conversions.h"
    17 #include "packager/base/sys_byteorder.h"
    18 #include "packager/mpd/base/media_info.pb.h"
    19 #include "packager/mpd/base/mpd_utils.h"
    20 #include "packager/mpd/base/segment_info.h"
    21 
    22 DEFINE_bool(segment_template_constant_duration,
    23  false,
    24  "Generates SegmentTemplate@duration if all segments except the "
    25  "last one has the same duration if this flag is set to true.");
    26 
    27 namespace shaka {
    28 
    29 using xml::XmlNode;
    30 typedef MediaInfo::AudioInfo AudioInfo;
    31 typedef MediaInfo::VideoInfo VideoInfo;
    32 
    33 namespace {
    34 const char kEC3Codec[] = "ec-3";
    35 
    36 std::string RangeToString(const Range& range) {
    37  return base::Uint64ToString(range.begin()) + "-" +
    38  base::Uint64ToString(range.end());
    39 }
    40 
    41 // Check if segments are continuous and all segments except the last one are of
    42 // the same duration.
    43 bool IsTimelineConstantDuration(const std::list<SegmentInfo>& segment_infos,
    44  uint32_t start_number) {
    45  if (!FLAGS_segment_template_constant_duration)
    46  return false;
    47 
    48  DCHECK(!segment_infos.empty());
    49  if (segment_infos.size() > 2)
    50  return false;
    51 
    52  const SegmentInfo& first_segment = segment_infos.front();
    53  if (first_segment.start_time != first_segment.duration * (start_number - 1))
    54  return false;
    55 
    56  if (segment_infos.size() == 1)
    57  return true;
    58 
    59  const SegmentInfo& last_segment = segment_infos.back();
    60  if (last_segment.repeat != 0)
    61  return false;
    62 
    63  const int64_t expected_last_segment_start_time =
    64  first_segment.start_time +
    65  first_segment.duration * (first_segment.repeat + 1);
    66  return expected_last_segment_start_time == last_segment.start_time;
    67 }
    68 
    69 bool PopulateSegmentTimeline(const std::list<SegmentInfo>& segment_infos,
    70  XmlNode* segment_timeline) {
    71  for (const SegmentInfo& segment_info : segment_infos) {
    72  XmlNode s_element("S");
    73  s_element.SetIntegerAttribute("t", segment_info.start_time);
    74  s_element.SetIntegerAttribute("d", segment_info.duration);
    75  if (segment_info.repeat > 0)
    76  s_element.SetIntegerAttribute("r", segment_info.repeat);
    77 
    78  CHECK(segment_timeline->AddChild(s_element.PassScopedPtr()));
    79  }
    80 
    81  return true;
    82 }
    83 
    84 void CollectNamespaceFromName(const std::string& name,
    85  std::set<std::string>* namespaces) {
    86  const size_t pos = name.find(':');
    87  if (pos != std::string::npos)
    88  namespaces->insert(name.substr(0, pos));
    89 }
    90 
    91 void TraverseAttrsAndCollectNamespaces(const xmlAttr* attr,
    92  std::set<std::string>* namespaces) {
    93  for (const xmlAttr* cur_attr = attr; cur_attr; cur_attr = cur_attr->next) {
    94  CollectNamespaceFromName(reinterpret_cast<const char*>(cur_attr->name),
    95  namespaces);
    96  }
    97 }
    98 
    99 void TraverseNodesAndCollectNamespaces(const xmlNode* node,
    100  std::set<std::string>* namespaces) {
    101  for (const xmlNode* cur_node = node; cur_node; cur_node = cur_node->next) {
    102  CollectNamespaceFromName(reinterpret_cast<const char*>(cur_node->name),
    103  namespaces);
    104 
    105  TraverseNodesAndCollectNamespaces(cur_node->children, namespaces);
    106  TraverseAttrsAndCollectNamespaces(cur_node->properties, namespaces);
    107  }
    108 }
    109 
    110 } // namespace
    111 
    112 namespace xml {
    113 
    114 XmlNode::XmlNode(const char* name) : node_(xmlNewNode(NULL, BAD_CAST name)) {
    115  DCHECK(name);
    116  DCHECK(node_);
    117 }
    118 
    119 XmlNode::~XmlNode() {}
    120 
    121 bool XmlNode::AddChild(scoped_xml_ptr<xmlNode> child) {
    122  DCHECK(node_);
    123  DCHECK(child);
    124  if (!xmlAddChild(node_.get(), child.get()))
    125  return false;
    126 
    127  // Reaching here means the ownership of |child| transfered to |node_|.
    128  // Release the pointer so that it doesn't get destructed in this scope.
    129  ignore_result(child.release());
    130  return true;
    131 }
    132 
    133 bool XmlNode::AddElements(const std::vector<Element>& elements) {
    134  for (size_t element_index = 0; element_index < elements.size();
    135  ++element_index) {
    136  const Element& child_element = elements[element_index];
    137  XmlNode child_node(child_element.name.c_str());
    138  for (std::map<std::string, std::string>::const_iterator attribute_it =
    139  child_element.attributes.begin();
    140  attribute_it != child_element.attributes.end(); ++attribute_it) {
    141  child_node.SetStringAttribute(attribute_it->first.c_str(),
    142  attribute_it->second);
    143  }
    144 
    145  // Note that somehow |SetContent| needs to be called before |AddElements|
    146  // otherwise the added children will be overwritten by the content.
    147  child_node.SetContent(child_element.content);
    148 
    149  // Recursively set children for the child.
    150  if (!child_node.AddElements(child_element.subelements))
    151  return false;
    152 
    153  if (!xmlAddChild(node_.get(), child_node.GetRawPtr())) {
    154  LOG(ERROR) << "Failed to set child " << child_element.name
    155  << " to parent element "
    156  << reinterpret_cast<const char*>(node_->name);
    157  return false;
    158  }
    159  // Reaching here means the ownership of |child_node| transfered to |node_|.
    160  // Release the pointer so that it doesn't get destructed in this scope.
    161  ignore_result(child_node.Release());
    162  }
    163  return true;
    164 }
    165 
    166 void XmlNode::SetStringAttribute(const char* attribute_name,
    167  const std::string& attribute) {
    168  DCHECK(node_);
    169  DCHECK(attribute_name);
    170  xmlSetProp(node_.get(), BAD_CAST attribute_name, BAD_CAST attribute.c_str());
    171 }
    172 
    173 void XmlNode::SetIntegerAttribute(const char* attribute_name, uint64_t number) {
    174  DCHECK(node_);
    175  DCHECK(attribute_name);
    176  xmlSetProp(node_.get(),
    177  BAD_CAST attribute_name,
    178  BAD_CAST (base::Uint64ToString(number).c_str()));
    179 }
    180 
    181 void XmlNode::SetFloatingPointAttribute(const char* attribute_name,
    182  double number) {
    183  DCHECK(node_);
    184  DCHECK(attribute_name);
    185  xmlSetProp(node_.get(), BAD_CAST attribute_name,
    186  BAD_CAST(base::DoubleToString(number).c_str()));
    187 }
    188 
    189 void XmlNode::SetId(uint32_t id) {
    190  SetIntegerAttribute("id", id);
    191 }
    192 
    193 void XmlNode::SetContent(const std::string& content) {
    194  DCHECK(node_);
    195  xmlNodeSetContent(node_.get(), BAD_CAST content.c_str());
    196 }
    197 
    198 std::set<std::string> XmlNode::ExtractReferencedNamespaces() {
    199  std::set<std::string> namespaces;
    200  TraverseNodesAndCollectNamespaces(node_.get(), &namespaces);
    201  return namespaces;
    202 }
    203 
    204 scoped_xml_ptr<xmlNode> XmlNode::PassScopedPtr() {
    205  DVLOG(2) << "Passing node_.";
    206  DCHECK(node_);
    207  return std::move(node_);
    208 }
    209 
    210 xmlNodePtr XmlNode::Release() {
    211  DVLOG(2) << "Releasing node_.";
    212  DCHECK(node_);
    213  return node_.release();
    214 }
    215 
    216 xmlNodePtr XmlNode::GetRawPtr() {
    217  return node_.get();
    218 }
    219 
    220 RepresentationBaseXmlNode::RepresentationBaseXmlNode(const char* name)
    221  : XmlNode(name) {}
    222 RepresentationBaseXmlNode::~RepresentationBaseXmlNode() {}
    223 
    224 bool RepresentationBaseXmlNode::AddContentProtectionElements(
    225  const std::list<ContentProtectionElement>& content_protection_elements) {
    226  std::list<ContentProtectionElement>::const_iterator content_protection_it =
    227  content_protection_elements.begin();
    228  for (; content_protection_it != content_protection_elements.end();
    229  ++content_protection_it) {
    230  if (!AddContentProtectionElement(*content_protection_it))
    231  return false;
    232  }
    233 
    234  return true;
    235 }
    236 
    238  const std::string& scheme_id_uri,
    239  const std::string& value) {
    240  AddDescriptor("SupplementalProperty", scheme_id_uri, value);
    241 }
    242 
    244  const std::string& scheme_id_uri,
    245  const std::string& value) {
    246  AddDescriptor("EssentialProperty", scheme_id_uri, value);
    247 }
    248 
    250  const std::string& descriptor_name,
    251  const std::string& scheme_id_uri,
    252  const std::string& value) {
    253  XmlNode descriptor(descriptor_name.c_str());
    254  descriptor.SetStringAttribute("schemeIdUri", scheme_id_uri);
    255  if (!value.empty())
    256  descriptor.SetStringAttribute("value", value);
    257  return AddChild(descriptor.PassScopedPtr());
    258 }
    259 
    260 bool RepresentationBaseXmlNode::AddContentProtectionElement(
    261  const ContentProtectionElement& content_protection_element) {
    262  XmlNode content_protection_node("ContentProtection");
    263 
    264  // @value is an optional attribute.
    265  if (!content_protection_element.value.empty()) {
    266  content_protection_node.SetStringAttribute(
    267  "value", content_protection_element.value);
    268  }
    269  content_protection_node.SetStringAttribute(
    270  "schemeIdUri", content_protection_element.scheme_id_uri);
    271 
    272  typedef std::map<std::string, std::string> AttributesMapType;
    273  const AttributesMapType& additional_attributes =
    274  content_protection_element.additional_attributes;
    275 
    276  AttributesMapType::const_iterator attributes_it =
    277  additional_attributes.begin();
    278  for (; attributes_it != additional_attributes.end(); ++attributes_it) {
    279  content_protection_node.SetStringAttribute(attributes_it->first.c_str(),
    280  attributes_it->second);
    281  }
    282 
    283  if (!content_protection_node.AddElements(
    284  content_protection_element.subelements)) {
    285  return false;
    286  }
    287  return AddChild(content_protection_node.PassScopedPtr());
    288 }
    289 
    290 AdaptationSetXmlNode::AdaptationSetXmlNode()
    291  : RepresentationBaseXmlNode("AdaptationSet") {}
    292 AdaptationSetXmlNode::~AdaptationSetXmlNode() {}
    293 
    295  const std::string& scheme_id_uri,
    296  const std::string& value) {
    297  AddDescriptor("Accessibility", scheme_id_uri, value);
    298 }
    299 
    300 void AdaptationSetXmlNode::AddRoleElement(const std::string& scheme_id_uri,
    301  const std::string& value) {
    302  AddDescriptor("Role", scheme_id_uri, value);
    303 }
    304 
    305 RepresentationXmlNode::RepresentationXmlNode()
    306  : RepresentationBaseXmlNode("Representation") {}
    307 RepresentationXmlNode::~RepresentationXmlNode() {}
    308 
    309 bool RepresentationXmlNode::AddVideoInfo(const VideoInfo& video_info,
    310  bool set_width,
    311  bool set_height,
    312  bool set_frame_rate) {
    313  if (!video_info.has_width() || !video_info.has_height()) {
    314  LOG(ERROR) << "Missing width or height for adding a video info.";
    315  return false;
    316  }
    317 
    318  if (video_info.has_pixel_width() && video_info.has_pixel_height()) {
    319  SetStringAttribute("sar", base::IntToString(video_info.pixel_width()) +
    320  ":" +
    321  base::IntToString(video_info.pixel_height()));
    322  }
    323 
    324  if (set_width)
    325  SetIntegerAttribute("width", video_info.width());
    326  if (set_height)
    327  SetIntegerAttribute("height", video_info.height());
    328  if (set_frame_rate) {
    329  SetStringAttribute("frameRate",
    330  base::IntToString(video_info.time_scale()) + "/" +
    331  base::IntToString(video_info.frame_duration()));
    332  }
    333 
    334  if (video_info.has_playback_rate()) {
    335  SetStringAttribute("maxPlayoutRate",
    336  base::IntToString(video_info.playback_rate()));
    337  // Since the trick play stream contains only key frames, there is no coding
    338  // dependency on the main stream. Simply set the codingDependency to false.
    339  // TODO(hmchen): propagate this attribute up to the AdaptationSet, since
    340  // all are set to false.
    341  SetStringAttribute("codingDependency", "false");
    342  }
    343  return true;
    344 }
    345 
    346 bool RepresentationXmlNode::AddAudioInfo(const AudioInfo& audio_info) {
    347  if (!AddAudioChannelInfo(audio_info))
    348  return false;
    349 
    350  AddAudioSamplingRateInfo(audio_info);
    351  return true;
    352 }
    353 
    354 bool RepresentationXmlNode::AddVODOnlyInfo(const MediaInfo& media_info) {
    355  if (media_info.has_media_file_url()) {
    356  XmlNode base_url("BaseURL");
    357  base_url.SetContent(media_info.media_file_url());
    358 
    359  if (!AddChild(base_url.PassScopedPtr()))
    360  return false;
    361  }
    362 
    363  const bool need_segment_base = media_info.has_index_range() ||
    364  media_info.has_init_range() ||
    365  media_info.has_reference_time_scale();
    366 
    367  if (need_segment_base) {
    368  XmlNode segment_base("SegmentBase");
    369  if (media_info.has_index_range()) {
    370  segment_base.SetStringAttribute("indexRange",
    371  RangeToString(media_info.index_range()));
    372  }
    373 
    374  if (media_info.has_reference_time_scale()) {
    375  segment_base.SetIntegerAttribute("timescale",
    376  media_info.reference_time_scale());
    377  }
    378 
    379  if (media_info.has_presentation_time_offset()) {
    380  segment_base.SetIntegerAttribute("presentationTimeOffset",
    381  media_info.presentation_time_offset());
    382  }
    383 
    384  if (media_info.has_init_range()) {
    385  XmlNode initialization("Initialization");
    386  initialization.SetStringAttribute("range",
    387  RangeToString(media_info.init_range()));
    388 
    389  if (!segment_base.AddChild(initialization.PassScopedPtr()))
    390  return false;
    391  }
    392 
    393  if (!AddChild(segment_base.PassScopedPtr()))
    394  return false;
    395  }
    396 
    397  return true;
    398 }
    399 
    401  const MediaInfo& media_info,
    402  const std::list<SegmentInfo>& segment_infos,
    403  uint32_t start_number) {
    404  XmlNode segment_template("SegmentTemplate");
    405  if (media_info.has_reference_time_scale()) {
    406  segment_template.SetIntegerAttribute("timescale",
    407  media_info.reference_time_scale());
    408  }
    409 
    410  if (media_info.has_presentation_time_offset()) {
    411  segment_template.SetIntegerAttribute("presentationTimeOffset",
    412  media_info.presentation_time_offset());
    413  }
    414 
    415  if (media_info.has_init_segment_url()) {
    416  segment_template.SetStringAttribute("initialization",
    417  media_info.init_segment_url());
    418  }
    419 
    420  if (media_info.has_segment_template_url()) {
    421  segment_template.SetStringAttribute("media",
    422  media_info.segment_template_url());
    423  segment_template.SetIntegerAttribute("startNumber", start_number);
    424  }
    425 
    426  if (!segment_infos.empty()) {
    427  // Don't use SegmentTimeline if all segments except the last one are of
    428  // the same duration.
    429  if (IsTimelineConstantDuration(segment_infos, start_number)) {
    430  segment_template.SetIntegerAttribute("duration",
    431  segment_infos.front().duration);
    432  } else {
    433  XmlNode segment_timeline("SegmentTimeline");
    434  if (!PopulateSegmentTimeline(segment_infos, &segment_timeline) ||
    435  !segment_template.AddChild(segment_timeline.PassScopedPtr())) {
    436  return false;
    437  }
    438  }
    439  }
    440  return AddChild(segment_template.PassScopedPtr());
    441 }
    442 
    443 bool RepresentationXmlNode::AddAudioChannelInfo(const AudioInfo& audio_info) {
    444  std::string audio_channel_config_scheme;
    445  std::string audio_channel_config_value;
    446 
    447  if (audio_info.codec() == kEC3Codec) {
    448  // Convert EC3 channel map into string of hexadecimal digits. Spec: DASH-IF
    449  // Interoperability Points v3.0 9.2.1.2.
    450  const uint16_t ec3_channel_map =
    451  base::HostToNet16(audio_info.codec_specific_data().ec3_channel_map());
    452  audio_channel_config_value =
    453  base::HexEncode(&ec3_channel_map, sizeof(ec3_channel_map));
    454  audio_channel_config_scheme =
    455  "tag:dolby.com,2014:dash:audio_channel_configuration:2011";
    456  } else {
    457  audio_channel_config_value = base::UintToString(audio_info.num_channels());
    458  audio_channel_config_scheme =
    459  "urn:mpeg:dash:23003:3:audio_channel_configuration:2011";
    460  }
    461 
    462  return AddDescriptor("AudioChannelConfiguration", audio_channel_config_scheme,
    463  audio_channel_config_value);
    464 }
    465 
    466 // MPD expects one number for sampling frequency, or if it is a range it should
    467 // be space separated.
    468 void RepresentationXmlNode::AddAudioSamplingRateInfo(
    469  const AudioInfo& audio_info) {
    470  if (audio_info.has_sampling_frequency())
    471  SetIntegerAttribute("audioSamplingRate", audio_info.sampling_frequency());
    472 }
    473 
    474 } // namespace xml
    475 } // namespace shaka
    bool AddVideoInfo(const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate)
    Definition: xml_node.cc:309
    - -
    bool AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:249
    -
    std::set< std::string > ExtractReferencedNamespaces()
    Definition: xml_node.cc:198
    -
    void SetFloatingPointAttribute(const char *attribute_name, double number)
    Definition: xml_node.cc:181
    - - -
    scoped_xml_ptr< xmlNode > PassScopedPtr()
    Definition: xml_node.cc:204
    -
    XmlNode(const char *name)
    Definition: xml_node.cc:114
    -
    All the methods that are virtual are virtual for mocking.
    -
    bool AddVODOnlyInfo(const MediaInfo &media_info)
    Definition: xml_node.cc:354
    -
    void AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:243
    -
    void SetStringAttribute(const char *attribute_name, const std::string &attribute)
    Definition: xml_node.cc:166
    - -
    bool AddChild(scoped_xml_ptr< xmlNode > child)
    Definition: xml_node.cc:121
    -
    xmlNodePtr Release()
    Definition: xml_node.cc:210
    -
    bool AddLiveOnlyInfo(const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number)
    Definition: xml_node.cc:400
    -
    void SetId(uint32_t id)
    Definition: xml_node.cc:189
    -
    void AddAccessibilityElement(const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:294
    -
    bool AddElements(const std::vector< Element > &elements)
    Adds Elements to this node using the Element struct.
    Definition: xml_node.cc:133
    -
    void AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:237
    -
    void SetIntegerAttribute(const char *attribute_name, uint64_t number)
    Definition: xml_node.cc:173
    -
    void AddRoleElement(const std::string &scheme_id_uri, const std::string &value)
    Definition: xml_node.cc:300
    -
    void SetContent(const std::string &content)
    Definition: xml_node.cc:193
    -
    bool AddAudioInfo(const MediaInfo::AudioInfo &audio_info)
    Definition: xml_node.cc:346
    -
    xmlNodePtr GetRawPtr()
    Definition: xml_node.cc:216
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/mpd/base/xml/xml_node.h"
    +
    8 
    +
    9 #include <gflags/gflags.h>
    +
    10 #include <libxml/tree.h>
    +
    11 
    +
    12 #include <limits>
    +
    13 #include <set>
    +
    14 
    +
    15 #include "packager/base/logging.h"
    +
    16 #include "packager/base/macros.h"
    +
    17 #include "packager/base/strings/string_number_conversions.h"
    +
    18 #include "packager/base/sys_byteorder.h"
    +
    19 #include "packager/media/base/rcheck.h"
    +
    20 #include "packager/mpd/base/media_info.pb.h"
    +
    21 #include "packager/mpd/base/mpd_utils.h"
    +
    22 #include "packager/mpd/base/segment_info.h"
    +
    23 #include "packager/mpd/base/xml/scoped_xml_ptr.h"
    +
    24 
    +
    25 DEFINE_bool(segment_template_constant_duration,
    +
    26  false,
    +
    27  "Generates SegmentTemplate@duration if all segments except the "
    +
    28  "last one has the same duration if this flag is set to true.");
    +
    29 
    +
    30 DEFINE_bool(dash_add_last_segment_number_when_needed,
    +
    31  false,
    +
    32  "Adds a Supplemental Descriptor with @schemeIdUri "
    +
    33  "set to http://dashif.org/guidelines/last-segment-number with "
    +
    34  "the @value set to the last segment number.");
    +
    35 
    +
    36 namespace shaka {
    +
    37 
    +
    38 using xml::XmlNode;
    +
    39 typedef MediaInfo::AudioInfo AudioInfo;
    +
    40 typedef MediaInfo::VideoInfo VideoInfo;
    +
    41 
    +
    42 namespace {
    +
    43 const char kEC3Codec[] = "ec-3";
    +
    44 const char kAC4Codec[] = "ac-4";
    +
    45 
    +
    46 std::string RangeToString(const Range& range) {
    +
    47  return base::Uint64ToString(range.begin()) + "-" +
    +
    48  base::Uint64ToString(range.end());
    +
    49 }
    +
    50 
    +
    51 // Check if segments are continuous and all segments except the last one are of
    +
    52 // the same duration.
    +
    53 bool IsTimelineConstantDuration(const std::list<SegmentInfo>& segment_infos,
    +
    54  uint32_t start_number) {
    +
    55  if (!FLAGS_segment_template_constant_duration)
    +
    56  return false;
    +
    57 
    +
    58  DCHECK(!segment_infos.empty());
    +
    59  if (segment_infos.size() > 2)
    +
    60  return false;
    +
    61 
    +
    62  const SegmentInfo& first_segment = segment_infos.front();
    +
    63  if (first_segment.start_time != first_segment.duration * (start_number - 1))
    +
    64  return false;
    +
    65 
    +
    66  if (segment_infos.size() == 1)
    +
    67  return true;
    +
    68 
    +
    69  const SegmentInfo& last_segment = segment_infos.back();
    +
    70  if (last_segment.repeat != 0)
    +
    71  return false;
    +
    72 
    +
    73  const int64_t expected_last_segment_start_time =
    +
    74  first_segment.start_time +
    +
    75  first_segment.duration * (first_segment.repeat + 1);
    +
    76  return expected_last_segment_start_time == last_segment.start_time;
    +
    77 }
    +
    78 
    +
    79 bool PopulateSegmentTimeline(const std::list<SegmentInfo>& segment_infos,
    +
    80  XmlNode* segment_timeline) {
    +
    81  for (const SegmentInfo& segment_info : segment_infos) {
    +
    82  XmlNode s_element("S");
    +
    83  RCHECK(s_element.SetIntegerAttribute("t", segment_info.start_time));
    +
    84  RCHECK(s_element.SetIntegerAttribute("d", segment_info.duration));
    +
    85  if (segment_info.repeat > 0)
    +
    86  RCHECK(s_element.SetIntegerAttribute("r", segment_info.repeat));
    +
    87 
    +
    88  RCHECK(segment_timeline->AddChild(std::move(s_element)));
    +
    89  }
    +
    90 
    +
    91  return true;
    +
    92 }
    +
    93 
    +
    94 void CollectNamespaceFromName(const std::string& name,
    +
    95  std::set<std::string>* namespaces) {
    +
    96  const size_t pos = name.find(':');
    +
    97  if (pos != std::string::npos)
    +
    98  namespaces->insert(name.substr(0, pos));
    +
    99 }
    +
    100 
    +
    101 void TraverseAttrsAndCollectNamespaces(const xmlAttr* attr,
    +
    102  std::set<std::string>* namespaces) {
    +
    103  for (const xmlAttr* cur_attr = attr; cur_attr; cur_attr = cur_attr->next) {
    +
    104  CollectNamespaceFromName(reinterpret_cast<const char*>(cur_attr->name),
    +
    105  namespaces);
    +
    106  }
    +
    107 }
    +
    108 
    +
    109 void TraverseNodesAndCollectNamespaces(const xmlNode* node,
    +
    110  std::set<std::string>* namespaces) {
    +
    111  for (const xmlNode* cur_node = node; cur_node; cur_node = cur_node->next) {
    +
    112  CollectNamespaceFromName(reinterpret_cast<const char*>(cur_node->name),
    +
    113  namespaces);
    +
    114 
    +
    115  TraverseNodesAndCollectNamespaces(cur_node->children, namespaces);
    +
    116  TraverseAttrsAndCollectNamespaces(cur_node->properties, namespaces);
    +
    117  }
    +
    118 }
    +
    119 
    +
    120 } // namespace
    +
    121 
    +
    122 namespace xml {
    +
    123 
    +
    124 class XmlNode::Impl {
    +
    125  public:
    +
    126  scoped_xml_ptr<xmlNode> node;
    +
    127 };
    +
    128 
    +
    129 XmlNode::XmlNode(const std::string& name) : impl_(new Impl) {
    +
    130  impl_->node.reset(xmlNewNode(NULL, BAD_CAST name.c_str()));
    +
    131  DCHECK(impl_->node);
    +
    132 }
    +
    133 
    +
    134 XmlNode::XmlNode(XmlNode&&) = default;
    +
    135 
    +
    136 XmlNode::~XmlNode() {}
    +
    137 
    +
    138 XmlNode& XmlNode::operator=(XmlNode&&) = default;
    +
    139 
    + +
    141  DCHECK(impl_->node);
    +
    142  DCHECK(child.impl_->node);
    +
    143  RCHECK(xmlAddChild(impl_->node.get(), child.impl_->node.get()));
    +
    144 
    +
    145  // Reaching here means the ownership of |child| transfered to |node|.
    +
    146  // Release the pointer so that it doesn't get destructed in this scope.
    +
    147  ignore_result(child.impl_->node.release());
    +
    148  return true;
    +
    149 }
    +
    150 
    +
    151 bool XmlNode::AddElements(const std::vector<Element>& elements) {
    +
    152  for (size_t element_index = 0; element_index < elements.size();
    +
    153  ++element_index) {
    +
    154  const Element& child_element = elements[element_index];
    +
    155  XmlNode child_node(child_element.name);
    +
    156  for (std::map<std::string, std::string>::const_iterator attribute_it =
    +
    157  child_element.attributes.begin();
    +
    158  attribute_it != child_element.attributes.end(); ++attribute_it) {
    +
    159  RCHECK(child_node.SetStringAttribute(attribute_it->first,
    +
    160  attribute_it->second));
    +
    161  }
    +
    162 
    +
    163  // Note that somehow |SetContent| needs to be called before |AddElements|
    +
    164  // otherwise the added children will be overwritten by the content.
    +
    165  child_node.SetContent(child_element.content);
    +
    166 
    +
    167  // Recursively set children for the child.
    +
    168  RCHECK(child_node.AddElements(child_element.subelements));
    +
    169 
    +
    170  if (!xmlAddChild(impl_->node.get(), child_node.impl_->node.get())) {
    +
    171  LOG(ERROR) << "Failed to set child " << child_element.name
    +
    172  << " to parent element "
    +
    173  << reinterpret_cast<const char*>(impl_->node->name);
    +
    174  return false;
    +
    175  }
    +
    176  // Reaching here means the ownership of |child_node| transfered to |node|.
    +
    177  // Release the pointer so that it doesn't get destructed in this scope.
    +
    178  child_node.impl_->node.release();
    +
    179  }
    +
    180  return true;
    +
    181 }
    +
    182 
    +
    183 bool XmlNode::SetStringAttribute(const std::string& attribute_name,
    +
    184  const std::string& attribute) {
    +
    185  DCHECK(impl_->node);
    +
    186  return xmlSetProp(impl_->node.get(), BAD_CAST attribute_name.c_str(),
    +
    187  BAD_CAST attribute.c_str()) != nullptr;
    +
    188 }
    +
    189 
    +
    190 bool XmlNode::SetIntegerAttribute(const std::string& attribute_name,
    +
    191  uint64_t number) {
    +
    192  DCHECK(impl_->node);
    +
    193  return xmlSetProp(impl_->node.get(), BAD_CAST attribute_name.c_str(),
    +
    194  BAD_CAST(base::Uint64ToString(number).c_str())) != nullptr;
    +
    195 }
    +
    196 
    +
    197 bool XmlNode::SetFloatingPointAttribute(const std::string& attribute_name,
    +
    198  double number) {
    +
    199  DCHECK(impl_->node);
    +
    200  return xmlSetProp(impl_->node.get(), BAD_CAST attribute_name.c_str(),
    +
    201  BAD_CAST(base::DoubleToString(number).c_str())) != nullptr;
    +
    202 }
    +
    203 
    +
    204 bool XmlNode::SetId(uint32_t id) {
    +
    205  return SetIntegerAttribute("id", id);
    +
    206 }
    +
    207 
    +
    208 void XmlNode::AddContent(const std::string& content) {
    +
    209  DCHECK(impl_->node);
    +
    210  xmlNodeAddContent(impl_->node.get(), BAD_CAST content.c_str());
    +
    211 }
    +
    212 
    +
    213 void XmlNode::SetContent(const std::string& content) {
    +
    214  DCHECK(impl_->node);
    +
    215  xmlNodeSetContent(impl_->node.get(), BAD_CAST content.c_str());
    +
    216 }
    +
    217 
    +
    218 std::set<std::string> XmlNode::ExtractReferencedNamespaces() const {
    +
    219  std::set<std::string> namespaces;
    +
    220  TraverseNodesAndCollectNamespaces(impl_->node.get(), &namespaces);
    +
    221  return namespaces;
    +
    222 }
    +
    223 
    +
    224 std::string XmlNode::ToString(const std::string& comment) const {
    +
    225  // Create an xmlDoc from xmlNodePtr. The node is copied so ownership does not
    +
    226  // transfer.
    +
    227  xml::scoped_xml_ptr<xmlDoc> doc(xmlNewDoc(BAD_CAST "1.0"));
    +
    228  if (comment.empty()) {
    +
    229  xmlDocSetRootElement(doc.get(), xmlCopyNode(impl_->node.get(), true));
    +
    230  } else {
    +
    231  xml::scoped_xml_ptr<xmlNode> comment_xml(
    +
    232  xmlNewDocComment(doc.get(), BAD_CAST comment.c_str()));
    +
    233  xmlDocSetRootElement(doc.get(), comment_xml.get());
    +
    234  xmlAddSibling(comment_xml.release(), xmlCopyNode(impl_->node.get(), true));
    +
    235  }
    +
    236 
    +
    237  // Format the xmlDoc to string.
    +
    238  static const int kNiceFormat = 1;
    +
    239  int doc_str_size = 0;
    +
    240  xmlChar* doc_str = nullptr;
    +
    241  xmlDocDumpFormatMemoryEnc(doc.get(), &doc_str, &doc_str_size, "UTF-8",
    +
    242  kNiceFormat);
    +
    243  std::string output(doc_str, doc_str + doc_str_size);
    +
    244  xmlFree(doc_str);
    +
    245  return output;
    +
    246 }
    +
    247 
    +
    248 bool XmlNode::GetAttribute(const std::string& name, std::string* value) const {
    +
    249  xml::scoped_xml_ptr<xmlChar> str(
    +
    250  xmlGetProp(impl_->node.get(), BAD_CAST name.c_str()));
    +
    251  if (!str)
    +
    252  return false;
    +
    253  *value = reinterpret_cast<const char*>(str.get());
    +
    254  return true;
    +
    255 }
    +
    256 
    +
    257 xmlNode* XmlNode::GetRawPtr() const {
    +
    258  return impl_->node.get();
    +
    259 }
    +
    260 
    +
    261 RepresentationBaseXmlNode::RepresentationBaseXmlNode(const std::string& name)
    +
    262  : XmlNode(name) {}
    +
    263 RepresentationBaseXmlNode::~RepresentationBaseXmlNode() {}
    +
    264 
    +
    265 bool RepresentationBaseXmlNode::AddContentProtectionElements(
    +
    266  const std::list<ContentProtectionElement>& content_protection_elements) {
    +
    267  for (const auto& elem : content_protection_elements) {
    +
    268  RCHECK(AddContentProtectionElement(elem));
    +
    269  }
    +
    270 
    +
    271  return true;
    +
    272 }
    +
    273 
    + +
    275  const std::string& scheme_id_uri,
    +
    276  const std::string& value) {
    +
    277  return AddDescriptor("SupplementalProperty", scheme_id_uri, value);
    +
    278 }
    +
    279 
    + +
    281  const std::string& scheme_id_uri,
    +
    282  const std::string& value) {
    +
    283  return AddDescriptor("EssentialProperty", scheme_id_uri, value);
    +
    284 }
    +
    285 
    + +
    287  const std::string& descriptor_name,
    +
    288  const std::string& scheme_id_uri,
    +
    289  const std::string& value) {
    +
    290  XmlNode descriptor(descriptor_name);
    +
    291  RCHECK(descriptor.SetStringAttribute("schemeIdUri", scheme_id_uri));
    +
    292  if (!value.empty())
    +
    293  RCHECK(descriptor.SetStringAttribute("value", value));
    +
    294  return AddChild(std::move(descriptor));
    +
    295 }
    +
    296 
    +
    297 bool RepresentationBaseXmlNode::AddContentProtectionElement(
    +
    298  const ContentProtectionElement& content_protection_element) {
    +
    299  XmlNode content_protection_node("ContentProtection");
    +
    300 
    +
    301  // @value is an optional attribute.
    +
    302  if (!content_protection_element.value.empty()) {
    +
    303  RCHECK(content_protection_node.SetStringAttribute(
    +
    304  "value", content_protection_element.value));
    +
    305  }
    +
    306  RCHECK(content_protection_node.SetStringAttribute(
    +
    307  "schemeIdUri", content_protection_element.scheme_id_uri));
    +
    308 
    +
    309  for (const auto& pair : content_protection_element.additional_attributes) {
    +
    310  RCHECK(content_protection_node.SetStringAttribute(pair.first, pair.second));
    +
    311  }
    +
    312 
    +
    313  RCHECK(content_protection_node.AddElements(
    +
    314  content_protection_element.subelements));
    +
    315  return AddChild(std::move(content_protection_node));
    +
    316 }
    +
    317 
    +
    318 AdaptationSetXmlNode::AdaptationSetXmlNode()
    +
    319  : RepresentationBaseXmlNode("AdaptationSet") {}
    +
    320 AdaptationSetXmlNode::~AdaptationSetXmlNode() {}
    +
    321 
    + +
    323  const std::string& scheme_id_uri,
    +
    324  const std::string& value) {
    +
    325  return AddDescriptor("Accessibility", scheme_id_uri, value);
    +
    326 }
    +
    327 
    +
    328 bool AdaptationSetXmlNode::AddRoleElement(const std::string& scheme_id_uri,
    +
    329  const std::string& value) {
    +
    330  return AddDescriptor("Role", scheme_id_uri, value);
    +
    331 }
    +
    332 
    +
    333 RepresentationXmlNode::RepresentationXmlNode()
    +
    334  : RepresentationBaseXmlNode("Representation") {}
    +
    335 RepresentationXmlNode::~RepresentationXmlNode() {}
    +
    336 
    +
    337 bool RepresentationXmlNode::AddVideoInfo(const VideoInfo& video_info,
    +
    338  bool set_width,
    +
    339  bool set_height,
    +
    340  bool set_frame_rate) {
    +
    341  if (!video_info.has_width() || !video_info.has_height()) {
    +
    342  LOG(ERROR) << "Missing width or height for adding a video info.";
    +
    343  return false;
    +
    344  }
    +
    345 
    +
    346  if (video_info.has_pixel_width() && video_info.has_pixel_height()) {
    +
    347  RCHECK(SetStringAttribute(
    +
    348  "sar", base::IntToString(video_info.pixel_width()) + ":" +
    +
    349  base::IntToString(video_info.pixel_height())));
    +
    350  }
    +
    351 
    +
    352  if (set_width)
    +
    353  RCHECK(SetIntegerAttribute("width", video_info.width()));
    +
    354  if (set_height)
    +
    355  RCHECK(SetIntegerAttribute("height", video_info.height()));
    +
    356  if (set_frame_rate) {
    +
    357  RCHECK(SetStringAttribute(
    +
    358  "frameRate", base::IntToString(video_info.time_scale()) + "/" +
    +
    359  base::IntToString(video_info.frame_duration())));
    +
    360  }
    +
    361 
    +
    362  if (video_info.has_playback_rate()) {
    +
    363  RCHECK(SetStringAttribute("maxPlayoutRate",
    +
    364  base::IntToString(video_info.playback_rate())));
    +
    365  // Since the trick play stream contains only key frames, there is no coding
    +
    366  // dependency on the main stream. Simply set the codingDependency to false.
    +
    367  // TODO(hmchen): propagate this attribute up to the AdaptationSet, since
    +
    368  // all are set to false.
    +
    369  RCHECK(SetStringAttribute("codingDependency", "false"));
    +
    370  }
    +
    371  return true;
    +
    372 }
    +
    373 
    +
    374 bool RepresentationXmlNode::AddAudioInfo(const AudioInfo& audio_info) {
    +
    375  return AddAudioChannelInfo(audio_info) &&
    +
    376  AddAudioSamplingRateInfo(audio_info);
    +
    377 }
    +
    378 
    +
    379 bool RepresentationXmlNode::AddVODOnlyInfo(const MediaInfo& media_info) {
    +
    380  const bool use_segment_list_text =
    +
    381  media_info.has_text_info() && media_info.has_presentation_time_offset();
    +
    382 
    +
    383  if (media_info.has_media_file_url() && !use_segment_list_text) {
    +
    384  XmlNode base_url("BaseURL");
    +
    385  base_url.SetContent(media_info.media_file_url());
    +
    386 
    +
    387  RCHECK(AddChild(std::move(base_url)));
    +
    388  }
    +
    389 
    +
    390  const bool need_segment_base =
    +
    391  media_info.has_index_range() || media_info.has_init_range() ||
    +
    392  (media_info.has_reference_time_scale() && !media_info.has_text_info());
    +
    393  DCHECK(!need_segment_base || !use_segment_list_text);
    +
    394 
    +
    395  if (need_segment_base || use_segment_list_text) {
    +
    396  XmlNode child(need_segment_base ? "SegmentBase" : "SegmentList");
    +
    397  if (media_info.has_index_range()) {
    +
    398  RCHECK(child.SetStringAttribute("indexRange",
    +
    399  RangeToString(media_info.index_range())));
    +
    400  }
    +
    401 
    +
    402  if (media_info.has_reference_time_scale()) {
    +
    403  RCHECK(child.SetIntegerAttribute("timescale",
    +
    404  media_info.reference_time_scale()));
    +
    405  }
    +
    406 
    +
    407  if (media_info.has_presentation_time_offset()) {
    +
    408  RCHECK(child.SetIntegerAttribute("presentationTimeOffset",
    +
    409  media_info.presentation_time_offset()));
    +
    410  }
    +
    411 
    +
    412  if (media_info.has_init_range()) {
    +
    413  XmlNode initialization("Initialization");
    +
    414  RCHECK(initialization.SetStringAttribute(
    +
    415  "range", RangeToString(media_info.init_range())));
    +
    416 
    +
    417  RCHECK(child.AddChild(std::move(initialization)));
    +
    418  }
    +
    419 
    +
    420  if (use_segment_list_text) {
    +
    421  XmlNode media_url("SegmentURL");
    +
    422  RCHECK(
    +
    423  media_url.SetStringAttribute("media", media_info.media_file_url()));
    +
    424  RCHECK(child.AddChild(std::move(media_url)));
    +
    425  }
    +
    426 
    +
    427  RCHECK(AddChild(std::move(child)));
    +
    428  }
    +
    429 
    +
    430  return true;
    +
    431 }
    +
    432 
    + +
    434  const MediaInfo& media_info,
    +
    435  const std::list<SegmentInfo>& segment_infos,
    +
    436  uint32_t start_number) {
    +
    437  XmlNode segment_template("SegmentTemplate");
    +
    438  if (media_info.has_reference_time_scale()) {
    +
    439  RCHECK(segment_template.SetIntegerAttribute(
    +
    440  "timescale", media_info.reference_time_scale()));
    +
    441  }
    +
    442 
    +
    443  if (media_info.has_presentation_time_offset()) {
    +
    444  RCHECK(segment_template.SetIntegerAttribute(
    +
    445  "presentationTimeOffset", media_info.presentation_time_offset()));
    +
    446  }
    +
    447 
    +
    448  if (media_info.has_init_segment_url()) {
    +
    449  RCHECK(segment_template.SetStringAttribute("initialization",
    +
    450  media_info.init_segment_url()));
    +
    451  }
    +
    452 
    +
    453  if (media_info.has_segment_template_url()) {
    +
    454  RCHECK(segment_template.SetStringAttribute(
    +
    455  "media", media_info.segment_template_url()));
    +
    456  RCHECK(segment_template.SetIntegerAttribute("startNumber", start_number));
    +
    457  }
    +
    458 
    +
    459  if (!segment_infos.empty()) {
    +
    460  // Don't use SegmentTimeline if all segments except the last one are of
    +
    461  // the same duration.
    +
    462  if (IsTimelineConstantDuration(segment_infos, start_number)) {
    +
    463  RCHECK(segment_template.SetIntegerAttribute(
    +
    464  "duration", segment_infos.front().duration));
    +
    465  if (FLAGS_dash_add_last_segment_number_when_needed) {
    +
    466  uint32_t last_segment_number = start_number - 1;
    +
    467  for (const auto& segment_info_element : segment_infos)
    +
    468  last_segment_number += segment_info_element.repeat + 1;
    +
    469 
    + +
    471  "http://dashif.org/guidelines/last-segment-number",
    +
    472  std::to_string(last_segment_number)));
    +
    473  }
    +
    474  } else {
    +
    475  XmlNode segment_timeline("SegmentTimeline");
    +
    476  RCHECK(PopulateSegmentTimeline(segment_infos, &segment_timeline));
    +
    477  RCHECK(segment_template.AddChild(std::move(segment_timeline)));
    +
    478  }
    +
    479  }
    +
    480  return AddChild(std::move(segment_template));
    +
    481 }
    +
    482 
    +
    483 bool RepresentationXmlNode::AddAudioChannelInfo(const AudioInfo& audio_info) {
    +
    484  std::string audio_channel_config_scheme;
    +
    485  std::string audio_channel_config_value;
    +
    486 
    +
    487  if (audio_info.codec() == kEC3Codec) {
    +
    488  const auto& codec_data = audio_info.codec_specific_data();
    +
    489  // Use MPEG scheme if the mpeg value is available and valid, fallback to
    +
    490  // EC3 channel mapping otherwise.
    +
    491  // See https://github.com/Dash-Industry-Forum/DASH-IF-IOP/issues/268
    +
    492  const uint32_t ec3_channel_mpeg_value = codec_data.channel_mpeg_value();
    +
    493  const uint32_t NO_MAPPING = 0xFFFFFFFF;
    +
    494  if (ec3_channel_mpeg_value == NO_MAPPING) {
    +
    495  // Convert EC3 channel map into string of hexadecimal digits. Spec: DASH-IF
    +
    496  // Interoperability Points v3.0 9.2.1.2.
    +
    497  const uint16_t ec3_channel_map =
    +
    498  base::HostToNet16(codec_data.channel_mask());
    +
    499  audio_channel_config_value =
    +
    500  base::HexEncode(&ec3_channel_map, sizeof(ec3_channel_map));
    +
    501  audio_channel_config_scheme =
    +
    502  "tag:dolby.com,2014:dash:audio_channel_configuration:2011";
    +
    503  } else {
    +
    504  // Calculate EC3 channel configuration descriptor value with MPEG scheme.
    +
    505  // Spec: ETSI TS 102 366 V1.4.1 Digital Audio Compression
    +
    506  // (AC-3, Enhanced AC-3) I.1.2.
    +
    507  audio_channel_config_value = base::UintToString(ec3_channel_mpeg_value);
    +
    508  audio_channel_config_scheme = "urn:mpeg:mpegB:cicp:ChannelConfiguration";
    +
    509  }
    +
    510  bool ret = AddDescriptor("AudioChannelConfiguration",
    +
    511  audio_channel_config_scheme,
    +
    512  audio_channel_config_value);
    +
    513  // Dolby Digital Plus JOC descriptor. Spec: ETSI TS 103 420 v1.2.1
    +
    514  // Backwards-compatible object audio carriage using Enhanced AC-3 Standard
    +
    515  // D.2.2.
    +
    516  if (codec_data.ec3_joc_complexity() != 0) {
    +
    517  std::string ec3_joc_complexity =
    +
    518  base::UintToString(codec_data.ec3_joc_complexity());
    +
    519  ret &= AddDescriptor("SupplementalProperty",
    +
    520  "tag:dolby.com,2018:dash:EC3_ExtensionType:2018",
    +
    521  "JOC");
    +
    522  ret &= AddDescriptor("SupplementalProperty",
    +
    523  "tag:dolby.com,2018:dash:"
    +
    524  "EC3_ExtensionComplexityIndex:2018",
    +
    525  ec3_joc_complexity);
    +
    526  }
    +
    527  return ret;
    +
    528  } else if (audio_info.codec().substr(0, 4) == kAC4Codec) {
    +
    529  const auto& codec_data = audio_info.codec_specific_data();
    +
    530  const bool ac4_ims_flag = codec_data.ac4_ims_flag();
    +
    531  // Use MPEG scheme if the mpeg value is available and valid, fallback to
    +
    532  // AC4 channel mask otherwise.
    +
    533  // See https://github.com/Dash-Industry-Forum/DASH-IF-IOP/issues/268
    +
    534  const uint32_t ac4_channel_mpeg_value = codec_data.channel_mpeg_value();
    +
    535  const uint32_t NO_MAPPING = 0xFFFFFFFF;
    +
    536  if (ac4_channel_mpeg_value == NO_MAPPING) {
    +
    537  // Calculate AC-4 channel mask. Spec: ETSI TS 103 190-2 V1.2.1 Digital
    +
    538  // Audio Compression (AC-4) Standard; Part 2: Immersive and personalized
    +
    539  // audio G.3.1.
    +
    540  const uint32_t ac4_channel_mask =
    +
    541  base::HostToNet32(codec_data.channel_mask() << 8);
    +
    542  audio_channel_config_value =
    +
    543  base::HexEncode(&ac4_channel_mask, sizeof(ac4_channel_mask) - 1);
    +
    544  // Note that the channel config schemes for EC-3 and AC-4 are different.
    +
    545  // See https://github.com/Dash-Industry-Forum/DASH-IF-IOP/issues/268.
    +
    546  audio_channel_config_scheme =
    +
    547  "tag:dolby.com,2015:dash:audio_channel_configuration:2015";
    +
    548  } else {
    +
    549  // Calculate AC-4 channel configuration descriptor value with MPEG scheme.
    +
    550  // Spec: ETSI TS 103 190-2 V1.2.1 Digital Audio Compression (AC-4) Standard;
    +
    551  // Part 2: Immersive and personalized audio G.3.2.
    +
    552  audio_channel_config_value = base::UintToString(ac4_channel_mpeg_value);
    +
    553  audio_channel_config_scheme = "urn:mpeg:mpegB:cicp:ChannelConfiguration";
    +
    554  }
    +
    555  bool ret = AddDescriptor("AudioChannelConfiguration",
    +
    556  audio_channel_config_scheme,
    +
    557  audio_channel_config_value);
    +
    558  if (ac4_ims_flag) {
    +
    559  ret &= AddDescriptor("SupplementalProperty",
    +
    560  "tag:dolby.com,2016:dash:virtualized_content:2016",
    +
    561  "1");
    +
    562  }
    +
    563  return ret;
    +
    564  } else {
    +
    565  audio_channel_config_value = base::UintToString(audio_info.num_channels());
    +
    566  audio_channel_config_scheme =
    +
    567  "urn:mpeg:dash:23003:3:audio_channel_configuration:2011";
    +
    568  }
    +
    569 
    +
    570  return AddDescriptor("AudioChannelConfiguration", audio_channel_config_scheme,
    +
    571  audio_channel_config_value);
    +
    572 }
    +
    573 
    +
    574 // MPD expects one number for sampling frequency, or if it is a range it should
    +
    575 // be space separated.
    +
    576 bool RepresentationXmlNode::AddAudioSamplingRateInfo(
    +
    577  const AudioInfo& audio_info) {
    +
    578  return !audio_info.has_sampling_frequency() ||
    +
    579  SetIntegerAttribute("audioSamplingRate",
    +
    580  audio_info.sampling_frequency());
    +
    581 }
    +
    582 
    +
    583 } // namespace xml
    +
    584 } // namespace shaka
    +
    bool AddRoleElement(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:328
    +
    bool AddAccessibilityElement(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:322
    + +
    bool AddDescriptor(const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:286
    +
    bool AddSupplementalProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:274
    +
    bool AddEssentialProperty(const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
    Definition: xml_node.cc:280
    +
    bool AddVideoInfo(const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate) WARN_UNUSED_RESULT
    Definition: xml_node.cc:337
    +
    bool AddVODOnlyInfo(const MediaInfo &media_info) WARN_UNUSED_RESULT
    Definition: xml_node.cc:379
    +
    bool AddLiveOnlyInfo(const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number) WARN_UNUSED_RESULT
    Definition: xml_node.cc:433
    +
    bool AddAudioInfo(const MediaInfo::AudioInfo &audio_info) WARN_UNUSED_RESULT
    Definition: xml_node.cc:374
    + +
    bool AddChild(XmlNode child) WARN_UNUSED_RESULT
    Definition: xml_node.cc:140
    +
    std::set< std::string > ExtractReferencedNamespaces() const
    Definition: xml_node.cc:218
    +
    void AddContent(const std::string &content)
    Similar to SetContent, but appends to the end of existing content.
    Definition: xml_node.cc:208
    +
    void SetContent(const std::string &content)
    Definition: xml_node.cc:213
    +
    bool SetFloatingPointAttribute(const std::string &attribute_name, double number) WARN_UNUSED_RESULT
    Definition: xml_node.cc:197
    +
    bool SetIntegerAttribute(const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULT
    Definition: xml_node.cc:190
    +
    XmlNode(const std::string &name)
    Definition: xml_node.cc:129
    +
    bool SetStringAttribute(const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
    Definition: xml_node.cc:183
    +
    bool GetAttribute(const std::string &name, std::string *value) const
    Definition: xml_node.cc:248
    +
    bool SetId(uint32_t id) WARN_UNUSED_RESULT
    Definition: xml_node.cc:204
    +
    bool AddElements(const std::vector< Element > &elements) WARN_UNUSED_RESULT
    Adds Elements to this node using the Element struct.
    Definition: xml_node.cc:151
    +
    std::string ToString(const std::string &comment) const
    Definition: xml_node.cc:224
    +
    All the methods that are virtual are virtual for mocking.
    + +
    diff --git a/docs/df/d9a/structshaka_1_1media_1_1mp4_1_1TrackFragmentDecodeTime.html b/docs/df/d9a/structshaka_1_1media_1_1mp4_1_1TrackFragmentDecodeTime.html index fa2a4879bb..36bf0478b5 100644 --- a/docs/df/d9a/structshaka_1_1media_1_1mp4_1_1TrackFragmentDecodeTime.html +++ b/docs/df/d9a/structshaka_1_1media_1_1mp4_1_1TrackFragmentDecodeTime.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::mp4::TrackFragmentDecodeTime Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::mp4::FullBox shaka::media::mp4::Box - -
    + + @@ -121,7 +124,7 @@ Additional Inherited Members

    Public Member Functions

    Detailed Description

    -

    Definition at line 677 of file box_definitions.h.

    +

    Definition at line 695 of file box_definitions.h.

    Member Function Documentation

    ◆ BoxType()

    @@ -149,7 +152,7 @@ Additional Inherited Members

    Implements shaka::media::mp4::Box.

    -

    Definition at line 2353 of file box_definitions.cc.

    +

    Definition at line 2442 of file box_definitions.cc.

    @@ -160,9 +163,7 @@ Additional Inherited Members diff --git a/docs/df/d9e/classshaka_1_1xml_1_1RepresentationXmlNode.html b/docs/df/d9e/classshaka_1_1xml_1_1RepresentationXmlNode.html index 378d1dff2c..ea30a41ddd 100644 --- a/docs/df/d9e/classshaka_1_1xml_1_1RepresentationXmlNode.html +++ b/docs/df/d9e/classshaka_1_1xml_1_1RepresentationXmlNode.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::xml::RepresentationXmlNode Class Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    shaka::xml::RepresentationBaseXmlNode shaka::xml::XmlNode - -
    + + - - - - - - - - + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + +

    Public Member Functions

    bool AddVideoInfo (const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate)
     
    bool AddAudioInfo (const MediaInfo::AudioInfo &audio_info)
     
    bool AddVODOnlyInfo (const MediaInfo &media_info)
     
    bool AddLiveOnlyInfo (const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number)
     
    bool AddVideoInfo (const MediaInfo::VideoInfo &video_info, bool set_width, bool set_height, bool set_frame_rate) WARN_UNUSED_RESULT
     
    bool AddAudioInfo (const MediaInfo::AudioInfo &audio_info) WARN_UNUSED_RESULT
     
    bool AddVODOnlyInfo (const MediaInfo &media_info) WARN_UNUSED_RESULT
     
    bool AddLiveOnlyInfo (const MediaInfo &media_info, const std::list< SegmentInfo > &segment_infos, uint32_t start_number) WARN_UNUSED_RESULT
     
    - Public Member Functions inherited from shaka::xml::RepresentationBaseXmlNode
    -bool AddContentProtectionElements (const std::list< ContentProtectionElement > &content_protection_elements)
     
    void AddSupplementalProperty (const std::string &scheme_id_uri, const std::string &value)
     
    void AddEssentialProperty (const std::string &scheme_id_uri, const std::string &value)
     
    +bool AddContentProtectionElements (const std::list< ContentProtectionElement > &content_protection_elements) WARN_UNUSED_RESULT
     
    bool AddSupplementalProperty (const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
     
    bool AddEssentialProperty (const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
     
    - Public Member Functions inherited from shaka::xml::XmlNode
     XmlNode (const char *name)
     
    bool AddChild (scoped_xml_ptr< xmlNode > child)
     
    -bool AddElements (const std::vector< Element > &elements)
     Adds Elements to this node using the Element struct.
     
    void SetStringAttribute (const char *attribute_name, const std::string &attribute)
     
    void SetIntegerAttribute (const char *attribute_name, uint64_t number)
     
    void SetFloatingPointAttribute (const char *attribute_name, double number)
     
    void SetId (uint32_t id)
     
     XmlNode (const std::string &name)
     
    XmlNode (XmlNode &&)
     
    +XmlNodeoperator= (XmlNode &&)
     
    bool AddChild (XmlNode child) WARN_UNUSED_RESULT
     
    +bool AddElements (const std::vector< Element > &elements) WARN_UNUSED_RESULT
     Adds Elements to this node using the Element struct.
     
    bool SetStringAttribute (const std::string &attribute_name, const std::string &attribute) WARN_UNUSED_RESULT
     
    bool SetIntegerAttribute (const std::string &attribute_name, uint64_t number) WARN_UNUSED_RESULT
     
    bool SetFloatingPointAttribute (const std::string &attribute_name, double number) WARN_UNUSED_RESULT
     
    bool SetId (uint32_t id) WARN_UNUSED_RESULT
     
    +void AddContent (const std::string &content)
     Similar to SetContent, but appends to the end of existing content.
     
    void SetContent (const std::string &content)
     
    std::set< std::string > ExtractReferencedNamespaces ()
     
    scoped_xml_ptr< xmlNode > PassScopedPtr ()
     
    xmlNodePtr Release ()
     
    xmlNodePtr GetRawPtr ()
     
    std::set< std::string > ExtractReferencedNamespaces () const
     
    std::string ToString (const std::string &comment) const
     
    bool GetAttribute (const std::string &name, std::string *value) const
     
    - - - - + + + +

    Additional Inherited Members

    - Protected Member Functions inherited from shaka::xml::RepresentationBaseXmlNode
    RepresentationBaseXmlNode (const char *name)
     
    bool AddDescriptor (const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value)
     
    RepresentationBaseXmlNode (const std::string &name)
     
    bool AddDescriptor (const std::string &descriptor_name, const std::string &scheme_id_uri, const std::string &value) WARN_UNUSED_RESULT
     

    Detailed Description

    RepresentationType in MPD.

    -

    Definition at line 156 of file xml_node.h.

    +

    Definition at line 182 of file xml_node.h.

    Member Function Documentation

    - -

    ◆ AddAudioInfo()

    + +

    ◆ AddAudioInfo()

    @@ -168,12 +179,12 @@ Additional Inherited Members
    Returns
    true if successfully set attributes and children elements (if applicable), false otherwise.
    -

    Definition at line 346 of file xml_node.cc.

    +

    Definition at line 374 of file xml_node.cc.

    - -

    ◆ AddLiveOnlyInfo()

    + +

    ◆ AddLiveOnlyInfo()

    @@ -210,12 +221,12 @@ Additional Inherited Members -

    Definition at line 400 of file xml_node.cc.

    +

    Definition at line 433 of file xml_node.cc.

    - -

    ◆ AddVideoInfo()

    + +

    ◆ AddVideoInfo()

    @@ -262,12 +273,12 @@ Additional Inherited Members
    Returns
    true if successfully set attributes and children elements (if applicable), false otherwise.
    -

    Definition at line 309 of file xml_node.cc.

    +

    Definition at line 337 of file xml_node.cc.

    - -

    ◆ AddVODOnlyInfo()

    + +

    ◆ AddVODOnlyInfo()

    @@ -289,7 +300,7 @@ Additional Inherited Members
    Returns
    true on success, false otherwise.
    -

    Definition at line 354 of file xml_node.cc.

    +

    Definition at line 379 of file xml_node.cc.

    @@ -300,9 +311,7 @@ Additional Inherited Members diff --git a/docs/df/d9e/es__parser__dvb_8h_source.html b/docs/df/d9e/es__parser__dvb_8h_source.html new file mode 100644 index 0000000000..a1426293fd --- /dev/null +++ b/docs/df/d9e/es__parser__dvb_8h_source.html @@ -0,0 +1,139 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/mp2t/es_parser_dvb.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    es_parser_dvb.h
    +
    +
    +
    1 // Copyright 2020 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_DVB_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_DVB_H_
    +
    9 
    +
    10 #include <unordered_map>
    +
    11 
    +
    12 #include "packager/base/callback.h"
    +
    13 #include "packager/media/base/byte_queue.h"
    +
    14 #include "packager/media/formats/dvb/dvb_sub_parser.h"
    +
    15 #include "packager/media/formats/mp2t/es_parser.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 namespace mp2t {
    +
    20 
    +
    21 class EsParserDvb : public EsParser {
    +
    22  public:
    +
    23  EsParserDvb(uint32_t pid,
    +
    24  const NewStreamInfoCB& new_stream_info_cb,
    +
    25  const EmitTextSampleCB& emit_sample_cb,
    +
    26  const uint8_t* descriptor,
    +
    27  size_t descriptor_length);
    +
    28  ~EsParserDvb() override;
    +
    29 
    +
    30  // EsParser implementation.
    +
    31  bool Parse(const uint8_t* buf, int size, int64_t pts, int64_t dts) override;
    +
    32  bool Flush() override;
    +
    33  void Reset() override;
    +
    34 
    +
    35  private:
    +
    36  EsParserDvb(const EsParserDvb&) = delete;
    +
    37  EsParserDvb& operator=(const EsParserDvb&) = delete;
    +
    38 
    +
    39  bool ParseInternal(const uint8_t* data, size_t size, int64_t pts);
    +
    40 
    +
    41  // Callbacks:
    +
    42  // - to signal a new audio configuration,
    +
    43  // - to send ES buffers.
    +
    44  NewStreamInfoCB new_stream_info_cb_;
    +
    45  EmitTextSampleCB emit_sample_cb_;
    +
    46 
    +
    47  // A map of page_id to parser.
    +
    48  std::unordered_map<uint16_t, DvbSubParser> parsers_;
    +
    49  // A map of page_id to language.
    +
    50  std::unordered_map<uint16_t, std::string> languages_;
    +
    51  bool sent_info_ = false;
    +
    52 };
    +
    53 
    +
    54 } // namespace mp2t
    +
    55 } // namespace media
    +
    56 } // namespace shaka
    +
    57 
    +
    58 #endif // PACKAGER_MEDIA_FORMATS_MP2T_ES_PARSER_DVB_H_
    + + +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/df/da0/structshaka_1_1media_1_1mp4_1_1ChunkOffset-members.html b/docs/df/da0/structshaka_1_1media_1_1mp4_1_1ChunkOffset-members.html index 52c212f442..6ab55080cb 100644 --- a/docs/df/da0/structshaka_1_1media_1_1mp4_1_1ChunkOffset-members.html +++ b/docs/df/da0/structshaka_1_1media_1_1mp4_1_1ChunkOffset-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/da1/cc__stream__filter_8h_source.html b/docs/df/da1/cc__stream__filter_8h_source.html new file mode 100644 index 0000000000..a4cabf7e14 --- /dev/null +++ b/docs/df/da1/cc__stream__filter_8h_source.html @@ -0,0 +1,120 @@ + + + + + + + +Shaka Packager SDK: packager/media/base/cc_stream_filter.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    cc_stream_filter.h
    +
    +
    +
    1 // Copyright 2020 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_CC_STREAM_FILTER_H_
    +
    8 #define PACKAGER_MEDIA_BASE_CC_STREAM_FILTER_H_
    +
    9 
    +
    10 #include <string>
    +
    11 
    +
    12 #include "packager/media/base/media_handler.h"
    +
    13 #include "packager/media/base/text_sample.h"
    +
    14 #include "packager/status.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    +
    22 class CcStreamFilter : public MediaHandler {
    +
    23  public:
    +
    24  CcStreamFilter(const std::string& language, uint16_t cc_index);
    +
    25  ~CcStreamFilter() override = default;
    +
    26 
    +
    27  protected:
    +
    28  Status InitializeInternal() override;
    +
    29  Status Process(std::unique_ptr<StreamData> stream_data) override;
    +
    30 
    +
    31  private:
    +
    32  const std::string language_;
    +
    33  const uint16_t cc_index_;
    +
    34 };
    +
    35 
    +
    36 } // namespace media
    +
    37 } // namespace shaka
    +
    38 
    +
    39 #endif // PACKAGER_MEDIA_BASE_CC_STREAM_FILTER_H_
    + + +
    Status Process(std::unique_ptr< StreamData > stream_data) override
    +
    Status InitializeInternal() override
    + +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/df/da5/structshaka_1_1media_1_1mp4_1_1CueIDBox-members.html b/docs/df/da5/structshaka_1_1media_1_1mp4_1_1CueIDBox-members.html index b2c21ed522..bd302bc63c 100644 --- a/docs/df/da5/structshaka_1_1media_1_1mp4_1_1CueIDBox-members.html +++ b/docs/df/da5/structshaka_1_1media_1_1mp4_1_1CueIDBox-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/dab/structshaka_1_1media_1_1EventInfo-members.html b/docs/df/dab/structshaka_1_1media_1_1EventInfo-members.html index 74f0316cbc..0efd84f19a 100644 --- a/docs/df/dab/structshaka_1_1media_1_1EventInfo-members.html +++ b/docs/df/dab/structshaka_1_1media_1_1EventInfo-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/df/dad/decrypt__config_8h_source.html b/docs/df/dad/decrypt__config_8h_source.html index baf1c85b9b..87bf20c08b 100644 --- a/docs/df/dad/decrypt__config_8h_source.html +++ b/docs/df/dad/decrypt__config_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/decrypt_config.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    decrypt_config.h
    -
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #ifndef PACKAGER_MEDIA_BASE_DECRYPT_CONFIG_H_
    6 #define PACKAGER_MEDIA_BASE_DECRYPT_CONFIG_H_
    7 
    8 #include <stdint.h>
    9 
    10 #include <string>
    11 #include <vector>
    12 
    13 #include "packager/base/macros.h"
    14 #include "packager/media/base/fourccs.h"
    15 
    16 namespace shaka {
    17 namespace media {
    18 
    30  : clear_bytes(0), cipher_bytes(0) {}
    31  SubsampleEntry(uint16_t clear_bytes, uint32_t cipher_bytes)
    32  : clear_bytes(clear_bytes), cipher_bytes(cipher_bytes) {}
    33 
    34  uint16_t clear_bytes;
    35  uint32_t cipher_bytes;
    36 };
    37 
    41  public:
    43  static const size_t kDecryptionKeySize = 16;
    44 
    51  DecryptConfig(const std::vector<uint8_t>& key_id,
    52  const std::vector<uint8_t>& iv,
    53  const std::vector<SubsampleEntry>& subsamples);
    54 
    67  DecryptConfig(const std::vector<uint8_t>& key_id,
    68  const std::vector<uint8_t>& iv,
    69  const std::vector<SubsampleEntry>& subsamples,
    70  FourCC protection_scheme,
    71  uint8_t crypt_byte_block,
    72  uint8_t skip_byte_block);
    73 
    74  ~DecryptConfig();
    75 
    80  void AddSubsample(uint16_t clear_bytes, uint32_t cipher_bytes) {
    81  subsamples_.emplace_back(clear_bytes, cipher_bytes);
    82  }
    83 
    85  size_t GetTotalSizeOfSubsamples() const;
    86 
    87  const std::vector<uint8_t>& key_id() const { return key_id_; }
    88  const std::vector<uint8_t>& iv() const { return iv_; }
    89  const std::vector<SubsampleEntry>& subsamples() const { return subsamples_; }
    90  FourCC protection_scheme() const { return protection_scheme_; }
    91  uint8_t crypt_byte_block() const { return crypt_byte_block_; }
    92  uint8_t skip_byte_block() const { return skip_byte_block_; }
    93 
    94  private:
    95  const std::vector<uint8_t> key_id_;
    96 
    97  // Initialization vector.
    98  const std::vector<uint8_t> iv_;
    99 
    100  // Subsample information. May be empty for some formats, meaning entire frame
    101  // (less data ignored by data_offset_) is encrypted.
    102  std::vector<SubsampleEntry> subsamples_;
    103 
    104  const FourCC protection_scheme_;
    105  // For pattern-based protection schemes, like CENS and CBCS.
    106  const uint8_t crypt_byte_block_;
    107  const uint8_t skip_byte_block_;
    108 
    109  DISALLOW_COPY_AND_ASSIGN(DecryptConfig);
    110 };
    111 
    112 } // namespace media
    113 } // namespace shaka
    114 
    115 #endif // PACKAGER_MEDIA_BASE_DECRYPT_CONFIG_H_
    - -
    All the methods that are virtual are virtual for mocking.
    -
    void AddSubsample(uint16_t clear_bytes, uint32_t cipher_bytes)
    +
    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #ifndef PACKAGER_MEDIA_BASE_DECRYPT_CONFIG_H_
    +
    6 #define PACKAGER_MEDIA_BASE_DECRYPT_CONFIG_H_
    +
    7 
    +
    8 #include <stdint.h>
    +
    9 
    +
    10 #include <string>
    +
    11 #include <vector>
    +
    12 
    +
    13 #include "packager/base/macros.h"
    +
    14 #include "packager/media/base/fourccs.h"
    +
    15 
    +
    16 namespace shaka {
    +
    17 namespace media {
    +
    18 
    + + +
    30  : clear_bytes(0), cipher_bytes(0) {}
    +
    31  SubsampleEntry(uint16_t clear_bytes, uint32_t cipher_bytes)
    +
    32  : clear_bytes(clear_bytes), cipher_bytes(cipher_bytes) {}
    +
    33 
    +
    34  uint16_t clear_bytes;
    +
    35  uint32_t cipher_bytes;
    +
    36 };
    +
    37 
    + +
    41  public:
    +
    43  static const size_t kDecryptionKeySize = 16;
    +
    44 
    +
    51  DecryptConfig(const std::vector<uint8_t>& key_id,
    +
    52  const std::vector<uint8_t>& iv,
    +
    53  const std::vector<SubsampleEntry>& subsamples);
    +
    54 
    +
    67  DecryptConfig(const std::vector<uint8_t>& key_id,
    +
    68  const std::vector<uint8_t>& iv,
    +
    69  const std::vector<SubsampleEntry>& subsamples,
    +
    70  FourCC protection_scheme,
    +
    71  uint8_t crypt_byte_block,
    +
    72  uint8_t skip_byte_block);
    +
    73 
    +
    74  ~DecryptConfig();
    +
    75 
    +
    80  void AddSubsample(uint16_t clear_bytes, uint32_t cipher_bytes) {
    +
    81  subsamples_.emplace_back(clear_bytes, cipher_bytes);
    +
    82  }
    +
    83 
    +
    85  size_t GetTotalSizeOfSubsamples() const;
    +
    86 
    +
    87  const std::vector<uint8_t>& key_id() const { return key_id_; }
    +
    88  const std::vector<uint8_t>& iv() const { return iv_; }
    +
    89  const std::vector<SubsampleEntry>& subsamples() const { return subsamples_; }
    +
    90  FourCC protection_scheme() const { return protection_scheme_; }
    +
    91  uint8_t crypt_byte_block() const { return crypt_byte_block_; }
    +
    92  uint8_t skip_byte_block() const { return skip_byte_block_; }
    +
    93 
    +
    94  private:
    +
    95  const std::vector<uint8_t> key_id_;
    +
    96 
    +
    97  // Initialization vector.
    +
    98  const std::vector<uint8_t> iv_;
    +
    99 
    +
    100  // Subsample information. May be empty for some formats, meaning entire frame
    +
    101  // (less data ignored by data_offset_) is encrypted.
    +
    102  std::vector<SubsampleEntry> subsamples_;
    +
    103 
    +
    104  const FourCC protection_scheme_;
    +
    105  // For pattern-based protection schemes, like CENS and CBCS.
    +
    106  const uint8_t crypt_byte_block_;
    +
    107  const uint8_t skip_byte_block_;
    +
    108 
    +
    109  DISALLOW_COPY_AND_ASSIGN(DecryptConfig);
    +
    110 };
    +
    111 
    +
    112 } // namespace media
    +
    113 } // namespace shaka
    +
    114 
    +
    115 #endif // PACKAGER_MEDIA_BASE_DECRYPT_CONFIG_H_
    + +
    DecryptConfig(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &iv, const std::vector< SubsampleEntry > &subsamples)
    +
    void AddSubsample(uint16_t clear_bytes, uint32_t cipher_bytes)
    +
    size_t GetTotalSizeOfSubsamples() const
    +
    static const size_t kDecryptionKeySize
    Keys are always 128 bits.
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/df/db9/classshaka_1_1media_1_1BaseDescriptor.html b/docs/df/db9/classshaka_1_1media_1_1BaseDescriptor.html index 1ac4fd80e8..239a5bb1b4 100644 --- a/docs/df/db9/classshaka_1_1media_1_1BaseDescriptor.html +++ b/docs/df/db9/classshaka_1_1media_1_1BaseDescriptor.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::BaseDescriptor Class Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    shaka::media::DecoderSpecificInfoDescriptor shaka::media::ESDescriptor shaka::media::SLConfigDescriptor - -
    + + @@ -111,7 +114,7 @@ void 

    Public Member Functions

    Detailed Description

    Defines the base Descriptor object as defined in ISO 14496-1:2004 Systems section 7.2.2.2. All descriptors inherit from either BaseDescriptor.

    -

    Definition at line 41 of file es_descriptor.h.

    +

    Definition at line 43 of file es_descriptor.h.

    Member Function Documentation

    ◆ ComputeSize()

    @@ -157,7 +160,7 @@ void 
    Returns
    descriptor data size without header in bytes.
    -

    Definition at line 68 of file es_descriptor.h.

    +

    Definition at line 70 of file es_descriptor.h.

    @@ -204,7 +207,7 @@ void 

    Read the descriptor.

    Parameters
    - +
    readerpoints to a BitReader object.
    readerpoints to a BitReader object.
    @@ -246,9 +249,7 @@ void 
    diff --git a/docs/df/dc0/classshaka_1_1media_1_1WebVttToMp4Handler-members.html b/docs/df/dc0/classshaka_1_1media_1_1WebVttToMp4Handler-members.html index 79ef7a29ef..cc22b9b62e 100644 --- a/docs/df/dc0/classshaka_1_1media_1_1WebVttToMp4Handler-members.html +++ b/docs/df/dc0/classshaka_1_1media_1_1WebVttToMp4Handler-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    This is the complete list of members for shaka::media::WebVttToMp4Handler, including all inherited members.

    - + @@ -96,9 +99,7 @@ $(function() {
    AddHandler(std::shared_ptr< MediaHandler > handler)shaka::media::MediaHandlerinline
    Chain(std::initializer_list< std::shared_ptr< MediaHandler >> list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Chain(const std::vector< std::shared_ptr< MediaHandler >> &list) (defined in shaka::media::MediaHandler)shaka::media::MediaHandlerstatic
    Dispatch(std::unique_ptr< StreamData > stream_data) constshaka::media::MediaHandlerprotected
    DispatchCueEvent(size_t stream_index, std::shared_ptr< const CueEvent > cue_event) constshaka::media::MediaHandlerinlineprotected
    DispatchMediaSample(size_t stream_index, std::shared_ptr< const MediaSample > media_sample) constshaka::media::MediaHandlerinlineprotected
    diff --git a/docs/df/dc7/avc__decoder__configuration__record_8h_source.html b/docs/df/dc7/avc__decoder__configuration__record_8h_source.html index c1c824baee..4a0f6cc069 100644 --- a/docs/df/dc7/avc__decoder__configuration__record_8h_source.html +++ b/docs/df/dc7/avc__decoder__configuration__record_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs/avc_decoder_configuration_record.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    avc_decoder_configuration_record.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CODECS_AVC_DECODER_CONFIGURATION_RECORD_H_
    8 #define PACKAGER_MEDIA_CODECS_AVC_DECODER_CONFIGURATION_RECORD_H_
    9 
    10 #include <stdint.h>
    11 #include <string>
    12 #include <vector>
    13 
    14 #include "packager/base/macros.h"
    15 #include "packager/media/base/fourccs.h"
    16 #include "packager/media/codecs/decoder_configuration_record.h"
    17 
    18 namespace shaka {
    19 namespace media {
    20 
    23  public:
    26 
    28  std::string GetCodecString(FourCC codec_fourcc) const;
    29 
    30  uint8_t version() const { return version_; }
    31  uint8_t profile_indication() const { return profile_indication_; }
    32  uint8_t profile_compatibility() const { return profile_compatibility_; }
    33  uint8_t avc_level() const { return avc_level_; }
    34  uint32_t coded_width() const { return coded_width_; }
    35  uint32_t coded_height() const { return coded_height_; }
    36  uint32_t pixel_width() const { return pixel_width_; }
    37  uint32_t pixel_height() const { return pixel_height_; }
    38 
    41  static std::string GetCodecString(FourCC codec_fourcc,
    42  uint8_t profile_indication,
    43  uint8_t profile_compatibility,
    44  uint8_t avc_level);
    45 
    46  private:
    47  bool ParseInternal() override;
    48 
    49  uint8_t version_;
    50  uint8_t profile_indication_;
    51  uint8_t profile_compatibility_;
    52  uint8_t avc_level_;
    53 
    54  // Extracted from SPS.
    55  uint32_t coded_width_;
    56  uint32_t coded_height_;
    57  uint32_t pixel_width_;
    58  uint32_t pixel_height_;
    59 
    60  DISALLOW_COPY_AND_ASSIGN(AVCDecoderConfigurationRecord);
    61 };
    62 
    63 } // namespace media
    64 } // namespace shaka
    65 
    66 #endif // PACKAGER_MEDIA_CODECS_AVC_DECODER_CONFIGURATION_RECORD_H_
    -
    All the methods that are virtual are virtual for mocking.
    -
    std::string GetCodecString(FourCC codec_fourcc) const
    -
    Class for parsing AVC decoder configuration record.
    +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CODECS_AVC_DECODER_CONFIGURATION_RECORD_H_
    +
    8 #define PACKAGER_MEDIA_CODECS_AVC_DECODER_CONFIGURATION_RECORD_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 #include <string>
    +
    12 #include <vector>
    +
    13 
    +
    14 #include "packager/base/macros.h"
    +
    15 #include "packager/media/base/fourccs.h"
    +
    16 #include "packager/media/codecs/decoder_configuration_record.h"
    +
    17 
    +
    18 namespace shaka {
    +
    19 namespace media {
    +
    20 
    + +
    23  public:
    + + +
    26 
    +
    28  std::string GetCodecString(FourCC codec_fourcc) const;
    +
    29 
    +
    30  uint8_t version() const { return version_; }
    +
    31  uint8_t profile_indication() const { return profile_indication_; }
    +
    32  uint8_t profile_compatibility() const { return profile_compatibility_; }
    +
    33  uint8_t avc_level() const { return avc_level_; }
    +
    34  uint32_t coded_width() const { return coded_width_; }
    +
    35  uint32_t coded_height() const { return coded_height_; }
    +
    36  uint32_t pixel_width() const { return pixel_width_; }
    +
    37  uint32_t pixel_height() const { return pixel_height_; }
    +
    38  uint8_t chroma_format() const { return chroma_format_; }
    +
    39  uint8_t bit_depth_luma_minus8() const { return bit_depth_luma_minus8_; }
    +
    40  uint8_t bit_depth_chroma_minus8() const { return bit_depth_chroma_minus8_; }
    +
    41 
    +
    44  static std::string GetCodecString(FourCC codec_fourcc,
    +
    45  uint8_t profile_indication,
    +
    46  uint8_t profile_compatibility,
    +
    47  uint8_t avc_level);
    +
    48 
    +
    49  private:
    +
    50  bool ParseInternal() override;
    +
    51 
    +
    52  uint8_t version_ = 0;
    +
    53  uint8_t profile_indication_ = 0;
    +
    54  uint8_t profile_compatibility_ = 0;
    +
    55  uint8_t avc_level_ = 0;
    +
    56 
    +
    57  // Extracted from SPS.
    +
    58  uint32_t coded_width_ = 0;
    +
    59  uint32_t coded_height_ = 0;
    +
    60  uint32_t pixel_width_ = 0;
    +
    61  uint32_t pixel_height_ = 0;
    +
    62 
    +
    63  // Only should be present for special case profile values.
    +
    64  // Refer to ISO/IEC 14496-15 Section 5.3.3.1.1.
    +
    65  uint8_t chroma_format_ = 0;
    +
    66  uint8_t bit_depth_luma_minus8_ = 0;
    +
    67  uint8_t bit_depth_chroma_minus8_ = 0;
    +
    68 
    +
    69  DISALLOW_COPY_AND_ASSIGN(AVCDecoderConfigurationRecord);
    +
    70 };
    +
    71 
    +
    72 } // namespace media
    +
    73 } // namespace shaka
    +
    74 
    +
    75 #endif // PACKAGER_MEDIA_CODECS_AVC_DECODER_CONFIGURATION_RECORD_H_
    +
    Class for parsing AVC decoder configuration record.
    + + +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/dce/classshaka_1_1hls_1_1MockMediaPlaylist-members.html b/docs/df/dce/classshaka_1_1hls_1_1MockMediaPlaylist-members.html index 599f770ce5..e2b4be4d7c 100644 --- a/docs/df/dce/classshaka_1_1hls_1_1MockMediaPlaylist-members.html +++ b/docs/df/dce/classshaka_1_1hls_1_1MockMediaPlaylist-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    codec() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline EncryptionMethod enum name (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylist file_name() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline + GetAC4CbiFlag() constshaka::hls::MediaPlaylistvirtual + GetAC4ImsFlag() constshaka::hls::MediaPlaylistvirtual GetDisplayResolution(uint32_t *width, uint32_t *height) constshaka::hls::MediaPlaylistvirtual - GetFrameRate() constshaka::hls::MediaPlaylistvirtual - GetLongestSegmentDuration() constshaka::hls::MediaPlaylistvirtual - GetNumChannels() constshaka::hls::MediaPlaylistvirtual - GetVideoRange() constshaka::hls::MediaPlaylistvirtual - group_id() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline + GetEC3JocComplexity() constshaka::hls::MediaPlaylistvirtual + GetFrameRate() constshaka::hls::MediaPlaylistvirtual + GetLongestSegmentDuration() constshaka::hls::MediaPlaylistvirtual + GetNumChannels() constshaka::hls::MediaPlaylistvirtual + GetVideoRange() constshaka::hls::MediaPlaylistvirtual + group_id() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline + is_dvs() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline language() constshaka::hls::MediaPlaylistinline MaxBitrate() constshaka::hls::MediaPlaylistvirtual MediaPlaylist(const HlsParams &hls_params, const std::string &file_name, const std::string &name, const std::string &group_id)shaka::hls::MediaPlaylist @@ -92,34 +99,35 @@ $(function() { MOCK_CONST_METHOD0(AvgBitrate, uint64_t()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist MOCK_CONST_METHOD0(GetLongestSegmentDuration, double()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist MOCK_CONST_METHOD0(GetNumChannels, int()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_CONST_METHOD0(GetFrameRate, double()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_CONST_METHOD2(GetDisplayResolution, bool(uint32_t *width, uint32_t *height)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_METHOD0(AddPlacementOpportunity, void()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_METHOD1(SetMediaInfo, bool(const MediaInfo &media_info)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_METHOD1(WriteToFile, bool(const std::string &file_path)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_METHOD1(SetTargetDuration, void(uint32_t target_duration)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_METHOD3(AddKeyFrame, void(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_METHOD5(AddSegment, void(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t start_byte_offset, uint64_t size)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MOCK_METHOD6(AddEncryptionInfo, void(EncryptionMethod method, const std::string &url, const std::string &key_id, const std::string &iv, const std::string &key_format, const std::string &key_format_versions)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - MockMediaPlaylist(const std::string &file_name, const std::string &name, const std::string &group_id) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist - name() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline - SetCharacteristicsForTesting(const std::vector< std::string > &characteristics)shaka::hls::MediaPlaylist - SetCodecForTesting(const std::string &codec)shaka::hls::MediaPlaylist - SetLanguageForTesting(const std::string &language)shaka::hls::MediaPlaylist - SetMediaInfo(const MediaInfo &media_info)shaka::hls::MediaPlaylistvirtual - SetSampleDuration(uint32_t sample_duration)shaka::hls::MediaPlaylistvirtual - SetStreamTypeForTesting(MediaPlaylistStreamType stream_type)shaka::hls::MediaPlaylist - SetTargetDuration(uint32_t target_duration)shaka::hls::MediaPlaylistvirtual - stream_type() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline - WriteToFile(const std::string &file_path)shaka::hls::MediaPlaylistvirtual - ~MediaPlaylist() (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistvirtual - ~MockMediaPlaylist() override (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_CONST_METHOD0(GetEC3JocComplexity, int()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_CONST_METHOD0(GetAC4ImsFlag, bool()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_CONST_METHOD0(GetAC4CbiFlag, bool()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_CONST_METHOD0(GetFrameRate, double()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_CONST_METHOD2(GetDisplayResolution, bool(uint32_t *width, uint32_t *height)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_METHOD0(AddPlacementOpportunity, void()) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_METHOD1(SetMediaInfo, bool(const MediaInfo &media_info)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_METHOD1(WriteToFile, bool(const std::string &file_path)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_METHOD1(SetTargetDuration, void(uint32_t target_duration)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_METHOD3(AddKeyFrame, void(int64_t timestamp, uint64_t start_byte_offset, uint64_t size)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_METHOD5(AddSegment, void(const std::string &file_name, int64_t start_time, int64_t duration, uint64_t start_byte_offset, uint64_t size)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MOCK_METHOD6(AddEncryptionInfo, void(EncryptionMethod method, const std::string &url, const std::string &key_id, const std::string &iv, const std::string &key_format, const std::string &key_format_versions)) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + MockMediaPlaylist(const std::string &file_name, const std::string &name, const std::string &group_id) (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist + name() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline + SetCharacteristicsForTesting(const std::vector< std::string > &characteristics)shaka::hls::MediaPlaylist + SetCodecForTesting(const std::string &codec)shaka::hls::MediaPlaylist + SetLanguageForTesting(const std::string &language)shaka::hls::MediaPlaylist + SetMediaInfo(const MediaInfo &media_info)shaka::hls::MediaPlaylistvirtual + SetSampleDuration(uint32_t sample_duration)shaka::hls::MediaPlaylistvirtual + SetStreamTypeForTesting(MediaPlaylistStreamType stream_type)shaka::hls::MediaPlaylist + SetTargetDuration(uint32_t target_duration)shaka::hls::MediaPlaylistvirtual + stream_type() const (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistinline + WriteToFile(const std::string &file_path)shaka::hls::MediaPlaylistvirtual + ~MediaPlaylist() (defined in shaka::hls::MediaPlaylist)shaka::hls::MediaPlaylistvirtual + ~MockMediaPlaylist() override (defined in shaka::hls::MockMediaPlaylist)shaka::hls::MockMediaPlaylist
    diff --git a/docs/df/dd2/mpd__utils_8h_source.html b/docs/df/dd2/mpd__utils_8h_source.html index 0832e7d21e..0726953c78 100644 --- a/docs/df/dd2/mpd__utils_8h_source.html +++ b/docs/df/dd2/mpd__utils_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/mpd_utils.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    mpd_utils.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Funtions used by MpdBuilder class to generate an MPD file.
    8 
    9 #ifndef MPD_BASE_MPD_UTILS_H_
    10 #define MPD_BASE_MPD_UTILS_H_
    11 
    12 #include <libxml/tree.h>
    13 
    14 #include <list>
    15 #include <string>
    16 
    17 namespace shaka {
    18 
    19 class AdaptationSet;
    20 class MediaInfo;
    21 class Representation;
    22 struct ContentProtectionElement;
    23 struct SegmentInfo;
    24 
    25 const char kEncryptedMp4Scheme[] = "urn:mpeg:dash:mp4protection:2011";
    26 const char kPsshElementName[] = "cenc:pssh";
    27 
    28 bool HasVODOnlyFields(const MediaInfo& media_info);
    29 
    30 bool HasLiveOnlyFields(const MediaInfo& media_info);
    31 
    32 // If |content_protection_element| has 'value' or 'schemeIdUri' set but it's
    33 // also in the map, then this removes them from the map.
    34 // |content_protection_element| cannot be NULL.
    35 void RemoveDuplicateAttributes(
    36  ContentProtectionElement* content_protection_element);
    37 
    38 // Returns a language in ISO-639 shortest form. May be blank for video.
    39 std::string GetLanguage(const MediaInfo& media_info);
    40 
    41 // Returns a 'codecs' string that has all the video and audio codecs joined with
    42 // comma.
    43 std::string GetCodecs(const MediaInfo& media_info);
    44 
    45 // Returns a codec string without variants. For example, "mp4a" instead of
    46 // "mp4a.40.2". May return a format for text streams.
    47 std::string GetBaseCodec(const MediaInfo& media_info);
    48 
    49 // Returns a key made from the characteristics that separate AdaptationSets.
    50 std::string GetAdaptationSetKey(const MediaInfo& media_info);
    51 
    52 std::string SecondsToXmlDuration(double seconds);
    53 
    54 // Tries to get "duration" attribute from |node|. On success |duration| is set.
    55 bool GetDurationAttribute(xmlNodePtr node, float* duration);
    56 
    57 bool MoreThanOneTrue(bool b1, bool b2, bool b3);
    58 bool AtLeastOneTrue(bool b1, bool b2, bool b3);
    59 bool OnlyOneTrue(bool b1, bool b2, bool b3);
    60 
    64 bool HexToUUID(const std::string& data, std::string* uuid_format);
    65 
    66 // Update the <cenc:pssh> element for |drm_uuid| ContentProtection element.
    67 // If the element does not exist, this will add one.
    68 void UpdateContentProtectionPsshHelper(
    69  const std::string& drm_uuid,
    70  const std::string& pssh,
    71  std::list<ContentProtectionElement>* content_protection_elements);
    72 
    79 void AddContentProtectionElements(const MediaInfo& media_info,
    80  Representation* parent);
    81 
    87 void AddContentProtectionElements(const MediaInfo& media_info,
    88  AdaptationSet* parent);
    89 
    90 } // namespace shaka
    91 
    92 #endif // MPD_BASE_MPD_UTILS_H_
    All the methods that are virtual are virtual for mocking.
    -
    void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
    Definition: mpd_utils.cc:436
    -
    bool HexToUUID(const std::string &data, std::string *uuid_format)
    Definition: mpd_utils.cc:228
    +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Funtions used by MpdBuilder class to generate an MPD file.
    +
    8 
    +
    9 #ifndef MPD_BASE_MPD_UTILS_H_
    +
    10 #define MPD_BASE_MPD_UTILS_H_
    +
    11 
    +
    12 #include <libxml/tree.h>
    +
    13 
    +
    14 #include <list>
    +
    15 #include <string>
    +
    16 
    +
    17 namespace shaka {
    +
    18 
    +
    19 class AdaptationSet;
    +
    20 class MediaInfo;
    +
    21 class Representation;
    +
    22 struct ContentProtectionElement;
    +
    23 struct SegmentInfo;
    +
    24 
    +
    25 const char kEncryptedMp4Scheme[] = "urn:mpeg:dash:mp4protection:2011";
    +
    26 const char kPsshElementName[] = "cenc:pssh";
    +
    27 const char kMsproElementName[] = "mspr:pro";
    +
    28 
    +
    29 bool HasVODOnlyFields(const MediaInfo& media_info);
    +
    30 
    +
    31 bool HasLiveOnlyFields(const MediaInfo& media_info);
    +
    32 
    +
    33 // If |content_protection_element| has 'value' or 'schemeIdUri' set but it's
    +
    34 // also in the map, then this removes them from the map.
    +
    35 // |content_protection_element| cannot be NULL.
    +
    36 void RemoveDuplicateAttributes(
    +
    37  ContentProtectionElement* content_protection_element);
    +
    38 
    +
    39 // Returns a language in ISO-639 shortest form. May be blank for video.
    +
    40 std::string GetLanguage(const MediaInfo& media_info);
    +
    41 
    +
    42 // Returns a 'codecs' string that has all the video and audio codecs joined with
    +
    43 // comma.
    +
    44 std::string GetCodecs(const MediaInfo& media_info);
    +
    45 
    +
    46 // Returns a codec string without variants. For example, "mp4a" instead of
    +
    47 // "mp4a.40.2". May return a format for text streams.
    +
    48 std::string GetBaseCodec(const MediaInfo& media_info);
    +
    49 
    +
    50 // Returns a key made from the characteristics that separate AdaptationSets.
    +
    51 std::string GetAdaptationSetKey(const MediaInfo& media_info, bool ignore_codec);
    +
    52 
    +
    53 std::string SecondsToXmlDuration(double seconds);
    +
    54 
    +
    55 // Tries to get "duration" attribute from |node|. On success |duration| is set.
    +
    56 bool GetDurationAttribute(xmlNodePtr node, float* duration);
    +
    57 
    +
    58 bool MoreThanOneTrue(bool b1, bool b2, bool b3);
    +
    59 bool AtLeastOneTrue(bool b1, bool b2, bool b3);
    +
    60 bool OnlyOneTrue(bool b1, bool b2, bool b3);
    +
    61 
    +
    65 bool HexToUUID(const std::string& data, std::string* uuid_format);
    +
    66 
    +
    67 // Update the <cenc:pssh> element for |drm_uuid| ContentProtection element.
    +
    68 // If the element does not exist, this will add one.
    +
    69 void UpdateContentProtectionPsshHelper(
    +
    70  const std::string& drm_uuid,
    +
    71  const std::string& pssh,
    +
    72  std::list<ContentProtectionElement>* content_protection_elements);
    +
    73 
    +
    80 void AddContentProtectionElements(const MediaInfo& media_info,
    +
    81  Representation* parent);
    +
    82 
    +
    88 void AddContentProtectionElements(const MediaInfo& media_info,
    +
    89  AdaptationSet* parent);
    +
    90 
    +
    91 } // namespace shaka
    +
    92 
    +
    93 #endif // MPD_BASE_MPD_UTILS_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    bool HexToUUID(const std::string &data, std::string *uuid_format)
    Definition: mpd_utils.cc:232
    +
    void AddContentProtectionElements(const MediaInfo &media_info, Representation *parent)
    Definition: mpd_utils.cc:473
    diff --git a/docs/df/dd2/structshaka_1_1media_1_1H264Pps-members.html b/docs/df/dd2/structshaka_1_1media_1_1H264Pps-members.html index 90cdbbe6a8..d3c5dea08c 100644 --- a/docs/df/dd2/structshaka_1_1media_1_1H264Pps-members.html +++ b/docs/df/dd2/structshaka_1_1media_1_1H264Pps-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    constrained_intra_pred_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps deblocking_filter_control_present_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps entropy_coding_mode_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps - H264Pps() (defined in shaka::media::H264Pps)shaka::media::H264Pps - num_ref_idx_l0_default_active_minus1 (defined in shaka::media::H264Pps)shaka::media::H264Pps - num_ref_idx_l1_default_active_minus1 (defined in shaka::media::H264Pps)shaka::media::H264Pps - num_slice_groups_minus1 (defined in shaka::media::H264Pps)shaka::media::H264Pps - pic_init_qp_minus26 (defined in shaka::media::H264Pps)shaka::media::H264Pps - pic_init_qs_minus26 (defined in shaka::media::H264Pps)shaka::media::H264Pps - pic_parameter_set_id (defined in shaka::media::H264Pps)shaka::media::H264Pps - pic_scaling_matrix_present_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps - redundant_pic_cnt_present_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps - scaling_list4x4 (defined in shaka::media::H264Pps)shaka::media::H264Pps - scaling_list8x8 (defined in shaka::media::H264Pps)shaka::media::H264Pps - second_chroma_qp_index_offset (defined in shaka::media::H264Pps)shaka::media::H264Pps - seq_parameter_set_id (defined in shaka::media::H264Pps)shaka::media::H264Pps - transform_8x8_mode_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps - weighted_bipred_idc (defined in shaka::media::H264Pps)shaka::media::H264Pps - weighted_pred_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps + num_ref_idx_l0_default_active_minus1 (defined in shaka::media::H264Pps)shaka::media::H264Pps + num_ref_idx_l1_default_active_minus1 (defined in shaka::media::H264Pps)shaka::media::H264Pps + num_slice_groups_minus1 (defined in shaka::media::H264Pps)shaka::media::H264Pps + pic_init_qp_minus26 (defined in shaka::media::H264Pps)shaka::media::H264Pps + pic_init_qs_minus26 (defined in shaka::media::H264Pps)shaka::media::H264Pps + pic_parameter_set_id (defined in shaka::media::H264Pps)shaka::media::H264Pps + pic_scaling_matrix_present_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps + redundant_pic_cnt_present_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps + scaling_list4x4 (defined in shaka::media::H264Pps)shaka::media::H264Pps + scaling_list8x8 (defined in shaka::media::H264Pps)shaka::media::H264Pps + second_chroma_qp_index_offset (defined in shaka::media::H264Pps)shaka::media::H264Pps + seq_parameter_set_id (defined in shaka::media::H264Pps)shaka::media::H264Pps + transform_8x8_mode_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps + weighted_bipred_idc (defined in shaka::media::H264Pps)shaka::media::H264Pps + weighted_pred_flag (defined in shaka::media::H264Pps)shaka::media::H264Pps
    diff --git a/docs/df/dda/single__thread__job__manager_8cc_source.html b/docs/df/dda/single__thread__job__manager_8cc_source.html new file mode 100644 index 0000000000..035c164eb9 --- /dev/null +++ b/docs/df/dda/single__thread__job__manager_8cc_source.html @@ -0,0 +1,113 @@ + + + + + + + +Shaka Packager SDK: packager/app/single_thread_job_manager.cc Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    single_thread_job_manager.cc
    +
    +
    +
    1 // Copyright 2020 Google LLLC All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #include "packager/app/single_thread_job_manager.h"
    +
    8 
    +
    9 #include "packager/media/chunking/sync_point_queue.h"
    +
    10 #include "packager/media/origin/origin_handler.h"
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    15 SingleThreadJobManager::SingleThreadJobManager(
    +
    16  std::unique_ptr<SyncPointQueue> sync_points)
    +
    17  : JobManager(std::move(sync_points)) {}
    +
    18 
    +
    19 Status SingleThreadJobManager::InitializeJobs() {
    +
    20  Status status;
    +
    21  for (const JobEntry& job_entry : job_entries_)
    +
    22  status.Update(job_entry.worker->Initialize());
    +
    23  return status;
    +
    24 }
    +
    25 
    +
    26 Status SingleThreadJobManager::RunJobs() {
    +
    27  Status status;
    +
    28  for (const JobEntry& job_entry : job_entries_)
    +
    29  status.Update(job_entry.worker->Run());
    +
    30  return status;
    +
    31 }
    +
    32 
    +
    33 } // namespace media
    +
    34 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    +
    + + + + diff --git a/docs/df/ddc/structshaka_1_1MpdParams.html b/docs/df/ddc/structshaka_1_1MpdParams.html index 3eb6e0fcf0..31ff8985eb 100644 --- a/docs/df/ddc/structshaka_1_1MpdParams.html +++ b/docs/df/ddc/structshaka_1_1MpdParams.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::MpdParams Struct Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
      double target_segment_duration = 0   +bool allow_codec_switching = false +  +bool include_mspr_pro = true +  @@ -141,10 +148,27 @@ Static Public Attributes

    Static Public Attributes

    -

    For live profile only. If enabled, segments with close duration (i.e. with difference less than one sample) are considered to have the same duration. This enables MPD generator to generate less SegmentTimeline entries. If all segments are of the same duration except the last one, we will do further optimization to use SegmentTemplate instead and omit SegmentTimeline completely. Ignored if $Time$ is used in segment template, since $Time$ requires accurate Segment Timeline.

    +

    For live profile only. If enabled, segments with close duration (i.e. with difference less than one sample) are considered to have the same duration. This enables MPD generator to generate less SegmentTimeline entries. If all segments are of the same duration except the last one, we will do further optimization to use SegmentTemplate@duration instead and omit SegmentTimeline completely. Ignored if $Time$ is used in segment template, since $Time$ requires accurate Segment Timeline.

    Definition at line 76 of file mpd_params.h.

    +
    + + +

    ◆ allow_codec_switching

    + +
    +
    + + + + +
    bool shaka::MpdParams::allow_codec_switching = false
    +
    +

    If enabled, allow switching between different codecs, if they have the same language, media type (audio, video etc) and container type.

    + +

    Definition at line 85 of file mpd_params.h.

    +
    @@ -213,6 +237,23 @@ Static Public Attributes

    Definition at line 64 of file mpd_params.h.

    + + + +

    ◆ include_mspr_pro

    + +
    +
    + + + + +
    bool shaka::MpdParams::include_mspr_pro = true
    +
    +

    If enabled, PlayReady Object <mspr:pro> will be inserted into <ContentProtection ...> element alongside with <cenc:pssh> when using PlayReady protection system.

    + +

    Definition at line 89 of file mpd_params.h.

    +
    @@ -230,11 +271,11 @@ Static Public Attributes -static +staticconstexpr
    -

    Set MPD attribute. For 'dynamic' media presentations, it specifies a delay, in seconds, to be added to the media presentation time. The attribute is not set if the value is 0; the client is expected to choose a suitable value in this case.

    +

    Set MPD@suggestedPresentationDelay attribute. For 'dynamic' media presentations, it specifies a delay, in seconds, to be added to the media presentation time. The attribute is not set if the value is 0; the client is expected to choose a suitable value in this case.

    Definition at line 35 of file mpd_params.h.

    @@ -251,7 +292,7 @@ Static Public Attributes
    -

    Set MPD attribute, which specifies, in seconds, a common duration used in the definition of the MPD representation data rate. A client can be assured of having enough data for continous playout providing playout begins at min_buffer_time after the first bit is received.

    +

    Set MPD@minBufferTime attribute, which specifies, in seconds, a common duration used in the definition of the MPD representation data rate. A client can be assured of having enough data for continous playout providing playout begins at min_buffer_time after the first bit is received.

    Definition at line 27 of file mpd_params.h.

    @@ -268,7 +309,7 @@ Static Public Attributes
    -

    Set MPD attribute, which indicates to the player how often to refresh the MPD in seconds. For dynamic MPD only.

    +

    Set MPD@minimumUpdatePeriod attribute, which indicates to the player how often to refresh the MPD in seconds. For dynamic MPD only.

    Definition at line 30 of file mpd_params.h.

    @@ -302,7 +343,7 @@ Static Public Attributes
    -

    This is the target segment duration requested by the user. The actual segment duration may be different to the target segment duration. This parameter is included here to calculate the approximate SegmentTimeline if it is enabled. It will be populated from segment duration specified in ChunkingParams if not specified.

    +

    This is the target segment duration requested by the user. The actual segment duration may be different to the target segment duration. This parameter is included here to calculate the approximate SegmentTimeline if it is enabled. It will be populated from segment duration specified in ChunkingParams if not specified.

    Definition at line 82 of file mpd_params.h.

    @@ -319,7 +360,7 @@ Static Public Attributes
    -

    Set MPD attribute, which is the guaranteed duration of the time shifting buffer for 'dynamic' media presentations, in seconds.

    +

    Set MPD@timeShiftBufferDepth attribute, which is the guaranteed duration of the time shifting buffer for 'dynamic' media presentations, in seconds.

    Definition at line 39 of file mpd_params.h.

    @@ -331,9 +372,7 @@ Static Public Attributes
    diff --git a/docs/df/ddc/webm_2segmenter_8h_source.html b/docs/df/ddc/webm_2segmenter_8h_source.html index baaa781ee8..775a3f188d 100644 --- a/docs/df/ddc/webm_2segmenter_8h_source.html +++ b/docs/df/ddc/webm_2segmenter_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm/segmenter.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    segmenter.h
    -
    1 // Copyright 2015 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
    9 
    10 #include <memory>
    11 
    12 #include "packager/base/optional.h"
    13 #include "packager/media/base/range.h"
    14 #include "packager/media/formats/webm/mkv_writer.h"
    15 #include "packager/media/formats/webm/seek_head.h"
    16 #include "packager/status.h"
    17 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
    18 
    19 namespace shaka {
    20 namespace media {
    21 
    22 struct MuxerOptions;
    23 
    24 class AudioStreamInfo;
    25 class MediaSample;
    26 class MuxerListener;
    27 class ProgressListener;
    28 class StreamInfo;
    29 class VideoStreamInfo;
    30 
    31 namespace webm {
    32 
    33 class Segmenter {
    34  public:
    35  explicit Segmenter(const MuxerOptions& options);
    36  virtual ~Segmenter();
    37 
    44  Status Initialize(const StreamInfo& info,
    45  ProgressListener* progress_listener,
    46  MuxerListener* muxer_listener);
    47 
    50  Status Finalize();
    51 
    55  Status AddSample(const MediaSample& sample);
    56 
    58  virtual Status FinalizeSegment(uint64_t start_timestamp,
    59  uint64_t duration_timestamp,
    60  bool is_subsegment) = 0;
    61 
    64  virtual bool GetInitRangeStartAndEnd(uint64_t* start, uint64_t* end) = 0;
    65 
    68  virtual bool GetIndexRangeStartAndEnd(uint64_t* start, uint64_t* end) = 0;
    69 
    70  // Returns an empty vector if there are no specific ranges for the segments,
    71  // e.g. the media is in multiple files.
    72  // Otherwise, a vector of ranges for the media segments are returned.
    73  virtual std::vector<Range> GetSegmentRanges() = 0;
    74 
    76  float GetDurationInSeconds() const;
    77 
    78  protected:
    80  uint64_t FromBmffTimestamp(uint64_t bmff_timestamp);
    82  uint64_t FromWebMTimecode(uint64_t webm_timecode);
    84  Status WriteSegmentHeader(uint64_t file_size, MkvWriter* writer);
    86  Status SetCluster(uint64_t start_webm_timecode,
    87  uint64_t position,
    88  MkvWriter* writer);
    89 
    91  void UpdateProgress(uint64_t progress);
    92  void set_progress_target(uint64_t target) { progress_target_ = target; }
    93 
    94  const MuxerOptions& options() const { return options_; }
    95  mkvmuxer::Cluster* cluster() { return cluster_.get(); }
    96  mkvmuxer::Cues* cues() { return &cues_; }
    97  MuxerListener* muxer_listener() { return muxer_listener_; }
    98  SeekHead* seek_head() { return &seek_head_; }
    99 
    100  int track_id() const { return track_id_; }
    101  uint64_t segment_payload_pos() const { return segment_payload_pos_; }
    102 
    103  uint64_t duration() const { return duration_; }
    104 
    105  virtual Status DoInitialize() = 0;
    106  virtual Status DoFinalize() = 0;
    107 
    108  private:
    109  Status InitializeAudioTrack(const AudioStreamInfo& info,
    110  mkvmuxer::AudioTrack* track);
    111  Status InitializeVideoTrack(const VideoStreamInfo& info,
    112  mkvmuxer::VideoTrack* track);
    113 
    114  // Writes the previous frame to the file.
    115  Status WriteFrame(bool write_duration);
    116 
    117  // This is called when there needs to be a new (sub)segment.
    118  // In single-segment mode, a Cluster is a segment and there is no subsegment.
    119  // In multi-segment mode, a new file is a segment and the clusters in the file
    120  // are subsegments.
    121  virtual Status NewSegment(uint64_t start_timestamp, bool is_subsegment) = 0;
    122 
    123  // Store the previous sample so we know which one is the last frame.
    124  std::shared_ptr<const MediaSample> prev_sample_;
    125  // The reference frame timestamp; used to populate the ReferenceBlock element
    126  // when writing non-keyframe BlockGroups.
    127  uint64_t reference_frame_timestamp_ = 0;
    128 
    129  const MuxerOptions& options_;
    130 
    131  std::unique_ptr<mkvmuxer::Cluster> cluster_;
    132  mkvmuxer::Cues cues_;
    133  SeekHead seek_head_;
    134  mkvmuxer::SegmentInfo segment_info_;
    135  mkvmuxer::Tracks tracks_;
    136 
    137  MuxerListener* muxer_listener_ = nullptr;
    138  ProgressListener* progress_listener_ = nullptr;
    139  uint64_t progress_target_ = 0;
    140  uint64_t accumulated_progress_ = 0;
    141  uint64_t first_timestamp_ = 0;
    142  int64_t sample_duration_ = 0;
    143  // The position (in bytes) of the start of the Segment payload in the init
    144  // file. This is also the size of the header before the SeekHead.
    145  uint64_t segment_payload_pos_ = 0;
    146 
    147  // Indicate whether a new segment needed to be created, which is always true
    148  // in the beginning.
    149  bool new_segment_ = true;
    150  // Indicate whether a new subsegment needed to be created.
    151  bool new_subsegment_ = false;
    152  int track_id_ = 0;
    153 
    154  // The subset of information that we need from StreamInfo
    155  bool is_encrypted_ = false;
    156  uint64_t time_scale_ = 0;
    157  uint64_t duration_ = 0;
    158 
    159  DISALLOW_COPY_AND_ASSIGN(Segmenter);
    160 };
    161 
    162 } // namespace webm
    163 } // namespace media
    164 } // namespace shaka
    165 
    166 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
    Status WriteSegmentHeader(uint64_t file_size, MkvWriter *writer)
    Writes the Segment header to writer.
    Definition: segmenter.cc:223
    -
    Abstract class holds stream information.
    Definition: stream_info.h:62
    -
    uint64_t FromWebMTimecode(uint64_t webm_timecode)
    Converts the given time in WebM timecode to ISO BMFF timestamp.
    Definition: segmenter.cc:217
    - -
    uint64_t FromBmffTimestamp(uint64_t bmff_timestamp)
    Converts the given time in ISO BMFF timestamp to WebM timecode.
    Definition: segmenter.cc:211
    -
    All the methods that are virtual are virtual for mocking.
    -
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    -
    Status AddSample(const MediaSample &sample)
    Definition: segmenter.cc:159
    -
    virtual Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration_timestamp, bool is_subsegment)=0
    Finalize the (sub)segment.
    Definition: segmenter.cc:195
    - -
    Status SetCluster(uint64_t start_webm_timecode, uint64_t position, MkvWriter *writer)
    Creates a Cluster object with the given parameters.
    Definition: segmenter.cc:261
    -
    float GetDurationInSeconds() const
    Definition: segmenter.cc:205
    -
    This class listens to progress updates events.
    -
    virtual bool GetIndexRangeStartAndEnd(uint64_t *start, uint64_t *end)=0
    -
    Status Initialize(const StreamInfo &info, ProgressListener *progress_listener, MuxerListener *muxer_listener)
    Definition: segmenter.cc:78
    -
    An implementation of IMkvWriter using our File type.
    Definition: mkv_writer.h:21
    -
    Class to hold a media sample.
    Definition: media_sample.h:22
    - - -
    void UpdateProgress(uint64_t progress)
    Update segmentation progress using ProgressListener.
    Definition: segmenter.cc:270
    -
    virtual bool GetInitRangeStartAndEnd(uint64_t *start, uint64_t *end)=0
    -
    Holds video stream information.
    -
    Holds audio stream information.
    - +
    1 // Copyright 2015 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
    +
    8 #define PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 
    +
    12 #include "packager/base/optional.h"
    +
    13 #include "packager/media/base/range.h"
    +
    14 #include "packager/media/formats/webm/mkv_writer.h"
    +
    15 #include "packager/media/formats/webm/seek_head.h"
    +
    16 #include "packager/status.h"
    +
    17 #include "packager/third_party/libwebm/src/mkvmuxer.hpp"
    +
    18 
    +
    19 namespace shaka {
    +
    20 namespace media {
    +
    21 
    +
    22 struct MuxerOptions;
    +
    23 
    +
    24 class AudioStreamInfo;
    +
    25 class MediaSample;
    +
    26 class MuxerListener;
    +
    27 class ProgressListener;
    +
    28 class StreamInfo;
    +
    29 class VideoStreamInfo;
    +
    30 
    +
    31 namespace webm {
    +
    32 
    +
    33 class Segmenter {
    +
    34  public:
    +
    35  explicit Segmenter(const MuxerOptions& options);
    +
    36  virtual ~Segmenter();
    +
    37 
    +
    44  Status Initialize(const StreamInfo& info,
    +
    45  ProgressListener* progress_listener,
    +
    46  MuxerListener* muxer_listener);
    +
    47 
    +
    50  Status Finalize();
    +
    51 
    +
    55  Status AddSample(const MediaSample& sample);
    +
    56 
    +
    58  virtual Status FinalizeSegment(uint64_t start_timestamp,
    +
    59  uint64_t duration_timestamp,
    +
    60  bool is_subsegment) = 0;
    +
    61 
    +
    64  virtual bool GetInitRangeStartAndEnd(uint64_t* start, uint64_t* end) = 0;
    +
    65 
    +
    68  virtual bool GetIndexRangeStartAndEnd(uint64_t* start, uint64_t* end) = 0;
    +
    69 
    +
    70  // Returns an empty vector if there are no specific ranges for the segments,
    +
    71  // e.g. the media is in multiple files.
    +
    72  // Otherwise, a vector of ranges for the media segments are returned.
    +
    73  virtual std::vector<Range> GetSegmentRanges() = 0;
    +
    74 
    +
    76  float GetDurationInSeconds() const;
    +
    77 
    +
    78  protected:
    +
    80  uint64_t FromBmffTimestamp(uint64_t bmff_timestamp);
    +
    82  uint64_t FromWebMTimecode(uint64_t webm_timecode);
    +
    84  Status WriteSegmentHeader(uint64_t file_size, MkvWriter* writer);
    +
    86  Status SetCluster(uint64_t start_webm_timecode,
    +
    87  uint64_t position,
    +
    88  MkvWriter* writer);
    +
    89 
    +
    91  void UpdateProgress(uint64_t progress);
    +
    92  void set_progress_target(uint64_t target) { progress_target_ = target; }
    +
    93 
    +
    94  const MuxerOptions& options() const { return options_; }
    +
    95  mkvmuxer::Cluster* cluster() { return cluster_.get(); }
    +
    96  mkvmuxer::Cues* cues() { return &cues_; }
    +
    97  MuxerListener* muxer_listener() { return muxer_listener_; }
    +
    98  SeekHead* seek_head() { return &seek_head_; }
    +
    99 
    +
    100  int track_id() const { return track_id_; }
    +
    101  uint64_t segment_payload_pos() const { return segment_payload_pos_; }
    +
    102 
    +
    103  uint64_t duration() const { return duration_; }
    +
    104 
    +
    105  virtual Status DoInitialize() = 0;
    +
    106  virtual Status DoFinalize() = 0;
    +
    107 
    +
    108  private:
    +
    109  Status InitializeAudioTrack(const AudioStreamInfo& info,
    +
    110  mkvmuxer::AudioTrack* track);
    +
    111  Status InitializeVideoTrack(const VideoStreamInfo& info,
    +
    112  mkvmuxer::VideoTrack* track);
    +
    113 
    +
    114  // Writes the previous frame to the file.
    +
    115  Status WriteFrame(bool write_duration);
    +
    116 
    +
    117  // This is called when there needs to be a new (sub)segment.
    +
    118  // In single-segment mode, a Cluster is a segment and there is no subsegment.
    +
    119  // In multi-segment mode, a new file is a segment and the clusters in the file
    +
    120  // are subsegments.
    +
    121  virtual Status NewSegment(uint64_t start_timestamp, bool is_subsegment) = 0;
    +
    122 
    +
    123  // Store the previous sample so we know which one is the last frame.
    +
    124  std::shared_ptr<const MediaSample> prev_sample_;
    +
    125  // The reference frame timestamp; used to populate the ReferenceBlock element
    +
    126  // when writing non-keyframe BlockGroups.
    +
    127  uint64_t reference_frame_timestamp_ = 0;
    +
    128 
    +
    129  const MuxerOptions& options_;
    +
    130 
    +
    131  std::unique_ptr<mkvmuxer::Cluster> cluster_;
    +
    132  mkvmuxer::Cues cues_;
    +
    133  SeekHead seek_head_;
    +
    134  mkvmuxer::SegmentInfo segment_info_;
    +
    135  mkvmuxer::Tracks tracks_;
    +
    136 
    +
    137  MuxerListener* muxer_listener_ = nullptr;
    +
    138  ProgressListener* progress_listener_ = nullptr;
    +
    139  uint64_t progress_target_ = 0;
    +
    140  uint64_t accumulated_progress_ = 0;
    +
    141  uint64_t first_timestamp_ = 0;
    +
    142  int64_t sample_duration_ = 0;
    +
    143  // The position (in bytes) of the start of the Segment payload in the init
    +
    144  // file. This is also the size of the header before the SeekHead.
    +
    145  uint64_t segment_payload_pos_ = 0;
    +
    146 
    +
    147  // Indicate whether a new segment needed to be created, which is always true
    +
    148  // in the beginning.
    +
    149  bool new_segment_ = true;
    +
    150  // Indicate whether a new subsegment needed to be created.
    +
    151  bool new_subsegment_ = false;
    +
    152  int track_id_ = 0;
    +
    153 
    +
    154  // The subset of information that we need from StreamInfo
    +
    155  bool is_encrypted_ = false;
    +
    156  uint64_t time_scale_ = 0;
    +
    157  uint64_t duration_ = 0;
    +
    158 
    +
    159  DISALLOW_COPY_AND_ASSIGN(Segmenter);
    +
    160 };
    +
    161 
    +
    162 } // namespace webm
    +
    163 } // namespace media
    +
    164 } // namespace shaka
    +
    165 
    +
    166 #endif // PACKAGER_MEDIA_FORMATS_WEBM_SEGMENTER_H_
    + +
    Class to hold a media sample.
    Definition: media_sample.h:22
    +
    An implementation of IMkvWriter using our File type.
    Definition: mkv_writer.h:21
    + +
    This class listens to progress updates events.
    +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    + +
    Status Initialize(const StreamInfo &info, ProgressListener *progress_listener, MuxerListener *muxer_listener)
    Definition: segmenter.cc:78
    +
    void UpdateProgress(uint64_t progress)
    Update segmentation progress using ProgressListener.
    Definition: segmenter.cc:272
    +
    virtual bool GetIndexRangeStartAndEnd(uint64_t *start, uint64_t *end)=0
    +
    virtual Status FinalizeSegment(uint64_t start_timestamp, uint64_t duration_timestamp, bool is_subsegment)=0
    Finalize the (sub)segment.
    Definition: segmenter.cc:197
    +
    Status SetCluster(uint64_t start_webm_timecode, uint64_t position, MkvWriter *writer)
    Creates a Cluster object with the given parameters.
    Definition: segmenter.cc:263
    +
    virtual bool GetInitRangeStartAndEnd(uint64_t *start, uint64_t *end)=0
    +
    float GetDurationInSeconds() const
    Definition: segmenter.cc:207
    +
    Status AddSample(const MediaSample &sample)
    Definition: segmenter.cc:161
    + +
    uint64_t FromBmffTimestamp(uint64_t bmff_timestamp)
    Converts the given time in ISO BMFF timestamp to WebM timecode.
    Definition: segmenter.cc:213
    +
    uint64_t FromWebMTimecode(uint64_t webm_timecode)
    Converts the given time in WebM timecode to ISO BMFF timestamp.
    Definition: segmenter.cc:219
    +
    Status WriteSegmentHeader(uint64_t file_size, MkvWriter *writer)
    Writes the Segment header to writer.
    Definition: segmenter.cc:225
    +
    All the methods that are virtual are virtual for mocking.
    +
    This structure contains the list of configuration options for Muxer.
    Definition: muxer_options.h:20
    diff --git a/docs/df/dde/ts__section__psi_8cc_source.html b/docs/df/dde/ts__section__psi_8cc_source.html index 6e6c7ade35..364a3092e8 100644 --- a/docs/df/dde/ts__section__psi_8cc_source.html +++ b/docs/df/dde/ts__section__psi_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t/ts_section_psi.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    ts_section_psi.cc
    -
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/formats/mp2t/ts_section_psi.h"
    6 
    7 #include <stdint.h>
    8 
    9 #include <algorithm>
    10 
    11 #include "packager/base/logging.h"
    12 #include "packager/media/base/bit_reader.h"
    13 #include "packager/media/formats/mp2t/mp2t_common.h"
    14 
    15 static bool IsCrcValid(const uint8_t* buf, int size) {
    16  uint32_t crc = 0xffffffffu;
    17  const uint32_t kCrcPoly = 0x4c11db7;
    18 
    19  for (int k = 0; k < size; k++) {
    20  int nbits = 8;
    21  uint32_t data_msb_aligned = buf[k];
    22  data_msb_aligned <<= (32 - nbits);
    23 
    24  while (nbits > 0) {
    25  if ((data_msb_aligned ^ crc) & 0x80000000) {
    26  crc <<= 1;
    27  crc ^= kCrcPoly;
    28  } else {
    29  crc <<= 1;
    30  }
    31 
    32  data_msb_aligned <<= 1;
    33  nbits--;
    34  }
    35  }
    36 
    37  return (crc == 0);
    38 }
    39 
    40 namespace shaka {
    41 namespace media {
    42 namespace mp2t {
    43 
    44 TsSectionPsi::TsSectionPsi()
    45  : wait_for_pusi_(true),
    46  leading_bytes_to_discard_(0) {
    47 }
    48 
    49 TsSectionPsi::~TsSectionPsi() {
    50 }
    51 
    52 bool TsSectionPsi::Parse(bool payload_unit_start_indicator,
    53  const uint8_t* buf,
    54  int size) {
    55  // Ignore partial PSI.
    56  if (wait_for_pusi_ && !payload_unit_start_indicator)
    57  return true;
    58 
    59  if (payload_unit_start_indicator) {
    60  // Reset the state of the PSI section.
    61  ResetPsiState();
    62 
    63  // Update the state.
    64  wait_for_pusi_ = false;
    65  DCHECK_GE(size, 1);
    66  int pointer_field = buf[0];
    67  leading_bytes_to_discard_ = pointer_field;
    68  buf++;
    69  size--;
    70  }
    71 
    72  // Discard some leading bytes if needed.
    73  if (leading_bytes_to_discard_ > 0) {
    74  int nbytes_to_discard = std::min(leading_bytes_to_discard_, size);
    75  buf += nbytes_to_discard;
    76  size -= nbytes_to_discard;
    77  leading_bytes_to_discard_ -= nbytes_to_discard;
    78  }
    79  if (size == 0)
    80  return true;
    81 
    82  // Add the data to the parser state.
    83  psi_byte_queue_.Push(buf, size);
    84  int raw_psi_size;
    85  const uint8_t* raw_psi;
    86  psi_byte_queue_.Peek(&raw_psi, &raw_psi_size);
    87 
    88  // Check whether we have enough data to start parsing.
    89  if (raw_psi_size < 3)
    90  return true;
    91  int section_length =
    92  ((static_cast<int>(raw_psi[1]) << 8) |
    93  (static_cast<int>(raw_psi[2]))) & 0xfff;
    94  if (section_length >= 1021)
    95  return false;
    96  int psi_length = section_length + 3;
    97  if (raw_psi_size < psi_length) {
    98  // Don't throw an error when there is not enough data,
    99  // just wait for more data to come.
    100  return true;
    101  }
    102 
    103  // There should not be any trailing bytes after a PMT.
    104  // Instead, the pointer field should be used to stuff bytes.
    105  DVLOG_IF(1, raw_psi_size > psi_length)
    106  << "Trailing bytes after a PSI section: "
    107  << psi_length << " vs " << raw_psi_size;
    108 
    109  // Verify the CRC.
    110  RCHECK(IsCrcValid(raw_psi, psi_length));
    111 
    112  // Parse the PSI section.
    113  BitReader bit_reader(raw_psi, raw_psi_size);
    114  bool status = ParsePsiSection(&bit_reader);
    115  if (status)
    116  ResetPsiState();
    117 
    118  return status;
    119 }
    120 
    121 void TsSectionPsi::Flush() {
    122 }
    123 
    124 void TsSectionPsi::Reset() {
    125  ResetPsiSection();
    126  ResetPsiState();
    127 }
    128 
    129 void TsSectionPsi::ResetPsiState() {
    130  wait_for_pusi_ = true;
    131  psi_byte_queue_.Reset();
    132  leading_bytes_to_discard_ = 0;
    133 }
    134 
    135 } // namespace mp2t
    136 } // namespace media
    137 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2014 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/formats/mp2t/ts_section_psi.h"
    +
    6 
    +
    7 #include <stdint.h>
    +
    8 
    +
    9 #include <algorithm>
    +
    10 
    +
    11 #include "packager/base/logging.h"
    +
    12 #include "packager/media/base/bit_reader.h"
    +
    13 #include "packager/media/formats/mp2t/mp2t_common.h"
    +
    14 
    +
    15 static bool IsCrcValid(const uint8_t* buf, int size) {
    +
    16  uint32_t crc = 0xffffffffu;
    +
    17  const uint32_t kCrcPoly = 0x4c11db7;
    +
    18 
    +
    19  for (int k = 0; k < size; k++) {
    +
    20  int nbits = 8;
    +
    21  uint32_t data_msb_aligned = buf[k];
    +
    22  data_msb_aligned <<= (32 - nbits);
    +
    23 
    +
    24  while (nbits > 0) {
    +
    25  if ((data_msb_aligned ^ crc) & 0x80000000) {
    +
    26  crc <<= 1;
    +
    27  crc ^= kCrcPoly;
    +
    28  } else {
    +
    29  crc <<= 1;
    +
    30  }
    +
    31 
    +
    32  data_msb_aligned <<= 1;
    +
    33  nbits--;
    +
    34  }
    +
    35  }
    +
    36 
    +
    37  return (crc == 0);
    +
    38 }
    +
    39 
    +
    40 namespace shaka {
    +
    41 namespace media {
    +
    42 namespace mp2t {
    +
    43 
    +
    44 TsSectionPsi::TsSectionPsi()
    +
    45  : wait_for_pusi_(true),
    +
    46  leading_bytes_to_discard_(0) {
    +
    47 }
    +
    48 
    +
    49 TsSectionPsi::~TsSectionPsi() {
    +
    50 }
    +
    51 
    +
    52 bool TsSectionPsi::Parse(bool payload_unit_start_indicator,
    +
    53  const uint8_t* buf,
    +
    54  int size) {
    +
    55  // Ignore partial PSI.
    +
    56  if (wait_for_pusi_ && !payload_unit_start_indicator)
    +
    57  return true;
    +
    58 
    +
    59  if (payload_unit_start_indicator) {
    +
    60  // Reset the state of the PSI section.
    +
    61  ResetPsiState();
    +
    62 
    +
    63  // Update the state.
    +
    64  wait_for_pusi_ = false;
    +
    65  DCHECK_GE(size, 1);
    +
    66  int pointer_field = buf[0];
    +
    67  leading_bytes_to_discard_ = pointer_field;
    +
    68  buf++;
    +
    69  size--;
    +
    70  }
    +
    71 
    +
    72  // Discard some leading bytes if needed.
    +
    73  if (leading_bytes_to_discard_ > 0) {
    +
    74  int nbytes_to_discard = std::min(leading_bytes_to_discard_, size);
    +
    75  buf += nbytes_to_discard;
    +
    76  size -= nbytes_to_discard;
    +
    77  leading_bytes_to_discard_ -= nbytes_to_discard;
    +
    78  }
    +
    79  if (size == 0)
    +
    80  return true;
    +
    81 
    +
    82  // Add the data to the parser state.
    +
    83  psi_byte_queue_.Push(buf, size);
    +
    84  int raw_psi_size;
    +
    85  const uint8_t* raw_psi;
    +
    86  psi_byte_queue_.Peek(&raw_psi, &raw_psi_size);
    +
    87 
    +
    88  // Check whether we have enough data to start parsing.
    +
    89  if (raw_psi_size < 3)
    +
    90  return true;
    +
    91  int section_length =
    +
    92  ((static_cast<int>(raw_psi[1]) << 8) |
    +
    93  (static_cast<int>(raw_psi[2]))) & 0xfff;
    +
    94  if (section_length >= 1021)
    +
    95  return false;
    +
    96  int psi_length = section_length + 3;
    +
    97  if (raw_psi_size < psi_length) {
    +
    98  // Don't throw an error when there is not enough data,
    +
    99  // just wait for more data to come.
    +
    100  return true;
    +
    101  }
    +
    102 
    +
    103  // There should not be any trailing bytes after a PMT.
    +
    104  // Instead, the pointer field should be used to stuff bytes.
    +
    105  DVLOG_IF(1, raw_psi_size > psi_length)
    +
    106  << "Trailing bytes after a PSI section: "
    +
    107  << psi_length << " vs " << raw_psi_size;
    +
    108 
    +
    109  // Verify the CRC.
    +
    110  RCHECK(IsCrcValid(raw_psi, psi_length));
    +
    111 
    +
    112  // Parse the PSI section.
    +
    113  BitReader bit_reader(raw_psi, raw_psi_size);
    +
    114  bool status = ParsePsiSection(&bit_reader);
    +
    115  if (status)
    +
    116  ResetPsiState();
    +
    117 
    +
    118  return status;
    +
    119 }
    +
    120 
    +
    121 bool TsSectionPsi::Flush() {
    +
    122  return true;
    +
    123 }
    +
    124 
    +
    125 void TsSectionPsi::Reset() {
    +
    126  ResetPsiSection();
    +
    127  ResetPsiState();
    +
    128 }
    +
    129 
    +
    130 void TsSectionPsi::ResetPsiState() {
    +
    131  wait_for_pusi_ = true;
    +
    132  psi_byte_queue_.Reset();
    +
    133  leading_bytes_to_discard_ = 0;
    +
    134 }
    +
    135 
    +
    136 } // namespace mp2t
    +
    137 } // namespace media
    +
    138 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/de2/structshaka_1_1media_1_1H264SEIRecoveryPoint.html b/docs/df/de2/structshaka_1_1media_1_1H264SEIRecoveryPoint.html index 5dddb67c41..8a134324c9 100644 --- a/docs/df/de2/structshaka_1_1media_1_1H264SEIRecoveryPoint.html +++ b/docs/df/de2/structshaka_1_1media_1_1H264SEIRecoveryPoint.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: shaka::media::H264SEIRecoveryPoint Struct Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    changing_slice_group_i

    Detailed Description

    -

    Definition at line 225 of file h264_parser.h.

    +

    Definition at line 219 of file h264_parser.h.


    The documentation for this struct was generated from the following file:
    diff --git a/docs/df/de3/text__track__config_8cc_source.html b/docs/df/de3/text__track__config_8cc_source.html index f9e27a1ae2..e3653b969f 100644 --- a/docs/df/de3/text__track__config_8cc_source.html +++ b/docs/df/de3/text__track__config_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/text_track_config.cc Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    text_track_config.cc
    -
    1 // Copyright 2013 The Chromium Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 #include "packager/media/base/text_track_config.h"
    6 
    7 namespace shaka {
    8 namespace media {
    9 
    10 TextTrackConfig::TextTrackConfig()
    11  : kind_(kTextNone) {
    12 }
    13 
    14 TextTrackConfig::TextTrackConfig(TextKind kind,
    15  const std::string& label,
    16  const std::string& language,
    17  const std::string& id)
    18  : kind_(kind),
    19  label_(label),
    20  language_(language),
    21  id_(id) {
    22 }
    23 
    24 bool TextTrackConfig::Matches(const TextTrackConfig& config) const {
    25  return config.kind() == kind_ &&
    26  config.label() == label_ &&
    27  config.language() == language_ &&
    28  config.id() == id_;
    29 }
    30 
    31 } // namespace media
    32 } // namespace shaka
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2013 The Chromium Authors. All rights reserved.
    +
    2 // Use of this source code is governed by a BSD-style license that can be
    +
    3 // found in the LICENSE file.
    +
    4 
    +
    5 #include "packager/media/base/text_track_config.h"
    +
    6 
    +
    7 namespace shaka {
    +
    8 namespace media {
    +
    9 
    +
    10 TextTrackConfig::TextTrackConfig()
    +
    11  : kind_(kTextNone) {
    +
    12 }
    +
    13 
    +
    14 TextTrackConfig::TextTrackConfig(TextKind kind,
    +
    15  const std::string& label,
    +
    16  const std::string& language,
    +
    17  const std::string& id)
    +
    18  : kind_(kind),
    +
    19  label_(label),
    +
    20  language_(language),
    +
    21  id_(id) {
    +
    22 }
    +
    23 
    +
    24 bool TextTrackConfig::Matches(const TextTrackConfig& config) const {
    +
    25  return config.kind() == kind_ &&
    +
    26  config.label() == label_ &&
    +
    27  config.language() == language_ &&
    +
    28  config.id() == id_;
    +
    29 }
    +
    30 
    +
    31 } // namespace media
    +
    32 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/de9/segment__info_8h_source.html b/docs/df/de9/segment__info_8h_source.html index 14b57f6519..19f9992fc1 100644 --- a/docs/df/de9/segment__info_8h_source.html +++ b/docs/df/de9/segment__info_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/segment_info.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    segment_info.h
    -
    1 // Copyright 2014 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef MPD_BASE_SEGMENT_INFO_H_
    8 #define MPD_BASE_SEGMENT_INFO_H_
    9 
    10 namespace shaka {
    14 struct SegmentInfo {
    15  int64_t start_time;
    16  int64_t duration;
    17  // This is the number of times same duration segments are repeated not
    18  // inclusive. In other words if this is the only one segment that starts at
    19  // |start_time| and has |duration| but none others have |start_time| * N and
    20  // |duration|, then this should be set to 0. The semantics is the same as S@r
    21  // in the DASH MPD spec.
    22  int repeat;
    23 };
    24 } // namespace shaka
    25 
    26 #endif // MPD_BASE_SEGMENT_INFO_H_
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2014 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef MPD_BASE_SEGMENT_INFO_H_
    +
    8 #define MPD_BASE_SEGMENT_INFO_H_
    +
    9 
    +
    10 namespace shaka {
    +
    14 struct SegmentInfo {
    +
    15  int64_t start_time;
    +
    16  int64_t duration;
    +
    17  // This is the number of times same duration segments are repeated not
    +
    18  // inclusive. In other words if this is the only one segment that starts at
    +
    19  // |start_time| and has |duration| but none others have |start_time| * N and
    +
    20  // |duration|, then this should be set to 0. The semantics is the same as S@r
    +
    21  // in the DASH MPD spec.
    +
    22  int repeat;
    +
    23 };
    +
    24 } // namespace shaka
    +
    25 
    +
    26 #endif // MPD_BASE_SEGMENT_INFO_H_
    +
    All the methods that are virtual are virtual for mocking.
    +
    diff --git a/docs/df/dee/classshaka_1_1HttpFile-members.html b/docs/df/dee/classshaka_1_1HttpFile-members.html new file mode 100644 index 0000000000..ad016fcd03 --- /dev/null +++ b/docs/df/dee/classshaka_1_1HttpFile-members.html @@ -0,0 +1,111 @@ + + + + + + + +Shaka Packager SDK: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    shaka::HttpFile Member List
    +
    +
    + +

    This is the complete list of members for shaka::HttpFile, including all inherited members.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Close() overrideshaka::HttpFilevirtual
    CloseWithStatus() (defined in shaka::HttpFile)shaka::HttpFile
    Copy(const char *from_file_name, const char *to_file_name)shaka::Filestatic
    CopyFile(File *source, File *destination)shaka::Filestatic
    CopyFile(File *source, File *destination, int64_t max_copy)shaka::Filestatic
    Delete(const char *file_name)shaka::Filestatic
    File(const std::string &file_name) (defined in shaka::File)shaka::Fileinlineexplicitprotected
    file_name() constshaka::Fileinline
    Flush() overrideshaka::HttpFilevirtual
    GetFileSize(const char *file_name)shaka::Filestatic
    HttpFile(HttpMethod method, const std::string &url) (defined in shaka::HttpFile)shaka::HttpFile
    HttpFile(HttpMethod method, const std::string &url, const std::string &upload_content_type, const std::vector< std::string > &headers, uint32_t timeout_in_seconds) (defined in shaka::HttpFile)shaka::HttpFile
    HttpFile(const HttpFile &)=delete (defined in shaka::HttpFile)shaka::HttpFile
    IsLocalRegularFile(const char *file_name)shaka::Filestatic
    MakeCallbackFileName(const BufferCallbackParams &callback_params, const std::string &name)shaka::Filestatic
    Open() overrideshaka::HttpFilevirtual
    shaka::File::Open(const char *file_name, const char *mode)shaka::Filestatic
    OpenWithNoBuffering(const char *file_name, const char *mode)shaka::Filestatic
    operator=(const HttpFile &)=delete (defined in shaka::HttpFile)shaka::HttpFile
    ParseCallbackFileName(const std::string &callback_file_name, const BufferCallbackParams **callback_params, std::string *name)shaka::Filestatic
    Read(void *buffer, uint64_t length) overrideshaka::HttpFilevirtual
    ReadFileToString(const char *file_name, std::string *contents)shaka::Filestatic
    Seek(uint64_t position) overrideshaka::HttpFilevirtual
    Size() overrideshaka::HttpFilevirtual
    Tell(uint64_t *position) overrideshaka::HttpFilevirtual
    Write(const void *buffer, uint64_t length) overrideshaka::HttpFilevirtual
    WriteFileAtomically(const char *file_name, const std::string &contents)shaka::Filestatic
    WriteStringToFile(const char *file_name, const std::string &contents)shaka::Filestatic
    ~File()shaka::Fileinlineprotectedvirtual
    ~HttpFile() override (defined in shaka::HttpFile)shaka::HttpFileprotected
    + + + + diff --git a/docs/df/df1/structshaka_1_1ContentProtectionElement-members.html b/docs/df/df1/structshaka_1_1ContentProtectionElement-members.html index 93974a2854..9e5d68bab5 100644 --- a/docs/df/df1/structshaka_1_1ContentProtectionElement-members.html +++ b/docs/df/df1/structshaka_1_1ContentProtectionElement-members.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Member List @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/df/df8/subsample__generator_8h_source.html b/docs/df/df8/subsample__generator_8h_source.html index ce15f8345d..e52bb325ba 100644 --- a/docs/df/df8/subsample__generator_8h_source.html +++ b/docs/df/df8/subsample__generator_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto/subsample_generator.h Source File @@ -29,18 +29,21 @@ - + +/* @license-end */
    subsample_generator.h
    -
    1 // Copyright 2018 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_CRYPTO_SUBSAMPLE_GENERATOR_H_
    8 #define PACKAGER_MEDIA_CRYPTO_SUBSAMPLE_GENERATOR_H_
    9 
    10 #include <memory>
    11 #include <vector>
    12 
    13 #include "packager/media/base/fourccs.h"
    14 #include "packager/media/base/stream_info.h"
    15 #include "packager/status.h"
    16 
    17 namespace shaka {
    18 namespace media {
    19 
    20 class AV1Parser;
    21 class VideoSliceHeaderParser;
    22 class VPxParser;
    23 struct SubsampleEntry;
    24 
    35  public:
    38  explicit SubsampleGenerator(bool vp9_subsample_encryption);
    39 
    40  virtual ~SubsampleGenerator();
    41 
    48  virtual Status Initialize(FourCC protection_scheme,
    49  const StreamInfo& stream_info);
    50 
    59  virtual Status GenerateSubsamples(const uint8_t* frame,
    60  size_t frame_size,
    61  std::vector<SubsampleEntry>* subsamples);
    62 
    63  // Testing injections.
    64  void InjectVpxParserForTesting(std::unique_ptr<VPxParser> vpx_parser);
    65  void InjectVideoSliceHeaderParserForTesting(
    66  std::unique_ptr<VideoSliceHeaderParser> header_parser);
    67  void InjectAV1ParserForTesting(std::unique_ptr<AV1Parser> av1_parser);
    68 
    69  private:
    70  SubsampleGenerator(const SubsampleGenerator&) = delete;
    71  SubsampleGenerator& operator=(const SubsampleGenerator&) = delete;
    72 
    73  Status GenerateSubsamplesFromVPxFrame(
    74  const uint8_t* frame,
    75  size_t frame_size,
    76  std::vector<SubsampleEntry>* subsamples);
    77  Status GenerateSubsamplesFromH26xFrame(
    78  const uint8_t* frame,
    79  size_t frame_size,
    80  std::vector<SubsampleEntry>* subsamples);
    81  Status GenerateSubsamplesFromAV1Frame(
    82  const uint8_t* frame,
    83  size_t frame_size,
    84  std::vector<SubsampleEntry>* subsamples);
    85 
    86  const bool vp9_subsample_encryption_ = false;
    87  // Whether the protected portion should be AES block (16 bytes) aligned.
    88  bool align_protected_data_ = false;
    89  Codec codec_ = kUnknownCodec;
    90  // For NAL structured video only, the size of NAL unit length in bytes. Can be
    91  // 1, 2 or 4 bytes.
    92  uint8_t nalu_length_size_ = 0;
    93  // For SAMPLE AES only, 32 bytes for Video and 16 bytes for audio.
    94  size_t leading_clear_bytes_size_ = 0;
    95  // For SAMPLE AES only, if the data size is less than this value, none of the
    96  // bytes are encrypted. The size is 48+1 bytes for video NAL and 32 bytes for
    97  // audio according to MPEG-2 Stream Encryption Format for HTTP Live Streaming.
    98  size_t min_protected_data_size_ = 0;
    99 
    100  // VPx parser for VPx streams.
    101  std::unique_ptr<VPxParser> vpx_parser_;
    102  // Video slice header parser for NAL strucutred streams.
    103  std::unique_ptr<VideoSliceHeaderParser> header_parser_;
    104  // AV1 parser for AV1 streams.
    105  std::unique_ptr<AV1Parser> av1_parser_;
    106 };
    107 
    108 } // namespace media
    109 } // namespace shaka
    110 
    111 #endif // PACKAGER_MEDIA_CRYPTO_SUBSAMPLE_GENERATOR_H_
    Abstract class holds stream information.
    Definition: stream_info.h:62
    - -
    All the methods that are virtual are virtual for mocking.
    - -
    virtual Status GenerateSubsamples(const uint8_t *frame, size_t frame_size, std::vector< SubsampleEntry > *subsamples)
    -
    SubsampleGenerator(bool vp9_subsample_encryption)
    -
    virtual Status Initialize(FourCC protection_scheme, const StreamInfo &stream_info)
    +
    1 // Copyright 2018 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_CRYPTO_SUBSAMPLE_GENERATOR_H_
    +
    8 #define PACKAGER_MEDIA_CRYPTO_SUBSAMPLE_GENERATOR_H_
    +
    9 
    +
    10 #include <memory>
    +
    11 #include <vector>
    +
    12 
    +
    13 #include "packager/media/base/fourccs.h"
    +
    14 #include "packager/media/base/stream_info.h"
    +
    15 #include "packager/status.h"
    +
    16 
    +
    17 namespace shaka {
    +
    18 namespace media {
    +
    19 
    +
    20 class AV1Parser;
    +
    21 class VideoSliceHeaderParser;
    +
    22 class VPxParser;
    +
    23 struct SubsampleEntry;
    +
    24 
    + +
    35  public:
    +
    38  explicit SubsampleGenerator(bool vp9_subsample_encryption);
    +
    39 
    +
    40  virtual ~SubsampleGenerator();
    +
    41 
    +
    48  virtual Status Initialize(FourCC protection_scheme,
    +
    49  const StreamInfo& stream_info);
    +
    50 
    +
    59  virtual Status GenerateSubsamples(const uint8_t* frame,
    +
    60  size_t frame_size,
    +
    61  std::vector<SubsampleEntry>* subsamples);
    +
    62 
    +
    63  // Testing injections.
    +
    64  void InjectVpxParserForTesting(std::unique_ptr<VPxParser> vpx_parser);
    +
    65  void InjectVideoSliceHeaderParserForTesting(
    +
    66  std::unique_ptr<VideoSliceHeaderParser> header_parser);
    +
    67  void InjectAV1ParserForTesting(std::unique_ptr<AV1Parser> av1_parser);
    +
    68 
    +
    69  private:
    +
    70  SubsampleGenerator(const SubsampleGenerator&) = delete;
    +
    71  SubsampleGenerator& operator=(const SubsampleGenerator&) = delete;
    +
    72 
    +
    73  Status GenerateSubsamplesFromVPxFrame(
    +
    74  const uint8_t* frame,
    +
    75  size_t frame_size,
    +
    76  std::vector<SubsampleEntry>* subsamples);
    +
    77  Status GenerateSubsamplesFromH26xFrame(
    +
    78  const uint8_t* frame,
    +
    79  size_t frame_size,
    +
    80  std::vector<SubsampleEntry>* subsamples);
    +
    81  Status GenerateSubsamplesFromAV1Frame(
    +
    82  const uint8_t* frame,
    +
    83  size_t frame_size,
    +
    84  std::vector<SubsampleEntry>* subsamples);
    +
    85 
    +
    86  const bool vp9_subsample_encryption_ = false;
    +
    87  // Whether the protected portion should be AES block (16 bytes) aligned.
    +
    88  bool align_protected_data_ = false;
    +
    89  Codec codec_ = kUnknownCodec;
    +
    90  // For NAL structured video only, the size of NAL unit length in bytes. Can be
    +
    91  // 1, 2 or 4 bytes.
    +
    92  uint8_t nalu_length_size_ = 0;
    +
    93  // For SAMPLE AES only, 32 bytes for Video and 16 bytes for audio.
    +
    94  size_t leading_clear_bytes_size_ = 0;
    +
    95  // For SAMPLE AES only, if the data size is less than this value, none of the
    +
    96  // bytes are encrypted. The size is 48+1 bytes for video NAL and 32 bytes for
    +
    97  // audio according to MPEG-2 Stream Encryption Format for HTTP Live Streaming.
    +
    98  size_t min_protected_data_size_ = 0;
    +
    99 
    +
    100  // VPx parser for VPx streams.
    +
    101  std::unique_ptr<VPxParser> vpx_parser_;
    +
    102  // Video slice header parser for NAL strucutred streams.
    +
    103  std::unique_ptr<VideoSliceHeaderParser> header_parser_;
    +
    104  // AV1 parser for AV1 streams.
    +
    105  std::unique_ptr<AV1Parser> av1_parser_;
    +
    106 };
    +
    107 
    +
    108 } // namespace media
    +
    109 } // namespace shaka
    +
    110 
    +
    111 #endif // PACKAGER_MEDIA_CRYPTO_SUBSAMPLE_GENERATOR_H_
    + +
    Abstract class holds stream information.
    Definition: stream_info.h:65
    + +
    SubsampleGenerator(bool vp9_subsample_encryption)
    +
    virtual Status GenerateSubsamples(const uint8_t *frame, size_t frame_size, std::vector< SubsampleEntry > *subsamples)
    +
    virtual Status Initialize(FourCC protection_scheme, const StreamInfo &stream_info)
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/dfa/video__util_8h_source.html b/docs/df/dfa/video__util_8h_source.html index c87e7db81e..3153f4c112 100644 --- a/docs/df/dfa/video__util_8h_source.html +++ b/docs/df/dfa/video__util_8h_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base/video_util.h Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    video_util.h
    -
    1 // Copyright 2019 Google LLC. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 
    7 #ifndef PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
    8 #define PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
    9 
    10 #include <stdint.h>
    11 
    12 namespace shaka {
    13 namespace media {
    14 
    15 // Derive pixel aspect ratio from Display Aspect Ratio and Frame Aspect Ratio.
    16 void DerivePixelWidthHeight(uint32_t frame_width,
    17  uint32_t frame_height,
    18  uint32_t display_width,
    19  uint32_t display_height,
    20  uint32_t* pixel_width,
    21  uint32_t* pixel_height);
    22 
    23 } // namespace media
    24 } // namespace shaka
    25 
    26 #endif // PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
    All the methods that are virtual are virtual for mocking.
    +
    1 // Copyright 2019 Google LLC. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 
    +
    7 #ifndef PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
    +
    8 #define PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
    +
    9 
    +
    10 #include <stdint.h>
    +
    11 
    +
    12 namespace shaka {
    +
    13 namespace media {
    +
    14 
    +
    15 // Derive pixel aspect ratio from Display Aspect Ratio and Frame Aspect Ratio.
    +
    16 void DerivePixelWidthHeight(uint32_t frame_width,
    +
    17  uint32_t frame_height,
    +
    18  uint32_t display_width,
    +
    19  uint32_t display_height,
    +
    20  uint32_t* pixel_width,
    +
    21  uint32_t* pixel_height);
    +
    22 
    +
    23 } // namespace media
    +
    24 } // namespace shaka
    +
    25 
    +
    26 #endif // PACKAGER_MEDIA_BASE_VIDEO_UTIL_H_
    +
    All the methods that are virtual are virtual for mocking.
    diff --git a/docs/df/dfc/playready__key__encryption__flags_8cc_source.html b/docs/df/dfc/playready__key__encryption__flags_8cc_source.html index f5fc3a67ee..8c01f9c001 100644 --- a/docs/df/dfc/playready__key__encryption__flags_8cc_source.html +++ b/docs/df/dfc/playready__key__encryption__flags_8cc_source.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app/playready_key_encryption_flags.cc Source File @@ -29,18 +29,21 @@
    - + +/* @license-end */
    playready_key_encryption_flags.cc
    -
    1 // Copyright 2017 Google Inc. All rights reserved.
    2 //
    3 // Use of this source code is governed by a BSD-style
    4 // license that can be found in the LICENSE file or at
    5 // https://developers.google.com/open-source/licenses/bsd
    6 //
    7 // Defines command line flags for PlayReady encryption.
    8 
    9 #include "packager/app/playready_key_encryption_flags.h"
    10 
    11 #include "packager/app/validate_flag.h"
    12 
    13 DEFINE_bool(enable_playready_encryption,
    14  false,
    15  "Enable encryption with PlayReady key.");
    16 DEFINE_string(playready_server_url, "", "PlayReady packaging server url.");
    17 DEFINE_string(program_identifier, "",
    18  "Program identifier for packaging request.");
    19 DEFINE_string(ca_file, "",
    20  "Absolute path to the Certificate Authority file for the "
    21  "server cert. PEM format");
    22 DEFINE_string(client_cert_file, "",
    23  "Absolute path to client certificate file.");
    24 DEFINE_string(client_cert_private_key_file, "",
    25  "Absolute path to the Private Key file.");
    26 DEFINE_string(client_cert_private_key_password, "",
    27  "Password to the private key file.");
    28 
    29 namespace shaka {
    30 namespace {
    31 const bool kFlagIsOptional = true;
    32 }
    33 
    35  bool success = true;
    36 
    37  const char playready_label[] = "--enable_playready_encryption";
    38  bool playready_enabled = FLAGS_enable_playready_encryption;
    39  if (!ValidateFlag("playready_server_url", FLAGS_playready_server_url,
    40  playready_enabled, !kFlagIsOptional, playready_label)) {
    41  success = false;
    42  }
    43  if (!ValidateFlag("program_identifier", FLAGS_program_identifier,
    44  playready_enabled, !kFlagIsOptional, playready_label)) {
    45  success = false;
    46  }
    47  return success;
    48 }
    49 
    50 } // namespace shaka
    bool ValidateFlag(const char *flag_name, const FlagType &flag_value, bool condition, bool optional, const char *label)
    Definition: validate_flag.h:37
    -
    All the methods that are virtual are virtual for mocking.
    - +
    1 // Copyright 2017 Google Inc. All rights reserved.
    +
    2 //
    +
    3 // Use of this source code is governed by a BSD-style
    +
    4 // license that can be found in the LICENSE file or at
    +
    5 // https://developers.google.com/open-source/licenses/bsd
    +
    6 //
    +
    7 // Defines command line flags for PlayReady encryption.
    +
    8 
    +
    9 #include "packager/app/playready_key_encryption_flags.h"
    +
    10 
    +
    11 #include "packager/app/validate_flag.h"
    +
    12 
    +
    13 DEFINE_bool(enable_playready_encryption,
    +
    14  false,
    +
    15  "Enable encryption with PlayReady key.");
    +
    16 DEFINE_string(playready_server_url, "", "PlayReady packaging server url.");
    +
    17 DEFINE_string(program_identifier, "",
    +
    18  "Program identifier for packaging request.");
    +
    19 
    +
    20 namespace shaka {
    +
    21 namespace {
    +
    22 const bool kFlagIsOptional = true;
    +
    23 }
    +
    24 
    + +
    26  bool success = true;
    +
    27 
    +
    28  const char playready_label[] = "--enable_playready_encryption";
    +
    29  bool playready_enabled = FLAGS_enable_playready_encryption;
    +
    30  if (!ValidateFlag("playready_server_url", FLAGS_playready_server_url,
    +
    31  playready_enabled, !kFlagIsOptional, playready_label)) {
    +
    32  success = false;
    +
    33  }
    +
    34  if (!ValidateFlag("program_identifier", FLAGS_program_identifier,
    +
    35  playready_enabled, !kFlagIsOptional, playready_label)) {
    +
    36  success = false;
    +
    37  }
    +
    38  return success;
    +
    39 }
    +
    40 
    +
    41 } // namespace shaka
    +
    All the methods that are virtual are virtual for mocking.
    + +
    bool ValidateFlag(const char *flag_name, const FlagType &flag_value, bool condition, bool optional, const char *label)
    Definition: validate_flag.h:37
    diff --git a/docs/dir_121b61e6efa4d9009f3d31a3be5e474d.html b/docs/dir_121b61e6efa4d9009f3d31a3be5e474d.html new file mode 100644 index 0000000000..35af8d4bf7 --- /dev/null +++ b/docs/dir_121b61e6efa4d9009f3d31a3be5e474d.html @@ -0,0 +1,78 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/ttml Directory Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    ttml Directory Reference
    +
    +
    +
    + + + + diff --git a/docs/dir_1338cd99faf71b6cb1609e99e3340e45.html b/docs/dir_1338cd99faf71b6cb1609e99e3340e45.html index edba9fd19b..2f92ea46aa 100644 --- a/docs/dir_1338cd99faf71b6cb1609e99e3340e45.html +++ b/docs/dir_1338cd99faf71b6cb1609e99e3340e45.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/chunking Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_35c1fdffcdd4ade6d7f948073ab165de.html b/docs/dir_35c1fdffcdd4ade6d7f948073ab165de.html index 3ee08244ee..1b134e3917 100644 --- a/docs/dir_35c1fdffcdd4ade6d7f948073ab165de.html +++ b/docs/dir_35c1fdffcdd4ade6d7f948073ab165de.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp2t Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_375ba2cfd8fd5b05c50b92d996b9d386.html b/docs/dir_375ba2cfd8fd5b05c50b92d996b9d386.html index 1515bce9a4..fc48c18f87 100644 --- a/docs/dir_375ba2cfd8fd5b05c50b92d996b9d386.html +++ b/docs/dir_375ba2cfd8fd5b05c50b92d996b9d386.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_3f8eec2fc361645de4b1ec14c19fffc7.html b/docs/dir_3f8eec2fc361645de4b1ec14c19fffc7.html index 99ea030e42..ce3f37ea13 100644 --- a/docs/dir_3f8eec2fc361645de4b1ec14c19fffc7.html +++ b/docs/dir_3f8eec2fc361645de4b1ec14c19fffc7.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager Directory Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dir_48fdaa95ed78e499807eaa909d50b2cd.html b/docs/dir_48fdaa95ed78e499807eaa909d50b2cd.html index 8f93599733..251a8d6a27 100644 --- a/docs/dir_48fdaa95ed78e499807eaa909d50b2cd.html +++ b/docs/dir_48fdaa95ed78e499807eaa909d50b2cd.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/wvm Directory Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dir_51897ee7df8868b4f901d3ff10922ac3.html b/docs/dir_51897ee7df8868b4f901d3ff10922ac3.html index 3813885eba..d898dc14dd 100644 --- a/docs/dir_51897ee7df8868b4f901d3ff10922ac3.html +++ b/docs/dir_51897ee7df8868b4f901d3ff10922ac3.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/replicator Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_51a7c7233efd277e3898c7f3689e7b5b.html b/docs/dir_51a7c7233efd277e3898c7f3689e7b5b.html new file mode 100644 index 0000000000..d9f80fcc4d --- /dev/null +++ b/docs/dir_51a7c7233efd277e3898c7f3689e7b5b.html @@ -0,0 +1,78 @@ + + + + + + + +Shaka Packager SDK: packager/media/formats/dvb Directory Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    Shaka Packager SDK +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    dvb Directory Reference
    +
    +
    +
    + + + + diff --git a/docs/dir_588b87f799233a7c3afc1168633bb252.html b/docs/dir_588b87f799233a7c3afc1168633bb252.html index 343f343fdf..e02d52c37c 100644 --- a/docs/dir_588b87f799233a7c3afc1168633bb252.html +++ b/docs/dir_588b87f799233a7c3afc1168633bb252.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/public Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_64597db6ac7a9160e951a4226a03f10e.html b/docs/dir_64597db6ac7a9160e951a4226a03f10e.html index 09e8526c07..8f66d74520 100644 --- a/docs/dir_64597db6ac7a9160e951a4226a03f10e.html +++ b/docs/dir_64597db6ac7a9160e951a4226a03f10e.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/codecs Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_65bafb41b3669ba481c8da543a696a08.html b/docs/dir_65bafb41b3669ba481c8da543a696a08.html index f03bdff5fe..f335d5f08a 100644 --- a/docs/dir_65bafb41b3669ba481c8da543a696a08.html +++ b/docs/dir_65bafb41b3669ba481c8da543a696a08.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/base Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_6fe4b0529cd3ec97045d3314254a0cce.html b/docs/dir_6fe4b0529cd3ec97045d3314254a0cce.html index 3c057408e9..2ad23924fa 100644 --- a/docs/dir_6fe4b0529cd3ec97045d3314254a0cce.html +++ b/docs/dir_6fe4b0529cd3ec97045d3314254a0cce.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_7053349436b45d276056de3c928a6fc6.html b/docs/dir_7053349436b45d276056de3c928a6fc6.html index 3f1c151550..d51b3e9463 100644 --- a/docs/dir_7053349436b45d276056de3c928a6fc6.html +++ b/docs/dir_7053349436b45d276056de3c928a6fc6.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/origin Directory Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dir_7fa7c3de4a91b9652697b9f1c2d38e70.html b/docs/dir_7fa7c3de4a91b9652697b9f1c2d38e70.html index bab45e8f6e..034d0e512a 100644 --- a/docs/dir_7fa7c3de4a91b9652697b9f1c2d38e70.html +++ b/docs/dir_7fa7c3de4a91b9652697b9f1c2d38e70.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webvtt Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_83c56f445d5c796bd14e4ebf939c29ad.html b/docs/dir_83c56f445d5c796bd14e4ebf939c29ad.html index 0cd3f7112b..09b9fffd20 100644 --- a/docs/dir_83c56f445d5c796bd14e4ebf939c29ad.html +++ b/docs/dir_83c56f445d5c796bd14e4ebf939c29ad.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/base/xml Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_880f0837661bea0e588ff6a42c226fba.html b/docs/dir_880f0837661bea0e588ff6a42c226fba.html index 4f625137f5..759e7c2d0b 100644 --- a/docs/dir_880f0837661bea0e588ff6a42c226fba.html +++ b/docs/dir_880f0837661bea0e588ff6a42c226fba.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file/public Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_933242dc2ed3ec7a82c146e98110781e.html b/docs/dir_933242dc2ed3ec7a82c146e98110781e.html index 5c60e7aa7d..6dbc2d5b91 100644 --- a/docs/dir_933242dc2ed3ec7a82c146e98110781e.html +++ b/docs/dir_933242dc2ed3ec7a82c146e98110781e.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/public Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_aa847bee70cdde822696c7e33a504139.html b/docs/dir_aa847bee70cdde822696c7e33a504139.html index 2f9e713e6c..040efb30c8 100644 --- a/docs/dir_aa847bee70cdde822696c7e33a504139.html +++ b/docs/dir_aa847bee70cdde822696c7e33a504139.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/crypto Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_ae142483ff91a68c468a97c037f98d4d.html b/docs/dir_ae142483ff91a68c468a97c037f98d4d.html index c3a5bb7340..fa506db3d4 100644 --- a/docs/dir_ae142483ff91a68c468a97c037f98d4d.html +++ b/docs/dir_ae142483ff91a68c468a97c037f98d4d.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/mp4 Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_b23f8e22c8c095d1c8c0cb8f88104a00.html b/docs/dir_b23f8e22c8c095d1c8c0cb8f88104a00.html index 8567e54dcc..1507c5c32d 100644 --- a/docs/dir_b23f8e22c8c095d1c8c0cb8f88104a00.html +++ b/docs/dir_b23f8e22c8c095d1c8c0cb8f88104a00.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/webm Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_b7f276137d53b05d7f6b34219adc0a31.html b/docs/dir_b7f276137d53b05d7f6b34219adc0a31.html index 94b7b3b3a4..82d1a466a6 100644 --- a/docs/dir_b7f276137d53b05d7f6b34219adc0a31.html +++ b/docs/dir_b7f276137d53b05d7f6b34219adc0a31.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_b885194e7131202a9b4650a8967e838c.html b/docs/dir_b885194e7131202a9b4650a8967e838c.html index db189f4cef..005716b2b6 100644 --- a/docs/dir_b885194e7131202a9b4650a8967e838c.html +++ b/docs/dir_b885194e7131202a9b4650a8967e838c.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd Directory Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dir_b8a35a7f00287a46b0da66a108ec1239.html b/docs/dir_b8a35a7f00287a46b0da66a108ec1239.html index 1459960912..e6e29cd794 100644 --- a/docs/dir_b8a35a7f00287a46b0da66a108ec1239.html +++ b/docs/dir_b8a35a7f00287a46b0da66a108ec1239.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/demuxer Directory Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dir_bf7f1d16febc509cca62cff27fb88644.html b/docs/dir_bf7f1d16febc509cca62cff27fb88644.html index 30fd71a5a0..a455a94487 100644 --- a/docs/dir_bf7f1d16febc509cca62cff27fb88644.html +++ b/docs/dir_bf7f1d16febc509cca62cff27fb88644.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/app Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_c41da90e13af52a77978e497cf9cac63.html b/docs/dir_c41da90e13af52a77978e497cf9cac63.html index df6724e066..7e68f2fc45 100644 --- a/docs/dir_c41da90e13af52a77978e497cf9cac63.html +++ b/docs/dir_c41da90e13af52a77978e497cf9cac63.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/mpd/util Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_c727d19e3a8f99ea2539fb71bdb2ad10.html b/docs/dir_c727d19e3a8f99ea2539fb71bdb2ad10.html index 34653618f0..fd783636b0 100644 --- a/docs/dir_c727d19e3a8f99ea2539fb71bdb2ad10.html +++ b/docs/dir_c727d19e3a8f99ea2539fb71bdb2ad10.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/formats/packed_audio Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_d258fb6e36cbaad69b44b6c9489b2bbb.html b/docs/dir_d258fb6e36cbaad69b44b6c9489b2bbb.html index 987e37a7d5..28625d063f 100644 --- a/docs/dir_d258fb6e36cbaad69b44b6c9489b2bbb.html +++ b/docs/dir_d258fb6e36cbaad69b44b6c9489b2bbb.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/file Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_e329e4913ca1adf6e112c00fbb0d634f.html b/docs/dir_e329e4913ca1adf6e112c00fbb0d634f.html index ae0ce8cac2..bdb47f7494 100644 --- a/docs/dir_e329e4913ca1adf6e112c00fbb0d634f.html +++ b/docs/dir_e329e4913ca1adf6e112c00fbb0d634f.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/event Directory Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/dir_e3bda0bde998a4d5063328245b9909be.html b/docs/dir_e3bda0bde998a4d5063328245b9909be.html index 3bc6857c7c..2745952710 100644 --- a/docs/dir_e3bda0bde998a4d5063328245b9909be.html +++ b/docs/dir_e3bda0bde998a4d5063328245b9909be.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/base Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_f74090996960c752a82246b98a23aa62.html b/docs/dir_f74090996960c752a82246b98a23aa62.html index 651c4c955b..895fdaeed7 100644 --- a/docs/dir_f74090996960c752a82246b98a23aa62.html +++ b/docs/dir_f74090996960c752a82246b98a23aa62.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media/trick_play Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_f99dae54fe7170f791f339b952d5067a.html b/docs/dir_f99dae54fe7170f791f339b952d5067a.html index 46a23478ea..80fe11c940 100644 --- a/docs/dir_f99dae54fe7170f791f339b952d5067a.html +++ b/docs/dir_f99dae54fe7170f791f339b952d5067a.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/media Directory Reference @@ -29,18 +29,21 @@
    - + +/* @license-end */
    diff --git a/docs/dir_ffb529e2a1792bf603304ea6ff9bf092.html b/docs/dir_ffb529e2a1792bf603304ea6ff9bf092.html index f459207c8d..9cb82a55d5 100644 --- a/docs/dir_ffb529e2a1792bf603304ea6ff9bf092.html +++ b/docs/dir_ffb529e2a1792bf603304ea6ff9bf092.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: packager/hls/public Directory Reference @@ -29,18 +29,21 @@ - + +/* @license-end */
    diff --git a/docs/doxygen.css b/docs/doxygen.css index 4f1ab9195b..ffbff02249 100644 --- a/docs/doxygen.css +++ b/docs/doxygen.css @@ -1,4 +1,4 @@ -/* The standard CSS for doxygen 1.8.13 */ +/* The standard CSS for doxygen 1.9.1 */ body, table, div, p, dl { font: 400 14px/22px Roboto,sans-serif; @@ -53,17 +53,24 @@ dt { font-weight: bold; } -div.multicol { +ul.multicol { -moz-column-gap: 1em; -webkit-column-gap: 1em; + column-gap: 1em; -moz-column-count: 3; -webkit-column-count: 3; + column-count: 3; } p.startli, p.startdd { margin-top: 2px; } +th p.starttd, th p.intertd, th p.endtd { + font-size: 100%; + font-weight: 700; +} + p.starttd { margin-top: 0px; } @@ -80,6 +87,15 @@ p.endtd { margin-bottom: 2px; } +p.interli { +} + +p.interdd { +} + +p.intertd { +} + /* @end */ caption { @@ -87,30 +103,96 @@ caption { } span.legend { - font-size: 70%; - text-align: center; -} - -h3.version { - font-size: 90%; - text-align: center; -} - -div.qindex, div.navtab{ - background-color: #EBEFF6; - border: 1px solid #A3B4D7; + font-size: 70%; text-align: center; } -div.qindex, div.navpath { - width: 100%; - line-height: 140%; +h3.version { + font-size: 90%; + text-align: center; } div.navtab { - margin-right: 15px; + border-right: 1px solid #A3B4D7; + padding-right: 15px; + text-align: right; + line-height: 110%; } +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} +td.navtabHL { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} + +a.navtab { + font-weight: bold; +} + +div.qindex{ + text-align: center; + width: 100%; + line-height: 140%; + font-size: 130%; + color: #A0A0A0; +} + +dt.alphachar{ + font-size: 180%; + font-weight: bold; +} + +.alphachar a{ + color: black; +} + +.alphachar a:hover, .alphachar a:visited{ + text-decoration: none; +} + +.classindex dl { + padding: 25px; + column-count:1 +} + +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; +} + +.classindex dl.odd { + background-color: #F8F9FC; +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } +} + + /* @group Link Styling */ a { @@ -127,19 +209,8 @@ a:hover { text-decoration: underline; } -a.qindex { - font-weight: bold; -} - -a.qindexHL { - font-weight: bold; - background-color: #9CAFD4; - color: #ffffff; - border: 1px double #869DCA; -} - .contents a.qindexHL:visited { - color: #ffffff; + color: #FFFFFF; } a.el { @@ -163,6 +234,25 @@ dl.el { margin-left: -1cm; } +ul { + overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + pre.fragment { border: 1px solid #C4CFE5; background-color: #FBFCFD; @@ -177,8 +267,8 @@ pre.fragment { } div.fragment { - padding: 0px; - margin: 4px 8px 4px 2px; + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; background-color: #FBFCFD; border: 1px solid #C4CFE5; } @@ -248,7 +338,7 @@ span.lineno a:hover { div.ah, span.ah { background-color: black; font-weight: bold; - color: #ffffff; + color: #FFFFFF; margin-bottom: 3px; margin-top: 3px; padding: 0.2em; @@ -324,7 +414,7 @@ img.formulaDsp { } -img.formulaInl { +img.formulaInl, img.inline { vertical-align: middle; } @@ -402,6 +492,13 @@ blockquote { padding: 0 12px 0 16px; } +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #9CAFD4; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + /* @end */ /* @@ -498,7 +595,7 @@ table.memberdecls { white-space: nowrap; } -.memItemRight { +.memItemRight, .memTemplItemRight { width: 100%; } @@ -666,17 +763,17 @@ dl.reflist dd { padding-left: 0px; } -.params .paramname, .retval .paramname { +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { font-weight: bold; vertical-align: top; } -.params .paramtype { +.params .paramtype, .tparams .paramtype { font-style: italic; vertical-align: top; } -.params .paramdir { +.params .paramdir, .tparams .paramdir { font-family: "courier new",courier,monospace; vertical-align: top; } @@ -1081,72 +1178,143 @@ div.headertitle padding: 5px 5px 5px 10px; } -dl -{ - padding: 0 0 0 10px; +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; } -/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug */ -dl.section -{ +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { margin-left: 0px; padding-left: 0px; } -dl.note -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #D0C000; +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; } -dl.warning, dl.attention -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #FF0000; +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; } -dl.pre, dl.post, dl.invariant -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00D000; +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; } -dl.deprecated -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #505050; +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; } -dl.todo -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #00C0E0; +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; } -dl.test -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #3030E0; +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; } -dl.bug -{ - margin-left:-7px; - padding-left: 3px; - border-left:4px solid; - border-color: #C08050; +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; } dl.section dd { @@ -1245,10 +1413,12 @@ dl.citelist dt { font-weight:bold; margin-right:10px; padding:5px; + text-align:right; + width:52px; } dl.citelist dd { - margin:2px 0; + margin:2px 0 2px 72px; padding:5px 0; } @@ -1263,6 +1433,11 @@ div.toc { width: 200px; } +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + div.toc li { background: url("bdwn.png") no-repeat scroll 0 5px transparent; font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; @@ -1271,6 +1446,12 @@ div.toc li { padding-top: 2px; } +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + div.toc h3 { font: bold 12px/1.2 Arial,FreeSans,sans-serif; color: #4665A2; @@ -1300,6 +1481,32 @@ div.toc li.level4 { margin-left: 45px; } +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ +} + +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + .inherit_header { font-weight: bold; color: gray; @@ -1413,7 +1620,7 @@ tr.heading h2 { } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { - border-top-color: #ffffff; + border-top-color: #FFFFFF; border-width: 10px; margin: 0px -10px; } @@ -1441,7 +1648,7 @@ tr.heading h2 { } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { - border-bottom-color: #ffffff; + border-bottom-color: #FFFFFF; border-width: 10px; margin: 0px -10px; } @@ -1468,7 +1675,7 @@ tr.heading h2 { left: 100%; } #powerTip.e:after { - border-left-color: #ffffff; + border-left-color: #FFFFFF; border-width: 10px; top: 50%; margin-top: -10px; @@ -1484,7 +1691,7 @@ tr.heading h2 { right: 100%; } #powerTip.w:after { - border-right-color: #ffffff; + border-right-color: #FFFFFF; border-width: 10px; top: 50%; margin-top: -10px; @@ -1517,47 +1724,6 @@ tr.heading h2 { /* @group Markdown */ -/* -table.markdownTable { - border-collapse:collapse; - margin-top: 4px; - margin-bottom: 4px; -} - -table.markdownTable td, table.markdownTable th { - border: 1px solid #2D4068; - padding: 3px 7px 2px; -} - -table.markdownTableHead tr { -} - -table.markdownTableBodyLeft td, table.markdownTable th { - border: 1px solid #2D4068; - padding: 3px 7px 2px; -} - -th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { - background-color: #374F7F; - color: #FFFFFF; - font-size: 110%; - padding-bottom: 4px; - padding-top: 5px; -} - -th.markdownTableHeadLeft { - text-align: left -} - -th.markdownTableHeadRight { - text-align: right -} - -th.markdownTableHeadCenter { - text-align: center -} -*/ - table.markdownTable { border-collapse:collapse; margin-top: 4px; @@ -1592,5 +1758,36 @@ th.markdownTableHeadCenter, td.markdownTableBodyCenter { text-align: center } +.DocNodeRTL { + text-align: right; + direction: rtl; +} +.DocNodeLTR { + text-align: left; + direction: ltr; +} + +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; +} + +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; +} + +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; +} /* @end */ + +u { + text-decoration: underline; +} + diff --git a/docs/doxygen.png b/docs/doxygen.png deleted file mode 100644 index 3ff17d807fd8aa003bed8bb2a69e8f0909592fd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3779 zcmV;!4m|ORP)tMIv#Q0*~7*`IBSO7_x;@a8#Zk6_PeKR_s92J&)(m+);m9Iz3blw)z#Gi zP!9lj4$%+*>Hz@HCmM9L9|8c+0u=!H$O3?R0Kgx|#WP<6fKfC8fM-CQZT|_r@`>VO zX^Hgb|9cJqpdJA5$MCEK`F_2@2Y@s>^+;pF`~jdI0Pvr|vl4`=C)EH@1IFe7pdJ8F zH(qGi004~QnF)Ggga~8v08kGAs2hKTATxr7pwfNk|4#_AaT>w8P6TV+R2kbS$v==} zAjf`s0g#V8lB+b3)5oEI*q+{Yt$MZDruD2^;$+(_%Qn+%v0X-bJO=;@kiJ^ygLBnC z?1OVv_%aex1M@jKU|Z~$eI?PoF4Vj>fDzyo zAiLfpXY*a^Sj-S5D0S3@#V$sRW)g)_1e#$%8xdM>Jm7?!h zu0P2X=xoN>^!4DoPRgph2(2va07yfpXF+WH7EOg1GY%Zn z7~1A<(z7Q$ktEXhW_?GMpHp9l_UL18F3KOsxu81pqoBiNbFSGsof-W z6~eloMoz=4?OOnl2J268x5rOY`dCk0us(uS#Ud4yqOr@?=Q57a}tit|BhY>}~frH1sP`ScHS_d)oqH^lYy zZ%VP`#10MlE~P?cE(%(#(AUSv_T{+;t@$U}El}(1ig`vZo`Rm;+5&(AYzJ^Ae=h2X z@Re%vHwZU>|f0NI&%$*4eJweC5OROQrpPMA@*w|o z()A==l}(@bv^&>H1Ob3C=<^|hob?0+xJ?QQ3-ueQC}zy&JQNib!OqSO@-=>XzxlSF zAZ^U*1l6EEmg3r};_HY>&Jo_{dOPEFTWPmt=U&F#+0(O59^UIlHbNX+eF8UzyDR*T z(=5X$VF3!gm@RooS-&iiUYGG^`hMR(07zr_xP`d!^BH?uD>Phl8Rdifx3Af^Zr`Ku ztL+~HkVeL#bJ)7;`=>;{KNRvjmc}1}c58Sr#Treq=4{xo!ATy|c>iRSp4`dzMMVd@ zL8?uwXDY}Wqgh4mH`|$BTXpUIu6A1-cSq%hJw;@^Zr8TP=GMh*p(m(tN7@!^D~sl$ zz^tf4II4|};+irE$Fnm4NTc5%p{PRA`%}Zk`CE5?#h3|xcyQsS#iONZ z6H(@^i9td!$z~bZiJLTax$o>r(p}3o@< zyD7%(>ZYvy=6$U3e!F{Z`uSaYy`xQyl?b{}eg|G3&fz*`QH@mDUn)1%#5u`0m$%D} z?;tZ0u(mWeMV0QtzjgN!lT*pNRj;6510Wwx?Yi_=tYw|J#7@(Xe7ifDzXuK;JB;QO z#bg~K$cgm$@{QiL_3yr}y&~wuv=P=#O&Tj=Sr)aCUlYmZMcw?)T?c%0rUe1cS+o!qs_ zQ6Gp)-{)V!;=q}llyK3|^WeLKyjf%y;xHku;9(vM!j|~<7w1c*Mk-;P{T&yG) z@C-8E?QPynNQ<8f01D`2qexcVEIOU?y}MG)TAE6&VT5`rK8s(4PE;uQ92LTXUQ<>^ ztyQ@=@kRdh@ebUG^Z6NWWIL;_IGJ2ST>$t!$m$qvtj0Qmw8moN6GUV^!QKNK zHBXCtUH8)RY9++gH_TUV4^=-j$t}dD3qsN7GclJ^Zc&(j6&a_!$jCf}%c5ey`pm~1)@{yI3 zTdWyB+*X{JFw#z;PwRr5evb2!ueWF;v`B0HoUu4-(~aL=z;OXUUEtG`_$)Oxw6FKg zEzY`CyKaSBK3xt#8gA|r_|Kehn_HYVBMpEwbn9-fI*!u*eTA1ef8Mkl1=!jV4oYwWYM}i`A>_F4nhmlCIC6WLa zY%;4&@AlnaG11ejl61Jev21|r*m+?Kru3;1tFDl}#!OzUp6c>go4{C|^erwpG*&h6bspUPJag}oOkN2912Y3I?(eRc@U9>z#HPBHC?nps7H5!zP``90!Q1n80jo+B3TWXp!8Pe zwuKuLLI6l3Gv@+QH*Y}2wPLPQ1^EZhT#+Ed8q8Wo z1pTmIBxv14-{l&QVKxAyQF#8Q@NeJwWdKk>?cpiJLkJr+aZ!Me+Cfp!?FWSRf^j2k z73BRR{WSKaMkJ>1Nbx5dan5hg^_}O{Tj6u%iV%#QGz0Q@j{R^Ik)Z*+(YvY2ziBG)?AmJa|JV%4UT$k`hcOg5r9R?5>?o~JzK zJCrj&{i#hG>N7!B4kNX(%igb%kDj0fOQThC-8mtfap82PNRXr1D>lbgg)dYTQ(kbx z`Ee5kXG~Bh+BHQBf|kJEy6(ga%WfhvdQNDuOfQoe377l#ht&DrMGeIsI5C<&ai zWG$|hop2@@q5YDa)_-A?B02W;#fH!%k`daQLEItaJJ8Yf1L%8x;kg?)k)00P-lH+w z)5$QNV6r2$YtnV(4o=0^3{kmaXn*Dm0F*fU(@o)yVVjk|ln8ea6BMy%vZAhW9|wvA z8RoDkVoMEz1d>|5(k0Nw>22ZT){V<3$^C-cN+|~hKt2)){+l-?3m@-$c?-dlzQ)q- zZ)j%n^gerV{|+t}9m1_&&Ly!9$rtG4XX|WQ8`xYzGC~U@nYh~g(z9)bdAl#xH)xd5a=@|qql z|FzEil{P5(@gy!4ek05i$>`E^G~{;pnf6ftpLh$h#W?^#4UkPfa;;?bsIe&kz!+40 zI|6`F2n020)-r`pFaZ38F!S-lJM-o&inOw|66=GMeP@xQU5ghQH{~5Uh~TMTd;I9` z>YhVB`e^EVj*S7JF39ZgNf}A-0DwOcTT63ydN$I3b?yBQtUI*_fae~kPvzoD$zjX3 zoqBe#>12im4WzZ=f^4+u=!lA|#r%1`WB0-6*3BL#at`47#ebPpR|D1b)3BjT34nYY z%Ds%d?5$|{LgOIaRO{{oC&RK`O91$fqwM0(C_TALcozu*fWHb%%q&p-q{_8*2Zsi^ zh1ZCnr^UYa;4vQEtHk{~zi>wwMC5o{S=$P0X681y`SXwFH?Ewn{x-MOZynmc)JT5v zuHLwh;tLfxRrr%|k370}GofLl7thg>ACWWY&msqaVu&ry+`7+Ss>NL^%T1|z{IGMA zW-SKl=V-^{(f!Kf^#3(|T2W47d(%JVCI4JgRrT1pNz>+ietmFToNv^`gzC@&O-)+i zPQ~RwK8%C_vf%;%e>NyTp~dM5;!C|N0Q^6|CEb7Bw=Vz~$1#FA;Z*?mKSC)Hl-20s t8QyHj(g6VK0RYbl8UjE)0O0w=e*@m04r>stuEhWV002ovPDHLkV1hl;dM*F} diff --git a/docs/doxygen.svg b/docs/doxygen.svg new file mode 100644 index 0000000000..d42dad52d5 --- /dev/null +++ b/docs/doxygen.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dynsections.js b/docs/dynsections.js index 1e6bf07f9f..88f2c27e6d 100644 --- a/docs/dynsections.js +++ b/docs/dynsections.js @@ -1,3 +1,27 @@ +/* + @licstart The following is the entire license notice for the JavaScript code in this file. + + The MIT License (MIT) + + Copyright (C) 1997-2020 by Dimitri van Heesch + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software + and associated documentation files (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or + substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + @licend The above is the entire license notice for the JavaScript code in this file + */ function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); @@ -15,7 +39,7 @@ function toggleVisibility(linkObj) summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); - } + } return false; } @@ -94,11 +118,11 @@ function toggleInherit(id) $(img).attr('src',src.substring(0,src.length-10)+'open.png'); } } - +/* @license-end */ $(document).ready(function() { $('.code,.codeRef').each(function() { - $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html()); + $(this).data('powertip',$('#a'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html()); $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true }); }); }); diff --git a/docs/files.html b/docs/files.html index af85b180ba..e5665948f8 100644 --- a/docs/files.html +++ b/docs/files.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: File List @@ -29,18 +29,21 @@
    - + +/* @license-end */ @@ -99,14 +102,16 @@ $(function() {  raw_key_encryption_flags.h  retired_flags.cc  retired_flags.h - stream_descriptor.cc - stream_descriptor.h - validate_flag.cc - validate_flag.h - vlog_flags.cc - vlog_flags.h - widevine_encryption_flags.cc - widevine_encryption_flags.h + single_thread_job_manager.cc + single_thread_job_manager.h + stream_descriptor.cc + stream_descriptor.h + validate_flag.cc + validate_flag.h + vlog_flags.cc + vlog_flags.h + widevine_encryption_flags.cc + widevine_encryption_flags.h   file   public  buffer_callback_params.h @@ -118,18 +123,20 @@ $(function() {  file_test_util.h  file_util.cc  file_util.h - io_cache.cc - io_cache.h - local_file.cc - local_file.h - memory_file.cc - memory_file.h - threaded_io_file.cc - threaded_io_file.h - udp_file.cc - udp_file.h - udp_options.cc - udp_options.h + http_file.cc + http_file.h + io_cache.cc + io_cache.h + local_file.cc + local_file.h + memory_file.cc + memory_file.h + threaded_io_file.cc + threaded_io_file.h + udp_file.cc + udp_file.h + udp_options.cc + udp_options.h   hls   base  hls_notifier.h @@ -169,88 +176,92 @@ $(function() {  buffer_writer.h  byte_queue.cc  byte_queue.h - closure_thread.cc - closure_thread.h - common_pssh_generator.cc - common_pssh_generator.h - container_names.cc - container_names.h - decrypt_config.cc - decrypt_config.h - decryptor_source.cc - decryptor_source.h - encryption_config.h - fourccs.h - http_key_fetcher.cc - http_key_fetcher.h - id3_tag.cc - id3_tag.h - key_fetcher.cc - key_fetcher.h - key_source.cc - key_source.h - language_utils.cc - language_utils.h - limits.h - macros.h - media_handler.cc - media_handler.h - media_handler_test_base.cc - media_handler_test_base.h - media_parser.h - media_sample.cc - media_sample.h - mock_aes_cryptor.h - muxer.cc - muxer.h - muxer_options.cc - muxer_options.h - muxer_util.cc - muxer_util.h - network_util.cc - network_util.h - offset_byte_queue.cc - offset_byte_queue.h - playready_key_source.cc - playready_key_source.h - playready_pssh_generator.cc - playready_pssh_generator.h - producer_consumer_queue.h - protection_system_ids.h - protection_system_specific_info.cc - protection_system_specific_info.h - proto_json_util.cc - proto_json_util.h - pssh_generator.cc - pssh_generator.h - pssh_generator_util.cc - pssh_generator_util.h - range.h - raw_key_source.cc - raw_key_source.h - rcheck.h - request_signer.cc - request_signer.h - rsa_key.cc - rsa_key.h - stream_info.cc - stream_info.h - text_sample.cc - text_sample.h - text_stream_info.cc - text_stream_info.h - text_track.h - text_track_config.cc - text_track_config.h - timestamp.h - video_stream_info.cc - video_stream_info.h - video_util.cc - video_util.h - widevine_key_source.cc - widevine_key_source.h - widevine_pssh_generator.cc - widevine_pssh_generator.h + cc_stream_filter.cc + cc_stream_filter.h + closure_thread.cc + closure_thread.h + common_pssh_generator.cc + common_pssh_generator.h + container_names.cc + container_names.h + decrypt_config.cc + decrypt_config.h + decryptor_source.cc + decryptor_source.h + encryption_config.h + fourccs.h + http_key_fetcher.cc + http_key_fetcher.h + id3_tag.cc + id3_tag.h + key_fetcher.cc + key_fetcher.h + key_source.cc + key_source.h + language_utils.cc + language_utils.h + limits.h + macros.h + media_handler.cc + media_handler.h + media_handler_test_base.cc + media_handler_test_base.h + media_parser.h + media_sample.cc + media_sample.h + mock_aes_cryptor.h + muxer.cc + muxer.h + muxer_options.cc + muxer_options.h + muxer_util.cc + muxer_util.h + network_util.cc + network_util.h + offset_byte_queue.cc + offset_byte_queue.h + playready_key_source.cc + playready_key_source.h + playready_pssh_generator.cc + playready_pssh_generator.h + producer_consumer_queue.h + protection_system_ids.h + protection_system_specific_info.cc + protection_system_specific_info.h + proto_json_util.cc + proto_json_util.h + pssh_generator.cc + pssh_generator.h + pssh_generator_util.cc + pssh_generator_util.h + range.h + raw_key_source.cc + raw_key_source.h + rcheck.h + request_signer.cc + request_signer.h + rsa_key.cc + rsa_key.h + stream_info.cc + stream_info.h + text_muxer.cc + text_muxer.h + text_sample.cc + text_sample.h + text_stream_info.cc + text_stream_info.h + text_track.h + text_track_config.cc + text_track_config.h + timestamp.h + video_stream_info.cc + video_stream_info.h + video_util.cc + video_util.h + widevine_key_source.cc + widevine_key_source.h + widevine_pssh_generator.cc + widevine_pssh_generator.h   chunking  chunking_handler.cc  chunking_handler.h @@ -265,50 +276,52 @@ $(function() {  aac_audio_specific_config.h  ac3_audio_util.cc  ac3_audio_util.h - av1_codec_configuration_record.cc - av1_codec_configuration_record.h - av1_parser.cc - av1_parser.h - avc_decoder_configuration_record.cc - avc_decoder_configuration_record.h - decoder_configuration_record.cc - decoder_configuration_record.h - dovi_decoder_configuration_record.cc - dovi_decoder_configuration_record.h - ec3_audio_util.cc - ec3_audio_util.h - es_descriptor.cc - es_descriptor.h - h264_byte_to_unit_stream_converter.cc - h264_byte_to_unit_stream_converter.h - h264_parser.cc - h264_parser.h - h265_byte_to_unit_stream_converter.cc - h265_byte_to_unit_stream_converter.h - h265_parser.cc - h265_parser.h - h26x_bit_reader.cc - h26x_bit_reader.h - h26x_byte_to_unit_stream_converter.cc - h26x_byte_to_unit_stream_converter.h - hevc_decoder_configuration_record.cc - hevc_decoder_configuration_record.h - hls_audio_util.cc - hls_audio_util.h - nal_unit_to_byte_stream_converter.cc - nal_unit_to_byte_stream_converter.h - nalu_reader.cc - nalu_reader.h - video_slice_header_parser.cc - video_slice_header_parser.h - vp8_parser.cc - vp8_parser.h - vp9_parser.cc - vp9_parser.h - vp_codec_configuration_record.cc - vp_codec_configuration_record.h - vpx_parser.h - webvtt_util.h + ac4_audio_util.cc + ac4_audio_util.h + av1_codec_configuration_record.cc + av1_codec_configuration_record.h + av1_parser.cc + av1_parser.h + avc_decoder_configuration_record.cc + avc_decoder_configuration_record.h + decoder_configuration_record.cc + decoder_configuration_record.h + dovi_decoder_configuration_record.cc + dovi_decoder_configuration_record.h + ec3_audio_util.cc + ec3_audio_util.h + es_descriptor.cc + es_descriptor.h + h264_byte_to_unit_stream_converter.cc + h264_byte_to_unit_stream_converter.h + h264_parser.cc + h264_parser.h + h265_byte_to_unit_stream_converter.cc + h265_byte_to_unit_stream_converter.h + h265_parser.cc + h265_parser.h + h26x_bit_reader.cc + h26x_bit_reader.h + h26x_byte_to_unit_stream_converter.cc + h26x_byte_to_unit_stream_converter.h + hevc_decoder_configuration_record.cc + hevc_decoder_configuration_record.h + hls_audio_util.cc + hls_audio_util.h + nal_unit_to_byte_stream_converter.cc + nal_unit_to_byte_stream_converter.h + nalu_reader.cc + nalu_reader.h + video_slice_header_parser.cc + video_slice_header_parser.h + vp8_parser.cc + vp8_parser.h + vp9_parser.cc + vp9_parser.h + vp_codec_configuration_record.cc + vp_codec_configuration_record.h + vpx_parser.h + webvtt_util.h   crypto  aes_encryptor_factory.cc  aes_encryptor_factory.h @@ -331,165 +344,185 @@ $(function() {  mock_muxer_listener.h  mpd_notify_muxer_listener.cc  mpd_notify_muxer_listener.h - muxer_listener.h - muxer_listener_factory.cc - muxer_listener_factory.h - muxer_listener_internal.cc - muxer_listener_internal.h - muxer_listener_test_helper.cc - muxer_listener_test_helper.h - progress_listener.h - vod_media_info_dump_muxer_listener.cc - vod_media_info_dump_muxer_listener.h + multi_codec_muxer_listener.cc + multi_codec_muxer_listener.h + muxer_listener.h + muxer_listener_factory.cc + muxer_listener_factory.h + muxer_listener_internal.cc + muxer_listener_internal.h + muxer_listener_test_helper.cc + muxer_listener_test_helper.h + progress_listener.h + vod_media_info_dump_muxer_listener.cc + vod_media_info_dump_muxer_listener.h   formats -  mp2t - ac3_header.cc - ac3_header.h - adts_header.cc - adts_header.h - audio_header.h - continuity_counter.cc - continuity_counter.h - es_parser.h - es_parser_audio.cc - es_parser_audio.h - es_parser_h264.cc - es_parser_h264.h - es_parser_h265.cc - es_parser_h265.h - es_parser_h26x.cc - es_parser_h26x.h - mp2t_common.h - mp2t_media_parser.cc - mp2t_media_parser.h - pes_packet.cc - pes_packet.h - pes_packet_generator.cc - pes_packet_generator.h - program_map_table_writer.cc - program_map_table_writer.h - ts_muxer.cc - ts_muxer.h - ts_packet.cc - ts_packet.h - ts_packet_writer_util.cc - ts_packet_writer_util.h - ts_section.h - ts_section_pat.cc - ts_section_pat.h - ts_section_pes.cc - ts_section_pes.h - ts_section_pmt.cc - ts_section_pmt.h - ts_section_psi.cc - ts_section_psi.h - ts_segmenter.cc - ts_segmenter.h - ts_stream_type.h - ts_writer.cc - ts_writer.h -  mp4 - box.cc - box.h - box_buffer.h - box_definitions.cc - box_definitions.h - box_definitions_comparison.h - box_reader.cc - box_reader.h - chunk_info_iterator.cc - chunk_info_iterator.h - composition_offset_iterator.cc - composition_offset_iterator.h - decoding_time_iterator.cc - decoding_time_iterator.h - fragmenter.cc - fragmenter.h - key_frame_info.h - mp4_media_parser.cc - mp4_media_parser.h - mp4_muxer.cc - mp4_muxer.h - multi_segment_segmenter.cc - multi_segment_segmenter.h - segmenter.cc - segmenter.h - single_segment_segmenter.cc - single_segment_segmenter.h - sync_sample_iterator.cc - sync_sample_iterator.h - track_run_iterator.cc - track_run_iterator.h -  packed_audio - packed_audio_segmenter.cc - packed_audio_segmenter.h - packed_audio_writer.cc - packed_audio_writer.h -  webm - cluster_builder.cc - cluster_builder.h - encryptor.cc - encryptor.h - mkv_writer.cc - mkv_writer.h - multi_segment_segmenter.cc - multi_segment_segmenter.h - seek_head.cc - seek_head.h - segmenter.cc - segmenter.h - segmenter_test_base.cc - segmenter_test_base.h - single_segment_segmenter.cc - single_segment_segmenter.h - tracks_builder.cc - tracks_builder.h - two_pass_single_segment_segmenter.cc - two_pass_single_segment_segmenter.h - webm_audio_client.cc - webm_audio_client.h - webm_cluster_parser.cc - webm_cluster_parser.h - webm_constants.cc - webm_constants.h - webm_content_encodings.cc - webm_content_encodings.h - webm_content_encodings_client.cc - webm_content_encodings_client.h - webm_crypto_helpers.cc - webm_crypto_helpers.h - webm_info_parser.cc - webm_info_parser.h - webm_media_parser.cc - webm_media_parser.h - webm_muxer.cc - webm_muxer.h - webm_parser.cc - webm_parser.h - webm_tracks_parser.cc - webm_tracks_parser.h - webm_video_client.cc - webm_video_client.h - webm_webvtt_parser.cc - webm_webvtt_parser.h -  webvtt - text_padder.cc - text_padder.h - text_readers.cc - text_readers.h - webvtt_file_buffer.cc - webvtt_file_buffer.h - webvtt_parser.cc - webvtt_parser.h - webvtt_text_output_handler.cc - webvtt_text_output_handler.h - webvtt_timestamp.cc - webvtt_timestamp.h - webvtt_to_mp4_handler.cc - webvtt_to_mp4_handler.h -  wvm - wvm_media_parser.cc - wvm_media_parser.h +  dvb + dvb_image.cc + dvb_image.h + dvb_sub_parser.cc + dvb_sub_parser.h + subtitle_composer.cc + subtitle_composer.h +  mp2t + ac3_header.cc + ac3_header.h + adts_header.cc + adts_header.h + audio_header.h + continuity_counter.cc + continuity_counter.h + es_parser.h + es_parser_audio.cc + es_parser_audio.h + es_parser_dvb.cc + es_parser_dvb.h + es_parser_h264.cc + es_parser_h264.h + es_parser_h265.cc + es_parser_h265.h + es_parser_h26x.cc + es_parser_h26x.h + mp2t_common.h + mp2t_media_parser.cc + mp2t_media_parser.h + mpeg1_header.cc + mpeg1_header.h + pes_packet.cc + pes_packet.h + pes_packet_generator.cc + pes_packet_generator.h + program_map_table_writer.cc + program_map_table_writer.h + ts_muxer.cc + ts_muxer.h + ts_packet.cc + ts_packet.h + ts_packet_writer_util.cc + ts_packet_writer_util.h + ts_section.h + ts_section_pat.cc + ts_section_pat.h + ts_section_pes.cc + ts_section_pes.h + ts_section_pmt.cc + ts_section_pmt.h + ts_section_psi.cc + ts_section_psi.h + ts_segmenter.cc + ts_segmenter.h + ts_stream_type.h + ts_writer.cc + ts_writer.h +  mp4 + box.cc + box.h + box_buffer.h + box_definitions.cc + box_definitions.h + box_definitions_comparison.h + box_reader.cc + box_reader.h + chunk_info_iterator.cc + chunk_info_iterator.h + composition_offset_iterator.cc + composition_offset_iterator.h + decoding_time_iterator.cc + decoding_time_iterator.h + fragmenter.cc + fragmenter.h + key_frame_info.h + mp4_media_parser.cc + mp4_media_parser.h + mp4_muxer.cc + mp4_muxer.h + multi_segment_segmenter.cc + multi_segment_segmenter.h + segmenter.cc + segmenter.h + single_segment_segmenter.cc + single_segment_segmenter.h + sync_sample_iterator.cc + sync_sample_iterator.h + track_run_iterator.cc + track_run_iterator.h +  packed_audio + packed_audio_segmenter.cc + packed_audio_segmenter.h + packed_audio_writer.cc + packed_audio_writer.h +  ttml + ttml_generator.cc + ttml_generator.h + ttml_muxer.cc + ttml_muxer.h + ttml_to_mp4_handler.cc + ttml_to_mp4_handler.h +  webm + cluster_builder.cc + cluster_builder.h + encryptor.cc + encryptor.h + mkv_writer.cc + mkv_writer.h + multi_segment_segmenter.cc + multi_segment_segmenter.h + seek_head.cc + seek_head.h + segmenter.cc + segmenter.h + segmenter_test_base.cc + segmenter_test_base.h + single_segment_segmenter.cc + single_segment_segmenter.h + tracks_builder.cc + tracks_builder.h + two_pass_single_segment_segmenter.cc + two_pass_single_segment_segmenter.h + webm_audio_client.cc + webm_audio_client.h + webm_cluster_parser.cc + webm_cluster_parser.h + webm_constants.cc + webm_constants.h + webm_content_encodings.cc + webm_content_encodings.h + webm_content_encodings_client.cc + webm_content_encodings_client.h + webm_crypto_helpers.cc + webm_crypto_helpers.h + webm_info_parser.cc + webm_info_parser.h + webm_media_parser.cc + webm_media_parser.h + webm_muxer.cc + webm_muxer.h + webm_parser.cc + webm_parser.h + webm_tracks_parser.cc + webm_tracks_parser.h + webm_video_client.cc + webm_video_client.h + webm_webvtt_parser.cc + webm_webvtt_parser.h +  webvtt + text_padder.cc + text_padder.h + text_readers.cc + text_readers.h + webvtt_file_buffer.cc + webvtt_file_buffer.h + webvtt_muxer.cc + webvtt_muxer.h + webvtt_parser.cc + webvtt_parser.h + webvtt_to_mp4_handler.cc + webvtt_to_mp4_handler.h + webvtt_utils.cc + webvtt_utils.h +  wvm + wvm_media_parser.cc + wvm_media_parser.h   origin  origin_handler.cc  origin_handler.h @@ -551,9 +584,7 @@ $(function() { diff --git a/docs/functions.html b/docs/functions.html index e7faf65cc3..6f71a892fa 100644 --- a/docs/functions.html +++ b/docs/functions.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -71,13 +74,13 @@ $(function() { : shaka::AdaptationSet
  • AddAccessibilityElement() -: shaka::xml::AdaptationSetXmlNode +: shaka::xml::AdaptationSetXmlNode
  • AddAdaptationSetSwitching() : shaka::AdaptationSet
  • AddAudioInfo() -: shaka::xml::RepresentationXmlNode +: shaka::xml::RepresentationXmlNode
  • AddBaseUrl() : shaka::MpdBuilder @@ -86,23 +89,26 @@ $(function() { : shaka::BandwidthEstimator
  • AddChild() -: shaka::xml::XmlNode +: shaka::xml::XmlNode +
  • +
  • AddContent() +: shaka::xml::XmlNode
  • AddContentProtectionElement() : shaka::AdaptationSet , shaka::Representation
  • AddDescriptor() -: shaka::xml::RepresentationBaseXmlNode +: shaka::xml::RepresentationBaseXmlNode
  • AddElements() -: shaka::xml::XmlNode +: shaka::xml::XmlNode
  • AddEncryptionInfo() : shaka::hls::MediaPlaylist
  • AddEssentialProperty() -: shaka::xml::RepresentationBaseXmlNode +: shaka::xml::RepresentationBaseXmlNode
  • AddFloat() : shaka::hls::Tag @@ -114,7 +120,7 @@ $(function() { : shaka::hls::MediaPlaylist
  • AddLiveOnlyInfo() -: shaka::xml::RepresentationXmlNode +: shaka::xml::RepresentationXmlNode
  • AddNalu() : shaka::media::DecoderConfigurationRecord @@ -129,7 +135,7 @@ $(function() { : shaka::hls::Tag
  • AddPesPacket() -: shaka::media::mp2t::TsWriter +: shaka::media::mp2t::TsWriter
  • AddPlacementOpportunity() : shaka::hls::MediaPlaylist @@ -150,7 +156,7 @@ $(function() { : shaka::AdaptationSet
  • AddRoleElement() -: shaka::xml::AdaptationSetXmlNode +: shaka::xml::AdaptationSetXmlNode
  • AddSample() : shaka::media::mp2t::TsSegmenter @@ -169,7 +175,7 @@ $(function() { : shaka::media::DecryptConfig
  • AddSupplementalProperty() -: shaka::xml::RepresentationBaseXmlNode +: shaka::xml::RepresentationBaseXmlNode
  • AddThread() : shaka::media::SyncPointQueue @@ -178,10 +184,10 @@ $(function() { : shaka::AdaptationSet
  • AddVideoInfo() -: shaka::xml::RepresentationXmlNode +: shaka::xml::RepresentationXmlNode
  • AddVODOnlyInfo() -: shaka::xml::RepresentationXmlNode +: shaka::xml::RepresentationXmlNode
  • Advance() : shaka::media::NaluReader @@ -203,7 +209,7 @@ $(function() { : shaka::media::AesCbcDecryptor
  • AesCbcEncryptor() -: shaka::media::AesCbcEncryptor +: shaka::media::AesCbcEncryptor
  • AesCryptor() : shaka::media::AesCryptor @@ -217,6 +223,9 @@ $(function() {
  • allow_approximate_segment_timeline : shaka::MpdParams
  • +
  • allow_codec_switching +: shaka::MpdParams +
  • AppendInt() : shaka::media::BufferWriter
  • @@ -239,9 +248,7 @@ $(function() { diff --git a/docs/functions_b.html b/docs/functions_b.html index 2fd096b48b..6cfbbf11cd 100644 --- a/docs/functions_b.html +++ b/docs/functions_b.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -94,6 +97,7 @@ $(function() {
  • BoxType() : shaka::media::mp4::AC3Specific +, shaka::media::mp4::AC4Specific , shaka::media::mp4::AudioSampleEntry , shaka::media::mp4::Box , shaka::media::mp4::ChunkLargeOffset @@ -130,6 +134,7 @@ $(function() { , shaka::media::mp4::MovieFragment , shaka::media::mp4::MovieFragmentHeader , shaka::media::mp4::MovieHeader +, shaka::media::mp4::NullMediaHeader , shaka::media::mp4::OpusSpecific , shaka::media::mp4::OriginalFormat , shaka::media::mp4::PixelAspectRatio @@ -196,9 +201,7 @@ $(function() { diff --git a/docs/functions_c.html b/docs/functions_c.html index 23f96cce3e..ec8d590511 100644 --- a/docs/functions_c.html +++ b/docs/functions_c.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -76,6 +79,9 @@ $(function() { , shaka::media::SyncPointQueue , shaka::Packager
  • +
  • cc_index +: shaka::StreamDescriptor +
  • ChildExist() : shaka::media::mp4::BoxReader
  • @@ -116,6 +122,7 @@ $(function() {
  • Close() : shaka::CallbackFile , shaka::File +, shaka::HttpFile , shaka::IoCache , shaka::LocalFile , shaka::media::MkvWriter @@ -133,7 +140,8 @@ $(function() { : shaka::media::WebMClusterParser
  • codec() -: shaka::media::mp2t::ProgramMapTableWriter +: shaka::AdaptationSet +, shaka::media::mp2t::ProgramMapTableWriter
  • codec_config() : shaka::media::VPxParser @@ -168,16 +176,16 @@ $(function() { : shaka::File
  • CopyFile() -: shaka::File +: shaka::File
  • CopyFrom() -: shaka::media::MediaSample +: shaka::media::MediaSample
  • CopyRepresentation() : shaka::AdaptationSet
  • Create() -: shaka::media::RawKeySource +: shaka::media::RawKeySource , shaka::media::RsaPrivateKey , shaka::media::RsaPublicKey
  • @@ -221,9 +229,15 @@ $(function() {
  • Crypt() : shaka::media::AesCryptor
  • +
  • crypt_byte_block +: shaka::EncryptionParams +
  • cue_points : shaka::AdCueGeneratorParams
  • +
  • current_byte_ptr() +: shaka::media::BitReader +
  • current_chunk() : shaka::media::mp4::ChunkInfoIterator
  • @@ -231,9 +245,7 @@ $(function() { diff --git a/docs/functions_d.html b/docs/functions_d.html index bcdd0b5424..e989211439 100644 --- a/docs/functions_d.html +++ b/docs/functions_d.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -64,6 +67,9 @@ $(function() {
  • dash_accessiblities : shaka::StreamDescriptor
  • +
  • dash_only +: shaka::StreamDescriptor +
  • dash_profile() : shaka::MpdNotifier
  • @@ -85,7 +91,7 @@ $(function() { : shaka::media::RsaPrivateKey
  • DecryptConfig() -: shaka::media::DecryptConfig +: shaka::media::DecryptConfig
  • DecryptorSource() : shaka::media::DecryptorSource @@ -116,7 +122,8 @@ $(function() { : shaka::media::Demuxer
  • Dispatch() -: shaka::media::MediaHandler +: shaka::media::FakeInputMediaHandler +, shaka::media::MediaHandler
  • DispatchCueEvent() : shaka::media::MediaHandler @@ -158,9 +165,7 @@ $(function() { diff --git a/docs/functions_e.html b/docs/functions_e.html index ef39a6f406..4443461e33 100644 --- a/docs/functions_e.html +++ b/docs/functions_e.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -83,15 +86,13 @@ $(function() { : shaka::BandwidthEstimator
  • ExtractReferencedNamespaces() -: shaka::xml::XmlNode +: shaka::xml::XmlNode
diff --git a/docs/functions_enum.html b/docs/functions_enum.html index cf604e3e5c..63a8bc58d4 100644 --- a/docs/functions_enum.html +++ b/docs/functions_enum.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Enumerations @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -62,16 +65,11 @@ $(function() {
  • PatternEncryptionMode : shaka::media::AesPatternCryptor
  • -
  • ProtectionSystem -: shaka::EncryptionParams -
  • diff --git a/docs/functions_eval.html b/docs/functions_eval.html index 8fdfe20742..7a9fbc23f8 100644 --- a/docs/functions_eval.html +++ b/docs/functions_eval.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Enumerator @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -75,9 +78,7 @@ $(function() { diff --git a/docs/functions_f.html b/docs/functions_f.html index 7c0eab7682..d0f7888bd1 100644 --- a/docs/functions_f.html +++ b/docs/functions_f.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -82,7 +85,6 @@ $(function() {
  • FinalizeSegment() : shaka::media::mp2t::TsSegmenter -, shaka::media::mp2t::TsWriter , shaka::media::mp4::Segmenter , shaka::media::PackedAudioSegmenter , shaka::media::webm::MultiSegmentSegmenter @@ -97,14 +99,18 @@ $(function() { , shaka::File , shaka::hls::HlsNotifier , shaka::hls::SimpleHlsNotifier +, shaka::HttpFile , shaka::LocalFile , shaka::media::BitWriter +, shaka::media::BlockReader +, shaka::media::LineReader , shaka::media::MediaParser , shaka::media::mp2t::Mp2tMediaParser , shaka::media::mp2t::PesPacketGenerator , shaka::media::mp4::MP4MediaParser , shaka::media::WebMClusterParser , shaka::media::WebMMediaParser +, shaka::media::WebVttParser , shaka::media::wvm::WvmMediaParser , shaka::MemoryFile , shaka::MpdNotifier @@ -113,10 +119,12 @@ $(function() { , shaka::UdpFile
  • FlushAllDownstreams() -: shaka::media::MediaHandler +: shaka::media::FakeInputMediaHandler +, shaka::media::MediaHandler
  • FlushDownstream() -: shaka::media::MediaHandler +: shaka::media::FakeInputMediaHandler +, shaka::media::MediaHandler
  • ForceSetSegmentAlignment() : shaka::AdaptationSet @@ -137,9 +145,7 @@ $(function() { diff --git a/docs/functions_func.html b/docs/functions_func.html index 0ed2a76150..2d649638b4 100644 --- a/docs/functions_func.html +++ b/docs/functions_func.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Functions @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -68,13 +71,13 @@ $(function() { : shaka::AdaptationSet
  • AddAccessibilityElement() -: shaka::xml::AdaptationSetXmlNode +: shaka::xml::AdaptationSetXmlNode
  • AddAdaptationSetSwitching() : shaka::AdaptationSet
  • AddAudioInfo() -: shaka::xml::RepresentationXmlNode +: shaka::xml::RepresentationXmlNode
  • AddBaseUrl() : shaka::MpdBuilder @@ -83,23 +86,26 @@ $(function() { : shaka::BandwidthEstimator
  • AddChild() -: shaka::xml::XmlNode +: shaka::xml::XmlNode +
  • +
  • AddContent() +: shaka::xml::XmlNode
  • AddContentProtectionElement() : shaka::AdaptationSet , shaka::Representation
  • AddDescriptor() -: shaka::xml::RepresentationBaseXmlNode +: shaka::xml::RepresentationBaseXmlNode
  • AddElements() -: shaka::xml::XmlNode +: shaka::xml::XmlNode
  • AddEncryptionInfo() : shaka::hls::MediaPlaylist
  • AddEssentialProperty() -: shaka::xml::RepresentationBaseXmlNode +: shaka::xml::RepresentationBaseXmlNode
  • AddFloat() : shaka::hls::Tag @@ -111,7 +117,7 @@ $(function() { : shaka::hls::MediaPlaylist
  • AddLiveOnlyInfo() -: shaka::xml::RepresentationXmlNode +: shaka::xml::RepresentationXmlNode
  • AddNalu() : shaka::media::DecoderConfigurationRecord @@ -126,7 +132,7 @@ $(function() { : shaka::hls::Tag
  • AddPesPacket() -: shaka::media::mp2t::TsWriter +: shaka::media::mp2t::TsWriter
  • AddPlacementOpportunity() : shaka::hls::MediaPlaylist @@ -147,7 +153,7 @@ $(function() { : shaka::AdaptationSet
  • AddRoleElement() -: shaka::xml::AdaptationSetXmlNode +: shaka::xml::AdaptationSetXmlNode
  • AddSample() : shaka::media::mp2t::TsSegmenter @@ -166,7 +172,7 @@ $(function() { : shaka::media::DecryptConfig
  • AddSupplementalProperty() -: shaka::xml::RepresentationBaseXmlNode +: shaka::xml::RepresentationBaseXmlNode
  • AddThread() : shaka::media::SyncPointQueue @@ -175,10 +181,10 @@ $(function() { : shaka::AdaptationSet
  • AddVideoInfo() -: shaka::xml::RepresentationXmlNode +: shaka::xml::RepresentationXmlNode
  • AddVODOnlyInfo() -: shaka::xml::RepresentationXmlNode +: shaka::xml::RepresentationXmlNode
  • Advance() : shaka::media::NaluReader @@ -197,10 +203,10 @@ $(function() { , shaka::media::mp4::TrackRunIterator
  • AesCbcDecryptor() -: shaka::media::AesCbcDecryptor +: shaka::media::AesCbcDecryptor
  • AesCbcEncryptor() -: shaka::media::AesCbcEncryptor +: shaka::media::AesCbcEncryptor
  • AesCryptor() : shaka::media::AesCryptor @@ -233,9 +239,7 @@ $(function() { diff --git a/docs/functions_func_b.html b/docs/functions_func_b.html index afe4eea271..b05f2fd3b2 100644 --- a/docs/functions_func_b.html +++ b/docs/functions_func_b.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Functions @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -80,10 +83,11 @@ $(function() { : shaka::media::mp4::Box
  • BoxBuffer() -: shaka::media::mp4::BoxBuffer +: shaka::media::mp4::BoxBuffer
  • BoxType() : shaka::media::mp4::AC3Specific +, shaka::media::mp4::AC4Specific , shaka::media::mp4::AudioSampleEntry , shaka::media::mp4::Box , shaka::media::mp4::ChunkLargeOffset @@ -120,6 +124,7 @@ $(function() { , shaka::media::mp4::MovieFragment , shaka::media::mp4::MovieFragmentHeader , shaka::media::mp4::MovieHeader +, shaka::media::mp4::NullMediaHeader , shaka::media::mp4::OpusSpecific , shaka::media::mp4::OriginalFormat , shaka::media::mp4::PixelAspectRatio @@ -183,9 +188,7 @@ $(function() { diff --git a/docs/functions_func_c.html b/docs/functions_func_c.html index 096c1a0dd3..7539a08209 100644 --- a/docs/functions_func_c.html +++ b/docs/functions_func_c.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Functions @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -98,6 +101,7 @@ $(function() {
  • Close() : shaka::CallbackFile , shaka::File +, shaka::HttpFile , shaka::IoCache , shaka::LocalFile , shaka::media::MkvWriter @@ -115,7 +119,8 @@ $(function() { : shaka::media::WebMClusterParser
  • codec() -: shaka::media::mp2t::ProgramMapTableWriter +: shaka::AdaptationSet +, shaka::media::mp2t::ProgramMapTableWriter
  • codec_config() : shaka::media::VPxParser @@ -156,7 +161,7 @@ $(function() { : shaka::AdaptationSet
  • Create() -: shaka::media::RawKeySource +: shaka::media::RawKeySource , shaka::media::RsaPrivateKey , shaka::media::RsaPublicKey
  • @@ -200,6 +205,9 @@ $(function() {
  • Crypt() : shaka::media::AesCryptor
  • +
  • current_byte_ptr() +: shaka::media::BitReader +
  • current_chunk() : shaka::media::mp4::ChunkInfoIterator
  • @@ -207,9 +215,7 @@ $(function() { diff --git a/docs/functions_func_d.html b/docs/functions_func_d.html index d2eb2d7803..b5dd79c19d 100644 --- a/docs/functions_func_d.html +++ b/docs/functions_func_d.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Functions @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -102,7 +105,8 @@ $(function() { : shaka::media::Demuxer
  • Dispatch() -: shaka::media::MediaHandler +: shaka::media::FakeInputMediaHandler +, shaka::media::MediaHandler
  • DispatchCueEvent() : shaka::media::MediaHandler @@ -135,9 +139,7 @@ $(function() { diff --git a/docs/functions_func_e.html b/docs/functions_func_e.html index e4855079f2..b553cc7992 100644 --- a/docs/functions_func_e.html +++ b/docs/functions_func_e.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Functions @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -77,15 +80,13 @@ $(function() { : shaka::BandwidthEstimator
  • ExtractReferencedNamespaces() -: shaka::xml::XmlNode +: shaka::xml::XmlNode
  • diff --git a/docs/functions_func_f.html b/docs/functions_func_f.html index b4efb236ea..8ff534974c 100644 --- a/docs/functions_func_f.html +++ b/docs/functions_func_f.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Functions @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -82,7 +85,6 @@ $(function() {
  • FinalizeSegment() : shaka::media::mp2t::TsSegmenter -, shaka::media::mp2t::TsWriter , shaka::media::mp4::Segmenter , shaka::media::PackedAudioSegmenter , shaka::media::webm::MultiSegmentSegmenter @@ -97,14 +99,18 @@ $(function() { , shaka::File , shaka::hls::HlsNotifier , shaka::hls::SimpleHlsNotifier +, shaka::HttpFile , shaka::LocalFile , shaka::media::BitWriter +, shaka::media::BlockReader +, shaka::media::LineReader , shaka::media::MediaParser , shaka::media::mp2t::Mp2tMediaParser , shaka::media::mp2t::PesPacketGenerator , shaka::media::mp4::MP4MediaParser , shaka::media::WebMClusterParser , shaka::media::WebMMediaParser +, shaka::media::WebVttParser , shaka::media::wvm::WvmMediaParser , shaka::MemoryFile , shaka::MpdNotifier @@ -113,10 +119,12 @@ $(function() { , shaka::UdpFile
  • FlushAllDownstreams() -: shaka::media::MediaHandler +: shaka::media::FakeInputMediaHandler +, shaka::media::MediaHandler
  • FlushDownstream() -: shaka::media::MediaHandler +: shaka::media::FakeInputMediaHandler +, shaka::media::MediaHandler
  • ForceSetSegmentAlignment() : shaka::AdaptationSet @@ -137,9 +145,7 @@ $(function() { diff --git a/docs/functions_func_g.html b/docs/functions_func_g.html index 5ab943b526..00f42d3f18 100644 --- a/docs/functions_func_g.html +++ b/docs/functions_func_g.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Functions @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -85,9 +88,18 @@ $(function() {
  • Get() : shaka::media::HttpKeyFetcher
  • +
  • GetAC4CbiFlag() +: shaka::hls::MediaPlaylist +
  • +
  • GetAC4ImsFlag() +: shaka::hls::MediaPlaylist +
  • GetAdaptationSets() : shaka::Period
  • +
  • GetAttribute() +: shaka::xml::XmlNode +
  • GetAudioDefaultDuration() : shaka::media::WebMTracksParser
  • @@ -98,6 +110,7 @@ $(function() { : shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header
  • GetAudioStreamInfo() : shaka::media::WebMAudioClient @@ -133,8 +146,8 @@ $(function() {
  • GetDurationInSeconds() : shaka::media::webm::Segmenter
  • -
  • GetFilePosition() -: shaka::media::mp2t::TsWriter +
  • GetEC3JocComplexity() +: shaka::hls::MediaPlaylist
  • GetFileSize() : shaka::File @@ -146,11 +159,13 @@ $(function() { : shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header
  • GetFrameSizeWithoutParsing() : shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header
  • GetHeaderSize() : shaka::media::H264VideoSliceHeaderParser @@ -158,6 +173,7 @@ $(function() { , shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header , shaka::media::VideoSliceHeaderParser
  • GetHint() @@ -205,6 +221,7 @@ $(function() { : shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header
  • GetNext() : shaka::media::mp2t::ContinuityCounter @@ -219,11 +236,13 @@ $(function() { , shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header
  • GetObjectType() : shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header
  • GetOrCreateAdaptationSet() : shaka::Period @@ -234,16 +253,17 @@ $(function() {
  • GetOutputStreamDataVector() : shaka::media::MediaHandlerGraphTestBase
  • +
  • GetPixels() +: shaka::media::DvbImageBuilder +
  • GetPps() : shaka::media::H265Parser
  • -
  • GetRawPtr() -: shaka::xml::XmlNode -
  • GetSamplesPerFrame() : shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header
  • GetSamplesPerSecond() : shaka::media::AACAudioSpecificConfig @@ -252,6 +272,7 @@ $(function() { : shaka::media::mp2t::Ac3Header , shaka::media::mp2t::AdtsHeader , shaka::media::mp2t::AudioHeader +, shaka::media::mp2t::Mpeg1Header
  • GetSps() : shaka::media::H265Parser @@ -273,17 +294,15 @@ $(function() { : shaka::media::WebMVideoClient
  • GetXml() -: shaka::AdaptationSet -, shaka::Period -, shaka::Representation +: shaka::AdaptationSet +, shaka::Period +, shaka::Representation
  • diff --git a/docs/functions_func_h.html b/docs/functions_func_h.html index 8773d60460..7fee650185 100644 --- a/docs/functions_func_h.html +++ b/docs/functions_func_h.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Functions @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -62,10 +65,10 @@ $(function() {

    - h -

    diff --git a/docs/functions_u.html b/docs/functions_u.html index dedd700512..451b5f1cbc 100644 --- a/docs/functions_u.html +++ b/docs/functions_u.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -78,9 +81,6 @@ $(function() { : shaka::media::mp4::Segmenter , shaka::media::webm::Segmenter -
  • UpdateProtectionSystemInfo() -: shaka::media::KeySource -
  • use_constant_iv() : shaka::media::AesCryptor
  • @@ -88,9 +88,7 @@ $(function() { diff --git a/docs/functions_v.html b/docs/functions_v.html index a0ea4e08f3..59fecab985 100644 --- a/docs/functions_v.html +++ b/docs/functions_v.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -81,9 +84,7 @@ $(function() { diff --git a/docs/functions_vars.html b/docs/functions_vars.html index c211956e17..e78105fbdf 100644 --- a/docs/functions_vars.html +++ b/docs/functions_vars.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members - Variables @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -67,6 +70,9 @@ $(function() {
  • allow_approximate_segment_timeline : shaka::MpdParams
  • +
  • allow_codec_switching +: shaka::MpdParams +
  • @@ -91,6 +97,9 @@ $(function() {
  • ca_file : shaka::PlayReadyEncryptionParams
  • +
  • cc_index +: shaka::StreamDescriptor +
  • chunking_params : shaka::PackagingParams
  • @@ -109,6 +118,9 @@ $(function() {
  • content_id : shaka::WidevineEncryptionParams
  • +
  • crypt_byte_block +: shaka::EncryptionParams +
  • cue_points : shaka::AdCueGeneratorParams
  • @@ -119,6 +131,9 @@ $(function() {
  • dash_accessiblities : shaka::StreamDescriptor
  • +
  • dash_only +: shaka::StreamDescriptor +
  • dash_roles : shaka::StreamDescriptor
  • @@ -169,6 +184,10 @@ $(function() {

    - h -

    @@ -338,6 +390,9 @@ $(function() {
  • sample_encryption_data : shaka::media::mp4::SampleEncryption
  • +
  • scroll +: shaka::media::TextRegion +
  • segment_duration_in_seconds : shaka::ChunkingParams
  • @@ -358,6 +413,12 @@ $(function() {
  • signing_key_type : shaka::WidevineSigner
  • +
  • single_threaded +: shaka::PackagingParams +
  • +
  • skip_byte_block +: shaka::EncryptionParams +
  • skip_encryption : shaka::StreamDescriptor
  • @@ -391,6 +452,9 @@ $(function() { : shaka::media::MuxerOptions , shaka::PackagingParams +
  • text_alignment +: shaka::media::TextSettings +
  • time_shift_buffer_depth : shaka::HlsParams , shaka::MpdParams @@ -412,16 +476,24 @@ $(function() {

    - w -

    diff --git a/docs/functions_w.html b/docs/functions_w.html index 270508d13b..cb59a8597d 100644 --- a/docs/functions_w.html +++ b/docs/functions_w.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -65,7 +68,7 @@ $(function() { : shaka::IoCache
  • WebMClusterParser() -: shaka::media::WebMClusterParser +: shaka::media::WebMClusterParser
  • WebMListParser() : shaka::media::WebMListParser @@ -73,12 +76,23 @@ $(function() {
  • WebMMuxer() : shaka::media::webm::WebMMuxer
  • +
  • WebVttMuxer() +: shaka::media::webvtt::WebVttMuxer +
  • WidevineKeySource() -: shaka::media::WidevineKeySource +: shaka::media::WidevineKeySource +
  • +
  • width +: shaka::media::TextRegion +, shaka::media::TextSettings +
  • +
  • window_anchor_x +: shaka::media::TextRegion
  • Write() : shaka::CallbackFile , shaka::File +, shaka::HttpFile , shaka::IoCache , shaka::LocalFile , shaka::media::BaseDescriptor @@ -106,7 +120,7 @@ $(function() { , shaka::media::mp4::Box
  • WriteMasterPlaylist() -: shaka::hls::MasterPlaylist +: shaka::hls::MasterPlaylist
  • WriteMediaInfoToFile() : shaka::media::VodMediaInfoDumpMuxerListener @@ -139,13 +153,14 @@ $(function() {
  • WriteWebM() : shaka::media::VPCodecConfigurationRecord
  • +
  • writing_direction +: shaka::media::TextSettings +
  • diff --git a/docs/functions_x.html b/docs/functions_x.html index 99223b54de..6fdb424d45 100644 --- a/docs/functions_x.html +++ b/docs/functions_x.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -62,15 +65,13 @@ $(function() {

    - x -

    diff --git a/docs/functions_0x7e.html b/docs/functions_~.html similarity index 80% rename from docs/functions_0x7e.html rename to docs/functions_~.html index 9f189e4203..efd3e45b76 100644 --- a/docs/functions_0x7e.html +++ b/docs/functions_~.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Members @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -60,7 +63,7 @@ $(function() {
    Here is a list of all documented class members with links to the class documentation for each member:
    -

    - ~ -

    diff --git a/docs/hierarchy.html b/docs/hierarchy.html index 71635c2b5a..c8b1680751 100644 --- a/docs/hierarchy.html +++ b/docs/hierarchy.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Class Hierarchy @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -80,6 +83,7 @@ $(function() {  Cshaka::media::mp2t::AudioHeader  Cshaka::media::mp2t::Ac3Header  Cshaka::media::mp2t::AdtsHeader + Cshaka::media::mp2t::Mpeg1Header  Cshaka::media::mp4::AudioRollRecoveryEntry  Cshaka::media::AudioTimestampHelper  Cshaka::media::AV1CodecConfigurationRecordClass for parsing AV1 codec configuration record @@ -95,79 +99,81 @@ $(function() {  Cshaka::media::BlockReader  Cshaka::media::mp4::Box  Cshaka::media::mp4::AC3Specific - Cshaka::media::mp4::AudioSampleEntry - Cshaka::media::mp4::CodecConfiguration - Cshaka::media::mp4::CueIDBox - Cshaka::media::mp4::CuePayloadBox - Cshaka::media::mp4::CueSettingsBox - Cshaka::media::mp4::CueSourceIDBox - Cshaka::media::mp4::CueTimeBox - Cshaka::media::mp4::DataInformation + Cshaka::media::mp4::AC4Specific + Cshaka::media::mp4::AudioSampleEntry + Cshaka::media::mp4::CodecConfiguration + Cshaka::media::mp4::CueIDBox + Cshaka::media::mp4::CuePayloadBox + Cshaka::media::mp4::CueSettingsBox + Cshaka::media::mp4::CueSourceIDBox + Cshaka::media::mp4::CueTimeBox  Cshaka::media::mp4::DTSSpecific - Cshaka::media::mp4::EC3Specific - Cshaka::media::mp4::Edit - Cshaka::media::mp4::FileType - Cshaka::media::mp4::SegmentType - Cshaka::media::mp4::FullBox - Cshaka::media::mp4::ChunkLargeOffset - Cshaka::media::mp4::ChunkOffset - Cshaka::media::mp4::CompactSampleSize - Cshaka::media::mp4::CompositionTimeToSample - Cshaka::media::mp4::DataEntryUrl - Cshaka::media::mp4::DataReference - Cshaka::media::mp4::DecodingTimeToSample - Cshaka::media::mp4::EditList - Cshaka::media::mp4::ElementaryStreamDescriptor - Cshaka::media::mp4::FlacSpecific - Cshaka::media::mp4::HandlerReference - Cshaka::media::mp4::ID3v2Implemented per http://mp4ra.org/#/references - Cshaka::media::mp4::MediaHeader - Cshaka::media::mp4::Metadata - Cshaka::media::mp4::MovieExtendsHeader - Cshaka::media::mp4::MovieFragmentHeader - Cshaka::media::mp4::MovieHeader - Cshaka::media::mp4::ProtectionSystemSpecificHeader - Cshaka::media::mp4::SampleAuxiliaryInformationOffset - Cshaka::media::mp4::SampleAuxiliaryInformationSize - Cshaka::media::mp4::SampleDescription - Cshaka::media::mp4::SampleEncryption - Cshaka::media::mp4::SampleGroupDescription - Cshaka::media::mp4::SampleSize - Cshaka::media::mp4::SampleToChunk - Cshaka::media::mp4::SampleToGroup - Cshaka::media::mp4::SchemeType - Cshaka::media::mp4::SegmentIndex - Cshaka::media::mp4::SoundMediaHeader - Cshaka::media::mp4::SubtitleMediaHeader - Cshaka::media::mp4::SyncSample - Cshaka::media::mp4::TrackEncryption - Cshaka::media::mp4::TrackExtends - Cshaka::media::mp4::TrackFragmentDecodeTime - Cshaka::media::mp4::TrackFragmentHeader - Cshaka::media::mp4::TrackFragmentRun - Cshaka::media::mp4::TrackHeader - Cshaka::media::mp4::VideoMediaHeader - Cshaka::media::mp4::Media - Cshaka::media::mp4::MediaData - Cshaka::media::mp4::MediaInformation - Cshaka::media::mp4::Movie - Cshaka::media::mp4::MovieExtends - Cshaka::media::mp4::MovieFragment - Cshaka::media::mp4::OpusSpecific - Cshaka::media::mp4::OriginalFormat - Cshaka::media::mp4::PixelAspectRatio - Cshaka::media::mp4::ProtectionSchemeInfo - Cshaka::media::mp4::SampleTable - Cshaka::media::mp4::SchemeInfo - Cshaka::media::mp4::TextSampleEntry - Cshaka::media::mp4::Track - Cshaka::media::mp4::TrackFragment - Cshaka::media::mp4::VideoSampleEntry + Cshaka::media::mp4::DataInformation + Cshaka::media::mp4::EC3Specific + Cshaka::media::mp4::Edit + Cshaka::media::mp4::FileType + Cshaka::media::mp4::SegmentType + Cshaka::media::mp4::FullBox + Cshaka::media::mp4::ChunkLargeOffset + Cshaka::media::mp4::ChunkOffset + Cshaka::media::mp4::CompactSampleSize + Cshaka::media::mp4::CompositionTimeToSample + Cshaka::media::mp4::DataEntryUrl + Cshaka::media::mp4::DataReference + Cshaka::media::mp4::DecodingTimeToSample + Cshaka::media::mp4::EditList + Cshaka::media::mp4::ElementaryStreamDescriptor + Cshaka::media::mp4::FlacSpecific + Cshaka::media::mp4::HandlerReference + Cshaka::media::mp4::ID3v2Implemented per http://mp4ra.org/#/references + Cshaka::media::mp4::MediaHeader + Cshaka::media::mp4::Metadata + Cshaka::media::mp4::MovieExtendsHeader + Cshaka::media::mp4::MovieFragmentHeader + Cshaka::media::mp4::MovieHeader + Cshaka::media::mp4::NullMediaHeader + Cshaka::media::mp4::ProtectionSystemSpecificHeader + Cshaka::media::mp4::SampleAuxiliaryInformationOffset + Cshaka::media::mp4::SampleAuxiliaryInformationSize + Cshaka::media::mp4::SampleDescription + Cshaka::media::mp4::SampleEncryption + Cshaka::media::mp4::SampleGroupDescription + Cshaka::media::mp4::SampleSize + Cshaka::media::mp4::SampleToChunk + Cshaka::media::mp4::SampleToGroup + Cshaka::media::mp4::SchemeType + Cshaka::media::mp4::SegmentIndex + Cshaka::media::mp4::SoundMediaHeader + Cshaka::media::mp4::SubtitleMediaHeader + Cshaka::media::mp4::SyncSample + Cshaka::media::mp4::TrackEncryption + Cshaka::media::mp4::TrackExtends + Cshaka::media::mp4::TrackFragmentDecodeTime + Cshaka::media::mp4::TrackFragmentHeader + Cshaka::media::mp4::TrackFragmentRun + Cshaka::media::mp4::TrackHeader + Cshaka::media::mp4::VideoMediaHeader + Cshaka::media::mp4::Media + Cshaka::media::mp4::MediaData + Cshaka::media::mp4::MediaInformation + Cshaka::media::mp4::Movie + Cshaka::media::mp4::MovieExtends + Cshaka::media::mp4::MovieFragment + Cshaka::media::mp4::OpusSpecific + Cshaka::media::mp4::OriginalFormat + Cshaka::media::mp4::PixelAspectRatio + Cshaka::media::mp4::ProtectionSchemeInfo + Cshaka::media::mp4::SampleTable + Cshaka::media::mp4::SchemeInfo + Cshaka::media::mp4::TextSampleEntry + Cshaka::media::mp4::Track + Cshaka::media::mp4::TrackFragment  Cshaka::media::mp4::VTTAdditionalTextBox  Cshaka::media::mp4::VTTCueBox  Cshaka::media::mp4::VTTEmptyCueBox - Cshaka::media::mp4::WebVTTConfigurationBox - Cshaka::media::mp4::WebVTTSourceLabelBox + Cshaka::media::mp4::VideoSampleEntry + Cshaka::media::mp4::WebVTTConfigurationBox + Cshaka::media::mp4::WebVTTSourceLabelBox  Cshaka::media::mp4::BoxBuffer  Cshaka::BufferCallbackParamsBuffer callback params  Cshaka::media::BufferReader @@ -195,250 +201,267 @@ $(function() {  Cshaka::media::mp4::DecodingTimeIterator  Cshaka::media::DecryptConfig  Cshaka::DecryptionParamsDecryption parameters - Cshaka::media::DecryptorSourceDecryptorSource wraps KeySource and is responsible for decryptor management + Cshaka::media::DecryptorSourceDecryptorSource wraps KeySource and is responsible for decryptor management  Cshaka::media::wvm::DemuxStreamIdMediaSample  Cshaka::media::DOVIDecoderConfigurationRecordClass for parsing Dolby Vision decoder configuration record - Cshaka::media::mp4::EditListEntry - Cshaka::Element - Cshaka::EncryptionParams::EncryptedStreamAttributesEncrypted stream information that is used to determine stream label - Cshaka::media::EncryptionConfig - Cshaka::media::EncryptionKey - Cshaka::EncryptionParamsEncryption parameters - Cshaka::media::mp2t::EsParser - Cshaka::media::mp2t::EsParserAudio - Cshaka::media::mp2t::EsParserH26x - Cshaka::media::mp2t::EsParserH264 - Cshaka::media::mp2t::EsParserH265 - Cshaka::media::EventInfo - Cshaka::FileDefine an abstract file interface - Cshaka::CallbackFile - Cshaka::LocalFileImplement LocalFile which deals with local storage - Cshaka::MemoryFile - Cshaka::ThreadedIoFileDeclaration of class which implements a thread-safe circular buffer - Cshaka::UdpFileImplements UdpFile, which receives UDP unicast and multicast streams - Cshaka::FileCloser - Cshaka::media::FileReaderClass to read character-by-character from a file - Cshaka::media::mp4::Fragmenter - Cshaka::media::H264DecRefPicMarking - Cshaka::media::H264ModificationOfPicNum - Cshaka::media::H264Parser - Cshaka::media::H264Pps - Cshaka::media::H264SEIMessage - Cshaka::media::H264SEIRecoveryPoint - Cshaka::media::H264SliceHeader - Cshaka::media::H264Sps - Cshaka::media::H264WeightingFactors - Cshaka::media::H265Parser - Cshaka::media::H265Pps - Cshaka::media::H265ReferencePictureListModifications - Cshaka::media::H265ReferencePictureSet - Cshaka::media::H265SliceHeader - Cshaka::media::H265Sps - Cshaka::media::H265VuiParameters - Cshaka::media::H26xBitReader - Cshaka::media::H26xByteToUnitStreamConverterA base class that is used to convert H.26x byte streams to NAL unit streams - Cshaka::media::H264ByteToUnitStreamConverter - Cshaka::media::H265ByteToUnitStreamConverter - Cshaka::hls::HlsEntry - Cshaka::hls::HlsNotifier - Cshaka::hls::SimpleHlsNotifierThis is thread safe - Cshaka::HlsParamsHLS related parameters - Cshaka::media::Id3Tag - CIMkvWriter - Cshaka::media::MkvWriterAn implementation of IMkvWriter using our File type - Cshaka::IoCacheDeclaration of class which implements a thread-safe circular buffer - Cshaka::media::JobManager - Cshaka::media::KeyFetcherBase class for fetching keys from the license service - Cshaka::media::HttpKeyFetcher - Cshaka::media::KeyFrameEvent - Cshaka::media::mp4::KeyFrameInfoTracks key frame information - Cshaka::RawKeyParams::KeyInfo - Cshaka::media::KeySourceKeySource is responsible for encryption key acquisition - Cshaka::media::PlayReadyKeySourceA key source that uses PlayReady for encryption - Cshaka::media::RawKeySourceA key source that uses raw keys for encryption - Cshaka::media::WidevineKeySource - Cshaka::media::mp4::Language - Cshaka::media::LibcryptoThreadingConvenience class which initializes and terminates libcrypto threading - Cshaka::media::LineReader - Cshaka::media::H265SliceHeader::LongTermPicsInfo - Cshaka::hls::MasterPlaylist - Cshaka::media::MediaHandler - Cshaka::media::CachingMediaHandler - Cshaka::media::ChunkingHandler - Cshaka::media::CueAlignmentHandler - Cshaka::media::EncryptionHandler - Cshaka::media::FakeInputMediaHandler - Cshaka::media::MockOutputMediaHandler - Cshaka::media::Muxer - Cshaka::media::mp2t::TsMuxer - Cshaka::media::mp4::MP4Muxer - Cshaka::media::PackedAudioWriter - Cshaka::media::webm::WebMMuxerImplements WebM Muxer - Cshaka::media::OriginHandler - Cshaka::media::Demuxer - Cshaka::media::WebVttParser - Cshaka::media::Replicator - Cshaka::media::TextChunker - Cshaka::media::TextPadder - Cshaka::media::TrickPlayHandler - Cshaka::media::WebVttTextOutputHandler - Cshaka::media::WebVttToMp4Handler - Cshaka::media::MediaParser - Cshaka::media::mp2t::Mp2tMediaParser - Cshaka::media::mp4::MP4MediaParser - Cshaka::media::WebMMediaParser - Cshaka::media::wvm::WvmMediaParser - Cshaka::hls::MediaPlaylistMethods are virtual for mocking - Cshaka::hls::MockMediaPlaylist - Cshaka::hls::MediaPlaylistFactory - Cshaka::media::MuxerListener::MediaRanges - Cshaka::media::MediaSampleClass to hold a media sample - Cshaka::Mp4OutputParamsMP4 (ISO-BMFF) output related parameters - Cshaka::MpdBuilderThis class generates DASH MPDs (Media Presentation Descriptions) - Cshaka::MockMpdBuilder - Cshaka::MpdNotifier - Cshaka::MockMpdNotifier - Cshaka::SimpleMpdNotifier - Cshaka::MpdNotifierFactory - Cshaka::MpdOptionsDefines Mpd Options - Cshaka::MpdParamsDASH MPD related parameters - Cshaka::MpdWriter - Cshaka::media::MuxerFactory - Cshaka::media::MuxerListener - Cshaka::media::CombinedMuxerListener - Cshaka::media::HlsNotifyMuxerListenerMuxerListener that uses HlsNotifier - Cshaka::media::MockMuxerListener - Cshaka::media::MpdNotifyMuxerListener - Cshaka::media::VodMediaInfoDumpMuxerListener - Cshaka::media::MuxerListenerFactory - Cshaka::media::MuxerOptionsThis structure contains the list of configuration options for Muxer - Cshaka::media::Nalu - Cshaka::media::NalUnitToByteStreamConverter - Cshaka::media::NaluReader - Cshaka::media::OffsetByteQueue - Cshaka::EncryptionParams::EncryptedStreamAttributes::OneOf - Cshaka::media::OnMediaEndParameters - Cshaka::media::OnNewSegmentParameters - Cshaka::Packager - Cshaka::PackagingParamsPackaging parameters - Cshaka::media::PackedAudioSegmenter - Cshaka::media::PeekingReader - Cshaka::Period - Cshaka::MockPeriod - Cshaka::media::mp2t::PesPacketClass that carries PES packet information - Cshaka::media::mp2t::PesPacketGenerator - Cshaka::PlayReadyEncryptionParams - Cshaka::media::wvm::PrevSampleData - Cshaka::media::ProducerConsumerQueue< T > - Cshaka::media::mp2t::ProgramMapTableWriterPuts PMT into TS packets and writes them to buffer - Cshaka::media::mp2t::AudioProgramMapTableWriterProgramMapTableWriter for video codecs - Cshaka::media::mp2t::VideoProgramMapTableWriterProgramMapTableWriter for video codecs - Cshaka::media::ProgressListenerThis class listens to progress updates events - Cshaka::media::ProtectionSystemSpecificInfo - Cshaka::media::PsshBoxBuilder - Cshaka::media::PsshGenerator - Cshaka::media::CommonPsshGenerator - Cshaka::media::PlayReadyPsshGenerator - Cshaka::media::WidevinePsshGenerator - Cshaka::media::Range - Cshaka::RawKeyParamsRaw key encryption/decryption parameters, i.e. with key parameters provided - Cshaka::Representation - Cshaka::MockRepresentation - Cshaka::RepresentationStateChangeListener - Cshaka::media::RequestSignerAbstract class used for signature generation - Cshaka::media::AesRequestSignerAesRequestSigner uses AES-CBC signing - Cshaka::media::RsaRequestSignerRsaRequestSigner uses RSA-PSS signing - Cshaka::media::RsaPrivateKeyRsa private key, used for message signing and decryption - Cshaka::media::RsaPublicKeyRsa public key, used for signature verification and encryption - Cshaka::media::mp4::SampleEncryptionEntry - Cshaka::media::mp4::SampleToGroupEntry - Cshaka::media::Scte35Event - Cshaka::media::SeekHead - Cshaka::media::mp4::Segmenter - Cshaka::media::mp4::MultiSegmentSegmenter - Cshaka::media::mp4::SingleSegmentSegmenter - Cshaka::media::webm::Segmenter - Cshaka::media::webm::MultiSegmentSegmenter - Cshaka::media::webm::SingleSegmentSegmenter - Cshaka::media::webm::TwoPassSingleSegmentSegmenter - Cshaka::media::SegmentEventInfo - Cshaka::media::SegmentInfo - Cshaka::SegmentInfo - Cshaka::media::mp4::SegmentReference - CSimpleThread - Cshaka::media::ClosureThread - Cshaka::media::Job - Cshaka::Status - Cshaka::media::MuxerListenerFactory::StreamData - Cshaka::media::StreamData - Cshaka::StreamDescriptorDefines a single input/output stream - Cshaka::media::StreamInfoAbstract class holds stream information - Cshaka::media::AudioStreamInfoHolds audio stream information - Cshaka::media::TextStreamInfo - Cshaka::media::VideoStreamInfoHolds video stream information - Cshaka::media::SubsampleEntry - Cshaka::media::SubsampleGenerator - Cshaka::media::SyncPointQueueA synchronized queue for cue points - Cshaka::media::mp4::SyncSampleIterator - Cshaka::hls::Tag - CTest - Cshaka::media::MediaHandlerTestBase - Cshaka::media::MediaHandlerGraphTestBase - Cshaka::media::SegmentTestBase - Cshaka::TestParamsParameters used for testing - Cshaka::media::TextSample - Cshaka::media::TextTrack - Cshaka::media::TextTrackConfig - Cshaka::media::AV1Parser::Tile - Cshaka::media::mp4::TrackRunIterator - Cshaka::media::TracksBuilder - Cshaka::media::mp2t::TsPacket - Cshaka::media::mp2t::TsSection - Cshaka::media::mp2t::TsSectionPes - Cshaka::media::mp2t::TsSectionPsi - Cshaka::media::mp2t::TsSectionPat - Cshaka::media::mp2t::TsSectionPmt - Cshaka::media::mp2t::TsSegmenter - Cshaka::media::mp2t::TsWriter - Cshaka::UdpOptionsOptions parsed from UDP url string of the form: udp://ip:port[?options] - Cshaka::MpdParams::UtcTimingUTCTimings. For dynamic MPD only - Cshaka::media::VideoSliceHeaderParser - Cshaka::media::H264VideoSliceHeaderParser - Cshaka::media::H265VideoSliceHeaderParser - Cshaka::media::mp2t::EsParserH26x::VideoSliceInfo - Cshaka::media::VideoStreamInfoParameters - Cshaka::media::VPCodecConfigurationRecordClass for parsing or writing VP codec configuration record - Cshaka::media::VPxFrameInfo - Cshaka::media::VPxParser - Cshaka::media::VP8Parser - Cshaka::media::VP9ParserClass to parse a vp9 bit stream - Cshaka::media::WebMListParser - Cshaka::media::WebMParserClient - Cshaka::media::SegmentTestBase::ClusterParser - Cshaka::media::WebMAudioClientHelper class used to parse an Audio element inside a TrackEntry element - Cshaka::media::WebMClusterParser - Cshaka::media::WebMContentEncodingsClientParser for WebM ContentEncodings element - Cshaka::media::WebMInfoParserParser for WebM Info element - Cshaka::media::WebMTracksParserParser for WebM Tracks element - Cshaka::media::WebMVideoClientHelper class used to parse a Video element inside a TrackEntry element - Cshaka::media::WebMWebVTTParser - Cshaka::media::WebVttFileBuffer - Cshaka::WidevineDecryptionParamsWidevine decryption parameters - Cshaka::WidevineEncryptionParamsWidevine encryption parameters - Cshaka::WidevineSignerSigner credential for Widevine license server - Cshaka::xml::XmlDeleter - Cshaka::xml::XmlNode - Cshaka::xml::RepresentationBaseXmlNode - Cshaka::xml::AdaptationSetXmlNodeAdaptationSetType specified in MPD - Cshaka::xml::RepresentationXmlNodeRepresentationType in MPD + Cshaka::media::DvbImageBuilder + Cshaka::media::DvbImageColorSpace + Cshaka::media::DvbSubParser + Cshaka::media::mp4::EditListEntry + Cshaka::Element + Cshaka::EncryptionParams::EncryptedStreamAttributesEncrypted stream information that is used to determine stream label + Cshaka::media::EncryptionConfig + Cshaka::media::EncryptionKey + Cshaka::EncryptionParamsEncryption parameters + Cshaka::media::mp2t::EsParser + Cshaka::media::mp2t::EsParserAudio + Cshaka::media::mp2t::EsParserDvb + Cshaka::media::mp2t::EsParserH26x + Cshaka::media::mp2t::EsParserH264 + Cshaka::media::mp2t::EsParserH265 + Cshaka::media::EventInfo + Cshaka::FileDefine an abstract file interface + Cshaka::CallbackFile + Cshaka::HttpFile + Cshaka::LocalFileImplement LocalFile which deals with local storage + Cshaka::MemoryFile + Cshaka::ThreadedIoFileDeclaration of class which implements a thread-safe circular buffer + Cshaka::UdpFileImplements UdpFile, which receives UDP unicast and multicast streams + Cshaka::FileCloser + Cshaka::media::mp4::Fragmenter + Cshaka::media::H264DecRefPicMarking + Cshaka::media::H264ModificationOfPicNum + Cshaka::media::H264Parser + Cshaka::media::H264Pps + Cshaka::media::H264SEIMessage + Cshaka::media::H264SEIRecoveryPoint + Cshaka::media::H264SliceHeader + Cshaka::media::H264Sps + Cshaka::media::H264WeightingFactors + Cshaka::media::H265Parser + Cshaka::media::H265Pps + Cshaka::media::H265ReferencePictureListModifications + Cshaka::media::H265ReferencePictureSet + Cshaka::media::H265SliceHeader + Cshaka::media::H265Sps + Cshaka::media::H265VuiParameters + Cshaka::media::H26xBitReader + Cshaka::media::H26xByteToUnitStreamConverterA base class that is used to convert H.26x byte streams to NAL unit streams + Cshaka::media::H264ByteToUnitStreamConverter + Cshaka::media::H265ByteToUnitStreamConverter + Cshaka::hls::HlsEntry + Cshaka::hls::HlsNotifier + Cshaka::hls::SimpleHlsNotifierThis is thread safe + Cshaka::HlsParamsHLS related parameters + Cshaka::media::Id3Tag + Cmkvmuxer::IMkvWriter + Cshaka::media::MkvWriterAn implementation of IMkvWriter using our File type + Cshaka::IoCacheDeclaration of class which implements a thread-safe circular buffer + Cshaka::media::JobManager::JobEntry + Cshaka::media::JobManager + Cshaka::media::SingleThreadJobManager + Cshaka::media::KeyFetcherBase class for fetching keys from the license service + Cshaka::media::HttpKeyFetcher + Cshaka::media::KeyFrameEvent + Cshaka::media::mp4::KeyFrameInfoTracks key frame information + Cshaka::RawKeyParams::KeyInfo + Cshaka::media::KeySourceKeySource is responsible for encryption key acquisition + Cshaka::media::PlayReadyKeySourceA key source that uses PlayReady for encryption + Cshaka::media::RawKeySourceA key source that uses raw keys for encryption + Cshaka::media::WidevineKeySource + Cshaka::media::mp4::Language + Cshaka::media::LibcryptoThreadingConvenience class which initializes and terminates libcrypto threading + Cshaka::media::LineReader + Cshaka::media::H265SliceHeader::LongTermPicsInfo + Cshaka::hls::MasterPlaylist + Cshaka::media::MediaHandler + Cshaka::media::CachingMediaHandler + Cshaka::media::CcStreamFilter + Cshaka::media::ChunkingHandler + Cshaka::media::CueAlignmentHandler + Cshaka::media::EncryptionHandler + Cshaka::media::FakeInputMediaHandler + Cshaka::media::MockOutputMediaHandler + Cshaka::media::Muxer + Cshaka::media::PackedAudioWriter + Cshaka::media::TextMuxer + Cshaka::media::ttml::TtmlMuxer + Cshaka::media::webvtt::WebVttMuxerImplements WebVtt Muxer + Cshaka::media::mp2t::TsMuxer + Cshaka::media::mp4::MP4Muxer + Cshaka::media::webm::WebMMuxerImplements WebM Muxer + Cshaka::media::OriginHandler + Cshaka::media::Demuxer + Cshaka::media::Replicator + Cshaka::media::TextChunker + Cshaka::media::TextPadder + Cshaka::media::TrickPlayHandler + Cshaka::media::WebVttToMp4Handler + Cshaka::media::ttml::TtmlToMp4Handler + Cshaka::media::MediaParser + Cshaka::media::WebMMediaParser + Cshaka::media::WebVttParser + Cshaka::media::mp2t::Mp2tMediaParser + Cshaka::media::mp4::MP4MediaParser + Cshaka::media::wvm::WvmMediaParser + Cshaka::hls::MediaPlaylistMethods are virtual for mocking + Cshaka::hls::MockMediaPlaylist + Cshaka::hls::MediaPlaylistFactory + Cshaka::media::MuxerListener::MediaRanges + Cshaka::media::MediaSampleClass to hold a media sample + Cshaka::Mp4OutputParamsMP4 (ISO-BMFF) output related parameters + Cshaka::MpdBuilderThis class generates DASH MPDs (Media Presentation Descriptions) + Cshaka::MockMpdBuilder + Cshaka::MpdNotifier + Cshaka::MockMpdNotifier + Cshaka::SimpleMpdNotifier + Cshaka::MpdNotifierFactory + Cshaka::MpdOptionsDefines Mpd Options + Cshaka::MpdParamsDASH MPD related parameters + Cshaka::MpdWriter + Cshaka::media::MuxerFactory + Cshaka::media::MuxerListener + Cshaka::media::CombinedMuxerListener + Cshaka::media::MultiCodecMuxerListener + Cshaka::media::HlsNotifyMuxerListenerMuxerListener that uses HlsNotifier + Cshaka::media::MockMuxerListener + Cshaka::media::MpdNotifyMuxerListener + Cshaka::media::VodMediaInfoDumpMuxerListener + Cshaka::media::MuxerListenerFactory + Cshaka::media::MuxerOptionsThis structure contains the list of configuration options for Muxer + Cshaka::media::Nalu + Cshaka::media::NalUnitToByteStreamConverter + Cshaka::media::NaluReader + Cshaka::media::OffsetByteQueue + Cshaka::EncryptionParams::EncryptedStreamAttributes::OneOf + Cshaka::media::OnMediaEndParameters + Cshaka::media::OnNewSegmentParameters + Cshaka::Packager + Cshaka::PackagingParamsPackaging parameters + Cshaka::media::PackedAudioSegmenter + Cshaka::Period + Cshaka::MockPeriod + Cshaka::media::mp2t::PesPacketClass that carries PES packet information + Cshaka::media::mp2t::PesPacketGenerator + Cshaka::PlayReadyEncryptionParams + Cshaka::media::wvm::PrevSampleData + Cshaka::media::ProducerConsumerQueue< T > + Cshaka::media::mp2t::ProgramMapTableWriterPuts PMT into TS packets and writes them to buffer + Cshaka::media::mp2t::AudioProgramMapTableWriterProgramMapTableWriter for video codecs + Cshaka::media::mp2t::VideoProgramMapTableWriterProgramMapTableWriter for video codecs + Cshaka::media::ProgressListenerThis class listens to progress updates events + Cshaka::media::ProtectionSystemSpecificInfo + Cshaka::media::PsshBoxBuilder + Cshaka::media::PsshGenerator + Cshaka::media::CommonPsshGenerator + Cshaka::media::PlayReadyPsshGenerator + Cshaka::media::WidevinePsshGenerator + Cshaka::media::Range + Cshaka::RawKeyParamsRaw key encryption/decryption parameters, i.e. with key parameters provided + Cshaka::Representation + Cshaka::MockRepresentation + Cshaka::RepresentationStateChangeListener + Cshaka::media::RequestSignerAbstract class used for signature generation + Cshaka::media::AesRequestSignerAesRequestSigner uses AES-CBC signing + Cshaka::media::RsaRequestSignerRsaRequestSigner uses RSA-PSS signing + Cshaka::media::RgbaColor + Cshaka::media::RsaPrivateKeyRsa private key, used for message signing and decryption + Cshaka::media::RsaPublicKeyRsa public key, used for signature verification and encryption + Cshaka::media::mp4::SampleEncryptionEntry + Cshaka::media::mp4::SampleToGroupEntry + Cshaka::media::Scte35Event + Cshaka::media::SeekHead + Cshaka::media::mp4::Segmenter + Cshaka::media::mp4::MultiSegmentSegmenter + Cshaka::media::mp4::SingleSegmentSegmenter + Cshaka::media::webm::Segmenter + Cshaka::media::webm::MultiSegmentSegmenter + Cshaka::media::webm::SingleSegmentSegmenter + Cshaka::media::webm::TwoPassSingleSegmentSegmenter + Cshaka::media::SegmentEventInfo + Cshaka::media::SegmentInfo + Cshaka::SegmentInfo + Cshaka::media::mp4::SegmentReference + Cbase::SimpleThread + Cshaka::media::ClosureThread + Cshaka::media::Job + Cshaka::Status + Cshaka::media::MuxerListenerFactory::StreamData + Cshaka::media::StreamData + Cshaka::StreamDescriptorDefines a single input/output stream + Cshaka::media::StreamInfoAbstract class holds stream information + Cshaka::media::AudioStreamInfoHolds audio stream information + Cshaka::media::TextStreamInfo + Cshaka::media::VideoStreamInfoHolds video stream information + Cshaka::media::SubsampleEntry + Cshaka::media::SubsampleGenerator + Cshaka::media::SubtitleComposer + Cshaka::media::SyncPointQueueA synchronized queue for cue points + Cshaka::media::mp4::SyncSampleIterator + Cshaka::hls::Tag + Ctesting::Test + Cshaka::media::MediaHandlerTestBase + Cshaka::media::MediaHandlerGraphTestBase + Cshaka::media::SegmentTestBase + Cshaka::TestParamsParameters used for testing + Cshaka::media::TextFragment + Cshaka::media::TextFragmentStyle + Cshaka::media::TextNumber + Cshaka::media::TextRegion + Cshaka::media::TextSample + Cshaka::media::TextSettings + Cshaka::media::TextSubStreamInfo + Cshaka::media::TextTrack + Cshaka::media::TextTrackConfig + Cshaka::media::AV1Parser::Tile + Cshaka::media::mp4::TrackRunIterator + Cshaka::media::TracksBuilder + Cshaka::media::mp2t::TsPacket + Cshaka::media::mp2t::TsSection + Cshaka::media::mp2t::TsSectionPes + Cshaka::media::mp2t::TsSectionPsi + Cshaka::media::mp2t::TsSectionPat + Cshaka::media::mp2t::TsSectionPmt + Cshaka::media::mp2t::TsSegmenter + Cshaka::media::mp2t::TsWriter + Cshaka::media::ttml::TtmlGenerator + Cshaka::UdpOptionsOptions parsed from UDP url string of the form: udp://ip:port[?options] + Cshaka::MpdParams::UtcTimingUTCTimings. For dynamic MPD only + Cshaka::media::VideoSliceHeaderParser + Cshaka::media::H264VideoSliceHeaderParser + Cshaka::media::H265VideoSliceHeaderParser + Cshaka::media::mp2t::EsParserH26x::VideoSliceInfo + Cshaka::media::VideoStreamInfoParameters + Cshaka::media::VPCodecConfigurationRecordClass for parsing or writing VP codec configuration record + Cshaka::media::VPxFrameInfo + Cshaka::media::VPxParser + Cshaka::media::VP8Parser + Cshaka::media::VP9ParserClass to parse a vp9 bit stream + Cshaka::media::WebMListParser + Cshaka::media::WebMParserClient + Cshaka::media::SegmentTestBase::ClusterParser + Cshaka::media::WebMAudioClientHelper class used to parse an Audio element inside a TrackEntry element + Cshaka::media::WebMClusterParser + Cshaka::media::WebMContentEncodingsClientParser for WebM ContentEncodings element + Cshaka::media::WebMInfoParserParser for WebM Info element + Cshaka::media::WebMTracksParserParser for WebM Tracks element + Cshaka::media::WebMVideoClientHelper class used to parse a Video element inside a TrackEntry element + Cshaka::media::WebMWebVTTParser + Cshaka::media::WebVttFileBuffer + Cshaka::WidevineDecryptionParamsWidevine decryption parameters + Cshaka::WidevineEncryptionParamsWidevine encryption parameters + Cshaka::WidevineSignerSigner credential for Widevine license server + Cshaka::xml::XmlDeleter + Cshaka::xml::XmlNode + Cshaka::xml::RepresentationBaseXmlNode + Cshaka::xml::AdaptationSetXmlNodeAdaptationSetType specified in MPD + Cshaka::xml::RepresentationXmlNodeRepresentationType in MPD diff --git a/docs/index.html b/docs/index.html index e0ab2c9de3..72b0c8c646 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,9 +1,9 @@ - + - + Shaka Packager SDK: Main Page @@ -29,18 +29,21 @@ - + +/* @license-end */ @@ -65,9 +68,7 @@ $(function() { diff --git a/docs/jquery.js b/docs/jquery.js index f5343eda92..103c32d79b 100644 --- a/docs/jquery.js +++ b/docs/jquery.js @@ -1,71 +1,26 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
    "),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
    ").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
    "),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
    "),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element +},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** + * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.2 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1)[^>]*$|#([\w\-]*)$)/,bM=/\S/,bI=/^\s+/,bE=/\s+$/,bA=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,bN=/^[\],:{}\s]*$/,bW=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,bP=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,bJ=/(?:^|:|,)(?:\s*\[)+/g,by=/(webkit)[ \/]([\w.]+)/,bR=/(opera)(?:.*version)?[ \/]([\w.]+)/,bQ=/(msie) ([\w.]+)/,bS=/(mozilla)(?:.*? rv:([\w.]+))?/,bB=/-([a-z]|[0-9])/ig,bZ=/^-ms-/,bT=function(b0,b1){return(b1+"").toUpperCase()},bX=bu.userAgent,bV,bC,e,bL=Object.prototype.toString,bG=Object.prototype.hasOwnProperty,bz=Array.prototype.push,bK=Array.prototype.slice,bO=String.prototype.trim,bv=Array.prototype.indexOf,bx={};bF.fn=bF.prototype={constructor:bF,init:function(b0,b4,b3){var b2,b5,b1,b6;if(!b0){return this}if(b0.nodeType){this.context=this[0]=b0;this.length=1;return this}if(b0==="body"&&!b4&&av.body){this.context=av;this[0]=av.body;this.selector=b0;this.length=1;return this}if(typeof b0==="string"){if(b0.charAt(0)==="<"&&b0.charAt(b0.length-1)===">"&&b0.length>=3){b2=[null,b0,null]}else{b2=bY.exec(b0)}if(b2&&(b2[1]||!b4)){if(b2[1]){b4=b4 instanceof bF?b4[0]:b4;b6=(b4?b4.ownerDocument||b4:av);b1=bA.exec(b0);if(b1){if(bF.isPlainObject(b4)){b0=[av.createElement(b1[1])];bF.fn.attr.call(b0,b4,true)}else{b0=[b6.createElement(b1[1])]}}else{b1=bF.buildFragment([b2[1]],[b6]);b0=(b1.cacheable?bF.clone(b1.fragment):b1.fragment).childNodes}return bF.merge(this,b0)}else{b5=av.getElementById(b2[2]);if(b5&&b5.parentNode){if(b5.id!==b2[2]){return b3.find(b0)}this.length=1;this[0]=b5}this.context=av;this.selector=b0;return this}}else{if(!b4||b4.jquery){return(b4||b3).find(b0)}else{return this.constructor(b4).find(b0)}}}else{if(bF.isFunction(b0)){return b3.ready(b0)}}if(b0.selector!==L){this.selector=b0.selector;this.context=b0.context}return bF.makeArray(b0,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return bK.call(this,0)},get:function(b0){return b0==null?this.toArray():(b0<0?this[this.length+b0]:this[b0])},pushStack:function(b1,b3,b0){var b2=this.constructor();if(bF.isArray(b1)){bz.apply(b2,b1)}else{bF.merge(b2,b1)}b2.prevObject=this;b2.context=this.context;if(b3==="find"){b2.selector=this.selector+(this.selector?" ":"")+b0}else{if(b3){b2.selector=this.selector+"."+b3+"("+b0+")"}}return b2},each:function(b1,b0){return bF.each(this,b1,b0)},ready:function(b0){bF.bindReady();bC.add(b0);return this},eq:function(b0){b0=+b0;return b0===-1?this.slice(b0):this.slice(b0,b0+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(bK.apply(this,arguments),"slice",bK.call(arguments).join(","))},map:function(b0){return this.pushStack(bF.map(this,function(b2,b1){return b0.call(b2,b1,b2)}))},end:function(){return this.prevObject||this.constructor(null)},push:bz,sort:[].sort,splice:[].splice};bF.fn.init.prototype=bF.fn;bF.extend=bF.fn.extend=function(){var b9,b2,b0,b1,b6,b7,b5=arguments[0]||{},b4=1,b3=arguments.length,b8=false;if(typeof b5==="boolean"){b8=b5;b5=arguments[1]||{};b4=2}if(typeof b5!=="object"&&!bF.isFunction(b5)){b5={}}if(b3===b4){b5=this;--b4}for(;b40){return}bC.fireWith(av,[bF]);if(bF.fn.trigger){bF(av).trigger("ready").off("ready")}}},bindReady:function(){if(bC){return}bC=bF.Callbacks("once memory");if(av.readyState==="complete"){return setTimeout(bF.ready,1)}if(av.addEventListener){av.addEventListener("DOMContentLoaded",e,false);bb.addEventListener("load",bF.ready,false)}else{if(av.attachEvent){av.attachEvent("onreadystatechange",e);bb.attachEvent("onload",bF.ready);var b0=false;try{b0=bb.frameElement==null}catch(b1){}if(av.documentElement.doScroll&&b0){bw()}}}},isFunction:function(b0){return bF.type(b0)==="function"},isArray:Array.isArray||function(b0){return bF.type(b0)==="array"},isWindow:function(b0){return b0&&typeof b0==="object"&&"setInterval" in b0},isNumeric:function(b0){return !isNaN(parseFloat(b0))&&isFinite(b0)},type:function(b0){return b0==null?String(b0):bx[bL.call(b0)]||"object"},isPlainObject:function(b2){if(!b2||bF.type(b2)!=="object"||b2.nodeType||bF.isWindow(b2)){return false}try{if(b2.constructor&&!bG.call(b2,"constructor")&&!bG.call(b2.constructor.prototype,"isPrototypeOf")){return false}}catch(b1){return false}var b0;for(b0 in b2){}return b0===L||bG.call(b2,b0)},isEmptyObject:function(b1){for(var b0 in b1){return false}return true},error:function(b0){throw new Error(b0)},parseJSON:function(b0){if(typeof b0!=="string"||!b0){return null}b0=bF.trim(b0);if(bb.JSON&&bb.JSON.parse){return bb.JSON.parse(b0)}if(bN.test(b0.replace(bW,"@").replace(bP,"]").replace(bJ,""))){return(new Function("return "+b0))()}bF.error("Invalid JSON: "+b0)},parseXML:function(b2){var b0,b1;try{if(bb.DOMParser){b1=new DOMParser();b0=b1.parseFromString(b2,"text/xml")}else{b0=new ActiveXObject("Microsoft.XMLDOM");b0.async="false";b0.loadXML(b2)}}catch(b3){b0=L}if(!b0||!b0.documentElement||b0.getElementsByTagName("parsererror").length){bF.error("Invalid XML: "+b2)}return b0},noop:function(){},globalEval:function(b0){if(b0&&bM.test(b0)){(bb.execScript||function(b1){bb["eval"].call(bb,b1)})(b0)}},camelCase:function(b0){return b0.replace(bZ,"ms-").replace(bB,bT)},nodeName:function(b1,b0){return b1.nodeName&&b1.nodeName.toUpperCase()===b0.toUpperCase()},each:function(b3,b6,b2){var b1,b4=0,b5=b3.length,b0=b5===L||bF.isFunction(b3);if(b2){if(b0){for(b1 in b3){if(b6.apply(b3[b1],b2)===false){break}}}else{for(;b40&&b0[0]&&b0[b1-1])||b1===0||bF.isArray(b0));if(b3){for(;b21?aJ.call(arguments,0):bG;if(!(--bw)){bC.resolveWith(bC,bx)}}}function bz(bF){return function(bG){bB[bF]=arguments.length>1?aJ.call(arguments,0):bG;bC.notifyWith(bE,bB)}}if(e>1){for(;bv
    a";bI=bv.getElementsByTagName("*");bF=bv.getElementsByTagName("a")[0];if(!bI||!bI.length||!bF){return{}}bG=av.createElement("select");bx=bG.appendChild(av.createElement("option"));bE=bv.getElementsByTagName("input")[0];bJ={leadingWhitespace:(bv.firstChild.nodeType===3),tbody:!bv.getElementsByTagName("tbody").length,htmlSerialize:!!bv.getElementsByTagName("link").length,style:/top/.test(bF.getAttribute("style")),hrefNormalized:(bF.getAttribute("href")==="/a"),opacity:/^0.55/.test(bF.style.opacity),cssFloat:!!bF.style.cssFloat,checkOn:(bE.value==="on"),optSelected:bx.selected,getSetAttribute:bv.className!=="t",enctype:!!av.createElement("form").enctype,html5Clone:av.createElement("nav").cloneNode(true).outerHTML!=="<:nav>",submitBubbles:true,changeBubbles:true,focusinBubbles:false,deleteExpando:true,noCloneEvent:true,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableMarginRight:true};bE.checked=true;bJ.noCloneChecked=bE.cloneNode(true).checked;bG.disabled=true;bJ.optDisabled=!bx.disabled;try{delete bv.test}catch(bC){bJ.deleteExpando=false}if(!bv.addEventListener&&bv.attachEvent&&bv.fireEvent){bv.attachEvent("onclick",function(){bJ.noCloneEvent=false});bv.cloneNode(true).fireEvent("onclick")}bE=av.createElement("input");bE.value="t";bE.setAttribute("type","radio");bJ.radioValue=bE.value==="t";bE.setAttribute("checked","checked");bv.appendChild(bE);bD=av.createDocumentFragment();bD.appendChild(bv.lastChild);bJ.checkClone=bD.cloneNode(true).cloneNode(true).lastChild.checked;bJ.appendChecked=bE.checked;bD.removeChild(bE);bD.appendChild(bv);bv.innerHTML="";if(bb.getComputedStyle){bA=av.createElement("div");bA.style.width="0";bA.style.marginRight="0";bv.style.width="2px";bv.appendChild(bA);bJ.reliableMarginRight=(parseInt((bb.getComputedStyle(bA,null)||{marginRight:0}).marginRight,10)||0)===0}if(bv.attachEvent){for(by in {submit:1,change:1,focusin:1}){bB="on"+by;bw=(bB in bv);if(!bw){bv.setAttribute(bB,"return;");bw=(typeof bv[bB]==="function")}bJ[by+"Bubbles"]=bw}}bD.removeChild(bv);bD=bG=bx=bA=bv=bE=null;b(function(){var bM,bU,bV,bT,bN,bO,bL,bS,bR,e,bP,bQ=av.getElementsByTagName("body")[0];if(!bQ){return}bL=1;bS="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";bR="visibility:hidden;border:0;";e="style='"+bS+"border:5px solid #000;padding:0;'";bP="
    ";bM=av.createElement("div");bM.style.cssText=bR+"width:0;height:0;position:static;top:0;margin-top:"+bL+"px";bQ.insertBefore(bM,bQ.firstChild);bv=av.createElement("div");bM.appendChild(bv);bv.innerHTML="
    t
    ";bz=bv.getElementsByTagName("td");bw=(bz[0].offsetHeight===0);bz[0].style.display="";bz[1].style.display="none";bJ.reliableHiddenOffsets=bw&&(bz[0].offsetHeight===0);bv.innerHTML="";bv.style.width=bv.style.paddingLeft="1px";b.boxModel=bJ.boxModel=bv.offsetWidth===2;if(typeof bv.style.zoom!=="undefined"){bv.style.display="inline";bv.style.zoom=1;bJ.inlineBlockNeedsLayout=(bv.offsetWidth===2);bv.style.display="";bv.innerHTML="
    ";bJ.shrinkWrapBlocks=(bv.offsetWidth!==2)}bv.style.cssText=bS+bR;bv.innerHTML=bP;bU=bv.firstChild;bV=bU.firstChild;bN=bU.nextSibling.firstChild.firstChild;bO={doesNotAddBorder:(bV.offsetTop!==5),doesAddBorderForTableAndCells:(bN.offsetTop===5)};bV.style.position="fixed";bV.style.top="20px";bO.fixedPosition=(bV.offsetTop===20||bV.offsetTop===15);bV.style.position=bV.style.top="";bU.style.overflow="hidden";bU.style.position="relative";bO.subtractsBorderForOverflowNotVisible=(bV.offsetTop===-5);bO.doesNotIncludeMarginInBodyOffset=(bQ.offsetTop!==bL);bQ.removeChild(bM);bv=bM=null;b.extend(bJ,bO)});return bJ})();var aS=/^(?:\{.*\}|\[.*\])$/,aA=/([A-Z])/g;b.extend({cache:{},uuid:0,expando:"jQuery"+(b.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},hasData:function(e){e=e.nodeType?b.cache[e[b.expando]]:e[b.expando];return !!e&&!S(e)},data:function(bx,bv,bz,by){if(!b.acceptData(bx)){return}var bG,bA,bD,bE=b.expando,bC=typeof bv==="string",bF=bx.nodeType,e=bF?b.cache:bx,bw=bF?bx[bE]:bx[bE]&&bE,bB=bv==="events";if((!bw||!e[bw]||(!bB&&!by&&!e[bw].data))&&bC&&bz===L){return}if(!bw){if(bF){bx[bE]=bw=++b.uuid}else{bw=bE}}if(!e[bw]){e[bw]={};if(!bF){e[bw].toJSON=b.noop}}if(typeof bv==="object"||typeof bv==="function"){if(by){e[bw]=b.extend(e[bw],bv)}else{e[bw].data=b.extend(e[bw].data,bv)}}bG=bA=e[bw];if(!by){if(!bA.data){bA.data={}}bA=bA.data}if(bz!==L){bA[b.camelCase(bv)]=bz}if(bB&&!bA[bv]){return bG.events}if(bC){bD=bA[bv];if(bD==null){bD=bA[b.camelCase(bv)]}}else{bD=bA}return bD},removeData:function(bx,bv,by){if(!b.acceptData(bx)){return}var bB,bA,bz,bC=b.expando,bD=bx.nodeType,e=bD?b.cache:bx,bw=bD?bx[bC]:bC;if(!e[bw]){return}if(bv){bB=by?e[bw]:e[bw].data;if(bB){if(!b.isArray(bv)){if(bv in bB){bv=[bv]}else{bv=b.camelCase(bv);if(bv in bB){bv=[bv]}else{bv=bv.split(" ")}}}for(bA=0,bz=bv.length;bA-1){return true}}return false},val:function(bx){var e,bv,by,bw=this[0];if(!arguments.length){if(bw){e=b.valHooks[bw.nodeName.toLowerCase()]||b.valHooks[bw.type];if(e&&"get" in e&&(bv=e.get(bw,"value"))!==L){return bv}bv=bw.value;return typeof bv==="string"?bv.replace(aU,""):bv==null?"":bv}return}by=b.isFunction(bx);return this.each(function(bA){var bz=b(this),bB;if(this.nodeType!==1){return}if(by){bB=bx.call(this,bA,bz.val())}else{bB=bx}if(bB==null){bB=""}else{if(typeof bB==="number"){bB+=""}else{if(b.isArray(bB)){bB=b.map(bB,function(bC){return bC==null?"":bC+""})}}}e=b.valHooks[this.nodeName.toLowerCase()]||b.valHooks[this.type];if(!e||!("set" in e)||e.set(this,bB,"value")===L){this.value=bB}})}});b.extend({valHooks:{option:{get:function(e){var bv=e.attributes.value;return !bv||bv.specified?e.value:e.text}},select:{get:function(e){var bA,bv,bz,bx,by=e.selectedIndex,bB=[],bC=e.options,bw=e.type==="select-one";if(by<0){return null}bv=bw?by:0;bz=bw?by+1:bC.length;for(;bv=0});if(!e.length){bv.selectedIndex=-1}return e}}},attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(bA,bx,bB,bz){var bw,e,by,bv=bA.nodeType;if(!bA||bv===3||bv===8||bv===2){return}if(bz&&bx in b.attrFn){return b(bA)[bx](bB)}if(typeof bA.getAttribute==="undefined"){return b.prop(bA,bx,bB)}by=bv!==1||!b.isXMLDoc(bA);if(by){bx=bx.toLowerCase();e=b.attrHooks[bx]||(ao.test(bx)?aY:be)}if(bB!==L){if(bB===null){b.removeAttr(bA,bx);return}else{if(e&&"set" in e&&by&&(bw=e.set(bA,bB,bx))!==L){return bw}else{bA.setAttribute(bx,""+bB);return bB}}}else{if(e&&"get" in e&&by&&(bw=e.get(bA,bx))!==null){return bw}else{bw=bA.getAttribute(bx);return bw===null?L:bw}}},removeAttr:function(bx,bz){var by,bA,bv,e,bw=0;if(bz&&bx.nodeType===1){bA=bz.toLowerCase().split(af);e=bA.length;for(;bw=0)}}})});var bd=/^(?:textarea|input|select)$/i,n=/^([^\.]*)?(?:\.(.+))?$/,J=/\bhover(\.\S+)?\b/,aO=/^key/,bf=/^(?:mouse|contextmenu)|click/,T=/^(?:focusinfocus|focusoutblur)$/,U=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,Y=function(e){var bv=U.exec(e);if(bv){bv[1]=(bv[1]||"").toLowerCase();bv[3]=bv[3]&&new RegExp("(?:^|\\s)"+bv[3]+"(?:\\s|$)")}return bv},j=function(bw,e){var bv=bw.attributes||{};return((!e[1]||bw.nodeName.toLowerCase()===e[1])&&(!e[2]||(bv.id||{}).value===e[2])&&(!e[3]||e[3].test((bv["class"]||{}).value)))},bt=function(e){return b.event.special.hover?e:e.replace(J,"mouseenter$1 mouseleave$1")};b.event={add:function(bx,bC,bJ,bA,by){var bD,bB,bK,bI,bH,bF,e,bG,bv,bz,bw,bE;if(bx.nodeType===3||bx.nodeType===8||!bC||!bJ||!(bD=b._data(bx))){return}if(bJ.handler){bv=bJ;bJ=bv.handler}if(!bJ.guid){bJ.guid=b.guid++}bK=bD.events;if(!bK){bD.events=bK={}}bB=bD.handle;if(!bB){bD.handle=bB=function(bL){return typeof b!=="undefined"&&(!bL||b.event.triggered!==bL.type)?b.event.dispatch.apply(bB.elem,arguments):L};bB.elem=bx}bC=b.trim(bt(bC)).split(" ");for(bI=0;bI=0){bG=bG.slice(0,-1);bw=true}if(bG.indexOf(".")>=0){bx=bG.split(".");bG=bx.shift();bx.sort()}if((!bA||b.event.customEvent[bG])&&!b.event.global[bG]){return}bv=typeof bv==="object"?bv[b.expando]?bv:new b.Event(bG,bv):new b.Event(bG);bv.type=bG;bv.isTrigger=true;bv.exclusive=bw;bv.namespace=bx.join(".");bv.namespace_re=bv.namespace?new RegExp("(^|\\.)"+bx.join("\\.(?:.*\\.)?")+"(\\.|$)"):null;by=bG.indexOf(":")<0?"on"+bG:"";if(!bA){e=b.cache;for(bC in e){if(e[bC].events&&e[bC].events[bG]){b.event.trigger(bv,bD,e[bC].handle.elem,true)}}return}bv.result=L;if(!bv.target){bv.target=bA}bD=bD!=null?b.makeArray(bD):[];bD.unshift(bv);bF=b.event.special[bG]||{};if(bF.trigger&&bF.trigger.apply(bA,bD)===false){return}bB=[[bA,bF.bindType||bG]];if(!bJ&&!bF.noBubble&&!b.isWindow(bA)){bI=bF.delegateType||bG;bH=T.test(bI+bG)?bA:bA.parentNode;bz=null;for(;bH;bH=bH.parentNode){bB.push([bH,bI]);bz=bH}if(bz&&bz===bA.ownerDocument){bB.push([bz.defaultView||bz.parentWindow||bb,bI])}}for(bC=0;bCbA){bH.push({elem:this,matches:bz.slice(bA)})}for(bC=0;bC0?this.on(e,null,bx,bw):this.trigger(e)};if(b.attrFn){b.attrFn[e]=true}if(aO.test(e)){b.event.fixHooks[e]=b.event.keyHooks}if(bf.test(e)){b.event.fixHooks[e]=b.event.mouseHooks}}); -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){var bH=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,bC="sizcache"+(Math.random()+"").replace(".",""),bI=0,bL=Object.prototype.toString,bB=false,bA=true,bK=/\\/g,bO=/\r\n/g,bQ=/\W/;[0,0].sort(function(){bA=false;return 0});var by=function(bV,e,bY,bZ){bY=bY||[];e=e||av;var b1=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!bV||typeof bV!=="string"){return bY}var bS,b3,b6,bR,b2,b5,b4,bX,bU=true,bT=by.isXML(e),bW=[],b0=bV;do{bH.exec("");bS=bH.exec(b0);if(bS){b0=bS[3];bW.push(bS[1]);if(bS[2]){bR=bS[3];break}}}while(bS);if(bW.length>1&&bD.exec(bV)){if(bW.length===2&&bE.relative[bW[0]]){b3=bM(bW[0]+bW[1],e,bZ)}else{b3=bE.relative[bW[0]]?[e]:by(bW.shift(),e);while(bW.length){bV=bW.shift();if(bE.relative[bV]){bV+=bW.shift()}b3=bM(bV,b3,bZ)}}}else{if(!bZ&&bW.length>1&&e.nodeType===9&&!bT&&bE.match.ID.test(bW[0])&&!bE.match.ID.test(bW[bW.length-1])){b2=by.find(bW.shift(),e,bT);e=b2.expr?by.filter(b2.expr,b2.set)[0]:b2.set[0]}if(e){b2=bZ?{expr:bW.pop(),set:bF(bZ)}:by.find(bW.pop(),bW.length===1&&(bW[0]==="~"||bW[0]==="+")&&e.parentNode?e.parentNode:e,bT);b3=b2.expr?by.filter(b2.expr,b2.set):b2.set;if(bW.length>0){b6=bF(b3)}else{bU=false}while(bW.length){b5=bW.pop();b4=b5;if(!bE.relative[b5]){b5=""}else{b4=bW.pop()}if(b4==null){b4=e}bE.relative[b5](b6,b4,bT)}}else{b6=bW=[]}}if(!b6){b6=b3}if(!b6){by.error(b5||bV)}if(bL.call(b6)==="[object Array]"){if(!bU){bY.push.apply(bY,b6)}else{if(e&&e.nodeType===1){for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&(b6[bX]===true||b6[bX].nodeType===1&&by.contains(e,b6[bX]))){bY.push(b3[bX])}}}else{for(bX=0;b6[bX]!=null;bX++){if(b6[bX]&&b6[bX].nodeType===1){bY.push(b3[bX])}}}}}else{bF(b6,bY)}if(bR){by(bR,b1,bY,bZ);by.uniqueSort(bY)}return bY};by.uniqueSort=function(bR){if(bJ){bB=bA;bR.sort(bJ);if(bB){for(var e=1;e0};by.find=function(bX,e,bY){var bW,bS,bU,bT,bV,bR;if(!bX){return[]}for(bS=0,bU=bE.order.length;bS":function(bW,bR){var bV,bU=typeof bR==="string",bS=0,e=bW.length;if(bU&&!bQ.test(bR)){bR=bR.toLowerCase();for(;bS=0)){if(!bS){e.push(bV)}}else{if(bS){bR[bU]=false}}}}return false},ID:function(e){return e[1].replace(bK,"")},TAG:function(bR,e){return bR[1].replace(bK,"").toLowerCase()},CHILD:function(e){if(e[1]==="nth"){if(!e[2]){by.error(e[0])}e[2]=e[2].replace(/^\+|\s*/g,"");var bR=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(bR[1]+(bR[2]||1))-0;e[3]=bR[3]-0}else{if(e[2]){by.error(e[0])}}e[0]=bI++;return e},ATTR:function(bU,bR,bS,e,bV,bW){var bT=bU[1]=bU[1].replace(bK,"");if(!bW&&bE.attrMap[bT]){bU[1]=bE.attrMap[bT]}bU[4]=(bU[4]||bU[5]||"").replace(bK,"");if(bU[2]==="~="){bU[4]=" "+bU[4]+" "}return bU},PSEUDO:function(bU,bR,bS,e,bV){if(bU[1]==="not"){if((bH.exec(bU[3])||"").length>1||/^\w/.test(bU[3])){bU[3]=by(bU[3],null,null,bR)}else{var bT=by.filter(bU[3],bR,bS,true^bV);if(!bS){e.push.apply(e,bT)}return false}}else{if(bE.match.POS.test(bU[0])||bE.match.CHILD.test(bU[0])){return true}}return bU},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){if(e.parentNode){e.parentNode.selectedIndex}return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(bS,bR,e){return !!by(e[3],bS).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(bS){var e=bS.getAttribute("type"),bR=bS.type;return bS.nodeName.toLowerCase()==="input"&&"text"===bR&&(e===bR||e===null)},radio:function(e){return e.nodeName.toLowerCase()==="input"&&"radio"===e.type},checkbox:function(e){return e.nodeName.toLowerCase()==="input"&&"checkbox"===e.type},file:function(e){return e.nodeName.toLowerCase()==="input"&&"file"===e.type},password:function(e){return e.nodeName.toLowerCase()==="input"&&"password"===e.type},submit:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"submit"===bR.type},image:function(e){return e.nodeName.toLowerCase()==="input"&&"image"===e.type},reset:function(bR){var e=bR.nodeName.toLowerCase();return(e==="input"||e==="button")&&"reset"===bR.type},button:function(bR){var e=bR.nodeName.toLowerCase();return e==="input"&&"button"===bR.type||e==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(bR,e){return e===0},last:function(bS,bR,e,bT){return bR===bT.length-1},even:function(bR,e){return e%2===0},odd:function(bR,e){return e%2===1},lt:function(bS,bR,e){return bRe[3]-0},nth:function(bS,bR,e){return e[3]-0===bR},eq:function(bS,bR,e){return e[3]-0===bR}},filter:{PSEUDO:function(bS,bX,bW,bY){var e=bX[1],bR=bE.filters[e];if(bR){return bR(bS,bW,bX,bY)}else{if(e==="contains"){return(bS.textContent||bS.innerText||bw([bS])||"").indexOf(bX[3])>=0}else{if(e==="not"){var bT=bX[3];for(var bV=0,bU=bT.length;bV=0)}}},ID:function(bR,e){return bR.nodeType===1&&bR.getAttribute("id")===e},TAG:function(bR,e){return(e==="*"&&bR.nodeType===1)||!!bR.nodeName&&bR.nodeName.toLowerCase()===e},CLASS:function(bR,e){return(" "+(bR.className||bR.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(bV,bT){var bS=bT[1],e=by.attr?by.attr(bV,bS):bE.attrHandle[bS]?bE.attrHandle[bS](bV):bV[bS]!=null?bV[bS]:bV.getAttribute(bS),bW=e+"",bU=bT[2],bR=bT[4];return e==null?bU==="!=":!bU&&by.attr?e!=null:bU==="="?bW===bR:bU==="*="?bW.indexOf(bR)>=0:bU==="~="?(" "+bW+" ").indexOf(bR)>=0:!bR?bW&&e!==false:bU==="!="?bW!==bR:bU==="^="?bW.indexOf(bR)===0:bU==="$="?bW.substr(bW.length-bR.length)===bR:bU==="|="?bW===bR||bW.substr(0,bR.length+1)===bR+"-":false},POS:function(bU,bR,bS,bV){var e=bR[2],bT=bE.setFilters[e];if(bT){return bT(bU,bS,bR,bV)}}}};var bD=bE.match.POS,bx=function(bR,e){return"\\"+(e-0+1)};for(var bz in bE.match){bE.match[bz]=new RegExp(bE.match[bz].source+(/(?![^\[]*\])(?![^\(]*\))/.source));bE.leftMatch[bz]=new RegExp(/(^(?:.|\r|\n)*?)/.source+bE.match[bz].source.replace(/\\(\d+)/g,bx))}var bF=function(bR,e){bR=Array.prototype.slice.call(bR,0);if(e){e.push.apply(e,bR);return e}return bR};try{Array.prototype.slice.call(av.documentElement.childNodes,0)[0].nodeType}catch(bP){bF=function(bU,bT){var bS=0,bR=bT||[];if(bL.call(bU)==="[object Array]"){Array.prototype.push.apply(bR,bU)}else{if(typeof bU.length==="number"){for(var e=bU.length;bS";e.insertBefore(bR,e.firstChild);if(av.getElementById(bS)){bE.find.ID=function(bU,bV,bW){if(typeof bV.getElementById!=="undefined"&&!bW){var bT=bV.getElementById(bU[1]);return bT?bT.id===bU[1]||typeof bT.getAttributeNode!=="undefined"&&bT.getAttributeNode("id").nodeValue===bU[1]?[bT]:L:[]}};bE.filter.ID=function(bV,bT){var bU=typeof bV.getAttributeNode!=="undefined"&&bV.getAttributeNode("id");return bV.nodeType===1&&bU&&bU.nodeValue===bT}}e.removeChild(bR);e=bR=null})();(function(){var e=av.createElement("div");e.appendChild(av.createComment(""));if(e.getElementsByTagName("*").length>0){bE.find.TAG=function(bR,bV){var bU=bV.getElementsByTagName(bR[1]);if(bR[1]==="*"){var bT=[];for(var bS=0;bU[bS];bS++){if(bU[bS].nodeType===1){bT.push(bU[bS])}}bU=bT}return bU}}e.innerHTML="";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){bE.attrHandle.href=function(bR){return bR.getAttribute("href",2)}}e=null})();if(av.querySelectorAll){(function(){var e=by,bT=av.createElement("div"),bS="__sizzle__";bT.innerHTML="

    ";if(bT.querySelectorAll&&bT.querySelectorAll(".TEST").length===0){return}by=function(b4,bV,bZ,b3){bV=bV||av;if(!b3&&!by.isXML(bV)){var b2=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b4);if(b2&&(bV.nodeType===1||bV.nodeType===9)){if(b2[1]){return bF(bV.getElementsByTagName(b4),bZ)}else{if(b2[2]&&bE.find.CLASS&&bV.getElementsByClassName){return bF(bV.getElementsByClassName(b2[2]),bZ)}}}if(bV.nodeType===9){if(b4==="body"&&bV.body){return bF([bV.body],bZ)}else{if(b2&&b2[3]){var bY=bV.getElementById(b2[3]);if(bY&&bY.parentNode){if(bY.id===b2[3]){return bF([bY],bZ)}}else{return bF([],bZ)}}}try{return bF(bV.querySelectorAll(b4),bZ)}catch(b0){}}else{if(bV.nodeType===1&&bV.nodeName.toLowerCase()!=="object"){var bW=bV,bX=bV.getAttribute("id"),bU=bX||bS,b6=bV.parentNode,b5=/^\s*[+~]/.test(b4);if(!bX){bV.setAttribute("id",bU)}else{bU=bU.replace(/'/g,"\\$&")}if(b5&&b6){bV=bV.parentNode}try{if(!b5||b6){return bF(bV.querySelectorAll("[id='"+bU+"'] "+b4),bZ)}}catch(b1){}finally{if(!bX){bW.removeAttribute("id")}}}}}return e(b4,bV,bZ,b3)};for(var bR in e){by[bR]=e[bR]}bT=null})()}(function(){var e=av.documentElement,bS=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(bS){var bU=!bS.call(av.createElement("div"),"div"),bR=false;try{bS.call(av.documentElement,"[test!='']:sizzle")}catch(bT){bR=true}by.matchesSelector=function(bW,bY){bY=bY.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!by.isXML(bW)){try{if(bR||!bE.match.PSEUDO.test(bY)&&!/!=/.test(bY)){var bV=bS.call(bW,bY);if(bV||!bU||bW.document&&bW.document.nodeType!==11){return bV}}}catch(bX){}}return by(bY,null,null,[bW]).length>0}}})();(function(){var e=av.createElement("div");e.innerHTML="
    ";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}bE.order.splice(1,0,"CLASS");bE.find.CLASS=function(bR,bS,bT){if(typeof bS.getElementsByClassName!=="undefined"&&!bT){return bS.getElementsByClassName(bR[1])}};e=null})();function bv(bR,bW,bV,bZ,bX,bY){for(var bT=0,bS=bZ.length;bT0){bU=e;break}}}e=e[bR]}bZ[bT]=bU}}}if(av.documentElement.contains){by.contains=function(bR,e){return bR!==e&&(bR.contains?bR.contains(e):true)}}else{if(av.documentElement.compareDocumentPosition){by.contains=function(bR,e){return !!(bR.compareDocumentPosition(e)&16)}}else{by.contains=function(){return false}}}by.isXML=function(e){var bR=(e?e.ownerDocument||e:0).documentElement;return bR?bR.nodeName!=="HTML":false};var bM=function(bS,e,bW){var bV,bX=[],bU="",bY=e.nodeType?[e]:e;while((bV=bE.match.PSEUDO.exec(bS))){bU+=bV[0];bS=bS.replace(bE.match.PSEUDO,"")}bS=bE.relative[bS]?bS+"*":bS;for(var bT=0,bR=bY.length;bT0){for(bB=bA;bB=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(by,bx){var bv=[],bw,e,bz=this[0];if(b.isArray(by)){var bB=1;while(bz&&bz.ownerDocument&&bz!==bx){for(bw=0;bw-1:b.find.matchesSelector(bz,by)){bv.push(bz);break}else{bz=bz.parentNode;if(!bz||!bz.ownerDocument||bz===bx||bz.nodeType===11){break}}}}bv=bv.length>1?b.unique(bv):bv;return this.pushStack(bv,"closest",by)},index:function(e){if(!e){return(this[0]&&this[0].parentNode)?this.prevAll().length:-1}if(typeof e==="string"){return b.inArray(this[0],b(e))}return b.inArray(e.jquery?e[0]:e,this)},add:function(e,bv){var bx=typeof e==="string"?b(e,bv):b.makeArray(e&&e.nodeType?[e]:e),bw=b.merge(this.get(),bx);return this.pushStack(C(bx[0])||C(bw[0])?bw:b.unique(bw))},andSelf:function(){return this.add(this.prevObject)}});function C(e){return !e||!e.parentNode||e.parentNode.nodeType===11}b.each({parent:function(bv){var e=bv.parentNode;return e&&e.nodeType!==11?e:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(bv,e,bw){return b.dir(bv,"parentNode",bw)},next:function(e){return b.nth(e,2,"nextSibling")},prev:function(e){return b.nth(e,2,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(bv,e,bw){return b.dir(bv,"nextSibling",bw)},prevUntil:function(bv,e,bw){return b.dir(bv,"previousSibling",bw)},siblings:function(e){return b.sibling(e.parentNode.firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.makeArray(e.childNodes)}},function(e,bv){b.fn[e]=function(by,bw){var bx=b.map(this,bv,by);if(!ab.test(e)){bw=by}if(bw&&typeof bw==="string"){bx=b.filter(bw,bx)}bx=this.length>1&&!ay[e]?b.unique(bx):bx;if((this.length>1||a9.test(bw))&&aq.test(e)){bx=bx.reverse()}return this.pushStack(bx,e,P.call(arguments).join(","))}});b.extend({filter:function(bw,e,bv){if(bv){bw=":not("+bw+")"}return e.length===1?b.find.matchesSelector(e[0],bw)?[e[0]]:[]:b.find.matches(bw,e)},dir:function(bw,bv,by){var e=[],bx=bw[bv];while(bx&&bx.nodeType!==9&&(by===L||bx.nodeType!==1||!b(bx).is(by))){if(bx.nodeType===1){e.push(bx)}bx=bx[bv]}return e},nth:function(by,e,bw,bx){e=e||1;var bv=0;for(;by;by=by[bw]){if(by.nodeType===1&&++bv===e){break}}return by},sibling:function(bw,bv){var e=[];for(;bw;bw=bw.nextSibling){if(bw.nodeType===1&&bw!==bv){e.push(bw)}}return e}});function aG(bx,bw,e){bw=bw||0;if(b.isFunction(bw)){return b.grep(bx,function(bz,by){var bA=!!bw.call(bz,by,bz);return bA===e})}else{if(bw.nodeType){return b.grep(bx,function(bz,by){return(bz===bw)===e})}else{if(typeof bw==="string"){var bv=b.grep(bx,function(by){return by.nodeType===1});if(bp.test(bw)){return b.filter(bw,bv,!e)}else{bw=b.filter(bw,bv)}}}}return b.grep(bx,function(bz,by){return(b.inArray(bz,bw)>=0)===e})}function a(e){var bw=aR.split("|"),bv=e.createDocumentFragment();if(bv.createElement){while(bw.length){bv.createElement(bw.pop())}}return bv}var aR="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ag=/ jQuery\d+="(?:\d+|null)"/g,ar=/^\s+/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,d=/<([\w:]+)/,w=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},ac=a(av);ax.optgroup=ax.option;ax.tbody=ax.tfoot=ax.colgroup=ax.caption=ax.thead;ax.th=ax.td;if(!b.support.htmlSerialize){ax._default=[1,"div
    ","
    "]}b.fn.extend({text:function(e){if(b.isFunction(e)){return this.each(function(bw){var bv=b(this);bv.text(e.call(this,bw,bv.text()))})}if(typeof e!=="object"&&e!==L){return this.empty().append((this[0]&&this[0].ownerDocument||av).createTextNode(e))}return b.text(this)},wrapAll:function(e){if(b.isFunction(e)){return this.each(function(bw){b(this).wrapAll(e.call(this,bw))})}if(this[0]){var bv=b(e,this[0].ownerDocument).eq(0).clone(true);if(this[0].parentNode){bv.insertBefore(this[0])}bv.map(function(){var bw=this;while(bw.firstChild&&bw.firstChild.nodeType===1){bw=bw.firstChild}return bw}).append(this)}return this},wrapInner:function(e){if(b.isFunction(e)){return this.each(function(bv){b(this).wrapInner(e.call(this,bv))})}return this.each(function(){var bv=b(this),bw=bv.contents();if(bw.length){bw.wrapAll(e)}else{bv.append(e)}})},wrap:function(e){var bv=b.isFunction(e);return this.each(function(bw){b(this).wrapAll(bv?e.call(this,bw):e)})},unwrap:function(){return this.parent().each(function(){if(!b.nodeName(this,"body")){b(this).replaceWith(this.childNodes)}}).end()},append:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.appendChild(e)}})},prepend:function(){return this.domManip(arguments,true,function(e){if(this.nodeType===1){this.insertBefore(e,this.firstChild)}})},before:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this)})}else{if(arguments.length){var e=b.clean(arguments);e.push.apply(e,this.toArray());return this.pushStack(e,"before",arguments)}}},after:function(){if(this[0]&&this[0].parentNode){return this.domManip(arguments,false,function(bv){this.parentNode.insertBefore(bv,this.nextSibling)})}else{if(arguments.length){var e=this.pushStack(this,"after",arguments);e.push.apply(e,b.clean(arguments));return e}}},remove:function(e,bx){for(var bv=0,bw;(bw=this[bv])!=null;bv++){if(!e||b.filter(e,[bw]).length){if(!bx&&bw.nodeType===1){b.cleanData(bw.getElementsByTagName("*"));b.cleanData([bw])}if(bw.parentNode){bw.parentNode.removeChild(bw)}}}return this},empty:function(){for(var e=0,bv;(bv=this[e])!=null;e++){if(bv.nodeType===1){b.cleanData(bv.getElementsByTagName("*"))}while(bv.firstChild){bv.removeChild(bv.firstChild)}}return this},clone:function(bv,e){bv=bv==null?false:bv;e=e==null?bv:e;return this.map(function(){return b.clone(this,bv,e)})},html:function(bx){if(bx===L){return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(ag,""):null}else{if(typeof bx==="string"&&!ae.test(bx)&&(b.support.leadingWhitespace||!ar.test(bx))&&!ax[(d.exec(bx)||["",""])[1].toLowerCase()]){bx=bx.replace(R,"<$1>");try{for(var bw=0,bv=this.length;bw1&&bw0?this.clone(true):this).get();b(bC[bA])[bv](by);bz=bz.concat(by)}return this.pushStack(bz,e,bC.selector)}}});function bg(e){if(typeof e.getElementsByTagName!=="undefined"){return e.getElementsByTagName("*")}else{if(typeof e.querySelectorAll!=="undefined"){return e.querySelectorAll("*")}else{return[]}}}function az(e){if(e.type==="checkbox"||e.type==="radio"){e.defaultChecked=e.checked}}function E(e){var bv=(e.nodeName||"").toLowerCase();if(bv==="input"){az(e)}else{if(bv!=="script"&&typeof e.getElementsByTagName!=="undefined"){b.grep(e.getElementsByTagName("input"),az)}}}function al(e){var bv=av.createElement("div");ac.appendChild(bv);bv.innerHTML=e.outerHTML;return bv.firstChild}b.extend({clone:function(by,bA,bw){var e,bv,bx,bz=b.support.html5Clone||!ah.test("<"+by.nodeName)?by.cloneNode(true):al(by);if((!b.support.noCloneEvent||!b.support.noCloneChecked)&&(by.nodeType===1||by.nodeType===11)&&!b.isXMLDoc(by)){ai(by,bz);e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){if(bv[bx]){ai(e[bx],bv[bx])}}}if(bA){t(by,bz);if(bw){e=bg(by);bv=bg(bz);for(bx=0;e[bx];++bx){t(e[bx],bv[bx])}}}e=bv=null;return bz},clean:function(bw,by,bH,bA){var bF;by=by||av;if(typeof by.createElement==="undefined"){by=by.ownerDocument||by[0]&&by[0].ownerDocument||av}var bI=[],bB;for(var bE=0,bz;(bz=bw[bE])!=null;bE++){if(typeof bz==="number"){bz+=""}if(!bz){continue}if(typeof bz==="string"){if(!W.test(bz)){bz=by.createTextNode(bz)}else{bz=bz.replace(R,"<$1>");var bK=(d.exec(bz)||["",""])[1].toLowerCase(),bx=ax[bK]||ax._default,bD=bx[0],bv=by.createElement("div");if(by===av){ac.appendChild(bv)}else{a(by).appendChild(bv)}bv.innerHTML=bx[1]+bz+bx[2];while(bD--){bv=bv.lastChild}if(!b.support.tbody){var e=w.test(bz),bC=bK==="table"&&!e?bv.firstChild&&bv.firstChild.childNodes:bx[1]===""&&!e?bv.childNodes:[];for(bB=bC.length-1;bB>=0;--bB){if(b.nodeName(bC[bB],"tbody")&&!bC[bB].childNodes.length){bC[bB].parentNode.removeChild(bC[bB])}}}if(!b.support.leadingWhitespace&&ar.test(bz)){bv.insertBefore(by.createTextNode(ar.exec(bz)[0]),bv.firstChild)}bz=bv.childNodes}}var bG;if(!b.support.appendChecked){if(bz[0]&&typeof(bG=bz.length)==="number"){for(bB=0;bB=0){return bx+"px"}}else{return bx}}}});if(!b.support.opacity){b.cssHooks.opacity={get:function(bv,e){return au.test((e&&bv.currentStyle?bv.currentStyle.filter:bv.style.filter)||"")?(parseFloat(RegExp.$1)/100)+"":e?"1":""},set:function(by,bz){var bx=by.style,bv=by.currentStyle,e=b.isNumeric(bz)?"alpha(opacity="+bz*100+")":"",bw=bv&&bv.filter||bx.filter||"";bx.zoom=1;if(bz>=1&&b.trim(bw.replace(ak,""))===""){bx.removeAttribute("filter");if(bv&&!bv.filter){return}}bx.filter=ak.test(bw)?bw.replace(ak,e):bw+" "+e}}}b(function(){if(!b.support.reliableMarginRight){b.cssHooks.marginRight={get:function(bw,bv){var e;b.swap(bw,{display:"inline-block"},function(){if(bv){e=Z(bw,"margin-right","marginRight")}else{e=bw.style.marginRight}});return e}}}});if(av.defaultView&&av.defaultView.getComputedStyle){aI=function(by,bw){var bv,bx,e;bw=bw.replace(z,"-$1").toLowerCase();if((bx=by.ownerDocument.defaultView)&&(e=bx.getComputedStyle(by,null))){bv=e.getPropertyValue(bw);if(bv===""&&!b.contains(by.ownerDocument.documentElement,by)){bv=b.style(by,bw)}}return bv}}if(av.documentElement.currentStyle){aX=function(bz,bw){var bA,e,by,bv=bz.currentStyle&&bz.currentStyle[bw],bx=bz.style;if(bv===null&&bx&&(by=bx[bw])){bv=by}if(!bc.test(bv)&&bn.test(bv)){bA=bx.left;e=bz.runtimeStyle&&bz.runtimeStyle.left;if(e){bz.runtimeStyle.left=bz.currentStyle.left}bx.left=bw==="fontSize"?"1em":(bv||0);bv=bx.pixelLeft+"px";bx.left=bA;if(e){bz.runtimeStyle.left=e}}return bv===""?"auto":bv}}Z=aI||aX;function p(by,bw,bv){var bA=bw==="width"?by.offsetWidth:by.offsetHeight,bz=bw==="width"?an:a1,bx=0,e=bz.length;if(bA>0){if(bv!=="border"){for(;bx)<[^<]*)*<\/script>/gi,q=/^(?:select|textarea)/i,h=/\s+/,br=/([?&])_=[^&]*/,K=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,A=b.fn.load,aa={},r={},aE,s,aV=["*/"]+["*"];try{aE=bl.href}catch(aw){aE=av.createElement("a");aE.href="";aE=aE.href}s=K.exec(aE.toLowerCase())||[];function f(e){return function(by,bA){if(typeof by!=="string"){bA=by;by="*"}if(b.isFunction(bA)){var bx=by.toLowerCase().split(h),bw=0,bz=bx.length,bv,bB,bC;for(;bw=0){var e=bw.slice(by,bw.length);bw=bw.slice(0,by)}var bx="GET";if(bz){if(b.isFunction(bz)){bA=bz;bz=L}else{if(typeof bz==="object"){bz=b.param(bz,b.ajaxSettings.traditional);bx="POST"}}}var bv=this;b.ajax({url:bw,type:bx,dataType:"html",data:bz,complete:function(bC,bB,bD){bD=bC.responseText;if(bC.isResolved()){bC.done(function(bE){bD=bE});bv.html(e?b("
    ").append(bD.replace(a6,"")).find(e):bD)}if(bA){bv.each(bA,[bD,bB,bC])}}});return this},serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?b.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||q.test(this.nodeName)||aZ.test(this.type))}).map(function(e,bv){var bw=b(this).val();return bw==null?null:b.isArray(bw)?b.map(bw,function(by,bx){return{name:bv.name,value:by.replace(bs,"\r\n")}}):{name:bv.name,value:bw.replace(bs,"\r\n")}}).get()}});b.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,bv){b.fn[bv]=function(bw){return this.on(bv,bw)}});b.each(["get","post"],function(e,bv){b[bv]=function(bw,by,bz,bx){if(b.isFunction(by)){bx=bx||bz;bz=by;by=L}return b.ajax({type:bv,url:bw,data:by,success:bz,dataType:bx})}});b.extend({getScript:function(e,bv){return b.get(e,L,bv,"script")},getJSON:function(e,bv,bw){return b.get(e,bv,bw,"json")},ajaxSetup:function(bv,e){if(e){am(bv,b.ajaxSettings)}else{e=bv;bv=b.ajaxSettings}am(bv,e);return bv},ajaxSettings:{url:aE,isLocal:aM.test(s[1]),global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":aV},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":bb.String,"text html":true,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{context:true,url:true}},ajaxPrefilter:f(aa),ajaxTransport:f(r),ajax:function(bz,bx){if(typeof bz==="object"){bx=bz;bz=L}bx=bx||{};var bD=b.ajaxSetup({},bx),bS=bD.context||bD,bG=bS!==bD&&(bS.nodeType||bS instanceof b)?b(bS):b.event,bR=b.Deferred(),bN=b.Callbacks("once memory"),bB=bD.statusCode||{},bC,bH={},bO={},bQ,by,bL,bE,bI,bA=0,bw,bK,bJ={readyState:0,setRequestHeader:function(bT,bU){if(!bA){var e=bT.toLowerCase();bT=bO[e]=bO[e]||bT;bH[bT]=bU}return this},getAllResponseHeaders:function(){return bA===2?bQ:null},getResponseHeader:function(bT){var e;if(bA===2){if(!by){by={};while((e=aD.exec(bQ))){by[e[1].toLowerCase()]=e[2]}}e=by[bT.toLowerCase()]}return e===L?null:e},overrideMimeType:function(e){if(!bA){bD.mimeType=e}return this},abort:function(e){e=e||"abort";if(bL){bL.abort(e)}bF(0,e);return this}};function bF(bZ,bU,b0,bW){if(bA===2){return}bA=2;if(bE){clearTimeout(bE)}bL=L;bQ=bW||"";bJ.readyState=bZ>0?4:0;var bT,b4,b3,bX=bU,bY=b0?bj(bD,bJ,b0):L,bV,b2;if(bZ>=200&&bZ<300||bZ===304){if(bD.ifModified){if((bV=bJ.getResponseHeader("Last-Modified"))){b.lastModified[bC]=bV}if((b2=bJ.getResponseHeader("Etag"))){b.etag[bC]=b2}}if(bZ===304){bX="notmodified";bT=true}else{try{b4=G(bD,bY);bX="success";bT=true}catch(b1){bX="parsererror";b3=b1}}}else{b3=bX;if(!bX||bZ){bX="error";if(bZ<0){bZ=0}}}bJ.status=bZ;bJ.statusText=""+(bU||bX);if(bT){bR.resolveWith(bS,[b4,bX,bJ])}else{bR.rejectWith(bS,[bJ,bX,b3])}bJ.statusCode(bB);bB=L;if(bw){bG.trigger("ajax"+(bT?"Success":"Error"),[bJ,bD,bT?b4:b3])}bN.fireWith(bS,[bJ,bX]);if(bw){bG.trigger("ajaxComplete",[bJ,bD]);if(!(--b.active)){b.event.trigger("ajaxStop")}}}bR.promise(bJ);bJ.success=bJ.done;bJ.error=bJ.fail;bJ.complete=bN.add;bJ.statusCode=function(bT){if(bT){var e;if(bA<2){for(e in bT){bB[e]=[bB[e],bT[e]]}}else{e=bT[bJ.status];bJ.then(e,e)}}return this};bD.url=((bz||bD.url)+"").replace(bq,"").replace(c,s[1]+"//");bD.dataTypes=b.trim(bD.dataType||"*").toLowerCase().split(h);if(bD.crossDomain==null){bI=K.exec(bD.url.toLowerCase());bD.crossDomain=!!(bI&&(bI[1]!=s[1]||bI[2]!=s[2]||(bI[3]||(bI[1]==="http:"?80:443))!=(s[3]||(s[1]==="http:"?80:443))))}if(bD.data&&bD.processData&&typeof bD.data!=="string"){bD.data=b.param(bD.data,bD.traditional)}aW(aa,bD,bx,bJ);if(bA===2){return false}bw=bD.global;bD.type=bD.type.toUpperCase();bD.hasContent=!aQ.test(bD.type);if(bw&&b.active++===0){b.event.trigger("ajaxStart")}if(!bD.hasContent){if(bD.data){bD.url+=(M.test(bD.url)?"&":"?")+bD.data;delete bD.data}bC=bD.url;if(bD.cache===false){var bv=b.now(),bP=bD.url.replace(br,"$1_="+bv);bD.url=bP+((bP===bD.url)?(M.test(bD.url)?"&":"?")+"_="+bv:"")}}if(bD.data&&bD.hasContent&&bD.contentType!==false||bx.contentType){bJ.setRequestHeader("Content-Type",bD.contentType)}if(bD.ifModified){bC=bC||bD.url;if(b.lastModified[bC]){bJ.setRequestHeader("If-Modified-Since",b.lastModified[bC])}if(b.etag[bC]){bJ.setRequestHeader("If-None-Match",b.etag[bC])}}bJ.setRequestHeader("Accept",bD.dataTypes[0]&&bD.accepts[bD.dataTypes[0]]?bD.accepts[bD.dataTypes[0]]+(bD.dataTypes[0]!=="*"?", "+aV+"; q=0.01":""):bD.accepts["*"]);for(bK in bD.headers){bJ.setRequestHeader(bK,bD.headers[bK])}if(bD.beforeSend&&(bD.beforeSend.call(bS,bJ,bD)===false||bA===2)){bJ.abort();return false}for(bK in {success:1,error:1,complete:1}){bJ[bK](bD[bK])}bL=aW(r,bD,bx,bJ);if(!bL){bF(-1,"No Transport")}else{bJ.readyState=1;if(bw){bG.trigger("ajaxSend",[bJ,bD])}if(bD.async&&bD.timeout>0){bE=setTimeout(function(){bJ.abort("timeout")},bD.timeout)}try{bA=1;bL.send(bH,bF)}catch(bM){if(bA<2){bF(-1,bM)}else{throw bM}}}return bJ},param:function(e,bw){var bv=[],by=function(bz,bA){bA=b.isFunction(bA)?bA():bA;bv[bv.length]=encodeURIComponent(bz)+"="+encodeURIComponent(bA)};if(bw===L){bw=b.ajaxSettings.traditional}if(b.isArray(e)||(e.jquery&&!b.isPlainObject(e))){b.each(e,function(){by(this.name,this.value)})}else{for(var bx in e){v(bx,e[bx],bw,by)}}return bv.join("&").replace(k,"+")}});function v(bw,by,bv,bx){if(b.isArray(by)){b.each(by,function(bA,bz){if(bv||ap.test(bw)){bx(bw,bz)}else{v(bw+"["+(typeof bz==="object"||b.isArray(bz)?bA:"")+"]",bz,bv,bx)}})}else{if(!bv&&by!=null&&typeof by==="object"){for(var e in by){v(bw+"["+e+"]",by[e],bv,bx)}}else{bx(bw,by)}}}b.extend({active:0,lastModified:{},etag:{}});function bj(bD,bC,bz){var bv=bD.contents,bB=bD.dataTypes,bw=bD.responseFields,by,bA,bx,e;for(bA in bw){if(bA in bz){bC[bw[bA]]=bz[bA]}}while(bB[0]==="*"){bB.shift();if(by===L){by=bD.mimeType||bC.getResponseHeader("content-type")}}if(by){for(bA in bv){if(bv[bA]&&bv[bA].test(by)){bB.unshift(bA);break}}}if(bB[0] in bz){bx=bB[0]}else{for(bA in bz){if(!bB[0]||bD.converters[bA+" "+bB[0]]){bx=bA;break}if(!e){e=bA}}bx=bx||e}if(bx){if(bx!==bB[0]){bB.unshift(bx)}return bz[bx]}}function G(bH,bz){if(bH.dataFilter){bz=bH.dataFilter(bz,bH.dataType)}var bD=bH.dataTypes,bG={},bA,bE,bw=bD.length,bB,bC=bD[0],bx,by,bF,bv,e;for(bA=1;bA=bw.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();bw.animatedProperties[this.prop]=true;for(bA in bw.animatedProperties){if(bw.animatedProperties[bA]!==true){e=false}}if(e){if(bw.overflow!=null&&!b.support.shrinkWrapBlocks){b.each(["","X","Y"],function(bC,bD){bz.style["overflow"+bD]=bw.overflow[bC]})}if(bw.hide){b(bz).hide()}if(bw.hide||bw.show){for(bA in bw.animatedProperties){b.style(bz,bA,bw.orig[bA]);b.removeData(bz,"fxshow"+bA,true);b.removeData(bz,"toggle"+bA,true)}}bv=bw.complete;if(bv){bw.complete=false;bv.call(bz)}}return false}else{if(bw.duration==Infinity){this.now=bx}else{bB=bx-this.startTime;this.state=bB/bw.duration;this.pos=b.easing[bw.animatedProperties[this.prop]](this.state,bB,0,1,bw.duration);this.now=this.start+((this.end-this.start)*this.pos)}this.update()}return true}};b.extend(b.fx,{tick:function(){var bw,bv=b.timers,e=0;for(;e").appendTo(e),bw=bv.css("display");bv.remove();if(bw==="none"||bw===""){if(!a8){a8=av.createElement("iframe");a8.frameBorder=a8.width=a8.height=0}e.appendChild(a8);if(!m||!a8.createElement){m=(a8.contentWindow||a8.contentDocument).document;m.write((av.compatMode==="CSS1Compat"?"":"")+"");m.close()}bv=m.createElement(bx);m.body.appendChild(bv);bw=b.css(bv,"display");e.removeChild(a8)}Q[bx]=bw}return Q[bx]}var V=/^t(?:able|d|h)$/i,ad=/^(?:body|html)$/i;if("getBoundingClientRect" in av.documentElement){b.fn.offset=function(bI){var by=this[0],bB;if(bI){return this.each(function(e){b.offset.setOffset(this,bI,e)})}if(!by||!by.ownerDocument){return null}if(by===by.ownerDocument.body){return b.offset.bodyOffset(by)}try{bB=by.getBoundingClientRect()}catch(bF){}var bH=by.ownerDocument,bw=bH.documentElement;if(!bB||!b.contains(bw,by)){return bB?{top:bB.top,left:bB.left}:{top:0,left:0}}var bC=bH.body,bD=aK(bH),bA=bw.clientTop||bC.clientTop||0,bE=bw.clientLeft||bC.clientLeft||0,bv=bD.pageYOffset||b.support.boxModel&&bw.scrollTop||bC.scrollTop,bz=bD.pageXOffset||b.support.boxModel&&bw.scrollLeft||bC.scrollLeft,bG=bB.top+bv-bA,bx=bB.left+bz-bE;return{top:bG,left:bx}}}else{b.fn.offset=function(bF){var bz=this[0];if(bF){return this.each(function(bG){b.offset.setOffset(this,bF,bG)})}if(!bz||!bz.ownerDocument){return null}if(bz===bz.ownerDocument.body){return b.offset.bodyOffset(bz)}var bC,bw=bz.offsetParent,bv=bz,bE=bz.ownerDocument,bx=bE.documentElement,bA=bE.body,bB=bE.defaultView,e=bB?bB.getComputedStyle(bz,null):bz.currentStyle,bD=bz.offsetTop,by=bz.offsetLeft;while((bz=bz.parentNode)&&bz!==bA&&bz!==bx){if(b.support.fixedPosition&&e.position==="fixed"){break}bC=bB?bB.getComputedStyle(bz,null):bz.currentStyle;bD-=bz.scrollTop;by-=bz.scrollLeft;if(bz===bw){bD+=bz.offsetTop;by+=bz.offsetLeft;if(b.support.doesNotAddBorder&&!(b.support.doesAddBorderForTableAndCells&&V.test(bz.nodeName))){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}bv=bw;bw=bz.offsetParent}if(b.support.subtractsBorderForOverflowNotVisible&&bC.overflow!=="visible"){bD+=parseFloat(bC.borderTopWidth)||0;by+=parseFloat(bC.borderLeftWidth)||0}e=bC}if(e.position==="relative"||e.position==="static"){bD+=bA.offsetTop;by+=bA.offsetLeft}if(b.support.fixedPosition&&e.position==="fixed"){bD+=Math.max(bx.scrollTop,bA.scrollTop);by+=Math.max(bx.scrollLeft,bA.scrollLeft)}return{top:bD,left:by}}}b.offset={bodyOffset:function(e){var bw=e.offsetTop,bv=e.offsetLeft;if(b.support.doesNotIncludeMarginInBodyOffset){bw+=parseFloat(b.css(e,"marginTop"))||0;bv+=parseFloat(b.css(e,"marginLeft"))||0}return{top:bw,left:bv}},setOffset:function(bx,bG,bA){var bB=b.css(bx,"position");if(bB==="static"){bx.style.position="relative"}var bz=b(bx),bv=bz.offset(),e=b.css(bx,"top"),bE=b.css(bx,"left"),bF=(bB==="absolute"||bB==="fixed")&&b.inArray("auto",[e,bE])>-1,bD={},bC={},bw,by;if(bF){bC=bz.position();bw=bC.top;by=bC.left}else{bw=parseFloat(e)||0;by=parseFloat(bE)||0}if(b.isFunction(bG)){bG=bG.call(bx,bA,bv)}if(bG.top!=null){bD.top=(bG.top-bv.top)+bw}if(bG.left!=null){bD.left=(bG.left-bv.left)+by}if("using" in bG){bG.using.call(bx,bD)}else{bz.css(bD)}}};b.fn.extend({position:function(){if(!this[0]){return null}var bw=this[0],bv=this.offsetParent(),bx=this.offset(),e=ad.test(bv[0].nodeName)?{top:0,left:0}:bv.offset();bx.top-=parseFloat(b.css(bw,"marginTop"))||0;bx.left-=parseFloat(b.css(bw,"marginLeft"))||0;e.top+=parseFloat(b.css(bv[0],"borderTopWidth"))||0;e.left+=parseFloat(b.css(bv[0],"borderLeftWidth"))||0;return{top:bx.top-e.top,left:bx.left-e.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||av.body;while(e&&(!ad.test(e.nodeName)&&b.css(e,"position")==="static")){e=e.offsetParent}return e})}});b.each(["Left","Top"],function(bv,e){var bw="scroll"+e;b.fn[bw]=function(bz){var bx,by;if(bz===L){bx=this[0];if(!bx){return null}by=aK(bx);return by?("pageXOffset" in by)?by[bv?"pageYOffset":"pageXOffset"]:b.support.boxModel&&by.document.documentElement[bw]||by.document.body[bw]:bx[bw]}return this.each(function(){by=aK(this);if(by){by.scrollTo(!bv?bz:b(by).scrollLeft(),bv?bz:b(by).scrollTop())}else{this[bw]=bz}})}});function aK(e){return b.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:false}b.each(["Height","Width"],function(bv,e){var bw=e.toLowerCase();b.fn["inner"+e]=function(){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,"padding")):this[bw]():null};b.fn["outer"+e]=function(by){var bx=this[0];return bx?bx.style?parseFloat(b.css(bx,bw,by?"margin":"border")):this[bw]():null};b.fn[bw]=function(bz){var bA=this[0];if(!bA){return bz==null?null:this}if(b.isFunction(bz)){return this.each(function(bE){var bD=b(this);bD[bw](bz.call(this,bE,bD[bw]()))})}if(b.isWindow(bA)){var bB=bA.document.documentElement["client"+e],bx=bA.document.body;return bA.document.compatMode==="CSS1Compat"&&bB||bx&&bx["client"+e]||bB}else{if(bA.nodeType===9){return Math.max(bA.documentElement["client"+e],bA.body["scroll"+e],bA.documentElement["scroll"+e],bA.body["offset"+e],bA.documentElement["offset"+e])}else{if(bz===L){var bC=b.css(bA,bw),by=parseFloat(bC);return b.isNumeric(by)?by:bC}else{return this.css(bw,typeof bz==="string"?bz:bz+"px")}}}}});bb.jQuery=bb.$=b;if(typeof define==="function"&&define.amd&&define.amd.jQuery){define("jquery",[],function(){return b})}})(window);/*! - * jQuery UI 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI - */ -(function(a,d){a.ui=a.ui||{};if(a.ui.version){return}a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var g=this;setTimeout(function(){a(g).focus();if(f){f.call(g)}},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;if((a.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){e=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(a.curCSS(this,"position",1))&&(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}else{e=this.parents().filter(function(){return(/(auto|scroll)/).test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!e.length?a(document):e},zIndex:function(h){if(h!==d){return this.css("zIndex",h)}if(this.length){var f=a(this[0]),e,g;while(f.length&&f[0]!==document){e=f.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){g=parseInt(f.css("zIndex"),10);if(!isNaN(g)&&g!==0){return g}}f=f.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(g,e){var f=e==="Width"?["Left","Right"]:["Top","Bottom"],h=e.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};function j(m,l,i,n){a.each(f,function(){l-=parseFloat(a.curCSS(m,"padding"+this,true))||0;if(i){l-=parseFloat(a.curCSS(m,"border"+this+"Width",true))||0}if(n){l-=parseFloat(a.curCSS(m,"margin"+this,true))||0}});return l}a.fn["inner"+e]=function(i){if(i===d){return k["inner"+e].call(this)}return this.each(function(){a(this).css(h,j(this,i)+"px")})};a.fn["outer"+e]=function(i,l){if(typeof i!=="number"){return k["outer"+e].call(this,i)}return this.each(function(){a(this).css(h,j(this,i,true,l)+"px")})}});function c(g,e){var j=g.nodeName.toLowerCase();if("area"===j){var i=g.parentNode,h=i.name,f;if(!g.href||!h||i.nodeName.toLowerCase()!=="map"){return false}f=a("img[usemap=#"+h+"]")[0];return !!f&&b(f)}return(/input|select|textarea|button|object/.test(j)?!g.disabled:"a"==j?g.href||e:e)&&b(g)}function b(e){return !a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.extend(a.expr[":"],{data:function(g,f,e){return !!a.data(g,e[3])},focusable:function(e){return c(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(g){var e=a.attr(g,"tabindex"),f=isNaN(e);return(f||e>=0)&&c(g,!f)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));f.offsetHeight;a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart" in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(f,g,j){var h=a.ui[f].prototype;for(var e in j){h.plugins[e]=h.plugins[e]||[];h.plugins[e].push([g,j[e]])}},call:function(e,g,f){var j=e.plugins[g];if(!j||!e.element[0].parentNode){return}for(var h=0;h0){return true}h[e]=1;g=(h[e]>0);h[e]=0;return g},isOverAxis:function(f,e,g){return(f>e)&&(f<(e+g))},isOver:function(j,f,i,h,e,g){return a.ui.isOverAxis(j,i,e)&&a.ui.isOverAxis(f,h,g)}})})(jQuery);/*! - * jQuery UI Widget 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Widget - */ -(function(b,d){if(b.cleanData){var c=b.cleanData;b.cleanData=function(f){for(var g=0,h;(h=f[g])!=null;g++){try{b(h).triggerHandler("remove")}catch(j){}}c(f)}}else{var a=b.fn.remove;b.fn.remove=function(e,f){return this.each(function(){if(!f){if(!e||b.filter(e,[this]).length){b("*",this).add([this]).each(function(){try{b(this).triggerHandler("remove")}catch(g){}})}}return a.call(b(this),e,f)})}}b.widget=function(f,h,e){var g=f.split(".")[0],j;f=f.split(".")[1];j=g+"-"+f;if(!e){e=h;h=b.Widget}b.expr[":"][j]=function(k){return !!b.data(k,f)};b[g]=b[g]||{};b[g][f]=function(k,l){if(arguments.length){this._createWidget(k,l)}};var i=new h();i.options=b.extend(true,{},i.options);b[g][f].prototype=b.extend(true,i,{namespace:g,widgetName:f,widgetEventPrefix:b[g][f].prototype.widgetEventPrefix||f,widgetBaseClass:j},e);b.widget.bridge(f,b[g][f])};b.widget.bridge=function(f,e){b.fn[f]=function(i){var g=typeof i==="string",h=Array.prototype.slice.call(arguments,1),j=this;i=!g&&h.length?b.extend.apply(null,[true,i].concat(h)):i;if(g&&i.charAt(0)==="_"){return j}if(g){this.each(function(){var k=b.data(this,f),l=k&&b.isFunction(k[i])?k[i].apply(k,h):k;if(l!==k&&l!==d){j=l;return false}})}else{this.each(function(){var k=b.data(this,f);if(k){k.option(i||{})._init()}else{b.data(this,f,new e(i,this))}})}return j}};b.Widget=function(e,f){if(arguments.length){this._createWidget(e,f)}};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(f,g){b.data(g,this.widgetName,this);this.element=b(g);this.options=b.extend(true,{},this.options,this._getCreateOptions(),f);var e=this;this.element.bind("remove."+this.widgetName,function(){e.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(f,g){var e=f;if(arguments.length===0){return b.extend({},this.options)}if(typeof f==="string"){if(g===d){return this.options[f]}e={};e[f]=g}this._setOptions(e);return this},_setOptions:function(f){var e=this;b.each(f,function(g,h){e._setOption(g,h)});return this},_setOption:function(e,f){this.options[e]=f;if(e==="disabled"){this.widget()[f?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",f)}return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(e,f,g){var j,i,h=this.options[e];g=g||{};f=b.Event(f);f.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase();f.target=this.element[0];i=f.originalEvent;if(i){for(j in i){if(!(j in f)){f[j]=i[j]}}}this.element.trigger(f,g);return !(b.isFunction(h)&&h.call(this.element[0],f,g)===false||f.isDefaultPrevented())}}})(jQuery);/*! - * jQuery UI Mouse 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Mouse - * - * Depends: - * jquery.ui.widget.js - */ -(function(b,c){var a=false;b(document).mouseup(function(d){a=false});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var d=this;this.element.bind("mousedown."+this.widgetName,function(e){return d._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===b.data(e.target,d.widgetName+".preventClickEvent")){b.removeData(e.target,d.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(f){if(a){return}(this._mouseStarted&&this._mouseUp(f));this._mouseDownEvent=f;var e=this,g=(f.which==1),d=(typeof this.options.cancel=="string"&&f.target.nodeName?b(f.target).closest(this.options.cancel).length:false);if(!g||d||!this._mouseCapture(f)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(f)&&this._mouseDelayMet(f)){this._mouseStarted=(this._mouseStart(f)!==false);if(!this._mouseStarted){f.preventDefault();return true}}if(true===b.data(f.target,this.widgetName+".preventClickEvent")){b.removeData(f.target,this.widgetName+".preventClickEvent")}this._mouseMoveDelegate=function(h){return e._mouseMove(h)};this._mouseUpDelegate=function(h){return e._mouseUp(h)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);f.preventDefault();a=true;return true},_mouseMove:function(d){if(b.browser.msie&&!(document.documentMode>=9)&&!d.button){return this._mouseUp(d)}if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,d)!==false);(this._mouseStarted?this._mouseDrag(d):this._mouseUp(d))}return !this._mouseStarted},_mouseUp:function(d){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;if(d.target==this._mouseDownEvent.target){b.data(d.target,this.widgetName+".preventClickEvent",true)}this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return(Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance)},_mouseDelayMet:function(d){return this.mouseDelayMet},_mouseStart:function(d){},_mouseDrag:function(d){},_mouseStop:function(d){},_mouseCapture:function(d){return true}})})(jQuery);(function(c,d){c.widget("ui.resizable",c.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000},_create:function(){var f=this,k=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(k.aspectRatio),aspectRatio:k.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:k.helper||k.ghost||k.animate?k.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){this.element.wrap(c('
    ').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=k.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var l=this.handles.split(",");this.handles={};for(var g=0;g
    ');if(/sw|se|ne|nw/.test(j)){h.css({zIndex:++k.zIndex})}if("se"==j){h.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[j]=".ui-resizable-"+j;this.element.append(h)}}this._renderAxis=function(q){q=q||this.element;for(var n in this.handles){if(this.handles[n].constructor==String){this.handles[n]=c(this.handles[n],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=c(this.handles[n],this.element),p=0;p=/sw|ne|nw|se|n|s/.test(n)?o.outerHeight():o.outerWidth();var m=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");q.css(m,p);this._proportionallyResize()}if(!c(this.handles[n]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!f.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}f.axis=i&&i[1]?i[1]:"se"}});if(k.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){if(k.disabled){return}c(this).removeClass("ui-resizable-autohide");f._handles.show()},function(){if(k.disabled){return}if(!f.resizing){c(this).addClass("ui-resizable-autohide");f._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var e=function(g){c(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var f=this.element;f.after(this.originalElement.css({position:f.css("position"),width:f.outerWidth(),height:f.outerHeight(),top:f.css("top"),left:f.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(f){var g=false;for(var e in this.handles){if(c(this.handles[e])[0]==f.target){g=true}}return !this.options.disabled&&g},_mouseStart:function(g){var j=this.options,f=this.element.position(),e=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(e.is(".ui-draggable")||(/absolute/).test(e.css("position"))){e.css({position:"absolute",top:f.top,left:f.left})}this._renderProxy();var k=b(this.helper.css("left")),h=b(this.helper.css("top"));if(j.containment){k+=c(j.containment).scrollLeft()||0;h+=c(j.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:k,top:h};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:k,top:h};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:g.pageX,top:g.pageY};this.aspectRatio=(typeof j.aspectRatio=="number")?j.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var i=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",i=="auto"?this.axis+"-resize":i);e.addClass("ui-resizable-resizing");this._propagate("start",g);return true},_mouseDrag:function(e){var h=this.helper,g=this.options,m={},q=this,j=this.originalMousePosition,n=this.axis;var r=(e.pageX-j.left)||0,p=(e.pageY-j.top)||0;var i=this._change[n];if(!i){return false}var l=i.apply(this,[e,r,p]),k=c.browser.msie&&c.browser.version<7,f=this.sizeDiff;this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey){l=this._updateRatio(l,e)}l=this._respectSize(l,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(l);this._trigger("resize",e,this.ui());return false},_mouseStop:function(h){this.resizing=false;var i=this.options,m=this;if(this._helper){var g=this._proportionallyResizeElements,e=g.length&&(/textarea/i).test(g[0].nodeName),f=e&&c.ui.hasScroll(g[0],"left")?0:m.sizeDiff.height,k=e?0:m.sizeDiff.width;var n={width:(m.helper.width()-k),height:(m.helper.height()-f)},j=(parseInt(m.element.css("left"),10)+(m.position.left-m.originalPosition.left))||null,l=(parseInt(m.element.css("top"),10)+(m.position.top-m.originalPosition.top))||null;if(!i.animate){this.element.css(c.extend(n,{top:l,left:j}))}m.helper.height(m.size.height);m.helper.width(m.size.width);if(this._helper&&!i.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",h);if(this._helper){this.helper.remove()}return false},_updateVirtualBoundaries:function(g){var j=this.options,i,h,f,k,e;e={minWidth:a(j.minWidth)?j.minWidth:0,maxWidth:a(j.maxWidth)?j.maxWidth:Infinity,minHeight:a(j.minHeight)?j.minHeight:0,maxHeight:a(j.maxHeight)?j.maxHeight:Infinity};if(this._aspectRatio||g){i=e.minHeight*this.aspectRatio;f=e.minWidth/this.aspectRatio;h=e.maxHeight*this.aspectRatio;k=e.maxWidth/this.aspectRatio;if(i>e.minWidth){e.minWidth=i}if(f>e.minHeight){e.minHeight=f}if(hl.width),s=a(l.height)&&i.minHeight&&(i.minHeight>l.height);if(h){l.width=i.minWidth}if(s){l.height=i.minHeight}if(t){l.width=i.maxWidth}if(m){l.height=i.maxHeight}var f=this.originalPosition.left+this.originalSize.width,p=this.position.top+this.size.height;var k=/sw|nw|w/.test(q),e=/nw|ne|n/.test(q);if(h&&k){l.left=f-i.minWidth}if(t&&k){l.left=f-i.maxWidth}if(s&&e){l.top=p-i.minHeight}if(m&&e){l.top=p-i.maxHeight}var n=!l.width&&!l.height;if(n&&!l.left&&l.top){l.top=null}else{if(n&&!l.top&&l.left){l.left=null}}return l},_proportionallyResize:function(){var k=this.options;if(!this._proportionallyResizeElements.length){return}var g=this.helper||this.element;for(var f=0;f');var e=c.browser.msie&&c.browser.version<7,g=(e?1:0),h=(e?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++i.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(g,f,e){return{width:this.originalSize.width+f}},w:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{left:i.left+f,width:g.width-f}},n:function(h,f,e){var j=this.options,g=this.originalSize,i=this.originalPosition;return{top:i.top+e,height:g.height-e}},s:function(g,f,e){return{height:this.originalSize.height+e}},se:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},sw:function(g,f,e){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[g,f,e]))},ne:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[g,f,e]))},nw:function(g,f,e){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[g,f,e]))}},_propagate:function(f,e){c.ui.plugin.call(this,f,[e,this.ui()]);(f!="resize"&&this._trigger(f,e,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});c.extend(c.ui.resizable,{version:"1.8.18"});c.ui.plugin.add("resizable","alsoResize",{start:function(f,g){var e=c(this).data("resizable"),i=e.options;var h=function(j){c(j).each(function(){var k=c(this);k.data("resizable-alsoresize",{width:parseInt(k.width(),10),height:parseInt(k.height(),10),left:parseInt(k.css("left"),10),top:parseInt(k.css("top"),10)})})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.parentNode){if(i.alsoResize.length){i.alsoResize=i.alsoResize[0];h(i.alsoResize)}else{c.each(i.alsoResize,function(j){h(j)})}}else{h(i.alsoResize)}},resize:function(g,i){var f=c(this).data("resizable"),j=f.options,h=f.originalSize,l=f.originalPosition;var k={height:(f.size.height-h.height)||0,width:(f.size.width-h.width)||0,top:(f.position.top-l.top)||0,left:(f.position.left-l.left)||0},e=function(m,n){c(m).each(function(){var q=c(this),r=c(this).data("resizable-alsoresize"),p={},o=n&&n.length?n:q.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];c.each(o,function(s,u){var t=(r[u]||0)+(k[u]||0);if(t&&t>=0){p[u]=t||null}});q.css(p)})};if(typeof(j.alsoResize)=="object"&&!j.alsoResize.nodeType){c.each(j.alsoResize,function(m,n){e(m,n)})}else{e(j.alsoResize)}},stop:function(e,f){c(this).removeData("resizable-alsoresize")}});c.ui.plugin.add("resizable","animate",{stop:function(i,n){var p=c(this).data("resizable"),j=p.options;var h=p._proportionallyResizeElements,e=h.length&&(/textarea/i).test(h[0].nodeName),f=e&&c.ui.hasScroll(h[0],"left")?0:p.sizeDiff.height,l=e?0:p.sizeDiff.width;var g={width:(p.size.width-l),height:(p.size.height-f)},k=(parseInt(p.element.css("left"),10)+(p.position.left-p.originalPosition.left))||null,m=(parseInt(p.element.css("top"),10)+(p.position.top-p.originalPosition.top))||null;p.element.animate(c.extend(g,m&&k?{top:m,left:k}:{}),{duration:j.animateDuration,easing:j.animateEasing,step:function(){var o={width:parseInt(p.element.css("width"),10),height:parseInt(p.element.css("height"),10),top:parseInt(p.element.css("top"),10),left:parseInt(p.element.css("left"),10)};if(h&&h.length){c(h[0]).css({width:o.width,height:o.height})}p._updateCache(o);p._propagate("resize",i)}})}});c.ui.plugin.add("resizable","containment",{start:function(f,r){var t=c(this).data("resizable"),j=t.options,l=t.element;var g=j.containment,k=(g instanceof c)?g.get(0):(/parent/.test(g))?l.parent().get(0):g;if(!k){return}t.containerElement=c(k);if(/document/.test(g)||g==document){t.containerOffset={left:0,top:0};t.containerPosition={left:0,top:0};t.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var n=c(k),i=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){i[p]=b(n.css("padding"+o))});t.containerOffset=n.offset();t.containerPosition=n.position();t.containerSize={height:(n.innerHeight()-i[3]),width:(n.innerWidth()-i[1])};var q=t.containerOffset,e=t.containerSize.height,m=t.containerSize.width,h=(c.ui.hasScroll(k,"left")?k.scrollWidth:m),s=(c.ui.hasScroll(k)?k.scrollHeight:e);t.parentData={element:k,left:q.left,top:q.top,width:h,height:s}}},resize:function(g,q){var t=c(this).data("resizable"),i=t.options,f=t.containerSize,p=t.containerOffset,m=t.size,n=t.position,r=t._aspectRatio||g.shiftKey,e={top:0,left:0},h=t.containerElement;if(h[0]!=document&&(/static/).test(h.css("position"))){e=p}if(n.left<(t._helper?p.left:0)){t.size.width=t.size.width+(t._helper?(t.position.left-p.left):(t.position.left-e.left));if(r){t.size.height=t.size.width/i.aspectRatio}t.position.left=i.helper?p.left:0}if(n.top<(t._helper?p.top:0)){t.size.height=t.size.height+(t._helper?(t.position.top-p.top):t.position.top);if(r){t.size.width=t.size.height*i.aspectRatio}t.position.top=t._helper?p.top:0}t.offset.left=t.parentData.left+t.position.left;t.offset.top=t.parentData.top+t.position.top;var l=Math.abs((t._helper?t.offset.left-e.left:(t.offset.left-e.left))+t.sizeDiff.width),s=Math.abs((t._helper?t.offset.top-e.top:(t.offset.top-p.top))+t.sizeDiff.height);var k=t.containerElement.get(0)==t.element.parent().get(0),j=/relative|absolute/.test(t.containerElement.css("position"));if(k&&j){l-=t.parentData.left}if(l+t.size.width>=t.parentData.width){t.size.width=t.parentData.width-l;if(r){t.size.height=t.size.width/t.aspectRatio}}if(s+t.size.height>=t.parentData.height){t.size.height=t.parentData.height-s;if(r){t.size.width=t.size.height*t.aspectRatio}}},stop:function(f,n){var q=c(this).data("resizable"),g=q.options,l=q.position,m=q.containerOffset,e=q.containerPosition,i=q.containerElement;var j=c(q.helper),r=j.offset(),p=j.outerWidth()-q.sizeDiff.width,k=j.outerHeight()-q.sizeDiff.height;if(q._helper&&!g.animate&&(/relative/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}if(q._helper&&!g.animate&&(/static/).test(i.css("position"))){c(this).css({left:r.left-e.left-m.left,width:p,height:k})}}});c.ui.plugin.add("resizable","ghost",{start:function(g,h){var e=c(this).data("resizable"),i=e.options,f=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:"");e.ghost.appendTo(e.helper)},resize:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost){e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})}},stop:function(f,g){var e=c(this).data("resizable"),h=e.options;if(e.ghost&&e.helper){e.helper.get(0).removeChild(e.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(e,m){var p=c(this).data("resizable"),h=p.options,k=p.size,i=p.originalSize,j=p.originalPosition,n=p.axis,l=h._aspectRatio||e.shiftKey;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var g=Math.round((k.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1),f=Math.round((k.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f}else{if(/^(ne)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f}else{if(/^(sw)$/.test(n)){p.size.width=i.width+g;p.size.height=i.height+f;p.position.left=j.left-g}else{p.size.width=i.width+g;p.size.height=i.height+f;p.position.top=j.top-f;p.position.left=j.left-g}}}}});var b=function(e){return parseInt(e,10)||0};var a=function(e){return !isNaN(parseInt(e,10))}})(jQuery);/*! - * jQuery hashchange event - v1.3 - 7/21/2010 - * http://benalman.com/projects/jquery-hashchange-plugin/ - * - * Copyright (c) 2010 "Cowboy" Ben Alman - * Dual licensed under the MIT and GPL licenses. - * http://benalman.com/about/license/ - */ -(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('