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
e6527ec1
authored
Jan 04, 2023
by
kimvde
Committed by
Marc Baechinger
Jan 04, 2023
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Merge BaseSamplePipeline and SamplePipeline
PiperOrigin-RevId: 499469006
parent
9d431a52
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
108 additions
and
140 deletions
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AudioTranscodingSamplePipeline.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/BaseSamplePipeline.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/PassthroughSamplePipeline.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/SamplePipeline.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoTranscodingSamplePipeline.java
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AudioTranscodingSamplePipeline.java
View file @
e6527ec1
...
...
@@ -36,7 +36,7 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
import
org.checkerframework.dataflow.qual.Pure
;
/** Pipeline to process, re-encode and mux raw audio samples. */
/* package */
final
class
AudioTranscodingSamplePipeline
extends
Base
SamplePipeline
{
/* package */
final
class
AudioTranscodingSamplePipeline
extends
SamplePipeline
{
private
static
final
int
DEFAULT_ENCODER_BITRATE
=
128
*
1024
;
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/BaseSamplePipeline.java
deleted
100644 → 0
View file @
9d431a52
/*
* 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
com
.
google
.
android
.
exoplayer2
.
transformer
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Assertions
.
checkStateNotNull
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.decoder.DecoderInputBuffer
;
import
com.google.android.exoplayer2.util.MimeTypes
;
/* package */
abstract
class
BaseSamplePipeline
implements
SamplePipeline
{
private
final
long
streamStartPositionUs
;
private
final
MuxerWrapper
muxerWrapper
;
private
final
@C
.
TrackType
int
trackType
;
private
boolean
muxerWrapperTrackAdded
;
public
BaseSamplePipeline
(
Format
inputFormat
,
long
streamStartPositionUs
,
MuxerWrapper
muxerWrapper
)
{
this
.
streamStartPositionUs
=
streamStartPositionUs
;
this
.
muxerWrapper
=
muxerWrapper
;
trackType
=
MimeTypes
.
getTrackType
(
inputFormat
.
sampleMimeType
);
}
protected
static
TransformationException
createNoSupportedMimeTypeException
(
Format
requestedEncoderFormat
)
{
return
TransformationException
.
createForCodec
(
new
IllegalArgumentException
(
"No MIME type is supported by both encoder and muxer."
),
MimeTypes
.
isVideo
(
requestedEncoderFormat
.
sampleMimeType
),
/* isDecoder= */
false
,
requestedEncoderFormat
,
/* mediaCodecName= */
null
,
TransformationException
.
ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED
);
}
@Override
public
boolean
expectsDecodedData
()
{
return
true
;
}
@Override
public
boolean
processData
()
throws
TransformationException
{
return
feedMuxer
()
||
processDataUpToMuxer
();
}
protected
abstract
boolean
processDataUpToMuxer
()
throws
TransformationException
;
@Nullable
protected
abstract
Format
getMuxerInputFormat
()
throws
TransformationException
;
@Nullable
protected
abstract
DecoderInputBuffer
getMuxerInputBuffer
()
throws
TransformationException
;
protected
abstract
void
releaseMuxerInputBuffer
()
throws
TransformationException
;
protected
abstract
boolean
isMuxerInputEnded
();
/**
* Attempts to pass encoded data to the muxer, and returns whether it may be possible to pass more
* data immediately by calling this method again.
*/
private
boolean
feedMuxer
()
throws
TransformationException
{
if
(!
muxerWrapperTrackAdded
)
{
@Nullable
Format
inputFormat
=
getMuxerInputFormat
();
if
(
inputFormat
==
null
)
{
return
false
;
}
try
{
muxerWrapper
.
addTrackFormat
(
inputFormat
);
}
catch
(
Muxer
.
MuxerException
e
)
{
throw
TransformationException
.
createForMuxer
(
e
,
TransformationException
.
ERROR_CODE_MUXING_FAILED
);
}
muxerWrapperTrackAdded
=
true
;
}
if
(
isMuxerInputEnded
())
{
muxerWrapper
.
endTrack
(
trackType
);
return
false
;
}
@Nullable
DecoderInputBuffer
muxerInputBuffer
=
getMuxerInputBuffer
();
if
(
muxerInputBuffer
==
null
)
{
return
false
;
}
long
samplePresentationTimeUs
=
muxerInputBuffer
.
timeUs
-
streamStartPositionUs
;
// TODO(b/204892224): Consider subtracting the first sample timestamp from the sample pipeline
// buffer from all samples so that they are guaranteed to start from zero in the output file.
try
{
if
(!
muxerWrapper
.
writeSample
(
trackType
,
checkStateNotNull
(
muxerInputBuffer
.
data
),
muxerInputBuffer
.
isKeyFrame
(),
samplePresentationTimeUs
))
{
return
false
;
}
}
catch
(
Muxer
.
MuxerException
e
)
{
throw
TransformationException
.
createForMuxer
(
e
,
TransformationException
.
ERROR_CODE_MUXING_FAILED
);
}
releaseMuxerInputBuffer
();
return
true
;
}
}
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/PassthroughSamplePipeline.java
View file @
e6527ec1
...
...
@@ -21,7 +21,7 @@ import com.google.android.exoplayer2.Format;
import
com.google.android.exoplayer2.decoder.DecoderInputBuffer
;
/** Pipeline that muxes encoded samples without any transcoding or transformation. */
/* package */
final
class
PassthroughSamplePipeline
extends
Base
SamplePipeline
{
/* package */
final
class
PassthroughSamplePipeline
extends
SamplePipeline
{
private
final
DecoderInputBuffer
buffer
;
private
final
Format
format
;
...
...
@@ -62,11 +62,6 @@ import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
public
void
release
()
{}
@Override
protected
boolean
processDataUpToMuxer
()
{
return
false
;
}
@Override
protected
Format
getMuxerInputFormat
()
{
return
format
;
}
...
...
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/SamplePipeline.java
View file @
e6527ec1
/*
* Copyright 202
1
The Android Open Source Project
* Copyright 202
2
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.
...
...
@@ -16,19 +16,120 @@
package
com
.
google
.
android
.
exoplayer2
.
transformer
;
import
static
com
.
google
.
android
.
exoplayer2
.
util
.
Assertions
.
checkStateNotNull
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.Format
;
import
com.google.android.exoplayer2.decoder.DecoderInputBuffer
;
import
com.google.android.exoplayer2.util.MimeTypes
;
/**
* Pipeline for processing media data.
*
* <p>This pipeline can be used to implement transformations of audio or video samples.
*/
/* package */
interface
SamplePipeline
extends
SampleConsumer
{
/* package */
abstract
class
SamplePipeline
implements
SampleConsumer
{
private
final
long
streamStartPositionUs
;
private
final
MuxerWrapper
muxerWrapper
;
private
final
@C
.
TrackType
int
trackType
;
private
boolean
muxerWrapperTrackAdded
;
public
SamplePipeline
(
Format
inputFormat
,
long
streamStartPositionUs
,
MuxerWrapper
muxerWrapper
)
{
this
.
streamStartPositionUs
=
streamStartPositionUs
;
this
.
muxerWrapper
=
muxerWrapper
;
trackType
=
MimeTypes
.
getTrackType
(
inputFormat
.
sampleMimeType
);
}
protected
static
TransformationException
createNoSupportedMimeTypeException
(
Format
requestedEncoderFormat
)
{
return
TransformationException
.
createForCodec
(
new
IllegalArgumentException
(
"No MIME type is supported by both encoder and muxer."
),
MimeTypes
.
isVideo
(
requestedEncoderFormat
.
sampleMimeType
),
/* isDecoder= */
false
,
requestedEncoderFormat
,
/* mediaCodecName= */
null
,
TransformationException
.
ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED
);
}
@Override
public
boolean
expectsDecodedData
()
{
return
true
;
}
/**
* Processes the input data and returns whether it may be possible to process more data by calling
* this method again.
*/
boolean
processData
()
throws
TransformationException
;
public
final
boolean
processData
()
throws
TransformationException
{
return
feedMuxer
()
||
processDataUpToMuxer
();
}
/** Releases all resources held by the pipeline. */
void
release
();
public
abstract
void
release
();
protected
boolean
processDataUpToMuxer
()
throws
TransformationException
{
return
false
;
}
@Nullable
protected
abstract
Format
getMuxerInputFormat
()
throws
TransformationException
;
@Nullable
protected
abstract
DecoderInputBuffer
getMuxerInputBuffer
()
throws
TransformationException
;
protected
abstract
void
releaseMuxerInputBuffer
()
throws
TransformationException
;
protected
abstract
boolean
isMuxerInputEnded
();
/**
* Attempts to pass encoded data to the muxer, and returns whether it may be possible to pass more
* data immediately by calling this method again.
*/
private
boolean
feedMuxer
()
throws
TransformationException
{
if
(!
muxerWrapperTrackAdded
)
{
@Nullable
Format
inputFormat
=
getMuxerInputFormat
();
if
(
inputFormat
==
null
)
{
return
false
;
}
try
{
muxerWrapper
.
addTrackFormat
(
inputFormat
);
}
catch
(
Muxer
.
MuxerException
e
)
{
throw
TransformationException
.
createForMuxer
(
e
,
TransformationException
.
ERROR_CODE_MUXING_FAILED
);
}
muxerWrapperTrackAdded
=
true
;
}
if
(
isMuxerInputEnded
())
{
muxerWrapper
.
endTrack
(
trackType
);
return
false
;
}
@Nullable
DecoderInputBuffer
muxerInputBuffer
=
getMuxerInputBuffer
();
if
(
muxerInputBuffer
==
null
)
{
return
false
;
}
long
samplePresentationTimeUs
=
muxerInputBuffer
.
timeUs
-
streamStartPositionUs
;
// TODO(b/204892224): Consider subtracting the first sample timestamp from the sample pipeline
// buffer from all samples so that they are guaranteed to start from zero in the output file.
try
{
if
(!
muxerWrapper
.
writeSample
(
trackType
,
checkStateNotNull
(
muxerInputBuffer
.
data
),
muxerInputBuffer
.
isKeyFrame
(),
samplePresentationTimeUs
))
{
return
false
;
}
}
catch
(
Muxer
.
MuxerException
e
)
{
throw
TransformationException
.
createForMuxer
(
e
,
TransformationException
.
ERROR_CODE_MUXING_FAILED
);
}
releaseMuxerInputBuffer
();
return
true
;
}
}
library/transformer/src/main/java/com/google/android/exoplayer2/transformer/VideoTranscodingSamplePipeline.java
View file @
e6527ec1
...
...
@@ -54,7 +54,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import
org.checkerframework.dataflow.qual.Pure
;
/** Pipeline to process, re-encode and mux raw video frames. */
/* package */
final
class
VideoTranscodingSamplePipeline
extends
Base
SamplePipeline
{
/* package */
final
class
VideoTranscodingSamplePipeline
extends
SamplePipeline
{
private
final
FrameProcessor
frameProcessor
;
private
final
ColorInfo
frameProcessorInputColor
;
...
...
@@ -258,11 +258,6 @@ import org.checkerframework.dataflow.qual.Pure;
}
@Override
protected
boolean
processDataUpToMuxer
()
{
return
false
;
}
@Override
@Nullable
protected
Format
getMuxerInputFormat
()
throws
TransformationException
{
return
encoderWrapper
.
getOutputFormat
();
...
...
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