"Fossies" - the Fresh Open Source Software Archive

Member "faac-1_30/common/Cfaac/Cfaad.cpp" (16 Oct 2019, 23844 Bytes) of package /linux/misc/faac-1_30.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Cfaad.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2 CFAAC - set of classes to import/export .aac/.mp4 files
    3 Copyright (C) 2004 Antonio Foranna
    4 
    5 This program is free software; you can redistribute it and/or modify
    6 it under the terms of the GNU General Public License as published by
    7 the Free Software Foundation.
    8     
    9 This program is distributed in the hope that it will be useful,
   10 but WITHOUT ANY WARRANTY; without even the implied warranty of
   11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12 GNU General Public License for more details.
   13         
   14 You should have received a copy of the GNU General Public License
   15 along with this program; if not, write to the Free Software
   16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   17             
   18 The author can be contacted at:
   19 ntnfrn_email-temp@yahoo.it
   20 */
   21 
   22 #include "Cfaad.h"
   23 
   24 
   25 
   26 // *********************************************************************************************
   27 
   28 
   29 
   30 Cfaad::Cfaad(HANDLE hIn)
   31 {
   32     ShowDlg4RawAAC=NULL;
   33     pCfg=NULL;
   34 
   35     if(hIn)
   36     {
   37         hInput=hIn;
   38         return;
   39     }
   40 
   41 MYINPUT *mi;
   42 
   43     if(!(hInput=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE|GMEM_ZEROINIT,sizeof(MYINPUT))))
   44         MessageBox(0, "Memory allocation error: hInput", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
   45     if(!(mi=(MYINPUT *)GlobalLock(hInput)))
   46         MessageBox(0, "GlobalLock(hInput)", APP_NAME " plugin", MB_OK|MB_ICONSTOP); \
   47 /*
   48     mi->mp4File=0;
   49     mi->aacFile=0;
   50     mi->hDecoder=0;
   51     mi->buffer=0;
   52     mi->bytes_read=0;*/
   53     mi->BitsPerSample=16;
   54     mi->FindBitrate=FALSE;
   55     newpos_ms=-1;
   56     mi->seek_table=NULL;
   57     mi->seek_table_length=0;
   58     mi->LockSeeking=false;
   59     GlobalUnlock(hInput);
   60 }
   61 // -----------------------------------------------------------------------------------------------
   62 
   63 Cfaad::~Cfaad()
   64 {
   65 MYINPUT *mi;
   66 
   67     if(!hInput)
   68         return;
   69 
   70     GLOBALLOCK(mi,hInput,MYINPUT,return);
   71 
   72     if(mi->mp4File)
   73         MP4Close(mi->mp4File);
   74     if(mi->aacFile)
   75         fclose(mi->aacFile);
   76     if(mi->hDecoder)
   77         faacDecClose(mi->hDecoder);
   78     FREE_ARRAY(mi->buffer);
   79     FREE_ARRAY(mi->seek_table);
   80 
   81     GlobalUnlock(hInput);
   82     GlobalFree(hInput);
   83 }
   84 
   85 // *********************************************************************************************
   86 //                                  Utilities
   87 // *********************************************************************************************
   88 
   89 int Cfaad::GetAACTrack(MP4FileHandle infile)
   90 {
   91 // find AAC track
   92 int i, rc;
   93 int numTracks = MP4GetNumberOfTracks(infile, NULL, 0);
   94 
   95     for (i = 0; i < numTracks; i++)
   96     {
   97     MP4TrackId trackId = MP4FindTrackId(infile, i, NULL, 0);
   98     const char* trackType = MP4GetTrackType(infile, trackId);
   99 
  100         if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE))
  101         {
  102         unsigned char *buff = NULL;
  103         unsigned __int32 buff_size = 0;
  104         mp4AudioSpecificConfig mp4ASC;
  105 
  106             MP4GetTrackESConfiguration(infile, trackId, (unsigned __int8 **)&buff, &buff_size);
  107 
  108             if (buff)
  109             {
  110                 rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
  111                 free(buff);
  112 
  113                 if (rc < 0)
  114                     return -1;
  115                 return trackId;
  116             }
  117         }
  118     }
  119 
  120     // can't decode this
  121     return -1;
  122 }
  123 // *********************************************************************************************
  124 
  125 int Cfaad::IsMP4(LPSTR lpstrFilename)
  126 {
  127 DWORD   mp4file = 0;
  128 FILE    *hMP4File = fopen(lpstrFilename, "rb");
  129 BYTE    header[8];
  130     if(!hMP4File)
  131         return -1;
  132     fread(header, 1, 8, hMP4File);
  133     fclose(hMP4File);
  134     if(header[4]=='f' && header[5]=='t' && header[6]=='y' && header[7]=='p')
  135         return 1;
  136 
  137     return 0;
  138 }
  139 // *********************************************************************************************
  140 long Cfaad::id3v2_TagSize(unsigned char *buffer)
  141 {
  142     if(StringComp((const char *)buffer, "ID3", 3) == 0)
  143     {
  144     unsigned long tagsize;
  145 
  146     // high bit is not used
  147         tagsize =   (buffer[6] << 21) | (buffer[7] << 14) |
  148                     (buffer[8] <<  7) | (buffer[9] <<  0);
  149         tagsize += 10;
  150         return tagsize;
  151     }
  152     return 0;
  153 }
  154 /*
  155 long Cfaad::id3v2_TagSize(aac_buffer *b)
  156 {
  157 DWORD    tagsize = 0;
  158     if (!memcmp(b->buffer, "ID3", 3))
  159     {
  160         // high bit is not used
  161         tagsize = (b->buffer[6] << 21) | (b->buffer[7] << 14) |
  162             (b->buffer[8] <<  7) | (b->buffer[9] <<  0);
  163 
  164         tagsize += 10;
  165         advance_buffer(b, tagsize);
  166         fill_buffer(b);
  167     }
  168     return tagsize;
  169 }
  170 // *********************************************************************************************
  171 
  172 int Cfaad::fill_buffer(aac_buffer *b)
  173 {
  174     int bread;
  175 
  176     if (b->bytes_consumed > 0)
  177     {
  178         if (b->bytes_into_buffer)
  179         {
  180             memmove((void*)b->buffer, (void*)(b->buffer + b->bytes_consumed),
  181                 b->bytes_into_buffer*sizeof(unsigned char));
  182         }
  183 
  184         if (!b->at_eof)
  185         {
  186             bread = fread((void*)(b->buffer + b->bytes_into_buffer), 1,
  187                 b->bytes_consumed, b->infile);
  188 
  189             if (bread != b->bytes_consumed)
  190                 b->at_eof = 1;
  191 
  192             b->bytes_into_buffer += bread;
  193         }
  194 
  195         b->bytes_consumed = 0;
  196 
  197         if (b->bytes_into_buffer > 3)
  198         {
  199             if (memcmp(b->buffer, "TAG", 3) == 0)
  200                 b->bytes_into_buffer = 0;
  201         }
  202         if (b->bytes_into_buffer > 11)
  203         {
  204             if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0)
  205                 b->bytes_into_buffer = 0;
  206         }
  207         if (b->bytes_into_buffer > 8)
  208         {
  209             if (memcmp(b->buffer, "APETAGEX", 8) == 0)
  210                 b->bytes_into_buffer = 0;
  211         }
  212     }
  213 
  214     return 1;
  215 }
  216 // *********************************************************************************************
  217 
  218 void Cfaad::advance_buffer(aac_buffer *b, int bytes)
  219 {
  220     b->file_offset += bytes;
  221     b->bytes_consumed = bytes;
  222     b->bytes_into_buffer -= bytes;
  223 }
  224 // *********************************************************************************************
  225 
  226 static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};
  227 
  228 int Cfaad::adts_parse(aac_buffer *b, int *bitrate, float *length)
  229 {
  230     int frames, frame_length;
  231     int t_framelength = 0;
  232     int samplerate;
  233     float frames_per_sec, bytes_per_frame;
  234 
  235     // Read all frames to ensure correct time and bitrate
  236     for (frames = 0; ; frames++)
  237     {
  238         fill_buffer(b);
  239 
  240         if (b->bytes_into_buffer > 7)
  241         {
  242             // check syncword 
  243             if (!((b->buffer[0] == 0xFF)&&((b->buffer[1] & 0xF6) == 0xF0)))
  244                 break;
  245 
  246             if (frames == 0)
  247                 samplerate = adts_sample_rates[(b->buffer[2]&0x3c)>>2];
  248 
  249             frame_length = ((((unsigned int)b->buffer[3] & 0x3)) << 11)
  250                 | (((unsigned int)b->buffer[4]) << 3) | (b->buffer[5] >> 5);
  251 
  252             t_framelength += frame_length;
  253 
  254             if (frame_length > b->bytes_into_buffer)
  255                 break;
  256 
  257             advance_buffer(b, frame_length);
  258         } else {
  259             break;
  260         }
  261     }
  262 
  263     frames_per_sec = (float)samplerate/1024.0f;
  264     if (frames != 0)
  265         bytes_per_frame = (float)t_framelength/(float)(frames*1000);
  266     else
  267         bytes_per_frame = 0;
  268     *bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5);
  269     if (frames_per_sec != 0)
  270         *length = (float)frames/frames_per_sec;
  271     else
  272         *length = 1;
  273 
  274     return 1;
  275 }
  276 // *********************************************************************************************
  277 
  278 // get AAC infos for printing 
  279 void Cfaad::GetAACInfos(aac_buffer *b, DWORD *header_type, float *song_length, int *pbitrate, long filesize)
  280 {
  281 int     bitrate=0;
  282 float   length=0;
  283 int     bread;
  284 long    tagsize=id3v2_TagSize(b);
  285 
  286     *header_type = 0;
  287     b->file_offset=tagsize;
  288 
  289     if ((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0))
  290     {
  291         adts_parse(b, &bitrate, &length);
  292         fseek(b->infile, tagsize, SEEK_SET);
  293 
  294         bread = fread(b->buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, b->infile);
  295         if (bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
  296             b->at_eof = 1;
  297         else
  298             b->at_eof = 0;
  299         b->bytes_into_buffer = bread;
  300         b->bytes_consumed = 0;
  301         b->file_offset = tagsize;
  302 
  303         *header_type = 1;
  304     } else if (memcmp(b->buffer, "ADIF", 4) == 0) {
  305         int skip_size = (b->buffer[4] & 0x80) ? 9 : 0;
  306         bitrate = ((unsigned int)(b->buffer[4 + skip_size] & 0x0F)<<19) |
  307             ((unsigned int)b->buffer[5 + skip_size]<<11) |
  308             ((unsigned int)b->buffer[6 + skip_size]<<3) |
  309             ((unsigned int)b->buffer[7 + skip_size] & 0xE0);
  310 
  311         length = (float)filesize;
  312         if (length != 0)
  313         {
  314             length = ((float)length*8.f)/((float)bitrate) + 0.5f;
  315         }
  316 
  317         bitrate = (int)((float)bitrate/1000.0f + 0.5f);
  318 
  319         *header_type = 2;
  320     }
  321 
  322     *song_length = length;
  323     *pbitrate=bitrate;
  324 }
  325 
  326 void Cfaad::GetAACInfos(char *Filename, aac_buffer *b, DWORD *header_type, float *song_length, int *pbitrate)
  327 {
  328     if(!(b->infile=fopen(Filename,"rb")))
  329     {
  330         MessageBox(NULL,"Error opening file",NULL,MB_OK);
  331         return;
  332     }
  333     fseek(b->infile, 0, SEEK_END);
  334 long    src_size=ftell(b->infile);
  335     fseek(b->infile, 0, SEEK_SET);
  336     if(!(b->buffer=(BYTE *)malloc(FAAD_STREAMSIZE)))
  337     {
  338         MessageBox(NULL,"Memory allocation error: b->buffer",NULL,MB_OK);
  339         return;
  340     }
  341 
  342 int tread=src_size<FAAD_STREAMSIZE ? src_size : FAAD_STREAMSIZE;
  343     b->bytes_into_buffer=fread(b->buffer, 1, tread, b->infile);
  344     if(b->bytes_into_buffer!=tread)
  345     {
  346         MessageBox(NULL,"Read failed!",NULL,MB_OK);
  347         return;
  348     }
  349     b->bytes_consumed=0;
  350     b->file_offset=0;
  351     b->at_eof=(b->bytes_into_buffer!=tread) ? 1 : 0;
  352 
  353     *header_type = 0;
  354     b->file_offset=0;
  355 
  356     GetAACInfos(b,header_type,song_length,pbitrate,src_size);
  357 
  358     free(b->buffer);
  359     fclose(b->infile);
  360 }
  361 */
  362 // *********************************************************************************************
  363 //                                  Main functions
  364 // *********************************************************************************************
  365 
  366 void CMyDecCfg::getCfg(CMyDecCfg *cfg) 
  367 { 
  368 CRegistry reg;
  369 
  370 if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAD"))
  371     {
  372         cfg->DefaultCfg=reg.GetSetBool(REG_DEFAULT,true);
  373         cfg->DecCfg.defObjectType=reg.GetSetByte(REG_PROFILE,LC);
  374         cfg->DecCfg.defSampleRate=reg.GetSetDword(REG_SAMPLERATE,44100);
  375         cfg->DecCfg.outputFormat=reg.GetSetByte(REG_BPS,FAAD_FMT_16BIT);
  376         cfg->DecCfg.downMatrix=reg.GetSetByte(REG_DOWNMATRIX,0);
  377         cfg->DecCfg.useOldADTSFormat=reg.GetSetByte(REG_OLDADTS,0);
  378         cfg->DecCfg.dontUpSampleImplicitSBR=reg.GetSetByte(REG_DONTUPSAMPLESBR,1);
  379 //      cfg->Channels=reg.GetSetByte("Channels",2);
  380     }
  381     else
  382         MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
  383 }
  384 // -----------------------------------------------------------------------------------------------
  385 
  386 void CMyDecCfg::setCfg(CMyDecCfg *cfg)
  387 { 
  388 CRegistry reg;
  389 
  390     if(reg.OpenCreate(HKEY_CURRENT_USER, REGISTRY_PROGRAM_NAME "\\FAAD"))
  391     {
  392         reg.SetBool(REG_DEFAULT,cfg->DefaultCfg);
  393         reg.SetByte(REG_PROFILE,cfg->DecCfg.defObjectType);
  394         reg.SetDword(REG_SAMPLERATE,cfg->DecCfg.defSampleRate);
  395         reg.SetByte(REG_BPS,cfg->DecCfg.outputFormat);
  396         reg.SetByte(REG_DOWNMATRIX,cfg->DecCfg.downMatrix);
  397         reg.SetByte(REG_OLDADTS,cfg->DecCfg.useOldADTSFormat);
  398         reg.SetByte(REG_DONTUPSAMPLESBR,cfg->DecCfg.dontUpSampleImplicitSBR);
  399 //      reg.SetByte("Channels",cfg->Channels);
  400     }
  401     else
  402         MessageBox(0,"Can't open registry!",0,MB_OK|MB_ICONSTOP);
  403 }
  404 // *********************************************************************************************
  405 
  406 void Cfaad::setFaadCfg(faacDecHandle hDecoder, CMyDecCfg Cfg)
  407 {
  408 faacDecConfigurationPtr config=faacDecGetCurrentConfiguration(hDecoder);
  409 
  410     if(!Cfg.DefaultCfg)
  411     {
  412         config->defObjectType=Cfg.DecCfg.defObjectType;
  413         config->outputFormat=Cfg.DecCfg.outputFormat;
  414         config->defSampleRate=Cfg.DecCfg.defSampleRate;
  415         config->downMatrix=Cfg.DecCfg.downMatrix;
  416         config->useOldADTSFormat=Cfg.DecCfg.useOldADTSFormat;
  417         config->dontUpSampleImplicitSBR=1;
  418     }
  419     else
  420     {
  421         config->defObjectType=LC;
  422         config->outputFormat=FAAD_FMT_16BIT;
  423         config->defSampleRate=44100;
  424         config->downMatrix=0;
  425         config->useOldADTSFormat=0;
  426         config->dontUpSampleImplicitSBR=1;
  427     }
  428     faacDecSetConfiguration(hDecoder, config);
  429 }
  430 // -----------------------------------------------------------------------------------------------
  431 
  432 void Cfaad::setDefaultFaadCfg(faacDecHandle hDecoder, BOOL showDlg)
  433 {
  434     if(showDlg && ShowDlg4RawAAC)
  435         ShowDlg4RawAAC();
  436 
  437 CMyDecCfg Cfg(false);
  438     setFaadCfg(hDecoder,Cfg);
  439 }
  440 // -----------------------------------------------------------------------------------------------
  441 
  442 void Cfaad::DisplayError(char *ProcName, char *str)
  443 {
  444 MYINPUT *mi;
  445 char buf[100]="";
  446 
  447     GlobalUnlock(hInput); // it wasn't done in getInfos()
  448     GLOBALLOCK(mi,hInput,MYINPUT,return);
  449 
  450     if(ProcName && *ProcName)
  451         sprintf(buf,"%s: ", ProcName);
  452     if(str && *str)
  453         strcat(buf,str);
  454     if(*buf && str)
  455         MessageBox(0, buf, APP_NAME " plugin", MB_OK|MB_ICONSTOP);
  456 
  457     mi->bytes_into_buffer=-1;
  458     GlobalUnlock(hInput);
  459 }
  460 // *********************************************************************************************
  461 
  462 HANDLE Cfaad::getInfos(LPSTR lpstrFilename)
  463 {
  464 MYINPUT *mi;
  465 
  466 // test tags
  467 //CMyDecCfg cfg;    cfg.Tag.ReadMp4Tag(lpstrFilename);
  468 //CMyDecCfg cfg;    cfg.Tag.ReadAacTag(lpstrFilename);
  469 
  470     GLOBALLOCK(mi,hInput,MYINPUT,return NULL);
  471 
  472 //  mi->IsAAC=strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".aac")==0;
  473     if((mi->IsMP4=IsMP4(lpstrFilename))==-1)
  474         return ERROR_getInfos("Error opening file");
  475 
  476     if(mi->IsMP4) // MP4 file ---------------------------------------------------------------------
  477     {
  478     MP4Duration         length;
  479     unsigned __int32    buffer_size;
  480     DWORD               timeScale;
  481     BYTE                sf;
  482     mp4AudioSpecificConfig mp4ASC;
  483 
  484         if(!(mi->mp4File=MP4Read(lpstrFilename, 0)))
  485             return ERROR_getInfos("Error opening file");
  486 
  487         if((mi->track=GetAACTrack(mi->mp4File))<0)
  488             return ERROR_getInfos(0); //"Unable to find correct AAC sound track");
  489 
  490         if(!(mi->hDecoder=faacDecOpen()))
  491             return ERROR_getInfos("Error initializing decoder library");
  492 
  493         MP4GetTrackESConfiguration(mi->mp4File, mi->track, (unsigned __int8 **)&mi->buffer, &buffer_size);
  494         if(!mi->buffer)
  495             return ERROR_getInfos("MP4GetTrackESConfiguration()");
  496         AudioSpecificConfig(mi->buffer, buffer_size, &mp4ASC);
  497 
  498         timeScale = mp4ASC.samplingFrequency;
  499         mi->Channels=mp4ASC.channelsConfiguration;
  500         sf = mp4ASC.samplingFrequencyIndex;
  501         mi->type = mp4ASC.objectTypeIndex;
  502 //        mi->SBR=mp4ASC.sbr_present_flag;
  503 
  504         if(faacDecInit2(mi->hDecoder, mi->buffer, buffer_size, &mi->Samprate, &mi->Channels) < 0)
  505             return ERROR_getInfos("Error initializing decoder library");
  506         FREE_ARRAY(mi->buffer);
  507 
  508         length=MP4GetTrackDuration(mi->mp4File, mi->track);
  509         mi->len_ms=(DWORD)MP4ConvertFromTrackDuration(mi->mp4File, mi->track, length, MP4_MSECS_TIME_SCALE);
  510         mi->file_info.bitrate=MP4GetTrackBitRate(mi->mp4File, mi->track);
  511         mi->file_info.version=MP4GetTrackAudioType(mi->mp4File, mi->track)==MP4_MPEG4_AUDIO_TYPE ? 4 : 2;
  512         mi->numSamples=MP4GetTrackNumberOfSamples(mi->mp4File, mi->track);
  513         mi->sampleId=1;
  514 
  515         mi->IsSeekable=true;
  516         mi->LockSeeking=!mi->IsSeekable;
  517     }
  518     else // AAC file ------------------------------------------------------------------------------
  519     {   
  520     DWORD           read,
  521                     tmp;
  522     BYTE            Channels4Raw=0;
  523 
  524         if(!(mi->aacFile=fopen(lpstrFilename,"rb")))
  525             return ERROR_getInfos("Error opening file"); 
  526 
  527         // use bufferized stream
  528         setvbuf(mi->aacFile,NULL,_IOFBF,32767);
  529 
  530         // get size of file
  531         fseek(mi->aacFile, 0, SEEK_END);
  532         mi->src_size=ftell(mi->aacFile);
  533         fseek(mi->aacFile, 0, SEEK_SET);
  534 
  535         if(!(mi->buffer=(BYTE *)malloc(FAAD_STREAMSIZE)))
  536             return ERROR_getInfos("Memory allocation error: mi->buffer");
  537 
  538         tmp=mi->src_size<FAAD_STREAMSIZE ? mi->src_size : FAAD_STREAMSIZE;
  539         read=fread(mi->buffer, 1, tmp, mi->aacFile);
  540         if(read==tmp)
  541         {
  542             mi->bytes_read=read;
  543             mi->bytes_into_buffer=read;
  544         }
  545         else
  546             return ERROR_getInfos("Read failed!");
  547 
  548         // skip Tag
  549     long tagsize;
  550         if(tagsize=id3v2_TagSize(mi->buffer))
  551         {
  552             if(tagsize>(long)mi->src_size)
  553                 ERROR_getInfos("Corrupt stream!");
  554             if(tagsize<mi->bytes_into_buffer)
  555             {
  556                 mi->bytes_into_buffer-=tagsize;
  557                 memcpy(mi->buffer,mi->buffer+tagsize,mi->bytes_into_buffer);
  558             }
  559             else
  560             {
  561                 mi->bytes_read=tagsize;
  562                 mi->bytes_into_buffer=0;
  563                 if(tagsize>mi->bytes_into_buffer)
  564                     fseek(mi->aacFile, tagsize, SEEK_SET);
  565             }
  566             if(mi->src_size<mi->bytes_read+FAAD_STREAMSIZE-mi->bytes_into_buffer)
  567                 tmp=mi->src_size-mi->bytes_read;
  568             else
  569                 tmp=FAAD_STREAMSIZE-mi->bytes_into_buffer;
  570             read=fread(mi->buffer+mi->bytes_into_buffer, 1, tmp, mi->aacFile);
  571             if(read==tmp)
  572             {
  573                 mi->bytes_read+=read;
  574                 mi->bytes_into_buffer+=read;
  575             }
  576             else
  577                 ERROR_getInfos("Read failed!");
  578         }
  579 
  580         if(get_AAC_format(lpstrFilename, &mi->file_info, &mi->seek_table, &mi->seek_table_length, 0))
  581             ERROR_getInfos("get_AAC_format()");
  582         mi->IsSeekable=mi->file_info.headertype==ADTS && mi->seek_table && mi->seek_table_length>0;
  583         mi->LockSeeking=!mi->IsSeekable;
  584 /*
  585     aac_buffer  b;
  586     float       fLength;
  587     DWORD       headertype;
  588         b.infile=mi->aacFile;
  589         b.buffer=mi->buffer;
  590         b.bytes_into_buffer=read;
  591         b.bytes_consumed=mi->bytes_consumed;
  592         b.file_offset=0;
  593         b.at_eof=(read!=tmp) ? 1 : 0;
  594         GetAACInfos(&b,&headertype,&fLength,&mi->file_info.bitrate,mi->src_size);
  595         mi->file_info.bitrate*=1024;
  596         mi->file_info.headertype=headertype;
  597         mi->bytes_into_buffer=b.bytes_into_buffer;
  598         mi->bytes_consumed=b.bytes_consumed;
  599         IsSeekable=false; // only mp4 can be seeked
  600 */
  601         if(!mi->FindBitrate) // open a new instance to get info from decoder
  602         {
  603         MYINPUT *miTmp;
  604         Cfaad   *NewInst;
  605             if(!(NewInst=new Cfaad()))
  606                 return ERROR_getInfos("Memory allocation error: NewInst");
  607 
  608             GLOBALLOCK(miTmp,NewInst->hInput,MYINPUT,return 0);
  609             miTmp->FindBitrate=TRUE;
  610             NewInst->ShowDlg4RawAAC=ShowDlg4RawAAC;
  611             NewInst->pCfg=pCfg;
  612             if(!NewInst->getInfos(lpstrFilename))
  613                 return ERROR_getInfos(0);
  614             mi->Channels=miTmp->frameInfo.channels;
  615             if(mi->file_info.headertype==RAW)
  616                 mi->file_info.bitrate=miTmp->file_info.bitrate;//*mi->Channels;
  617             mi->Samprate=miTmp->Samprate;
  618             mi->file_info.headertype=miTmp->file_info.headertype;
  619             mi->file_info.object_type=miTmp->file_info.object_type;
  620             mi->file_info.version=miTmp->file_info.version;
  621             GlobalUnlock(NewInst->hInput);
  622             delete NewInst;
  623         }
  624 
  625         if(!(mi->hDecoder=faacDecOpen()))
  626             return ERROR_getInfos("Can't open library");
  627         if(mi->file_info.headertype==RAW)
  628             if(pCfg)
  629                 setFaadCfg(mi->hDecoder,*pCfg);
  630             else
  631                 setDefaultFaadCfg(mi->hDecoder,mi->FindBitrate);
  632     BYTE Channels; // faacDecInit doesn't report correctly the number of channels in raw aac files
  633         if((mi->bytes_consumed=faacDecInit(mi->hDecoder, mi->buffer, mi->bytes_into_buffer, &mi->Samprate, &Channels))<0)
  634             return ERROR_getInfos("faacDecInit()");
  635         mi->bytes_into_buffer-=mi->bytes_consumed;
  636 
  637         if(mi->FindBitrate) // get info from decoder
  638         {
  639         DWORD   Samples,
  640                 BytesConsumed;
  641 
  642             if(!processData(hInput,0,0))
  643                 return ERROR_getInfos(0);
  644             Samples=mi->frameInfo.samples/sizeof(short);
  645             BytesConsumed=mi->frameInfo.bytesconsumed;
  646             if(mi->file_info.headertype==RAW || !mi->file_info.bitrate)
  647                 mi->file_info.bitrate=(BytesConsumed*8*mi->Samprate)/(Samples*2);
  648             if(!mi->file_info.bitrate)
  649                 return ERROR_getInfos("Can't determine the bitrate");
  650         }
  651 
  652         mi->len_ms=(DWORD)((mi->src_size<<3)/(mi->file_info.bitrate>>10));
  653 //      mi->len_ms=(DWORD)((1000*((float)mi->src_size*8))/mi->file_info.bitrate);
  654     }
  655 
  656     if(mi->len_ms)
  657         mi->dst_size=(DWORD)(mi->len_ms*((float)mi->Samprate/1000)*mi->Channels*(mi->BitsPerSample/8));
  658     else
  659         return ERROR_getInfos("Can't determine the length");
  660 
  661     showInfo(mi);
  662 
  663     GlobalUnlock(hInput);
  664     return hInput;
  665 }
  666 // *********************************************************************************************
  667 
  668 int Cfaad::processData(HANDLE hInput, unsigned char far *bufout, long lBytes)
  669 {
  670 BYTE    *buffer;
  671 DWORD   BytesDecoded=0;
  672 char    *sample_buffer=0;
  673 int     read;
  674 MYINPUT *mi;
  675 
  676     GLOBALLOCK(mi,hInput,MYINPUT,return 0);
  677 
  678     if(mi->LockSeeking)
  679     {
  680         NoSeek();
  681         mi->LockSeeking=false;
  682     }
  683 
  684     if(mi->IsMP4) // MP4 file --------------------------------------------------------------------------
  685     {   
  686     unsigned __int32 buffer_size=0;
  687     int rc;
  688 
  689         if(newpos_ms>-1)
  690         {
  691         MP4Duration duration=MP4ConvertToTrackDuration(mi->mp4File,mi->track,newpos_ms,MP4_MSECS_TIME_SCALE);
  692         MP4SampleId sampleId=MP4GetSampleIdFromTime(mi->mp4File,mi->track,duration,0);
  693             mi->bytes_read=(DWORD)(((float)newpos_ms*mi->file_info.bitrate)/(8*1000));
  694             if(seek(mi->bytes_read))  // update the slider
  695                 return ERROR_processData(0);
  696             newpos_ms=-1;
  697         }
  698         do
  699         {
  700             buffer=NULL;
  701             if(mi->sampleId>=mi->numSamples)
  702                 return ERROR_processData(0);
  703 
  704             rc=MP4ReadSample(mi->mp4File, mi->track, mi->sampleId++, (unsigned __int8 **)&buffer, &buffer_size, NULL, NULL, NULL, NULL);
  705             if(rc==0 || buffer==NULL)
  706             {
  707                 FREE_ARRAY(buffer);
  708                 return ERROR_processData("MP4ReadSample()");
  709             }
  710 
  711             sample_buffer=(char *)faacDecDecode(mi->hDecoder,&mi->frameInfo,buffer,buffer_size);
  712             BytesDecoded=mi->frameInfo.samples*sizeof(short);
  713             if(BytesDecoded>(DWORD)lBytes)
  714                 BytesDecoded=lBytes;
  715             memmove(bufout,sample_buffer,BytesDecoded);
  716             FREE_ARRAY(buffer);
  717             // to update the slider
  718             mi->bytes_read+=buffer_size;
  719             if(seek(mi->bytes_read))
  720                 return ERROR_processData(0);
  721         }while(!BytesDecoded && !mi->frameInfo.error);
  722     }
  723     else // AAC file --------------------------------------------------------------------------
  724     {   
  725         if(newpos_ms>-1)
  726         {
  727             if(mi->IsSeekable)
  728             {
  729             DWORD normalized=mi->len_ms/(mi->seek_table_length-1);
  730                 if(normalized<1000)
  731                     normalized=1000;
  732                 mi->bytes_read=mi->seek_table[newpos_ms/normalized];
  733                 fseek(mi->aacFile, mi->bytes_read, SEEK_SET);
  734                 if(seek(mi->bytes_read))  // update the slider
  735                     return ERROR_processData(0);
  736                 mi->bytes_into_buffer=0;
  737                 mi->bytes_consumed=FAAD_STREAMSIZE;
  738             }
  739             newpos_ms=-1;
  740         }
  741         buffer=mi->buffer;
  742         do
  743         {
  744             if(mi->bytes_consumed>0)
  745             {
  746                 if(mi->bytes_into_buffer)
  747                     memmove(buffer,buffer+mi->bytes_consumed,mi->bytes_into_buffer);
  748 
  749                 if(mi->bytes_read<mi->src_size)
  750                 {
  751                 int tmp;
  752                     if(mi->bytes_read+mi->bytes_consumed<mi->src_size)
  753                         tmp=mi->bytes_consumed;
  754                     else
  755                         tmp=mi->src_size-mi->bytes_read;
  756                     read=fread(buffer+mi->bytes_into_buffer, 1, tmp, mi->aacFile);
  757                     if(read==tmp)
  758                     {
  759                         mi->bytes_read+=read;
  760                         mi->bytes_into_buffer+=read;
  761                     }
  762                 }
  763                 else
  764                     if(mi->bytes_into_buffer)
  765                         memset(buffer+mi->bytes_into_buffer, 0, mi->bytes_consumed);
  766 
  767                 mi->bytes_consumed=0;
  768 
  769                 if( (mi->bytes_into_buffer>3 && !memcmp(mi->buffer, "TAG", 3)) ||
  770                     (mi->bytes_into_buffer>11 && !memcmp(mi->buffer, "LYRICSBEGIN", 11)) ||
  771                     (mi->bytes_into_buffer>8 && !memcmp(mi->buffer, "APETAGEX", 8)))
  772                     return ERROR_processData(0);
  773             }
  774 
  775             if(mi->bytes_into_buffer<1)
  776                 if(mi->bytes_read<mi->src_size)
  777                     return ERROR_processData("Buffer empty!");
  778                 else
  779                     return ERROR_processData(0);
  780 
  781             sample_buffer=(char *)faacDecDecode(mi->hDecoder,&mi->frameInfo,buffer,mi->bytes_into_buffer);
  782             BytesDecoded=mi->frameInfo.samples*sizeof(short);
  783             if(bufout)
  784             {
  785                 if(BytesDecoded>(DWORD)lBytes)
  786                     BytesDecoded=lBytes;
  787                 if(sample_buffer && BytesDecoded && !mi->frameInfo.error)
  788                     memmove(bufout,sample_buffer,BytesDecoded);
  789             }
  790             else // Data needed to decode Raw files
  791             {
  792                 mi->Channels=mi->frameInfo.channels;
  793                 mi->file_info.object_type=mi->frameInfo.object_type;
  794             }
  795             mi->bytes_consumed+=mi->frameInfo.bytesconsumed;
  796             mi->bytes_into_buffer-=mi->bytes_consumed;
  797         }while(!BytesDecoded && !mi->frameInfo.error);
  798     } // END AAC file --------------------------------------------------------------------------
  799 
  800     if(mi->frameInfo.error)
  801         return ERROR_processData((char *)faacDecGetErrorMessage(mi->frameInfo.error));
  802 
  803     showProgress(mi);
  804 
  805     GlobalUnlock(hInput);
  806     return BytesDecoded;
  807 }