FFMPEG Plugin: Refactor scope of fTempPacket in audio path.
- There are two main reasons for this refactoring:
1. Prepare using FFMPEGs functionality of audio frame start time assignment
(instead of rolling it ourself) like already done for the video path
(see _LoadNextVideoChunkIfNeededAndAssignStartTime() for reference).
2. Get rid of fChunkBufferOffset (this is a minor reason though).
- Untangle some of the conditional checks to increase readability.
- No functional change intended.
This commit is contained in:
@@ -107,7 +107,6 @@ AVCodecDecoder::AVCodecDecoder()
|
|||||||
|
|
||||||
fChunkBuffer(NULL),
|
fChunkBuffer(NULL),
|
||||||
fVideoChunkBuffer(NULL),
|
fVideoChunkBuffer(NULL),
|
||||||
fChunkBufferOffset(0),
|
|
||||||
fChunkBufferSize(0),
|
fChunkBufferSize(0),
|
||||||
fAudioDecodeError(false),
|
fAudioDecodeError(false),
|
||||||
|
|
||||||
@@ -269,7 +268,6 @@ AVCodecDecoder::SeekedTo(int64 frame, bigtime_t time)
|
|||||||
// responsible for freeing the chunk buffer, too.
|
// responsible for freeing the chunk buffer, too.
|
||||||
fVideoChunkBuffer = NULL;
|
fVideoChunkBuffer = NULL;
|
||||||
fChunkBuffer = NULL;
|
fChunkBuffer = NULL;
|
||||||
fChunkBufferOffset = 0;
|
|
||||||
fChunkBufferSize = 0;
|
fChunkBufferSize = 0;
|
||||||
fDecodedDataBufferOffset = 0;
|
fDecodedDataBufferOffset = 0;
|
||||||
fDecodedDataBufferSize = 0;
|
fDecodedDataBufferSize = 0;
|
||||||
@@ -415,7 +413,6 @@ AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* inOutFormat)
|
|||||||
result, fOutputFrameSize, fOutputFrameCount, fOutputFrameRate);
|
result, fOutputFrameSize, fOutputFrameCount, fOutputFrameRate);
|
||||||
|
|
||||||
fChunkBuffer = NULL;
|
fChunkBuffer = NULL;
|
||||||
fChunkBufferOffset = 0;
|
|
||||||
fChunkBufferSize = 0;
|
fChunkBufferSize = 0;
|
||||||
fAudioDecodeError = false;
|
fAudioDecodeError = false;
|
||||||
fDecodedDataBufferOffset = 0;
|
fDecodedDataBufferOffset = 0;
|
||||||
@@ -665,7 +662,11 @@ AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount,
|
|||||||
status_t
|
status_t
|
||||||
AVCodecDecoder::_DecodeNextAudioFrame()
|
AVCodecDecoder::_DecodeNextAudioFrame()
|
||||||
{
|
{
|
||||||
fDecodedDataSizeInBytes = 0;
|
assert(fTempPacket.size >= 0);
|
||||||
|
assert(fDecodedDataSizeInBytes == 0);
|
||||||
|
// _DecodeNextAudioFrame needs to be called on empty fDecodedData only!
|
||||||
|
// If this assert holds wrong we have a bug somewhere.
|
||||||
|
|
||||||
size_t maximumSizeOfDecodedData = fOutputFrameCount * fOutputFrameSize;
|
size_t maximumSizeOfDecodedData = fOutputFrameCount * fOutputFrameSize;
|
||||||
if (fDecodedData == NULL)
|
if (fDecodedData == NULL)
|
||||||
fDecodedData
|
fDecodedData
|
||||||
@@ -680,10 +681,10 @@ AVCodecDecoder::_DecodeNextAudioFrame()
|
|||||||
"buffer! %ld\n", fDecodedDataBufferSize);
|
"buffer! %ld\n", fDecodedDataBufferSize);
|
||||||
fDecodedDataBufferSize = 0;
|
fDecodedDataBufferSize = 0;
|
||||||
}
|
}
|
||||||
if (fChunkBufferSize < 0) {
|
if (fTempPacket.size < 0) {
|
||||||
fprintf(stderr, "Decoding read past the end of the chunk buffer! "
|
fprintf(stderr, "Decoding read past the end of the temp packet! "
|
||||||
"%ld\n", fChunkBufferSize);
|
"%d\n", fTempPacket.size);
|
||||||
fChunkBufferSize = 0;
|
fTempPacket.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fDecodedDataBufferSize > 0) {
|
if (fDecodedDataBufferSize > 0) {
|
||||||
@@ -705,7 +706,7 @@ AVCodecDecoder::_DecodeNextAudioFrame()
|
|||||||
fStartTime += (bigtime_t)((1000000LL * frames) / fOutputFrameRate);
|
fStartTime += (bigtime_t)((1000000LL * frames) / fOutputFrameRate);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (fChunkBufferSize == 0) {
|
if (fTempPacket.size == 0) {
|
||||||
// Time to read the next chunk buffer. We use a separate
|
// Time to read the next chunk buffer. We use a separate
|
||||||
// media_header, since the chunk header may not belong to
|
// media_header, since the chunk header may not belong to
|
||||||
// the start of the decoded audio frames we return. For
|
// the start of the decoded audio frames we return. For
|
||||||
@@ -726,50 +727,53 @@ AVCodecDecoder::_DecodeNextAudioFrame()
|
|||||||
fChunkBufferSize = 0;
|
fChunkBufferSize = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fChunkBufferOffset = 0;
|
fTempPacket.data
|
||||||
|
= static_cast<uint8_t*>(const_cast<void*>(fChunkBuffer));
|
||||||
|
fTempPacket.size = fChunkBufferSize;
|
||||||
fStartTime = chunkMediaHeader.start_time;
|
fStartTime = chunkMediaHeader.start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
fTempPacket.data = (uint8_t*)fChunkBuffer + fChunkBufferOffset;
|
|
||||||
fTempPacket.size = fChunkBufferSize;
|
|
||||||
|
|
||||||
avcodec_get_frame_defaults(fDecodedDataBuffer);
|
avcodec_get_frame_defaults(fDecodedDataBuffer);
|
||||||
int gotFrame = 0;
|
int gotFrame = 0;
|
||||||
int usedBytes = avcodec_decode_audio4(fContext,
|
int usedBytes = avcodec_decode_audio4(fContext,
|
||||||
fDecodedDataBuffer, &gotFrame, &fTempPacket);
|
fDecodedDataBuffer, &gotFrame, &fTempPacket);
|
||||||
if (usedBytes < 0 && !fAudioDecodeError) {
|
if (usedBytes < 0 && !fAudioDecodeError) {
|
||||||
// Report failure if not done already
|
// Report failure if not done already
|
||||||
|
int32 chunkBufferOffset = fTempPacket.data
|
||||||
|
- static_cast<uint8_t*>(const_cast<void*>(fChunkBuffer));
|
||||||
printf("########### audio decode error, "
|
printf("########### audio decode error, "
|
||||||
"fChunkBufferSize %ld, fChunkBufferOffset %ld\n",
|
"fTempPacket.size %d, fChunkBuffer data offset %ld\n",
|
||||||
fChunkBufferSize, fChunkBufferOffset);
|
fTempPacket.size, chunkBufferOffset);
|
||||||
fAudioDecodeError = true;
|
fAudioDecodeError = true;
|
||||||
}
|
}
|
||||||
if (usedBytes <= 0) {
|
if (usedBytes <= 0) {
|
||||||
// Error or failure to produce decompressed output.
|
// Error or failure to produce decompressed output.
|
||||||
// Skip the chunk buffer data entirely.
|
// Skip the temp packet data entirely.
|
||||||
usedBytes = fChunkBufferSize;
|
fTempPacket.size = 0;
|
||||||
fDecodedDataBufferSize = 0;
|
|
||||||
// Assume the audio decoded until now is broken.
|
// Assume the audio decoded until now is broken.
|
||||||
memset(fDecodedData, 0, decodedData - fDecodedData);
|
memset(fDecodedData, 0, decodedData - fDecodedData);
|
||||||
} else {
|
fDecodedDataBufferOffset = 0;
|
||||||
// Success
|
continue;
|
||||||
fAudioDecodeError = false;
|
|
||||||
if (gotFrame == 1) {
|
|
||||||
fDecodedDataBufferSize = av_samples_get_buffer_size(NULL,
|
|
||||||
fContext->channels, fDecodedDataBuffer->nb_samples,
|
|
||||||
fContext->sample_fmt, 1);
|
|
||||||
if (fDecodedDataBufferSize < 0)
|
|
||||||
fDecodedDataBufferSize = 0;
|
|
||||||
} else
|
|
||||||
fDecodedDataBufferSize = 0;
|
|
||||||
}
|
}
|
||||||
//printf(" chunk size: %d, decoded: %d, used: %d\n",
|
|
||||||
//fTempPacket.size, decodedBytes, usedBytes);
|
|
||||||
|
|
||||||
fChunkBufferOffset += usedBytes;
|
fAudioDecodeError = false;
|
||||||
fChunkBufferSize -= usedBytes;
|
fDecodedDataBufferSize = 0;
|
||||||
fDecodedDataBufferOffset = 0;
|
fDecodedDataBufferOffset = 0;
|
||||||
|
|
||||||
|
fTempPacket.data += usedBytes;
|
||||||
|
fTempPacket.size -= usedBytes;
|
||||||
|
|
||||||
|
bool gotNoAudioFrame = gotFrame == 0;
|
||||||
|
if (gotNoAudioFrame)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fDecodedDataBufferSize = av_samples_get_buffer_size(NULL,
|
||||||
|
fContext->channels, fDecodedDataBuffer->nb_samples,
|
||||||
|
fContext->sample_fmt, 1);
|
||||||
|
if (fDecodedDataBufferSize < 0)
|
||||||
|
fDecodedDataBufferSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fFrame += currentFrameCount;
|
fFrame += currentFrameCount;
|
||||||
fDecodedDataSizeInBytes = currentFrameCount * fOutputFrameSize;
|
fDecodedDataSizeInBytes = currentFrameCount * fOutputFrameSize;
|
||||||
TRACE_AUDIO(" frame count: %lld current: %lld\n", currentFrameCount, fFrame);
|
TRACE_AUDIO(" frame count: %lld current: %lld\n", currentFrameCount, fFrame);
|
||||||
|
|||||||
@@ -114,10 +114,9 @@ private:
|
|||||||
const void* fChunkBuffer;
|
const void* fChunkBuffer;
|
||||||
uint8_t* fVideoChunkBuffer;
|
uint8_t* fVideoChunkBuffer;
|
||||||
// TODO: Remove and use fChunkBuffer again
|
// TODO: Remove and use fChunkBuffer again
|
||||||
// (with type uint8_t*) once the audio path is
|
// (with type uint8_t*) once the audio path
|
||||||
// responsible for freeing the chunk buffer,
|
// is responsible for freeing the chunk
|
||||||
// too.
|
// buffer, too.
|
||||||
int32 fChunkBufferOffset;
|
|
||||||
size_t fChunkBufferSize;
|
size_t fChunkBufferSize;
|
||||||
bool fAudioDecodeError;
|
bool fAudioDecodeError;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user