Skip to content

Commit 5e1cf3a

Browse files
author
Android (Google) Code Review
committed
Merge change 4836 into donut
* changes: OMX M4V encoding drops the first I frame
2 parents d73587e + c665b71 commit 5e1cf3a

File tree

2 files changed

+78
-53
lines changed

2 files changed

+78
-53
lines changed

nodes/pvomxencnode/src/pvmf_omx_enc_node.cpp

+65-48
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,9 @@ PVMFOMXEncNode::PVMFOMXEncNode(int32 aPriority) :
848848
iVideoEncodeParam.iRVLCEnable = false;
849849
iVideoEncodeParam.iIFrameInterval = DEFAULT_I_FRAME_INTERVAL;
850850
iVideoEncodeParam.iBufferDelay = (float)0.2;
851-
iVideoEncodeParam.iContentType = EI_H263;
851+
iVideoEncodeParam.iShortHeader = false;
852+
iVideoEncodeParam.iDataPartitioning = false;
853+
iVideoEncodeParam.iResyncMarker = true;
852854

853855
// set the default rate control type to variable bit rate control
854856
// since it has better performance
@@ -2524,16 +2526,8 @@ bool PVMFOMXEncNode::SetMP4EncoderParameters()
25242526

25252527
//Set the parameters now
25262528
ErrCorrType.nPortIndex = iOutputPortIndex;
2527-
if (iVideoEncodeParam.iContentType == EI_M4V_STREAMING)
2528-
{
2529-
ErrCorrType.bEnableDataPartitioning = OMX_TRUE;
2530-
ErrCorrType.bEnableResync = OMX_TRUE;
2531-
}
2532-
else
2533-
{
2534-
ErrCorrType.bEnableDataPartitioning = OMX_FALSE;
2535-
ErrCorrType.bEnableResync = OMX_FALSE;
2536-
}
2529+
ErrCorrType.bEnableDataPartitioning = ((iVideoEncodeParam.iDataPartitioning == true) ? OMX_TRUE : OMX_FALSE);
2530+
ErrCorrType.bEnableResync = ((iVideoEncodeParam.iResyncMarker == true) ? OMX_TRUE : OMX_FALSE);
25372531

25382532
// extra parameters - hardcoded
25392533
ErrCorrType.bEnableHEC = OMX_FALSE;
@@ -4923,16 +4917,18 @@ OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aC
49234917
uint32 bufLen = (uint32) aBuffer->nFilledLen;
49244918

49254919
// in case of mp4 streaming and the very 1st buffer, save vol header separately
4926-
if ((iOutFormat == PVMF_MIME_M4V) && (iVideoEncodeParam.iContentType == EI_M4V_STREAMING)
4927-
&& (iFrameCounter == 1))
4920+
if ((iOutFormat == PVMF_MIME_M4V) && (iFrameCounter == 1))
49284921
{
49294922

49304923
// save the first buffer since this is the VOL header
4931-
49324924
uint refCounterSize = oscl_mem_aligned_size(sizeof(OsclRefCounterDA));
49334925
OsclMemoryFragment volHeader;
4926+
4927+
int vol_len = aBuffer->nFilledLen;
4928+
bool frameInVolHdr = CheckM4vVopStartCode(pBufdata, &vol_len);
4929+
49344930
volHeader.ptr = NULL;
4935-
volHeader.len = aBuffer->nFilledLen; // vol header size should be (28)
4931+
volHeader.len = vol_len;
49364932
uint8* memBuffer = (uint8*)iAlloc.allocate(refCounterSize + volHeader.len);
49374933
oscl_memset(memBuffer, 0, refCounterSize + volHeader.len);
49384934
OsclRefCounter* refCounter = OSCL_PLACEMENT_NEW(memBuffer, OsclRefCounterDA(memBuffer, (OsclDestructDealloc*) & iAlloc));
@@ -4945,9 +4941,17 @@ OMX_ERRORTYPE PVMFOMXEncNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aC
49454941
// save in class variable
49464942
iVolHeader = OsclRefCounterMemFrag(volHeader, refCounter, volHeader.len);
49474943

4948-
// release the OMX buffer
4949-
iOutBufMemoryPool->deallocate(pContext);
4950-
return OMX_ErrorNone;
4944+
if (frameInVolHdr == false)
4945+
{
4946+
// release the OMX buffer
4947+
iOutBufMemoryPool->deallocate(pContext);
4948+
return OMX_ErrorNone;
4949+
}
4950+
else // there is a frame in this buffer, update the pointer and continue to process it.
4951+
{
4952+
pBufdata += vol_len;
4953+
bufLen -= vol_len;
4954+
}
49514955
}
49524956

49534957
if (iFrameCounter == 1)
@@ -5315,7 +5319,7 @@ bool PVMFOMXEncNode::QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediada
53155319
// Check if Fsi needs to be sent (VOL header)
53165320
if (sendYuvFsi)
53175321
{
5318-
if (iVideoEncodeParam.iContentType == EI_M4V_STREAMING)
5322+
if (iOutFormat == PVMF_MIME_M4V)
53195323
{
53205324
mediaDataOut->setFormatSpecificInfo(iVolHeader);
53215325

@@ -8326,20 +8330,10 @@ OSCL_EXPORT_REF bool PVMFOMXEncNode::SetDataPartitioning(bool aDataPartitioning)
83268330
break;
83278331
}
83288332

8329-
if (iVideoEncodeParam.iContentType == EI_H263 || iVideoEncodeParam.iContentType == EI_H264)
8330-
{
8331-
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
8332-
(0, "PVMFOMXEncNode-%s::SetDataPartitioning: Error data partitioning not supported for H263 or H264", iNodeTypeId));
8333+
iVideoEncodeParam.iDataPartitioning = aDataPartitioning;
83338334

8334-
// ignore the error
8335-
return true;
8336-
//return false;
8337-
}
8338-
8339-
if (aDataPartitioning)
8340-
iVideoEncodeParam.iContentType = EI_M4V_STREAMING;
8341-
else
8342-
iVideoEncodeParam.iContentType = EI_M4V_DOWNLOAD;
8335+
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
8336+
(0, "PVMFOMXEncNode-%s::SetDataPartitioning Called", iNodeTypeId));
83438337

83448338
return true;
83458339
}
@@ -8404,16 +8398,8 @@ OSCL_EXPORT_REF bool PVMFOMXEncNode::SetRVLC(bool aRVLC)
84048398
break;
84058399
}
84068400

8407-
if (iVideoEncodeParam.iContentType == EI_H263 || iVideoEncodeParam.iContentType == EI_H264)
8408-
{
8409-
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
8410-
(0, "PVMFOMXEncNode-%s::SetRVLC : RVLC not supported for H263 or H264", iNodeTypeId));
8411-
8412-
// ignore the error
8413-
return true;
8414-
}
8415-
84168401
iVideoEncodeParam.iRVLCEnable = aRVLC;
8402+
84178403
return true;
84188404
}
84198405

@@ -8443,7 +8429,7 @@ OSCL_EXPORT_REF bool PVMFOMXEncNode::GetVolHeader(OsclRefCounterMemFrag& aVolHea
84438429
return false;
84448430
}
84458431

8446-
if ((iVideoEncodeParam.iContentType == EI_H263) || (iVideoEncodeParam.iContentType == EI_H264))
8432+
if (iOutFormat != PVMF_MIME_M4V)
84478433
{
84488434
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
84498435
(0, "PVMFOMXEncNode-%s::GetVolHeader: Error - VOL header only for M4V encode", iNodeTypeId));
@@ -8452,12 +8438,12 @@ OSCL_EXPORT_REF bool PVMFOMXEncNode::GetVolHeader(OsclRefCounterMemFrag& aVolHea
84528438

84538439
uint8 *ptr = (uint8 *) iVolHeader.getMemFragPtr();
84548440
//If data partioning mode
8455-
if (iVideoEncodeParam.iContentType == EI_M4V_STREAMING)
8441+
if (iVideoEncodeParam.iDataPartitioning == true)
84568442
{
84578443
ptr[iVolHeader.getMemFragSize() - 1] = 0x8F;
84588444
}
84598445
//else combined mode
8460-
else if (iVideoEncodeParam.iContentType == EI_M4V_DOWNLOAD)
8446+
else
84618447
{
84628448
ptr[iVolHeader.getMemFragSize() - 1] = 0x1F;
84638449
}
@@ -8525,23 +8511,19 @@ PVMFStatus PVMFOMXEncNode::SetCodecType(PVMFFormatType aCodec)
85258511

85268512
if (aCodec == PVMF_MIME_H2631998)
85278513
{
8528-
iVideoEncodeParam.iContentType = EI_H263;
85298514
iOutFormat = PVMF_MIME_H2631998;
85308515
}
85318516
else if (aCodec == PVMF_MIME_H2632000)
85328517
{
8533-
iVideoEncodeParam.iContentType = EI_H263;
85348518
iOutFormat = PVMF_MIME_H2632000;
85358519
}
85368520
else if (aCodec == PVMF_MIME_M4V)
85378521
{
8538-
iVideoEncodeParam.iContentType = EI_M4V_STREAMING;
85398522
iOutFormat = PVMF_MIME_M4V;
85408523
}
85418524
else if (aCodec == PVMF_MIME_H264_VIDEO_RAW ||
85428525
aCodec == PVMF_MIME_H264_VIDEO_MP4)
85438526
{
8544-
iVideoEncodeParam.iContentType = EI_H264;
85458527
iOutFormat = aCodec;
85468528
}
85478529
else if (aCodec == PVMF_MIME_AMR_IETF ||
@@ -9920,3 +9902,38 @@ bool PVMFOMXEncNode::AVCAnnexBGetNALUnit(uint8 *bitstream, uint8 **nal_unit, int
99209902

99219903
return true;
99229904
}
9905+
9906+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
9907+
bool PVMFOMXEncNode::CheckM4vVopStartCode(uint8* data, int* len)
9908+
{
9909+
int32 count = 0;
9910+
int32 i = *len;
9911+
9912+
if (i < 4) // at least the size of frame header
9913+
{
9914+
return false;
9915+
}
9916+
while (--i)
9917+
{
9918+
if ((count > 1) && (data[0] == 0x01) && (data[1] == 0xB6))
9919+
{
9920+
i += 2;
9921+
break;
9922+
}
9923+
9924+
if (*data++)
9925+
count = 0;
9926+
else
9927+
count++;
9928+
}
9929+
9930+
// i is number of bytes left (including 00 00 01 B6)
9931+
if (i > 0)
9932+
{
9933+
*len = (*len - i - 1); // len before finding VOP start code
9934+
return true;
9935+
}
9936+
9937+
return false;
9938+
}
9939+

nodes/pvomxencnode/src/pvmf_omx_enc_node.h

+13-5
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,6 @@ typedef struct PV_VideoEncodeParam
573573
bool iEnableFrameQuality;
574574

575575

576-
/** Specifies the type of the access whether it is streaming, EI_H263, EI_M4V_STREAMING
577-
(data partitioning mode) or download, EI_M4V_DOWNLOAD (combined mode).*/
578-
EncContentType iContentType;
579-
580-
581576
/** Specifies high quality but also high complexity mode for rate control. */
582577
bool iRDOptimal;
583578

@@ -601,6 +596,18 @@ typedef struct PV_VideoEncodeParam
601596
control the average number of bits spent to meet the target bit rate. */
602597
bool iNoFrameSkip;
603598

599+
600+
/** Specify short header mode in MPEG4 */
601+
bool iShortHeader;
602+
603+
/** Specifies whether data partitioning mode is used or not. Has no meaning if encoding H.263 or short header */
604+
bool iDataPartitioning;
605+
606+
607+
/** Specifies whether Resync markers are used or not Has no meaning if iDataPartitioning is on */
608+
bool iResyncMarker;
609+
610+
604611
/** Specifies whether RVLC (reversible VLC) is to be used or not.
605612
*/
606613
bool iRVLCEnable;
@@ -1139,6 +1146,7 @@ class PVMFOMXEncNode
11391146

11401147
bool ParseFullAVCFramesIntoNALs(OMX_BUFFERHEADERTYPE* aOutputBuffer);
11411148
bool AVCAnnexBGetNALUnit(uint8 *bitstream, uint8 **nal_unit, int32 *size, bool getPtrOnly);
1149+
bool CheckM4vVopStartCode(uint8* data, int* len);
11421150

11431151
friend class PVMFOMXEncPort;
11441152

0 commit comments

Comments
 (0)