int decodeMP4file(char *sndfile, aac_dec_opt *opt) { int track; unsigned long samplerate; unsigned char channels; void *sample_buffer; mp4ff_t *infile; FILE *mp4File; int sampleId, numSamples; audio_file *aufile; NeAACDecHandle hDecoder; NeAACDecFrameInfo frameInfo; unsigned char *buffer; int buffer_size; int first_time = 1; /* initialise the callback structure */ mp4ff_callback_t *mp4cb = malloc(sizeof(mp4ff_callback_t)); mp4File = fopen(opt->filename, "rb"); mp4cb->read = read_callback; mp4cb->seek = seek_callback; mp4cb->user_data = mp4File; infile = mp4ff_open_read(mp4cb); if (!infile) { /* unable to open file */ error_handler("Error opening file: %s\n", opt->filename); return 1; } if ((track = GetAACTrack(infile)) < 0) { error_handler("Unable to find correct AAC sound track in the MP4 file.\n"); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } buffer = NULL; buffer_size = 0; mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size); hDecoder = NeAACDecOpen(); if(NeAACDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0) { /* If some error initializing occured, skip the file */ error_handler("Error initializing decoder library.\n"); NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } if (buffer) free(buffer); numSamples = mp4ff_num_samples(infile, track); for (sampleId = 0; sampleId < numSamples; sampleId++) { int rc; /* get access unit from MP4 file */ buffer = NULL; buffer_size = 0; rc = mp4ff_read_sample(infile, track, sampleId, &buffer, &buffer_size); if (rc == 0) { error_handler("Reading from MP4 file failed.\n"); NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 1; } sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, buffer_size); if (buffer) free(buffer); opt->progress_update((long)numSamples, sampleId); /* open the sound file now that the number of channels are known */ if (first_time && !frameInfo.error) { if(opt->decode_mode == 0) { if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE, frameInfo.channels) < 0) { error_handler("\nCan't access %s\n", "WAVE OUT"); NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return (0); } } else { aufile = open_audio_file(sndfile, samplerate, frameInfo.channels, opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo)); if (aufile == NULL) { NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); return 0; } } first_time = 0; } if ((frameInfo.error == 0) && (frameInfo.samples > 0)) { if(opt->decode_mode == 0) WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples); else write_audio_file(aufile, sample_buffer, frameInfo.samples, 0); } if (frameInfo.error > 0) { error_handler("Error: %s\n", NeAACDecGetErrorMessage(frameInfo.error)); break; } if(stop_decoding) break; } NeAACDecClose(hDecoder); mp4ff_close(infile); free(mp4cb); fclose(mp4File); if(opt->decode_mode == 0) WIN_Audio_close(); else { if (!first_time) close_audio_file(aufile); } return frameInfo.error; }
int Play_Decoder() { int i; int Size=0; DEBUG_PRINT("Inside %s \n", __FUNCTION__); OMX_ERRORTYPE ret; OMX_STATETYPE state; unsigned int bufCnt=0; #ifdef PCM_PLAYBACK struct msm_audio_pcm_config drv_pcm_config; #endif // PCM_PLAYBACK DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE)); /* open the i/p and o/p files based on the video file format passed */ if(open_audio_file()) { DEBUG_PRINT("\n Returning -1"); return -1; } /* Query the decoder input min buf requirements */ CONFIG_VERSION_SIZE(inputportFmt); /* Port for which the Client needs to obtain info */ inputportFmt.nPortIndex = portParam.nStartPortNumber; OMX_GetParameter(aac_dec_handle,OMX_IndexParamPortDefinition,&inputportFmt); DEBUG_PRINT ("\nDec: Input Buffer Count %d\n", inputportFmt.nBufferCountMin); DEBUG_PRINT ("\nDec: Input Buffer Size %d\n", inputportFmt.nBufferSize); if(OMX_DirInput != inputportFmt.eDir) { DEBUG_PRINT ("\nDec: Expect Input Port\n"); return -1; } if(tunnel == 0) { /* Query the decoder outport's min buf requirements */ CONFIG_VERSION_SIZE(outputportFmt); /* Port for which the Client needs to obtain info */ outputportFmt.nPortIndex = portParam.nStartPortNumber + 1; OMX_GetParameter(aac_dec_handle,OMX_IndexParamPortDefinition,&outputportFmt); DEBUG_PRINT ("\nDec: Output Buffer Count %d\n", outputportFmt.nBufferCountMin); DEBUG_PRINT ("\nDec: Output Buffer Size %d\n", outputportFmt.nBufferSize); if(OMX_DirOutput != outputportFmt.eDir) { DEBUG_PRINT ("\nDec: Expect Output Port\n"); return -1; } } CONFIG_VERSION_SIZE(aacparam); aacparam.nPortIndex = 0; aacparam.nChannels = channels; //2 ; /* 1-> mono 2-> stereo*/ aacparam.nBitRate = samplerate; //SAMPLE_RATE; aacparam.nSampleRate = samplerate; //SAMPLE_RATE; aacparam.eChannelMode = OMX_AUDIO_ChannelModeStereo; if (sbr_ps_enabled == 0 ) aacparam.eAACProfile = OMX_AUDIO_AACObjectLC; else if (sbr_ps_enabled == 1 ) aacparam.eAACProfile = OMX_AUDIO_AACObjectHE; else if (sbr_ps_enabled == 2 ) aacparam.eAACProfile = OMX_AUDIO_AACObjectHE_PS; aacparam.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP2ADTS; OMX_SetParameter(aac_dec_handle,OMX_IndexParamAudioAac,&aacparam); #ifdef PCM_PLAYBACK if(pcmplayback == 1) { DEBUG_PRINT(" open pcm device \n"); m_pcmdrv_fd = open("/dev/msm_pcm_out", O_RDWR); if (m_pcmdrv_fd < 0) { DEBUG_PRINT("Play_Decoder: cannot open audio device"); } DEBUG_PRINT(" Play_Decoder: open pcm device successfull\n"); } #endif // PCM_PLAYBACK #ifdef PCM_PLAYBACK if(pcmplayback == 1) { DEBUG_PRINT("configure Driver for PCM playback \n"); ioctl(m_pcmdrv_fd, AUDIO_GET_CONFIG, &drv_pcm_config); drv_pcm_config.sample_rate = samplerate; //SAMPLE_RATE; //m_adec_param.nSampleRate; drv_pcm_config.channel_count = channels; //STEREO; // drv_pcm_config.in_buf_size = OMX_AAC_OUTPUT_BUFFER_SIZE ; ioctl(m_pcmdrv_fd, AUDIO_SET_CONFIG, &drv_pcm_config); // ioctl(m_pcmdrv_fd, AUDIO_START, 0); } #endif //PCM_PLAYBACK DEBUG_PRINT ("\nOMX_SendCommand Decoder -> IDLE\n"); OMX_SendCommand(aac_dec_handle, OMX_CommandStateSet, OMX_StateIdle,0); /* wait_for_event(); should not wait here event complete status will not come until enough buffer are allocated */ input_buf_cnt = inputportFmt.nBufferCountMin + 5; DEBUG_PRINT("Transition to Idle State succesful...\n"); /* Allocate buffer on decoder's i/p port */ error = Allocate_Buffer(aac_dec_handle, &pInputBufHdrs, inputportFmt.nPortIndex, input_buf_cnt, inputportFmt.nBufferSize); if (error != OMX_ErrorNone) { DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer error\n"); return -1; } else { DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer success\n"); } if(tunnel == 0) { output_buf_cnt = outputportFmt.nBufferCountMin ; /* Allocate buffer on decoder's O/Pp port */ error = Allocate_Buffer(aac_dec_handle, &pOutputBufHdrs, outputportFmt.nPortIndex, output_buf_cnt, outputportFmt.nBufferSize); if (error != OMX_ErrorNone) { DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error\n"); return -1; } else { DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success\n"); } } wait_for_event(); if (tunnel == 1) { DEBUG_PRINT ("\nOMX_SendCommand to enable TUNNEL MODE during IDLE\n"); OMX_SendCommand(aac_dec_handle, OMX_CommandPortDisable,1,0); wait_for_event(); } DEBUG_PRINT ("\nOMX_SendCommand Decoder -> Executing\n"); OMX_SendCommand(aac_dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0); wait_for_event(); DEBUG_PRINT(" Start sending OMX_emptythisbuffer\n"); for (i = 0;i < input_buf_cnt;i++) { DEBUG_PRINT ("\nOMX_EmptyThisBuffer on Input buf no.%d\n",i); pInputBufHdrs[i]->nInputPortIndex = 0; Size = Read_Buffer(pInputBufHdrs[i]); if(Size <=0 ){ DEBUG_PRINT("NO DATA READ\n"); } pInputBufHdrs[i]->nFilledLen = Size; pInputBufHdrs[i]->nInputPortIndex = 0; used_ip_buf_cnt++; ret = OMX_EmptyThisBuffer(aac_dec_handle, pInputBufHdrs[i]); if (OMX_ErrorNone != ret) { DEBUG_PRINT("OMX_EmptyThisBuffer failed with result %d\n", ret); } else { DEBUG_PRINT("OMX_EmptyThisBuffer success!\n"); } } // wait for port settings changed event wait_for_event(); DEBUG_PRINT("************************************"); DEBUG_PRINT("RECIEVED EVENT PORT SETTINGS CHANGED EVENT\n"); DEBUG_PRINT("******************************************\n"); DEBUG_PRINT("************************************"); DEBUG_PRINT("NOW SENDING FLUSH CMD\n"); DEBUG_PRINT("******************************************\n"); OMX_SendCommand(aac_dec_handle, OMX_CommandFlush, 1, 0); wait_for_event(); DEBUG_PRINT("************************************"); DEBUG_PRINT("RECIEVED FLUSH EVENT CMPL\n"); DEBUG_PRINT("******************************************\n"); // Send DISABLE command OMX_SendCommand(aac_dec_handle, OMX_CommandPortDisable, 1, 0); DEBUG_PRINT("******************************************\n"); DEBUG_PRINT("FREEING BUFFERS output_buf_cnt=%d\n",output_buf_cnt); DEBUG_PRINT("******************************************\n"); // Free output Buffer for(bufCnt=0; bufCnt < output_buf_cnt; ++bufCnt) { OMX_FreeBuffer(aac_dec_handle, 1, pOutputBufHdrs[bufCnt]); } // wait for Disable event to come back wait_for_event(); DEBUG_PRINT("******************************************\n"); DEBUG_PRINT("DISABLE EVENT RECD\n"); DEBUG_PRINT("******************************************\n"); // Send Enable command OMX_SendCommand(aac_dec_handle, OMX_CommandPortEnable, 1, 0); // AllocateBuffers DEBUG_PRINT("******************************************\n"); DEBUG_PRINT("ALLOC BUFFER AFTER PORT REENABLE"); DEBUG_PRINT("******************************************\n"); /* Allocate buffer on decoder's o/p port */ error = Allocate_Buffer(aac_dec_handle, &pOutputBufHdrs, outputportFmt.nPortIndex, output_buf_cnt, outputportFmt.nBufferSize); if (error != OMX_ErrorNone) { DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error output_buf_cnt=%d\n",output_buf_cnt); return -1; } else { DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success output_buf_cnt=%d\n",output_buf_cnt); } DEBUG_PRINT("******************************************\n"); DEBUG_PRINT("ENABLE EVENTiHANDLER RECD\n"); DEBUG_PRINT("******************************************\n"); // wait for enable event to come back wait_for_event(); DEBUG_PRINT("******************************************\n"); DEBUG_PRINT("FTB after PORT RENABLE\n"); DEBUG_PRINT("******************************************\n"); for(i=0; i < output_buf_cnt; i++) { DEBUG_PRINT ("\nOMX_FillThisBuffer on output buf no.%d\n",i); pOutputBufHdrs[i]->nOutputPortIndex = 1; //pOutputBufHdrs[i]->nFlags &= ~OMX_BUFFERFLAG_EOS; ret = OMX_FillThisBuffer(aac_dec_handle, pOutputBufHdrs[i]); if (OMX_ErrorNone != ret) { DEBUG_PRINT("OMX_FillThisBuffer failed with result %d\n", ret); } else { DEBUG_PRINT("OMX_FillThisBuffer success!\n"); } } return 0; }
int decodeMP4file(char *sndfile, aac_dec_opt *opt) { int track; unsigned long samplerate; unsigned char channels; void *sample_buffer; MP4FileHandle infile; MP4SampleId sampleId, numSamples; audio_file *aufile; faacDecHandle hDecoder; faacDecFrameInfo frameInfo; unsigned char *buffer; int buffer_size; int first_time = 1; hDecoder = faacDecOpen(); infile = MP4Read(opt->filename, 0); if (!infile) { /* unable to open file */ error_handler("Error opening file: %s\n", opt->filename); return 1; } if ((track = GetAACTrack(infile)) < 0) { error_handler("Unable to find correct AAC sound track in the MP4 file.\n"); MP4Close(infile); return 1; } buffer = NULL; buffer_size = 0; MP4GetTrackESConfiguration(infile, track, &buffer, &buffer_size); if(faacDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0) { /* If some error initializing occured, skip the file */ error_handler("Error initializing decoder library.\n"); faacDecClose(hDecoder); MP4Close(infile); return 1; } if (buffer) free(buffer); numSamples = MP4GetTrackNumberOfSamples(infile, track); for (sampleId = 1; sampleId <= numSamples; sampleId++) { int rc; /* get access unit from MP4 file */ buffer = NULL; buffer_size = 0; rc = MP4ReadSample(infile, track, sampleId, &buffer, &buffer_size, NULL, NULL, NULL, NULL); if (rc == 0) { error_handler("Reading from MP4 file failed.\n"); faacDecClose(hDecoder); MP4Close(infile); return 1; } sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size); if (buffer) free(buffer); opt->progress_update((long)numSamples, sampleId); /* open the sound file now that the number of channels are known */ if (first_time && !frameInfo.error) { if(opt->decode_mode == 0) { if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE, frameInfo.channels) < 0) { error_handler("\nCan't access %s\n", "WAVE OUT"); faacDecClose(hDecoder); MP4Close(infile); return (0); } } else { aufile = open_audio_file(sndfile, samplerate, frameInfo.channels, opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo)); if (aufile == NULL) { faacDecClose(hDecoder); MP4Close(infile); return 0; } } first_time = 0; } if ((frameInfo.error == 0) && (frameInfo.samples > 0)) { if(opt->decode_mode == 0) WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples); else write_audio_file(aufile, sample_buffer, frameInfo.samples, 0); } if (frameInfo.error > 0) { error_handler("Error: %s\n", faacDecGetErrorMessage(frameInfo.error)); break; } if(stop_decoding) break; } faacDecClose(hDecoder); MP4Close(infile); if(opt->decode_mode == 0) WIN_Audio_close(); else { if (!first_time) close_audio_file(aufile); } return frameInfo.error; }
int decodeAACfile(char *sndfile, int def_srate, aac_dec_opt *opt) { int tagsize; unsigned long samplerate; unsigned char channels; void *sample_buffer; FILE *infile; audio_file *aufile; NeAACDecHandle hDecoder; NeAACDecFrameInfo frameInfo; NeAACDecConfigurationPtr config; int first_time = 1; /* declare variables for buffering */ DEC_BUFF_VARS infile = fopen(opt->filename, "rb"); if (infile == NULL) { /* unable to open file */ error_handler("Error opening file: %s\n", opt->filename); return 1; } INIT_BUFF(infile) tagsize = id3v2_tag(buffer); if (tagsize) { UPDATE_BUFF_SKIP(tagsize) } hDecoder = NeAACDecOpen(); /* Set the default object type and samplerate */ /* This is useful for RAW AAC files */ config = NeAACDecGetCurrentConfiguration(hDecoder); if (def_srate) config->defSampleRate = def_srate; config->defObjectType = opt->object_type; config->outputFormat = opt->output_format; NeAACDecSetConfiguration(hDecoder, config); if ((bytesconsumed = NeAACDecInit(hDecoder, buffer, bytes_in_buffer, &samplerate, &channels)) < 0) { /* If some error initializing occured, skip the file */ error_handler("Error initializing decoder library.\n"); END_BUFF NeAACDecClose(hDecoder); fclose(infile); return 1; } buffer_index += bytesconsumed; do { /* update buffer */ UPDATE_BUFF_READ sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer); /* update buffer indices */ UPDATE_BUFF_IDX(frameInfo) if (frameInfo.error > 0) { error_handler("Error: %s\n", NeAACDecGetErrorMessage(frameInfo.error)); } opt->progress_update((long)fileread, buffer_index); /* open the sound file now that the number of channels are known */ if (first_time && !frameInfo.error) { if(opt->decode_mode == 0) { if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE, frameInfo.channels) < 0) { error_handler("\nCan't access %s\n", "WAVE OUT"); END_BUFF NeAACDecClose(hDecoder); fclose(infile); return (0); } } else { aufile = open_audio_file(sndfile, samplerate, frameInfo.channels, opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo)); if (aufile == NULL) { END_BUFF NeAACDecClose(hDecoder); fclose(infile); return 0; } } first_time = 0; } if ((frameInfo.error == 0) && (frameInfo.samples > 0)) { if(opt->decode_mode == 0) WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples); else write_audio_file(aufile, sample_buffer, frameInfo.samples, 0); } if (buffer_index >= fileread) sample_buffer = NULL; /* to make sure it stops now */ if(stop_decoding) break; } while (sample_buffer != NULL); NeAACDecClose(hDecoder); fclose(infile); if(opt->decode_mode == 0) WIN_Audio_close(); else { if (!first_time) close_audio_file(aufile); } END_BUFF return frameInfo.error; }
int main(int argc, char **argv) { /* Default values */ oe_options opt = { NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, 1, 0, 0, 0, 16,44100,2, 0, NULL, DEFAULT_NAMEFMT_REMOVE, DEFAULT_NAMEFMT_REPLACE, NULL, 0, -1,-1,-1, .3,-1, 0,0,0.f, 0, 0, 0, 0, 0}; input_format raw_format = {NULL, 0, raw_open, wav_close, "raw", N_("RAW file reader")}; int i; char **infiles; int numfiles; int errors=0; get_args_from_ucs16(&argc, &argv); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); parse_options(argc, argv, &opt); if(optind >= argc) { fprintf(stderr, _("ERROR: No input files specified. Use -h for help.\n")); return 1; } else { infiles = argv + optind; numfiles = argc - optind; } /* Now, do some checking for illegal argument combinations */ for(i = 0; i < numfiles; i++) { if(!strcmp(infiles[i], "-") && numfiles > 1) { fprintf(stderr, _("ERROR: Multiple files specified when using stdin\n")); exit(1); } } if(numfiles > 1 && opt.outfile) { fprintf(stderr, _("ERROR: Multiple input files with specified output filename: suggest using -n\n")); exit(1); } if(!opt.fixedserial) { /* We randomly pick a serial number. This is then incremented for each file. The random seed includes the PID so two copies of oggenc that start in the same second will generate different serial numbers. */ srand(time(NULL) ^ getpid()); opt.serial = rand(); } opt.skeleton_serial = opt.serial + numfiles; opt.kate_serial = opt.skeleton_serial + numfiles; for(i = 0; i < numfiles; i++) { /* Once through the loop for each file */ oe_enc_opt enc_opts; vorbis_comment vc; char *out_fn = NULL; FILE *in, *out = NULL; int foundformat = 0; int closeout = 0, closein = 0; char *artist=NULL, *album=NULL, *title=NULL, *track=NULL; char *date=NULL, *genre=NULL; char *lyrics=NULL, *lyrics_language=NULL; input_format *format; int resampled = 0; /* Set various encoding defaults */ enc_opts.serialno = opt.serial++; enc_opts.skeleton_serialno = opt.skeleton_serial++; enc_opts.kate_serialno = opt.kate_serial++; enc_opts.progress_update = update_statistics_full; enc_opts.start_encode = start_encode_full; enc_opts.end_encode = final_statistics; enc_opts.error = encode_error; enc_opts.comments = &vc; enc_opts.copy_comments = opt.copy_comments; enc_opts.with_skeleton = opt.with_skeleton; enc_opts.ignorelength = opt.ignorelength; /* OK, let's build the vorbis_comments structure */ build_comments(&vc, &opt, i, &artist, &album, &title, &track, &date, &genre); if(opt.lyrics_count) { if(i >= opt.lyrics_count) { lyrics = NULL; } else lyrics = opt.lyrics[i]; } if(opt.lyrics_language_count) { if(i >= opt.lyrics_language_count) { if(!opt.quiet) fprintf(stderr, _("WARNING: Insufficient lyrics languages specified, defaulting to final lyrics language.\n")); lyrics_language = opt.lyrics_language[opt.lyrics_language_count-1]; } else lyrics_language = opt.lyrics_language[i]; } if(!strcmp(infiles[i], "-")) { setbinmode(stdin); in = stdin; infiles[i] = NULL; if(!opt.outfile) { setbinmode(stdout); out = stdout; } } else { in = oggenc_fopen(infiles[i], "rb", opt.isutf8); if(in == NULL) { fprintf(stderr, _("ERROR: Cannot open input file \"%s\": %s\n"), infiles[i], strerror(errno)); free(out_fn); errors++; continue; } closein = 1; } /* Now, we need to select an input audio format - we do this before opening the output file so that we don't end up with a 0-byte file if the input file can't be read */ if(opt.rawmode) { enc_opts.rate=opt.raw_samplerate; enc_opts.channels=opt.raw_channels; enc_opts.samplesize=opt.raw_samplesize; enc_opts.endianness=opt.raw_endianness; format = &raw_format; format->open_func(in, &enc_opts, NULL, 0); foundformat=1; } else { format = open_audio_file(in, &enc_opts); if(format) { if(!opt.quiet) fprintf(stderr, _("Opening with %s module: %s\n"), format->format, format->description); foundformat=1; } } if(!foundformat) { fprintf(stderr, _("ERROR: Input file \"%s\" is not a supported format\n"), infiles[i]?infiles[i]:"(stdin)"); if(closein) fclose(in); errors++; continue; } if(enc_opts.rate <= 0) { fprintf(stderr, _("ERROR: Input file \"%s\" has invalid sampling rate\n"), infiles[i]?infiles[i]:"(stdin)"); if(closein) fclose(in); errors++; continue; } /* Ok. We can read the file - so now open the output file */ if(opt.outfile && !strcmp(opt.outfile, "-")) { setbinmode(stdout); out = stdout; } else if(out == NULL) { if(opt.outfile) { out_fn = strdup(opt.outfile); } else if(opt.namefmt) { out_fn = generate_name_string(opt.namefmt, opt.namefmt_remove, opt.namefmt_replace, artist, title, album, track,date, genre); } /* This bit was widely derided in mid-2002, so it's been removed */ /* else if(opt.title) { out_fn = malloc(strlen(title) + 5); strcpy(out_fn, title); strcat(out_fn, ".ogg"); } */ else if(infiles[i]) { /* Create a filename from existing filename, replacing extension with .ogg or .oga */ char *start, *end; char *extension; /* if adding Skeleton or Kate, we're not Vorbis I anymore */ extension = (opt.with_skeleton || opt.lyrics_count>0) ? ".oga" : ".ogg"; start = infiles[i]; end = strrchr(infiles[i], '.'); end = end?end:(start + strlen(infiles[i])+1); out_fn = malloc(end - start + 5); strncpy(out_fn, start, end-start); out_fn[end-start] = 0; strcat(out_fn, extension); } else { /* if adding skeleton or kate, we're not Vorbis I anymore */ if (opt.with_skeleton || opt.lyrics_count>0) out_fn = strdup("default.oga"); else out_fn = strdup("default.ogg"); fprintf(stderr, _("WARNING: No filename, defaulting to \"%s\"\n"), out_fn); } /* Create any missing subdirectories, if possible */ if(create_directories(out_fn, opt.isutf8)) { if(closein) fclose(in); fprintf(stderr, _("ERROR: Could not create required subdirectories for output filename \"%s\"\n"), out_fn); errors++; free(out_fn); continue; } if(infiles[i] && !strcmp(infiles[i], out_fn)) { fprintf(stderr, _("ERROR: Input filename is the same as output filename \"%s\"\n"), out_fn); errors++; free(out_fn); continue; } out = oggenc_fopen(out_fn, "wb", opt.isutf8); if(out == NULL) { if(closein) fclose(in); fprintf(stderr, _("ERROR: Cannot open output file \"%s\": %s\n"), out_fn, strerror(errno)); errors++; free(out_fn); continue; } closeout = 1; } /* Now, set the rest of the options */ enc_opts.out = out; enc_opts.comments = &vc; #ifdef _WIN32 enc_opts.filename = NULL; enc_opts.infilename = NULL; if (opt.isutf8) { if (out_fn) { utf8_decode(out_fn, &enc_opts.filename); } if (infiles[i]) { utf8_decode(infiles[i], &enc_opts.infilename); } } else { if (out_fn) { enc_opts.filename = strdup(out_fn); } if (infiles[i]) { enc_opts.infilename = strdup(infiles[i]); } } #else enc_opts.filename = out_fn; enc_opts.infilename = infiles[i]; #endif enc_opts.managed = opt.managed; enc_opts.bitrate = opt.nominal_bitrate; enc_opts.min_bitrate = opt.min_bitrate; enc_opts.max_bitrate = opt.max_bitrate; enc_opts.quality = opt.quality; enc_opts.quality_set = opt.quality_set; enc_opts.advopt = opt.advopt; enc_opts.advopt_count = opt.advopt_count; enc_opts.lyrics = lyrics; enc_opts.lyrics_language = lyrics_language; if(opt.resamplefreq && opt.resamplefreq != enc_opts.rate) { int fromrate = enc_opts.rate; resampled = 1; enc_opts.resamplefreq = opt.resamplefreq; if(setup_resample(&enc_opts)) { errors++; goto clear_all; } else if(!opt.quiet) { fprintf(stderr, _("Resampling input from %d Hz to %d Hz\n"), fromrate, opt.resamplefreq); } } if(opt.downmix) { if(enc_opts.channels == 2) { setup_downmix(&enc_opts); if(!opt.quiet) { fprintf(stderr, _("Downmixing stereo to mono\n")); } } else { fprintf(stderr, _("WARNING: Can't downmix except from stereo to mono\n")); opt.downmix = 0; } } if(opt.scale > 0.f) { setup_scaler(&enc_opts, opt.scale); if(!opt.quiet) { fprintf(stderr, _("Scaling input to %f\n"), opt.scale); } } if(enc_opts.total_samples_per_channel <= 0) { enc_opts.progress_update = update_statistics_notime; } if(opt.quiet) { enc_opts.start_encode = start_encode_null; enc_opts.progress_update = update_statistics_null; enc_opts.end_encode = final_statistics_null; } if(oe_encode(&enc_opts)) { errors++; } if(opt.scale > 0) { clear_scaler(&enc_opts); } if(opt.downmix) { clear_downmix(&enc_opts); } if(resampled) { clear_resample(&enc_opts); } clear_all: if(out_fn) free(out_fn); if(opt.outfile) free(opt.outfile); #ifdef _WIN32 if(enc_opts.filename) free(enc_opts.filename); if(enc_opts.infilename) free(enc_opts.infilename); #endif vorbis_comment_clear(&vc); format->close_func(enc_opts.readdata); if(closein) { fclose(in); } if(closeout) { fclose(out); } }/* Finished this file, loop around to next... */ return errors?1:0; }
int opusEncoder(int argc, char **argv) { static const input_format raw_format = {NULL, 0, raw_open, wav_close, "raw",N_("RAW file reader")}; int option_index=0; struct option long_options[] = { {"quiet", no_argument, NULL, 0}, {"bitrate", required_argument, NULL, 0}, {"hard-cbr",no_argument,NULL, 0}, {"vbr",no_argument,NULL, 0}, {"cvbr",no_argument,NULL, 0}, {"comp", required_argument, NULL, 0}, {"complexity", required_argument, NULL, 0}, {"framesize", required_argument, NULL, 0}, {"expect-loss", required_argument, NULL, 0}, {"downmix-mono",no_argument,NULL, 0}, {"downmix-stereo",no_argument,NULL, 0}, {"no-downmix",no_argument,NULL, 0}, {"max-delay", required_argument, NULL, 0}, {"serial", required_argument, NULL, 0}, {"save-range", required_argument, NULL, 0}, {"set-ctl-int", required_argument, NULL, 0}, {"help", no_argument, NULL, 0}, {"raw", no_argument, NULL, 0}, {"raw-bits", required_argument, NULL, 0}, {"raw-rate", required_argument, NULL, 0}, {"raw-chan", required_argument, NULL, 0}, {"raw-endianness", required_argument, NULL, 0}, {"ignorelength", no_argument, NULL, 0}, {"rate", required_argument, NULL, 0}, {"version", no_argument, NULL, 0}, {"version-short", no_argument, NULL, 0}, {"comment", required_argument, NULL, 0}, {"artist", required_argument, NULL, 0}, {"title", required_argument, NULL, 0}, {"album", required_argument, NULL, 0}, {"date", required_argument, NULL, 0}, {"genre", required_argument, NULL, 0}, {"picture", required_argument, NULL, 0}, {"padding", required_argument, NULL, 0}, {"discard-comments", no_argument, NULL, 0}, {"discard-pictures", no_argument, NULL, 0}, {0, 0, 0, 0} }; int i, ret; int cline_size; OpusMSEncoder *st; const char *opus_version; unsigned char *packet; float *input; /*I/O*/ oe_enc_opt inopt; const input_format *in_format; char *inFile; char *outFile; char *range_file; FILE *fin; FILE *fout; FILE *frange; ogg_stream_state os; ogg_page og; ogg_packet op; ogg_int64_t last_granulepos=0; ogg_int64_t enc_granulepos=0; ogg_int64_t original_samples=0; ogg_int32_t id=-1; int last_segments=0; int eos=0; OpusHeader header; char ENCODER_string[1024]; /*Counters*/ opus_int64 nb_encoded=0; opus_int64 bytes_written=0; opus_int64 pages_out=0; opus_int64 total_bytes=0; opus_int64 total_samples=0; opus_int32 nbBytes; opus_int32 nb_samples; opus_int32 peak_bytes=0; opus_int32 min_bytes; time_t start_time; time_t stop_time; time_t last_spin=0; int last_spin_len=0; /*Settings*/ int quiet=0; int max_frame_bytes; opus_int32 bitrate=-1; opus_int32 rate=48000; opus_int32 coding_rate=48000; opus_int32 frame_size=960; int chan=2; int with_hard_cbr=0; int with_cvbr=0; int expect_loss=0; int complexity=10; int downmix=0; int *opt_ctls_ctlval; int opt_ctls=0; int max_ogg_delay=48000; /*48kHz samples*/ int seen_file_icons=0; int comment_padding=512; int serialno; opus_int32 lookahead=0; #ifdef WIN_UNICODE int argc_utf8; char **argv_utf8; #endif if(query_cpu_support()){ fprintf(stderr,"\n\n** WARNING: This program was compiled with SSE%s\n",query_cpu_support()>1?"2":""); fprintf(stderr," but this CPU claims to lack these instructions. **\n\n"); } #ifdef WIN_UNICODE (void)argc; (void)argv; init_commandline_arguments_utf8(&argc_utf8, &argv_utf8); #endif opt_ctls_ctlval=NULL; frange=NULL; range_file=NULL; in_format=NULL; inopt.channels=chan; inopt.rate=coding_rate=rate; /* 0 dB gain is recommended unless you know what you're doing */ inopt.gain=0; inopt.samplesize=16; inopt.endianness=0; inopt.rawmode=0; inopt.ignorelength=0; inopt.copy_comments=1; inopt.copy_pictures=1; start_time = time(NULL); srand(((getpid()&65535)<<15)^start_time); serialno=rand(); opus_version=opus_get_version_string(); /*Vendor string should just be the encoder library, the ENCODER comment specifies the tool used.*/ comment_init(&inopt.comments, &inopt.comments_length, opus_version); // snprintf(ENCODER_string, sizeof(ENCODER_string), "opusenc from %s %s",PACKAGE_NAME,PACKAGE_VERSION); comment_add(&inopt.comments, &inopt.comments_length, "ENCODER", ENCODER_string); /*Process command-line options*/ cline_size=0; while(1){ int c; int save_cmd=1; c=getopt_long(argc_utf8, argv_utf8, "hV", long_options, &option_index); if(c==-1) break; switch(c){ case 0: if(strcmp(long_options[option_index].name,"quiet")==0){ quiet=1; }else if(strcmp(long_options[option_index].name,"bitrate")==0){ bitrate=atof(optarg)*1000.; }else if(strcmp(long_options[option_index].name,"hard-cbr")==0){ with_hard_cbr=1; with_cvbr=0; }else if(strcmp(long_options[option_index].name,"cvbr")==0){ with_cvbr=1; with_hard_cbr=0; }else if(strcmp(long_options[option_index].name,"vbr")==0){ with_cvbr=0; with_hard_cbr=0; }else if(strcmp(long_options[option_index].name,"help")==0){ usage(); return 0;//exit(0); }else if(strcmp(long_options[option_index].name,"version")==0){ opustoolsversion(opus_version); return 0;//exit(0); }else if(strcmp(long_options[option_index].name,"version-short")==0){ opustoolsversion_short(opus_version); return 0;//exit(0); }else if(strcmp(long_options[option_index].name,"ignorelength")==0){ inopt.ignorelength=1; }else if(strcmp(long_options[option_index].name,"raw")==0){ inopt.rawmode=1; save_cmd=0; }else if(strcmp(long_options[option_index].name,"raw-bits")==0){ inopt.rawmode=1; inopt.samplesize=atoi(optarg); save_cmd=0; if(inopt.samplesize!=8&&inopt.samplesize!=16&&inopt.samplesize!=24){ fprintf(stderr,"Invalid bit-depth: %s\n",optarg); fprintf(stderr,"--raw-bits must be one of 8,16, or 24\n"); return 0;//exit(1); } }else if(strcmp(long_options[option_index].name,"raw-rate")==0){ inopt.rawmode=1; inopt.rate=atoi(optarg); save_cmd=0; }else if(strcmp(long_options[option_index].name,"raw-chan")==0){ inopt.rawmode=1; inopt.channels=atoi(optarg); save_cmd=0; }else if(strcmp(long_options[option_index].name,"raw-endianness")==0){ inopt.rawmode=1; inopt.endianness=atoi(optarg); save_cmd=0; }else if(strcmp(long_options[option_index].name,"downmix-mono")==0){ downmix=1; }else if(strcmp(long_options[option_index].name,"downmix-stereo")==0){ downmix=2; }else if(strcmp(long_options[option_index].name,"no-downmix")==0){ downmix=-1; }else if(strcmp(long_options[option_index].name,"expect-loss")==0){ expect_loss=atoi(optarg); if(expect_loss>100||expect_loss<0){ fprintf(stderr,"Invalid expect-loss: %s\n",optarg); fprintf(stderr,"Expected loss is a percent and must be 0-100.\n"); return 0;//exit(1); } }else if(strcmp(long_options[option_index].name,"comp")==0 || strcmp(long_options[option_index].name,"complexity")==0){ complexity=atoi(optarg); if(complexity>10||complexity<0){ fprintf(stderr,"Invalid complexity: %s\n",optarg); fprintf(stderr,"Complexity must be 0-10.\n"); return 0;//exit(1); } }else if(strcmp(long_options[option_index].name,"framesize")==0){ if(strcmp(optarg,"2.5")==0)frame_size=120; else if(strcmp(optarg,"5")==0)frame_size=240; else if(strcmp(optarg,"10")==0)frame_size=480; else if(strcmp(optarg,"20")==0)frame_size=960; else if(strcmp(optarg,"40")==0)frame_size=1920; else if(strcmp(optarg,"60")==0)frame_size=2880; else{ fprintf(stderr,"Invalid framesize: %s\n",optarg); fprintf(stderr,"Framesize must be 2.5, 5, 10, 20, 40, or 60.\n"); return 0;//exit(1); } }else if(strcmp(long_options[option_index].name,"max-delay")==0){ max_ogg_delay=floor(atof(optarg)*48.); if(max_ogg_delay<0||max_ogg_delay>48000){ fprintf(stderr,"Invalid max-delay: %s\n",optarg); fprintf(stderr,"max-delay 0-1000 ms.\n"); return 0;//exit(1); } }else if(strcmp(long_options[option_index].name,"serial")==0){ serialno=atoi(optarg); }else if(strcmp(long_options[option_index].name,"set-ctl-int")==0){ int len=strlen(optarg),target; char *spos,*tpos; spos=strchr(optarg,'='); if(len<3||spos==NULL||(spos-optarg)<1||(spos-optarg)>=len){ fprintf(stderr, "Invalid set-ctl-int: %s\n", optarg); fprintf(stderr, "Syntax is --set-ctl-int intX=intY or\n"); fprintf(stderr, "Syntax is --set-ctl-int intS:intX=intY\n"); return 0;//exit(1); } tpos=strchr(optarg,':'); if(tpos==NULL){ target=-1; tpos=optarg-1; }else target=atoi(optarg); if((atoi(tpos+1)&1)!=0){ fprintf(stderr, "Invalid set-ctl-int: %s\n", optarg); fprintf(stderr, "libopus set CTL values are even.\n"); return 0;//exit(1); } if(opt_ctls==0)opt_ctls_ctlval=malloc(sizeof(int)*3); else opt_ctls_ctlval=realloc(opt_ctls_ctlval,sizeof(int)*(opt_ctls+1)*3); opt_ctls_ctlval[opt_ctls*3]=target; opt_ctls_ctlval[opt_ctls*3+1]=atoi(tpos+1); opt_ctls_ctlval[opt_ctls*3+2]=atoi(spos+1); opt_ctls++; }else if(strcmp(long_options[option_index].name,"save-range")==0){ frange=fopen_utf8(optarg,"w"); save_cmd=0; if(frange==NULL){ perror(optarg); fprintf(stderr,"Could not open save-range file: %s\n",optarg); fprintf(stderr,"Must provide a writable file name.\n"); return 0;//exit(1); } range_file=optarg; }else if(strcmp(long_options[option_index].name,"comment")==0){ save_cmd=0; if(!strchr(optarg,'=')){ fprintf(stderr, "Invalid comment: %s\n", optarg); fprintf(stderr, "Comments must be of the form name=value\n"); return 0;//exit(1); } comment_add(&inopt.comments, &inopt.comments_length, NULL, optarg); }else if(strcmp(long_options[option_index].name,"artist")==0){ save_cmd=0; comment_add(&inopt.comments, &inopt.comments_length, "artist", optarg); } else if(strcmp(long_options[option_index].name,"title")==0){ save_cmd=0; comment_add(&inopt.comments, &inopt.comments_length, "title", optarg); } else if(strcmp(long_options[option_index].name,"album")==0){ save_cmd=0; comment_add(&inopt.comments, &inopt.comments_length, "album", optarg); } else if(strcmp(long_options[option_index].name,"date")==0){ save_cmd=0; comment_add(&inopt.comments, &inopt.comments_length, "date", optarg); } else if(strcmp(long_options[option_index].name,"genre")==0){ save_cmd=0; comment_add(&inopt.comments, &inopt.comments_length, "genre", optarg); } else if(strcmp(long_options[option_index].name,"picture")==0){ const char *error_message; char *picture_data; save_cmd=0; picture_data=parse_picture_specification(optarg,&error_message, &seen_file_icons); if(picture_data==NULL){ fprintf(stderr,"Error parsing picture option: %s\n",error_message); return 0;//exit(1); } comment_add(&inopt.comments,&inopt.comments_length, "METADATA_BLOCK_PICTURE",picture_data); free(picture_data); } else if(strcmp(long_options[option_index].name,"padding")==0){ comment_padding=atoi(optarg); } else if(strcmp(long_options[option_index].name,"discard-comments")==0){ inopt.copy_comments=0; inopt.copy_pictures=0; } else if(strcmp(long_options[option_index].name,"discard-pictures")==0){ inopt.copy_pictures=0; } /*Commands whos arguments would leak file paths or just end up as metadata should have save_cmd=0; to prevent them from being saved in the command-line tag.*/ break; case 'h': usage(); return 0;//exit(0); break; case 'V': opustoolsversion(opus_version); return 0;//exit(0); break; case '?': usage(); return 0;//exit(1); break; } if(save_cmd && cline_size<(int)sizeof(ENCODER_string)){ ret=snprintf(&ENCODER_string[cline_size], sizeof(ENCODER_string)-cline_size, "%s--%s",cline_size==0?"":" ",long_options[option_index].name); if(ret<0||ret>=((int)sizeof(ENCODER_string)-cline_size)){ cline_size=sizeof(ENCODER_string); } else { cline_size+=ret; if(optarg){ ret=snprintf(&ENCODER_string[cline_size], sizeof(ENCODER_string)-cline_size, " %s",optarg); if(ret<0||ret>=((int)sizeof(ENCODER_string)-cline_size)){ cline_size=sizeof(ENCODER_string); } else { cline_size+=ret; } } } } } if(argc_utf8-optind!=2){ usage(); return 0;//exit(1); } inFile=argv_utf8[optind]; outFile=argv_utf8[optind+1]; if(cline_size>0)comment_add(&inopt.comments, &inopt.comments_length, "ENCODER_OPTIONS", ENCODER_string); if(strcmp(inFile, "-")==0){ #if defined WIN32 || defined _WIN32 _setmode(_fileno(stdin), _O_BINARY); #elif defined OS2 _fsetmode(stdin,"b"); #endif fin=stdin; }else{ fin=fopen_utf8(inFile, "rb"); if(!fin){ perror(inFile); return 0;//exit(1); } } if(inopt.rawmode){ in_format = &raw_format; in_format->open_func(fin, &inopt, NULL, 0); }else in_format=open_audio_file(fin,&inopt); if(!in_format){ fprintf(stderr,"Error parsing input file: %s\n",inFile); return 0;//exit(1); } if(downmix==0&&inopt.channels>2&&bitrate>0&&bitrate<(16000*inopt.channels)){ if(!quiet)fprintf(stderr,"Notice: Surround bitrate less than 16kbit/sec/channel, downmixing.\n"); downmix=inopt.channels>8?1:2; } if(downmix>0&&downmix<inopt.channels)downmix=setup_downmix(&inopt,downmix); else downmix=0; rate=inopt.rate; chan=inopt.channels; inopt.skip=0; /*In order to code the complete length we'll need to do a little padding*/ setup_padder(&inopt,&original_samples); if(rate>24000)coding_rate=48000; else if(rate>16000)coding_rate=24000; else if(rate>12000)coding_rate=16000; else if(rate>8000)coding_rate=12000; else coding_rate=8000; frame_size=frame_size/(48000/coding_rate); /*Scale the resampler complexity, but only for 48000 output because the near-cutoff behavior matters a lot more at lower rates.*/ //if(rate!=coding_rate)setup_resample(&inopt,coding_rate==48000?(complexity+1)/2:5,coding_rate); if(rate!=coding_rate&&complexity!=10&&!quiet){ fprintf(stderr,"Notice: Using resampling with complexity<10.\n"); fprintf(stderr,"Opusenc is fastest with 48, 24, 16, 12, or 8kHz input.\n\n"); } /*OggOpus headers*/ /*FIXME: broke forcemono*/ header.channels=chan; header.channel_mapping=header.channels>8?255:chan>2; header.input_sample_rate=rate; header.gain=inopt.gain; /*Initialize OPUS encoder*/ /*Framesizes <10ms can only use the MDCT modes, so we switch on RESTRICTED_LOWDELAY to save the extra 2.5ms of codec lookahead when we'll be using only small frames.*/ st=opus_multistream_surround_encoder_create(coding_rate, chan, header.channel_mapping, &header.nb_streams, &header.nb_coupled, header.stream_map, frame_size<480/(48000/coding_rate)?OPUS_APPLICATION_RESTRICTED_LOWDELAY:OPUS_APPLICATION_AUDIO, &ret); if(ret!=OPUS_OK){ fprintf(stderr, "Error cannot create encoder: %s\n", opus_strerror(ret)); return 0;//exit(1); } min_bytes=max_frame_bytes=(1275*3+7)*header.nb_streams; packet=malloc(sizeof(unsigned char)*max_frame_bytes); if(packet==NULL){ fprintf(stderr,"Error allocating packet buffer.\n"); return 0;//exit(1); } if(bitrate<0){ /*Lower default rate for sampling rates [8000-44100) by a factor of (rate+16k)/(64k)*/ bitrate=((64000*header.nb_streams+32000*header.nb_coupled)* (IMIN(48,IMAX(8,((rate<44100?rate:48000)+1000)/1000))+16)+32)>>6; }
int Encode ( char* szInput, char* szOutput, float fQuality ) { oe_options OggOptions = { "ISO-8859-1", NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0, 0, 0, 16, 44100, 2, NULL, DEFAULT_NAMEFMT_REMOVE, DEFAULT_NAMEFMT_REPLACE, NULL, -1, -1, -1, -1,0 }; int i; char infiles [ 10 ] [ 256 ]; int numfiles; int errors = 0; setlocale ( LC_ALL, "" ); OggOptions.outfile = szOutput; OggOptions.raw_samplerate = 44100; OggOptions.serial = 0; OggOptions.nominal_bitrate = -1; OggOptions.min_bitrate = -1; OggOptions.max_bitrate = -1; OggOptions.quality = 0.1f; numfiles = 1; strcpy ( &infiles [ 0 ] [ 0 ], szInput ); if ( OggOptions.serial == 0 ) OggOptions.serial = rand ( ); for ( i = 0; i < numfiles; i++ ) { oe_enc_opt enc_opts; vorbis_comment vc; char* out_fn = NULL; FILE* in = NULL; FILE* out = NULL; int foundformat = 0; int closeout = 0, closein = 0; char *artist=NULL, *album=NULL, *title=NULL, *track=NULL; char *date=NULL, *genre=NULL; input_format *format; enc_opts.serialno = OggOptions.serial++; memset ( &vc, 0, sizeof ( vc ) ); in = fopen ( infiles [ i ], "rb" ); if ( in == NULL ) { free ( out_fn ); errors++; continue; } closein = 1; format = open_audio_file ( in, &enc_opts ); if ( format ) foundformat = 1; if ( !foundformat ) { if ( closein ) fclose ( in ); errors++; continue; } if ( OggOptions.outfile ) out_fn = strdup ( OggOptions.outfile ); out = fopen ( out_fn, "wb" ); if ( out == NULL ) { if ( closein ) fclose ( in ); errors++; free ( out_fn ); continue; } closeout = 1; enc_opts.out = out; enc_opts.comments = &vc; enc_opts.filename = out_fn; enc_opts.infilename = infiles [ i ]; enc_opts.bitrate = OggOptions.nominal_bitrate; enc_opts.min_bitrate = OggOptions.min_bitrate; enc_opts.max_bitrate = OggOptions.max_bitrate; enc_opts.quality = OggOptions.quality; if ( oe_encode ( &enc_opts ) ) errors++; if ( out_fn ) free ( out_fn ); vorbis_comment_clear ( &vc ); if ( !OggOptions.rawmode ) format->close_func ( enc_opts.readdata ); if ( closein ) fclose ( in ); if ( closeout ) fclose ( out ); } return errors ? 1 : 0; }
int convert( const char* source_path, const char* target_path, int bitRate, int quality) { static const input_format raw_format = {NULL, 0, raw_open, wav_close, "raw",N_("RAW file reader")}; int i, ret; int cline_size; OpusMSEncoder *st; const char *opus_version; unsigned char *packet; #ifdef FIXED_POINT opus_int16 *input; #else float *input; #endif /*I/O*/ oe_enc_opt inopt; const input_format *in_format; char *range_file; FILE *fin; FILE *fout; FILE *frange; ogg_stream_state os; ogg_page og; ogg_packet op; ogg_int64_t last_granulepos=0; ogg_int64_t enc_granulepos=0; ogg_int64_t original_samples=0; ogg_int32_t id=-1; int last_segments=0; int eos=0; OpusHeader header; char ENCODER_string[1024]; /*Counters*/ opus_int64 nb_encoded=0; opus_int64 bytes_written=0; opus_int64 pages_out=0; opus_int64 total_bytes=0; opus_int64 total_samples=0; opus_int32 nbBytes; opus_int32 nb_samples; opus_int32 peak_bytes=0; opus_int32 min_bytes; time_t start_time; time_t stop_time; time_t last_spin=0; int last_spin_len=0; /*Settings*/ int quiet=0; int max_frame_bytes; opus_int32 bitrate=bitRate * 1000; opus_int32 rate=48000; opus_int32 coding_rate=48000; opus_int32 frame_size=960; int chan=2; int with_hard_cbr=0; int with_cvbr=0; int expect_loss=0; int complexity=10 - quality; // 10 -- best int downmix=0; int *opt_ctls_ctlval; int opt_ctls=0; int max_ogg_delay=48000; // 48kHz samples int seen_file_icons=0; int comment_padding=512; int serialno; opus_int32 lookahead=0; opt_ctls_ctlval=NULL; frange=NULL; range_file=NULL; in_format=NULL; inopt.channels=chan; inopt.rate=coding_rate=rate; // 0 dB gain is recommended unless you know what you're doing inopt.gain=0; inopt.samplesize=16; inopt.endianness=0; inopt.rawmode=0; inopt.ignorelength=0; inopt.copy_comments=1; start_time = time(NULL); srand(((getpid()&65535)<<15)^start_time); serialno=rand(); opus_version= "libopus 1.1.1"; //opus_get_version_string(); // Vendor string should just be the encoder library, the ENCODER comment specifies the tool used. if( comment_init(&inopt.comments, &inopt.comments_length, opus_version) ) { return 1; // failed } snprintf(ENCODER_string, sizeof(ENCODER_string), "%s %s",PACKAGE_NAME,PACKAGE_VERSION); if( comment_add(&inopt.comments, &inopt.comments_length, "ENCODER", ENCODER_string) ) { return 1; // failed } if(cline_size>0){ if( comment_add(&inopt.comments, &inopt.comments_length, "ENCODER_OPTIONS", ENCODER_string) ) { return 1; // failed } } fin=fopen_utf8(source_path, "rb"); if(!fin){ perror(source_path); return 1; } if(inopt.rawmode){ in_format = &raw_format; in_format->open_func(fin, &inopt, NULL, 0); }else in_format=open_audio_file(fin,&inopt); if(!in_format){ LOGD("Error parsing input file: %s\n",source_path); return 1; } if(downmix==0&&inopt.channels>2&&bitrate>0&&bitrate<(16000*inopt.channels)){ if(!quiet)LOGD("Notice: Surround bitrate less than 16kbit/sec/channel, downmixing.\n"); downmix=inopt.channels>8?1:2; } if(downmix>0&&downmix<inopt.channels)downmix=setup_downmix(&inopt,downmix); else downmix=0; rate=inopt.rate; chan=inopt.channels; inopt.skip=0; // In order to code the complete length we'll need to do a little padding setup_padder(&inopt,&original_samples); if(rate>24000)coding_rate=48000; else if(rate>16000)coding_rate=24000; else if(rate>12000)coding_rate=16000; else if(rate>8000)coding_rate=12000; else coding_rate=8000; frame_size=frame_size/(48000/coding_rate); // Scale the resampler complexity, but only for 48000 output because // the near-cutoff behavior matters a lot more at lower rates. // if(rate!=coding_rate)setup_resample(&inopt,coding_rate==48000?(complexity+1)/2:5,coding_rate); if(rate!=coding_rate&&complexity!=10&&!quiet){ LOGD("Notice: Using resampling with complexity<10.\n"); LOGD("Opusenc is fastest with 48, 24, 16, 12, or 8kHz input.\n\n"); } // OggOpus headers // FIXME: broke forcemono header.channels=chan; header.channel_mapping=header.channels>8?255:chan>2; header.input_sample_rate=rate; header.gain=inopt.gain; // Initialize OPUS encoder st=opus_multistream_surround_encoder_create(coding_rate, chan, header.channel_mapping, &header.nb_streams, &header.nb_coupled, header.stream_map, OPUS_APPLICATION_AUDIO, &ret); if(ret!=OPUS_OK){ LOGD( "Error cannot create encoder: %s\n", opus_strerror(ret)); return 1; } min_bytes=max_frame_bytes=(1275*3+7)*header.nb_streams; packet=malloc(sizeof(unsigned char)*max_frame_bytes); if(packet==NULL){ LOGD("Error allocating packet buffer.\n"); return 1; } if(bitrate<0){ // Lower default rate for sampling rates [8000-44100) by a factor of (rate+16k)/(64k) bitrate=((64000*header.nb_streams+32000*header.nb_coupled)* (IMIN(48,IMAX(8,((rate<44100?rate:48000)+1000)/1000))+16)+32)>>6; }
int Play_Decoder() { int i; int Size=0; DEBUG_PRINT("Inside %s \n", __FUNCTION__); OMX_ERRORTYPE ret; OMX_INDEXTYPE index; DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE)); /* open the i/p and o/p files based on the video file format passed */ if(open_audio_file()) { DEBUG_PRINT("\n Returning -1"); return -1; } /* Configuration of Input Port definition */ /* Query the decoder input min buf requirements */ CONFIG_VERSION_SIZE(inputportFmt); /* Port for which the Client needs to obtain info */ inputportFmt.nPortIndex = portParam.nStartPortNumber; OMX_GetParameter(aac_dec_handle,OMX_IndexParamPortDefinition,&inputportFmt); DEBUG_PRINT ("\nDec: Input Buffer Count %lu\n", inputportFmt.nBufferCountMin); DEBUG_PRINT ("\nDec: Input Buffer Size %lu\n", inputportFmt.nBufferSize); if(OMX_DirInput != inputportFmt.eDir) { DEBUG_PRINT ("\nDec: Expect Input Port\n"); return -1; } inputportFmt.nBufferCountActual = inputportFmt.nBufferCountMin + 5; OMX_SetParameter(aac_dec_handle,OMX_IndexParamPortDefinition,&inputportFmt); OMX_GetExtensionIndex(aac_dec_handle,"OMX.Qualcomm.index.audio.sessionId",&index); OMX_GetParameter(aac_dec_handle,index,&streaminfoparam); #ifdef AUDIOV2 session_id = streaminfoparam.sessionId; devmgr_fd = open("/data/omx_devmgr", O_WRONLY); if(devmgr_fd >= 0) { control = 0; write_devctlcmd(devmgr_fd, "-cmd=register_session_rx -sid=", session_id); } else { /*control = msm_mixer_open("/dev/snd/controlC0", 0); if(control < 0) printf("ERROR opening the device\n"); device_id = msm_get_device(device); device_id = 2; DEBUG_PRINT ("\ndevice_id = %d\n",device_id); DEBUG_PRINT("\nsession_id = %d\n",session_id); if (msm_en_device(device_id, 1)) { perror("could not enable device\n"); return -1; } if (msm_route_stream(1,session_id,device_id, 1)) { perror("could not set stream routing\n"); return -1; } */ } #endif /* Configuration of Ouput Port definition */ /* Query the decoder outport's min buf requirements */ CONFIG_VERSION_SIZE(outputportFmt); /* Port for which the Client needs to obtain info */ outputportFmt.nPortIndex = portParam.nStartPortNumber + 1; OMX_GetParameter(aac_dec_handle,OMX_IndexParamPortDefinition,&outputportFmt); DEBUG_PRINT ("\nDec: Output Buffer Count %lu\n", outputportFmt.nBufferCountMin); DEBUG_PRINT ("\nDec: Output Buffer Size %lu\n", outputportFmt.nBufferSize); if(OMX_DirOutput != outputportFmt.eDir) { DEBUG_PRINT ("\nDec: Expect Output Port\n"); return -1; } outputportFmt.nBufferCountActual = outputportFmt.nBufferCountMin + 3; OMX_SetParameter(aac_dec_handle,OMX_IndexParamPortDefinition,&outputportFmt); CONFIG_VERSION_SIZE(aacparam); aacparam.nPortIndex = 0; aacparam.nChannels = channels; //2 ; /* 1-> mono 2-> stereo*/ aacparam.nBitRate = samplerate; //SAMPLE_RATE; aacparam.nSampleRate = samplerate; //SAMPLE_RATE; aacparam.eChannelMode = OMX_AUDIO_ChannelModeStereo; if (sbr_ps_enabled == 0 ) aacparam.eAACProfile = OMX_AUDIO_AACObjectLC; else if (sbr_ps_enabled == 1 ) aacparam.eAACProfile = OMX_AUDIO_AACObjectHE; else if (sbr_ps_enabled == 2 ) aacparam.eAACProfile = OMX_AUDIO_AACObjectHE_PS; aacparam.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP2ADTS; OMX_SetParameter(aac_dec_handle,OMX_IndexParamAudioAac,&aacparam); DEBUG_PRINT ("\nOMX_SendCommand Decoder -> IDLE\n"); OMX_SendCommand(aac_dec_handle, OMX_CommandStateSet, OMX_StateIdle,0); /* wait_for_event(); should not wait here event complete status will not come until enough buffer are allocated */ input_buf_cnt = inputportFmt.nBufferCountActual; // inputportFmt.nBufferCountMin + 5; DEBUG_PRINT("Transition to Idle State succesful...\n"); /* Allocate buffer on decoder's i/p port */ error = Allocate_Buffer(aac_dec_handle, &pInputBufHdrs, inputportFmt.nPortIndex, input_buf_cnt, inputportFmt.nBufferSize); if (error != OMX_ErrorNone) { DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer error\n"); return -1; } else { DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer success\n"); } output_buf_cnt = outputportFmt.nBufferCountActual; // outputportFmt.nBufferCountMin ; /* Allocate buffer on decoder's O/Pp port */ error = Allocate_Buffer(aac_dec_handle, &pOutputBufHdrs, outputportFmt.nPortIndex, output_buf_cnt, outputportFmt.nBufferSize); if (error != OMX_ErrorNone) { DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error\n"); return -1; } else { DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success\n"); } wait_for_event(); DEBUG_PRINT ("\nOMX_SendCommand Decoder -> Executing\n"); OMX_SendCommand(aac_dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0); wait_for_event(); DEBUG_PRINT(" Start sending OMX_FILLthisbuffer\n"); for(i=0; i < output_buf_cnt; i++) { DEBUG_PRINT ("\nOMX_FillThisBuffer on output buf no.%d\n",i); pOutputBufHdrs[i]->nOutputPortIndex = 1; pOutputBufHdrs[i]->nFlags = 0; ret = OMX_FillThisBuffer(aac_dec_handle, pOutputBufHdrs[i]); if (OMX_ErrorNone != ret) { DEBUG_PRINT("OMX_FillThisBuffer failed with result %d\n", ret); } else { DEBUG_PRINT("OMX_FillThisBuffer success!\n"); } } DEBUG_PRINT(" Start sending OMX_emptythisbuffer\n"); for (i = 0;i < input_buf_cnt;i++) { DEBUG_PRINT ("\nOMX_EmptyThisBuffer on Input buf no.%d\n",i); pInputBufHdrs[i]->nInputPortIndex = 0; Size = Read_Buffer(pInputBufHdrs[i]); if(Size <=0 ){ DEBUG_PRINT("NO DATA READ\n"); //bInputEosReached = true; bEosOnInputBuf = true; pInputBufHdrs[i]->nFlags= OMX_BUFFERFLAG_EOS; } pInputBufHdrs[i]->nFilledLen = Size; pInputBufHdrs[i]->nInputPortIndex = 0; used_ip_buf_cnt++; ret = OMX_EmptyThisBuffer(aac_dec_handle, pInputBufHdrs[i]); if (OMX_ErrorNone != ret) { DEBUG_PRINT("OMX_EmptyThisBuffer failed with result %d\n", ret); } else { DEBUG_PRINT("OMX_EmptyThisBuffer success!\n"); } if(Size <=0 ){ break;//eos reached } } pthread_mutex_lock(&etb_lock); if(etb_done) { DEBUG_PRINT("Component is waiting for EBD to be released.\n"); etb_event_complete(); } else { DEBUG_PRINT("\n****************************\n"); DEBUG_PRINT("EBD not yet happened ...\n"); DEBUG_PRINT("\n****************************\n"); etb_done++; } pthread_mutex_unlock(&etb_lock); while(1) { wait_for_event(); if(bOutputEosReached) { bReconfigureOutputPort = 0; printf("bOutputEosReached breaking\n"); break; } else { if(bReconfigureOutputPort) process_portreconfig(); } } return 0; }