Exemplo n.º 1
0
int mp3dec_seek(mp3dec_t mp3dec, int64_t pos, int units)
{
    register struct mp3dec_t *mp3 = (struct mp3dec_t *)mp3dec;
    int64_t newpos;

    if (!mp3 || (mp3->size != sizeof(struct mp3dec_t)) || !mp3->mpadec)
      return MP3DEC_RETCODE_INVALID_HANDLE;
    if (!(mp3->flags & MP3DEC_FLAG_INITIALIZED)) return MP3DEC_RETCODE_BAD_STATE;
    if (!(mp3->flags & MP3DEC_FLAG_SEEKABLE)) return MP3DEC_RETCODE_SEEK_FAILED;
    if (units == MP3DEC_SEEK_BYTES) {
      newpos = (pos < mp3->stream_size) ? pos : mp3->stream_size;
      newpos = lseek(mp3->fd, mp3->stream_offset + newpos, SEEK_SET);
      if (newpos < 0) return MP3DEC_RETCODE_SEEK_FAILED;
      mp3->stream_position = newpos - mp3->stream_offset;
      mp3->in_buffer_offset = mp3->in_buffer_used = 0;
      mp3->out_buffer_offset = mp3->out_buffer_used = 0;
    } else if (units == MP3DEC_SEEK_SAMPLES) {
      MYFLT fsize =
        (MYFLT)(125.0*mp3->mpainfo.bitrate*mp3->mpainfo.decoded_frame_samples)/
        (MYFLT)mp3->mpainfo.decoded_frequency;
      newpos = (int64_t)
        ((MYFLT)pos*fsize/(MYFLT)mp3->mpainfo.decoded_frame_samples);
      if (newpos > mp3->stream_size) newpos = mp3->stream_size;
      pos = (pos%mp3->mpainfo.decoded_frame_samples)*
        mp3->mpainfo.decoded_sample_size;
      newpos = lseek(mp3->fd, mp3->stream_offset + newpos, SEEK_SET);
      if (newpos < 0) return MP3DEC_RETCODE_SEEK_FAILED;
      mp3->stream_position = newpos - mp3->stream_offset;
      mp3->in_buffer_offset = mp3->in_buffer_used = 0;
      mp3->out_buffer_offset = mp3->out_buffer_used = 0;
      {
        uint8_t temp[8*1152];
        mp3dec_decode(mp3, temp, (uint32_t)pos, NULL);
      }
    } else if (units == MP3DEC_SEEK_SECONDS) {
      if (pos > mp3->mpainfo.duration) pos = mp3->mpainfo.duration;
      if (mp3->taginfo.flags & 4) {
        int32_t n = (int32_t)((100*pos + (mp3->mpainfo.duration >> 1))/
                              mp3->mpainfo.duration);
        if (n > 99) newpos = mp3->stream_size;
        else newpos = (mp3->taginfo.toc[n]*mp3->stream_size)/255;
      } 
      else newpos = 
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;
}