Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
e3a9ed65
authored
Apr 06, 2022
by
Ian Baker
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #56 from ittiam-systems:rtp_wav
PiperOrigin-RevId: 437783926
parents
0096b40b
3f8a6800
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
331 additions
and
3 deletions
RELEASENOTES.md
libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/RtpPayloadFormat.java
libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/RtspMediaTrack.java
libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/reader/DefaultRtpPayloadReaderFactory.java
libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/reader/RtpPcmReader.java
libraries/exoplayer_rtsp/src/test/java/androidx/media3/exoplayer/rtsp/reader/RtpPcmReaderTest.java
RELEASENOTES.md
View file @
e3a9ed65
...
@@ -38,11 +38,13 @@
...
@@ -38,11 +38,13 @@
*
RTSP:
*
RTSP:
*
Add RTP reader for HEVC
*
Add RTP reader for HEVC
(
[
#36
](
https://github.com/androidx/media/pull/36
)
).
(
[
#36
](
https://github.com/androidx/media/pull/36
)
).
*
Add RTP reader for AMR. Currently only mono-channel, non-interleaved
*
Add RTP reader for AMR. Currently only mono-channel, non-interleaved
AMR streams are supported. Compound AMR RTP payload is not supported.
AMR streams are supported. Compound AMR RTP payload is not supported.
(
[
#46
](
https://github.com/androidx/media/pull/46
)
)
(
[
#46
](
https://github.com/androidx/media/pull/46
)
)
*
Add RTP reader for VP8
*
Add RTP reader for VP8
(
[
#47
](
https://github.com/androidx/media/pull/47
)
).
(
[
#47
](
https://github.com/androidx/media/pull/47
)
).
*
Add RTP reader for WAV
(
[
#56
](
https://github.com/androidx/media/pull/56
)
).
*
Remove deprecated symbols:
*
Remove deprecated symbols:
*
Remove
`Player.Listener.onTracksChanged`
. Use
*
Remove
`Player.Listener.onTracksChanged`
. Use
`Player.Listener.onTracksInfoChanged`
instead.
`Player.Listener.onTracksInfoChanged`
instead.
...
...
libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/RtpPayloadFormat.java
View file @
e3a9ed65
...
@@ -15,7 +15,10 @@
...
@@ -15,7 +15,10 @@
*/
*/
package
androidx
.
media3
.
exoplayer
.
rtsp
;
package
androidx
.
media3
.
exoplayer
.
rtsp
;
import
static
androidx
.
media3
.
common
.
util
.
Assertions
.
checkArgument
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
androidx.media3.common.C
;
import
androidx.media3.common.Format
;
import
androidx.media3.common.Format
;
import
androidx.media3.common.MimeTypes
;
import
androidx.media3.common.MimeTypes
;
import
androidx.media3.common.util.UnstableApi
;
import
androidx.media3.common.util.UnstableApi
;
...
@@ -42,6 +45,10 @@ public final class RtpPayloadFormat {
...
@@ -42,6 +45,10 @@ public final class RtpPayloadFormat {
private
static
final
String
RTP_MEDIA_MPEG4_GENERIC
=
"MPEG4-GENERIC"
;
private
static
final
String
RTP_MEDIA_MPEG4_GENERIC
=
"MPEG4-GENERIC"
;
private
static
final
String
RTP_MEDIA_H264
=
"H264"
;
private
static
final
String
RTP_MEDIA_H264
=
"H264"
;
private
static
final
String
RTP_MEDIA_H265
=
"H265"
;
private
static
final
String
RTP_MEDIA_H265
=
"H265"
;
private
static
final
String
RTP_MEDIA_PCM_L8
=
"L8"
;
private
static
final
String
RTP_MEDIA_PCM_L16
=
"L16"
;
private
static
final
String
RTP_MEDIA_PCMA
=
"PCMA"
;
private
static
final
String
RTP_MEDIA_PCMU
=
"PCMU"
;
private
static
final
String
RTP_MEDIA_VP8
=
"VP8"
;
private
static
final
String
RTP_MEDIA_VP8
=
"VP8"
;
/** Returns whether the format of a {@link MediaDescription} is supported. */
/** Returns whether the format of a {@link MediaDescription} is supported. */
...
@@ -53,6 +60,10 @@ public final class RtpPayloadFormat {
...
@@ -53,6 +60,10 @@ public final class RtpPayloadFormat {
case
RTP_MEDIA_H264:
case
RTP_MEDIA_H264:
case
RTP_MEDIA_H265:
case
RTP_MEDIA_H265:
case
RTP_MEDIA_MPEG4_GENERIC:
case
RTP_MEDIA_MPEG4_GENERIC:
case
RTP_MEDIA_PCM_L8:
case
RTP_MEDIA_PCM_L16:
case
RTP_MEDIA_PCMA:
case
RTP_MEDIA_PCMU:
case
RTP_MEDIA_VP8:
case
RTP_MEDIA_VP8:
return
true
;
return
true
;
default
:
default
:
...
@@ -81,6 +92,13 @@ public final class RtpPayloadFormat {
...
@@ -81,6 +92,13 @@ public final class RtpPayloadFormat {
return
MimeTypes
.
VIDEO_H265
;
return
MimeTypes
.
VIDEO_H265
;
case
RTP_MEDIA_MPEG4_GENERIC:
case
RTP_MEDIA_MPEG4_GENERIC:
return
MimeTypes
.
AUDIO_AAC
;
return
MimeTypes
.
AUDIO_AAC
;
case
RTP_MEDIA_PCM_L8:
case
RTP_MEDIA_PCM_L16:
return
MimeTypes
.
AUDIO_RAW
;
case
RTP_MEDIA_PCMA:
return
MimeTypes
.
AUDIO_ALAW
;
case
RTP_MEDIA_PCMU:
return
MimeTypes
.
AUDIO_MLAW
;
case
RTP_MEDIA_VP8:
case
RTP_MEDIA_VP8:
return
MimeTypes
.
VIDEO_VP8
;
return
MimeTypes
.
VIDEO_VP8
;
default
:
default
:
...
@@ -88,6 +106,15 @@ public final class RtpPayloadFormat {
...
@@ -88,6 +106,15 @@ public final class RtpPayloadFormat {
}
}
}
}
/** Returns the PCM encoding type for {@code mediaEncoding}. */
public
static
@C
.
PcmEncoding
int
getRawPcmEncodingType
(
String
mediaEncoding
)
{
checkArgument
(
mediaEncoding
.
equals
(
RTP_MEDIA_PCM_L8
)
||
mediaEncoding
.
equals
(
RTP_MEDIA_PCM_L16
));
return
mediaEncoding
.
equals
(
RtpPayloadFormat
.
RTP_MEDIA_PCM_L8
)
?
C
.
ENCODING_PCM_8BIT
:
C
.
ENCODING_PCM_16BIT_BIG_ENDIAN
;
}
/** The payload type associated with this format. */
/** The payload type associated with this format. */
public
final
int
rtpPayloadType
;
public
final
int
rtpPayloadType
;
/** The clock rate in Hertz, associated with the format. */
/** The clock rate in Hertz, associated with the format. */
...
...
libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/RtspMediaTrack.java
View file @
e3a9ed65
...
@@ -123,8 +123,9 @@ import com.google.common.collect.ImmutableMap;
...
@@ -123,8 +123,9 @@ import com.google.common.collect.ImmutableMap;
}
}
int
rtpPayloadType
=
mediaDescription
.
rtpMapAttribute
.
payloadType
;
int
rtpPayloadType
=
mediaDescription
.
rtpMapAttribute
.
payloadType
;
String
mediaEncoding
=
mediaDescription
.
rtpMapAttribute
.
mediaEncoding
;
String
mimeType
=
getMimeTypeFromRtpMediaType
(
media
Description
.
rtpMapAttribute
.
media
Encoding
);
String
mimeType
=
getMimeTypeFromRtpMediaType
(
mediaEncoding
);
formatBuilder
.
setSampleMimeType
(
mimeType
);
formatBuilder
.
setSampleMimeType
(
mimeType
);
int
clockRate
=
mediaDescription
.
rtpMapAttribute
.
clockRate
;
int
clockRate
=
mediaDescription
.
rtpMapAttribute
.
clockRate
;
...
@@ -168,8 +169,13 @@ import com.google.common.collect.ImmutableMap;
...
@@ -168,8 +169,13 @@ import com.google.common.collect.ImmutableMap;
// width and height.
// width and height.
formatBuilder
.
setWidth
(
DEFAULT_VP8_WIDTH
).
setHeight
(
DEFAULT_VP8_HEIGHT
);
formatBuilder
.
setWidth
(
DEFAULT_VP8_WIDTH
).
setHeight
(
DEFAULT_VP8_HEIGHT
);
break
;
break
;
case
MimeTypes
.
AUDIO_RAW
:
formatBuilder
.
setPcmEncoding
(
RtpPayloadFormat
.
getRawPcmEncodingType
(
mediaEncoding
));
break
;
case
MimeTypes
.
AUDIO_AC3
:
case
MimeTypes
.
AUDIO_AC3
:
// AC3 does not require a fmtp attribute. Fall through.
case
MimeTypes
.
AUDIO_ALAW
:
case
MimeTypes
.
AUDIO_MLAW
:
// Does not require a fmtp attribute. Fall through.
default
:
default
:
// Do nothing.
// Do nothing.
}
}
...
...
libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/reader/DefaultRtpPayloadReaderFactory.java
View file @
e3a9ed65
...
@@ -39,6 +39,10 @@ import androidx.media3.exoplayer.rtsp.RtpPayloadFormat;
...
@@ -39,6 +39,10 @@ import androidx.media3.exoplayer.rtsp.RtpPayloadFormat;
case
MimeTypes
.
AUDIO_AMR_NB
:
case
MimeTypes
.
AUDIO_AMR_NB
:
case
MimeTypes
.
AUDIO_AMR_WB
:
case
MimeTypes
.
AUDIO_AMR_WB
:
return
new
RtpAmrReader
(
payloadFormat
);
return
new
RtpAmrReader
(
payloadFormat
);
case
MimeTypes
.
AUDIO_RAW
:
case
MimeTypes
.
AUDIO_ALAW
:
case
MimeTypes
.
AUDIO_MLAW
:
return
new
RtpPcmReader
(
payloadFormat
);
case
MimeTypes
.
VIDEO_H264
:
case
MimeTypes
.
VIDEO_H264
:
return
new
RtpH264Reader
(
payloadFormat
);
return
new
RtpH264Reader
(
payloadFormat
);
case
MimeTypes
.
VIDEO_H265
:
case
MimeTypes
.
VIDEO_H265
:
...
...
libraries/exoplayer_rtsp/src/main/java/androidx/media3/exoplayer/rtsp/reader/RtpPcmReader.java
0 → 100644
View file @
e3a9ed65
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
androidx
.
media3
.
exoplayer
.
rtsp
.
reader
;
import
static
androidx
.
media3
.
common
.
util
.
Assertions
.
checkNotNull
;
import
android.util.Log
;
import
androidx.media3.common.C
;
import
androidx.media3.common.util.ParsableByteArray
;
import
androidx.media3.common.util.UnstableApi
;
import
androidx.media3.common.util.Util
;
import
androidx.media3.exoplayer.rtsp.RtpPacket
;
import
androidx.media3.exoplayer.rtsp.RtpPayloadFormat
;
import
androidx.media3.extractor.ExtractorOutput
;
import
androidx.media3.extractor.TrackOutput
;
import
org.checkerframework.checker.nullness.qual.MonotonicNonNull
;
/**
* Parses byte stream carried on RTP packets, and extracts PCM frames. Refer to RFC3551 for more
* details.
*/
@UnstableApi
/* package */
public
final
class
RtpPcmReader
implements
RtpPayloadReader
{
private
static
final
String
TAG
=
"RtpPcmReader"
;
private
final
RtpPayloadFormat
payloadFormat
;
private
@MonotonicNonNull
TrackOutput
trackOutput
;
private
long
firstReceivedTimestamp
;
private
long
startTimeOffsetUs
;
private
int
previousSequenceNumber
;
public
RtpPcmReader
(
RtpPayloadFormat
payloadFormat
)
{
this
.
payloadFormat
=
payloadFormat
;
firstReceivedTimestamp
=
C
.
TIME_UNSET
;
// Start time offset must be 0 before the first seek.
startTimeOffsetUs
=
0
;
previousSequenceNumber
=
C
.
INDEX_UNSET
;
}
@Override
public
void
createTracks
(
ExtractorOutput
extractorOutput
,
int
trackId
)
{
trackOutput
=
extractorOutput
.
track
(
trackId
,
C
.
TRACK_TYPE_AUDIO
);
trackOutput
.
format
(
payloadFormat
.
format
);
}
@Override
public
void
onReceivingFirstPacket
(
long
timestamp
,
int
sequenceNumber
)
{
firstReceivedTimestamp
=
timestamp
;
}
@Override
public
void
consume
(
ParsableByteArray
data
,
long
timestamp
,
int
sequenceNumber
,
boolean
rtpMarker
)
{
checkNotNull
(
trackOutput
);
if
(
previousSequenceNumber
!=
C
.
INDEX_UNSET
)
{
int
expectedSequenceNumber
=
RtpPacket
.
getNextSequenceNumber
(
previousSequenceNumber
);
if
(
sequenceNumber
!=
expectedSequenceNumber
)
{
Log
.
w
(
TAG
,
Util
.
formatInvariant
(
"Received RTP packet with unexpected sequence number. Expected: %d; received: %d."
,
expectedSequenceNumber
,
sequenceNumber
));
}
}
long
sampleTimeUs
=
toSampleUs
(
startTimeOffsetUs
,
timestamp
,
firstReceivedTimestamp
,
payloadFormat
.
clockRate
);
int
size
=
data
.
bytesLeft
();
trackOutput
.
sampleData
(
data
,
size
);
trackOutput
.
sampleMetadata
(
sampleTimeUs
,
C
.
BUFFER_FLAG_KEY_FRAME
,
size
,
/* offset= */
0
,
/* cryptoData= */
null
);
previousSequenceNumber
=
sequenceNumber
;
}
@Override
public
void
seek
(
long
nextRtpTimestamp
,
long
timeUs
)
{
// TODO(b/198620566) Rename firstReceivedTimestamp to timestampBase for all RtpPayloadReaders.
firstReceivedTimestamp
=
nextRtpTimestamp
;
startTimeOffsetUs
=
timeUs
;
}
/** Returns the correct sample time from RTP timestamp, accounting for the given clock rate. */
private
static
long
toSampleUs
(
long
startTimeOffsetUs
,
long
rtpTimestamp
,
long
firstReceivedRtpTimestamp
,
int
clockRate
)
{
return
startTimeOffsetUs
+
Util
.
scaleLargeTimestamp
(
rtpTimestamp
-
firstReceivedRtpTimestamp
,
/* multiplier= */
C
.
MICROS_PER_SECOND
,
/* divisor= */
clockRate
);
}
}
libraries/exoplayer_rtsp/src/test/java/androidx/media3/exoplayer/rtsp/reader/RtpPcmReaderTest.java
0 → 100644
View file @
e3a9ed65
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
androidx
.
media3
.
exoplayer
.
rtsp
.
reader
;
import
static
com
.
google
.
common
.
truth
.
Truth
.
assertThat
;
import
androidx.media3.common.C
;
import
androidx.media3.common.Format
;
import
androidx.media3.common.MimeTypes
;
import
androidx.media3.common.util.ParsableByteArray
;
import
androidx.media3.exoplayer.rtsp.RtpPacket
;
import
androidx.media3.exoplayer.rtsp.RtpPayloadFormat
;
import
androidx.media3.test.utils.FakeExtractorOutput
;
import
androidx.media3.test.utils.FakeTrackOutput
;
import
androidx.media3.test.utils.TestUtil
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
com.google.common.collect.ImmutableMap
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
/** Unit test for {@link RtpPcmReader}. */
@RunWith
(
AndroidJUnit4
.
class
)
public
final
class
RtpPcmReaderTest
{
// A typical RTP payload type for audio.
private
static
final
int
RTP_PAYLOAD_TYPE
=
97
;
private
static
final
byte
[]
FRAME_1_PAYLOAD
=
TestUtil
.
buildTestData
(
/* length= */
4
);
private
static
final
byte
[]
FRAME_2_PAYLOAD
=
TestUtil
.
buildTestData
(
/* length= */
4
);
private
static
final
RtpPacket
PACKET_1
=
createRtpPacket
(
/* timestamp= */
2599168056L
,
/* sequenceNumber= */
40289
,
FRAME_1_PAYLOAD
);
private
static
final
RtpPacket
PACKET_2
=
createRtpPacket
(
/* timestamp= */
2599169592L
,
/* sequenceNumber= */
40290
,
FRAME_2_PAYLOAD
);
private
ParsableByteArray
packetData
;
private
FakeExtractorOutput
extractorOutput
;
private
RtpPcmReader
pcmReader
;
@Before
public
void
setUp
()
{
packetData
=
new
ParsableByteArray
();
extractorOutput
=
new
FakeExtractorOutput
();
}
@Test
public
void
consume_twoDualChannelWav8bitPackets
()
{
pcmReader
=
new
RtpPcmReader
(
new
RtpPayloadFormat
(
new
Format
.
Builder
()
.
setChannelCount
(
2
)
.
setSampleMimeType
(
MimeTypes
.
AUDIO_WAV
)
.
setPcmEncoding
(
C
.
ENCODING_PCM_8BIT
)
.
setSampleRate
(
48_000
)
.
build
(),
/* rtpPayloadType= */
RTP_PAYLOAD_TYPE
,
/* clockRate= */
48_000
,
/* fmtpParameters= */
ImmutableMap
.
of
()));
pcmReader
.
createTracks
(
extractorOutput
,
/* trackId= */
0
);
pcmReader
.
onReceivingFirstPacket
(
PACKET_1
.
timestamp
,
PACKET_1
.
sequenceNumber
);
consume
(
PACKET_1
);
consume
(
PACKET_2
);
FakeTrackOutput
trackOutput
=
extractorOutput
.
trackOutputs
.
get
(
0
);
assertThat
(
trackOutput
.
getSampleCount
()).
isEqualTo
(
2
);
assertThat
(
trackOutput
.
getSampleData
(
0
)).
isEqualTo
(
FRAME_1_PAYLOAD
);
assertThat
(
trackOutput
.
getSampleTimeUs
(
0
)).
isEqualTo
(
0
);
assertThat
(
trackOutput
.
getSampleData
(
1
)).
isEqualTo
(
FRAME_2_PAYLOAD
);
assertThat
(
trackOutput
.
getSampleTimeUs
(
1
)).
isEqualTo
(
32000
);
}
@Test
public
void
consume_twoSingleChannelWav16bitPackets
()
{
pcmReader
=
new
RtpPcmReader
(
new
RtpPayloadFormat
(
new
Format
.
Builder
()
.
setChannelCount
(
1
)
.
setSampleMimeType
(
MimeTypes
.
AUDIO_WAV
)
.
setPcmEncoding
(
C
.
ENCODING_PCM_16BIT_BIG_ENDIAN
)
.
setSampleRate
(
60_000
)
.
build
(),
/* rtpPayloadType= */
RTP_PAYLOAD_TYPE
,
/* clockRate= */
60_000
,
/* fmtpParameters= */
ImmutableMap
.
of
()));
pcmReader
.
createTracks
(
extractorOutput
,
/* trackId= */
0
);
pcmReader
.
onReceivingFirstPacket
(
PACKET_1
.
timestamp
,
PACKET_1
.
sequenceNumber
);
consume
(
PACKET_1
);
consume
(
PACKET_2
);
FakeTrackOutput
trackOutput
=
extractorOutput
.
trackOutputs
.
get
(
0
);
assertThat
(
trackOutput
.
getSampleCount
()).
isEqualTo
(
2
);
assertThat
(
trackOutput
.
getSampleData
(
0
)).
isEqualTo
(
FRAME_1_PAYLOAD
);
assertThat
(
trackOutput
.
getSampleTimeUs
(
0
)).
isEqualTo
(
0
);
assertThat
(
trackOutput
.
getSampleData
(
1
)).
isEqualTo
(
FRAME_2_PAYLOAD
);
assertThat
(
trackOutput
.
getSampleTimeUs
(
1
)).
isEqualTo
(
25600
);
}
@Test
public
void
consume_twoDualChannelAlawPackets
()
{
pcmReader
=
new
RtpPcmReader
(
new
RtpPayloadFormat
(
new
Format
.
Builder
()
.
setChannelCount
(
2
)
.
setSampleMimeType
(
MimeTypes
.
AUDIO_ALAW
)
.
setSampleRate
(
16_000
)
.
build
(),
/* rtpPayloadType= */
RTP_PAYLOAD_TYPE
,
/* clockRate= */
16_000
,
/* fmtpParameters= */
ImmutableMap
.
of
()));
pcmReader
.
createTracks
(
extractorOutput
,
/* trackId= */
0
);
pcmReader
.
onReceivingFirstPacket
(
PACKET_1
.
timestamp
,
PACKET_1
.
sequenceNumber
);
consume
(
PACKET_1
);
consume
(
PACKET_2
);
FakeTrackOutput
trackOutput
=
extractorOutput
.
trackOutputs
.
get
(
0
);
assertThat
(
trackOutput
.
getSampleCount
()).
isEqualTo
(
2
);
assertThat
(
trackOutput
.
getSampleData
(
0
)).
isEqualTo
(
FRAME_1_PAYLOAD
);
assertThat
(
trackOutput
.
getSampleTimeUs
(
0
)).
isEqualTo
(
0
);
assertThat
(
trackOutput
.
getSampleData
(
1
)).
isEqualTo
(
FRAME_2_PAYLOAD
);
assertThat
(
trackOutput
.
getSampleTimeUs
(
1
)).
isEqualTo
(
96000
);
}
@Test
public
void
consume_twoDualChannelMlawPackets
()
{
pcmReader
=
new
RtpPcmReader
(
new
RtpPayloadFormat
(
new
Format
.
Builder
()
.
setChannelCount
(
2
)
.
setSampleMimeType
(
MimeTypes
.
AUDIO_MLAW
)
.
setSampleRate
(
24_000
)
.
build
(),
/* rtpPayloadType= */
RTP_PAYLOAD_TYPE
,
/* clockRate= */
24_000
,
/* fmtpParameters= */
ImmutableMap
.
of
()));
pcmReader
.
createTracks
(
extractorOutput
,
/* trackId= */
0
);
pcmReader
.
onReceivingFirstPacket
(
PACKET_1
.
timestamp
,
PACKET_1
.
sequenceNumber
);
consume
(
PACKET_1
);
consume
(
PACKET_2
);
FakeTrackOutput
trackOutput
=
extractorOutput
.
trackOutputs
.
get
(
0
);
assertThat
(
trackOutput
.
getSampleCount
()).
isEqualTo
(
2
);
assertThat
(
trackOutput
.
getSampleData
(
0
)).
isEqualTo
(
FRAME_1_PAYLOAD
);
assertThat
(
trackOutput
.
getSampleTimeUs
(
0
)).
isEqualTo
(
0
);
assertThat
(
trackOutput
.
getSampleData
(
1
)).
isEqualTo
(
FRAME_2_PAYLOAD
);
assertThat
(
trackOutput
.
getSampleTimeUs
(
1
)).
isEqualTo
(
64000
);
}
private
static
RtpPacket
createRtpPacket
(
long
timestamp
,
int
sequenceNumber
,
byte
[]
payloadData
)
{
return
new
RtpPacket
.
Builder
()
.
setTimestamp
(
timestamp
)
.
setSequenceNumber
(
sequenceNumber
)
// RFC3551 Section 4.1.
.
setMarker
(
false
)
.
setPayloadData
(
payloadData
)
.
build
();
}
private
void
consume
(
RtpPacket
frame
)
{
packetData
.
reset
(
frame
.
payloadData
);
pcmReader
.
consume
(
packetData
,
frame
.
timestamp
,
frame
.
sequenceNumber
,
frame
.
marker
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment