MP3Encoder Class Reference

Implementation of Adaptor that takes UncompressedAudioFrame (raw PCM) as input and returns an CompressedAudioFrame (MPEG-1 layer 3 aka mp3) as output. <short description="">. More...

#include <MP3Encoder.hpp>

Inheritance diagram for MP3Encoder:

AudioAdaptor Adaptor List of all members.

Public Member Functions

 MP3Encoder (AudioESInfo *pESInfo, u32 targetBitRate, enum CodecID outputFormat=CODEC_ID_MP3LAME, char *mp4EncoderConfig=NULL)
 Constructor.
virtual ~MP3Encoder ()
 Destructor.
list< Frame * > adapt (Frame *frm)
 raw PCM Frame in - MP3Frame out.
list< Frame * > close ()
 Flush all buffered MPGFrame objects (if any).
Adaptorclone ()
 Not implemented.
void initialize ()
 Initialize internal data structures.
u32 getTranscodingCosts () const
 returns adaptation costs (CPU only) per second! For visual streams they are expressed in pixels/seconds.

Detailed Description

Implementation of Adaptor that takes UncompressedAudioFrame (raw PCM) as input and returns an CompressedAudioFrame (MPEG-1 layer 3 aka mp3) as output. <short description="">.

Author:
Michael Kropfberger
Version:
Id
MP3Encoder.hpp,v 1.2 2005/05/13 18:18:02 mkropfbe Exp

Definition at line 68 of file MP3Encoder.hpp.


Constructor & Destructor Documentation

MP3Encoder::MP3Encoder AudioESInfo *  pESInfo,
u32  targetBitRate,
enum CodecID  outputFormat = CODEC_ID_MP3LAME,
char *  mp4EncoderConfig = NULL
 

Constructor.

Creates a MP3Encoder instance. Do set attributes of pESInfo object carefully.

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 Used attributes of ESInfo: avgBandwidth
Definition at line 49 of file MP3Encoder.cpp.

Referenced by clone().

00050 { 00051 this->mpEncoderHandle = encoderConfig; 00052 es = pESInfo; 00053 muiTargetBitrate = targetBitRate; 00054 initialized = false; 00055 strcpy(name,"MP3Encoder-FFMPEG"); 00056 outputFormat=outFormat; 00057 }


Member Function Documentation

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

raw PCM Frame in - MP3Frame out.

Input raw PCM Frame object will be deleted in this method! Adaptor implementation for raw PCM Frame objects.

Parameters:
*frm Pointer to raw PCM Frame object.
Returns:
List containing MP3Frame objects. Will contain in general only one MPGFrame object

Reimplemented from Adaptor.

Definition at line 88 of file MP3Encoder.cpp.

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

00088 { 00089 CompressedAudioFrame *mpgFrame = NULL; 00090 list < Frame * >frmList; 00091 u32 iFramesize = 0; 00092 00093 if (!initialized) 00094 initialize(); 00095 if (!initialized) 00096 return frmList; 00097 00098 #define PCM_FRAME_SIZE (1152*2*2) //FIXME: should be read from AVCodecContext->frame_size 00099 00100 if (inBufSize > 0) { // smth was left from last round.... 00101 memcpy(mpInBuf+inBufSize, frm->getAU()->payload, frm->getAU()->size); 00102 dprintf_full("MP3Encoder::adapt %i bytes were left from last round...stored further %i bytes\n",inBufSize,frm->getAU()->size); 00103 inBufSize += frm->getAU()->size; 00104 00105 if (inBufSize >= PCM_FRAME_SIZE) { 00106 iFramesize = FFMPEGaudioEncodeFrame(mpEncoderHandle, (char *)mpInBuf, mpOutBuf); 00107 inBufSize -= PCM_FRAME_SIZE; 00108 assert(inBufSize <= PCM_FRAME_SIZE); //avoid overlapping rest-buffer 00109 memcpy(mpInBuf,mpInBuf+PCM_FRAME_SIZE,inBufSize); //move rest to the front 00110 00111 if (iFramesize > 0) { 00112 AU *pAU = new AU(frm->getAU()); 00113 u8 *payload = new u8[iFramesize]; 00114 memcpy(payload, mpOutBuf, iFramesize); 00115 00116 pAU->size = iFramesize; 00117 pAU->payload = payload; 00118 pAU->cts = muiFrameNumber * es->getVOPTimeIncrement(); 00119 00120 mpgFrame = new CompressedAudioFrame(Frame::MP3_AUDIO); 00121 00122 //mpgFrame->detectFrameType(); 00123 mpgFrame->setAU(pAU); 00124 mpgFrame->setMediaTimeScale(es->getMediaTimeScale()); 00125 frmList.push_back(mpgFrame); 00126 dprintf_full("MP3Encoder::adapt overlapping frame: size %i bytes, %s frameNo %i, CTS %u:\r\n", 00127 pAU->size, Frame::VOPTypeToChar(mpgFrame->getType()), muiFrameNumber, 00128 mpgFrame->getAU()->cts); 00129 muiFrameNumber++; 00130 } else { 00131 dprintf_full("MP3Encoder::adapt ... filling encoder queue: no return data yet.\n"); 00132 } 00133 } else { 00134 dprintf_full("MP3Encoder::adapt ... still harvesting small pcm bits for one full frame...!\n"); 00135 } 00136 } // smth was left from last round.... 00137 else { //inBufSize==0, so store for next round 00138 memcpy(mpInBuf, frm->getAU()->payload, frm->getAU()->size); 00139 inBufSize= frm->getAU()->size; 00140 dprintf_full("MP3Encoder::adapt %i tail-bytes saved for next round...\n",inBufSize); 00141 } 00142 00143 return frmList; 00144 }

Adaptor * MP3Encoder::clone  )  [virtual]
 

Not implemented.

Returns:
Defaults to NULL.

Implements Adaptor.

Definition at line 197 of file MP3Encoder.cpp.

References MP3Encoder().

00197 { 00198 char* copyEncoderConfig=NULL; 00199 #ifdef ENABLE_FFMPEG 00200 AVCodec *codec=NULL; 00201 /* Make sure that the required encoder exists in the ffmpeg library */ 00202 codec = avcodec_find_encoder(this->outputFormat); 00203 if(codec) { 00204 AVCodecContext* srcClone = avcodec_alloc_context(); 00205 avcodec_get_context_defaults(srcClone); 00206 00207 AVCodecContext* src=(AVCodecContext*) mpEncoderHandle; 00208 // don't do a memcpy --> pointers! 00209 srcClone->codec=codec; 00210 srcClone->b_frame_strategy=src->b_frame_strategy; 00211 srcClone->b_quant_factor=src->b_quant_factor; 00212 srcClone->b_quant_offset=src->b_quant_offset; 00213 srcClone->bit_rate=src->bit_rate; 00214 srcClone->rtp_payload_size=src->rtp_payload_size; 00215 srcClone->width=src->width; 00216 srcClone->height=src->height; 00217 srcClone->gop_size=srcClone->gop_size; 00218 srcClone->qmin=src->qmin; 00219 srcClone->qmax=src->qmax; 00220 srcClone->max_b_frames=src->max_b_frames; 00221 srcClone->sample_aspect_ratio.den=src->sample_aspect_ratio.den; 00222 srcClone->sample_aspect_ratio.num=src->sample_aspect_ratio.num; 00223 srcClone->rc_max_rate=src->rc_max_rate; 00224 srcClone->rc_min_rate=src->rc_min_rate; 00225 srcClone->mb_qmax=src->mb_qmax; 00226 srcClone->mb_qmin=src->mb_qmin; 00227 srcClone->time_base=src->time_base; 00228 // open the codec for encoding 00229 if (avcodec_open(srcClone, codec) < 0) { 00230 printf("MP3Encoder::clone(): Could not open codec\n"); 00231 av_free(srcClone); 00232 } 00233 else 00234 copyEncoderConfig=(char*)srcClone; 00235 } 00236 #else 00237 dprintf_err("MP3Encoder::clone: compiled without ffmpeg support!\n"); 00238 exit(1); 00239 #endif 00240 00241 return new MP3Encoder(es,muiTargetBitrate,outputFormat,copyEncoderConfig); 00242 }

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

Flush all buffered MPGFrame objects (if any).

Returns:
List of MPGFrame objects

Reimplemented from Adaptor.

Definition at line 148 of file MP3Encoder.cpp.

References Frame::getAU(), Frame::getType(), Frame::setAU(), and Frame::setMediaTimeScale().

00148 { 00149 CompressedAudioFrame *mpgFrame = NULL; 00150 list < Frame * >frmList; 00151 u32 iFramesize; 00152 00153 00154 dprintf_full("MP3Encoder::close ... there are %i bytes left in inBuf, draining....\n",inBufSize); 00155 00156 if (inBufSize > 0) { 00157 //maybe FIXME: for large input frames, maybe more than one PCM_FRAME_SIZE is still in buffer? --> while() needed... 00158 assert(inBufSize <= PCM_FRAME_SIZE); //avoid overlapping rest-buffer 00159 iFramesize = FFMPEGaudioEncodeFrame(mpEncoderHandle, (char *)mpInBuf, mpOutBuf); 00160 00161 do { 00162 if (iFramesize > 0) { 00163 AU *pAU = new AU(); 00164 u8 *payload = new u8[iFramesize]; 00165 memcpy(payload, mpOutBuf, iFramesize); 00166 00167 pAU->size = iFramesize; 00168 pAU->payload = payload; 00169 pAU->cts = muiFrameNumber * es->getVOPTimeIncrement(); 00170 00171 mpgFrame = new CompressedAudioFrame(Frame::MP3_AUDIO); 00172 00173 //mpgFrame->detectFrameType(); 00174 mpgFrame->setAU(pAU); 00175 mpgFrame->setMediaTimeScale(es->getMediaTimeScale()); 00176 frmList.push_back(mpgFrame); 00177 dprintf_full("MP3Encoder::close FINAL frame: size %i bytes, %s frameNo %i, CTS %u:\n", 00178 pAU->size, Frame::VOPTypeToChar(mpgFrame->getType()), muiFrameNumber, 00179 mpgFrame->getAU()->cts); 00180 muiFrameNumber++; 00181 } else { 00182 dprintf_err("MP3Encoder::close ... FINAL pcm samples didnt lead to encoded frame?!?!\n"); 00183 } 00184 iFramesize = FFMPEGaudioEncodeFrame(mpEncoderHandle, NULL /*FLUSH!*/, mpOutBuf); 00185 } while (iFramesize > 0); 00186 00187 } else { 00188 dprintf_full("MP3Encoder::close ... nothing left to decode.\n"); 00189 } 00190 00191 00192 return frmList; 00193 }

u32 MP3Encoder::getTranscodingCosts  )  const [inline, virtual]
 

returns adaptation costs (CPU only) per second! For visual streams they are expressed in pixels/seconds.

Call this only on INITIALIZED adaptors!!!! Otherwise costs will be way too high.

Implements Adaptor.

Definition at line 109 of file MP3Encoder.hpp.

00109 { return 1000; };

void MP3Encoder::initialize  )  [virtual]
 

Initialize internal data structures.

Implements Adaptor.

Definition at line 61 of file MP3Encoder.cpp.

Referenced by adapt().

00061 { 00062 if(initialized) 00063 return; 00064 dprintf_full("MP3Encoder::initialize() Handle: %p BW: %i bps\n", 00065 mpEncoderHandle, muiTargetBitrate); 00066 initialized = true; 00067 if (FFMPEGaudioEncoderInit(&mpEncoderHandle, muiTargetBitrate, 44100, 2, 16) != ERR_OK) { 00068 dprintf_err("MP3Encoder::initialize: Error creating encoder instance!\n"); 00069 initialized = false; 00070 } 00071 assert(mpEncoderHandle); 00072 es->setAvgBandwidth(muiTargetBitrate); 00073 es->setVOPTimeIncrement(2350); // FIXME: 90000 DIV 38 frames, known by analyzing ffmpeg :( 00074 muiFrameNumber = 0; 00075 inBufSize=0; 00076 firstFrame = true; 00077 }


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