Skip to content

Instantly share code, notes, and snippets.

@FlyingJester
Created June 18, 2014 20:47
Show Gist options
  • Select an option

  • Save FlyingJester/43b91d439296f52a2e9d to your computer and use it in GitHub Desktop.

Select an option

Save FlyingJester/43b91d439296f52a2e9d to your computer and use it in GitHub Desktop.
{
class MediaCodecData : public MediaData {
mcdecode::Decoder *mDecoder;
int mBuffer;
MediaData::Type mType;
public:
MediaCodecData(MediaData::Type aType,int64_t aOffset,int64_t aTimestamp,
int64_t aDuration, mcdecode::Decoder *aDecoder, int aBuffer)
: MediaData(aType,aOffset,aTimestamp,aDuration)
, mDecoder(aDecoder)
, mBuffer(aBuffer)
, mType(aType) { printf_stderr("We will want to release buffer %i at some point.\n", aBuffer);}
virtual ~MediaCodecData(){
printf_stderr("Media Codec: Releaseing output buffer number %i...\n", mBuffer);
mDecoder->ReleaseOutputBuffer(mBuffer, false);
printf_stderr("Media Codec: Released output buffer number %i successfully.\n", mBuffer);
}
};
// Auto-free MC resources
MediaCodecBuffer::MediaCodecBuffer()
{
mDecoder = nullptr;
mBufferIndex = -1;
}
MediaCodecBuffer::MediaCodecBuffer(int32_t aBufferIndex, int32_t aOffset,
int32_t aSize, int32_t aTime,
int32_t aFlags, mcdecode::Decoder *aDecoder)
{
mDecoder = aDecoder;
mBufferIndex = aBufferIndex;
mOffset = aOffset;
mSize = aSize;
mTime = aTime;
mFlags = aFlags;
}
MediaCodecBuffer::~MediaCodecBuffer()
{
printf_stderr("Media Codec: Queueing inputbuffer %i from AutoPtr.\n", mBufferIndex);
printf_stderr("Media Codec: Stats: mOffset %i\tmSize %i\tmTime %i\tmFlags %i (FLAGS NOT suppressed to 0 in actual call).\n", mOffset, mSize, mTime, mFlags);
if( (mDecoder != nullptr) && (mBufferIndex >= 0) ){
mDecoder->QueueInputBuffer(mBufferIndex, mOffset, mSize, mTime, mFlags);
printf_stderr("Media Codec: Inputbuffer %i queued successfuly.\n", mBufferIndex);
}
else
printf_stderr("Media Codec: Decided not to queue inputbuffer %i\n", mBufferIndex);
}
nsresult AndroidInputLoader::Run(){
printf_stderr("Media Codec: Run is starting!\n");
int lInputIndex = mDecoder->DequeueInputBuffer(-1);
printf_stderr("Media Codec: DequeueInputBuffer has completed.\n");
// Don't worry, aSample. This smart pointer will...take care...of you.
nsAutoPtr<mp4_demuxer::MP4Sample> apSample(mSample);
// Until we chose to forget, any return means we had errors.
nsAutoPtr<ErrorCaller<MediaDataDecoderCallback> > lErrorCallback(
new ErrorCaller<MediaDataDecoderCallback>(mCallback));
if(lInputIndex<0){
return NS_ERROR_NOT_AVAILABLE;
}
// Ensures that the buffer at the dequeued index is returned to MediaCodec.
// The size is set to zero until we know how large of a buffer we have.
// This ensures that if we return before we are sure we are in bounds,
// we won't crash from the Java side.
nsAutoPtr<MediaCodecBuffer> lAutoInputBuffer(new MediaCodecBuffer(
lInputIndex, 0, 0, 1,
((mSample->is_sync_point)?MediaCodec::getBUFFER_FLAG_SYNC_FRAME():0),
mDecoder));
printf_stderr("Media Codec: Asking for JNI environment.\n");
JNIEnv *aJEnv = GetJNIForThread();
printf_stderr("Media Codec: Got JNI environment.\n");
if(aJEnv == nullptr){
return NS_ERROR_FAILURE;
}
mInputBuffers = mDecoder->GetInputBuffers();
mOutputBuffers = mDecoder->GetOutputBuffers();
printf_stderr("Media Codec: Inside the input loader, the Input buffer is %p and the Output buffer is %p.\n", mInputBuffers, mOutputBuffers);
{
int bufferNum = aJEnv->GetArrayLength(mInputBuffers);
printf_stderr("Media Codec: The input buffer array is %i buffers long.\n", bufferNum);
}
jobject lJInBuffer = aJEnv->GetObjectArrayElement(mInputBuffers,
lInputIndex);
printf_stderr("Media Codec: Got the buffer.\n");
if(lJInBuffer == nullptr){
return NS_ERROR_FAILURE;
}
MCByteBuffer *lInBuffer = MCByteBuffer::Wrap(lJInBuffer);
if(lInBuffer==nullptr){
return NS_ERROR_FAILURE;
}
size_t lMaximumPayload = lInBuffer->GetCapacity();
printf_stderr("Media Codec: Got the buffer's capacity.\n");
if(lMaximumPayload>mSample->size)
lMaximumPayload=mSample->size;
printf_stderr("Media Codec: The maximum payload was %i. The max of %i"
" (sample) and %i (buffer)\n", lMaximumPayload,
mSample->size, lInBuffer->GetCapacity());
lAutoInputBuffer->mSize = lMaximumPayload;
// If we are lucky the buffer is backed with a native array. Then we can
// write directly into its raw buffer.
// TODO: Find out why this is crashing.
void *rawBuffer = nullptr;
if(lJInBuffer!=nullptr && lInBuffer->IsDirect() && false)
rawBuffer = aJEnv->GetDirectBufferAddress(lJInBuffer);
if(rawBuffer != nullptr){
//Fill the input buffer.
memcpy(rawBuffer, mSample->data, lMaximumPayload);
}
else{
// We have to make do by slowly placing the pieces in one after another
// Do this in chunks of 8 bytes until there are < 8 bytes eft, put the
// remains in by char.
//delete lInBuffer;
//mozilla::widget::android::ByteBuffer *lByteBuffer = mozilla::widget::android::ByteBuffer::Wrap(lJInBuffer);
if(lInBuffer == nullptr){
return NS_ERROR_FAILURE;
}
size_t i = 0;
for(; i < lMaximumPayload; i+=sizeof(int64_t)){
lInBuffer->PutLong(i, mSample->data[i]);
}
for(; i < lMaximumPayload; i++){
lInBuffer->PutChar1(i, mSample->data[i]);
}
}
printf_stderr("Media Codec: Ride it out at %s %i.\n",
__func__, __LINE__);
// Input successfully placed. We don't need to worry about this anymore.
lErrorCallback->forget();
//delete lAutoInputBuffer.forget();
// mDecoder->QueueInputBuffer(lInputIndex, 0, lMaximumPayload, 1000000, (mSample->is_sync_point)?MediaCodec::getBUFFER_FLAG_SYNC_FRAME():0);
//printf_stderr("Media Codec: Inputbuffer %i queued successfuly.\n", lInputIndex);
// Check to see if we can get any output:
int lOutputIndex;
do{
BufferInfo *lInfo = new BufferInfo();
lOutputIndex = mDecoder->DequeueOutputBuffer(nullptr, 1000000);
printf_stderr("Media Codec: The output buffer we got is %i\n", lOutputIndex);
if(lOutputIndex == MediaCodec::getINFO_OUTPUT_BUFFERS_CHANGED()){
printf_stderr("Media Codec: The output buffers have moved. Old location %p\n", mOutputBuffers);
mOutputBuffers = mDecoder->GetOutputBuffers();
printf_stderr("Media Codec: The output buffers have moved. New location %p\n", mOutputBuffers);
continue;
}
if(lOutputIndex<0){
printf_stderr("Media Codec: Announcing out of input.\n");
mCallback->InputExhausted();
continue;
}
/*
enum Type {
AUDIO_SAMPLES = 0,
VIDEO_FRAME = 1
};
*/
printf_stderr("Media Codec: Announcing output.\n");
mCallback->Output(
new MediaCodecData(mType, 0, mSample->composition_timestamp,
mSample->duration, mDecoder, lOutputIndex));
} while(lOutputIndex>=0);
printf_stderr("Media Codec: Riding out Input.\n");
return NS_OK;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment