Skip to content

Commit

Permalink
Add IsTemporalUnitAvailable function.
Browse files Browse the repository at this point in the history
This a convenience function provided to users to call in a while loop condition in order to know when they should stop querying for output temporal units.

PiperOrigin-RevId: 728764403
  • Loading branch information
Googler authored and jwcullen committed Feb 19, 2025
1 parent e0b17be commit baf63e5
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
4 changes: 4 additions & 0 deletions iamf/api/iamf_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ absl::Status IamfDecoder::Decode(absl::Span<const uint8_t> bitstream) {
return absl::OkStatus();
}

bool IamfDecoder::IsTemporalUnitAvailable() {
return !rendered_pcm_samples_.empty();
}

bool IamfDecoder::IsDescriptorProcessingComplete() {
return obu_processor_ != nullptr;
}
Expand Down
9 changes: 9 additions & 0 deletions iamf/api/iamf_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,15 @@ class IamfDecoder {
absl::Status GetOutputTemporalUnit(
std::vector<uint8_t>& output_decoded_temporal_unit);

/*!\brief Returns true iff a decoded temporal unit is available.
*
* This function can be used to determine when the user should call
* GetOutputTemporalUnit().
*
* \return true iff a decoded temporal unit is available.
*/
bool IsTemporalUnitAvailable();

/*!\brief Returns true iff the descriptor OBUs have been parsed.
*
* This function can be used for determining when configuration setters that
Expand Down
38 changes: 37 additions & 1 deletion iamf/api/tests/iamf_decoder_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,11 @@ TEST(CreateFromDescriptors, FailsWithDescriptorObuInSubsequentDecode) {
EXPECT_FALSE(decoder->Decode(second_chunk).ok());
}

TEST(Decode, SucceeedsWithSeparatePushesOfDescriptorAndTemporalUnits) {
TEST(Decode, SucceedsWithSeparatePushesOfDescriptorAndTemporalUnits) {
std::vector<uint8_t> source_data = GenerateBasicDescriptorObus();
auto decoder = IamfDecoder::CreateFromDescriptors(source_data);
ASSERT_THAT(decoder, IsOk());
EXPECT_FALSE(decoder->IsTemporalUnitAvailable());
AudioFrameObu audio_frame(ObuHeader(), kFirstSubstreamId,
kEightSampleAudioFrame);
auto temporal_unit = SerializeObus({&audio_frame});
Expand Down Expand Up @@ -197,5 +198,40 @@ TEST(Decode, SucceedsWithMultipleTemporalUnits) {
EXPECT_THAT(decoder->Decode(source_data), IsOk());
}

TEST(IsTemporalUnitAvailable, ReturnsFalseAfterCreateFromDescriptorObus) {
auto decoder =
IamfDecoder::CreateFromDescriptors(GenerateBasicDescriptorObus());
ASSERT_THAT(decoder, IsOk());
EXPECT_FALSE(decoder->IsTemporalUnitAvailable());
}

TEST(IsTemporalUnitAvailable, ReturnsTrueAfterDecodingOneTemporalUnit) {
auto decoder = IamfDecoder::Create();
ASSERT_THAT(decoder, IsOk());
std::vector<uint8_t> source_data = GenerateBasicDescriptorObus();
AudioFrameObu audio_frame(ObuHeader(), kFirstSubstreamId,
kEightSampleAudioFrame);
auto temporal_unit = SerializeObus({&audio_frame});
source_data.insert(source_data.end(), temporal_unit.begin(),
temporal_unit.end());

ASSERT_THAT(decoder->Decode(source_data), IsOk());
EXPECT_TRUE(decoder->IsTemporalUnitAvailable());
}

TEST(IsTemporalUnitAvailable, ReturnsTrueAfterDecodingMultipleTemporalUnits) {
auto decoder = IamfDecoder::Create();
ASSERT_THAT(decoder, IsOk());
std::vector<uint8_t> source_data = GenerateBasicDescriptorObus();
AudioFrameObu audio_frame(ObuHeader(), kFirstSubstreamId,
kEightSampleAudioFrame);
auto temporal_units = SerializeObus({&audio_frame, &audio_frame});
source_data.insert(source_data.end(), temporal_units.begin(),
temporal_units.end());

ASSERT_THAT(decoder->Decode(source_data), IsOk());
EXPECT_TRUE(decoder->IsTemporalUnitAvailable());
}

} // namespace
} // namespace iamf_tools

0 comments on commit baf63e5

Please sign in to comment.