MP4Encoder Class Reference

Implementation of Adaptor that takes UncompressedVideoFrame as input and returns an CompressedVideoFrame as output. <short description="">. More...

#include <MP4Encoder.hpp>

Inheritance diagram for MP4Encoder:

VideoAdaptor Adaptor List of all members.

Public Member Functions

 MP4Encoder (VideoESInfo *pESInfo, u32 targetBitRate, u32 frameRate, u32 uiKeyFrameInterval=300, u32 numBFrames=0, UncompressedVideoFrame::ColorSpace colorSpace=UncompressedVideoFrame::ColorSpaceI420, MP4Decoder::eCoderType coderType=MP4Decoder::XVID, enum CodecID outputFormat=CODEC_ID_MPEG4, char *mp4EncoderConfig=NULL)
 Constructor.
virtual ~MP4Encoder ()
 Destructor.
list< Frame * > adapt (Frame *frm)
 YUVFrame in - MPGFrame out.
list< Frame * > close ()
 Flush all buffered MPGFrame objects (if any).
Adaptorclone ()
 Not implemented.
void initialize ()
 Initialize internal data structures.
void setCoderType (MP4Decoder::eCoderType ct)
u32 getTranscodingCosts () const
 returns adaptation costs (CPU only).

Static Public Member Functions

ffmpegColorSpace mapToFFMPEGColorspace (UncompressedVideoFrame::ColorSpace colorSpace)
 Mapping function between MP4Decoders colorspace (defined in meColorSpace) and FFMPEG codec colorspace.
u8 * createNewHeader (VideoESInfo *vid, u32 targetBitRate, u32 width, u32 height, u32 uiKeyFrameInterval, int framerate, u32 *headerSize)

Detailed Description

Implementation of Adaptor that takes UncompressedVideoFrame as input and returns an CompressedVideoFrame as output. <short description="">.

Author:
Michael Kropfberger and Peter Schojer
Version:
Id
MP4Encoder.hpp,v 1.16 2005/05/31 06:24:58 mkropfbe Exp

Definition at line 67 of file MP4Encoder.hpp.


Constructor & Destructor Documentation

MP4Encoder::MP4Encoder VideoESInfo *  pESInfo,
u32  targetBitRate,
u32  frameRate,
u32  uiKeyFrameInterval = 300,
u32  numBFrames = 0,
UncompressedVideoFrame::ColorSpace  colorSpace = UncompressedVideoFrame::ColorSpaceI420,
MP4Decoder::eCoderType  coderType = MP4Decoder::XVID,
enum CodecID  outputFormat = CODEC_ID_MPEG4,
char *  mp4EncoderConfig = NULL
 

Constructor.

Creates a MP4Encoder instance. Do set attributes of pESInfo object carefully. Width, Height, and FPS must match the YUV input!

Parameters:
pESInfo Pointer to ESInfo object with proper encoding parameters.
targetBitRate is set in bits/second
outputFormat which video format should be created as output, will be ignored when XVid is used for encoding which only allows for CODEC_ID_MPEG4 Used attributes of ESInfo: avgBandwidth, width, height, FPS (via getFPS()). Width, Height, and FPS must match the YUV input.

Referenced by clone().


Member Function Documentation

list< Frame * > MP4Encoder::adapt Frame frm  )  [virtual]
 

YUVFrame in - MPGFrame out.

Input YUVFrame object will be deleted in this method! Adaptor implementation for YUVFrame objects.

Parameters:
*frm Pointer to YUVFrame object.
Returns:
List containing MPGFrame objects. Will contain in general only one MPGFrame object unless B frame support is activated in the XviD library.

Reimplemented from Adaptor.

Definition at line 106 of file MP4Encoder.cpp.

References CompressedVideoFrame::detectFrameType(), Frame::getAU(), Frame::getMediaTimeScale(), Frame::getType(), initialize(), Frame::setAU(), and Frame::setMediaTimeScale().

00106 { 00107 CompressedVideoFrame *mpgFrame = NULL; 00108 list < Frame * >frmList; 00109 int iFramesize = 0; 00110 if (!initialized) 00111 initialize(); 00112 if (!initialized) 00113 return frmList; 00114 00115 if ((muiFrameNumber % muiKeyFrameInterval) == 0) 00116 iFramesize = EncodeFrame(mpEncoderHandle, (char *) frm->getAU()->payload, 00117 mpOutBuf, mColorSpace, 1); 00118 else 00119 iFramesize = EncodeFrame(mpEncoderHandle, (char *) frm->getAU()->payload, 00120 mpOutBuf, mColorSpace, 0); 00121 00122 dprintf_full("MP4Encoder::adapt Encode Frame No %d compressed size: %d, first bytes: %x %x %x %x\n", 00123 muiFrameNumber, iFramesize,mpOutBuf[0],mpOutBuf[1],mpOutBuf[2],mpOutBuf[3]); 00124 if (iFramesize > 0) { 00125 00126 AU *pAU = new AU(frm->getAU()); 00127 u8 *payload = new u8[iFramesize]; 00128 00129 memcpy(payload, mpOutBuf, iFramesize); 00130 00131 // First frame is tricky: 00132 // - obtain headers to set decoderconfig in ESInfo 00133 // - remove header from payload, otherwise it will exist two times. 00134 // FIXME by mike: why should we need this?? 00135 // even worse, we need this header, if it wasn't sent via net RTSP/SDP 00136 00137 // Derive headers for ESInfo object from first frame 00138 if (muiFrameNumber == 0) { 00139 u32 uiVESHeaderLen = iFramesize; 00140 int i; 00141 u32 ch = 0; 00142 u32 startCode = 0; 00143 bool foundVOPcode = false; 00144 00145 // Search for first VOP startcode in freshly encoded frame 00146 foundVOPcode = false; 00147 i = 0; 00148 startCode = 0; 00149 while (!foundVOPcode) { 00150 if (i >= iFramesize) { 00151 dprintf_err("MP4Encoder::adapt:FATAL: couldnt find frame MPEG-4 VOP code (00 00 01 B6) in newly coded frame!!!\n"); 00152 exit(1); 00153 } 00154 ch = (u32) payload[i]; 00155 startCode = (startCode << 8) | ch; 00156 if (startCode == 0x1B6) { 00157 uiVESHeaderLen = i - 4; 00158 foundVOPcode = true; 00159 } 00160 i++; 00161 } 00162 00163 // Create new header 00164 es->setDecoderConfig(payload,uiVESHeaderLen); //deep copy first bytes... 00165 es->clearDecConfUpdated(); 00166 00167 00168 if (!foundVOPcode) { //assume, there is just the header (by xvid) 00169 // iFramesize = 0; 00170 //delete[] payload; 00171 } 00172 00173 /* 00174 // remove header from payload 00175 //FIXME by mike: why should we need this?? 00176 //even worse, we need this header, if it wasn't sent via net RTSP/SDP 00177 memmove(payload, payload + uiVESHeaderLen+1, iFramesize - uiVESHeaderLen-1); 00178 iFramesize -= uiVESHeaderLen+1; 00179 */ 00180 } 00181 00182 if (iFramesize != 0) { 00183 // All the other frames is easy, just memcopy output. 00184 pAU->size = iFramesize; 00185 pAU->payload = payload; 00186 00187 /* 00188 if ((muiFrameNumber % muiKeyFrameInterval) == 0) 00189 mpgFrame = new CompressedVideoFrame(Frame::I_VOP, es->getWidth(), es->getHeight()); 00190 else 00191 mpgFrame = new CompressedVideoFrame(Frame::P_VOP, es->getWidth(), es->getHeight()); 00192 */ 00193 mpgFrame = new CompressedVideoFrame(Frame::UNKNOWN_VOP, es->getWidth(), es->getHeight()); 00194 00195 mpgFrame->detectFrameType(); 00196 mpgFrame->setAU(pAU); 00197 mpgFrame->setMediaTimeScale(frm->getMediaTimeScale()); 00198 frmList.push_back(mpgFrame); 00199 dprintf_full("MP4Encoder::adapt: first 4 bytes of %i bytes, %s frameNo %i, CTS %u: %x %x %x %x\r\n", 00200 pAU->size, Frame::VOPTypeToChar(mpgFrame->getType()), muiFrameNumber, 00201 mpgFrame->getAU()->cts, mpgFrame->getAU()->payload[0], 00202 mpgFrame->getAU()->payload[1], 00203 mpgFrame->getAU()->payload[2], 00204 mpgFrame->getAU()->payload[3]); 00205 muiFrameNumber++; 00206 } 00207 } 00208 00209 return frmList; 00210 }

Adaptor * MP4Encoder::clone  )  [virtual]
 

Not implemented.

Returns:
Defaults to NULL.

Implements Adaptor.

Definition at line 222 of file MP4Encoder.cpp.

References MP4Encoder().

00222 { 00223 char* copyEncoderConfig=NULL; 00224 if(mpEncoderHandle && meCoder != MP4Decoder::XVID) { 00225 #ifdef ENABLE_FFMPEG 00226 AVCodec *codec=NULL; 00227 /* Make sure that the required encoder exists in the ffmpeg library */ 00228 codec = avcodec_find_encoder(this->outputFormat); 00229 if(codec) { 00230 AVCodecContext* srcClone = avcodec_alloc_context(); 00231 avcodec_get_context_defaults(srcClone); 00232 00233 AVCodecContext* src=(AVCodecContext*) mpEncoderHandle; 00234 // don't do a memcpy --> pointers! 00235 srcClone->codec=codec; 00236 srcClone->b_frame_strategy=src->b_frame_strategy; 00237 srcClone->b_quant_factor=src->b_quant_factor; 00238 srcClone->b_quant_offset=src->b_quant_offset; 00239 srcClone->bit_rate=src->bit_rate; 00240 srcClone->rtp_payload_size=src->rtp_payload_size; 00241 srcClone->width=src->width; 00242 srcClone->height=src->height; 00243 srcClone->gop_size=srcClone->gop_size; 00244 srcClone->qmin=src->qmin; 00245 srcClone->qmax=src->qmax; 00246 srcClone->max_b_frames=src->max_b_frames; 00247 srcClone->sample_aspect_ratio.den=src->sample_aspect_ratio.den; 00248 srcClone->sample_aspect_ratio.num=src->sample_aspect_ratio.num; 00249 srcClone->rc_max_rate=src->rc_max_rate; 00250 srcClone->rc_min_rate=src->rc_min_rate; 00251 srcClone->mb_qmax=src->mb_qmax; 00252 srcClone->mb_qmin=src->mb_qmin; 00253 srcClone->time_base=src->time_base; 00254 // open the codec for encoding 00255 if (avcodec_open(srcClone, codec) < 0) { 00256 printf("MP4Encoder::clone(): Could not open codec\n"); 00257 av_free(srcClone); 00258 } 00259 else 00260 copyEncoderConfig=(char*)srcClone; 00261 } 00262 #else 00263 dprintf_err("MP4Encoder::clone: compiled without ffmpeg support!\n"); 00264 exit(1); 00265 #endif 00266 } 00267 00268 return new MP4Encoder(es,muiTargetBitrate,frameRate,muiKeyFrameInterval,numBFrames, 00269 mColorSpace,meCoder,outputFormat,copyEncoderConfig); 00270 }

list< Frame * > MP4Encoder::close  )  [virtual]
 

Flush all buffered MPGFrame objects (if any).

Returns:
List of MPGFrame objects

Reimplemented from Adaptor.

Definition at line 214 of file MP4Encoder.cpp.

00214 { 00215 list < Frame * >frmList; 00216 00217 return frmList; 00218 }

u32 MP4Encoder::getTranscodingCosts  )  const [virtual]
 

returns adaptation costs (CPU only).

Decoding costs depend directly on the number of out YUV pixels and frames decoded per second (FIXME: codec not supported)

Implements Adaptor.

Definition at line 381 of file MP4Encoder.cpp.

00381 { 00382 return (u32)(es->getWidth()*es->getHeight()*es->getFPS()*2); 00383 }

void MP4Encoder::initialize  )  [virtual]
 

Initialize internal data structures.

Implements Adaptor.

Definition at line 80 of file MP4Encoder.cpp.

Referenced by adapt().

00080 { 00081 if(initialized) 00082 return; 00083 dprintf_full("MP4Encoder::initialize() Handle: %p Width: %i Height: %i BW: %i kbps FPS: %i numBFrames: %i\n", 00084 mpEncoderHandle, es->getWidth(), es->getHeight(), 00085 muiTargetBitrate / 1024, frameRate, numBFrames); 00086 initialized = true; 00087 if (EncoderInit(&mpEncoderHandle, es->getWidth(), es->getHeight(), 00088 muiTargetBitrate, frameRate, numBFrames, muiKeyFrameInterval, es) != ERR_OK) { 00089 dprintf_err("MP4Encoder::initialize: Error creating encoder instance!\n"); 00090 initialized = false; 00091 } 00092 assert(mpEncoderHandle); 00093 es->setAvgBandwidth(muiTargetBitrate); 00094 muiFrameNumber = 0; 00095 }

ffmpegColorSpace MP4Encoder::mapToFFMPEGColorspace UncompressedVideoFrame::ColorSpace  colorSpace  )  [static]
 

Mapping function between MP4Decoders colorspace (defined in meColorSpace) and FFMPEG codec colorspace.

See also:
meColorSpace

mapToXVIDColorspace

Definition at line 353 of file MP4Encoder.cpp.

References UncompressedVideoFrame::ColorSpace.

00353 { 00354 ffmpegColorSpace ret = FFMPEGColorSpaceUnknown; 00355 00356 switch (colorSpace) { 00357 case UncompressedVideoFrame::ColorSpaceYV12: 00358 ret = FFMPEGColorSpaceYV12; 00359 break; 00360 case UncompressedVideoFrame::ColorSpaceRGB24: 00361 ret = FFMPEGColorSpaceRGB24; 00362 break; 00363 case UncompressedVideoFrame::ColorSpaceI420: 00364 ret = FFMPEGColorSpaceI420; 00365 break; 00366 case UncompressedVideoFrame::ColorSpaceRGB32: 00367 ret = FFMPEGColorSpaceRGB32; 00368 break; 00369 default: 00370 ret = FFMPEGColorSpaceUnknown; 00371 break; 00372 } 00373 00374 return ret; 00375 }


The documentation for this class was generated from the following files: