Changeset 593
- Timestamp:
- Feb 27, 2016, 2:31:34 PM (7 years ago)
- Location:
- trunk/Utilities/FFmpeg/DecodeMpeg4Video02
- Files:
-
- 2 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Utilities/FFmpeg/DecodeMpeg4Video02/Application.cpp
r592 r593 46 46 47 47 private: 48 BOOL m_bAnnexB; 48 49 49 50 public: 50 51 // CModule 52 CModule() 53 { 54 m_bAnnexB = FALSE; 55 } 56 HRESULT PreMessageLoop(INT nShowCommand) 57 { 58 _V(__super::PreMessageLoop(nShowCommand)); 59 return S_OK; 60 } 51 61 static BOOL ReadFileData(LPCTSTR pszPath, CHeapPtr<BYTE>& pnData, SIZE_T& nDataSize) 52 62 { … … 67 77 return ReadFileData(pszPath, Blob.m_pnData, Blob.m_nDataSize); 68 78 } 69 HRESULT PreMessageLoop(INT nShowCommand) 70 { 71 _V(__super::PreMessageLoop(nShowCommand)); 72 return S_OK; 79 template <typename LENGTH> 80 static SIZE_T CopyNalUnits(const BYTE* pnSourceData, SIZE_T nSourceDataSize, BYTE* pnDestinationData, SIZE_T nDestinationDataCapacity, BOOL bForceLongStartCode = FALSE) 81 { 82 _A(sizeof (LENGTH) == 2 || sizeof (LENGTH) == 4); 83 BYTE* pnDestinationDataPointer = pnDestinationData; 84 for(; nSourceDataSize; ) 85 { 86 const SIZE_T nUnitDataSize = (typename LENGTH::CBase) *((const LENGTH*) pnSourceData); 87 __D(sizeof (LENGTH) + nUnitDataSize <= nSourceDataSize, HRESULT_FROM_WIN32(ERROR_INVALID_DATA)); 88 __D((SIZE_T) (pnDestinationDataPointer + 4 + nUnitDataSize - pnDestinationData) <= nDestinationDataCapacity, HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)); 89 pnSourceData += sizeof (LENGTH); 90 nSourceDataSize -= sizeof (LENGTH); 91 static const BYTE g_pnStartCode[] = { 0x00, 0x00, 0x00, 0x01 }; 92 BOOL bLongStartCode = FALSE; 93 if(!bForceLongStartCode) 94 { 95 if(nUnitDataSize) 96 { 97 const UINT nNalUnitType = *pnSourceData & 0x1F; 98 if(nNalUnitType >= 6 && nNalUnitType <= 9) // SEI, SPS, PPS, Access Unit Delimiter 99 bLongStartCode = TRUE; 100 } 101 } else 102 bLongStartCode = TRUE; 103 SIZE_T nStartCodeSize = sizeof g_pnStartCode; 104 if(!bLongStartCode) 105 { 106 memcpy(pnDestinationDataPointer, g_pnStartCode + 1, sizeof g_pnStartCode - 1); 107 nStartCodeSize--; 108 } else 109 memcpy(pnDestinationDataPointer, g_pnStartCode, sizeof g_pnStartCode); 110 pnDestinationDataPointer += nStartCodeSize; 111 memcpy(pnDestinationDataPointer, pnSourceData, nUnitDataSize); 112 pnSourceData += nUnitDataSize; 113 nSourceDataSize -= nUnitDataSize; 114 pnDestinationDataPointer += nUnitDataSize; 115 } 116 return pnDestinationDataPointer - pnDestinationData; 73 117 } 74 118 static INT CompareMediaSampleFileNames(LPCTSTR pszNameA, LPCTSTR pszNameB, INT) … … 92 136 { 93 137 CAvPacketT<FALSE> AvPacket(Blob.m_pnData, Blob.m_nDataSize); 138 CBlob LocalBlob; 139 if(m_bAnnexB) 140 { 141 SIZE_T nDataCapacity = 1024 + Blob.m_nDataSize + Blob.m_nDataSize / 8; 142 __D(LocalBlob.m_pnData.Allocate(nDataCapacity), E_OUTOFMEMORY); 143 LocalBlob.m_nDataSize = CopyNalUnits<NUINT32>(Blob.m_pnData, Blob.m_nDataSize, LocalBlob.m_pnData, nDataCapacity); 144 _tprintf(_T("%d Annex B bytes from %d bytes\n"), LocalBlob.m_nDataSize, Blob.m_nDataSize); 145 AvPacket.data = LocalBlob.m_pnData; 146 AvPacket.size = (INT) LocalBlob.m_nDataSize; 147 } 94 148 AvPacket.flags = 0; //AV_PKT_FLAG_KEY; 95 149 AvPacket.dts = AV_NOPTS_VALUE; … … 97 151 SIZE_T nDecodeDataSize; 98 152 const BOOL bFrameAvailable = pAvCodecContext.DecodeVideo(pAvFrame, &AvPacket, nDecodeDataSize); 99 _A(nDecodeDataSize == Blob.m_nDataSize);153 _A(nDecodeDataSize == (SIZE_T) AvPacket.size); 100 154 if(bFrameAvailable) 101 155 ProcessFrame(pAvFrame); … … 125 179 static LPCTSTR g_pszDirectory = 126 180 _T("D:\\Projects\\Alax.Info\\Repository-Private\\Utilities\\DirectShow\\H.264\\tiny.mp4 NAL Units"); 127 static ULONG g_nFrameTime = 250; 181 m_bAnnexB = TRUE; 182 if(m_bAnnexB) 183 _tprintf(_T("Using H.264 Annex B\n")); 128 184 #pragma region Extra Data 129 CBlob AvcDecoderConfigurationRecordBlob; 130 { 131 CRoListT<CBlob> BlobList; 132 CRoArrayT<CBlob*> SpsBlobList, PpsBlobList; 133 for(UINT nIndex = 0; ; nIndex++) 185 if(!m_bAnnexB) 186 { 187 CBlob AvcDecoderConfigurationRecordBlob; 134 188 { 135 // NOTE: Naming sample: MediaType_00 136 const CString sName = AtlFormatString(_T("MediaType_%02d"), nIndex); 137 CPath sPath = Combine(g_pszDirectory, sName); 138 if(!sPath.FileExists()) 139 break; 140 CBlob& Blob = BlobList.GetAt(BlobList.AddTail()); 141 _W(ReadFileData(sPath, Blob)); 142 _tprintf(_T("Read %d bytes from %s\n"), Blob.m_nDataSize, sName); 143 if(Blob.m_nDataSize < 1) 144 continue; 145 const UINT nNalUnitType = Blob.m_pnData[0] & 0x1F; 146 if(nNalUnitType == 7) 147 SpsBlobList.Add(&Blob); 148 else 149 if(nNalUnitType == 8) 150 PpsBlobList.Add(&Blob); 151 //else 152 // continue; 153 } 154 if(!SpsBlobList.IsEmpty() || !PpsBlobList.IsEmpty()) 155 { 156 // NOTE: See MPEG-4 Part 15, 5.2.4.1.1 Syntax 157 AvcDecoderConfigurationRecordBlob.m_nDataSize = 64 << 10; // 64 KB 158 __D(AvcDecoderConfigurationRecordBlob.m_pnData.Allocate(AvcDecoderConfigurationRecordBlob.m_nDataSize), E_OUTOFMEMORY); 159 BYTE* A = AvcDecoderConfigurationRecordBlob.m_pnData; 160 A[0] = 1; // configurationVersion 161 A[1] = 100; // MPEG-4 Part 10, profile_idc, A.2.4 High profile 162 A[2] = 0; // profile_compatibility 163 A[3] = 40; // MPEG-4 Part 10, level_idc 164 A[4] = 0xFC | 3; // lengthSizeMinusOne, 4 byte long lengths 165 A += 5; 166 BYTE* pnSequenceParameterSetCount = A++; 167 *pnSequenceParameterSetCount = 0xE0 | SpsBlobList.GetCount(); 168 for(auto&& pSpsBlob: SpsBlobList) 169 { 170 *((NUINT16*) A) = (UINT16) pSpsBlob->m_nDataSize; 171 A += sizeof (NUINT16); 172 memcpy(A, pSpsBlob->m_pnData, pSpsBlob->m_nDataSize); 173 A += pSpsBlob->m_nDataSize; 189 CRoListT<CBlob> BlobList; 190 CRoArrayT<CBlob*> SpsBlobList, PpsBlobList; 191 for(UINT nIndex = 0; ; nIndex++) 192 { 193 // NOTE: Naming sample: MediaType_00 194 const CString sName = AtlFormatString(_T("MediaType_%02d"), nIndex); 195 CPath sPath = Combine(g_pszDirectory, sName); 196 if(!sPath.FileExists()) 197 break; 198 CBlob& Blob = BlobList.GetAt(BlobList.AddTail()); 199 _W(ReadFileData(sPath, Blob)); 200 _tprintf(_T("Read %d bytes from %s\n"), Blob.m_nDataSize, sName); 201 if(Blob.m_nDataSize < 1) 202 continue; 203 const UINT nNalUnitType = Blob.m_pnData[0] & 0x1F; 204 if(nNalUnitType == 7) 205 SpsBlobList.Add(&Blob); 206 else 207 if(nNalUnitType == 8) 208 PpsBlobList.Add(&Blob); 209 //else 210 // continue; 174 211 } 175 BYTE* pnPictureParameterSetCount = A++; 176 *pnPictureParameterSetCount = 0x00 | PpsBlobList.GetCount(); 177 for(auto&& pPpsBlob: PpsBlobList) 178 { 179 *((NUINT16*) A) = (UINT16) pPpsBlob->m_nDataSize; 180 A += sizeof (NUINT16); 181 memcpy(A, pPpsBlob->m_pnData, pPpsBlob->m_nDataSize); 182 A += pPpsBlob->m_nDataSize; 212 if(!SpsBlobList.IsEmpty() || !PpsBlobList.IsEmpty()) 213 { 214 // NOTE: See MPEG-4 Part 15, 5.2.4.1.1 Syntax 215 AvcDecoderConfigurationRecordBlob.m_nDataSize = 64 << 10; // 64 KB 216 __D(AvcDecoderConfigurationRecordBlob.m_pnData.Allocate(AvcDecoderConfigurationRecordBlob.m_nDataSize), E_OUTOFMEMORY); 217 BYTE* A = AvcDecoderConfigurationRecordBlob.m_pnData; 218 A[0] = 1; // configurationVersion 219 A[1] = 100; // MPEG-4 Part 10, profile_idc, A.2.4 High profile 220 A[2] = 0; // profile_compatibility 221 A[3] = 40; // MPEG-4 Part 10, level_idc 222 A[4] = 0xFC | 3; // lengthSizeMinusOne, 4 byte long lengths 223 A += 5; 224 BYTE* pnSequenceParameterSetCount = A++; 225 *pnSequenceParameterSetCount = 0xE0 | SpsBlobList.GetCount(); 226 for(auto&& pSpsBlob: SpsBlobList) 227 { 228 *((NUINT16*) A) = (UINT16) pSpsBlob->m_nDataSize; 229 A += sizeof (NUINT16); 230 memcpy(A, pSpsBlob->m_pnData, pSpsBlob->m_nDataSize); 231 A += pSpsBlob->m_nDataSize; 232 } 233 BYTE* pnPictureParameterSetCount = A++; 234 *pnPictureParameterSetCount = 0x00 | PpsBlobList.GetCount(); 235 for(auto&& pPpsBlob: PpsBlobList) 236 { 237 *((NUINT16*) A) = (UINT16) pPpsBlob->m_nDataSize; 238 A += sizeof (NUINT16); 239 memcpy(A, pPpsBlob->m_pnData, pPpsBlob->m_nDataSize); 240 A += pPpsBlob->m_nDataSize; 241 } 242 _A((SIZE_T) (A - AvcDecoderConfigurationRecordBlob.m_pnData) <= AvcDecoderConfigurationRecordBlob.m_nDataSize); 243 AvcDecoderConfigurationRecordBlob.m_nDataSize = A - AvcDecoderConfigurationRecordBlob.m_pnData; 244 pAvCodecContext->extradata_size = (int) AvcDecoderConfigurationRecordBlob.m_nDataSize; 245 pAvCodecContext->extradata = (BYTE*) AvcDecoderConfigurationRecordBlob.m_pnData; 183 246 } 184 _A((SIZE_T) (A - AvcDecoderConfigurationRecordBlob.m_pnData) <= AvcDecoderConfigurationRecordBlob.m_nDataSize);185 AvcDecoderConfigurationRecordBlob.m_nDataSize = A - AvcDecoderConfigurationRecordBlob.m_pnData;186 pAvCodecContext->extradata_size = (int) AvcDecoderConfigurationRecordBlob.m_nDataSize;187 pAvCodecContext->extradata = (BYTE*) AvcDecoderConfigurationRecordBlob.m_pnData;188 247 } 189 248 }
Note: See TracChangeset
for help on using the changeset viewer.