/***************************************************************************** * FUNCTION * daf_check_next_frame * DESCRIPTION * * IMPACT * * PARAMETERS * audio_input_stream_struct *input_stream * daf_header_struct* prev_header * kal_int32 min_next_pos * kal_int32 max_next_pos * kal_int32 *next_pos * RETURNS * kal_uint8 : DAF_CHECK_NEXT_FRAME_RESULT_ENUM * GLOBALS AFFECTED * *****************************************************************************/ kal_uint8 daf_check_next_frame( audio_input_stream_struct *input_stream, daf_header_struct* prev_header, kal_int32 min_next_pos, kal_int32 max_next_pos, kal_int32 *next_pos ) { daf_header_struct header; kal_int32 search_pos; kal_uint8 search_count; if( (kal_uint32)max_next_pos + 4 > input_stream->total_load ) // check if enough space for decoding next frame header { // refill buffer audio_input_stream_read( input_stream, 0 ); if( (kal_uint32)max_next_pos + 4 > input_stream->total_load ) // check if still have enough space return DAF_CHECK_FRAME_EOF; // eof } // check if it's a valid frame header for( search_count = 0; search_count < 2; search_count++ ) { if( search_count == 0 ) search_pos = max_next_pos; else search_pos = min_next_pos; if( daf_parse_frame_header( input_stream->tail + search_pos - input_stream->total_load, &header ) ) { if( prev_header->version == header.version && prev_header->layer == header.layer && prev_header->channel_num == header.channel_num && prev_header->sample_rate == header.sample_rate ) { *next_pos = search_pos; return DAF_CHECK_FRAME_TRUE; } } } return DAF_CHECK_FRAME_FALSE; }
/***************************************************************************** * FUNCTION * daf_check_next_frame * DESCRIPTION * * PARAMETERS * input_stream [?] * prev_header [?] * min_next_pos [IN] * max_next_pos [IN] * next_pos [?] * RETURNS * kal_uint8 : DAF_CHECK_NEXT_FRAME_RESULT_ENUM *****************************************************************************/ kal_uint8 daf_check_next_frame( audio_input_stream_struct *input_stream, daf_header_struct *prev_header, kal_int32 min_next_pos, kal_int32 max_next_pos, kal_int32 *next_pos) { /*----------------------------------------------------------------*/ /* Local Variables */ /*----------------------------------------------------------------*/ daf_header_struct header; kal_int32 search_pos; kal_uint8 search_count; /*----------------------------------------------------------------*/ /* Code Body */ /*----------------------------------------------------------------*/ if ((kal_uint32) max_next_pos + 4 > input_stream->total_load) /* check if enough space for decoding next frame header */ { /* refill buffer */ audio_input_stream_read(input_stream, 0); if ((kal_uint32) max_next_pos + 4 > input_stream->total_load) /* check if still have enough space */ { return DAF_CHECK_FRAME_EOF; /* eof */ } } /* check if it's a valid frame header */ for (search_count = 0; search_count < 2; search_count++) { if (search_count == 0) { search_pos = max_next_pos; } else { search_pos = min_next_pos; } if (daf_parse_frame_header(input_stream->tail + search_pos - input_stream->total_load, &header)) { if (prev_header->version == header.version && prev_header->layer == header.layer && prev_header->channel_num == header.channel_num && prev_header->sample_rate == header.sample_rate) { *next_pos = search_pos; return DAF_CHECK_FRAME_TRUE; } } } return DAF_CHECK_FRAME_FALSE; }
/***************************************************************************** * FUNCTION * daf_parse * DESCRIPTION * * PARAMETERS * input_stream [?] * offset [?] * info_p [?] * FILE* file(?) * RETURNS * kal_bool *****************************************************************************/ kal_bool daf_parse(audio_input_stream_struct *input_stream, kal_uint32 *offset, daf_data_info_struct *info_p) { /*----------------------------------------------------------------*/ /* Local Variables */ /*----------------------------------------------------------------*/ kal_uint8 result, sync_count; kal_uint8 slot_bytes, frame_slots; kal_int32 cur_pos, min_next_pos, max_next_pos, next_pos; kal_uint32 data_size, movement; daf_header_struct header; /*----------------------------------------------------------------*/ /* Code Body */ /*----------------------------------------------------------------*/ input_stream->skip = *offset; data_size = (kal_uint32) audio_input_stream_get_data_size(input_stream); /* find the first frame with 2 consecutive frames */ for (movement = 0;; input_stream->free_bitrate = 0, movement = 1) { /* find the first frame */ if (!daf_find_next_frame(input_stream, &header, movement)) { return KAL_FALSE; /* not found */ } /* calculate current frame position */ cur_pos = input_stream->total_load - (input_stream->tail - input_stream->ptr); /* calculate next frame position because we need to find 2 consecutive frames */ min_next_pos = cur_pos + header.min_frame_size; max_next_pos = cur_pos + header.max_frame_size; /* check if next frame position reference to a valid frame */ result = daf_check_next_frame(input_stream, &header, min_next_pos, max_next_pos, &next_pos); if (result == DAF_CHECK_FRAME_EOF) { break; } else if (result == DAF_CHECK_FRAME_TRUE) { /* calculate the offset of the first found frame position */ *offset = (kal_uint32) cur_pos; /* calc frame_size */ header.frame_size = next_pos - cur_pos; /* check 2 consecutive frames */ for (sync_count = 0; sync_count < 2; sync_count++) { /* move to next frame */ input_stream->ptr += header.frame_size; ASSERT(input_stream->ptr < input_stream->tail); /* decode frame header */ daf_parse_frame_header(input_stream->ptr, &header); /* calculate frame length for free bitrate */ if (header.bitrate == 0) { /* if it's a free bitrate frame but the first frame is not, it's false */ if (input_stream->free_bitrate == 0) { break; } header.bitrate = input_stream->free_bitrate; slot_bytes = 1; if (header.layer == DAF_LAYER_I) { frame_slots = 12; slot_bytes = 4; } else if ((header.layer == DAF_LAYER_III) && (header.version == DAF_VERSION_2 || header.version == DAF_VERSION_2_5)) { frame_slots = 72; } else { frame_slots = 144; } header.min_frame_size = (frame_slots * header.bitrate / header.sample_rate) * slot_bytes; header.max_frame_size = header.min_frame_size + slot_bytes; } /* calculate current frame position */ cur_pos = input_stream->total_load - (input_stream->tail - input_stream->ptr); /* calculate next frame position because we need to find 2 consecutive frames */ min_next_pos = cur_pos + header.min_frame_size; max_next_pos = cur_pos + header.max_frame_size; /* check if next frame position reference to a valid frame */ result = daf_check_next_frame(input_stream, &header, min_next_pos, max_next_pos, &next_pos); if (result != DAF_CHECK_FRAME_TRUE) { break; } /* calc frame_size */ header.frame_size = next_pos - cur_pos; } if (result == DAF_CHECK_FRAME_EOF || sync_count == 2) { break; } else { audio_input_stream_seek(input_stream, (kal_int32) * offset); } } } if (info_p != NULL) { info_p->bitrate = header.bitrate; info_p->duration = (data_size - *offset) * 8 / header.bitrate; info_p->samplerate = header.sample_rate; info_p->channel_num = header.channel_num; } return KAL_TRUE; }
/***************************************************************************** * FUNCTION * daf_find_next_frame * DESCRIPTION * * PARAMETERS * input_stream [?] * header [?] * move_offset [IN] * RETURNS * kal_bool *****************************************************************************/ kal_bool daf_find_next_frame( audio_input_stream_struct *input_stream, daf_header_struct *header, kal_uint32 move_offset) { /*----------------------------------------------------------------*/ /* Local Variables */ /*----------------------------------------------------------------*/ daf_header_struct free_bitrate_header; kal_uint32 round, read_size; kal_uint32 sample_rate, bitrate, frame_slots, channel_num; kal_uint8 layer, version, slot_bytes; kal_uint8 *ptr, *end; kal_uint8 result = DAF_FIND_FRAME_FALSE; /*----------------------------------------------------------------*/ /* Code Body */ /*----------------------------------------------------------------*/ for (round = 0; result != DAF_FIND_FRAME_TRUE; round++) { /* check if it is out of searching range */ if (input_stream->total_load > input_stream->skip + DAF_FRAME_CHECK_SIZE) { return KAL_FALSE; } /* refill data */ audio_input_stream_read(input_stream, 0); read_size = input_stream->tail - input_stream->ptr; if (round == 0) { if (read_size < 4 + move_offset) /* we need at least 4 + move_offset bytes to check frame header */ { return KAL_FALSE; /* eof */ } input_stream->ptr += move_offset; } else if (read_size < 4) /* we need at least 4 bytes to check frame header */ { return KAL_FALSE; /* eof */ } if (result == DAF_FIND_FRAME_FREE_BITRATE) { /* search next frame for calculating free bitrate */ bitrate = 0; version = header->version; layer = header->layer; sample_rate = header->sample_rate; channel_num = header->channel_num; for (ptr = input_stream->ptr + 4, end = input_stream->tail - 4; ptr <= end; ptr++) { /* check if ptr reference to a valid frame header */ if (daf_parse_frame_header(ptr, &free_bitrate_header)) { if (version == free_bitrate_header.version && layer == free_bitrate_header.layer && sample_rate == free_bitrate_header.sample_rate && bitrate == free_bitrate_header.bitrate && channel_num == free_bitrate_header.channel_num) { slot_bytes = 1; if (layer == DAF_LAYER_I) { frame_slots = 12; slot_bytes = 4; } else if ((layer == DAF_LAYER_III) && (version == DAF_VERSION_2 || version == DAF_VERSION_2_5)) { frame_slots = 72; } else { frame_slots = 144; } header->min_frame_size = header->max_frame_size = ptr - input_stream->ptr; bitrate = (header->min_frame_size / slot_bytes) * sample_rate / frame_slots; if (bitrate >= 8000 && !(layer == DAF_LAYER_III && bitrate > 640000)) { header->bitrate = input_stream->free_bitrate = bitrate; input_stream->ptr = ptr; return KAL_TRUE; } } // if the latest found frame header doesn't match with the previous frame header, // we discard the previous one, and use the latest found frame header memcpy(header, &free_bitrate_header, sizeof(daf_header_struct)); bitrate = header->bitrate; layer = header->layer; if (header->bitrate != 0) { result = DAF_FIND_FRAME_TRUE; } break; } } input_stream->ptr = ptr; } else { /* loop through all data in input_stream */ for (ptr = input_stream->ptr, end = input_stream->tail - 4; ptr <= end; ptr++) { /* check if ptr reference to a valid frame header */ if (daf_parse_frame_header(ptr, header)) { result = DAF_FIND_FRAME_TRUE; /* check if it's free bitrate */ if (header->bitrate == 0) { if (input_stream->free_bitrate == 0) { result = DAF_FIND_FRAME_FREE_BITRATE; } else { header->bitrate = input_stream->free_bitrate; /* calculate frame length */ version = header->version; layer = header->layer; slot_bytes = 1; if (layer == DAF_LAYER_I) { frame_slots = 12; slot_bytes = 4; } else if ((layer == DAF_LAYER_III) && (version == DAF_VERSION_2 || version == DAF_VERSION_2_5)) { frame_slots = 72; } else { frame_slots = 144; } header->min_frame_size = (frame_slots * header->bitrate / header->sample_rate) * slot_bytes; header->max_frame_size = header->min_frame_size + slot_bytes; } } break; } } input_stream->ptr = ptr; } } return KAL_TRUE; }