static Bool MP3_ConfigureFromFile(MP3Reader *read) { u32 hdr, size, pos; if (!read->stream) return 0; hdr = gf_mp3_get_next_header(read->stream); if (!hdr) return 0; read->sample_rate = gf_mp3_sampling_rate(hdr); read->oti = gf_mp3_object_type_indication(hdr); fseek(read->stream, 0, SEEK_SET); if (!read->oti) return 0; /*we don't have the full file...*/ if (read->is_remote) return 1; return 1; read->duration = gf_mp3_window_size(hdr); size = gf_mp3_frame_size(hdr); pos = ftell(read->stream); fseek(read->stream, pos + size - 4, SEEK_SET); while (1) { hdr = gf_mp3_get_next_header(read->stream); if (!hdr) break; read->duration += gf_mp3_window_size(hdr); size = gf_mp3_frame_size(hdr); pos = ftell(read->stream); fseek(read->stream, pos + size - 4, SEEK_SET); } fseek(read->stream, 0, SEEK_SET); return 1; }
static void MP3_OnLiveData(MP3Reader *read, char *data, u32 data_size) { u32 hdr, size, pos; if (read->needs_connection) { hdr = gf_mp3_get_next_header_mem(data, data_size, &pos); if (!hdr) return; read->sample_rate = gf_mp3_sampling_rate(hdr); read->oti = gf_mp3_object_type_indication(hdr); read->is_live = 1; memset(&read->sl_hdr, 0, sizeof(GF_SLHeader)); read->needs_connection = 0; gf_term_on_connect(read->service, NULL, GF_OK); mp3_setup_object(read); } if (!data_size) return; read->data = gf_realloc(read->data, sizeof(char)*(read->data_size+data_size) ); memcpy(read->data + read->data_size, data, sizeof(char)*data_size); read->data_size += data_size; if (!read->ch) return; data = read->data; data_size = read->data_size; while (1) { hdr = gf_mp3_get_next_header_mem(data, data_size, &pos); if (hdr) size = gf_mp3_frame_size(hdr); /*not enough data, copy over*/ if (!hdr || (pos+size>data_size)) { char *d = gf_malloc(sizeof(char) * data_size); memcpy(d, data, sizeof(char) * data_size); gf_free(read->data); read->data = d; read->data_size = data_size; MP3_RegulateDataRate(read); return; } read->sl_hdr.accessUnitStartFlag = 1; read->sl_hdr.accessUnitEndFlag = 1; read->sl_hdr.AU_sequenceNumber++; read->sl_hdr.compositionTimeStampFlag = 1; read->sl_hdr.compositionTimeStamp += gf_mp3_window_size(hdr); gf_term_on_sl_packet(read->service, read->ch, data + pos, size, &read->sl_hdr, GF_OK); data += pos + size; assert(data_size>=pos+size); data_size -= pos+size; } }
/** * Returns TRUE if file is ready to be read, FALSE otherwise * @param read Reader * @param minSizeToRead How much bytes do we need to start reading at minimum */ static Bool MP3_ConfigureFromFile(MP3Reader *read, u32 *minSizeToRead) { unsigned char id3v2[10]; u32 hdr, size; u64 pos; if (!read->stream) return 0; /* ID3VVFFFFSIZE = 13bytes * ID3 string * VV = Version * F = Flags * SIZE = 32bits size with first Most Significant bit set to 0 -> 28 bits * Size starts AFTER this header, meaning we have to add 10 bytes */ pos = fread(id3v2, sizeof(unsigned char), 10, read->stream); *minSizeToRead = 0; if (pos == 10){ /* Did we read an ID3v2 ? */ if (id3v2[0] == 'I' && id3v2[1] == 'D' && id3v2[2] == '3'){ int sz = 10 + ((id3v2[9] & 0x7f) + ((id3v2[8] & 0x7f) << 7) + ((id3v2[7] & 0x7f) << 14) + ((id3v2[6] & 0x7f) << 21)); //printf("Size of id3v2 header = %d\n", sz); *minSizeToRead = sz; } } gf_f64_seek(read->stream, 0, SEEK_SET); hdr = gf_mp3_get_next_header(read->stream); if (!hdr) return 0; read->sample_rate = gf_mp3_sampling_rate(hdr); read->oti = gf_mp3_object_type_indication(hdr); gf_f64_seek(read->stream, 0, SEEK_SET); if (!read->oti) return 0; /*we don't have the full file...*/ if (read->is_remote) return 1; // return 1; gf_f64_seek(read->stream, 0, SEEK_SET); read->duration = 0; while (1) { hdr = gf_mp3_get_next_header(read->stream); if (!hdr) break; read->duration += gf_mp3_window_size(hdr); size = gf_mp3_frame_size(hdr); pos = gf_f64_tell(read->stream); gf_f64_seek(read->stream, pos + size - 4, SEEK_SET); } gf_f64_seek(read->stream, 0, SEEK_SET); return 1; }
static GF_Err MP3_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data) { u64 pos; u32 hdr, start_from; MP3Reader *read = plug->priv; if (read->ch != channel) return GF_STREAM_NOT_FOUND; *out_reception_status = GF_OK; *sl_compressed = 0; *is_new_data = 0; memset(&read->sl_hdr, 0, sizeof(GF_SLHeader)); read->sl_hdr.randomAccessPointFlag = 1; read->sl_hdr.compositionTimeStampFlag = 1; /*fetching es data*/ if (read->done) { *out_reception_status = GF_EOS; return GF_OK; } if (!read->data) { if (!read->stream) { *out_data_ptr = NULL; *out_data_size = 0; return GF_OK; } *is_new_data = 1; pos = gf_f64_tell(read->stream); hdr = gf_mp3_get_next_header(read->stream); if (!hdr) { if (!read->dnload) { *out_reception_status = GF_EOS; read->done = 1; } else { gf_f64_seek(read->stream, pos, SEEK_SET); *out_reception_status = GF_OK; } return GF_OK; } read->data_size = gf_mp3_frame_size(hdr); if (!read->data_size) { *out_reception_status = GF_EOS; read->done = 1; return GF_OK; } /*we're seeking*/ if (read->start_range && read->duration) { read->current_time = 0; start_from = (u32) (read->start_range * read->sample_rate); gf_f64_seek(read->stream, 0, SEEK_SET); while (read->current_time<start_from) { hdr = gf_mp3_get_next_header(read->stream); if (!hdr) { read->start_range = 0; *out_reception_status = GF_EOS; return GF_OK; } read->current_time += gf_mp3_window_size(hdr); read->data_size = gf_mp3_frame_size(hdr); gf_f64_seek(read->stream, read->data_size-4, SEEK_CUR); } read->start_range = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[MP3Demux] Seeking to frame size %d - TS %d - file pos %d\n", read->data_size, read->current_time, gf_f64_tell(read->stream))); } read->sl_hdr.compositionTimeStamp = read->current_time; GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[MP3Demux] Found new frame size %d - TS %d - file pos %d\n", read->data_size, read->current_time, gf_f64_tell(read->stream))); read->current_time += gf_mp3_window_size(hdr); read->data = gf_malloc(sizeof(char) * (read->data_size+read->pad_bytes)); read->data[0] = (hdr >> 24) & 0xFF; read->data[1] = (hdr >> 16) & 0xFF; read->data[2] = (hdr >> 8) & 0xFF; read->data[3] = (hdr ) & 0xFF; /*end of file*/ if (fread(&read->data[4], 1, read->data_size - 4, read->stream) != read->data_size-4) { gf_free(read->data); read->data = NULL; if (read->is_remote) { gf_f64_seek(read->stream, pos, SEEK_SET); *out_reception_status = GF_OK; } else { *out_reception_status = GF_EOS; } return GF_OK; } if (read->pad_bytes) memset(read->data + read->data_size, 0, sizeof(char) * read->pad_bytes); } *out_sl_hdr = read->sl_hdr; *out_data_ptr = read->data; *out_data_size = read->data_size; return GF_OK; }