void * startDecodeThread(void *url) { LogMessage(&gMain, LOG_DEBUG, "Starting decode thread"); char currentMetadata[2046] = ""; if (sourceMedia == MP3_FORMAT) { /* MP3 */ mp3dec_init(&mp3Decoder); } if (sourceMedia == OGGVORBIS_FORMAT) { /* Ogg Vorbis */ devorb_init (&vorbisDecoder); } decoderLoop = 1; while (decoderLoop) { int read = 0; long inbuffer = 0; char *pStreamData = NULL; inbuffer = cbuffer_get_used(&sourceCBuffer); if (decoderLoop) { if (inbuffer > 0) { pStreamData = (char*)malloc(inbuffer); if (cbuffer_extract(&sourceCBuffer, pStreamData, inbuffer)) { // fprintf(stdout, "Extracted %d from the circular buffer\n", inbuffer); pthread_mutex_lock(&encoders_mutex); if (sourceMedia == MP3_FORMAT) { mp3dec_feed_stream(&mp3Decoder, pStreamData, inbuffer); if (mp3dec_get_stream_size(&mp3Decoder) > MIN_MP3_STREAM_SIZE) { if (!mp3dec_decode(&mp3Decoder)) { pthread_mutex_unlock(&encoders_mutex); LogMessage(&gMain, LOG_ERROR, "Problem with mp3 decoding."); pthread_exit((void *)1); return 0; } } /* MP3 */ } if (sourceMedia == OGGVORBIS_FORMAT) { /* Vorbis */ devorb_read (&vorbisDecoder, pStreamData, inbuffer); while (devorb_decode (&vorbisDecoder)) { if (vorbisDecoder.headers_changed) { char StreamTitle[2046] = ""; char Artist[1024] = ""; char Title[1024] = ""; char **ptr=vorbisDecoder.vc.user_comments; while(*ptr){ char *pData = *ptr; if (!strncasecmp(pData, "ARTIST=", strlen("ARTIST="))) { strncpy(Artist, pData + strlen("ARTIST="), sizeof(Artist)-1); } if (!strncasecmp(pData, "TITLE=", strlen("TITLE="))) { strncpy(Title, pData + strlen("TITLE="), sizeof(Title)-1); } ++ptr; } sprintf(StreamTitle, "%s - %s", Artist, Title); inputMetadataCallback(&gMain, StreamTitle); for(int i = 0; i < gMain.gNumEncoders; i++) { setCurrentSongTitle(g[i], StreamTitle); } vorbisDecoder.headers_changed = 0; } } } pthread_mutex_unlock(&encoders_mutex); } if (pStreamData) { free(pStreamData); } } else { #ifdef WIN32 Sleep(100); #else usleep(250); #endif } } } LogMessage(&gMain, LOG_DEBUG, "Breaking out of decoder loop."); pthread_exit((void *)1); return 0; }
static void decode_file(const char *input_file_name, const unsigned char *buf_ref, int ref_size, FILE *file_out, const int wave_out) { mp3dec_t mp3d; int i, data_bytes, total_samples = 0, maxdiff = 0; double MSE = 0.0, psnr; mp3dec_file_info_t info; #ifdef MP4_MODE frames_iterate_data d = { &mp3d, &info, 0 }; mp3dec_init(&mp3d); memset(&info, 0, sizeof(info)); if (mp3dec_iterate(input_file_name, frames_iterate_cb, &d)) #else if (mp3dec_load(&mp3d, input_file_name, &info, 0, 0)) #endif { printf("error: file not found or read error"); exit(1); } #ifdef MINIMP3_FLOAT_OUTPUT int16_t *buffer = malloc(info.samples*sizeof(int16_t)); mp3dec_f32_to_s16(info.buffer, buffer, info.samples); free(info.buffer); #else int16_t *buffer = info.buffer; #endif #ifndef MINIMP3_NO_WAV if (wave_out && file_out) fwrite(wav_header(0, 0, 0, 0), 1, 44, file_out); #endif if (info.samples) { total_samples += info.samples; if (buf_ref) { int max_samples = MINIMP3_MIN((size_t)ref_size/2, info.samples); for (i = 0; i < max_samples; i++) { int MSEtemp = abs((int)buffer[i] - (int)(int16_t)read16le(&buf_ref[i*sizeof(int16_t)])); if (MSEtemp > maxdiff) maxdiff = MSEtemp; MSE += (float)MSEtemp*(float)MSEtemp; } } if (file_out) fwrite(buffer, info.samples, sizeof(int16_t), file_out); free(buffer); } #ifndef LIBFUZZER MSE /= total_samples ? total_samples : 1; if (0 == MSE) psnr = 99.0; else psnr = 10.0*log10(((double)0x7fff*0x7fff)/MSE); printf("rate=%d samples=%d max_diff=%d PSNR=%f\n", info.hz, total_samples, maxdiff, psnr); if (psnr < 96) { printf("PSNR compliance failed\n"); exit(1); } #endif #ifndef MINIMP3_NO_WAV if (wave_out && file_out) { data_bytes = ftell(file_out) - 44; rewind(file_out); fwrite(wav_header(info.hz, info.channels, 16, data_bytes), 1, 44, file_out); } #endif #ifdef MP4_MODE if (!total_samples) { printf("error: mp4 test should decode some samples\n"); exit(1); } #endif }