video_xvid.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:4k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  * Dave Mackie dmackie@cisco.com
  20.  */
  21. #include "mp4live.h"
  22. #include "video_xvid.h"
  23. CXvidVideoEncoder::CXvidVideoEncoder()
  24. {
  25. m_xvidHandle = NULL;
  26. m_vopBuffer = NULL;
  27. m_vopBufferLength = 0;
  28. }
  29. bool CXvidVideoEncoder::Init(CLiveConfig* pConfig, bool realTime)
  30. {
  31. m_pConfig = pConfig;
  32. XVID_INIT_PARAM xvidInitParams;
  33. memset(&xvidInitParams, 0, sizeof(xvidInitParams));
  34. if (xvid_init(NULL, 0, &xvidInitParams, NULL) != XVID_ERR_OK) {
  35. error_message("Failed to initialize Xvid");
  36. return false;
  37. }
  38. XVID_ENC_PARAM xvidEncParams;
  39. memset(&xvidEncParams, 0, sizeof(xvidEncParams));
  40. xvidEncParams.width = m_pConfig->m_videoWidth;
  41. xvidEncParams.height = m_pConfig->m_videoHeight;
  42. xvidEncParams.fincr = 1001;
  43. xvidEncParams.fbase = 
  44. (int)(1001 * m_pConfig->GetFloatValue(CONFIG_VIDEO_FRAME_RATE) + 0.5);
  45. xvidEncParams.bitrate = 
  46. m_pConfig->GetIntegerValue(CONFIG_VIDEO_BIT_RATE) * 1000;
  47. xvidEncParams.rc_buffersize = 16;
  48. xvidEncParams.min_quantizer = 1;
  49. xvidEncParams.max_quantizer = 31;
  50. xvidEncParams.max_key_interval = (int) 
  51. (m_pConfig->GetFloatValue(CONFIG_VIDEO_FRAME_RATE) 
  52.  * m_pConfig->GetFloatValue(CONFIG_VIDEO_KEY_FRAME_INTERVAL));
  53. if (xvidEncParams.max_key_interval == 0) {
  54. xvidEncParams.max_key_interval = 1;
  55. if (xvid_encore(NULL, XVID_ENC_CREATE, &xvidEncParams, NULL) 
  56.   != XVID_ERR_OK) {
  57. error_message("Failed to initialize Xvid encoder");
  58. return false;
  59. }
  60. m_xvidHandle = xvidEncParams.handle; 
  61. memset(&m_xvidFrame, 0, sizeof(m_xvidFrame));
  62. m_xvidFrame.general = XVID_HALFPEL | XVID_H263QUANT;
  63. if (!realTime) {
  64. m_xvidFrame.general |= XVID_INTER4V;
  65. m_xvidFrame.motion = 
  66. PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 
  67. | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8;
  68. } else {
  69. m_xvidFrame.motion = PMV_QUICKSTOP16;
  70. }
  71. m_xvidFrame.colorspace = XVID_CSP_I420;
  72. m_xvidFrame.quant = 0;
  73. return true;
  74. }
  75. bool CXvidVideoEncoder::EncodeImage(
  76. u_int8_t* pY, 
  77. u_int8_t* pU, 
  78. u_int8_t* pV, 
  79. u_int32_t yStride,
  80. u_int32_t uvStride,
  81. bool wantKeyFrame)
  82. {
  83. m_vopBuffer = (u_int8_t*)malloc(m_pConfig->m_videoMaxVopSize);
  84. if (m_vopBuffer == NULL) {
  85. return false;
  86. }
  87. m_xvidFrame.image_y = pY;
  88. m_xvidFrame.image_u = pU;
  89. m_xvidFrame.image_v = pV;
  90. m_xvidFrame.stride = yStride;
  91. m_xvidFrame.bitstream = m_vopBuffer;
  92. m_xvidFrame.intra = (wantKeyFrame ? 1 : -1);
  93. if (xvid_encore(m_xvidHandle, XVID_ENC_ENCODE, &m_xvidFrame, 
  94.   &m_xvidResult) != XVID_ERR_OK) {
  95. debug_message("Xvid can't encode frame!");
  96. return false;
  97. }
  98. m_vopBufferLength = m_xvidFrame.length;
  99. return true;
  100. }
  101. bool CXvidVideoEncoder::GetEncodedImage(
  102. u_int8_t** ppBuffer, u_int32_t* pBufferLength)
  103. {
  104. *ppBuffer = m_vopBuffer;
  105. *pBufferLength = m_vopBufferLength;
  106. m_vopBuffer = NULL;
  107. m_vopBufferLength = 0;
  108. return true;
  109. }
  110. bool CXvidVideoEncoder::GetReconstructedImage(
  111. u_int8_t* pY, u_int8_t* pU, u_int8_t* pV)
  112. {
  113. imgcpy(pY, (u_int8_t*)m_xvidResult.image_y,
  114. m_pConfig->m_videoWidth, 
  115. m_pConfig->m_videoHeight,
  116. m_xvidResult.stride_y);
  117. imgcpy(pU, (u_int8_t*)m_xvidResult.image_u,
  118. m_pConfig->m_videoWidth / 2, 
  119. m_pConfig->m_videoHeight / 2,
  120. m_xvidResult.stride_uv);
  121. imgcpy(pV, (u_int8_t*)m_xvidResult.image_v,
  122. m_pConfig->m_videoWidth / 2, 
  123. m_pConfig->m_videoHeight / 2,
  124. m_xvidResult.stride_uv);
  125. return true;
  126. }
  127. void CXvidVideoEncoder::Stop()
  128. {
  129. xvid_encore(m_xvidHandle, XVID_ENC_DESTROY, NULL, NULL);
  130. m_xvidHandle = NULL;
  131. }