ffmpegInterface.c

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: ffmpegInterface.cpp * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * * 00041 * * 00042 ***********************************************************************/ 00043 00044 #ifndef WINCE 00045 00046 00047 00048 //#undef DEBUG 00049 #include "ffmpegInterface.h" 00050 #include <stdio.h> 00051 #include <string.h> 00052 #include <stdlib.h> 00053 #include "assert.h" 00054 00055 #ifdef ENABLE_FFMPEG 00056 00057 #if BUILD_ARCH_INTEL 00058 #include "dsputil.h" 00059 #endif 00060 00061 //mutex is necessary since ffmpeg is not thrdad-safe!! 00062 //since this is plain C, we cannot use the capsuled VMutex.hpp 00063 #include <pthread.h> 00064 static pthread_mutex_t ffmpeg_mutex = PTHREAD_MUTEX_INITIALIZER; 00065 00066 #endif 00067 00068 00069 00070 int FFMPEGDecoderInit(char **pDecoderHandle, enum CodecID codecID, 00071 unsigned int uiWidth, unsigned int uiHeight) { 00072 #ifndef ENABLE_FFMPEG 00073 fprintf(stderr,"FFMPEGDecoderInit: ffmpeg disabled in this build!\n"); 00074 exit(2); 00075 #else 00076 #ifndef WIN32 00077 pthread_mutex_lock(&ffmpeg_mutex); 00078 #endif 00079 AVCodec *codec; 00080 AVCodecContext *cc= NULL; 00081 00082 #if BUILD_ARCH_INTEL 00083 /* this is done for using the img_convert(YUV420P to RGBA32) function 00084 just because the one-time init of croptbl, needed for img_convert, 00085 is a side effect of init'ing a DSPContext for which we have no use! */ 00086 DSPContext dspctx; 00087 #endif 00088 00089 #if DEBUG_LEVEL>1 00090 printf("FFMPEGDecoderInit : codecID = %d\n", codecID); 00091 #endif 00092 //first see if codec is available or not 00093 codec = avcodec_find_decoder(codecID); 00094 if (!codec) { 00095 printf("ffmpeginterface::FFMPEGDecoderInit: Video codec not found\n"); 00096 #ifndef WIN32 00097 pthread_mutex_unlock(&ffmpeg_mutex); 00098 #endif 00099 return ERR; 00100 } 00101 *pDecoderHandle = NULL; 00102 00103 //allocate AVCodecContext object 00104 cc = avcodec_alloc_context(); 00105 00106 /* if(codecID == CODEC_ID_MPEG4) { //This initialization is only required for MPEG4 00107 cc->width = uiWidth; 00108 cc->height = uiHeight; 00109 } 00110 */ 00111 assert(cc); 00112 00113 #if BUILD_ARCH_INTEL 00114 //This is done for initializing some tables for img_convert fuction 00115 dsputil_init(&dspctx, cc); 00116 #endif 00117 00118 //Everything's set - now open the codec 00119 if (avcodec_open(cc, codec) < 0) { 00120 printf("ffmpeginterface::FFMPEGDecoderInit: Could not open video codec\n"); 00121 #ifndef WIN32 00122 pthread_mutex_unlock(&ffmpeg_mutex); 00123 #endif 00124 return ERR; 00125 } 00126 else 00127 { 00128 *pDecoderHandle = (char*)cc; // cc is the handle to the codec 00129 #ifndef WIN32 00130 pthread_mutex_unlock(&ffmpeg_mutex); 00131 #endif 00132 return ERR_OK; 00133 } 00134 #endif 00135 } 00136 00137 00138 void FFMPEGDecoderClose(char **pDecoderHandle) { 00139 #ifndef ENABLE_FFMPEG 00140 fprintf(stderr,"FFMPEGDecoderClose: ffmpeg disabled in this build!\n"); 00141 exit(2); 00142 #else 00143 #ifndef WIN32 00144 pthread_mutex_lock(&ffmpeg_mutex); 00145 #endif 00146 00147 if(*pDecoderHandle) { 00148 avcodec_close((AVCodecContext *) *pDecoderHandle); 00149 av_free(*pDecoderHandle); 00150 *pDecoderHandle = NULL; 00151 } 00152 #ifndef WIN32 00153 pthread_mutex_unlock(&ffmpeg_mutex); 00154 #endif 00155 00156 #endif 00157 } 00158 00159 00160 int FFMPEGDecoderGetWidth(char *pDecoderHandle) { 00161 #ifndef ENABLE_FFMPEG 00162 fprintf(stderr,"FFMPEGDecoderGetWidth: ffmpeg disabled in this build!\n"); 00163 exit(2); 00164 #else 00165 if(pDecoderHandle != NULL) 00166 { 00167 return ((AVCodecContext *)pDecoderHandle)->width; 00168 } 00169 00170 return 0; 00171 #endif 00172 } 00173 00174 00175 int FFMPEGDecoderGetHeight(char *pDecoderHandle) { 00176 #ifndef ENABLE_FFMPEG 00177 fprintf(stderr,"FFMPEGDecoderGetHeight: ffmpeg disabled in this build!\n"); 00178 exit(2); 00179 #else 00180 if(pDecoderHandle != NULL) 00181 { 00182 return ((AVCodecContext *)pDecoderHandle)->height; 00183 } 00184 00185 return 0; 00186 #endif 00187 } 00188 00189 00190 00191 int FFMPEGDecodeFrame(char *pDecoderHandle, char *pCompressedFrame, int iCFSize, 00192 char* pYUVFrame, ffmpegColorSpace eColorSpace) { 00193 #ifndef ENABLE_FFMPEG 00194 fprintf(stderr,"FFMPEGDecodeFrame: ffmpeg disabled in this build!\n"); 00195 exit(2); 00196 #else 00197 #ifndef WIN32 00198 pthread_mutex_lock(&ffmpeg_mutex); 00199 #endif 00200 00201 AVFrame *frame; 00202 AVPicture picture, *formatted_picture, picture_format_temp; 00203 AVCodecContext *dec; 00204 int got_picture, lengthDecoded, i; 00205 int width, height, ref = 0; 00206 char* decodedFrame = pYUVFrame; 00207 00208 frame= avcodec_alloc_frame(); 00209 width = ((AVCodecContext *)pDecoderHandle)->width; 00210 height = ((AVCodecContext *)pDecoderHandle)->height; 00211 dec = ((AVCodecContext *)pDecoderHandle); 00212 00213 00214 /* Everything's set ... so decode video now!! 00215 00216 @param dec The decoder handle 00217 @param frame Contains the Uncompressed frame after decoding. The uncompressed frame is 00218 not exactly in YUV format you need to retrieve the YUV frame using "linesize"(see below) 00219 @param got_picture Is TRUE if complete uncompressed frame is obtained after deocding 00220 @param pCompressedFrame Contains the frame to be decoded 00221 iCFSize size of the compressed frame 00222 @return the length of pCompressedFrame that is deocded 00223 00224 @see ffmpeg 3rdparty/ffmpeg/libavcoded/avcodec.h 00225 */ 00226 00227 lengthDecoded = avcodec_decode_video(dec, frame, &got_picture, 00228 (uint8_t*)pCompressedFrame, iCFSize); 00229 //Look into libavcodec/avcodec.h to difference between AVframe and AVPicture 00230 picture= *(AVPicture*)frame; 00231 00232 if (got_picture) { 00233 u8 *buf = NULL; // *src, *dest; 00234 00235 /*the colorspace of decoded frame is YUV420P 00236 ....so do colorSpace conversion if required */ 00237 if((signed)dec->pix_fmt != eColorSpace && eColorSpace != FFMPEGColorSpaceYV12) { 00238 int size; 00239 /* create temporary picture */ 00240 size = avpicture_get_size(eColorSpace, dec->width, dec->height); 00241 buf = av_malloc(size); 00242 if (!buf) { 00243 printf("ffmpegInterface::FFMPEGDecodeFrame: Error in allocating Buffer\n"); 00244 #ifndef WIN32 00245 pthread_mutex_unlock(&ffmpeg_mutex); 00246 #endif 00247 00248 exit(1);//return -1; 00249 } 00250 formatted_picture = &picture_format_temp; 00251 avpicture_fill(formatted_picture, buf, eColorSpace, dec->width, dec->height); 00252 if(img_convert(formatted_picture, eColorSpace, 00253 &picture, dec->pix_fmt, 00254 dec->width, dec->height) < 0) { 00255 printf("ffmpegInterface::FFMPEGDecodeFrame: Pixel format conversion not handled\n"); 00256 #ifndef WIN32 00257 pthread_mutex_unlock(&ffmpeg_mutex); 00258 #endif 00259 00260 exit(1);//return -1; 00261 } 00262 00263 } else 00264 formatted_picture = &picture; 00265 00266 00267 /* the decoded frame data is stored in frame->data as follows : 00268 * frame->data[0] = Y 00269 * frame->data[1] = U 00270 * frame->data[2] = V 00271 * 00272 * so write this in the outputBuffer in the required way 00273 * i.e. YUVI420 or YV12 or RGB32 00274 * NOTE: always use frame->linesize, which tells the size of Y, U, or V Component 00275 */ 00276 switch(eColorSpace) { 00277 case FFMPEGColorSpaceYV12: //FIXME: why not just copy all in one or even keep "frame"??? 00278 for(i=0; i< height; i++) { 00279 memcpy(decodedFrame + i*width, 00280 formatted_picture->data[0] + i * formatted_picture->linesize[0], 00281 width); 00282 } 00283 ref = height*width; 00284 for(i=0; i<height/2; i++) { 00285 memcpy(decodedFrame + ref + i*width/2, 00286 formatted_picture->data[1] + i * formatted_picture->linesize[1], 00287 width/2); 00288 } 00289 ref += height*width/4; 00290 for(i=0; i<height/2; i++) { 00291 memcpy(decodedFrame + ref + i*width/2, 00292 formatted_picture->data[2] + i * formatted_picture->linesize[2], 00293 width/2); 00294 } 00295 break; 00296 00297 case FFMPEGColorSpaceI420: 00298 for(i=0; i< height; i++) { 00299 memcpy(decodedFrame + i*width, 00300 formatted_picture->data[0] + i * formatted_picture->linesize[0], 00301 width); 00302 } 00303 ref = height*width; 00304 for(i=0; i<height/2; i++) { 00305 memcpy(decodedFrame + ref + i*width/2, 00306 formatted_picture->data[2] + i * formatted_picture->linesize[2], 00307 width/2); 00308 } 00309 ref += height*width/4; 00310 for(i=0; i<height/2; i++) { 00311 memcpy(decodedFrame + ref + i*width/2, 00312 formatted_picture->data[1] + i * formatted_picture->linesize[1], 00313 width/2); 00314 } 00315 break; 00316 00317 case FFMPEGColorSpaceRGB24: 00318 for(i=0; i< height; i++) 00319 memcpy(decodedFrame + i*width*3, 00320 formatted_picture->data[0] + i * formatted_picture->linesize[0], 00321 width*3); 00322 00323 //memcpy(decodedFrame, formatted_picture->data[0], width*height*3); 00324 break; 00325 00326 case FFMPEGColorSpaceRGB32: 00327 for(i=0; i< height; i++) 00328 memcpy(decodedFrame + i*width*4, 00329 formatted_picture->data[0] + i * formatted_picture->linesize[0], 00330 width*4); 00331 break; 00332 00333 case FFMPEGColorSpaceRGB565: // 16bit colorspace 00334 for(i=0; i< height; i++) 00335 memcpy(decodedFrame + i*width*2, 00336 formatted_picture->data[0] + i * formatted_picture->linesize[0], 00337 width*2); 00338 break; 00339 00340 case FFMPEGColorSpaceGRAY8: 00341 for (i=0; i < height; i++) 00342 memcpy(decodedFrame + i*width, 00343 formatted_picture->data[0] + i*formatted_picture->linesize[0], 00344 width); 00345 break; 00346 00347 default : 00348 printf("ffmpegInterface::FFMPEGDecodeFrame: Specified ColorSpace not supported\n"); 00349 pthread_mutex_unlock(&ffmpeg_mutex); 00350 00351 exit(1); 00352 00353 00354 } 00355 00356 av_free(buf); 00357 } 00358 else 00359 lengthDecoded = 0-lengthDecoded; /* this is made negative just to differentiate 00360 * this info in MP4Decoder class 00361 * This is done to manage buffer in MP4Decoder class */ 00362 av_free(frame); 00363 00364 #ifndef WIN32 00365 pthread_mutex_unlock(&ffmpeg_mutex); 00366 #endif 00367 return lengthDecoded; 00368 #endif 00369 } 00370 00371 00372 int FFMPEGEncoderInit(char **pEncoderHandle, enum CodecID id, int iWidth, int iHeight, 00373 int bitrate, int iFramerate, int numBFrames, int keyFrameInterval) { 00374 #ifndef ENABLE_FFMPEG 00375 fprintf(stderr,"FFMPEGEncoderInit: ffmpeg disabled in this build!\n"); 00376 exit(2); 00377 #else 00378 #ifndef WIN32 00379 pthread_mutex_lock(&ffmpeg_mutex); 00380 #endif 00381 00382 AVCodec *codec=NULL; 00383 AVCodecContext *cc= NULL; 00384 00385 //assert(pEncoderHandle); 00386 00387 /* Make sure that the required encoder exists in the ffmpeg library */ 00388 codec = avcodec_find_encoder(id); 00389 if (!codec) { 00390 printf("ffmpegInterface::FFMPEGEncoderInit: Codec not found\n"); 00391 if(*pEncoderHandle) { 00392 av_free(*pEncoderHandle); 00393 *pEncoderHandle=NULL; 00394 } 00395 #ifndef WIN32 00396 pthread_mutex_unlock(&ffmpeg_mutex); 00397 #endif 00398 return ERR; 00399 } 00400 if(*pEncoderHandle==NULL) { 00401 cc= avcodec_alloc_context(); 00402 00403 //set the default values of encoding parameters 00404 avcodec_get_context_defaults(cc); 00405 00406 /*Set all the encoding parameters here */ 00407 //cc->flags |= CODEC_FLAG_QSCALE; 00408 fprintf(stdout,"ffmpegInterface::FFMPEGEncoderInit: created encoder with bitrate %u, fps %i, BbetweenP %i, keyFrameInterval %i\r\n",bitrate,iFramerate, numBFrames, keyFrameInterval); 00409 00410 cc->bit_rate = bitrate; 00411 cc->bit_rate_tolerance = cc->bit_rate * 5; 00412 cc->width = iWidth; 00413 cc->height = iHeight; 00414 cc->pix_fmt = PIX_FMT_YUV420P; 00415 00416 cc->qmin = 4; 00417 cc->qmax = 31; 00418 cc->mpeg_quant = 1; //0-> h263 quant 1-> mpeg quant 00419 00420 //cc->rc_max_rate = bitrate*2; 00421 //cc->rc_min_rate = bitrate/2; 00422 //cc->rc_buffer_size = 1.5 * 1024 * 1024 * 1024; // 4 MegaByte: size in bytes -> for rate control 00423 // cc->rc_buffer_size = bitrate*5; 00424 00425 cc->max_b_frames = numBFrames; 00426 cc->time_base.num = 1; 00427 cc->time_base.den = iFramerate; //XXX for variable fps ??? 00428 00429 cc->gop_size = keyFrameInterval; 00430 cc->refs = 1; //number of reference frames 00431 00432 // cc->flags |= CODEC_FLAG_GLOBAL_HEADER; 00433 } 00434 else 00435 cc=(AVCodecContext*) (*pEncoderHandle); 00436 00437 // open the codec for encoding 00438 if (avcodec_open(cc, codec) < 0) { 00439 fprintf(stderr,"ffmpegInterface::FFMPEGEncoderInit: Could not open codec\n"); 00440 av_free(cc); 00441 *pEncoderHandle=NULL; 00442 #ifndef WIN32 00443 pthread_mutex_unlock(&ffmpeg_mutex); 00444 #endif 00445 return ERR; 00446 } 00447 else 00448 *pEncoderHandle = (char*)cc; 00449 00450 #ifndef WIN32 00451 pthread_mutex_unlock(&ffmpeg_mutex); 00452 #endif 00453 return ERR_OK; 00454 #endif 00455 } 00456 00457 00458 void FFMPEGEncoderClose(char **pEncoderHandle) { 00459 #ifndef ENABLE_FFMPEG 00460 fprintf(stderr,"FFMPEGEncoderClose: ffmpeg disabled in this build!\n"); 00461 exit(2); 00462 #else 00463 if(*pEncoderHandle) { 00464 avcodec_close((AVCodecContext *) *pEncoderHandle); 00465 *pEncoderHandle=NULL; 00466 } 00467 av_free(*pEncoderHandle); 00468 #endif 00469 } 00470 00471 int FFMPEGEncodeFrame(char *pEncoderHandle, char *inBuf, char *outBuf, ffmpegColorSpace eColorSpace, int forceIFrame) { 00472 #ifndef ENABLE_FFMPEG 00473 fprintf(stderr,"FFMPEGEncodeFrame: ffmpeg disabled in this build!\n"); 00474 exit(2); 00475 #else 00476 #ifndef WIN32 00477 pthread_mutex_lock(&ffmpeg_mutex); 00478 #endif 00479 00480 AVFrame *frame; 00481 int width, height, size, frame_length; 00482 00483 frame= avcodec_alloc_frame(); 00484 00485 width = ((AVCodecContext *)pEncoderHandle)->width; 00486 height = ((AVCodecContext *)pEncoderHandle)->height; 00487 00488 size = width * height; 00489 00490 frame->linesize[0] = width; 00491 frame->linesize[1] = width / 2; 00492 frame->linesize[2] = width / 2; 00493 00494 /* Feed data to the encoder according to the input colorspace type */ 00495 switch(eColorSpace) { 00496 case FFMPEGColorSpaceI420: 00497 frame->data[0] = (uint8_t*)inBuf; 00498 frame->data[2] = frame->data[0] + size; 00499 frame->data[1] = frame->data[2] + size / 4; 00500 break; 00501 case FFMPEGColorSpaceYV12: 00502 frame->data[0] = (uint8_t*)inBuf; 00503 frame->data[1] = frame->data[0] + size; 00504 frame->data[2] = frame->data[1] + size / 4; 00505 break; 00506 default: 00507 printf("ffmpegInterface::FFMPEGEncodeFrame: ColorSpace = eColorSpace %d NOT supported!!\n", eColorSpace); 00508 } 00509 00510 if(forceIFrame == 1) { 00511 printf( "ffmpegInterface::FFMPEGEncodeFrame: forceIFrame not implemented.... ignoring...\n"); 00512 } 00513 00514 frame_length = avcodec_encode_video((AVCodecContext *)pEncoderHandle, (uint8_t*)outBuf, MAX_FRAME_SIZE, frame); 00515 00516 av_free(frame); 00517 #ifndef WIN32 00518 pthread_mutex_unlock(&ffmpeg_mutex); 00519 #endif 00520 00521 return frame_length; 00522 #endif 00523 } 00524 00525 00526 int FFMPEGEncodeFile(char *in, int width, int height, int bitrate, ffmpegColorSpace iColorSpace, char *out) { 00527 #ifndef ENABLE_FFMPEG 00528 fprintf(stderr,"FFMPEGEncodeFile: ffmpeg disabled in this build!\n"); 00529 exit(2); 00530 #else 00531 fprintf(stderr,"FFMPEGEncodeFile: not implemented!\n"); 00532 return 0; 00533 #endif 00534 } 00535 00536 00537 /***************************************************************************************/ 00538 /* AUDIO STUFF */ 00539 /***************************************************************************************/ 00540 00541 int FFMPEGaudioDecoderInit(char **pDecoderHandle, enum CodecID codecID) { 00542 #ifndef ENABLE_FFMPEG 00543 fprintf(stderr,"FFMPEGaudioDecoderInit: ffmpeg disabled in this build!\n"); 00544 exit(2); 00545 #else 00546 #ifndef WIN32 00547 pthread_mutex_lock(&ffmpeg_mutex); 00548 #endif 00549 00550 AVCodec *codec; 00551 AVCodecContext *cc= NULL; 00552 00553 //first see if codec is available or not 00554 codec = avcodec_find_decoder(CODEC_ID_MP3); //ONLY ***MP3**** 00555 if (!codec) { 00556 printf("ffmpegInterface::FFMPEGaudioDecoderInit: Audio codec not found\n"); 00557 #ifndef WIN32 00558 pthread_mutex_unlock(&ffmpeg_mutex); 00559 #endif 00560 00561 return ERR; 00562 } 00563 00564 //allocate AVCodecContext object 00565 cc= avcodec_alloc_context(); 00566 00567 /*Now open the codec*/ 00568 if (avcodec_open(cc, codec) < 0) { 00569 printf("ffmpegInterface::FFMPEGaudioDecoderInit: Could not open audio codec\n"); 00570 #ifndef WIN32 00571 pthread_mutex_unlock(&ffmpeg_mutex); 00572 #endif 00573 return ERR; 00574 } else { 00575 *pDecoderHandle = (char*)cc; //cc is the handle to the codec 00576 #ifndef WIN32 00577 pthread_mutex_unlock(&ffmpeg_mutex); 00578 #endif 00579 return ERR_OK; 00580 } 00581 #endif 00582 } 00583 00584 00585 void FFMPEGaudioDecoderClose(char **pDecoderHandle) { 00586 #ifndef ENABLE_FFMPEG 00587 fprintf(stderr,"FFMPEGaudioDecoderClose: ffmpeg disabled in this build!\n"); 00588 exit(2); 00589 #else 00590 #ifndef WIN32 00591 pthread_mutex_lock(&ffmpeg_mutex); 00592 #endif 00593 00594 avcodec_close((AVCodecContext *) *pDecoderHandle); 00595 av_free(*pDecoderHandle); 00596 *pDecoderHandle=NULL; 00597 #ifndef WIN32 00598 pthread_mutex_unlock(&ffmpeg_mutex); 00599 #endif 00600 00601 #endif 00602 } 00603 00604 00605 int FFMPEGaudioDecodeFrame(char *pDecoderHandle, char *pCompressedFrame, 00606 int iCFSize, char* PCMFrame, int *outsize) { 00607 #ifndef ENABLE_FFMPEG 00608 fprintf(stderr,"FFMPEGaudioDecodeFrame: ffmpeg disabled in this build!\n"); 00609 exit(2); 00610 #else 00611 #ifndef WIN32 00612 pthread_mutex_lock(&ffmpeg_mutex); 00613 #endif 00614 00615 AVCodecContext *dec; 00616 char* decodedFrame = PCMFrame; 00617 int CFSize = iCFSize, len1 = 0, lengthDecoded = 0, out_size= 0, total_size = 0; 00618 00619 dec = ((AVCodecContext *)pDecoderHandle); 00620 00621 /* decode the entire audio frame ... the decoder may take more than one round to decoded a frame 00622 However this is done specially for those cases where we do not send packets that are more than 00623 one frame 00624 */ 00625 while (CFSize > 0 ) { 00626 /* Function to decode an audio frame 00627 @param dec The decoder handle 00628 @param (decodedFrame+total_size) The pointer to the uncompresses frame buffer where decoded frame 00629 is to be stored 00630 @param out_size Size of the uncompressed/decoded audio frame 00631 @param pCompressedFrame The frame to be decoded 00632 @param CFSize Total size of the compressed frame 00633 00634 @return len1 Length of the compressed that is decoded after this call 00635 00636 @see 3rdparty/libavcodec/avcodec.h 00637 */ 00638 len1 = avcodec_decode_audio(dec, (short *)(decodedFrame+total_size), &out_size, 00639 (uint8_t*)(pCompressedFrame + lengthDecoded), CFSize); 00640 00641 // dprintf_full("ffmpegInterface::FFMPEGaudioDecodeFrame: len input = %d len decoded = %d output = %d\n", CFSize, len1, out_size); 00642 if(len1 < 0) { 00643 #ifndef WIN32 00644 pthread_mutex_unlock(&ffmpeg_mutex); 00645 #endif 00646 return lengthDecoded; 00647 } 00648 00649 if(out_size <= 0) { 00650 CFSize -= len1; 00651 continue; 00652 } 00653 lengthDecoded += len1; 00654 CFSize -= len1; 00655 total_size += out_size; 00656 00657 } //while 00658 // dprintf_full("FFMPEGaudioDecodeFrame : inSize = %d, lenghtDecoded = %d and outsize = %d\n", iCFSize, lengthDecoded, total_size); 00659 00660 if(total_size <= 0) 00661 lengthDecoded = 0; 00662 *outsize = total_size; 00663 #ifndef WIN32 00664 pthread_mutex_unlock(&ffmpeg_mutex); 00665 #endif 00666 00667 return lengthDecoded; 00668 #endif 00669 } 00670 00671 00672 int FFMPEGaudioEncoderInit( char **pEncoderHandle, int iBitrate, int iSampleRate, int iChannels, int iBits) { 00673 #ifndef ENABLE_FFMPEG 00674 fprintf(stderr,"FFMPEGaudioEncoderInit: ffmpeg disabled in this build!\n"); 00675 exit(2); 00676 #else 00677 #ifndef WIN32 00678 pthread_mutex_lock(&ffmpeg_mutex); 00679 #endif 00680 00681 AVCodec *codec; 00682 AVCodecContext *cc= NULL; 00683 int ret; 00684 00685 /* Make sure that mpeg4 encoder is available */ 00686 codec = avcodec_find_encoder(CODEC_ID_MP3); 00687 00688 if (!codec || (codec->type != CODEC_TYPE_AUDIO)) { 00689 fprintf(stderr,"ffmpegInterface::FFMPEGaudioEncoderInit: Audio codec not found\n"); 00690 #ifndef WIN32 00691 pthread_mutex_unlock(&ffmpeg_mutex); 00692 #endif 00693 00694 return ERR; 00695 } 00696 00697 //assert(codec == &mp3lame_encoder); 00698 00699 cc = avcodec_alloc_context(); 00700 //set the default values of encoding parameters 00701 avcodec_get_context_defaults(cc); 00702 00703 /* Set all the encoding parameters here */ 00704 assert((iBitrate/1000==128) || (iBitrate/1000==96) || (iBitrate/1000==64) || (iBitrate/1000==32)); 00705 cc->bit_rate = iBitrate; 00706 cc->sample_rate = iSampleRate; 00707 cc->channels = iChannels; 00708 cc->bits_per_sample = iBits; 00709 00710 /* open the codec */ 00711 if ((ret=avcodec_open(cc, codec)) < 0) { 00712 fprintf(stderr,"ffmpegInterface::FFMPEGaudioEncoderInit: Could not open audio codec, bitrate %i, err %i\n",cc->bit_rate,ret); 00713 *pEncoderHandle=NULL; 00714 #ifndef WIN32 00715 pthread_mutex_unlock(&ffmpeg_mutex); 00716 #endif 00717 00718 return ERR; 00719 } 00720 else 00721 *pEncoderHandle = (char*)cc; 00722 00723 fprintf(stderr,"ffmpegInterface::audioEncInit pcm frame size %i\n",cc->frame_size); 00724 #ifndef WIN32 00725 pthread_mutex_unlock(&ffmpeg_mutex); 00726 #endif 00727 00728 return ERR_OK; 00729 #endif 00730 00731 } 00732 00733 00734 void FFMPEGaudioEncoderClose(char **pEncoderHandle) { 00735 #ifndef ENABLE_FFMPEG 00736 fprintf(stderr,"FFMPEGaudioEncoderClose: ffmpeg disabled in this build!\n"); 00737 exit(2); 00738 #else 00739 #ifndef WIN32 00740 pthread_mutex_lock(&ffmpeg_mutex); 00741 #endif 00742 00743 avcodec_close((AVCodecContext *) *pEncoderHandle); 00744 av_free(*pEncoderHandle); 00745 *pEncoderHandle=NULL; 00746 #ifndef WIN32 00747 pthread_mutex_unlock(&ffmpeg_mutex); 00748 #endif 00749 00750 #endif 00751 } 00752 00753 00754 int FFMPEGaudioEncodeFrame(char *pEncoderHandle, char *PCMFrame, char *pCompressed) { 00755 #ifndef ENABLE_FFMPEG 00756 fprintf(stderr,"FFMPEGaudioEncodeFrame: ffmpeg disabled in this build!\n"); 00757 exit(2); 00758 #else 00759 #ifndef WIN32 00760 pthread_mutex_lock(&ffmpeg_mutex); 00761 #endif 00762 00763 int frame_length; 00764 AVCodecContext *cc = (AVCodecContext *)pEncoderHandle; 00765 /* encode the audio frame*/ 00766 frame_length = avcodec_encode_audio(cc, (uint8_t*)pCompressed, 00767 0, /* ffmpeg takes its own cc->frame_size */ 00768 (const short*)PCMFrame); 00769 #ifndef WIN32 00770 pthread_mutex_unlock(&ffmpeg_mutex); 00771 #endif 00772 00773 return frame_length; 00774 #endif 00775 } 00776 00777 #endif //wince 00778 00779