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).
Adaptor * clone ()
 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: