diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-24 01:25:21 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-03-18 12:00:39 +0100 |
commit | b5716df4cb2837bbbc42195cf1aefcf03e21d6a6 (patch) | |
tree | 130cd712e2e00893b6df9959a375a8d9523a1aca /apps/metadata/rm.c | |
parent | 24bd9d5393dbe39a5c6194877bc00ede669b1d5d (diff) |
Build librbcodec with DSP and metadata.
All associated files are moved to /lib/rbcodec.
Change-Id: I572ddd2b8a996aae1e98c081d06b1ed356dce222
Diffstat (limited to 'apps/metadata/rm.c')
-rw-r--r-- | apps/metadata/rm.c | 464 |
1 files changed, 0 insertions, 464 deletions
diff --git a/apps/metadata/rm.c b/apps/metadata/rm.c deleted file mode 100644 index 27f541cb25..0000000000 --- a/apps/metadata/rm.c +++ /dev/null @@ -1,464 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2009 Mohamed Tarek - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <ctype.h> -#include <inttypes.h> - -#include <codecs/librm/rm.h> -#include "system.h" -#include "metadata.h" -#include "metadata_common.h" -#include "metadata_parsers.h" -#include "logf.h" - -/* Uncomment the following line for debugging */ -//#define DEBUG_RM -#ifndef DEBUG_RM -#undef DEBUGF -#define DEBUGF(...) -#endif - -#define ID3V1_OFFSET -128 -#define METADATA_FOOTER_OFFSET -140 - -static inline void print_cook_extradata(RMContext *rmctx) { - - DEBUGF(" cook_version = 0x%08lx\n", rm_get_uint32be(rmctx->codec_extradata)); - DEBUGF(" samples_per_frame_per_channel = %d\n", rm_get_uint16be(&rmctx->codec_extradata[4])); - DEBUGF(" number_of_subbands_in_freq_domain = %d\n", rm_get_uint16be(&rmctx->codec_extradata[6])); - if(rmctx->extradata_size == 16) { - DEBUGF(" joint_stereo_subband_start = %d\n",rm_get_uint16be(&rmctx->codec_extradata[12])); - DEBUGF(" joint_stereo_vlc_bits = %d\n", rm_get_uint16be(&rmctx->codec_extradata[14])); - } -} - - -struct real_object_t -{ - uint32_t fourcc; - uint32_t size; - uint16_t version; -}; - -static int real_read_object_header(int fd, struct real_object_t* obj) -{ - int n; - - if ((n = read_uint32be(fd, &obj->fourcc)) <= 0) - return n; - if ((n = read_uint32be(fd, &obj->size)) <= 0) - return n; - if ((n = read_uint16be(fd, &obj->version)) <= 0) - return n; - - return 1; -} - -#if (defined(SIMULATOR) && defined(DEBUG_RM)) -static char* fourcc2str(uint32_t f) -{ - static char res[5]; - - res[0] = (f & 0xff000000) >> 24; - res[1] = (f & 0xff0000) >> 16; - res[2] = (f & 0xff00) >> 8; - res[3] = (f & 0xff); - res[4] = 0; - - return res; -} -#endif - -static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) -{ - int skipped = 0; - uint32_t version; - struct real_object_t obj; -#ifdef SIMULATOR - uint32_t header_size; - uint16_t flavor; - uint32_t coded_framesize; - uint8_t interleaver_id_length; - uint8_t fourcc_length; -#endif - uint32_t interleaver_id; - uint32_t fourcc = 0; - - memset(&obj,0,sizeof(obj)); - read_uint32be(fd, &version); - skipped += 4; - - DEBUGF(" version=0x%04lx\n",((version >> 16) & 0xff)); - if (((version >> 16) & 0xff) == 3) { - /* Very old version */ - } else { -#ifdef SIMULATOR - real_read_object_header(fd, &obj); - read_uint32be(fd, &header_size); - /* obj.size will be filled with an unknown value, replaced with header_size */ - DEBUGF(" Object: %s, size: %ld bytes, version: 0x%04x\n",fourcc2str(obj.fourcc),header_size,obj.version); - - read_uint16be(fd, &flavor); - read_uint32be(fd, &coded_framesize); -#else - lseek(fd, 20, SEEK_CUR); -#endif - lseek(fd, 12, SEEK_CUR); /* unknown */ - read_uint16be(fd, &rmctx->sub_packet_h); - read_uint16be(fd, &rmctx->block_align); - read_uint16be(fd, &rmctx->sub_packet_size); - lseek(fd, 2, SEEK_CUR); /* unknown */ - skipped += 40; - if (((version >> 16) & 0xff) == 5) - { - lseek(fd, 6, SEEK_CUR); /* unknown */ - skipped += 6; - } - read_uint16be(fd, &rmctx->sample_rate); - lseek(fd, 4, SEEK_CUR); /* unknown */ - read_uint16be(fd, &rmctx->nb_channels); - skipped += 8; - if (((version >> 16) & 0xff) == 4) - { -#ifdef SIMULATOR - read_uint8(fd, &interleaver_id_length); - read_uint32be(fd, &interleaver_id); - read_uint8(fd, &fourcc_length); -#else - lseek(fd, 6, SEEK_CUR); -#endif - read_uint32be(fd, &fourcc); - skipped += 10; - } - if (((version >> 16) & 0xff) == 5) - { - read_uint32be(fd, &interleaver_id); - read_uint32be(fd, &fourcc); - skipped += 8; - } - lseek(fd, 3, SEEK_CUR); /* unknown */ - skipped += 3; - if (((version >> 16) & 0xff) == 5) - { - lseek(fd, 1, SEEK_CUR); /* unknown */ - skipped += 1; - } - - switch(fourcc) { - case FOURCC('c','o','o','k'): - rmctx->codec_type = CODEC_COOK; - read_uint32be(fd, &rmctx->extradata_size); - skipped += 4; - read(fd, rmctx->codec_extradata, rmctx->extradata_size); - skipped += rmctx->extradata_size; - break; - - case FOURCC('r','a','a','c'): - case FOURCC('r','a','c','p'): - rmctx->codec_type = CODEC_AAC; - read_uint32be(fd, &rmctx->extradata_size); - skipped += 4; - read(fd, rmctx->codec_extradata, rmctx->extradata_size); - skipped += rmctx->extradata_size; - break; - - case FOURCC('d','n','e','t'): - rmctx->codec_type = CODEC_AC3; - break; - - case FOURCC('a','t','r','c'): - rmctx->codec_type = CODEC_ATRAC; - read_uint32be(fd, &rmctx->extradata_size); - skipped += 4; - read(fd, rmctx->codec_extradata, rmctx->extradata_size); - skipped += rmctx->extradata_size; - break; - - default: /* Not a supported codec */ - return -1; - } - - DEBUGF(" flavor = %d\n",flavor); - DEBUGF(" coded_frame_size = %ld\n",coded_framesize); - DEBUGF(" sub_packet_h = %d\n",rmctx->sub_packet_h); - DEBUGF(" frame_size = %d\n",rmctx->block_align); - DEBUGF(" sub_packet_size = %d\n",rmctx->sub_packet_size); - DEBUGF(" sample_rate= %d\n",rmctx->sample_rate); - DEBUGF(" channels= %d\n",rmctx->nb_channels); - DEBUGF(" fourcc = %s\n",fourcc2str(fourcc)); - DEBUGF(" codec_extra_data_length = %ld\n",rmctx->extradata_size); - DEBUGF(" codec_extradata :\n"); - if(rmctx->codec_type == CODEC_COOK) { - DEBUGF(" cook_extradata :\n"); - print_cook_extradata(rmctx); - } - - } - - return skipped; -} - -static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) -{ - struct real_object_t obj; - int res; - int skipped; - off_t curpos __attribute__((unused)); - uint8_t len; /* Holds a string_length, which is then passed to read_string() */ - -#ifdef SIMULATOR - uint32_t avg_bitrate = 0; - uint32_t max_packet_size; - uint32_t avg_packet_size; - uint32_t packet_count; - uint32_t duration; - uint32_t preroll; - uint32_t index_offset; - uint16_t stream_id; - uint32_t start_time; - uint32_t codec_data_size; -#endif - uint32_t v; - uint32_t max_bitrate; - uint16_t num_streams; - uint32_t next_data_off; - uint8_t header_end; - - memset(&obj,0,sizeof(obj)); - curpos = lseek(fd, 0, SEEK_SET); - res = real_read_object_header(fd, &obj); - - if (obj.fourcc == FOURCC('.','r','a',0xfd)) - { - /* Very old .ra format - not yet supported */ - return -1; - } - else if (obj.fourcc != FOURCC('.','R','M','F')) - { - return -1; - } - - lseek(fd, 8, SEEK_CUR); /* unknown */ - - DEBUGF("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj.fourcc),(int)obj.size,obj.version,(int)curpos); - - res = real_read_object_header(fd, &obj); - header_end = 0; - while(res) - { - DEBUGF("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj.fourcc),(int)obj.size,obj.version,(int)curpos); - skipped = 10; - if(obj.fourcc == FOURCC('I','N','D','X')) - break; - switch (obj.fourcc) - { - case FOURCC('P','R','O','P'): /* File properties */ - read_uint32be(fd, &max_bitrate); - read_uint32be(fd, &rmctx->bit_rate); /*avg bitrate*/ -#ifdef SIMULATOR - read_uint32be(fd, &max_packet_size); - read_uint32be(fd, &avg_packet_size); - read_uint32be(fd, &packet_count); -#else - lseek(fd, 3*sizeof(uint32_t), SEEK_CUR); -#endif - read_uint32be(fd, &rmctx->duration); -#ifdef SIMULATOR - read_uint32be(fd, &preroll); - read_uint32be(fd, &index_offset); -#else - lseek(fd, 2*sizeof(uint32_t), SEEK_CUR); -#endif - read_uint32be(fd, &rmctx->data_offset); - read_uint16be(fd, &num_streams); - read_uint16be(fd, &rmctx->flags); - skipped += 40; - - DEBUGF(" max_bitrate = %ld\n",max_bitrate); - DEBUGF(" avg_bitrate = %ld\n",rmctx->bit_rate); - DEBUGF(" max_packet_size = %ld\n",max_packet_size); - DEBUGF(" avg_packet_size = %ld\n",avg_packet_size); - DEBUGF(" packet_count = %ld\n",packet_count); - DEBUGF(" duration = %ld\n",rmctx->duration); - DEBUGF(" preroll = %ld\n",preroll); - DEBUGF(" index_offset = %ld\n",index_offset); - DEBUGF(" data_offset = %ld\n",rmctx->data_offset); - DEBUGF(" num_streams = %d\n",num_streams); - DEBUGF(" flags=0x%04x\n",rmctx->flags); - break; - - case FOURCC('C','O','N','T'): - /* Four strings - Title, Author, Copyright, Comment */ - read_uint8(fd,&len); - skipped += (int)read_string(fd, id3->id3v1buf[0], sizeof(id3->id3v1buf[0]), '\0', len); - read_uint8(fd,&len); - skipped += (int)read_string(fd, id3->id3v1buf[1], sizeof(id3->id3v1buf[1]), '\0', len); - read_uint8(fd,&len); - skipped += (int)read_string(fd, id3->id3v1buf[2], sizeof(id3->id3v1buf[2]), '\0', len); - read_uint8(fd,&len); - skipped += (int)read_string(fd, id3->id3v1buf[3], sizeof(id3->id3v1buf[3]), '\0', len); - skipped += 4; - - DEBUGF(" title=\"%s\"\n",id3->id3v1buf[0]); - DEBUGF(" author=\"%s\"\n",id3->id3v1buf[1]); - DEBUGF(" copyright=\"%s\"\n",id3->id3v1buf[2]); - DEBUGF(" comment=\"%s\"\n",id3->id3v1buf[3]); - break; - - case FOURCC('M','D','P','R'): /* Media properties */ -#ifdef SIMULATOR - read_uint16be(fd,&stream_id); - read_uint32be(fd,&max_bitrate); - read_uint32be(fd,&avg_bitrate); - read_uint32be(fd,&max_packet_size); - read_uint32be(fd,&avg_packet_size); - read_uint32be(fd,&start_time); - read_uint32be(fd,&preroll); - read_uint32be(fd,&duration); -#else - lseek(fd, 30, SEEK_CUR); -#endif - skipped += 30; - read_uint8(fd,&len); - skipped += 1; - lseek(fd, len, SEEK_CUR); /* desc */ - skipped += len; - read_uint8(fd,&len); - skipped += 1; -#ifdef SIMULATOR - lseek(fd, len, SEEK_CUR); /* mimetype */ - read_uint32be(fd,&codec_data_size); -#else - lseek(fd, len + 4, SEEK_CUR); -#endif - skipped += len + 4; - read_uint32be(fd,&v); - skipped += 4; - - DEBUGF(" stream_id = 0x%04x\n",stream_id); - DEBUGF(" max_bitrate = %ld\n",max_bitrate); - DEBUGF(" avg_bitrate = %ld\n",avg_bitrate); - DEBUGF(" max_packet_size = %ld\n",max_packet_size); - DEBUGF(" avg_packet_size = %ld\n",avg_packet_size); - DEBUGF(" start_time = %ld\n",start_time); - DEBUGF(" preroll = %ld\n",preroll); - DEBUGF(" duration = %ld\n",duration); - DEBUGF(" codec_data_size = %ld\n",codec_data_size); - DEBUGF(" v=\"%s\"\n", fourcc2str(v)); - - if (v == FOURCC('.','r','a',0xfd)) - { - int temp; - temp= real_read_audio_stream_info(fd, rmctx); - if(temp < 0) - return -1; - else - skipped += temp; - } - else if (v == FOURCC('L','S','D',':')) - { - DEBUGF("Real audio lossless is not supported."); - return -1; - } - else - { - /* We shall not abort with -1 here. *.rm file often seem - * to have a second media properties header that contains - * other metadata. */ - DEBUGF("Unknown header signature :\"%s\"\n", fourcc2str(v)); - } - - - break; - - case FOURCC('D','A','T','A'): - read_uint32be(fd,&rmctx->nb_packets); - skipped += 4; - read_uint32be(fd,&next_data_off); - skipped += 4; - - /*** - * nb_packets correction : - * in some samples, number of packets may not exactly form - * an integer number of scrambling units. This is corrected - * by constructing a partially filled unit out of the few - * remaining samples at the end of decoding. - ***/ - if(rmctx->nb_packets % rmctx->sub_packet_h) - rmctx->nb_packets += rmctx->sub_packet_h - (rmctx->nb_packets % rmctx->sub_packet_h); - - DEBUGF(" data_nb_packets = %ld\n",rmctx->nb_packets); - DEBUGF(" next DATA offset = %ld\n",next_data_off); - header_end = 1; - break; - } - if(header_end) break; - curpos = lseek(fd, obj.size - skipped, SEEK_CUR); - res = real_read_object_header(fd, &obj); - } - - - return 0; -} - - -bool get_rm_metadata(int fd, struct mp3entry* id3) -{ - RMContext *rmctx = (RMContext*) (( (intptr_t)id3->id3v2buf + 3 ) &~ 3); - memset(rmctx,0,sizeof(RMContext)); - if(rm_parse_header(fd, rmctx, id3) < 0) - return false; - - if (!setid3v1title(fd, id3)) { - /* file has no id3v1 tags, use the tags from CONT chunk */ - id3->title = id3->id3v1buf[0]; - id3->artist = id3->id3v1buf[1]; - id3->comment= id3->id3v1buf[3]; - } - - switch(rmctx->codec_type) - { - case CODEC_COOK: - /* Already set, do nothing */ - break; - case CODEC_AAC: - id3->codectype = AFMT_RM_AAC; - break; - - case CODEC_AC3: - id3->codectype = AFMT_RM_AC3; - break; - - case CODEC_ATRAC: - id3->codectype = AFMT_RM_ATRAC3; - break; - } - - id3->channels = rmctx->nb_channels; - id3->extradata_size = rmctx->extradata_size; - id3->bitrate = rmctx->bit_rate / 1000; - id3->frequency = rmctx->sample_rate; - id3->length = rmctx->duration; - id3->filesize = filesize(fd); - return true; -} |