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 |
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); |
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); |