1 /*! 2 *@page License 3 * 4 * \copy 5 * Copyright (c) 2013, Cisco Systems 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * * Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 */ 34 35 #ifndef WELS_VIDEO_CODEC_SVC_API_H__ 36 #define WELS_VIDEO_CODEC_SVC_API_H__ 37 38 #ifndef __cplusplus 39 #if defined(_MSC_VER) && (_MSC_VER < 1800) 40 typedef unsigned char bool; 41 #else 42 #include <stdbool.h> 43 #endif 44 #endif 45 46 #include "codec_app_def.h" 47 #include "codec_def.h" 48 49 #if defined(_WIN32) || defined(__cdecl) 50 #define EXTAPI __cdecl 51 #else 52 #define EXTAPI 53 #endif 54 55 /** 56 * @file codec_api.h 57 */ 58 59 /** 60 * @page Overview 61 * * This page is for openh264 codec API usage. 62 * * For how to use the encoder,please refer to page UsageExampleForEncoder 63 * * For how to use the decoder,please refer to page UsageExampleForDecoder 64 * * For more detail about ISVEncoder,please refer to page ISVCEncoder 65 * * For more detail about ISVDecoder,please refer to page ISVCDecoder 66 */ 67 68 /** 69 * @page DecoderUsageExample 70 * 71 * @brief 72 * * An example for using the decoder for Decoding only or Parsing only 73 * 74 * Step 1:decoder declaration 75 * @code 76 * 77 * //decoder declaration 78 * ISVCDecoder *pSvcDecoder; 79 * //input: encoded bitstream start position; should include start code prefix 80 * unsigned char *pBuf =...; 81 * //input: encoded bit stream length; should include the size of start code prefix 82 * int iSize =...; 83 * //output: [0~2] for Y,U,V buffer for Decoding only 84 * unsigned char *pData[3] =...; 85 * //in-out: for Decoding only: declare and initialize the output buffer info, this should never co-exist with Parsing only 86 * SBufferInfo sDstBufInfo; 87 * memset(&sDstBufInfo, 0, sizeof(SBufferInfo)); 88 * //in-out: for Parsing only: declare and initialize the output bitstream buffer info for parse only, this should never co-exist with Decoding only 89 * SParserBsInfo sDstParseInfo; 90 * memset(&sDstParseInfo, 0, sizeof(SParserBsInfo)); 91 * sDstParseInfo.pDstBuff = new unsigned char[PARSE_SIZE]; //In Parsing only, allocate enough buffer to save transcoded bitstream for a frame 92 * 93 * @endcode 94 * 95 * Step 2:decoder creation 96 * @code 97 * WelsCreateDecoder(&pSvcDecoder); 98 * @endcode 99 * 100 * Step 3:declare required parameter, used to differentiate Decoding only and Parsing only 101 * @code 102 * SDecodingParam sDecParam = {0}; 103 * sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_AVC; 104 * //for Parsing only, the assignment is mandatory 105 * sDecParam.bParseOnly = true; 106 * @endcode 107 * 108 * Step 4:initialize the parameter and decoder context, allocate memory 109 * @code 110 * pSvcDecoder->Initialize(&sDecParam); 111 * @endcode 112 * 113 * Step 5:do actual decoding process in slice level; 114 * this can be done in a loop until data ends 115 * @code 116 * //for Decoding only 117 * iRet = pSvcDecoder->DecodeFrameNoDelay(pBuf, iSize, pData, &sDstBufInfo); 118 * //or 119 * iRet = pSvcDecoder->DecodeFrame2(pBuf, iSize, pData, &sDstBufInfo); 120 * //for Parsing only 121 * iRet = pSvcDecoder->DecodeParser(pBuf, iSize, &sDstParseInfo); 122 * //decode failed 123 * If (iRet != 0){ 124 * //error handling (RequestIDR or something like that) 125 * } 126 * //for Decoding only, pData can be used for render. 127 * if (sDstBufInfo.iBufferStatus==1){ 128 * //output handling (pData[0], pData[1], pData[2]) 129 * } 130 * //for Parsing only, sDstParseInfo can be used for, e.g., HW decoding 131 * if (sDstBufInfo.iNalNum > 0){ 132 * //Hardware decoding sDstParseInfo; 133 * } 134 * //no-delay decoding can be realized by directly calling DecodeFrameNoDelay(), which is the recommended usage. 135 * //no-delay decoding can also be realized by directly calling DecodeFrame2() again with NULL input, as in the following. In this case, decoder would immediately reconstruct the input data. This can also be used similarly for Parsing only. Consequent decoding error and output indication should also be considered as above. 136 * iRet = pSvcDecoder->DecodeFrame2(NULL, 0, pData, &sDstBufInfo); 137 * //judge iRet, sDstBufInfo.iBufferStatus ... 138 * @endcode 139 * 140 * Step 6:uninitialize the decoder and memory free 141 * @code 142 * pSvcDecoder->Uninitialize(); 143 * @endcode 144 * 145 * Step 7:destroy the decoder 146 * @code 147 * DestroyDecoder(pSvcDecoder); 148 * @endcode 149 * 150 */ 151 152 /** 153 * @page EncoderUsageExample1 154 * 155 * @brief 156 * * An example for using encoder with basic parameter 157 * 158 * Step1:setup encoder 159 * @code 160 * ISVCEncoder* encoder_; 161 * int rv = WelsCreateSVCEncoder (&encoder_); 162 * assert (rv == 0); 163 * assert (encoder_ != NULL); 164 * @endcode 165 * 166 * Step2:initilize with basic parameter 167 * @code 168 * SEncParamBase param; 169 * memset (¶m, 0, sizeof (SEncParamBase)); 170 * param.iUsageType = usageType; //from EUsageType enum 171 * param.fMaxFrameRate = frameRate; 172 * param.iPicWidth = width; 173 * param.iPicHeight = height; 174 * param.iTargetBitrate = 5000000; 175 * encoder_->Initialize (¶m); 176 * @endcode 177 * 178 * Step3:set option, set option during encoding process 179 * @code 180 * encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &g_LevelSetting); 181 * int videoFormat = videoFormatI420; 182 * encoder_->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat); 183 * @endcode 184 * 185 * Step4: encode and store ouput bistream 186 * @code 187 * int frameSize = width * height * 3 / 2; 188 * BufferedData buf; 189 * buf.SetLength (frameSize); 190 * assert (buf.Length() == (size_t)frameSize); 191 * SFrameBSInfo info; 192 * memset (&info, 0, sizeof (SFrameBSInfo)); 193 * SSourcePicture pic; 194 * memset (&pic, 0, sizeof (SsourcePicture)); 195 * pic.iPicWidth = width; 196 * pic.iPicHeight = height; 197 * pic.iColorFormat = videoFormatI420; 198 * pic.iStride[0] = pic.iPicWidth; 199 * pic.iStride[1] = pic.iStride[2] = pic.iPicWidth >> 1; 200 * pic.pData[0] = buf.data(); 201 * pic.pData[1] = pic.pData[0] + width * height; 202 * pic.pData[2] = pic.pData[1] + (width * height >> 2); 203 * for(int num = 0;num<total_num;num++) { 204 * //prepare input data 205 * rv = encoder_->EncodeFrame (&pic, &info); 206 * assert (rv == cmResultSuccess); 207 * if (info.eFrameType != videoFrameTypeSkip) { 208 * //output bitstream handling 209 * } 210 * } 211 * @endcode 212 * 213 * Step5:teardown encoder 214 * @code 215 * if (encoder_) { 216 * encoder_->Uninitialize(); 217 * WelsDestroySVCEncoder (encoder_); 218 * } 219 * @endcode 220 * 221 */ 222 223 /** 224 * @page EncoderUsageExample2 225 * 226 * @brief 227 * * An example for using the encoder with extension parameter. 228 * * The same operation on Step 1,3,4,5 with Example-1 229 * 230 * Step 2:initialize with extension parameter 231 * @code 232 * SEncParamExt param; 233 * encoder_->GetDefaultParams (¶m); 234 * param.iUsageType = usageType; 235 * param.fMaxFrameRate = frameRate; 236 * param.iPicWidth = width; 237 * param.iPicHeight = height; 238 * param.iTargetBitrate = 5000000; 239 * param.bEnableDenoise = denoise; 240 * param.iSpatialLayerNum = layers; 241 * //SM_DYN_SLICE don't support multi-thread now 242 * if (sliceMode != SM_SINGLE_SLICE && sliceMode != SM_DYN_SLICE) 243 * param.iMultipleThreadIdc = 2; 244 * 245 * for (int i = 0; i < param.iSpatialLayerNum; i++) { 246 * param.sSpatialLayers[i].iVideoWidth = width >> (param.iSpatialLayerNum - 1 - i); 247 * param.sSpatialLayers[i].iVideoHeight = height >> (param.iSpatialLayerNum - 1 - i); 248 * param.sSpatialLayers[i].fFrameRate = frameRate; 249 * param.sSpatialLayers[i].iSpatialBitrate = param.iTargetBitrate; 250 * 251 * param.sSpatialLayers[i].sSliceCfg.uiSliceMode = sliceMode; 252 * if (sliceMode == SM_DYN_SLICE) { 253 * param.sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = 600; 254 * param.uiMaxNalSize = 1500; 255 * } 256 * } 257 * param.iTargetBitrate *= param.iSpatialLayerNum; 258 * encoder_->InitializeExt (¶m); 259 * int videoFormat = videoFormatI420; 260 * encoder_->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat); 261 * 262 * @endcode 263 */ 264 265 266 267 268 #ifdef __cplusplus 269 /** 270 * @brief Endocder definition 271 */ 272 class ISVCEncoder { 273 public: 274 /** 275 * @brief Initialize the encoder 276 * @param pParam basic encoder parameter 277 * @return CM_RETURN: 0 - success; otherwise - failed; 278 */ 279 virtual int EXTAPI Initialize (const SEncParamBase* pParam) = 0; 280 281 /** 282 * @brief Initilaize encoder by using extension parameters. 283 * @param pParam extension parameter for encoder 284 * @return CM_RETURN: 0 - success; otherwise - failed; 285 */ 286 virtual int EXTAPI InitializeExt (const SEncParamExt* pParam) = 0; 287 288 /** 289 * @brief Get the default extension parameters. 290 * If you want to change some parameters of encoder, firstly you need to get the default encoding parameters, 291 * after that you can change part of parameters you want to. 292 * @param pParam extension parameter for encoder 293 * @return CM_RETURN: 0 - success; otherwise - failed; 294 * */ 295 virtual int EXTAPI GetDefaultParams (SEncParamExt* pParam) = 0; 296 /// uninitialize the encoder 297 virtual int EXTAPI Uninitialize() = 0; 298 299 /** 300 * @brief Encode one frame 301 * @param kpSrcPic the pointer to the source luminance plane 302 * chrominance data: 303 * CbData = kpSrc + m_iMaxPicWidth * m_iMaxPicHeight; 304 * CrData = CbData + (m_iMaxPicWidth * m_iMaxPicHeight)/4; 305 * the application calling this interface needs to ensure the data validation between the location 306 * @param pBsInfo output bit stream 307 * @return 0 - success; otherwise -failed; 308 */ 309 virtual int EXTAPI EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSInfo* pBsInfo) = 0; 310 311 /** 312 * @brief Encode the parameters from output bit stream 313 * @param pBsInfo output bit stream 314 * @return 0 - success; otherwise - failed; 315 */ 316 virtual int EXTAPI EncodeParameterSets (SFrameBSInfo* pBsInfo) = 0; 317 318 /** 319 * @brief Force encoder to encoder frame as IDR if bIDR set as true 320 * @param bIDR true: force encoder to encode frame as IDR frame;false, return 1 and nothing to do 321 * @return 0 - success; otherwise - failed; 322 */ 323 virtual int EXTAPI ForceIntraFrame (bool bIDR, int iLayerId = -1) = 0; 324 325 /** 326 * @brief Set option for encoder, detail option type, please refer to enumurate ENCODER_OPTION. 327 * @param pOption option for encoder such as InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,... 328 * @return CM_RETURN: 0 - success; otherwise - failed; 329 */ 330 virtual int EXTAPI SetOption (ENCODER_OPTION eOptionId, void* pOption) = 0; 331 332 /** 333 * @brief Get option for encoder, detail option type, please refer to enumurate ENCODER_OPTION. 334 * @param pOption option for encoder such as InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,... 335 * @return CM_RETURN: 0 - success; otherwise - failed; 336 */ 337 virtual int EXTAPI GetOption (ENCODER_OPTION eOptionId, void* pOption) = 0; ~ISVCEncoder()338 virtual ~ISVCEncoder() {} 339 }; 340 341 342 343 /** 344 * @brief Decoder definition 345 */ 346 class ISVCDecoder { 347 public: 348 349 /** 350 * @brief Initilaize decoder 351 * @param pParam parameter for decoder 352 * @return 0 - success; otherwise - failed; 353 */ 354 virtual long EXTAPI Initialize (const SDecodingParam* pParam) = 0; 355 356 /// Uninitialize the decoder 357 virtual long EXTAPI Uninitialize() = 0; 358 359 /** 360 * @brief Decode one frame 361 * @param pSrc the h264 stream to be decoded 362 * @param iSrcLen the length of h264 stream 363 * @param ppDst buffer pointer of decoded data (YUV) 364 * @param pStride output stride 365 * @param iWidth output width 366 * @param iHeight output height 367 * @return 0 - success; otherwise -failed; 368 */ 369 virtual DECODING_STATE EXTAPI DecodeFrame (const unsigned char* pSrc, 370 const int iSrcLen, 371 unsigned char** ppDst, 372 int* pStride, 373 int& iWidth, 374 int& iHeight) = 0; 375 376 /** 377 * @brief For slice level DecodeFrameNoDelay() (4 parameters input), 378 * whatever the function return value is, the output data 379 * of I420 format will only be available when pDstInfo->iBufferStatus == 1,. 380 * This function will parse and reconstruct the input frame immediately if it is complete 381 * It is recommended as the main decoding function for H.264/AVC format input 382 * @param pSrc the h264 stream to be decoded 383 * @param iSrcLen the length of h264 stream 384 * @param ppDst buffer pointer of decoded data (YUV) 385 * @param pDstInfo information provided to API(width, height, etc.) 386 * @return 0 - success; otherwise -failed; 387 */ 388 virtual DECODING_STATE EXTAPI DecodeFrameNoDelay (const unsigned char* pSrc, 389 const int iSrcLen, 390 unsigned char** ppDst, 391 SBufferInfo* pDstInfo) = 0; 392 393 /** 394 * @brief For slice level DecodeFrame2() (4 parameters input), 395 * whatever the function return value is, the output data 396 * of I420 format will only be available when pDstInfo->iBufferStatus == 1,. 397 * (e.g., in multi-slice cases, only when the whole picture 398 * is completely reconstructed, this variable would be set equal to 1.) 399 * @param pSrc the h264 stream to be decoded 400 * @param iSrcLen the length of h264 stream 401 * @param ppDst buffer pointer of decoded data (YUV) 402 * @param pDstInfo information provided to API(width, height, etc.) 403 * @return 0 - success; otherwise -failed; 404 */ 405 virtual DECODING_STATE EXTAPI DecodeFrame2 (const unsigned char* pSrc, 406 const int iSrcLen, 407 unsigned char** ppDst, 408 SBufferInfo* pDstInfo) = 0; 409 410 411 /** 412 * @brief This function gets a decoded ready frame remaining in buffers after the last frame has been decoded. 413 * Use GetOption with option DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER to get the number of frames remaining in buffers. 414 * Note that it is only applicable for profile_idc != 66 415 * @param ppDst buffer pointer of decoded data (YUV) 416 * @param pDstInfo information provided to API(width, height, etc.) 417 * @return 0 - success; otherwise -failed; 418 */ 419 virtual DECODING_STATE EXTAPI FlushFrame (unsigned char** ppDst, 420 SBufferInfo* pDstInfo) = 0; 421 422 /** 423 * @brief This function parse input bitstream only, and rewrite possible SVC syntax to AVC syntax 424 * @param pSrc the h264 stream to be decoded 425 * @param iSrcLen the length of h264 stream 426 * @param pDstInfo bit stream info 427 * @return 0 - success; otherwise -failed; 428 */ 429 virtual DECODING_STATE EXTAPI DecodeParser (const unsigned char* pSrc, 430 const int iSrcLen, 431 SParserBsInfo* pDstInfo) = 0; 432 433 /** 434 * @brief This API does not work for now!! This is for future use to support non-I420 color format output. 435 * @param pSrc the h264 stream to be decoded 436 * @param iSrcLen the length of h264 stream 437 * @param pDst buffer pointer of decoded data (YUV) 438 * @param iDstStride output stride 439 * @param iDstLen bit stream info 440 * @param iWidth output width 441 * @param iHeight output height 442 * @param iColorFormat output color format 443 * @return to do ... 444 */ 445 virtual DECODING_STATE EXTAPI DecodeFrameEx (const unsigned char* pSrc, 446 const int iSrcLen, 447 unsigned char* pDst, 448 int iDstStride, 449 int& iDstLen, 450 int& iWidth, 451 int& iHeight, 452 int& iColorFormat) = 0; 453 454 /** 455 * @brief Set option for decoder, detail option type, please refer to enumurate DECODER_OPTION. 456 * @param pOption option for decoder such as OutDataFormat, Eos Flag, EC method, ... 457 * @return CM_RETURN: 0 - success; otherwise - failed; 458 */ 459 virtual long EXTAPI SetOption (DECODER_OPTION eOptionId, void* pOption) = 0; 460 461 /** 462 * @brief Get option for decoder, detail option type, please refer to enumurate DECODER_OPTION. 463 * @param pOption option for decoder such as OutDataFormat, Eos Flag, EC method, ... 464 * @return CM_RETURN: 0 - success; otherwise - failed; 465 */ 466 virtual long EXTAPI GetOption (DECODER_OPTION eOptionId, void* pOption) = 0; ~ISVCDecoder()467 virtual ~ISVCDecoder() {} 468 }; 469 470 471 extern "C" 472 { 473 #else 474 475 typedef struct ISVCEncoderVtbl ISVCEncoderVtbl; 476 typedef const ISVCEncoderVtbl* ISVCEncoder; 477 struct ISVCEncoderVtbl { 478 479 int (*Initialize) (ISVCEncoder*, const SEncParamBase* pParam); 480 int (*InitializeExt) (ISVCEncoder*, const SEncParamExt* pParam); 481 482 int (*GetDefaultParams) (ISVCEncoder*, SEncParamExt* pParam); 483 484 int (*Uninitialize) (ISVCEncoder*); 485 486 int (*EncodeFrame) (ISVCEncoder*, const SSourcePicture* kpSrcPic, SFrameBSInfo* pBsInfo); 487 int (*EncodeParameterSets) (ISVCEncoder*, SFrameBSInfo* pBsInfo); 488 489 int (*ForceIntraFrame) (ISVCEncoder*, bool bIDR); 490 491 int (*SetOption) (ISVCEncoder*, ENCODER_OPTION eOptionId, void* pOption); 492 int (*GetOption) (ISVCEncoder*, ENCODER_OPTION eOptionId, void* pOption); 493 }; 494 495 typedef struct ISVCDecoderVtbl ISVCDecoderVtbl; 496 typedef const ISVCDecoderVtbl* ISVCDecoder; 497 struct ISVCDecoderVtbl { 498 long (*Initialize) (ISVCDecoder*, const SDecodingParam* pParam); 499 long (*Uninitialize) (ISVCDecoder*); 500 501 DECODING_STATE (*DecodeFrame) (ISVCDecoder*, const unsigned char* pSrc, 502 const int iSrcLen, 503 unsigned char** ppDst, 504 int* pStride, 505 int* iWidth, 506 int* iHeight); 507 508 DECODING_STATE (*DecodeFrameNoDelay) (ISVCDecoder*, const unsigned char* pSrc, 509 const int iSrcLen, 510 unsigned char** ppDst, 511 SBufferInfo* pDstInfo); 512 513 DECODING_STATE (*DecodeFrame2) (ISVCDecoder*, const unsigned char* pSrc, 514 const int iSrcLen, 515 unsigned char** ppDst, 516 SBufferInfo* pDstInfo); 517 518 DECODING_STATE (*FlushFrame) (ISVCDecoder*, unsigned char** ppDst, 519 SBufferInfo* pDstInfo); 520 521 DECODING_STATE (*DecodeParser) (ISVCDecoder*, const unsigned char* pSrc, 522 const int iSrcLen, 523 SParserBsInfo* pDstInfo); 524 525 DECODING_STATE (*DecodeFrameEx) (ISVCDecoder*, const unsigned char* pSrc, 526 const int iSrcLen, 527 unsigned char* pDst, 528 int iDstStride, 529 int* iDstLen, 530 int* iWidth, 531 int* iHeight, 532 int* iColorFormat); 533 534 long (*SetOption) (ISVCDecoder*, DECODER_OPTION eOptionId, void* pOption); 535 long (*GetOption) (ISVCDecoder*, DECODER_OPTION eOptionId, void* pOption); 536 }; 537 #endif 538 539 typedef void (*WelsTraceCallback) (void* ctx, int level, const char* string); 540 541 /** @brief Create encoder 542 * @param ppEncoder encoder 543 * @return 0 - success; otherwise - failed; 544 */ 545 int WelsCreateSVCEncoder (ISVCEncoder** ppEncoder); 546 547 548 /** @brief Destroy encoder 549 * @param pEncoder encoder 550 * @return void 551 */ 552 void WelsDestroySVCEncoder (ISVCEncoder* pEncoder); 553 554 555 /** @brief Get the capability of decoder 556 * @param pDecCapability decoder capability 557 * @return 0 - success; otherwise - failed; 558 */ 559 int WelsGetDecoderCapability (SDecoderCapability* pDecCapability); 560 561 562 /** @brief Create decoder 563 * @param ppDecoder decoder 564 * @return 0 - success; otherwise - failed; 565 */ 566 long WelsCreateDecoder (ISVCDecoder** ppDecoder); 567 568 569 /** @brief Destroy decoder 570 * @param pDecoder decoder 571 * @return void 572 */ 573 void WelsDestroyDecoder (ISVCDecoder* pDecoder); 574 575 /** @brief Get codec version 576 * Note, old versions of Mingw (GCC < 4.7) are buggy and use an 577 * incorrect/different ABI for calling this function, making it 578 * incompatible with MSVC builds. 579 * @return The linked codec version 580 */ 581 OpenH264Version WelsGetCodecVersion (void); 582 583 /** @brief Get codec version 584 * @param pVersion struct to fill in with the version 585 */ 586 void WelsGetCodecVersionEx (OpenH264Version* pVersion); 587 588 #ifdef __cplusplus 589 } 590 #endif 591 592 #endif//WELS_VIDEO_CODEC_SVC_API_H__ 593