camcordermmfplugin/mediarecorder/Src/CCMRMDFVideoRecorder.cpp
changeset 42 605672cc2a86
parent 17 880d946921e4
equal deleted inserted replaced
39:e80a5e3e883f 42:605672cc2a86
  3170     TRAPD(error, (tmp = static_cast<TPtr8*>(buffer->DataL(0))));
  3170     TRAPD(error, (tmp = static_cast<TPtr8*>(buffer->DataL(0))));
  3171     if ( tmp != aPicture->iData.iRawData )
  3171     if ( tmp != aPicture->iData.iRawData )
  3172         {
  3172         {
  3173         // pictures are returned in different order than they were sent
  3173         // pictures are returned in different order than they were sent
  3174 		RPointerArray<MFrameBuffer> buffers;
  3174 		RPointerArray<MFrameBuffer> buffers;
  3175         buffers.Append(buffer);
  3175         TInt bufError = buffers.Append(buffer);
  3176 
  3176         VRASSERT( bufError == KErrNone );
       
  3177         
  3177         TUint i;
  3178         TUint i;
  3178         for ( i = 1; i < iNumCameraBuffers; i++ )
  3179         for ( i = 1; i < iNumCameraBuffers; i++ )
  3179             {
  3180             {
  3180             buffers.Append(reinterpret_cast<MFrameBuffer*>(iSourceFifo->Get()));
  3181             bufError = buffers.Append(reinterpret_cast<MFrameBuffer*>(iSourceFifo->Get()));
       
  3182             VRASSERT( bufError == KErrNone );
  3181 
  3183 
  3182             TRAP(error, (tmp = static_cast<TPtr8*>(buffers[i]->DataL(0))));
  3184             TRAP(error, (tmp = static_cast<TPtr8*>(buffers[i]->DataL(0))));
  3183             if ( tmp == aPicture->iData.iRawData )
  3185             if ( tmp == aPicture->iData.iRawData )
  3184                 {
  3186                 {
  3185                 // Found it! Put the retrieved buffers back to the queue
  3187                 // Found it! Put the retrieved buffers back to the queue
  3205     buffer->Release();
  3207     buffer->Release();
  3206     buffer = NULL;
  3208     buffer = NULL;
  3207 
  3209 
  3208     iEncoderInputQueueLength--;
  3210     iEncoderInputQueueLength--;
  3209 
  3211 
  3210 
       
  3211     // save the picture holder to fifo
  3212     // save the picture holder to fifo
  3212     TRAPD( err, iCodingFifo->PutL( reinterpret_cast<TAny*>(aPicture) ));
  3213     TRAPD( err, iCodingFifo->PutL( reinterpret_cast<TAny*>(aPicture) ));
  3213     if ( err != KErrNone )
  3214     if ( err != KErrNone )
  3214         {
  3215         {
  3215         // OOM, inform error and stop operation
  3216         // OOM, inform error and stop operation
  3524             else if ( iVideoBufferType == CCMRMediaBuffer::EVideoH264NAL )
  3525             else if ( iVideoBufferType == CCMRMediaBuffer::EVideoH264NAL )
  3525                 {// H.264 AVC NAL /  EDuGenericPayload / NAL encapsulation
  3526                 {// H.264 AVC NAL /  EDuGenericPayload / NAL encapsulation
  3526                 // Removes SPS & PPS from first frame from encoder to avoid situation where its both in
  3527                 // Removes SPS & PPS from first frame from encoder to avoid situation where its both in
  3527                 // .mp4 file metadata and in bitstream of video track.
  3528                 // .mp4 file metadata and in bitstream of video track.
  3528                 // Make sure buffer contains only one frame and rewrite encapsulation to make sure its ok.
  3529                 // Make sure buffer contains only one frame and rewrite encapsulation to make sure its ok.
  3529                 RemoveNalDecSpecInfoHeader( reinterpret_cast<TDesC8*>(&iOutputVideoBuffer->iData) );
  3530                 TRAPD( error, RemoveNalDecSpecInfoHeaderL( reinterpret_cast<TDesC8*>(&iOutputVideoBuffer->iData) ) );
       
  3531                 if ( error != KErrNone )
       
  3532                     {
       
  3533                     PRINT((_L("CCMRVideoRecorder::GetNextBuffer() RemoveNalDecSpecInfoHeaderL error %d"), error ));
       
  3534                     DoSendEventToClient( KCMRRunTimeError, error );
       
  3535                     return NULL;
       
  3536                     }
  3530                 outputMediaBufferSet = ETrue;
  3537                 outputMediaBufferSet = ETrue;
  3531                 }
  3538                 }
  3532             else if ( iVideoBufferType == CCMRMediaBuffer::EVideoH264Bytestream )
  3539             else if ( iVideoBufferType == CCMRMediaBuffer::EVideoH264Bytestream )
  3533                 {// H.264 AVC NAL /  EDuElementarystream / Bytestream
  3540                 {// H.264 AVC NAL /  EDuElementarystream / Bytestream
  3534                 // Removes SPS & PPS from first frame from encoder to avoid situation where its both in
  3541                 // Removes SPS & PPS from first frame from encoder to avoid situation where its both in
  3874         }
  3881         }
  3875     return headerLength;
  3882     return headerLength;
  3876     }
  3883     }
  3877 
  3884 
  3878 // -----------------------------------------------------------------------------
  3885 // -----------------------------------------------------------------------------
  3879 // CCMRVideoRecorder::RemoveNalDecSpecInfoHeader( TDesC8* aVideoBuffer )
  3886 // CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL( TDesC8* aVideoBuffer )
  3880 // Removes decoder configuration info (SPS & PPS) from first NAL encapsulated H.264/AVC video buffer
  3887 // Removes decoder configuration info (SPS & PPS) from first NAL encapsulated H.264/AVC video buffer
  3881 // from encoder to avoid situation where its both in .mp4 file metadata and in bitstream of video track.
  3888 // from encoder to avoid situation where its both in .mp4 file metadata and in bitstream of video track.
  3882 // Makes sure buffer contains only one frame and rewrite encapsulation to make sure its ok.
  3889 // Makes sure buffer contains only one frame and rewrite encapsulation to make sure its ok.
  3883 // -----------------------------------------------------------------------------
  3890 // -----------------------------------------------------------------------------
  3884 //
  3891 //
  3885 TInt CCMRVideoRecorder::RemoveNalDecSpecInfoHeader( TDesC8* aVideoBuffer )
  3892 TInt CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL( TDesC8* aVideoBuffer )
  3886 	{
  3893 	{
  3887 	// H.264 AVC NAL /  EDuGenericPayload / NAL encapsulation
  3894 	// H.264 AVC NAL /  EDuGenericPayload / NAL encapsulation
  3888 
  3895 
  3889     // Get reference to the buffer
  3896     // Get reference to the buffer
  3890     TPtr8* ptr = reinterpret_cast<TPtr8*>(aVideoBuffer);
  3897     TPtr8* ptr = reinterpret_cast<TPtr8*>(aVideoBuffer);
  3899     TInt firstCopiedNAL = 0;
  3906     TInt firstCopiedNAL = 0;
  3900     TInt nalCount = 0;
  3907     TInt nalCount = 0;
  3901     RArray<TInt> nalSizes;
  3908     RArray<TInt> nalSizes;
  3902     RArray<TInt> nalStarts;
  3909     RArray<TInt> nalStarts;
  3903 
  3910 
  3904     PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeader() in, length: %d "), buffer.Length() ));
  3911     PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL() in, length: %d "), buffer.Length() ));
  3905 
  3912 
  3906 	// There should be enough data for the NAL header + frame
  3913 	// There should be enough data for the NAL header + frame
  3907     if ( buffer.Length() > 12 )
  3914     if ( buffer.Length() > 12 )
  3908         {
  3915         {
  3909         // Offset to the end and get NAL unit count
  3916         // Offset to the end and get NAL unit count
  3923             frameStart = TInt(buffer[offset]) +
  3930             frameStart = TInt(buffer[offset]) +
  3924                         (TInt(buffer[offset + 1]) << 8) +
  3931                         (TInt(buffer[offset + 1]) << 8) +
  3925                         (TInt(buffer[offset + 2]) << 16) +
  3932                         (TInt(buffer[offset + 2]) << 16) +
  3926                         (TInt(buffer[offset + 3]) << 24);
  3933                         (TInt(buffer[offset + 3]) << 24);
  3927 
  3934 
  3928             PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeader() NAL unit %d frame start: %d "), i, frameStart ));
  3935             PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL() NAL unit %d frame start: %d "), i, frameStart ));
  3929 
  3936 
  3930             // Get frame size
  3937             // Get frame size
  3931             offset += 4;
  3938             offset += 4;
  3932             frameSize = TInt(buffer[offset]) +
  3939             frameSize = TInt(buffer[offset]) +
  3933                        (TInt(buffer[offset + 1]) << 8) +
  3940                        (TInt(buffer[offset + 1]) << 8) +
  3934                        (TInt(buffer[offset + 2]) << 16) +
  3941                        (TInt(buffer[offset + 2]) << 16) +
  3935                        (TInt(buffer[offset + 3]) << 24);
  3942                        (TInt(buffer[offset + 3]) << 24);
  3936 
  3943 
  3937            PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeader() NAL unit %d frame size: %d "), i, frameSize ));
  3944            PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL() NAL unit %d frame size: %d "), i, frameSize ));
  3938            bufType = buffer[frameStart] & 0x1F;
  3945            bufType = buffer[frameStart] & 0x1F;
  3939            PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeader() NAL unit %d type: %d "), i, bufType ));
  3946            PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL() NAL unit %d type: %d "), i, bufType ));
  3940            if ( bufType != 7 && //SPS
  3947            if ( bufType != 7 && //SPS
  3941                 bufType != 8 )//PPS
  3948                 bufType != 8 )//PPS
  3942                {
  3949                {
  3943                // we found first NAL unit that isn't SPS or PPS
  3950                // we found first NAL unit that isn't SPS or PPS
  3944                nalSizes.Append(frameSize);
  3951                nalSizes.AppendL(frameSize);
  3945                if (firstCopiedNAL==0)
  3952                if (firstCopiedNAL==0)
  3946                    {
  3953                    {
  3947                    firstCopiedNAL = frameStart;
  3954                    firstCopiedNAL = frameStart;
  3948                    }
  3955                    }
  3949                nalStarts.Append(frameStart-firstCopiedNAL);               
  3956                nalStarts.AppendL(frameStart-firstCopiedNAL);               
  3950                totalNALLength = frameStart+frameSize-firstCopiedNAL;
  3957                totalNALLength = frameStart+frameSize-firstCopiedNAL;
  3951                PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeader() new total length: %d, padding: %d "), totalNALLength, totalNALLength%4 ));
  3958                PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL() new total length: %d, padding: %d "), totalNALLength, totalNALLength%4 ));
  3952                totalNALLength += totalNALLength%4;
  3959                totalNALLength += totalNALLength%4;
  3953                }
  3960                }
  3954            }
  3961            }
  3955 
  3962 
  3956         // The buffer should have enough space for the new NAL header
  3963         // The buffer should have enough space for the new NAL header
  3957 
  3964 
  3958         // We need to write a new NAL header just after the frame end
  3965         // We need to write a new NAL header just after the frame end
  3959         PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeader() writing new header.")));
  3966         PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL() writing new header.")));
  3960         offset = firstCopiedNAL + totalNALLength;
  3967         offset = firstCopiedNAL + totalNALLength;
  3961         
  3968         
  3962         if ( (offset + nalSizes.Count()*8 + 4) > buffer.Length() ) 
  3969         if ( (offset + nalSizes.Count()*8 + 4) > buffer.Length() ) 
  3963             {
  3970             {
  3964             PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeader() Fatal error, cannot create header, non-align 32bit encoder output buffer.")));
  3971             PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL() Fatal error, cannot create header, non-align 32bit encoder output buffer.")));
  3965             VRASSERT(0);            
  3972             VRASSERT(0);            
  3966             }
  3973             }
  3967 
  3974 
  3968         for (TInt j=0; j<nalSizes.Count(); j++)
  3975         for (TInt j=0; j<nalSizes.Count(); j++)
  3969             {
  3976             {
  3970             PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeader() new header, unit: %d, start: %d, size: %d."), j, nalStarts[j], nalSizes[j] ));            
  3977             PRINT((_L("CCMRVideoRecorder::RemoveNalDecSpecInfoHeaderL() new header, unit: %d, start: %d, size: %d."), j, nalStarts[j], nalSizes[j] ));            
  3971             // Write NAL unit start position
  3978             // Write NAL unit start position
  3972             buffer[offset + 0] = TUint8(nalStarts[j] & 0xff);
  3979             buffer[offset + 0] = TUint8(nalStarts[j] & 0xff);
  3973             buffer[offset + 1] = TUint8((nalStarts[j] >> 8) & 0xff);
  3980             buffer[offset + 1] = TUint8((nalStarts[j] >> 8) & 0xff);
  3974             buffer[offset + 2] = TUint8((nalStarts[j] >> 16) & 0xff);
  3981             buffer[offset + 2] = TUint8((nalStarts[j] >> 16) & 0xff);
  3975             buffer[offset + 3] = TUint8((nalStarts[j] >> 24) & 0xff);
  3982             buffer[offset + 3] = TUint8((nalStarts[j] >> 24) & 0xff);